📄 alarm_clock.asm
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;A SIMPLE ALARM CLOCK: ;;
;; DISPLAY CURENT TIME,REMAIN TIME ON THE TOP-RIGHT ;;
;; PRESS 'S' TO START THE ALARM CLOCK,AND 'P' TO STOP IT ;;
;; WHEN REMAIN TIME IS OVER,PLAY SOUND AND DISPLAY ALERT MESSAGE ;;
;; DONE BY FXFX ;;
;; 07-06-21 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CODES SEGMENT
ASSUME CS:CODES,DS:CODES
ORG 100H
START:
MOV AX,CODES
MOV DS,AX
LEA DX,MSG
MOV AH,09H
INT 21H
MOV REMAIN_TIME,15H ;INITIAL REMAIN TIME
MOV STOP,01H ;INITIAL STOP
;------------------------------------------
;SAVE OLD INT1CH
;------------------------------------------
XOR AX,AX
MOV ES,AX
MOV AX,WORD PTR ES:[1CH*4]
MOV WORD PTR CS:OLD_INT1CH,AX
MOV AX,WORD PTR ES:[1CH*4+2]
MOV WORD PTR CS:OLD_INT1CH+2,AX
;------------------------------------------
;SAVE OLD INT9H
;------------------------------------------
XOR AX,AX
MOV ES,AX
MOV AX,WORD PTR ES:[9H*4]
MOV WORD PTR CS:OLD_INT9H,AX
MOV AX,WORD PTR ES:[9H*4+2]
MOV WORD PTR CS:OLD_INT9H+2,AX
;------------------------------------------
;SET NEW INT1CH
;------------------------------------------
XOR AX,AX
MOV ES,AX
MOV AX,OFFSET NEW_INT1CH
MOV WORD PTR ES:[1CH*4],AX
MOV WORD PTR ES:[1CH*4+2],CS
;------------------------------------------
;SET NEW INT9H
;------------------------------------------
XOR AX,AX
MOV ES,AX
MOV AX,OFFSET NEW_INT9H
MOV WORD PTR ES:[9H*4],AX
MOV WORD PTR ES:[9H*4+2],CS
;------------------------------------------
;驻留
;------------------------------------------
MOV DX,OFFSET NEW_INT1CH
INT 27H
;------------------------------------------
;NEW_INT1CH
;------------------------------------------
NEW_INT1CH PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
PUSHF
STI
PUSH CS ;LET DS BE CS
POP DS
CALL DWORD PTR CS:OLD_INT1CH
;------------------------------------------
;SAVE CURRENT CURSOR
;------------------------------------------
MOV AH,3H
MOV BH,0H
INT 10H
MOV CURRENT_CURSOR,DX
;------------------------------------------
;SET CURSOR TO TOP-RIGHT
;------------------------------------------
MOV AH,02H
MOV BH,0H
MOV DX,0048H
INT 10H
;------------------------------------------
;GET TIME
;------------------------------------------
MOV AH,02H
INT 1AH
;------------------------------------------
;DISPLAY HOUR
;------------------------------------------
MOV TIME_H,CH
CALL CONVT_ASC_AND_DISPLAY
MOV BH,0H
MOV AH,0EH
MOV AL,':'
INT 10H
;------------------------------------------
;DISPLAY MINUTE
;------------------------------------------
MOV TIME_H,CL
CALL CONVT_ASC_AND_DISPLAY
MOV AL,':'
INT 10H
;------------------------------------------
;DISPLAY SECOND AND DEAL WITH REMAIN_TIME
;------------------------------------------
MOV TIME_H,DH
CALL CONVT_ASC_AND_DISPLAY
MOV AH,STOP ;CHECK WHETHER STOP
CMP AH,01H
JZ NEXT
CMP SECOND,DH ;IF SECOND HASEN'T CHANGED,SKIP
JZ NEXT
MOV SECOND,DH ;SAVE CURRENT SECOND FOR NEXT CHECK
CMP REMAIN_TIME,0H
JNZ DECREASE ;IF REMAIN_TIME>0 THEN DEC
CALL REMINDER ;IF REMAIN_TIME=0 THEN SKIP DEC
JMP NEXT
DECREASE:
MOV AH,REMAIN_TIME ;IF REMAIN_TIME=X0 THEN REMAIN_TIME-6
AND AH,00001111B
CMP AH,00000000B
JNZ DEC_1
SUB REMAIN_TIME,6H
DEC_1:
DEC REMAIN_TIME
;------------------------------------------
;SET CURSOR TO NEXT LINE AND DISPLAY REMAIN_TIME
;------------------------------------------
MOV AH,2H
MOV BH,0H
MOV DX,0148H
INT 10H
XOR DX,DX ;CONVERT REMAIN_TIME TO ASCII
MOV DH,REMAIN_TIME
MOV CL,4H
ROL DX,CL
SHR DH,CL
ADD DH,30H
ADD DL,30H
MOV BH,0H ;DISPLAY
MOV AL,DL
MOV AH,0EH
INT 10H
MOV AL,DH
INT 10H
MOV AL,'S'
INT 10H
;------------------------------------------
;SET BACK CURRENT CURSOR
;------------------------------------------
NEXT:
MOV AH,2H
MOV BH,0H
MOV DX,CURRENT_CURSOR
INT 10H
CLI
POP ES
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
IRET
NEW_INT1CH ENDP
;------------------------------------------
;CONVT_ASC_AND_DISPLAY:ACCEPT ORINGIN TIME IN TIME_H
;------------------------------------------
CONVT_ASC_AND_DISPLAY PROC NEAR
PUSH CX
PUSH BX
PUSH AX
PUSHF
;------------------------------------------
;CONVERT TO ASCII
;------------------------------------------
XOR BX,BX
MOV TIME_L,BH
MOV BH,TIME_H
MOV CL,4H
ROL BX,CL
SHR BH,CL
ADD BH,30H
ADD BL,30H
MOV TIME_H,BH
MOV TIME_L,BL
;------------------------------------------
;DISPLAY
;------------------------------------------
MOV BH,0H
MOV AH,0EH
MOV AL,TIME_L
INT 10H
MOV AL,TIME_H
INT 10H
POPF
POP AX
POP BX
POP CX
RET
CONVT_ASC_AND_DISPLAY ENDP
;------------------------------------------
;NEW_INT9H
;------------------------------------------
NEW_INT9H PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
PUSHF
STI
PUSH CS
POP DS
CALL DWORD PTR CS:OLD_INT9H
MOV AH,1H ;READ KEY
INT 16H
MOV AH,1H
INT 16H
CMP AL,'s' ;WHETHER START
JNZ CMP_P
MOV STOP,02H
CMP_P:
CMP AL,'p' ;WHETHER PAUSE
JNZ NEXT_INT9H
MOV STOP,01H
NEXT_INT9H:
CLI
POP ES
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
IRET
NEW_INT9H ENDP
;------------------------------------------
;REMINDER:BEEP AND DISPLAY MSG
;------------------------------------------
REMINDER PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
PUSHF
;------------------------------------------
;DISPLAY MSG
;------------------------------------------
MOV AX,1303H
MOV CH,0H
MOV CL,MSG_LEN
SUB CL,9H
MOV BH,00H
MOV DX,0246H ;POSITION
MOV BP,SEG MSG_TIME
MOV ES,BP
MOV BP,OFFSET MSG_TIME
INT 10H
;------------------------------------------
;BEEP
;------------------------------------------
MOV AL,00B6H
OUT 43H,AL
MOV DX,12H
MOV AX,348CH
LEA SI,FREQ_TABLE
SET_FRC:
MOV DI,[SI]
CMP DI,-1H
JE END_PLAY
CALL PLAY_ONE_SOUND
ADD SI,2H
JMP SET_FRC
END_PLAY:
POPF
POP ES
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
RET
REMINDER ENDP
;------------------------------------------
;PLAY_ONE_SOUND: ACCEPT FRC IN DI
;------------------------------------------
PLAY_ONE_SOUND PROC NEAR
DIV DI
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
IN AL,61H
MOV AH,AL
OR AL,3
OUT 61H,AL ;SOUND START
MOV BEEP_TIME,6H ;300MS EACH SOUND
CALL DELAY_LONG
MOV AL,AH ;SOUND END
OUT 61H,AL
RET
PLAY_ONE_SOUND ENDP
;------------------------------------------
;DELAY_100MS
;------------------------------------------
DELAY_100MS PROC NEAR
PUSH AX
PUSH CX
MOV CX,6330d ;100MS=15.08US*6330
WAIT1:
IN AL,61H ;CHECK PB4
AND AL,10H
CMP AL,AH
JE WAIT1
MOV AH,AL ;SEVE PB4
LOOP WAIT1
POP CX
POP AX
RET
DELAY_100MS ENDP
;------------------------------------------
;DELAY_LONG:ACCEPT HOW MANY 100MS IN BEEP_TIME
;------------------------------------------
DELAY_LONG PROC NEAR
PUSH BX
MOV BL,BEEP_TIME
BACK:
CALL DELAY_100MS
DEC BL
JNZ BACK
POP BX
RET
DELAY_LONG ENDP
;------------------------------------------
;DATA_SEG
;------------------------------------------
CURRENT_CURSOR DW ? ;SAVE CURSOR POSITION
SECOND DB ? ;SAVE CURRENT SECONDS FOR NEXT CHECK
STOP DB ? ;1-STOP 2-GO
REMAIN_TIME DB ?
BEEP_TIME DB ?
TIME_H DB ?
TIME_L DB ?
OLD_INT9H DD ?
OLD_INT1CH DD ?
MSG DB 'PRESS s(LOWER CASE) TO START,PRESS p(LOWER CASE) TO PAUSE.',13,10,'$'
MSG_TIME DB 'TEIEMEEE EOEVEEERE!'
MSG_LEN DB $ - MSG_TIME
REMAIN DB 'REMAIM:','$'
FREQ_TABLE dw 262,294,330,262,262,294,330,262,-1
CODES ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -