;菜单显示:A)press 1,clear screen
; B)press 2,set foreground color
; C)press 3,set background color
; D)press 4,roll up one line
; E)press F1,back to menu
;功能号: 0清屏,1置前景色,2置背景色,3向上翻动一行,F1返回菜单
;对应扫描码: 0bh 2 3 4 3bh
;寻table值: 0 1 2 3 4
assume cs:code
stack segment
db128 dup (0)
stack ends
code segment
s1: db 'A)press 0,clear screen','$'
s2: db 'B)press 1,set foreground color','$'
s3: db 'C)press 2,set background color','$'
s4: db 'D)press 4,roll up one line','$'
s5: db 'E)press F1,back to menu','$'
s : dw offset s1,offset s2,offset s3,offsets4,offset s5
row:db 10,12,14,16
start:call show
;**********************************************
mov ax,stack
mov ss,ax
mov sp,128
push cs
pop ds
mov ax,0
mov es,ax
mov si,offset int9
mov di,204h
mov cx,offset int9end-offset int9
cld
rep movsb
push es:[9*4]
pop es:[200h]
push es:[9*4+2]
pop es:[202h]
cli
mov word ptr es:[9*4],204h
mov word ptr es:[9*4+2],0
sti
mov ax,4c00h
int 21h
int9:push ax
push bx
push cx
push es
jmp short set
;利用功能号查找地址表的方法,便于扩充,
;如果加入一个新功能子程序,只需要在地址表中加入它的入口地址即可
table dwsub1-int9+204h,sub2-int9+204h,sub3-int9+204h,sub4-int9+204h,show2-int9+204h
set:in al,60h ;从60H号端口读出键盘输入
pushf
call dword ptr cs:[200h] ;调用原来的int9
mov ah,al ;读入的扫描码送入ah
cmp ah,3bh ;F1的扫描码
jnenext1
sub ah,37h
jmpshort next3
next1:cmp ah,0bh ;0的扫描码
jne next2
sub ah,0bh ;0的扫描码-0bh=0
jmpshort next3
next2:sub ah,1 ;功能号为1,2,3,则将扫描码减去1即可
next3:mov al,02h ;颜色属性
cmp ah,4
jasret
movbl,ah
movbh,0
addbx,bx
callword ptr cs:[20ah+bx]
sret:pop es
pop cx
pop bx
pop ax
iret
;*****************************************************************************************
sub1:push bx ;清屏
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,0
mov cx,2000
sub1s:mov byte ptr es:[bx],' '
mov byte ptr es:[bx+1],0
add bx,2
loop sub1s
pop es
pop cx
pop bx
ret
sub2: push bx ;置前景色
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,1
mov cx,2000
sub2s:and byte ptr es:[bx],11111000b
or es:[bx],al
add bx,2
loop sub2s
pop es
pop cx
pop bx
ret
sub3:push bx ;置背景色
push cx
push es
mov cl,4
shl al,cl
mov bx,0b800h
mov es,bx
mov bx,1
mov cx,2000
sub3s:and byte ptr es:[bx],10001111b
or es:[bx],al
add bx,2
loop sub3s
pop es
pop cx
pop bx
ret
sub4: push cx ;向上滚动一行
push si
push di
push es
push ds
mov si,0b800h
mov es,si
mov ds,si
mov si,160
mov di,0
cld
mov cx,24
sub4s:push cx
mov cx,160
rep movsb
pop cx
loop sub4s
mov cx,80
mov si,0
sub4s1:mov byte ptr [160*24+si],' '
add si,2
loop sub4s1
pop ds
pop es
pop di
pop si
pop cx
ret
;******************************************************************************************
show2:push ax ;返回,先清屏,再显示菜单
push es
push bx
push cx
push ds
push si
push di
jmp show2s
db'A)press 0,clear screen '
db'B)press 1,set foreground color'
db'C)press 2,set background color' ;30个字符一行
db'D)press 4,roll up one line '
db'E)press F1,back to menu '
show2s: mov ax,0b800h ;清屏
mov es,ax
mov bx,0
mov cx,2000
clear_s: mov byte ptr es:[bx],' '
mov byte ptr es:[bx+1],0
add bx,2
loop clear_s
mov ax,0b800h ;显示菜单
mov es,ax
mov bx,160*10
mov di,20*2
movax,cs
mov ds,ax
movsi,offset show2-int9+204h+0ah
mov cx,5
show2s0:push cx
movcx,30
show2s1:mov al,ds:[si]
mov es:[bx+di],al
mov byte ptr es:[bx+di+1],02h ;菜单置为绿色
incsi
adddi,2
loopshow2s1
popcx
movdi,20*2
addbx,160*2
loopshow2s0
pop di
pop si
pop ds
pop cx
pop bx
pop es
pop ax
ret
;******************************************************************************************
int9end:nop
;名称:show
;功能:菜单显示
;参数:
show:push ax
push bx
push cx
push dx
mov ax,cs
mov ds,ax
mov bx,offset s
mov si,offset row
mov cx,5
ok:mov bh,0
mov dh,[si] ;行号
mov dl,20 ;列号
mov ah,2 ;10号中断例程的2号子程序:功能为置光标
int 10h
mov dx,[bx]
mov ah,9 ;21号中断例程的9号子程序:功能为在光标位置显示字符串,不含颜色参数
int 21h
inc si
add bx,2
loop ok
pop dx
pop cx
pop bx
pop ax
ret
code ends
end start