首页
社区
课程
招聘
[原创]关于在DOS下如何调用汉字库显示汉字
发表于: 2009-5-28 23:43 5631

[原创]关于在DOS下如何调用汉字库显示汉字

2009-5-28 23:43
5631

在DOS方式下显示中文,有2种办法, 要看分辨率
如果是标准的DOS文本方式下,那只有修改ASCII的点阵信息, 但是这种方法太麻烦,而且汉字数量有限制,一般情况下不用,用的最多的还是图形方式下调用中文字库显示汉字

我这个程序已经好久了, 是在640x480的分辨率下直接写屏输出汉字
程序很简单,一般都DOS编程经验的人一看就懂
要用到的有2个文件,HZK16是UCDOS里带的16点阵的字库文件,这个随便网上找个UCDOS下载就有了
'C:\WINDOWS\STHVCD\README.TXT' 是以前金山影霸的README文件,这个随便自己换

;〈1〉 汉字的字模与西文下的字模略有不同,但原理相同。
;〈2〉 西文下的字模是将一个字符左右拆分,左半边为一组数据,右半边为一组数据。
;〈3〉 汉字则不同,它将一个汉字上下拆分,上半边为一组数据,下半边为一组数据。
;〈4〉 所以在传输汉字的字模是要一“字”为单位,而西文字符要以“字节”为单位。
;〈5〉 在640X480的分辨率下,每行能存放80个字节的数据,即每行可以显示
;       40个16点阵的汉字。
;〈6〉 要注意:在写屏时,每写完2个字节的数据,要换行显示。(跳过76个字节)
;〈7〉 16X16点阵是按行存储的,而24X24点阵是按列存储的。
;〈8〉 汉字的机内码就是它的ASCII码,将低位和高位各减去161,就是区位;码了,低位是位码,高位是区码。
;〈9〉 有了区位码,就可根据公式“(区码X94+位码)X32 ”来得出该汉字
;       字模在字库中的位置。
;〈A〉 同样,利用上面的公式也可以求出汉字在其它点阵字库(如24X24点阵)
;       位置,只要将上式的32换成72即可。
;〈B〉 汉字换行,要将VIDEO  RAM中的指针增加80X16X行数。
;       公式:80X16X行数+列数(一个汉字有2列)

stack segment stack 'stack'
      
      db 1024 dup (0)

stack ends

data segment

;*****************************  DATA SEGMENT  ********************************

ver_msg db 50*1024 dup (0)
err_msg db 0dh,0ah,' Open Or Read File " HZK16 " Error !'
        db 0dh,0ah,' Path: C:\UCDOS\HZK16 ',0dh,0ah,07,'$'
hzk_file db 'C:\UCDOS\HZK16',0
read_file db 'C:\WINDOWS\STHVCD\README.TXT',0
file_byte dw ?
msg_ip dw 0
hz_q dw ?
hz_w dw ?
hzk_ip dw ?
       dw ?
file_handle dw ?
hzk_buf db 32 dup(0)
crt_emm db ?
ram_add dw 0

;*****************************  DATA SEGMENT  ********************************

data ends

cseg segment
     assume cs:cseg,ds:data,es:data,ss:stack

begin:       mov ax,data
             mov ds,ax
             mov ax,stack
             mov ss,ax

             mov ax,3d00h
             mov dx,offset read_file
             int 21h
             jc read_err
             mov word ptr [file_handle],ax

             mov ax,4202h
             mov bx,[file_handle]
             xor cx,cx
             xor dx,dx
             int 21h
             jc open_err

             mov word ptr [file_byte],ax
             mov ax,4200h
             mov bx,[file_handle]
             xor cx,cx
             xor dx,dx
             int 21h
             jc open_err

             mov ah,3fh
             mov bx,[file_handle]
             mov cx,[file_byte]
             mov dx,offset ver_msg
             int 21h
             jc open_err

             mov ax,3e00h
             mov bx,[file_handle]
             int 21h
             jc open_err

             mov cx,[file_byte]
             mov dx,offset ver_msg
             add cx,dx
             inc cx
             mov si,cx
             mov byte ptr ds:[si],1ah

             mov ax,0012h
             int 10h

             mov ax,0f00h
             int 10h
             mov byte ptr [crt_emm],bh
             mov ah,02h
             xor dx,dx
             int 10h

           mov ax,3d00h
           mov dx,offset hzk_file
           int 21h
           jc open_err
           mov word ptr [file_handle],ax

