REM 在BASIC程序中自动检测汉字系统
DEF SEG = &H40
mode = PEEK(&H49)
OUT &H3CE, &H6
result = INP(&H3CF) AND &HF
PRINT "mode="; mode, "result="; result
IF mode = 3 AND result = 5 THEN
PRINT "现在于直接写屏的汉字系统中"
PRINT "现在你看到的是汉字"
ELSE
IF mode = 3 AND result = 14 THEN
PRINT "Is not any CCDOS in the memory ,It's it ?"
PRINT "So , You only see the English"
ELSE
IF mode = 18 AND result = 1 THEN
PRINT "你现在非直接写屏的汉字系统中"
ELSE
PRINT "I Can't know which display mode ."
END IF
END IF
END IF
Gemini 解答
技术背景说明
在 20 世纪 80 年代至 90 年代中期的中文 DOS 环境下,由于原始的 PC 标准(如 IBM VGA/EGA 规范)并不直接支持双字节字符(DBCS)显示,中文系统(CCDOS、天汇、UCDOS、希望等)通常通过拦截中断和直接操作视频硬件寄存器来实现汉字显示。
本帖讨论的核心在于如何通过 Quick BASIC 代码识别当前的视频状态,从而判断是否加载了汉字系统。这主要涉及到 BIOS 数据区、VGA 控制器寄存器以及多路中断调用(Multiplex Interrupt)。
技术实现原理与纠正
1. 基于视频状态的检测(帖子 #1 与 #8)
原作者
mys和用户本是提到的方法是利用 VGA 图形控制器的 Graphics Controller (GC) 寄存器。
- 硬件原理: 索引为
06h的 Misc 寄存器(通过端口3CEh和3CFh访问)决定了显存的映射方式。
- 在标准的 DOS 文本模式(Mode 3, 80x25)下,该寄存器的默认值通常使得结果掩码为
0Eh(或包含位 1 和位 3)。- 许多中文字体驱动程序(如采用图形覆盖技术或拦截写屏的中文字体)会修改 VGA 的位平面(Bit Planes)访问方式,以便在字符模式下模拟图形输出或处理汉字点阵。
- 局限性: 这种基于硬件端口(
INP/OUT)的方法依赖于具体的汉字系统实现。Wengier 在帖子 #2 中指出的修正result = 1 or result = 5是必要的,因为不同的环境(如 Windows 虚拟 DOS 虚拟机、不同的驱动实现)在初始化 VGA 寄存器时存在细微差异。2. 基于软件中断的检测(帖子 #4)
Kinglion提供的汇编代码(通过CALL ABSOLUTE执行)使用了更标准的方法,即探测特定的中断调用。
- 中断 2Fh (Multiplex Interrupt): 这是 DOS 环境下各 TSR(内存驻留程序)之间通信的标准接口。
- 功能调用 0DB00h: 这是历史上许多中文系统(如天汇、UCDOS、CCDOS)约定的探测接口。如果
AX = 0DB00h调用后,AL返回0FFh,通常意味着中文内核已加载。- 功能调用 0DB10h / INT 10h: 另一部分中文系统通过扩展
INT 10h(视频服务)来提供中文支持。代码中检测AL是否返回0FFh来验证环境。- 技术细节: 帖子 #4 的代码逻辑是:
- 尝试
INT 2Fh / AX=0DB00h。- 如果失败,尝试
INT 10h / AX=0DB10h。- 根据返回值判断是否设置成功标志位,最后回传给 QB 的数组空间。这是当时最稳健的检测方案,因为它不依赖于特定的视频硬件状态。
关于环境变量与错误码的补充(帖子 #5, #7, #9)
在 DOS 中,由于每个进程都拥有自己的 环境变量块(Environment Block) 副本,子进程(如 QB 编写的程序)修改自己的环境变量副本后,在退出时无法直接反馈给父进程(如
COMMAND.COM)。
- 官方局限: 正如
xugaohui所述,QB 的ENVIRON语句只能修改局部环境。- 历史解决方案: 当年通用的做法是程序运行后通过
SYSTEM n或END n返回一个 退出码(ERRORLEVEL)。批处理文件随后使用IF ERRORLEVEL n逻辑来执行后续操作(例如加载不同的驱动或显示不同的界面)。- 另一种方式: 如果必须修改父进程的环境变量,则需要直接定位 DOS 内核中的 Master Environment Block。这涉及到遍历 PSP(程序段前缀)链表,操作复杂且由于不同 DOS 版本(MS-DOS 5.0+, PC-DOS, FreeDOS)的内核结构差异,极具风险。
关于 Windows 环境检测(帖子 #12)
byxyk提到的AX = 160Ah是 Windows 的增强模式探测调用。
- 功能: 如果程序运行在 Windows 的 DOS 虚拟机中,该调用会返回 Windows 的主次版本号。
- 意义: 在 Win9x 时代,DOS 窗口自带中文支持(基于 WinOldAp 的保护模式驱动),传统的 DOS 级检测(如直接探测显卡寄存器)可能会失效或产生不稳定的结果,结合此调用可以区分“纯实模式 DOS”和“Windows 下的虚拟 DOS 环境”。
总结
在 2004 年至 2010 年的讨论语境下,最推荐的方式是结合 INT 2Fh (AX=0DB00h) 和 ERRORLEVEL 返回。通过硬件端口直接读取寄存器(如
3C5h或3CFh)虽然代码简洁,但在不同显卡架构及模拟器(如 DOSBox)或现代兼容层下稳定性较低。
http://hzmys.blog.163.com/
我的网盘
firststep.qjwm.com
fsmys.ys168.com
ssmys.ys168.com
www.brsbox.com/fsmys
www.brsbox.com/ssmys
www.brsbox.com/ccdos


