main proc far
PUSH DX
sub AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV AH,0 ;設置顯示器模式
MOV al,02h ;40*25,16色文本模式
INT 10h
MOV AH,09h ;顯示操作說明字符
MOV DX,seg string
MOV ds,DX
MOV DX,offset string
INT 21h
lea DI,mess ;di指向字符圖形表
MOV DH,5 ;從第5行第5列位置開始
MOV DL,0 ;從第五行第五列開始顯示名字
call string_display ;調用字體顯示程序
RET
main endp
DATE PROC NEAR ;顯示日期子程序
MOV AH,2AH ;取系統日期,入口參數:AH=2AH,出口參數:CX=年(1980~2099),
;DH=月(1~12),DL=日(1~31),AL=星期幾(0=Sunday,1=Monday,...)
INT 21H
MOV SI,0
MOV AX,CX ;取年份
MOV BX,100
DIV BL
MOV BL,AH
CALL BCDASC1 ;日期數值轉換成相應的ASCII碼字符
MOV AL,BL
CALL BCDASC1
INC SI
MOV AL,DH
CALL BCDASC1
INC SI
MOV AL,DL
CALL BCDASC1
MOV BP,OFFSET DBUFFER1
MOV DH,23
MOV DL,20
MOV CX,20
MOV BX,000FH
MOV AH,13H ;顯示字符串
MOV AL,01H
INT 10H
MOV BX,0018H
REPEA: MOV CX,0FFFFH ;延時
Aa:
LOOP Aa
DEC BX
JNZ REPEA
RET
DATE ENDP
TIME PROC NEAR ;顯示時間子程序
MOV SI,0
MOV BX,100
DIV BL
MOV AH,2CH ;取系統時間 CH:CL=時:分,DH:DL=秒:1/100秒
INT 21H
MOV AL,CH ;把時轉換
CALL BCDASC ;將時間數值轉換成ASCII碼字符
INC SI
MOV AL,CL ;把分轉換
CALL BCDASC
INC SI
MOV AL,DH ;把秒轉換
CALL BCDASC
MOV BP,OFFSET DBUFFER
MOV DH,23
mov DL,40
MOV CX,20
MOV BH,00H
MOV BL,0FH
MOV AH,13H ;顯示字符串
MOV AL,01H
INT 10H
MOV BX,0018H ;做延時
RE: MOV CX,0FFFFH
REA: LOOP REA ;循環
DEC BX
JNZ RE ;是不是壹秒的循環?
RET
TIME ENDP
BCDASC PROC NEAR ;時間數值轉換成ASCII碼字符子程序
PUSH BX
CBW
MOV BL,10
DIV BL
ADD AL,'0'
MOV DBUFFER[SI],AL
INC SI
ADD AH,'0'
MOV DBUFFER[SI],AH
INC SI
POP BX
RET
BCDASC ENDP
BCDASC1 PROC NEAR ;日期數值轉換成ASCII碼字符子程序
PUSH BX
CBW
MOV BL,10
DIV BL
ADD AL,'0'
MOV DBUFFER1[SI],AL
INC SI
ADD AH,'0'
MOV DBUFFER1[SI],AH
INC SI
POP BX
RET
BCDASC1 ENDP
string_display proc near ;字體顯示子程序(主要的程序)
PUSH AX
PUSH bx
PUSH CX
PUSH DX
PUSH DI
sub CH,CH ;清除寄存器CX的高字節
MOV CL,[DI] ;CL放循環次數,也就是字符個數
INC DI ;di指向字符表的第壹個字符
MOV char_cnt,CX ;保存循環次數
MOV pointer,DI ;保存第壹個字符的偏移地址
MOV line_on,DH ;保存顯示的起始行5
MOV col_on,DL ;保存顯示的起始列0
plot_next:
ADD DH,[DI+2] ;改變相對行指針
ADD DL,[DI+3] ;改變列指針取下壹個列數
CMP DL,250 ;出屏否?
jMP con_display ;沒有出屏,則繼續顯示
call re_display ;出了屏幕則調用重新顯示程序
POP DI
POP DX
POP CX
POP BX
POP AX
RET
con_display:
MOV AH,2 ;移動光標位置
INT 10h
MOV al,[DI]
MOV BL,[DI+1] ;取字符值及屬性
PUSH AX
CMP RED,1
JNZ YELLOW2
XOR BL,23H
YELLOW2:
CMP YELLOW,1
JNZ BLUE2
XOR BL,11H
BLUE2:
CMP BLUE,1
JNZ GOON
XOR BL,6FH
GOON:
POP AX
PUSH CX
MOV CX,1
MOV AH,09 ;顯示字符
INT 10h
POP CX
ADD DI,4 ;di指向下壹個字符及其屬性,行列
LOOP plot_next ;循環顯示完所有的字符後
call delay ;調用延時以及按鍵子程序
Call date
call time ;先在窗口顯示時間
CMP flag,1
JNZ KEEP
call music
KEEP:call re_display ;調用重新顯示子程序
JMP SHORT plot_next
RET
string_display endp
re_display proc near ;重新顯示子程序
MOV CX,char_cnt
MOV DI,pointer
MOV DH,line_on
MOV DL,col_on
re_display_next:
ADD DH,[DI+2] ;取行/列值
ADD DL,[DI+3]
MOV AH,2 ;先確定光標位置
INT 10h
MOV al,[DI]
MOV BL,0
PUSH CX
MOV CX,1
MOV AH,9 ;再在當前光標處顯示字符
INT 10h
POP CX
ADD DI,4
loop re_display_next ;把所有字符都顯示完畢
MOV CX,char_cnt ;重新保存各項參數
MOV DI,pointer
MOV DH,line_on
INC col_on
MOV DL,col_on
RET
re_display endp
delay proc near ;延時子程序以及鍵盤掃描
PUSH CX
PUSH DX
MOV DX,DATA2
CMP INCLEASE,1
JNZ DECLE
ADD DX,1000
MOV DATA2,DX ;保存上壹次的值
DECLE:
CMP DECLEASE,1
JNZ d11
SUB DX,1000
d11:MOV CX,8000
d12:LOOP d12
DEC DX
JNZ d11
POP DX
POP CX
MOV AH,06H ;讀取鍵盤
XOR AL,AL
CMP MUSIC1,1
JNZ GO2
MOV DL,0
MOV RED,DL ;還原功能,先把所有標誌位清零
MOV YELLOW,DL
MOV BLUE,DL
GO2: MOV DL,0FFH
INT 21H
CMP AL,'R' ;變成紅色
JNZ A
MOV RED,1
A: CMP AL,'Y' ;改變成黃色
JNZ B
MOV YELLOW,1
B: CMP AL,'B' ;改變成藍色
JNZ AC
MOV BLUE,1
AC: CMP AL,'A' ;移動加速
JNZ D
MOV INCLEASE,1
D: CMP AL,'D' ;移動減速
JNZ M
MOV DECLEASE,1
M: CMP AL,'M' ;播放音樂,還原顏色按鍵
JNZ Q
PUSH AX
INC MUSIC1
MOV BH,2
MOV AX,MUSIC1
DIV BH
CMP AH,0
JZ flag_value ;整除就跳轉
MOV flag,0
flag_value:
MOV flag,1
POP AX
Q: CMP AL,'Q'
JNZ go
MOV AH,4CH
INT 21H
go: RET
delay ENDP
GENSOUND PROC near
PUSH AX ;先保存各個寄存器
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV AL, 0B6H ;8253通道地址
OUT 43H, AL
MOV DX, 12H
MOV AX, 533H*896
DIV DI
OUT 42H, AL
MOV AL, AH
OUT 42H, AL
IN AL, 61H
OR AL, 3
OUT 61H, AL
WAIT1: MOV CX, 700
DE: LOOP DE
DEC BX
JNZ WAIT1
MOV AL, AH
OUT 61H, AL
POP DI
POP DX
POP CX
POP BX
POP AX
RET
GENSOUND ENDP
MUSIC PROC NEAR
PUSH DS
PUSH DX
PUSH CX
PUSH BX
PUSH AX
CMP flag,1
JZ KEEP_ON
RET
KEEP_ON: MOV AX, DATA
MOV DS, AX
LEA SI, MUS_FREQ
LEA BP, DS: MUS_TIME
FREQ: MOV DI, [SI]
CMP DI, -1
JE END_MUS
MOV BX, DS: [BP]
CALL GENSOUND
ADD SI, 2
ADD BP, 2
JMP FREQ
END_MUS:
POP AX
POP BX
POP CX
POP DX
POP DS
RET
MUSIC ENDP
code ENDS
END main