📄 98_hzk_gb2312_v1.1_2004.11.12.asm
字号:
;╔━┅━┅━┅━┅━┅━┅━┅━┅━━┅━┅━┅━┅━┅━┅━ ╗
;┃≡TYPEGB of HZK V1.0 -----powered by BlasterKai! ≡ ┃
;┃ - ¤╭⌒╮ ╭⌒╮ ┃
;┃ ╱◥██◣ ╭ ⌒ ┃
;┃ |田︱田田| ╰---------一切都精彩-------缘自Buaa!! ┃
;┃︵﹏~︵﹏~︵﹏~︵﹏~︵﹏~︵ ┃
;╚┅━┅━┅━┅━┅━┅━┅━┅━┅━┅━┅━┅━┅━┅━┅━ ╝
;----------------------------------------------------------------
; ╭═══════════════╮
; ║ TYPEGB of HZK V1.0 ║
; ╭══════┤ -powered by BlasterKai! ├═════╮
; ║ ║ --2004.10.31 ║ ║
; ║ ╰═══════════════╯ ║
; ║ ★ 汇编语言 (研究型大作业)★ ║
; ║ |---------------------------------------------| ║
; ║ 3. 在VGA 12h模式下,在屏幕上显示汉字,字库源于UCDOS中的 ║
; ║CCLIB或24X24字库。并让其支持字型转置。 ║
; ║ ║
; ║ ║
; ║ 算法简述 ║
; ║ ----------------------- ║
; ║ ;调用 21号中断的a号功能,读入文件名及路径信息 ║
; ║ ;再读入字型转置方式,默认为正常显示 ║
; ║ ;打开所读文件 ║
; ║ ;读当前光标的位置 ║
; ║ ;从待显示的文件中读取两个字节 ║
; ║ ;测试文件是否结束当为0时,表示EOF ║
; ║ ;计算在CCLIB中的偏移量 qh=c1-0xa0 wh=c2-0xa0 ║
; ║ ;从CCLIB中读入16*16的点阵,32个字节 ║
; ║ ;依据字型转置方式来输出汉字 ║
; ║ ;屏幕满时开始上滚一行 ║
; ║ ;用来显示一些非汉字字符,即ASCII字符 ║
; ║ ;错误处理程序 ║
; ║ ;显示汉字子程序 ║
; ║ ║
; ║ ║
; ║ ╭──────────────────────╮ ║
; ╰══┤ ★★★ Made in Buaa ★★★ ├══╯
; ╰──────────────────────╯
;━┅━┅━┅━┅━┅━┅━┅━┅━━┅━┅━┅━┅━┅━┅━┅━
;TypeGB of HZK v1.1 ---2004.11.12
; update: 1。汉字显示过程得到精简。 2。真正实现30行一滚屏,并有滚屏提示信息
;----------------------------------------------------------------
.model small
.stack 100h
.data
inputfilename db 'Please input the file path and name : ','$'
maxlen db 32
actlen db ?
filename db 32 DUP(?)
inputmodel db 'Please input the model(normal,left,right,iverse) : ','$'
model db 'n'
file_cclib db 'hzk16',0
handle_cclib dw ? ; CCLIB 文件句柄
buffer_cclib db 32 DUP(?),'$'
handle_read dw ? ;读取文件句柄
buffer_read dw ?
linex dw ?
liney dw ?
msg_screenfull db 'Press any key to continue ...','$'
msg_goonscroll db ' ','$'
scrollnum db 27
msg_open_cclib_error db 'Could not find HZK16!','$'
msg_open_read_error db 'There is no such file!','$'
msg_read_cclib_error db 'HZK16 read wrong!','$'
msg_read_read_error db 'File read wrong!','$'
.code
;;*****************************************************************************************************************
main proc far
mov ax,@data
mov ds,ax
;;;;;;;;;;;;;;;;;;;;;;;;;;;
lea dx,inputfilename ;调用 21号中断的a号功能,读入文件名及路径信息
mov ah,9
INT 21h
mov dx,offset maxlen
mov ah,0ah
INT 21h
mov si,offset filename
mov bl,actlen
xor bh,bh
add si,bx
xor bx,bx
mov [si],bx
mov dl,0ah ;输出一个回车符
mov ah,2
INT 21h
lea dx,inputmodel ;再读入字型转置方式,默认为正常显示
mov ah,9
INT 21h
mov ah,1
INT 21h
mov model,al
mov dl,10 ;输出一个回车符
mov ah,2
INT 21h
;;*************************************************************************
open_file:
lea dx,filename ;打开所读文件
mov al,0
mov ah,3dh
INT 21h
jc open_read_error
mov handle_read,ax ;保存文件句柄
lea dx,file_cclib ;打开CCLIB
mov al,0
mov ah,3dh
INT 21h
jc open_cclib_error
mov handle_cclib,ax ;保存字库句柄
;;***************************************************
mov bh,0h ;读当前光标的位置
mov ah,3h
INT 10h
mov ax,16 ;保存光标位置,按象素点的行列保存
mul dh
;mov linex,0
mov linex,ax
mov liney,0
mov al,12h ;设置显示模式为640*480,16色模式
mov ah,0h
INT 10h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 读取并显示一个汉字,并循环
getword_file: ;从待显示的文件中读取两个字节
mov bx,handle_read ;INT 21H 42号功能移动文件指针
mov cx,0
mov dx,0h
mov al,1 ;移动方式,从当前位置开始移动
mov ah,42h
INT 21h
;上面的好像有点多余
mov bx,handle_read ;读文件,INT 21H,3F号功能
mov cx,1 ;只读取一个字节
lea dx,buffer_read ;保存位置
mov ah,3fh
INT 21h
jc read_read_error
;;;;;;;;;;;;;;;
test ax,0ffffh ;测试文件是否结束,AX中为实际写入的字节数,当为0时,表示EOF
jz done
;;;;;;;;;;;;;;;
mov ax,buffer_read ;判断读到的字符是否为ACSII字符,是则用INT 21H号中断显示
cmp al,0a0h
jb print_ansi_char
;;;;;;;;;;;;;;;;
mov bx,handle_read ;若为汉字,则再读取一个字节,并保存之后
mov cx,1
lea dx,buffer_read+1
mov ah,3fh
INT 21h
jc read_read_error
;***************************************************************
count_offset: ;计算在CCLIB中的偏移量 qh=c1-0xa0 wh=c2-0xa0
;;;;;;;;;;;;;;;;;;;;;; ;该汉字在字库中离起点的位置是: offset=(94*(qh-1)+(wh-1))*32L
mov bx,buffer_read
sub bh,0a0h
sub bl,0a0h
dec bh
dec bl
xor ax,ax
mov al,bl
mov cl,94 ;此时不会溢出
mul cl
xor cx,cx
mov cl,bh
add ax,cx
mov cx,32
mul cx
;mov buffer_read,ax ;结果保存在DX+AX中,可再写入buffer_read
;;****************************************************************
read_cclib: ;从CCLIB中读入16*16的点阵,32个字节,并保存在buffer_cclib中
mov bx,handle_cclib
mov cx,dx ;count_offset计算所得偏移量保存在DX:AX中,现在放入CX:DX中,42号功能
mov dx,ax
mov al,0 ;从文件头开始读取,与待显示的文件指针移动方式不同
mov ah,42h
INT 21h
mov bx,handle_cclib
mov cx,32 ;32个字节
lea dx,buffer_cclib
mov ah,3fh
INT 21h
jc read_cclib_error
;;************************************************************** ;依据字型转置方式来输出汉字
mov bh,model
mov bl,bh
cmp bl,'l'
jz isleft
mov bl,bh
cmp bl,'r'
jz isright
mov bl,bh
cmp bl,'i'
jz isreverse
call print_normal
jmp change
isleft:
call print_left
jmp change
isright:
call print_right
jmp change
isreverse:
call print_reverse
jmp change
;;****************************************************************************
change: ;屏幕满时开始上滚一行
cmp linex,448
jae reset_x
jmp changerow
reset_x:
inc scrollnum
cmp scrollnum,28
je fullscreen
jmp goonscroll
;;;;;;;;;;;;;;;;;; ;换页功能
fullscreen: ;可用来在最下端提示按键换页,实现
mov dh,29
mov dl,0
mov ah,2
INT 10h
lea dx,msg_screenfull ;最下端换页信息
mov ah,9
INT 21h
mov ah,00h ;按键但不回显,并且上滚20行
INT 16h ;用DOS 21--8号功能可能出现按一次键滚两屏的现象,用BIOS16号则不会有???
mov scrollnum,0
mov dh,29 ;删除换页提示信息
mov dl,0
mov ah,2
INT 10h
lea dx,msg_goonscroll ;
mov ah,9
INT 21h
;;;;;;;;;;;;;;
goonscroll: ;滚屏
mov al,1
mov ah,6h
xor cx,cx
mov dh,28
mov dl,80
mov bh,0
INT 10h
sub linex,16 ;恢复到上一行
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;换行
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -