ITEEDU

汉字显示编程示例

概述:

一般在屏幕上显示汉字的时候需要汉字系统的支持,但需要自己显示汉字的时候,就需要自己读汉字字库文件,把字符点阵读出来,再用绘图的办法显示到屏幕上,本文是读 UCDOS 16点字库文件的示例。
在 UCDOS 的点阵字库 HZK16 中,字符点阵是按照汉字内码排列的,汉字的内码从一些图形字符开始,起始编码为 A1A1H,汉字内码第一位为区码,每区为 94 个汉字,第二位为每区内的编码,每个汉字的点阵为 16点*16点 共32字节,数据按第一行 1-8点,9-16点,第二行 1-8点,9-16点...排列,每位数据 1 为要显示点,0 为不显示点。汉字点阵数据在字库中的偏移量为 ((区码-A1H)*94 + (区内编码-A1H))*32。
本程序为一个简单的例子,要显示的汉字在变量 DISP_DATA 中,且没有考虑汉字、英文混用的情况。

源程序:

; Write in May 22,1996
;            By LuoYunBin ----- http://asm.yeah.net 

.286
   LINE_CHAR  EQU       210         ;在屏幕上第几行显示
    COL_CHAR  EQU       230         ;在屏幕上第几列显示
  COLOR_CHAR  EQU       0EH         ;显示颜色
       CHARS  EQU       (OFFSET DISP_DATA_END-OFFSET DISP_DATA)/2
        CODE  SEGMENT
              ASSUME    CS:CODE,DS:CODE
              ORG       100H
      START:
              JMP       INSTALL
     CC_FILE  DB        'C:\UCDOS\HZK16',0      ;字库文件名,用 UCDOS 的16点阵汉字库
      HANDLE  DW        ?           ;file handle
   DISP_DATA  DB        '罗云彬'    ;要显示的汉字
           DISP_DATA_END  EQU       THIS BYTE
            D_OPEN_ERROR  DB        'File C:\UCDOS\HZK16 not found !',0DH,0AH,24H
    INSTALL:
              MOV       AX,3D00H    ;打开汉字库
              MOV       DX,OFFSET CC_FILE
              INT       21H
              JNB       OPEN_OK
		
              MOV       AH,9
              MOV       DX,OFFSET D_OPEN_ERROR
              INT       21H
              INT       20H
    OPEN_OK:
              MOV       HANDLE,AX
              MOV       SI,OFFSET DISP_DATA
              MOV       DI,OFFSET ZI_BUFFER
              MOV       CX,CHARS
              CLD
       INS2:
              LODSB
              MOV       AH,AL
              LODSB
              CALL      GET_DOTS		;读出汉字点针
              LOOP      INS2
              CALL      DISP_CC			;显示到屏幕
              INT       20H
    GET_DOTS  PROC
              PUSHA
              SUB       AX,0A1A1H   ;汉字的内码从 A1区开始
              CWD
              MOV       DL,AL       ;所以绝对开始区是内码-A1
              MOV       AL,AH       ;点阵在字库中的位置为
              CBW
              MOV       BL,94       ;((汉字码1-A1)* 94 + 汉字码2 - A1)* 32
              MUL       BL
              ADD       AX,DX
              MOV       BX,32
              MUL       BX
              MOV       CX,DX
              MOV       DX,AX
              MOV       AX,4200H    ;移动读写指针到点阵数据位置
              MOV       BX,HANDLE
              INT       21H
              MOV       AH,3FH
              MOV       CX,32
              MOV       DX,DI
              INT       21H
              POPA
              ADD       DI,32
              RET
    GET_DOTS  ENDP
     DISP_CC  PROC
              MOV       AX,12H      ;640*480 mode
              INT       10H         ;设置640*480/16色显示模式
              MOV       CX,CHARS
              MOV       SI,OFFSET ZI_BUFFER
              MOV       BX,COL_CHAR-20          ;BX = column
    DH_LOP0:
              ADD       BX,20       ;every char column+20
              PUSH      CX
              MOV       CX,16       ;l6 lines/char
              MOV       DX,LINE_CHAR            ;DX = start line
    DH_LOP1:
              PUSH      BX
              PUSH      CX
              LODSB                 ;16 dots/line
              MOV       AH,AL
              LODSB
              MOV       CX,16
    DH_LOP2:
              SHL       AX,1
              PUSH      AX
              PUSH      BX
              PUSH      CX
              JC        DB_COLOR
              XOR       AL,AL       ;back color is 0
              JMP       SHORT DB_DRAW
   DB_COLOR:
              MOV       AL,COLOR_CHAR
    DB_DRAW:
              MOV       AH,0CH
              MOV       CX,BX
              XOR       BH,BH
              INT       10H
              POP       CX
              POP       BX
              POP       AX
              INC       BX          ;inc column
              LOOP      DH_LOP2
              INC       DX          ;next line
              POP       CX
              POP       BX
              LOOP      DH_LOP1
              POP       CX
              LOOP      DH_LOP0
              XOR       AH,AH
              INT       16H
              MOV       AX,3
              INT       10H
              RET
     DISP_CC  ENDP
   ZI_BUFFER  EQU       THIS BYTE

        CODE  ENDS
              END       START