assume cs:code
code segment
setup: mov ax,cs ;将主程序写入磁盘2扇区
mov es,ax
calc: mov ax,offset zhuc-offset n_in9ok
mov dx,0
mov bx,512
div bx
cmp dx,0
jne adal
jmp short set
adal: inc al ;计算出需要的扇区数
set: mov bx,offset zhuc
mov ah,3 ;写入
mov ch,0 ;磁道号
mov cl,2 ;扇区号
mov dh,0 ;磁头号(面号)
mov dl,0 ;没有软盘,能否写到81h ;驱动器号(D盘)
int 13h
mov bx,offset lead ;将引导程序写入磁盘1扇区
mov al,1
mov ah,3 ;写入
mov ch,0 ;磁道号
mov cl,1 ;扇区号
mov dh,0 ;磁头号(面号)
mov dl,0 ;没有软盘,能否写到81h ;驱动器号(D盘)
int 13h
lead: mov ax,0 ;程序引导部分 ,负责将主程序写入到引导程序之后的内存
mov es,ax
mov ax,offset zhuc-offset n_in9ok ;根据主程序长度计算al
mov dx,0
mov bx,512
div bx
cmp dx,0
jne ada2
jmp short set1
ada2: inc al
set1: mov bx,offset zhuc-offset lead ;
add bx,7c00h
mov ah,2 ;读盘
mov ch,0 ;磁道号
mov cl,2 ;扇区号
mov dh,0 ;磁头号(面号)
mov dl,0 ;没有软盘,能否用D盘
int 13h
zhuc: jmp short start
stack segment
db 64 dup (0)
stack ends
start: mov ax,stack
mov ss,ax
mov sp,64
jmp short s
d1 db '1)reset pc',0
d2 db '2)start system',0
d3 db '3)clock',0
d4 db '4)set clock',0
d5 dw x1,x2,x3,x4
d6 db 'Esc)return',0
d7 db 'F1 )change colors',0
d8 db 'time setting error',0
s: mov ax,cs ;显示选项
mov ds,ax
mov ax,0b800h
mov es,ax
mov di,0
mov cx,2000
sq: mov byte ptr es:[di],' ' ;清屏
inc di
mov byte ptr es:[di],7
inc di
loop sq
mov si,offset d1
mov dh,10
mov dl,33
mov bl,7
call show
mov si,offset d2
inc dh
call show
mov si,offset d3
inc dh
call show
mov si,offset d4
inc dh
call show
s1: mov ah,0 ;等待输入
int 16h
cmp al,31h
jb s1
cmp al,34h
ja s1
mov bl,al ;直接定址
sub bl,31h
mov bh,0
add bx,bx
jmp cs:d5[bx]
x1: mov ax,0ffffh
push ax
mov ax,0
push ax
mov bp,sp
jmp dword ptr ss:[bp]
x2: mov ax,0
mov es,ax
mov bx,200h
mov al,1
mov ah,2 ;读盘
mov ch,0 ;磁道号
mov cl,1 ;扇区号
mov dh,0 ;磁头号(面号)
mov dl,80h ;c盘
int 13h
push bx
push es
mov bx,sp
jmp dword ptr ss:[bx]
x3: mov si,offset d3
mov dh,12
mov dl,33
mov bh,0
mov bl,es:[1]
or bl,00001000b
call show ; 使第三选项高亮
mov si,offset d6
mov dh,1
mov dl,60
mov bl,es:[1]
call show ;增加Esc提示
mov si,offset d7
inc dh
call show ;增加F1提示
x3a: in al,60h
cmp al,81h
je x3b ;回到初始
cmp al,3bh
je x31 ;跳至变色
call tm
mov si,offset td2
mov dh,24
mov dl,60
mov bh,1 ; bh不等于0时,不设置颜色属性
call show
jmp short x3
x3b: mov al,0
out 60h,al
jmp near ptr s
x31: mov ax,0b800h
out 60h,al ;很重要,调零60h端口的数值(这个设置到底有什么用还不太清楚,只知道不设置的话按F1就乱变色)
mov es,ax
mov di,1
mov cx,2000
cmp byte ptr es:[di],1
je x33
x32: dec byte ptr es:[di]
add di,2
loop x32
jmp near ptr x3a
x33: mov byte ptr es:[di],7
add di,2
loop x33
jmp near ptr x3a
x4: mov ax,0
mov es,ax
mov di,208h
push es:[9h*4+2]
push es:[9h*4]
pop es:[200h]
pop es:[200h+2]
mov word ptr es:[204h],0ffh
mov word ptr es:[206h],0ffh
mov ax,cs
mov ds,ax
mov si,offset n_in9
mov cx,offset n_in9ok-offset n_in9
cld
rep movsb
cli
mov word ptr es:[9h*4],208h
mov word ptr es:[9h*4+2],0
sti
mov si,offset d4 ; 修改时间主程序
mov ax,0b800h
mov es,ax
mov dh,13
mov dl,33
mov bh,0
mov bl,es:[1]
or bl,00001000b
call show ; 使第四选项高亮
mov byte ptr cs:td2[20],0
jmp short x4s
x4d3 dw tent,tz,ty,tesc,tz,ty
x4s: call tm ;查询时间
x4t: call tbm ;比对时间,并保存到td3
mov si,offset td3
mov dh,24
mov dl,60
mov bh,1 ; bh不等于0时,不设置颜色属性
call show
mov di,0f77h;设置查询首地址
call cw ;查亮度所对应的字符串位置(假如没有高亮位设置bl=0),保存到bl(38)
call zz ;BL位时间高亮,自动往后跳过非数字位,保存bl(38)
mov ax,0
mov es,ax
cmp byte ptr es:[204h],0ffh
jne x4x ;数字键程序
cmp byte ptr es:[206h],0ffh
jne x4g ;功能键程序
mov bh,1
jmp short x4t
x4x: mov di,0f77h
call cw
call tn
call ty
call zz
mov bh,1
jmp short x4t
x4g: mov bl,es:[206h]
add bl,bl
mov bh,0
mov byte ptr es:[206h],0ffh
call x4d3[bx]
mov bh,1
jmp short x4t
tent: mov ax,0
mov es,ax
mov byte ptr es:[206h],0ffh
push es:[200h+2]
push es:[200h]
pop es:[9h*4]
pop es:[9h*4+2]
mov al,0
out 60h,al
mov ax,0b800h
mov es,ax
mov di,1
mov cx,2000
tenq: mov byte ptr es:[di],7
add di,2
loop tenq
jmp near ptr x3
tz: mov di,0f77h
mov ax,0b800h
mov es,ax
call cw
cmp bx,0
je tz1
tz2: sub bx,2
cmp byte ptr es:[di+bx-1],30h
jb tz2
cmp byte ptr es:[di+bx-1],39h
ja tz2
call zz
ret
tz1: mov bx,36
call zz
ret
ty: mov di,0f77h
call cw
cmp bx,36
je ty1
add bx,2
call zz
ret
ty1: mov bx,0
call zz
ret
tesc: mov ax,0
mov es,ax
mov byte ptr es:[206h],0ffh
push es:[200h+2]
push es:[200h]
pop es:[9h*4]
pop es:[9h*4+2]
mov al,0
out 60h,al
jmp near ptr s
tm: push bx ; 查询并保存时间子程序 (直接循环显示时间没法应用中断,应在主程序设置条件循环)
push si
push cx
push ax
push di
jmp short ti
td1 db 9,8,7,4,2,0
td2 db '20yy/mm/dd hh:mm:ss',0,0
td3 db '20yy/mm/dd hh:mm:ss',0,0
ti: mov di,0
mov si,2
mov cx,6
tii: push cx
mov al,cs:td1[di]
out 70h,al
in al,71h
mov ah,al
mov cl,4
shr al,cl
and ah,00001111b
add ax,3030h
mov word ptr cs:td2[si],ax
cmp byte ptr cs:td2[20],0
jne tiii
mov word ptr cs:td3[si],ax
tiii: inc di
add si,3
pop cx
loop tii
pop di
pop ax
pop cx
pop si
pop bx
ret
tbm: push bx ;
push si
push cx
push ax
push di
mov si,18
tbii: mov al,0
out 70h,al
in al,71h
mov ah,al
mov cl,4
shr al,cl
and ah,00001111b
add ax,3030h
cmp byte ptr cs:td2[si],ah
jne tbiii
jmp short tbme
tbiii: mov byte ptr cs:td2[20],1
call tm
cmp td3[si],39h
jne jia
mov td3[si],30h
dec si
cmp td3[si],35h
jne jia
mov td3[si],30h
dec si
dec si
cmp td3[si],39h
jne jia
mov td3[si],30h
dec si
cmp td3[si],35h
jne jia
mov td3[si],30h
dec si
dec si
cmp word ptr td3[si-1],3332h
je jia0
cmp byte ptr td3[si],39h
jne jia
mov td3[si],30h
dec si
inc td3[si]
jmp short tbme
jia0: mov word ptr td3[si-1],3030h
call luna
jmp short tbme
jia: inc td3[si]
tbme: pop di
pop ax
pop cx
pop si
pop bx
ret
show: push ax ; 显示以0结尾的字符串程序 dx=行列 cs:[si]=字符串起点 bl=颜色 bh不等于0时 不设置颜色
push di
push cx
push si
push dx
mov ax,0b800h
mov es,ax
mov ax,160
mul dh
add dl,dl
sub dl,2
mov dh,0
add ax,dx
mov di,ax
sh1: mov cl,cs:[si]
jcxz sh2
mov es:[di],cl
inc di
cmp bh,0
jne sh_nc
mov es:[di],bl
sh_nc: inc si
inc di
jmp short sh1
sh2: pop dx
pop si
pop cx
pop di
pop ax
ret
cw: push ax ; 查亮度子程序(cw),保存至bl?, 参数:es:[di] 为查询字符串的首地址
push es
push cx
mov bx,0b800h
mov es,bx
mov bx,0
mov cx,19
c1: mov al,es:[di+bx]
and al,00001000b
cmp al,00001000b
je c2
add bx,2
loop c1
mov bx,0
c2: pop cx
pop es
pop ax
ret
zz: push bp ;高亮时间子程序,bl为高亮位,能自动跳过非数字位。参数:di为时间首地址
push ax
push cx
mov ax,0b800h
mov es,ax
mov bp,0
mov cx,19
z1: and byte ptr es:[di][bp],11110111b
add bp,2
loop z1
cmp byte ptr es:[di+bx-1],30h
jb z3
cmp byte ptr es:[di+bx-1],39h
ja z3
z2: or byte ptr es:[di][bx],00001000b
pop cx
pop ax
pop bp
ret
z3: add bx,2
jmp z2
tn: push ax ; 时间修改程序
push bx
mov bp,sp ;保存栈位置
push word ptr cs:td3[5]
push word ptr cs:td3[8]
push word ptr cs:td3[11]
push word ptr cs:td3[14]
push word ptr cs:td3[17]
mov ax,bx
mov bl,2
div bl
mov bh,0
mov bl,al
mov al,es:[204h]
tng: mov cs:td3[bx],al
push ax
push bx
mov bl,10
mov di,5
mov cx,5
tngs: sub word ptr cs:td3[di],3030h
add di,3
loop tngs
mov cx,5
mov di,5
tngs1: mov al,td3[di]
mul bl
add al,cs:td3[di+1]
mov td3[di],al
add di,3
loop tngs1
mov ax,0b800h
mov es,ax
mov di,0e36h
mov cx,20
tngx: mov byte ptr es:[di],' '
add di,2
loop tngx
call ttest
pop bx
pop ax
pop word ptr cs:td3[17]
pop word ptr cs:td3[14]
pop word ptr cs:td3[11]
pop word ptr cs:td3[8]
pop word ptr cs:td3[5]
mov cs:td3[bx],al
tne: mov ax,0
mov es,ax
mov word ptr es:[204h],0ffh
mov sp,bp
pop bx
pop ax
ret
ttest: cmp byte ptr cs:td3[5],12 ;看月份是否大于12
ja tns
cmp byte ptr cs:td3[8],31 ;看日期是否大于31
ja tns
cmp byte ptr cs:td3[5],2 ;看月份是否2月
je ttest1
mov si,0
mov cx,4
jmp short ttxiao
monn db 4,6,9,11
ttxiao: mov al,cs:monn[si] ;看月份是否小月
cmp byte ptr cs:td3[5],al
je ttest2
add si,2
loop ttxiao
cmp byte ptr cs:td3[11],23
ja tns
cmp byte ptr cs:td3[14],59
ja tns
cmp byte ptr cs:td3[17],59
ja tns
ret
ttest1: call runnian
cmp cs:td3[20],0 ;看是否闰年
je ttest1_1
cmp byte ptr cs:td3[8],28 ;看日期是否大于28
ja tns
ret
ttest1_1: cmp byte ptr cs:td3[8],29;看日期是否大于29
ja tns
ret
ttest2: cmp byte ptr cs:td3[8],30 ;看日期是否大于30
ja tns
ret
tns: mov si,offset d8
mov dh,22
mov dl,60
mov bh,1
call show
pop ax ; 多一个Pop 因为是跳到这里来的 栈里存了原ip
pop bx
pop ax
pop word ptr cs:td3[17]
pop word ptr cs:td3[14]
pop word ptr cs:td3[11]
pop word ptr cs:td3[8]
pop word ptr cs:td3[5]
jmp near ptr tne
tn1: push ax ; 时间修改程序
push bx
mov ax,bx
mov bl,2
div bl
mov bh,0
mov bl,al
mov al,es:[204h]
mov word ptr es:[204h],0ffh
mov cs:td3[bx],al
pop bx
pop ax
ret
luna: jmp short lunas
mon dw 3430h,3630h,3930h,3131h
lunas: mov cx,4
mov bp,3133h ;设置成31号
mov si,0
cmp_m: mov ax,cs:mon[si]
cmp word ptr cs:td3[5],ax ; 看是不是小月
je xiaoyue
add si,2
loop cmp_m
cmp word ptr cs:td3[5],3230h ; 看是不是2月
je eryue
jmp short dayue
xiaoyue: mov bp,3033h ;设置成30号
jmp short dayue
eryue: call runnian ;查是不是闰年,闰年余数保存在cs:td3[20]
cmp cs:td3[20],0
je eryue1
mov bp,3832h
jmp short dayue
eryue1: mov bp,3932h
dayue: cmp word ptr cs:td3[8],bp ;看是多少号
je dayue_1
cmp byte ptr cs:td3[9],39h ;看是不是9号
je dayue_2
inc byte ptr cs:td3[9]
ret
dayue_1: mov word ptr cs:td3[8],3130h ;是月底号就改成1号
cmp word ptr cs:td3[5],3231h ; 看是不是12月
je dayue12
cmp byte ptr cs:td3[6],39h ; 看是不是9月
je dayue11
inc byte ptr cs:td3[6]
ret
dayue_2: inc byte ptr cs:td3[8] ; 因为前一位不是3,所以是9让前一位加1
mov byte ptr cs:td3[9],30h ; 然后自己变成0
ret
dayue11: mov word ptr cs:td3[5],3031h ;是9月就改成10月
ret
dayue12: mov word ptr cs:td3[5],3130h ; 是12月就改成1月
cmp byte ptr cs:td3[3],39h ; 看是不是第9年
je dayue13
inc byte ptr cs:td3[3]
ret
dayue13: mov byte ptr cs:td3[3],30h ; 是第9年就改成0年
cmp byte ptr cs:td3[2],39h ; 看是不是第9年
je dayue14
inc byte ptr cs:td3[2]
ret
dayue14: mov byte ptr cs:td3[2],30h ; 是第9年就改成0年
cmp byte ptr cs:td3[1],39h ; 看是不是第9年
je dayue15
inc byte ptr cs:td3[1]
ret
dayue15: mov byte ptr cs:td3[1],30h ; 是第9年就改成0年
cmp byte ptr cs:td3[0],39h ; 看是不是第9年
je dayue16
inc byte ptr cs:td3[0]
ret
dayue16: mov byte ptr cs:td3[0],30h ; 是第9年就改成0年
ret
runnian: push ax ;闰年查询子程序 ,余数存入cs:td3[20]
push bx
push dx
push word ptr cs:td3[0]
push word ptr cs:td3[2]
sub word ptr cs:td3[0],3030h
sub word ptr cs:td3[2],3030h
mov al,cs:td3[2]
mov bl,10
mul bl
add al,cs:td3[3]
mov cs:td3[2],al ;46
mov cs:td3[3],0
mov al,cs:td3[1]
mov bl,100
mul bl
add word ptr cs:td3[2],ax
mov al,cs:td3[0]
mov ah,0
mov bx,1000
mul bx
add ax,word ptr cs:td3[2]
mov bx,4
mov dx,0
div bx
mov cs:td3[20],dl
pop word ptr cs:td3[2]
pop word ptr cs:td3[0]
pop dx
pop bx
pop ax
ret
n_in9: ;待安装的int9中断例程 ,功能是比对是否制定的按键,并存入数据段内存的指定区域
push ax
push bx
push cx
push si
push di
in al,60h
pushf
call dword ptr cs:[200h]
jmp short n
ind1 db 2,3,4,5,6,7,8,9,0ah,0bh
ind2 db 1ch,4bh,4dh,1,0eh,0fh
n: mov si,offset ind1-offset n_in9
mov di,offset ind2-offset n_in9
mov cx,10
mov bx,0
n1: cmp al,cs:[si+208h][bx]
je in16
inc bx
loop n1
mov bx,0
mov cx,6
n2: cmp al,cs:[di+208h][bx]
je gnj
inc bx
loop n2
jmp short n_end ;不是上列按键即返回
in16: cmp al,0bh
je in16_2
add al,2fh
in16_1: mov cs:[204h],al ;数字键转换ASCII码后存入205
jmp short n_end
in16_2: add al,25h
jmp short in16_1
gnj: ;功能键参数保存到1
mov cs:[206h],bl ; (4)位
n_end: pop di
pop si
pop cx
pop bx
pop ax
iret
n_in9ok: nop
code ends
end setup