0001-01-01  2024-09-15    1293 字  3 分钟

aos32-gb2312.tgz

一个GB2312汉字是由两个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每一个区有94个字符。

点阵结构

从图片可以看出:

  • 日文编码的第一个字节为点阵的左半部分,第二个字节为点阵的右半部分。

日文EUC

  • 中文编码的第一个字节为点阵的上半部分,第二个字节为点阵的下半部分

中文GB2312

偏移

在汉字占的两个字节中,前一个字节为该汉字的区号,后一个字节为该字的位号。其中,每个区记录94个汉字,位号为该字在该区中的位置。

  • 区码:区号(汉字的第一个字节)- 0xa0 (因为汉字编码是从0xa0区开始的,所以文件最前面就是从0xa0区开始,要算出相对区码)
  • 位码:位号(汉字的第二个字节)- 0xa0

由此可以得到汉字在HZK16中的绝对偏移位置:offset=(94*(区码-1)+(位码-1))*32

  • 区码减1是因为数组是以0为开始而区号位号是以1为开始的
  • (94*(区号-1)+位号-1)是一个汉字字模占用的字节数
  • 最后乘以32是因为汉字库文应从该位置起的32字节信息记录该字的字模信息(前面提到一个汉字要有32个字节显示)

代码实现

由于点阵结构不同,原先的putfont8函数并不适用于GB2312,所以重新编写一个函数来显示中文

c ▽
void putfont8_ud_rev(char *vram, int xsize, int x, int y, char c, char *font) { int i, k; char *p, d ; for(i = 0; i < 8; i++) { p = vram + (y + i) * xsize + x; d = font[2 * i]; for(k = 0; k < 8; k++) { if(d&(0x01<<k)) { p[k] = c; } } p += 8; d = font[2 * i + 1]; for(k = 0; k < 8; k++) { if(d&(0x01<<k)) { p[k] = c; } } } return; }

在putfonts8_asc中添加新的模式用以显示中文

c ▽
if (task->langmode == 3) { for (; *s != 0x00; s++) { if (task->langbyte1 == 0) { if (0xa1 <= *s && *s <= 0xfe) { task->langbyte1 = *s; } else { //只要是半角就使用hankaku里面的字符 putfont8(vram, xsize, x, y, c, hankaku + *s * 16); } } else { k = task->langbyte1 - 0xa1; t = *s - 0xa1; task->langbyte1 = 0; font = chinese + (k * 94 + t) * 32; putfont8_ud_rev(vram, xsize, x - 8, y , c, font ); putfont8_ud_rev(vram, xsize, x - 8, y + 8, c, font + 16); } x += 8; } }

如果不需要日文字体,可以直接将中文字体数据读入bootpack.c中的nihongo变量(注意分配的内存大小需要修改为memman_alloc_4k(memman, 0x5d5d * 32))

如果想要共存则需要添加新的变量,并且增大读入的扇区数量。

在chklang.c文件中添加下列代码,用户测试中文

c ▽
static char s3[16] = { // 中文 0xc4, 0xe3, 0xba, 0xc3, 0xce, 0xd2, 0xca, 0xc7, 0x41, 0x6b, 0x76, 0x69, 0x63, 0x6f, 0x72, 0x00 }; if (langmode == 3) { api_putstr0(s3); }

修改ipl.nas中读入的扇区数量

c ▽
CYLS EQU 30

修改bootpack.c

c ▽
// 定义全局变量 unsigned char *chinese; unsigned char *nihongo; // 函数void HariMain(void) 中 nihongo = (unsigned char *) memman_alloc_4k(memman, 16 * 256 + 32 * 94 * 47); chinese = (unsigned char *) memman_alloc_4k(memman, 0x5d5d * 32); fat = (int *) memman_alloc_4k(memman, 4 * 2880); file_readfat(fat, (unsigned char *) (ADR_DISKIMG + 0x000200)); finfo = file_search("nihongo.fnt", (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); if (finfo != 0) { file_loadfile(finfo->clustno, finfo->size, nihongo, fat, (char *) (ADR_DISKIMG + 0x003e00)); } else { for (i = 0; i < 16 * 256; i++) { nihongo[i] = hankaku[i]; // 没有字库,半角部分直接复制英文字裤 } for (i = 16 * 256; i < 16 * 256 + 32 * 94 * 47; i++) { nihongo[i] = 0xff; // 没有字库,全角部分以0xff填充 } } finfo = file_search("HZK16.fnt", (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); if (finfo != 0) { file_loadfile(finfo->clustno, finfo->size, chinese, fat, (char *) (ADR_DISKIMG + 0x003e00)); } else { for (i = 0; i < 16 * 256; i++) { chinese[i] = hankaku[i]; // 没有字库,半角部分直接复制英文字裤 } for (i = 16 * 256; i < 16 * 256 + 32 * 94 * 47; i++) { chinese[i] = 0xff; // 没有字库,全角部分以0xff填充 } } memman_free_4k(memman, (int) fat, 4 * 2880);

修改graphic.c文件putfonts8_asc的代码,添加下面两行

c ▽
extern char *nihongo; extern char *chinese;

修改console.c文件cmd_langmode函数中的if (mode <= 2)if (mode <= 3)

Result