【正文】
rA EQU 0e800h AddrB EQU 0e801h AddrC EQU 0e802h AddrCTL EQU 0e803h CAT DB 6 DUP(0) 。Store input note char。Keys code ARRAY DB 11100111B,11101011B,11101101B,11101110B DB 11010111B,11011011B,11011101B,11011110B DB 10110111B,10111011B,10111101B,10111110B DB 01110111B,01111011B,01111101B,01111110B 。Char code 0~9 NUM DB 0EDH,21H,0F4H,0F1H,39H 。0~5 DB 0D9H,0DDH,61H,0FDH,0F9H 。6~9 。Count number LOU DB 0,122,108,97,91,81,72,64 MID DB 0,61,54,48,45,40,36,32 HIG DB 0,30,27,24,22,20,18,16 DATA ENDS 。STACK SEGMENT STACK 39。STACK39。 DB 100 DUP(0)STACK ENDS 。CODE SEGMENT ASSUME DS:DATA,CS:CODE,SS:STACK 。 。DELAY FOR 1MSDELAY1MS PROC PUSH CX MOV CX,50OUTER: PUSH CX MOV CX,4000INNER: LOOP INNER POP CX LOOP OUTER POP CX RETDELAY1MS ENDP 。 。SHOW NUM ON CATsSHOW MACRO X,Y PUSH AX PUSH DX MOV AL,X MOV DX,AddrB OUT DX,AL MOV AL,Y MOV DX,AddrA OUT DX,AL POP DX POP AXENDM 。 SCAN PROC PUSH SI MOV SI,Offset CAT SHOW 01H,[SI] CALL DELAY1MS SHOW 02H,[SI+1] CALL DELAY1MS SHOW 04H,[SI+2] CALL DELAY1MS SHOW 08H,[SI+3] CALL DELAY1MS SHOW 10H,[SI+4] CALL DELAY1MS SHOW 20H,[SI+5] CALL DELAY1MS POP SI RETSCAN ENDP MAIN PROC FAR MOV AX,DATA MOV DS,AX MOV ES,AX MOV DX,0E823H 。Initialize 8253A MOV AL,16H OUT DX,ALCLEAR:XOR DX,DX 。Record how many digits has been stored MOV CX,6 MOV AL,0 XOR SI,SILOPC: MOV CAT[SI],AL 。Clear all CAT value INC SI LOOP LOPCNEXT: CALL SCAN 。Display notes, can display 6 a time CALL READ 。Read key state CMP AL,0FFH 。No Key pressed ? JE NEXT 。Key pressed! CLD 。Set DF direction: DI + 1 DI MOV CX,16 MOV DI,OFFSET ARRAY REPNZ SCASB 。Search array to find key code CMP CX,0 JE NFD 。Usually this is not going to 。happen, except sth wrong MOV BX,OFFSET ARRAY SUB DI,BX DEC DI CMP DI,7 。Is the key 0~7? JBE ISNUM 。Key A and B not defined, 。reserve for future use. CMP DI,12 JE CLEAR 。Key C means clear all input digits CMP DI,14 JE EXIT 。Key E means Exit the program. JMP NEXT ISNUM: PUSH DX MOV DX,0E8E0H IN AL,DX AND AL,03H CMP AL,01H JE PLOU CMP AL,02H JE PHIG JMP PMIDPLOU: MOV AL,LOU[DI] PUSH AX 。MOV AL,8CH MOV CAT[1],8CH POP AX JMP PPHIG: 。ADD DI,14 MOV AL,HIG[DI] MOV CAT[1],3DH 。SUB DI,14 JMP PPMID: 。 ADD DI,7 MOV AL,MID[DI] MOV CAT[1],0 。 SUB DI,7P: MOV DX,0E820H 。Counter 0 OUT DX,AL 。Write counter 0 , music on POP DXAGN: CALL READ 。Key pressed! push AX CALL SCAN MOV AL,NUM[DI] MOV CAT[0],AL pop ax CMP AL,0FFH 。Has the key been released? JNE AGN 。No:wait until it is released。 PUSH DX 。Yes:begin to judge the key. MOV DX,0E820H XOR AL,AL OUT DX,AL POP DX 。MOV AL,NUM[DI] 。MOV SI,DX 。MOV CAT[SI],AL 。Store the input number to memory. 。INC DX CALL SCAN 。CMP DX,6 。JE CLEAR2 JMP NEXTNFD: NOP 。Unknown state, terminate the program.EXIT:MOV AX,4C00H INT 21HCLEAR2: JMP CLEARMAIN ENDP 。READ PROC NEAR PUSH DX MOV DX,0E803H MOV AL,81H OUT DX,AL MOV AL,00H MOV DX,0E802H OUT DX,AL IN AL,DX 。Read Row info MOV BL,AL MOV DX,0E803H MOV AL,88H OUT DX,AL MOV AL,00H MOV DX,0E802H OUT DX,AL IN AL,DX 。Read Colum info OR AL,BL 。Keep info in AL for SCASB POP DX RET READ ENDP。 CODE ENDS END MAIN五、實(shí)驗(yàn)總結(jié) 本次實(shí)驗(yàn)綜合了前兩次實(shí)驗(yàn)所有學(xué)習(xí)到的東西,我了解并熟悉了實(shí)驗(yàn)臺(tái)的結(jié)構(gòu)、功能、使用方法;掌握8253計(jì)數(shù)器和定時(shí)器運(yùn)用的基本方法;熟練掌握Debug及編寫(xiě)匯編程序。 本次實(shí)驗(yàn)中的代碼,編寫(xiě)后不斷修改,到最后定稿,經(jīng)歷了多個(gè)版本。在對(duì)每一個(gè)版本改進(jìn)的過(guò)程中,我都逐漸加深了對(duì)匯編語(yǔ)言的理解,鍛煉了匯編編程及應(yīng)用的能力。并且還了解了很多多關(guān)于音樂(lè)的知識(shí),如:音符頻率、蜂鳴器電路結(jié)構(gòu)等等。 本次實(shí)驗(yàn)也是本學(xué)期最后一次實(shí)驗(yàn),也是我們學(xué)到的最多的一次實(shí)驗(yàn)。通過(guò)本學(xué)期的三次實(shí)驗(yàn),我們對(duì)了解更多微機(jī)知識(shí),通過(guò)動(dòng)手操作也學(xué)會(huì)了平常課堂上面所學(xué)不到的種種知識(shí)。36