⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alarm_clock.asm

📁 汇编课的作业
💻 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 + -