0% 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.

Uploaded by

DMA
Copyright
© © All Rights Reserved
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% 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.

Uploaded by

DMA
Copyright
© © All Rights Reserved
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

You might also like