LLM 解释
在 DOS 时代的 VGA/EGA 环境下,这种技术被称为**“自定义字体(User-defined Fonts)”或“软字库技术”**。它允许程序在不进入图形模式的情况下,通过修改显卡字符发生器(Character Generator)中的字模数据来显示非 ASCII 字符。
以下是该技术的原理与实现机制的详细解释:
1. 显卡文本模式的原理
在标准 VGA 文本模式(如 3h 模式,80x25 行)下,屏幕上的每一个字符位由两个字节组成:
-
ASCII 码(1 字节):指定显示哪一个字符(0-255)。
-
属性字节(1 字节):指定颜色、闪烁等。
显卡根据 ASCII 码,从其内置的 字模显存(Plane 2) 中读取对应的 8x16(或其他尺寸)像素位图,并将其渲染到屏幕上。
2. 汉字拆分与字模重定义
标准汉字字模通常是 16x16 像素。由于文本模式下单个字符单元格的宽度固定为 8 像素(某些模式下为 9 像素),一个汉字在物理上无法放入一个字符位中。
具体操作步骤如下:
-
拆分:将一个 16x16 的汉字字模纵向切分为左、右两个 8x16 的部分。
-
映射:在 VGA 字符表的 256 个编码中,选取两个不常用的编号(例如 ASCII 128 和 129)。
-
写入:通过 BIOS 中断
INT 10h, AX=1100h 或直接操作 VGA 寄存器,将汉字的左半部分位图写入 ASCII 128 的存储区,右半部分写入 ASCII 129 的存储区。
-
显示:当需要在屏幕坐标 (x, y) 处显示该汉字时,程序在显存(B800h 段)的对应位置连续写入字符 128 和 129。
3. 技术限制与“动态刷新”
这种方法的主要限制是字符数量。
- 标准 VGA 文本模式支持 256 个字符。如果保留前 128 个标准 ASCII 字符,剩下的 128 个位置只能同时显示 64 个不同的汉字(128 / 2 = 64)。
- 通过 VGA 的扩展功能,可以开启“双字库”模式,将字符上限提升至 512 个(利用属性字节中的第 3 位作为切换标志),此时可同时显示 192 个左右的汉字。
由于一屏幕显示的汉字往往超过 64 个,类似 UCDICT 或某些中文系统的“英文汉化版”会采用动态缓存机制:
程序会实时监控屏幕内容,根据当前屏幕上出现的汉字,动态地将需要的字模写往显卡的字模 RAM 中。如果屏幕上的汉字种类超过了 256/512 的上限,则会导致字符显示混乱或产生花屏现象。
4. 为什么不直接进入图形模式?
在 286/386 时代,直接在图形模式(如 Mode 12h, 640x480)下绘图显示中文虽然灵活,但存在以下缺陷:
-
性能开销大:图形模式下移动光标、滚动屏幕需要处理大量的像素位操作,速度远慢于文本模式。
-
内存占用高:图形显存的管理比文本模式复杂。
-
兼容性:文本模式可以无缝继承 DOS 系统的各种指令输出,而图形模式往往需要完全接管显示逻辑。
5. 汇编层面的关键操作
在汇编中,实现这一功能的核心通常是操作 VGA 寄存器进入字模读写模式,或调用 BIOS 中断:
; 示例:使用 BIOS 中断加载自定义字模
mov ax, 1100h ; 功能号:装入字模
mov bh, 16 ; 每个字符的高度(字节数)
mov bl, 0 ; 要加载到第几个字体块
mov cx, 1 ; 连续加载的字符个数
mov dx, 128 ; 起始 ASCII 码
push ds
pop es
mov bp, offset MyCharData ; 指向 16 字节的字模数据偏移地址
int 10h
总结
你所看到的 UCDICT 界面,本质上是将显卡当作一个可编程的字符显示器。它并未改变 DOS 的文本显示架构,而是通过高频率地欺骗显卡,将原本存储“英文字母”的内存区域替换成了“汉字的零碎部件”。这种技术在 90 年代初期的查词工具、安装程序及部分轻量级汉字系统(如简易版长城中文系统)中非常普遍。