引用回帖中提到的“将一个汉字拆分成两个字符并将其字模写入显卡的字符发生器”,在技术上完全成立,是 PC-DOS 时代在标准 VGA 文本模式(Mode 03h)下局部显示汉字的经典技术方案。
1. 硬件基础与原理
标准 VGA 文本模式(80×25 字符)并不直接存储点阵图形,而是由显存中的“字符编码+属性”与显卡板载字体发生器(Font RAM)配合渲染:
- 显存映射:屏幕显存位于
B800:0000,每 2 字节代表一个屏幕位置(1 字节 ASCII 字符编码 + 1 字节颜色属性)。
- 点阵规格:标准 80×25 文本模式下,每个字符单元的物理分辨率是 8×16 像素(部分模式为 9×16)。
- 汉字点阵:标准国标汉字库(如 HZK16)的点阵分辨率是 16×16 像素,共 32 字节。
- 空间对应关系:一个 16×16 点阵汉字,在物理尺寸上恰好等于两个水平相邻的 8×16 字符单元(左半部 16 字节 + 右半部 16 字节)。
VGA 硬件允许用户自定义可编程字符发生器(位于 VGA 显存的位面 2,即 Plane 2)。软件可以通过 VGA BIOS 中断(INT 10h, AX=1100h)或直接操作 VGA 序列发生器与图形控制器寄存器,将自定义的点阵数据写入字体区,替换掉原有的字符字形。
2. 软件运行逻辑
类似 UCDICT 这类英汉词典软件在文本模式下显示中文的完整过程如下:
- 字模拆分:软件从字库中检索出目标汉字的 16×16 点阵(每行 2 字节,共 16 行)。将其按纵向拆分成两组 8×16 点阵(每行的左字节属于左半字,右字节属于右半字)。
- 动态分配字符编码(Font Cache):
- 标准 ASCII 码占用 0~127,128~255 为扩展字符区。
- 软件在 128~255 范围内分配两个空闲的字符编码(例如
0x80 与 0x81)。
- 写入显卡字体区:调用
INT 10h / AX=1100h,将左半字模写入 0x80 对应的发生器位置,右半字模写入 0x81 对应的发生器位置。
- 输出到屏幕:直接向
B800:0000 连续写入两个字符编码 0x80 和 0x81。显卡在扫描到该位置时,硬件发生器自动取出这两个字模并在屏幕上连续绘制,肉眼看到的就是一个完整的 16×16 汉字。
3. 该方案的优势与边界条件
优势
- 速度极快:无需切换至图形模式(如 640×480 16 色模式),数据吞吐量极小,完全保留了文本模式即时刷屏的特性。
- 无需加载庞大的中文平台:程序自身内嵌字库索引与渲染逻辑,可在原生英文 DOS 环境下独立运行。
局限与工程限制
- 同屏汉字总数受限:
- 单套 VGA 字符集仅有 256 个编码槽位。扣除标准英文和常用符号后,空闲槽位通常只有约 128 个,最多只能同时显示约 64 个不同的汉字。
- 即使开启 VGA 的 512 字符模式(利用属性字节中的第 3 位切换两套 256 字符表,代价是失去字符闪烁或部分前景色),同屏最多也只能容纳约 200 个不同汉字。
- 因此该方案仅适用于英汉词典(释义较短)、状态提示框、菜单项等汉字密度极低的场景。全中文文本编辑(如 WPS)或长篇阅读必须依赖图形模式或物理汉卡。
- 刷新维护开销:当屏幕滚动或翻页时,软件必须重置这套动态字符缓存池;若一屏内的汉字种类超出字符槽位上限,程序就会出现字模覆盖导致的错乱。
- 9 点宽补偿:部分 VGA 文本模式为了排版美观,会在硬件上将 8 点宽拉伸为 9 点宽(字符第 9 列重复第 8 列像素)。在此模式下显示汉字必须通过设置 VGA 属性控制器寄存器(
3C0h)关闭第 9 点自动复制,否则汉字中央会出现 1 像素的纵向断裂白缝。