.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