The document contains code for an 8085 microprocessor. It includes routines for resetting the system, beeping, storing display messages, and handling interrupts. Upon startup it performs self-tests on ROM and RAM and initializes registers before entering a monitoring loop that waits for and decodes key inputs.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0 ratings0% found this document useful (0 votes)
126 views26 pages
ROM Assembly Listing
The document contains code for an 8085 microprocessor. It includes routines for resetting the system, beeping, storing display messages, and handling interrupts. Upon startup it performs self-tests on ROM and RAM and initializes registers before entering a monitoring loop that waits for and decodes key inputs.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 26
.
CR 8085 .TF 5036A.BIN,BIN .LF 5036A
RESET: MVI H,$08 ;PAGE ADRS OF WRITE TEST RAM
MOV A,M ;TEST RAM CELL DATA CMA ;COMPLEMENT IT MOV M,A ;STORE IT BCK IN RAM JMP STRT ;TO CONTINUE ; ;RS1 IS MAIN ENTRY POINT TO MONITOR ; RS1: SHLD TSAVH ;SAVE USER HL CONTENTS IN RAM OUT $10 ;UNPROTECT RAM JMP TRP ;CONTINUE ; ;BEEP PRODUCES A FIXED TONE FREQ + DURATION ; BEEP: MVI B,FREQ ;DEFAULT FREQUENCY BEEP1: MVI D,DURA ;DEFAULT DURATION JMP BEEP2 ;CONTINUE NOP ; ;STDM STORES DISP MESSAGE AT DE ADRS IN UDSP RAM ; STDM: PUSH B LXI H,UDSP0 ;ADRS OF UNDECODED DISPLAY DIGIT 0 JMP SDM ;CONTINUE NOP RS4: JMP RS4C ;USER ROUTINE NOP TRAP: JMP RS1 ;SAV USER REGS+RETURN TO MONITOR NOP RS5: JMP RS5C ;USER ROUTINE NOP RS55: JMP RS55C ;USER ROUTINE NOP RS6: JMP RS6C ;USER ROUTINE NOP RS65: JMP RS65C ;USER ROUTINE NOP RS7: JMP STRT6 ;RETURN TO MONITOR NOP RS75: RST 2 ;BEEP JMP SATL1 ;SA TEST LOOP ; ;POWER-UP SELF TEST AND INITIALIZE ; STRT: CMP M ;SEE IF DATA IS STORED IN RAM JNZ PPER ;IF RAM WAS INITIALIZED (RUN MODE) LXI SP,MSP ;INITIALIZE MONITOR SP XRA A ;CLEAR A MOV H,A ;CLEAR H FIRST ADRS MOV L,A ;CLEAR L OR ROM OUT LOUT ;TURN ON OUTPUT LEDS ; ;ROM SELF TEST ; STRT1: ADD M ;ADD ROM DATA TO A INX H ;POINT TO NEXT ROM ADRS MOV C,A ;SAVE A RESIDUE IN C MVI A,$08 ;LAST ADRS OF ROM+1 (MSBYTE) CMP H ;COMPARE IT TO H MOV A,C ;RESTORE RESIDUE TO A JNZ STRT1 ;IF LAST ROM ADRS NOT 0800 DCX H ;PONT HL TO 07FF CHECKSUM VALUE SUB M ;SUSTRACT CHECKSUM FOR A RESIDUE CMP M ;COMPARE RESIDUE TO CHECKSUM MVI B,$04 ;IC 4 (ROM) MESSAGE JNZ MERR1 ;IF NOT A MATCH ; ;RAM SELF TEST ; XRA A ;CLEAR A LXI H,$0800 ;1ST RAM ADDR MVI B,$03 ;ADD CONSTANT STRT2: MOV M,A ;STORE DATA IN RAM ADD B ;ADD 3 TO A INX H ;POINT TO NEXT RAM ADRS MOV C,A ;SAVE A MOV A,H ;GET MSBYTE ADRS CPI $0C ;LAST RAM ADRS+1 MOV A,C ;RESTORE A JNZ STRT2 ;IF NOT LAST RAM ADRS XRA A ;CLEAR A LXI H,$0800 ;1ST RAM ADRS STRT3: CMP M ;DID DATA GET STORED IN RAM? JNZ MERR ;IF DATA NOT SAME CMA MOV M,A ;STORE COMPLEMENT BACK IN RAM CMP M ;DID IT STORE? JNZ MERR ;IF NOT CMA ;UNCOMPLEMENT A ADD B ;ADD 3 TO A INX H ;NEXT RAM ADDR MOV C,A ;SAVE A MOV A,H ;GET MSBYTE ADRS CPI $0C ;LAST RAM ADRS+1 MOV A,C ;RESTORE A JNZ STRT3 ;TO CHECK NEXT RAM LOCATION ; ;DISPLAY TEST ; MVI B,$00 ;CLEAR LOOP COUNTER STRT4: LXI D,ALL ;DISPLAY MESSAGE POINTER ALL SEGS RST 3 ;GET MESSAGE CALL DCD ;UPDATE DISPLAY DCR B ;DECR LOOP COUNTER JNZ STRT4 ;IF NOT DONE ; ;CLEAR RAM (STORE 00 IN ALL LOCATIONS) ; MVI B,$00 ;CLEAR B MVI A,$0C ;MSBYTE ADRS OF TOP OF RAM+1 LXI H,$0800 ;1ST ADRS OF RAM STRT5: MOV M,B ;CLEAR RAM LOCATION INX H ;POINT TO NEXT LOCATION CMP H ;TO LAST RAM ADRS+1 JNZ STRT5 ;IF NOT DONE CLEARING RAM MVI A,$FF ;SET A TO ALL ONES OUT LOUT ;TURN OF OUTPUT LEDS STRT6: RST 2 ;SIGNAL START-UP DONE ; ; INITIALIZE REGISTERS ; LXI H,USP ;USER SP DEFAULT VALUE SHLD SAVSL ;STORE IT IN RAM LXI H,RS ;RUN STATUS WORD ADRS MVI M,$00 ;SET STATUS TO MONITOR MVI A,DIM ;DEFAULT INTERRUPT MASK STA SAVIM ;STORE IT IN RAM STRT7: LXI H,PC ;DEFAULT PC SHLD SAVPC ;STORE IT IN RAM MVI A,$FF ;RST7 INSTR CODE STA TPR ;STORE IT IN TOP OF PROTECTED RAM STA UR ;STORE IT IN UPPER RAM BELOW LINKS JMP TRP3 ;JUMP TO MONITOR ; ;PUSH-POP ERROR ROUTINE ; PPER: LXI SP,MSP ;SET MONITOR SP LXI H,PC ;DEFAULT PC SHLD SAVPC ;STORE IT IN RAM RST 2 ;SIGNAL AN ERROR XRA A ;CLEAR A STA RS ;SET RUN STATUS TO MONITOR LXI D,PPM ;PUSH-POP ERROR MESSAGE ADRS JMP TRP4 ; ;MEMORY ERROR SORT ; MERR: MVI B,$06 ;IC6 RAM FAIL MESSAGE XRA M ;GET DIFFERENCE INTO A ANI $0F ;TEST 4LSB'S OF IC6 JZ MERR1 ;IF PROBLEM IN IC6 DCR B ;SET B TO IC5 MERR1: LXI D,ICX ;ICX MESSAGE ADRS RST 3 ;GET MESSAGE LXI H,UDSP2 ;ADRS OF ICX IN UDSP RAM MOV M,B ;STORE IC NUMBER IN UDSP2 MERR2: CALL DCD ;DISPLAY MESSAGE JMP MERR2 ;LOOP MESSAGE ; ;RS1 IS MAIN ENTRY POINT TO MONITOR ; TRP: LXI H,$0000 ;CLEAR H,L JNC TRP1 ;NO USER CARRY WILL BYPASS DCXH DCX H ;SET H,L TO FF IF CARRY PRESENT TRP1: DAD SP ;GET SP VALUE INTO HL, RESTORE CY JNC TRP2 ;IF JNC TO TRP1 OCCURED INX H ;IF DCXH OCCURED BECAUSE OF CARRY TRP2: SHLD TSAVSP ;SAVE USER SP IN RAM LXI SP,TSAVSP ;TSAVA+1 ADRS PUSH PSW ;SAVE PSW AND A IN RAM LXI H,RS ;RUN STATUS ADRS XRA A ;CLEAR A CMP M ;FOR RUN STATUS=MONITOR STA UDSP6 ;CLEAR DATA MODIFY FLAG JNZ TRP6 ;IF CAME FROM USER PROGRAM TRP3: LXI D,DMT ;ULAB MESSAGE ADRS EI TRP4: MVI A,DIM ;DEFAULT INTERRUPT MASK SIM ;SET IT TO ENABLE RST7.5 ONLY OUT $10 ;UNPROTECT RAM RST 3 ;GET MESSAGE TRP5: CALL KIND ;INPUT KEYS CALL CFETA ;LOOK FOR ACCEPTABLE KEYS JMP TRP5 ;TRY AGAIN TRP6: MOV M,A ;STORE 0 IN RS TO SET MONITOR ; ;SAVE REGISTERS ; POP PSW ;FROM TSAVPSW IN RAM POP H ;GETS USER SP VALUE FROM RAM INX H ;USER SP INX H ;USER SP SHLD SAVSL ;SAVE SP IN RAM DCX H ;USER SP DCX H ;USER SP SPHL ;RESTORE SP POP H ;GET RETURN ADRS TO USER PROGRAM SHLD SAVPC ;STORE IT IN RAM LXI SP,$0BE8 ;ADRS OF SAVA+1 LHLD TSAVH ;RESTORE H,L PUSH PSW ;INTO SAVPSW PUSH B ;INTO SAVB PUSH D ;INTO SAVD PUSH H ;INTO SAVH RIM ;GET IM STA SAVIM ;STORE IT IN RAM TRP7: LXI SP,SAVPC ;POINT IT TO USER SP POP B ;AND POP IT IN BC LXI SP,MSP ;RESTORE MONITOR SP JMP FETA3 ; ;KEY INPUT AND DECODE ; KIND: PUSH D PUSH H KIND1: CALL DCD ;UPDATE DISPLAY AND WAIT CALL KPU ;CHK FOR PUSHED KEY JNZ KIND1 ;IF KEY STILL PUSHED KIND2: CALL DCD ;UDPATE DISP AND WAIT CALL KPU ;CHK FOR PUSHED KEY JZ KIND2 ;IF KEY NOT PUSHED LXI H,UDKY ;ADRS OF FIRST KEY ROW TO SCAN MVI D,$FF ;LOAD ROW COUNTER TO 0-1 KIND3: MOV A,M ;GET ROW N KEY DATA CPI $F7 ;IS IT THE HDWR STEP KEY? JZ KIND5 ;YES JUMPS CMA ;INVERT KEY DATA INR L ;NEXT ROW INR D ;NEXT TABLE BLOCK ANA A ;TEST ROW N FOR 0 JZ KIND3 ;JUMP IF KEY NOT PUSHED CPI $04 ;SEE IF D3=1 JNZ KIND4 ;IF SO DCR A ;ELSE SET A=3 KIND4: ADD D ;ADD 3X THE ROW N TO ADD D ;GET THE TABLE OFFSET ADD D MOV E,A ;STORE TABLE INDEX MVI D,$00 ;CLEAR MS BYTE OF DE LXI H,KIT-1 ;ADRS OF KEY CODE TABLE DAD D ;ADD INDEX TO TABLE ADRS MOV A,M ;PUT KEY CODE IN A KIND5: POP H POP D RET ; ;DETERMINES IF ANY KEY IS PUSHED ; KPU: PUSH B CALL KRD ;READ THE KEYBOARD MVI B,$08 ;SET THE LOOP COUNTER LXI H,UDKY ;ADDRESS OF UNDECODED KEY SCAN MVI A,$FF ;UNPUSHED KEY CODE KPU1: ANA M ;LET ANY PUSHED KEY CODE CHANGE A INR L ;NEXT RAM KEY ROW DCR B ;LOOP COUNTER JNZ KPU1 ;IF ALL KEY ROWS NOT ANDED WITH A CPI $FF ;SET FLAG IF ALL KEYS NOT PUSHED POP B RET ; ;READS KEYS AND STORES THEM IN RAM (UDKY) ; KRD: LXI H,UDKY ;ADRS OF UNDECODED KEY SCAN MVI A,$FF ;BLANK DISPLAY CODE OUT DSP ;CLEAR DISPLAY DCR A ;SET A TO 1111 1110 SCAN POINTER STC ;TO RESET END OF SCAN LOOP FLAG KRD1: OUT SCAN ;SCAN ONE KEY ROW MOV B,A ;SAVE SCAN POINTER IN KEY ;INPUT A KEY ROW MOV M,A ;STORE IT IN RAM MOV A,B ;RESTORE SCAN POINTER INR L ;POINT TO NEXT RAM ADRS RAL ;MOVE SCAN POINTER TO NEXT KEY ROW JC KRD1 ;IF LAW KEY ROW NOT SCANNED RET ; ;KEY INPUT DECODE TABLE (HDWR STEP IS F7) ; KIT: .DB $86 ;INSTR STEP KEY CODE .DB $85 ;FETCH PC KEY CODE .DB $00 ;(UNDEFINED) KEY CODE .DB $84 ;RUN KEY CODE .DB $80 ;FETCH REG KEY CODE .DB $82 ;FETCH ADRS KEY CODE .DB $00 ; 0 KEY CODE .DB $83 ;STORE/INCR KEY CODE .DB $81 ;DECR KEY CODE .DB $01 ; 1 KEY CODE .DB $02 ; 2 KEY CODE .DB $03 ; 3 KEY CODE .DB $04 ; 4 KEY CODE .DB $05 ; 5 KEY CODE .DB $06 ; 6 KEY CODE .DB $07 ; 7 KEY CODE .DB $08 ; 8 KEY CODE .DB $09 ; 9 KEY CODE .DB $0A ; A KEY CODE .DB $0B ; B KEY CODE .DB $0C ; C KEY CODE .DB $0D ; D KEY CODE .DB $0E ; E KEY CODE .DB $0F ; F KEY CODE ; ;SCAN DISPLAY SEGMENTS ; SDS: PUSH PSW PUSH H PUSH B LXI H,DDSP5 ;ADRS OF DECODED DISP DIGIT 5 MVI B,$20 ;DISP DIGIT 5 SCAN POINTER SDS1: XRA A ;CLEAR A OUT SCAN ;TURN DISP DIGIT OFF MOV A,M ;GET SEGMENT DATA OUT DSP ;STORE IT IN DSP LATCH MOV A,B ;GET SCAN DIGIT POINTER OUT SCAN ;TURN ON DISP DIGIT CALL DELA ;STRETCH DIGIT 1MS DCR L ;ADRS OF NEXT DIGIT IN RAM RAR ;GET SCAN DIGIT POINTER MOV B,A ;SAVE IT IN B JNC SDS1 ;IF NOT LAST SCANNED DIGIT (LSD) CMA ;SET A=FF BLANK DISP CODE OUT DSP ;TURN OFF DSP DIGITS POP B POP H POP PSW RET ; ;DISPLAY CHARACTER DECODER ; DCD: PUSH PSW PUSH B PUSH D PUSH H LXI B,DDSP0 ;DECODED DIGIT FIRST ADRS LXI D,UDSP0 ;UNDECODED DIGIT FIRST ADRS DCD1: LXI H,DCC ;DIPSLAY CODE CONVERTER TABLE ADRS LDAX D ;GET UNDECODED DATA FOR OFFSET PUSH D ;SAVE ITS ADRS MOV E,A ;TABLE OFFSET VALUE TO E MVI D,$00 ;CLEAR D DAD D ;ADD OFFSET VALUE TO DCC ADRS MOV A,M ;GET DECODED DATA FROM TABLE ADRS STAX B ;STORE IT IN DECODED RAM POP D ;RESTORE UDSPX ADRS INR E ;POINT TO NEXT UPSP ADRS INR C ;POINT TO NEXT DDSP ADRS JNZ DCD1 ;IF NOT LAST DIGIT LXI H,DDSP0 ;DECODED DIGIT 0 LDAX D ;UDSP6 DATA MODIFY FLAG ANA A ;CHECK FOR SET FLAG JZ DCD2 ;IF DATA NOT BEING MODIFIED MOV A,M ;GET DDSP0 DATA ANI $7F ;SET ITS DECIMAL POINT DISP BIT MOV M,A ;STORE IT IN DDSP0 DCD2: POP H ; POP D ; POP B ; POP PSW ; CALL SDS ;UDPATE DISPLAY RET ; ; ;DISPLAY CODE CONVERTER TABLE ; DCC: .DB $C0 ;0 .DB $F9 ;1 .DB $A4 ;2 .DB $B0 ;3 .DB $99 ;4 .DB $92 ;5 .DB $82 ;6 .DB $F8 ;7 .DB $80 ;8 .DB $90 ;9 .DB $88 ;A .DB $83 ;B .DB $C6 ;C .DB $A1 ;D .DB $86 ;E .DB $8E ;F .DB $FF ;BLANK .DB $89 ;H .DB $C7 ;L .DB $E3 ;U SMALL .DB $8C ;P .DB $A3 ;O .DB $C1 ;U LARGE .DB $F7 ;_ .DB $A7 ;C SMALL .DB $CF ;1 LEFT .DB $00 ;ALL SEGS .DB $AF ;R SMALL .DB $BF ;- ; ;STDM STORES DISP MESSAGE AT DE ADRS IN UDSP RAM ; SDM: MVI B,$06 ;LOOP COUNTER FOR 6 DISPLAY DIGITS SDM1: LDAX D ;DISPLAY CHARACTER MOV M,A ;STORE IT IN UPSPX IN RAM INR L ;NEXT UDSP ADRS INX D ;NEXT MESSAGE TABLE ADRS DCR B ;LOOP COUNTER JNZ SDM1 ;IF NOT LAST DIGIT POP B ; RET ; ;DISPLAY MESSAGE TABLES ; DMT: .DB $14 ;P .DB $16 ;U .DB $0B ;B .DB $0A ;A .DB $12 ;L .DB $13 ;U SMALL FETCH: .DB $10 ;SP .DB $10 ;SP .DB $17 ;_ .DB $17 ;_ .DB $17 ;_ .DB $17 ;_ MA: .DB $0A ;A .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP FLG: .DB $12 ;L .DB $0F ;F .DB $10 ;SP .DB $10 ;SP MB: .DB $0B ;B .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP MC: .DB $0C ;C .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP MD: .DB $0D ;D .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP ME: .DB $0E ;E .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP MH: .DB $11 ;H .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP ML: .DB $12 ;L .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP SPH: .DB $11 ;H .DB $14 ;P .DB $05 ;S .DB $10 ;SP SPL: .DB $12 ;L .DB $14 ;P .DB $05 ;S .DB $10 ;SP PCH: .DB $11 ;H .DB $0C ;C .DB $14 ;P .DB $10 ;SP PCL: .DB $12 ;L .DB $0C ;C .DB $14 ;P .DB $10 ;SP IM: .DB $19 ;I .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP ALL: .DB $1A ;ALL .DB $1A ;ALL .DB $1A ;ALL .DB $1A ;ALL .DB $1A ;ALL .DB $1A ;ALL ICX: .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP .DB $0C ;C .DB $01 ;I .DB $10 ;SP PPM: .DB $1B ;R SMALL .DB $0E ;E .DB $14 ;P .DB $05 ;S BLNKM: .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP .DB $10 ;SP ; ;BLANK THE DISPLAY ; BLNK: LXI D,BLNKM ;ADRS OF BLNAK MESSAGE TABLE RST 3 ;GET MESSAGE CALL DCD ;SEND TO DISPLAY RET ; ;CONTRL KEY JUMP TABLE ; CHDSS: CPI $F7 ;HARDWARE SINGLE STEP PUSHED? JZ HDSS ;HARDWARE SINGLE STEP ROUTINE CINSS: CPI $86 ;SOFTWARE SINGLE STEP PUSHED? JZ INSS ;SOFTWARE SINGLE STEP ROUTINE CRUN: CPI $84 ;RUN PUSHED? JZ RUN ;RUN ROUTINE CSTRM: CPI $83 ;STORE MEMORY PUSHED? JZ STRM ;STORE MEMORY ROUTINE CDCRM: CPI $81 ;DECREMENT MEMORY PUSHED? JZ DCRM ;DECREMENT MEMORY ROUTINE CFETA: CPI $82 ;FETCH ADRS PUSHED? JZ FETA ;FETCH ADRS ROUTINE CFETP: CPI $85 ;FETCH PROGRAM COUNTER PUSHED? JZ TRP7 ;FETCH PROGRAM COUNTER ROUTINE CFETR: CPI $80 ;FETCH REGISTER PUSHED? JZ FETR ;FETCH REGISTER ROUTINE RET ;IF NO LEGAL KEY WAS PUSHED CSTRR: CPI $83 ;STORE REGISTER PUSHED? JZ STRR ;STORE REGISTER ROUTINE CDCRR: CPI $81 ;DECREMENT REGISTER PUSHED? JZ DCRR ;DECREMENT REGISTER ROUTINE JMP CFETA ; ; ;FETCH REGISTER MODE ; FETR: POP H ;UNDO STACK CALL LXI H,MA ;A REG MESSAGE ADRS LXI B,SAVA ;ADRS OF USER A REG CONTENTS FETR1: DCX H ;6-2=4 CHARACTERS IN REG MESSAGE DCX H ; FETR2: SHLD RMP ;STORE IN REGISTER MESSAGE POINTER XCHG ;PUT MESSAGE ADRS IN DE RST 3 ;STORE MESSAGE IN RAM LDAX B ;USERS REG CONTENTS MOV E,A ;TRANSFER IT TO E LXI H,UDSP1 ;ADRS WHERE DISPLAY REG DATA GOES CALL FETA7 ;FORMAT REG BYTE DATA + STORE IT MVI A,$DB ;LS BYTE OF SAVIM ADRS CMP C ;IS REG EXAMINED THE INTRPT MASK? JZ FETR6 ;IF IT IS- HEX KEY INPUT NOT LEGAL FETR3: CALL KIND ;INPUT KEYS CALL CSTRR ;LOOK FOR CONTROL JNC FETR3 ;IF NOT A HEX KEY OR NEW CONTROL MOV E,A ;SAVE 1ST HEX KEY IN E INR L ;POINT TO UDSP1 MVI M,$00 ;CLEAR IT TO DISPLAY A 0 FETR4: DCR L ;POINT BACK TO UDSP0 MOV M,E ;STORE NEW HEX KEY THERE FETR5: CALL DPS ;TO SET DP AND INPUT KEYS CALL CSTRR ;LOOK FOR CONTROL JNC FETR5 ;IF NOT A HEX KEY OR NEW CONTROL INR L ;POINT TO UDSP1 MOV D,E ;PUT OLD NEX CHARACTER INTO D MOV E,A ;PUT NEW HEX CHARACTER INTO E MOV M,D ;STORE OLD HEX CHARACTER INTO DSP1 JMP FETR4 ;CONTINUE FETR6: CALL KIND ;INPUT KEYS AND UPDATE DISPLAY CALL CSTRR ;LOOK FOR CONTROL ONLY JMP FETR6 ;KEEP LOOKING ; ;DECIMAL POINT SET ; DPS: MVI A,$01 ;FLAG SET DATA STA UDSP6 ;SET DATA MODIFY FLAG CALL KIND ;GET ANOTHER KEY PUSH PSW ;SAVE KEY CODE XRA A ;CLEAR A STA UDSP6 ;CLEAR DATA MODIFY FLAG POP PSW ;RECOVER KEY CODE RET ; ;FETCH MEMORY ADDRESS ; FETA: POP D ;UNDO STACK CALL FETAR: LXI D,FETCH ;DISPLAY MESSAGE ADRS RST 3 ;STORE MESSAGE IN RAM MVI C,$04 ;ADRS DIGIT COUNTER FETA1: CALL KIND ;READ KEYS AND SCAN DISPLAY CALL CFETA ;LOOK FOR CONTROL JNC FETA1 ;IF NOT A HEX KEY OR NEW CONTROL LXI H,UDSP6 ;ADRS OF DISPLAY DIGIT 4+2 MOV B,A ;SAVE HEX KEY INPUT CPI $01 ;1 KEY PUSHED? JNZ NCTL ;IF NOT MVI A,$04 ;MS ADRS POSITION VALUE CMP C ;ADRS POSITION POINTER JNZ NCTL ;IF 1 KEY NOT MS ADRS BYTE JMP FETAR ;WAIT FOR ANOTHER KEY NCTL: MOV A,B ;RESTORE NON-1 KEY VALUE MVI B,$04 ;DISPLAY POSITION COUNTER FETA2: DCR L ;POINT TO DISP DIGIT ON RIGHT DCR L ;POINT TO DISP DIGIT ON RIGHT MOV D,M ;PUT THIS CHARACTER IN D INR L ;POINT TO DISP DIGIT ON LEFT MOV M,D ;STORE THE DIGIT SHIFTED 1 TO LEFT DCR B ;POSITION COUNTER JNZ FETA2 ;IF NOT DONE ENTERING ADRS MOV M,A ;KEY CODE TO DISP DIGIT ON LEFT DCR C ;DIGIT COUNTER JNZ FETA1 ;IF NOT DONE CALL FETA6 ;MERGE LS ADRS BYTE IN DISP TO A MOV C,A ;STORE MERGED BYTE IN C INR L ;POINT TO MS ADRS BYTE IN DISP CALL FETA6 ;MERGE IT IN A MOV B,A ;MERGE IT IN C FETA3: LXI H,UDSP5 ;ADRS OF DISP DIGIT 5 MOV E,B ;PUT MS ADRS BYTE IN E CALL FETA7 ;SEPARATE AND STORE IT IN RAM DCR L ;POINT TO UDSP3 MOV E,C ;SAVE LS ADRS BYTE CALL FETA7 ;SEPARATE AND STORE IT IN RAM DCR L ;POINT TO UDSP1 LDAX B ;GET DATA AT FETCH ADRS MOV E,A ;PUT IT IN E CALL FETA7 ;SEPARATE IT AND DISP IT AS DATA ; ;MODIFY THE DATA ; CALL KIND ;GET A KEY CALL CHDSS ;LOOK FOR ANY CONTROL KEY MOV E,A ;STORE HEX KEY IN E MOV M,A ;AND UDSP0 INR L ;POINT TO UDSP1 MVI M,$00 ;CLEAR IT FETA4: DCR L ;POINT TO UDSP0 MOV M,E ;STORE LATEST KEY ENTRY THERE FETA5: CALL DPS ;TO SET DP AND INPUT KEYS CALL CSTRM ;LOOK FOR CONTROL KEY JNC FETA5 ;IF NOT A VALID KEY INR L ;POINT TO UDSP1 MOV D,E ;LAST KEY ENTRY MOV E,A ;NEW KEY ENTRY MOV M,D ;LAST ENTRY SHIFTED TO UDSP1 JMP FETA4 ;UPDATE NEW KEY AND CONTINUE ; ;MERGES 2 HEX NUMBERS INTO A REG ; FETA6: MOV E,M ;LS HEX CHAR INX H ;POINT TO MS HEX CHAR MOV A,M ;MS HEX CHAR RLC ;MOVE IT TO 4 MS BITS IN A RLC ;AND CLEAR 4 LS BITS IN A RLC ; RLC ; ORA E ;MERGE MS AND LS HEX CHARS IN A RET ; ;SEPARATES 2 HEX CHARACTERS IN A + STORES IN M ; FETA7: MOV A,E ;PUT MERGED HEX CHARS INTO A RRC ;MOVE MS HEX CHAR TO 4 LS BITS A RRC ; RRC ; RRC ; MVI D,$0F ;MASK TO CLEAR 4 MS BITS ANA D ;DO IT MOV M,A ;STORE MS HEX CHAR DCR L ;LS CHAR DESTINATION ADRS MOV A,E ;GET MERGED HEX CHARS ANA D ;CLEAR MS HEX CHAR MOV M,A ;STORE LS HEX CHAR RET ; ;DECREMENTS MEMORY ADRS ; DCRM: DCX B ;POINT TO NEXT LOWER ADRS POP H ;UNDO STACK CALL JMP FETA3 ;TO FETCH NEW ADRS DATA ; ;STORES DATA IN MEM AND INCREMENTS ADRS ; STRM: POP D ;UNDO STACK CALL CALL FETA6 ;MERGE 2 HEX DATA VALUES INTO A MOV E,A ;SAVE IN E STAX B ;STORE DATA BYTE IN RAM ADRS IN B LDAX B ;READ IT BACK CMP E ;IS IT THE SAME? DID IT STORE? INX B ;POINT TO NEXT RAM ADRS JZ FETA3 ;FETCH NEW ADRS IF LAST STORE OK DCX B ;ELSE POINT BACK TO LAST RAM ADRS PUSH B ;SAVE THIS ADRS RST 2 ;BEEP A FAIL TO STORE ERROR POP B ;RESTORE RAM ADRS JMP FETA3 ;AND FETCH IT AGAIN ; ;RUNS THE PROGRAM STARTING AT ADRS IN DISPLAY ; RUN: LXI H,$0132 ;INSTR CODES FOR STA 01XX (RUN) RUN1: SHLD RAML1 ;JUMP LINK IN RAM LXI H,$C310 ;INSTR CODES OF 00 AND JMP XXXX SHLD RAML2 ;JUMP LINK IN RAM LXI SP,SAVIM ;USER PROG START ADRS LINK+1 PUSH B ;STORE USER START ADRS IN RAM LINK LXI H,SAVSH ;RAM ADRS OF MSBYTE MVI M,$0B ;MSBYTE USER SP DCX H ;RAM ADRS OF LSBYTE USER SP MOV A,M ;LSBYTE USER SP CPI $40 ;<= 40 JNC RUN2 ;IF AVAIL STACK SPACE MVI M,$B0 ;IF NOT, RESET POINTER RUN2: LXI SP,SAVE ;PREPARE TO RESTORE USER REGS POP D ;RESTORE D,E POP B ;RESTORE B,L POP PSW ;RESOTRE PSW,A LXI SP,SAVSL ;RAM ADRS OF USER SP POP H ;PUT SPH,L IN H,L SPHL ;TRANSFER SP VAL TO CPU SP LHLD SAVL ;RESTORE H,L JMP RAML1 ;LINK TO USER PROGRAM ; ;INSTRUCTION SINGLE STEP AND RETURN TO MONITOR ; INSS: LXI H,$0632 ;INSTR CODES FOR STA 06XX (INSS) JMP RUN1 ;SET LINKS,RESTORE REGS,USER PROG ; ;HARDWARE SINGLE STEP ONE LINE OF CODE ; HDSS: LXI H,$0332 ;INSTR CODES FOR STA 03XX (HDSS) JMP RUN1 ;SET LINKS,RESTORE REGS,USER PROG ; ;DECREMENTS REGISTER DISPLAYED ; DCRR: POP D ;UNDO STACK CALL INX B ;POINT TO LAST SAVX REG RAM ADRS LHLD RMP ;REGISTER MESSAGE POINTER DCX H ;SUBTRACT 2 FROM IT DCX H ; MVI A,$E8 ;LS BYTE OF SAVA+1 ADRS IN RAM CMP C ;SEE IF IT'S IM REG JNZ FETR1 ;FETCH NEW NON-IM REG+DISP IF NOT LXI B,SAVIM ;ADRS OF IM VALUE IN RAM LXI H,IM ;ADRS OF IM DISP MESSAGE JMP FETR1 ;FETCH IM REG + DISP IF IT IS IM ; ;STORES REGISTER DATA AND INCREMENTS ; STRR: POP D ;UNDO STACK CALL CALL FETA6 ;MERGE 2 HEX DATA VALUES IN A STAX B ;STORE DATA BYTE IN SAVX REG ADRS DCX B ;POINT TO NEXT SAVX REG ADRS LHLD RMP ;REGISTER MESSAGE POINTER INX H ;POINT TO NEXT REG MESSAGE INX H ; INX H ; INX H ; MVI A,$DA ;LS BYTE OF SAVIM-1 ADRS IN RAM CMP C ;SEE IF IT'S A REG JZ FETR ;FETCH A REG + DISP IF IT IS JMP FETR2 ;FETCH NEX REG + DISP IF NOT ; ;DELAYS APPROX 1MS ; DELA: PUSH B LXI B,$0001 ;FIXED 1MS VALUE JMP DEL1 ;START TIMIMG LOOP ; ;DELAYS APPROX 1MS TIMES VALUE IN BC ; DELB: PUSH B DEL1: PUSH PSW XRA A ;CLEAR A PUSH D ; DEL2: MVI D,TIME ;1MS SMALL LOOP TIME CONSTANT DEL3: DCR D ;1MS LOOP JNZ DEL3 ;IF NOT 1MS WORTH OF COUNTS DCX B ;LARGE LOOP COUNTER CMP B ;MS BYTE =0? JNZ DEL2 ;IF NOT, LOOP FOR 1 MORE MS CMP C ;LS BYTE =0? JNZ DEL2 ;IF NOT, LOOP POP D ;WHEN DONE POP PSW POP B RET ; ;BEEP PRODUCES A FIXED TONE FREQ. + DURATION ; BEEP2: MVI L,$FF ;DURATION MULTIPLIER MVI H,$00 ;SPEAKER FLAG MOV C,B ;SET COUNT REG B MOV E,D ;SET COUNT REG E PUSH H ;INIT. DONE FLAG BEEP3: DCR C ;DECR FREQ JNZ BEEP8 ; MOV C,B ;RESTORE FREQ MOV A,H ;CHG SPKR FLAG CMA ; ORA A ; MOV H,A ; JNZ BEEP4 ;TEST SPKR FLAG MVI A,$C0 ;TURN SPKR OFF SIM ; JMP BEEP5 ; BEEP4: MVI A,$40 ;TURN SPKR ON SIM ; CMP M ;TIME DELAY INSTR BEEP5: POP PSW ;GET DONE FLAG PUSH PSW ; ORA A ; JZ BEEP6 ;CONTINUE IF NOT DONE MOV A,H ;RETURN IF SPKR OFF ORA A ; JZ BEEP7 ; BEEP6: DCR E ;DURATION CNTR JNZ BEEP9 ; MOV E,D ;RESTORE DURATION DCR L ;TIME COUNT JNZ BEEP3 ; POP PSW ;GET DONE FLAG CMA ; PUSH PSW ;SET DONE FLAG JMP BEEP3 ; BEEP7: POP PSW ; RET ; BEEP8: XTHL ;DELAY 81 CYCLES XTHL ; XTHL ; XTHL ; CMP M ; JMP BEEP6 ; BEEP9: NOP ;DELAY 14 CYCLES NOP ; JMP BEEP3 ; ; ;SIGNATURE ANALYSYS TEST LOOP ; SATL1: DI ;TURN OFF INTERRUPTS IN $80 ;PULSE A15 READ START-STOP LINE OUT $80 ;PULSE A15 WRITE START-STOP LINE LXI SP,$0BCE ;SET TO MONITOR VALUE ; ;RAM PROTECT TEST ; OUT $11 ;SET RAM PROTECT STA $0B11 ;WRITE TO UNPROTECTED RAM STA $0911 ;WRITE TO PROTECTED RAM OUT $10 ;UNPROTECT RAM ; ;OUTPUT PORT TEST ; XRA A ;CLEAR A STC ;SET CARRY BIT TO 1 FOR 8 LOOPS SATL2: RAL ;MOVE 1 BIT TO LEFT OUT LOUT ;OUTPUT PORT LEDS JNC SATL2 ;IF NOT DONE ; ;DISPLAY LATCH TEST ; SATL3: RAL ;MOVE 1 BIT TO LEFT OUT DSP ;OUTPUT DISPLAY SEGMENTS JNC SATL3 ;IF NOT DONE ; ;SCAN LATCH TEST ; CMA ;SET A TO FF CMC ;CLEAR CARRY SATL4: RAL ;MOVE 0 BIT TO LEFT OUT SCAN ;OUTPUT SCAN LINES CALL DELA ;STRETCH EACH DISP DIGIT JC SATL4 ;IF NOT DONE ; ;SPEAKER SERIAL OUT TEST ; MVI A,$40 ;SPEAKER ON MASK SIM ;TURN SPKR ON MVI A,$C0 ;SPKR OFF MASK SIM ;TURN SPKR OFF ; ;KEY INPUT TEST ; XRA A ;CLEAR A OUT SCAN ;ALL SCAN LINES TO LOGIC 0 IN KEY ;RESPOND TO ALL KEYS ; ;INPUT PORT TEST ; IN SIN ;INPUT THE INPUT SWITCHES ; ;INTERRUPT KEY TEST ; LXI H,BEEP ;ADRS OF BEEP ROUTINE SHLD $0AFD ;STORE IT IN INTRPT RAM LINK 6.5 MVI A,$C3 ;JUMP OP CODE STA $0AFC ;STORE IT IN INTRPT RAM LINK 6.5 MVI A,$1D ;INTRPT MASK FOR RST 6.5 SIM ;SET MASK EI ;ENABLE INTERRUPTS JMP SATL1 ;LOOP BACK TO START OVER AGAIN ; ;PRESENTS INPUT SWITCH DATA ON OUTPUT LEDS ; ECHO: LDA $2000 ;READ INPUT PORT SWITCHES STA $3000 ;WRITE TO OUTPUT PORT LEDS JMP ECHO ;REPEAT ; ;AND GATE PROGRAM ; ANDGT: LDA $2000 ;READ INPUT PORT CPI $FF JZ ON ;JUMP IF ALL BITS ARE ONE MVI A,$FF STA $3000 ;TURN OUTPUT LEDS OFF JMP ANDGT ON: MVI A,$FE ;TURN LED ON STA $3000 JMP ANDGT ; ;CONVEYOR BELT CONTROLLER DEMO PROGRAM ; CONV: CALL BLNK ;BLANK THE DISPLAY XRA A ;CLEAR A STA UDSP0 ;SET DISPLAY COUNTER LOOP: CALL KIND ;DISPLAY MESSAGE & READ KEYS CPI $00 ;CHECK FOR "0" KEY JNZ LOOP LXI H,NUM ;INCREMENT COUNT INR M MOV A,M ;TEST FOR COUNT=10 CPI $0A JZ MOVE JMP LOOP MOVE: MVI A,$7F MVI D,MIN ;SET LOW FREQ VALUE MLP: STA $3000 ;WRITE DATA TO LEDS LXI B,DTIME ;WATE DELAY TIME PUSH D CALL DELB POP D CALL TONE ;GENERATE BEEP STC RAR ;SHIFT PATTERN JC MLP STA $3000 ;TURN OFF LEDS JMP CONV TONE: MOV E,A ;SAVE A PUSH D MOV B,D CALL BEEP1 ;GENERATE BEEP POP D MOV A,D ;INCREASE FREQUENCY SUI INCR MOV D,A MOV A,E ;RESTORE A RET NUM .EQ $0BF0 ;RAM BUFFER LOCATION INCR .EQ $10 ;FREQ INCREMENT MIN .EQ $F0 ;FEQUENCY MINIMUM DTIME .EQ 80 ;TIME BETWEEN SHIFTS ; ;WELL TEMPERED MICROPROCESSOR ;GENERATES PSEUDO RANDOM TONES FROM ROM ; WTM: LXI H,$0180 ;SET ROM POINTER TO 0180 WTM1: MOV A,M ;ROM CONTENTS ANI $7E ;MASK BITS MOV B,A ;SET BEEP FREQ. REG PUSH H ;SAVE ADRS POINTER CALL BEEP1 ;GENERATE BEEP POP H ;RESTORE ADRS POINTER LXI B,$0050 ;SET DELAY REG CALL DELB ;PAUSE INX H ;NEXT ADRS OF ROM MVI A,$03 ;LAST ADRS OF LOOP CMP H ;LAST ADRS JZ WTM ;IF LAST ADRS JMP WTM1 ;IF NOT LAST ADRS ; ;SQUIRREL FEEDBACK SHIFT REGISTER DISPLAY ; SQRL: CALL BLNK ;CLEAR THE DISPLAY XRA A ;CLEAR A AND CARRY MVI B,$01 ;SEED SQRL1: RAL ;SHIFT A A7 TO CARRY MOV D,A ;SAVE IT MOV A,B ;GET B FSR REGISTER RAR ;SHIFT A7 INTO B7 MOV C,A ;SAVE IT XRA B ;XOR B0 AND B1 ANI $01 ;SET B7 TO B1 TO 0 ORA D ;INSERT B0 XOR B1 IN A0 MOV B,C ;RESTORE NEW B LXI H,DDSP2 ;ADRS OF DECODED DISPALY D2 PUSH PSW ;SAVE A FSR REG RRC ;GET DIGIT 2 BITS IN POSITION RRC ; CALL SQRL3 ;FORMAT AND STORE DIGITS 2,3 INR L ;ADRS DIGIT 4 MOV A,B ;GET B FSR REGISTER RLC ;GET DIGIT 4 BITS IN POSITION CALL SQRL3 ;FORMAT AND STORE IN DIGITS 4,5 MVI C,$0F ;DISPLAY TIMER SEGMENTS SQRL2: CALL SDS ;DISPLAY SEGMENTS DCR C ;DCR TIMER JNZ SQRL2 ;IF TIME NOT UP POP PSW ;RESTORE A FSR REGISTER JMP SQRL1 ;DO IT AGAIN SQRL3: MOV C,A ;SAVE SHIFTED VALUE ORI $F0 ;BLANK E,F,G,DP SEGS MOV M,A ;STORE IN DIG 2 OR 4 MOV A,C ;RECALL SHIFTED VALUE INR L ;ADRS OF DIG 3,5 RLC ;GET A SEG IN D0 ANI $01 ;CLEAR D7-D1 MOV D,A ;SAVE A SEG MOV A,C ;RECALL SHIFTED VALUE RRC ;MOVE A,F,E,D TO D6-D3 ANI $38 ;CLEAR D7-D6,D2-D0 ORA D ;INSERT A SEG IN D0 ORI $C6 ;BLANK B,C,H,DP SEGS MOV M,A ;STORE DIG 3 OR 5 RET ; ;ORGAN GENERATES TONES FROM KEYBOARD ; ORGAN: MVI D,$40 ;INITIALIZE SPKR FLAG ORGAN1: CALL KRD ;READ KEYS CALL CODE ;DECODE KEYS & LOK-UP DELAY VALUE ORA A ;CHECK FOR NO KEY JZ ORGAN1 CALL DLY ;TIME DELAY CALL SPKR ;CHANGE SPEAKER STATE JMP ORGAN1 ;REPEAT ; ;DELAY ROUTINE ; DLY: DCR A ;DECREMENT A UNTIL ZERO NOP NOP JNZ DLY RET ; ;SPKR ROUTINE TO CHANGE SPEAKER STATE ; SPKR: MOV A,D ;GET SPKR FLAG XRI $80 ;COMPLEMENT BIT 7 MOV D,A ;SAVE FLAG SIM ;OUTPUT TO SPKR RET ; ;CODE ROUTINE DETERMINES WHICH KEY IS ; PRESSED AND LOOKS UP DELAY VALUE ; CODE: MVI B,$07 ;INITIALIZE ROW COUNT LXI H,$0BEF ;INITIALIZE DATA ADDRESS READ: MOV A,M ;GET KEY DATA CMA ORA A ;ANY KEY PRESSED? JZ NOKEY CPI $04 ;DATA=100? JNZ SHIFT ;IF YES CHANGE TO 011 DCR A SHIFT: MOV C,A ;SAVE KEY DATA MOV A,B ;SHIFT ROW COUNT RLC RLC ORA C ;COMBINE ROW COUNT & DATA LXI H,TABLE-9 ;SET LOOK-UP ADDRESS ADD L MOV L,A MOV A,M ;GET DELAY VALUE RET NOKEY: DCR B ;NO KEY PRESSED-GO TO NEXT ROW DCX H MOV A,B ;DONE? CPI $01 JNZ READ ;IF NOT, READ NEXT ROW XRA A ;NO KEY - SET DELAY TO 0 RET ; ;LOOK-UP TABEL FOR ORGAN DELAY VALUES ; TABLE: .DB $E6 ;E3 .DB $00 .DB $00 .DB $00 .DB $DA ;F3 .DB $BD ;G3 .DB $A3 ;A3 .DB $00 .DB $8F ;B3 .DB $85 ;C4 .DB $72 ;D4 .DB $00 .DB $64 ;E4 .DB $5C ;F4 .DB $4D ;G4 .DB $00 .DB $43 ;A4 .DB $38 ;B4 .DB $33 ;C5 .DB $00 .DB $2D ;D5 .DB $24 ;E5 .DB $20 ;F5 ; ;ROCKET BLAST-OFF DEMO PROGRAM ; ROCT: MVI A,$AA ;ALL AMBER LED MASK OUT LOUT ;TURN ON AMBER LEDS LXI D,ROCM ;ROCKET DISPLAY MESSAGE RST 3 ;STORE MESSAGE IN RAM ROCT1: MVI B,$80 ;1 SECOND DELAY LOOP COUNTER ROCT2: CALL DCD ;UPDATE DISPLAY DCR B ;COUNTER JNZ ROCT2 ;REPEAT IF <1 SECOND RST 2 ;BEEP LXI H,UDSP0 ;COUNT DOWN SECONDS DIGIT DCR M ;INCREMENT IT JNZ ROCT1 ;IF NOT LAST COUNT (0 SECONDS) MVI B,$00 ;START BLAST-OFF FREQUENCY MVI D,$02 ;START BLAST-OFF DURATION ROCT3: MVI A,$E7 ;LED PATTERN CALL ROCT5 ;SEQUENCE MVI A,$DB ;LED PATTERN CALL ROCT5 ;SEQUENCE MVI A,$BD ;LED PATTERN CALL ROCT5 ;SEQUENCE MVI A,$7E ;LED PATTERN CALL ROCT5 ;SEQUENCE JNZ ROCT3 ;REPEATE IF B70, FREQ <MAX XRA A ;CLEAR A CMA ;SET A TO FF OUT LOUT ;TURN OFF ALL LEDS LXI B,$0500 ;1 SECOND DELAY VALUE CALL DELB ;FOR 1 SECOND PAUSE MVI A,$03 ;NOTE COUNTER ROCT4: MVI B,$34 ;1ST NOTE FREQ PUSH PSW ;SAVE NOTE COUNT CALL BEEP1 ;PLAY NOTE POP PSW ;RESTORE NOTE COUNT LXI B,$0080 ;PAUSE VALUE CALL DELB ;PAUSE BETWEEN NOTES DCR A ;NOTE COUNTER JNZ ROCT4 ;IF NOT LAST OF 3 FIRST NOTES MVI B,$85 ;LAST NOTE FREQ MVI D,$40 ;LAST NOTE DURATION CALL BEEP2 ;PLAY LAST NOTE RST 1 ;RETURN TO MONITOR JMP ROCT ;RUN PROGRAM AGAIN ROCT5: OUT LOUT ;UPDATE LEDS CALL BEEP2 ;BEEP DCR B ;INCREASE FREQ BY 1 RET ROCM: .DB $09 ;9 .DB $1C ;- .DB $18 ;SMALL C .DB $15 ;SMALL O .DB $1B ;SMALL R .DB $10 ;SPACE ; ;STOPWATCH ; STW: LXI D,STWM ;ADRS OF DISPLAY MESSAGE RST 3 ;ZERO DISPLAY LXI D,$00FF ;RUN AND 3-KEY STATUS STW1: XRA A ;CLEAR A STA UDSP6 ;TURN OFF DECIMAL POINT FLAG CALL DCD ;UPDATE DISPLAY MVI B,$F5 ;DELAY CONSTANT STWL: DCR B ;DELAY COUNTER DAD H ;DELAY INSTRUCTION JNZ STWL ;IF NOT DONE MVI A,$FB ;0-KEY SCAN DATA OUT SCAN ;0-KEY ROW IN KEY ;INPUT CPI $FE ;CHECK FOR 0-KEY JZ STW ;IF PUSHED MVI A,$F7 ;3-KEY SCAN DATA OUT SCAN ;3-KEY ROW IN KEY ;INPUT CPI $FB ;CHECK FOR 3-KEY JNZ STW6 ;IF NOT PUSHED CMP E ;WAS IT PUSHED BEFORE? JZ STW2 ;IF IT WAS MOV E,A ;PUSHED STATUS CODE INR D ;CHANGE RUN MODE START/STOP STW2: MOV A,D ;CURRENT RUN MODE RAR ;FLAG MODE BIT TO CARRY JNC STW1 ;IF IN STOP MODE LXI H,UDSP0 ;.01 SEC MEM LOCATION STW3: INR M ;INCREMENT DIGIT COUNT MOV A,M ;LOAD DIGIT IN A CPI $0A ;OVERFLOW JNZ STW5 ;IF DIGIT 9 OR LESS MVI M,$00 ;SET DIGIT TO 0 STW4: INR L ;NEXT HIGHT DIGIT ADRS JMP STW3 ;REPEAT SEQUENCE ON THIS DIGIT STW5: LXI H,UDSP3 ;10 SEC MEM LOCATION MOV A,M ;LOAD DIGIT IN A CPI $06 ;OVERFLOW JNZ STW1 ;IF DIGIT 5 OR LESS MVI M,$00 ;SET DIGIT TO 0 INR L ;MIM DIGIT ADRS JMP STW4 ;REPEAT SEQUENCE FOR MIN DIGIT STW6: MVI E,$FF ;3-KEY NOT PUSHED CODE JMP STW2 ;CONTINUE IN CURRENT RUN MODE STWM: .DB $00 ;ZERO DISPLAY MESSAGE TABLE .DB $00 .DB $00 .DB $00 .DB $10 .DB $00 ; ;SNAKE PADDLE GAME ; SNAKE: LXI H,$FF00 ;INITIALIZE SCORE DISPLAY MVI B,$F7 ;RIGHT PLAYER CODE PUSH H ;SAVE SCORE SERV: MVI A,$40 ;SERVE SPEED STA SPEED ;CURRENT BALL SPEED CALL BLNK ;CLEAR THE DISPLAY POP H ;GET SCORE MVI C,$1C ;CODE FOR '-' CHAR MOV A,B ;PLAYER CODE CPI RIGHT ;RT PLAYER LOST POINT? MOV A,C ;DASH CHAR CODE JNZ LLOSE ;IF LEFT PLAYER LOST POINT STA UDSP5 ;LEFT SERVE DISPLAY MESSAGE INR H ;LEFT PLAYER GETS POINT MOV A,H ;LEFT SCORE MVI B,LEFT ;LEFT PLAYER GETS SERVE JMP SERV1 ;CONTINUE LLOSE: STA UDSP2 ;RIGHT SERVE DISPLAY MESSAGE INR L ;RIGHT PLAYER GETS POINT MOV A,L ;RIGHT SCORE MVI B,RIGHT ;RIGHT PLAYER GETS SERVE SERV1: CPI $0A ;LAST POINT PUSH H ;SAVE SCORE SHLD UDSP0 ;DISPLAY SCORE CALL DCD ;UDPATE DISPLAY JNZ SERV2 ;IF NOT LAST GAME POINT ENDGM: CALL RSTGM ;NEW GAME REQUEST? CALL SDS ;UPDATE DISPLAY JNZ ENDGM ;WAIT FOR NEW GAME REQUEST SERV2: CALL RSTGM ;NEW GAME REQUEST? JZ SNAKE ;IF NEW GAME REQUESTED CALL PADL ;CHECK PADDLE JNZ SERV2 ;IF NOT PUSHED RBND: PUSH B ;SAVE HITTING PLAYER CODE MOV A,B ;HITTING PLAYER CODE CPI LEFT ;LEFT PLAYER CODE LXI B,LSM ;LEFT PLAYER MESSAGE POINTER JZ RSRV ;IF LEFT PLAYER WAS HITTER LXI B,RSM ;RIGHT PLAYER MESSAGE CODE RSRV: CALL PASS ;START BALL MOVING POP B ;RESTORE LAST HITTER CODE MOV A,B ;HITTING PLAYER CODE CPI LEFT ;LEFT PLAYER CODE MVI B,RIGHT ;RIGHT PLAYER CODE JZ RBND1 ;IF BALL CAME FROM LEFT PLAYER MVI B,LEFT ;LEFT PLAYER NEXT HITTER RBND1: CALL PLAY ;CHECK PADDLE MOV A,D ;POINT LOSS REGISTER CPI $FF ;POINT LOSS CODE JNZ RBND ;IF NO LOST POINT, REVERSE BALL MVI C,LOSTN ;LOSE POINT TRILL CODE CALL TRIL ;PLAY TRILL JMP SERV ;NEW SERVE ; ;PASSES BALL FROM ONE PLAYER TO THE OTHER ; PASS: CALL BLNK ;CLEAR THE DISPLAY MVI H,$0B ;MSBYTE DISP MEM MVI D,$0E ;BALL PATTERN LENGTH PASS1: LDAX B ;BALL POSITION DISPLAY CODE MOV E,A ;SAVE A ANI $12 ;MASK RRC ;POSITION MOV L,A ;SAVE RRC ;POSITION RRC ;POSITION ORA L ;MASK ANI $03 ;MASK ADI $FC ;OFFSET FOR RAM MOV L,A ;LSBYTE DISP MEM MOV A,E ;RESTORE MESSAGE ORI $92 ;SET DP,E,B, SEGS OFF MOV M,A ;SEND TO UDSPX CALL TIMER ;DISPLAY IT INX B ;NEXT MESSAGE DCR D ;MESSAGE COUNTER JNZ PASS1 ;IF LAST BALL POSITION RET ; ;PLAY ROUTINE WHEN PASS IS COMPLETE ; PLAY: MVI D,PNTLS ;POINT LOSE CODE CALL PADL ;CHECK PADDLE RZ ;IF PUSHED TOO SOON LDA SPEED ;PRESENT BALL SPEED MOV E,A ;SAVE IT MOV D,A ;SET REACTION SPEED COUNTER VALUE RRC ;HALVE BALL SPEED/ TIME MOV C,A ;SAVE IT PLAY1: MOV A,D ;RESTORE COUNTER VALUE DCR A ;COUNTER CMP C ;HALF TIME JZ FSTR ;IF PADL NUT PUSHED BY THIS TIME MOV D,A ;SAVE COUNT CALL PADL ;CHECK PADDLE JNZ PLAY1 ;IF NOT PUSHED MVI C,SLOTN ;SLOWER TRILL CODE CALL TRIL ;PLAY TRILL MOV A,E ;ORIGINAL BALL SPEED CPI $40 ;SLOWEST SPEED RZ ;IF ALREADY AT SLOWEST SPEED RLC ;HALVE BALL SPEED STA SPEED ;STORE IT RET ; ;FASTER INCREASES RETURN SPEED ; FSTR: MOV A,D ;RESTORE COUNTER VALUE MVI D,PNTLS ;LOSE SIGNAL CODE DCR A ;COUNTER RZ ;IF PADDLE NOT PUSHED IN TIME MOV D,A ;SAVE A CALL PADL ;CHECK PADDLE JNZ FSTR ;IF NOT PUSHED MVI C,FSTTN ;FASTER SIGNAL CODE CALL TRIL ;PLAY TRILL MOV A,E ;ORIGINAL BALL SPEED RRC ;DOUBLE BALL SPEED STA SPEED ;STORE IT RET ; ;RESET GAME BUTTON PUSHED ? ; RSTGM: MVI A,$FB ;0 KEY INPUT CODE OUT SCAN ;SET SCAN LATCH IN KEY ;INPUT KEYS CPI $FE ;0 KEY INPUT CODE RET ; ;PADDLE PUSHED? ; PADL: CALL SDS ;UPDATE DISPLAY MOV A,B ;PADDLE KEY SCAN MASK OUT SCAN ;SET SCAN LATCH IN KEY ;INPUT KEYS CPI $FB ;ACCEPTABLE KEY INPUT CODE RET ; ;TIME CONTROLS BALL SPEED ; TIMER: LDA SPEED ;PRESENT BALL SPEED TIME1: CALL SDS ;UPDATE DISPLAY / DELAY SBI $02 ;COUNTER JNZ TIME1 ;IF COUNTER NOT DONE RET ; ;TRILL MAKES SPEAKER SOUNDS ; TRIL: PUSH D ; PUSH B ; MVI B,$06 ;START FREQ MVI D,$01 ;START DURATION TRIL1: PUSH B ;SAVE START FREQ CALL BEEP2 ;TONE POP B ;START FREQ INR B ;DECREASE FREQ MOV A,C ;TRILL CODE CPI FSTTN ;FASTER CODE JNZ TRIL2 ;IF NOT DCR B ;RESTORE FREQ DCR B ;INCREASE FREQ TRIL2: CMP B ;LAST BEEP JNZ TRIL1 ;IF NOT DONE POP B ; POP D ; RET ; ;LEFT SERVE MESSAGE TABLE ; LSM: .DB $F7 ;DISPLAY SEGMENT CODES .DB $F5 .DB $E7 .DB $E5 .DB $E1 .DB $A1 .DB $A7 .DB $B5 .DB $B7 .DB $97 .DB $96 .DB $B4 .DB $A6 .DB $A0 ; ;RIGHT SERVE MESSAGE TABLE ; RSM: .DB $EC ;DISPLAY SEGMENT CODES .DB $EE .DB $FC .DB $FE .DB $DE .DB $9E .DB $BC .DB $AE .DB $AC .DB $A8 .DB $A0 .DB $A6 .DB $B4 .DB $96 SPEED .EQ $0B00 PNTLS .EQ $FF LEFT .EQ $FB RIGHT .EQ $F7 LOSTN .EQ $28 SLOTN .EQ $0B FSTTN .EQ $01 ; ;LESSON 3 COUNTER PROGRAM ; XSTART: MVI A,$00 ;SET A REGISTER TO 0 XLOOP: INR A ;INCREMENT A REGISTER CPI $0A ;COMPARE A REGISTER TO 10 JZ XSTART ;GO TO BEGINNING IF A=10 JMP XLOOP ;INCREMENT AGAIN NOP NOP NOP NOP CHKSM: .DB $DE ; ;EQUATES ; KEY .EQ $18 ;KEY INPUT PORT ADRS SIN .EQ $20 ;KEY INPUT PORT ADRS SCAN .EQ $28 ;KEY SCAN PORT ADRS LOUT .EQ $30 ;KEY OUTPUT PORT ADRS DSP .EQ $38 ;KEY DISPLAY PORT ADRS DIM .EQ $0B ;DEFAULT INTERRUPT MASK PC .EQ $0800 ;DEFAULT PROGRAM COUNTER USP .EQ $0BB0 ;DEFAULT USER STACK POINTER MSP .EQ $0BCE ;MONITOR STACK POINTER TIME .EQ $8C ;1MS TIME CONSTANT FOR DELAY LOOP FREQ .EQ $06 ;BEEP DEFAULT FREQUENCY CONSTANT DURA .EQ $04 ;BEEP DEFAULT DURATION CONSTANT RS4C .EQ $0AF0 ;RST4 LINK RS5C .EQ $0AF3 ;RST5 LINK RS55C .EQ $0AF6 ;RST5.5 LINK RS6C .EQ $0AF9 ;RST6 LINK RS65C .EQ $0AFC ;RST6.5 LINK FOR INTRPT KEY TPR .EQ $0AFF ;TOP OF PROTECTED RAM UR .EQ $0AEF ;UPPER RAM BELOW RST LINKS TSAVSP .EQ $0BD1 ;TEMPORARY STACK POINTER SAVE ADRS TSAVH .EQ $0BD3 ;TEMPORARY H,L REG SAVE ADRS RAML1 .EQ $0BD5 ;RAM LINK TO USER PROG RS .EQ $0BD6 ;RUN STATUS ADRS RAML2 .EQ $0BD7 ;RAM LINK TO USER PROG SAVIM .EQ $0BDB ;SAVE INTERRUPT MASK ADRS SAVPC .EQ $0BDC ;SAVE PROGRAM COUNTER ADRS SAVSL .EQ $0BDE ;SAVE STACK POINTER LOW ADRS SAVSH .EQ $0BDF ;SAVE STACK POINTER HIGH ADRS SAVL .EQ $0BE0 ;SAVE L REG ADRS SAVE .EQ $0BE2 ;SAVE E REG ADRS SAVA .EQ $0BE7 ;SAVE A REG ADRS UDKY .EQ $0BE8 ;UNDECODED KEY SACN 0 UDSP0 .EQ $0BF0 ;UNDECODED DISPLAY DIGIT 0 ADRS UDSP1 .EQ $0BF1 ;UNDECODED DISPLAY DIGIT 1 ADRS UDSP2 .EQ $0BF2 ;UNDECODED DISPLAY DIGIT 2 ADRS UDSP3 .EQ $0BF3 ;UNDECODED DISPLAY DIGIT 3 ADRS UDSP5 .EQ $0BF5 ;UNDECODED DISPLAY DIGIT 5 ADRS UDSP6 .EQ $0BF6 ;UNDECODED DISPLAY DIGIT 6 ADRS RMP .EQ $0BF8 ;REGISTER MESSAGE POINTER DDSP0 .EQ $0BFA ;DECODED DISPLAY DIGIT 0 ADRS DDSP2 .EQ $0BFC ;DECODED DISPLAY DIGIT 2 ADRS DDSP5 .EQ $0BFF ;DECODED DISPLAY DIGIT 5 ADRS