load_msg:    call wait_user
             mov si,offset ver_msg
             add si,[msg_ip]
             mov al,0a1h
             cmp byte ptr [si],al
             jc dis_char

             add word ptr [msg_ip],2
             call set_ram
             call asc2qwm
             call hz2buf

             mov ax,0a000h
             mov es,ax
            
             mov si,offset hzk_buf
             mov di,[ram_add]
             call display_hz
             call set_gb
             jmp load_msg

quit:        mov ah,0
             int 16h
           
             mov ah,3eh
             mov bx,[file_handle]
             int 21h
           
             mov ax,0003h
             int 10h

open_err:    mov ax,4c00h
             int 21h

dis_char:    cmp byte ptr [si],1ah
             jz quit
             inc word ptr [msg_ip]
             mov ah,02h
             mov byte ptr dl,[si]
             int 21h
             jmp load_msg

display_hz   proc near

             sti
             pushf
             push cx
             push si
             push di
             mov cx,16

display:     movsw
             add di,4eh
             loop display

             pop di
             pop si
             pop cx
             popf
             ret

display_hz   endp

asc2qwm     proc near

            push ax
            push bx
            push cx
            push dx
            push si

          ;  mov si,offset message
            mov word ptr ax,[si]
            xchg ah,al                  ; 将区码和位码交换,AH是区码,AL是位码

            sub ax,0a1a1h               ; 将机内码转换成区位码
          ;  and ax,7f7fh
          ;  sub ax,2121h
            mov byte ptr [hz_q],ah
            mov byte ptr [hz_w],al

            xor ax,ax
            mov ax,[hz_q]
            mov dx,94
            mul dx
            push dx
            push ax
            xor ax,ax
            xor dx,dx
            mov ax,[hz_w]
            pop bx
            adc ax,bx

;            cmp dx,0
;            jz no_add

            mov dx,32
            mul dx
            pop cx                       ;pop high, cx
            mov word ptr [hzk_ip],ax
            add dx,cx
            mov word ptr [hzk_ip+2],dx

            pop si
            pop dx
            pop cx
            pop bx
            pop ax
            ret

asc2qwm     endp

hz2buf     proc near

           push ax
           push bx
           push cx
           push dx
           
;           mov ax,3d00h
;           mov dx,offset hzk_file
;           int 21h
;           jc error
;           mov word ptr [file_handle],ax

           mov ax,4200h
           mov bx,[file_handle]
           mov cx,[hzk_ip+2]
           mov dx,[hzk_ip]
           int 21h
           jc read_err

           mov ah,3fh                     
           mov bx,[file_handle]
           mov cx,32
           mov dx,offset hzk_buf
           int 21h
           jc read_err

;           mov ah,3eh
;           mov bx,[file_handle]
;           int 21h

           pop dx
           pop cx
           pop bx
           pop ax
           ret

read_err:  mov ah,3eh
           mov bx,[file_handle]
           int 21h

error:     mov ah,09
           mov dx,offset err_msg
           int 21h
           mov ax,4c01h
           int 21h

hz2buf     endp

set_gb     proc near

           push ax
           push bx
           push cx
           push dx

           mov ah,03h
           mov bh,[crt_emm]
           int 10h

           add dl,2
           cmp dl,80
           jc no_set
           inc dh
           xor dl,dl
no_set:    mov ah,02h
           int 10h

           pop dx
           pop cx
           pop bx
           pop ax
           ret

set_gb     endp

set_ram    proc near

           push ax
           push bx
           push cx
           push dx

           mov ah,03h
           mov bh,[crt_emm]
           int 10h
           
           mov cx,dx
           mov bx,80*16
           xor ax,ax
           mov al,ch
           mul bx
           push ax          ; X
           xor ax,ax
           mov al,cl
           pop bx
           add ax,bx
           mov word ptr [ram_add],ax

           pop dx
           pop cx
           pop bx
           pop ax
           ret

set_ram    endp

wait_user  proc near

           push ax
           push bx
           push cx
           push dx

           mov ah,03h
           mov bh,[crt_emm]
           int 10h
           
           cmp dh,29
           jnz no_change

           xor ah,ah
           int 16h

           mov ax,0600h
           mov bh,70h
           mov cx,0
           mov dx,2c4fh
           int 10h

           mov ah,02h
           mov bh,[crt_emm]
           xor dx,dx
           int 10h

no_change: pop dx
           pop cx
           pop bx
           pop ax
           ret

wait_user  endp

cseg ends
     
     end begin


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//