Cromemco-Z80-Monitor-Source-198002
;
;
STAT: EQU 0 ;STATUS PORT, DEVICE A
DATA: EQU 1 ;DATA PORT, DEVICE A
ACMNDP: EQU 2 ;COMMAND PORT, DEV. A
ABAUDP: EQU 0 ;BAUD PORT, DEVICE A
APARLP: EQU 4 ;PARALLEL PORT, DEV. A
BCMNDP: EQU 52H ;COMMAND PORT, DEV. B
BPARLP: EQU 54H ;PARALLEL PORT, DEV. B
DAV: EQU 40H ;DATA-AVLAILABLE MASK
TBE: EQU 8OH ;XMITTER-BUF-EMPTY MASK
;
NBRKPT: EQU 5 ;ALLOW ROOM FOR
BPSTOR: EQU NBRKPT*4+2 ;BREAKPOINT STORAGE
TEMPS: EQU BPSTOR
BPMRK: EQU 0BH ;USED TO MARK THE SET-
; ;TING OF A BP IN BPSTOR.
RSTLC: EQU 30H ;RST LOCATION
CASE: EQU 0 ;(REQUIRES UPPER-CASE)
B2F: EQU 5 ;2-BYTE FLAG
PF: EQU 6 ;PRIME-ABLE REG FLAG
CRF: EQU 7 ;CRLF FLAG
;
CR: EQU 0DH
LF: EQU 0AH
ESC: EQU 1BH
ALT: EQU 7DH
;
; DISPLACEMENTS FROM IX OF HI BYTE OF REG PAIRS
;
;
DUPC: EQU -1 ;(FFFF)
DUAF: EQU -3 ;(FFFD)
DUBC: EQU -5 ;(FFFB)
DUDE: EQU -7 ;(FFF9)
DUHL: EQU -9 ;(FFF7)
DUSP: EQU -11 ;(FFF5)
DUIX: EQU -13 ;(FFF3)
DUIY: EQU -15 ;(FFF1)
DUIN: EQU -17 ;(FFEF) I & THE INTERRUPT FF
DUAF2: EQU -19 ;(FFED)
DUBC2: EQU -21 ;(FFEB)
DUDE2: EQU -23 ;(FFE9)
DUHL2: EQU -25 ;(FFE7)
;
LENRGS: EQU DUPC-DUHL2+2
;
;
;
;
ORG 0E000H
;
; ENTER THE MONITOR FROM RESET.
; COLD START ENTRY. INITIALIZES THE UART
; AND ZEROES THE BREAKPOINT STACK POINTER.
; ALTERS THE A-REGISTER. SAVES ALL OTHER
; REGISTERS EXCEPT THE PROGRAM COUNTER,
; BUT DOES NOT DISPLAY THEM.
CSTART: LD A,1
OUT 40H,A ;SELECT BANK B
PUSH AF ;SIMULATE UPC
PUSH AF ;USER-F-REGISTER
JR COMMON
; WARM START ENTRY. INITIALIZES THE BREAKPOINT
; STORAGE POINTER. SAVES ALL REGISTERS EXCEPT
; THE PROGRAM COUNTER, BUT DOES NOT DISPLAY THEM.
WSTART: PUSH AF ;SIMULATE UPC
PUSH AF ;UAF
LD A,80H ;FLAG:
JR COMMON ;WARM-START ENTRY
;
; CHECK INPUT & RETURN WITH DATA IF READY.
;
CHKIN: IN A,STAT
AND DAV
RET Z
IN A,DATA
RET
;
;
; GET CHARACTER FROM INPUT.
;
GBYTE: CALL CHKIN
JR Z,GBYTE
AND 7FH
RET
;
;
; PRINT CHARACTER.
;
PBYTE: PUSH AF
PBY1: IN A,STAT
AND TBE
JR Z,PBY1
POP AF
OUT DATA,A
RET
;
;
; SELECT DEVICE A & INITIALIZE ITS BAUD RATE.
; ENTER WITH A=1.
;
INIT: OUT BPARLP,A ;SELECT DEVICE A
OUT BCMNDP,A ;RESET DEVICE B
; ;[CONTINUE BELOW]
;
;
; INITIALIZE BAUD RATE OF THE CURRENT DEVICE.
;
; PUSH CARRIAGE-RETURN TO SELECT THE PROPER BAUD
; RATE FOR THE CURRENT TERMINAL. (THE MAXIMUM
; NUMBER OF CARRIAGE-RETURNS REQUIRED IS FOUR.)
;
; WITH THE CROMEMCO TUART ANY OF THE FOLLOWING
; BAUD RATES CAN BE SELECTED:
; 19200, 9600, 4800, 2400, 1200, 300, 150, 110.
;
; WITH THE 3P+S: 2400, 300, 110.
;
; TWO CARRIAGE-RETURNS ARE REQUIRED FOR
; ANY UART WITH A FIXED BAUD RATE.
;
INITBAUD: LD HL,BAUDRS
LD C,ABAUDP
LD A,11H ;OCTUPLE THE CLOCK
IT1: OUT ACMNDP,A ;& RESET CURRENT DEVICE
OUTI
CALL GBYTE
CALL GBYTE
CP CR
LD A,1 ;SLOW THE CLOCK
JR NZ,IT1
RET
;
;
; BREAKPOINT ENTRY. INITIALIZES NOTHING.
; SAVES ALL REGISTERS AND DISPLAYS THEM.
;
SVMS: EX (SP),HL ;ADJUST BRKPT
DEC HL ;RET ADDR
EX (SP),HL
PUSH AF ;UAF
SUB A ;FLAG:
;BREAKPOINT ENTRY;
;
;
COMMON: PUSH BC ;UBC
LD B,A ;ENTRY FLAG
PUSH DE ;UDE
PUSH HL ;UHL
;
; PLACE SYS STACK AT HIGHEST PAGE OF
; AVAILABLE RAM.
; ALLOW ROOM FOR TEMP STORAGE.
;
LD HL,00FFH-TEMPS
COM1: DEC H
LD A,(HL)
INC (HL)
CP (HL) ;DID IT CHANGE?
JR Z,COM1
DEC (HL) ;YES. RESTORE IT.
;
LD A,B ;ENTRY FLAG
EX DE,HL
LD HL,9
ADD HL,SP ; -> UPC, HI BYTE
LD BC,10
LDDR
;
INC DE ;-> UHL,LO ON SYS STK
EX DE,HL
LD SP,HL ;CURRENT SYS SP
EX DE,HL
LD BC,DUPC-DUHL+3
ADD HL,BC ;HL = USER SP
PUSH HL ;USP
PUSH IX ;UIX
PUSH IY ;UIY
EX DE,HL
ADD HL,BC
LD C,L ;SAVE
DEC HL
PUSH HL
POP IX
CP 1 ;ENTRY?
JR C,COM3 ;SKIP IF VIA BP.
LD (HL),C ;BP PNTR, LO BYTE
INC HL
LD (HL),0 ;BP-STACK ENDMARK
; INITIALIZE THE TUART IF ENTRY WAS VIA RESET.
; (A CONTAINS 1.)
;
CALL Z,INIT
;
COM3: LD A,I
LD H,A
LD L,0
JP PO,COM4
INC L
COM4: PUSH HL ;UIN
EX AF,AF'
PUSH AF ;UAF'
EX AF,AF'
EXX
PUSH BC ;UBC'
PUSH DE ;UDE'
PUSH HL ;UHL'
EXX
;
;IF CY IS SET, ENTRY WAS VIA A BREAKPOINT
LD HL,HEAD
CALL NC,PMSG
LD BC,[['P'+CASE] SHL 8]+86H ;IF BP ENTRY,
CALL C,SUBR3 ;DISPLAY THE PC.
;
;
;CLEAR ALL BREAKPOINTS
;
CLBP: PUSH IX
POP HL ;POINTS TO BPSP,LO
LD L,(HL) ;BPSP NOW IN HL
;
CL1: LD A,(HL) ;BP STK EMPTY?
CP BPMRK ;IF BPMRK, BP IS SET
JR NZ,CL2
;
INC (HL) ;BP-ERASED MARK
DEC HL
LD D,(HL)
DEC HL
LD E,(HL)
DEC HL
LDD ;RESTORE MEM CONTENTS
JR CL1
;
CL2: LD A,L
DEC HL
LD (HL),A ;ADJUST BPSP
;
LD DE,-LENRGS ;FOR THE BENEFIT
ADD HL,DE ;OF ERROR & ESCPE
LD SP,HL ;RE-INITIALIZE SP
;
;
;GET 1-BYTE COMMAND.
;RETURNS VALUE IN HL & JUMPS TO THAT ADDR.
;
CALL CRLF
CMND: LD DE,CMND ;SET-UP RETURN
PUSH DE
CMND1: LD HL,PRMPT ;RE-ENTRY POINT
CALL PMSG ;FOR RECURSION
;HL NOW PNTS TO THE COMMAND TABLE.
;
;GET THE COMMAND.
;DE GETS THE FIRST ALPHA CHAR LESS 'D'.
CALL SKSG0 ;GET NON-SPACE
RET Z ;IF CR, IGNORE.
SUB 'D'+CASE ; < 'D'?
JR C,ERROR
CP 'W'-'D'+1 ; > 'W'?
JR NC,ERROR
LD E,A
LD D,0
;
LD C,D ;INITIALIZE FOR SUBR
EX DE,HL
ADD HL,HL ;TIMES 2
ADD HL,DE ; + TBL ADDR
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
CALL SKSG0 ;NEXT CMND GHAR
CP 'M'+CASE ; (USED IN SUBST & DISPL)
JP (HL)
;
;
; ERROR & ESCAPE. RETURNS TO CMND WITH SP
; POINTING TO SAVED-REG AREA (UHL').
ERROR: LD A,'?'
CALL PCHR
ESCPE: JR CLBP ;CLEAR ANY BRKPTS
;
;
; PROGRAM PROMS. ABORTS IF DESTINATION
; IS NOT ON A 1K (400H) BOUNDARY, OR IF SWATH
; WIDTH IS NOT A MULTIPLE OF 1K.
;
;
PROG: CALL L3NCR
LD A,B ;ARE INCREMENT &
OR D ;DESTINATION BOTH
AND 3 ;MULTIPLES OF
OR C ;1024?
OR E
ERRV1: JR NZ,ERROR ;ERROR VECTOR
;
PUSH HL ;SOURCE
LD HL,320 ;# OF ITERATIONS
PR1: EX (SP),HL
CALL MVE ;MOVE IT
EX (SP),HL
DEC HL ;ITERATION CT
LD A,H
OR L
JR NZ,PR1
POP HL
JR VRFY ;VERIFY IT
;
;
;PRINT THE 2 BYTES IN (HL) & (HL-1)
;DECREMENTS HL BY 2. ALTERS A.
;PRESERVES OTHER REGS.
;
P2NMS: CALL PNM
DEC HL
CALL PNM
DEC HL ; (CONTINUE BELOW)
;
;
;PRINT SPACE. ALTERS A.
;
SPACE: LD A,20H ; (CONTINUE BELOW)
;
;
;PRINT THE CHARACTER IN THE A-REGISTER.
;(CHKS INPUT FOR ESC.) PRESERVES ALL REGS.
;
PCHR: PUSH AF ;SAVE THE CHAR
PC1: AND 7FH
CP ESC
JR Z,ESCPE
CP ALT ;ALT MODE?
JR Z,ESCPE
CALL CHKIN
JR NZ,PC1
;
PC2: POP AF
PUSH HL
PUSH AF
AND 7FH
CALL PBYTE
LD HL,LFNN
CP CR
CALL Z,PMSG
CP '<' ;RECURSIVE CALL
JR NZ,PC3 ;ON CMND?
POP AF
LD A,CR ;YES. CONVERT
PUSH AF ;'<' TO A CR.
PUSH DE
PUSH BC
CALL CMND1
POP BC
POP DE
PC3: POP AF
POP HL
RET
;
;
; GET CHARACTER. RETURNS IT IN A.
; ALTERS F.
;
GCHR: CALL GBYTE
CALL PCHR
JR Z,GCHR ;IF NULL DON'T RETURN
RET
;
;
; CRLF. ALTERS A ONLY.
;
CRLF: LD A,CR
JR PCHR
;
;
; LOADS HL WITH SOURCE ADDR, BC & DE
; WITH THE INCREMENT. ENDS WITH A CRLF.
;
L2NCR0: SUB A
L2NCR: CALL LD2N
;
; SKIP INITIAL SPACES.
; IF DELIMITER NOT A CR, ERROR
;
SKSGCR: CALL SKSG ;WAIT FOR NON-SPACE
JR NZ,ERRV1 ;IF NOT CR, ERROR
EX DE,HL
RET
;
;
; PRINT THE NUMBER IN HL, FOLLOWED BY A COLON.
; PRESERVES ALL REGISTERS EXCEPT A.
;
PCADDR: CALL CRLF
;
PADDR: CALL PNHL
LD A,':'
JR PCHR
;
;
; COMMAND
;
VERIF: CALL L3NCR ;GET 3 OPERANDS
;
; COMPARES TWO AREAS OF MEMORY. ENTER WITH
; SOURCE IN HL, DESTINATION IN DE & COUNT
; IN BC. ALTERS ALL REGISTERS.
;
VRFY: LD A,(DE)
CPI ;COMPARE TO SOURCE
DEC HL
CALL NZ,PNHL ;PRINT SOURCE ADDR
CALL NZ,PSNM ; & CONTENTS
EX DE,HL
CALL NZ,PSNM ; & DEBT CONTENTS
CALL NZ,PSNHL ; & DEBT ADDR
CALL NZ,CRLF
EX DE,HL
INC HL
INC DE
RET PO ;IF BC=0, DONE.
JR VRFY
;
;
; COMMAND
;
MOVE: CALL L3NCR ;OPERANDS
CALL MVE ;MOVE IT
JR VRFY
;
;
; LOAD TWO NUMBERS. LOADS DE WITH THE BEGINNING
; ADDR, N1. LOADS BC & HL WITH THE INCREMENT
; N2-Ni+1 (OR WITH N2 IF THE OPR IS 'S').
; RETURNS WITH LAST DELIMITER IN A.
;
LD2N: CALL GNHL ;N1 TO HL, DELIM TO A
EX DE,HL ;SAVE Ni IN DE
CALL SKSG ;GET NEXT NON-SPACE
CP 'S'+CASE ;SWATH?
JR NZ,L2N1
;
CALL GNHL0 ;YES. INCREMENT TO HL.
JR L2N2
L2N1: CALL GNHL ;INCREMENT
OR A ;CLEAR CY
SBC HL,DE ;N2-Nl
INC HL ;INCLUDE END POINT
L2N2: LD B,H
LD C,L ;BC GETS THE INCRM
RET
;
;
; LOAD 3 OPERANDS. HL GETS THE SOURCE, BC
; THE INCREMENT, AND DE THE 3RD OPERAND.
;
L3NCR: CALL LD2N
; (CONTINUE BELOW)
;
;
; ENTER WITH SPACE OR THE FIRST DIGIT
; OF A NUMBER IN A. LOADS HL WITH
; WITH A NEW NUMBER & THEN EXCHANGES
; DE & HL. FINISHES WITH A CRLF.
;
L1NCR: CALL GNHL ;SKIP SPACES, LOAD HL
JR SKSGCR ;WAIT FOR A CR
;
;
; CLEARS HL. IF ENTERED WITH HEX CHAR IN A,
; SHIFTS IT INTO HL. O/W, IGNORES LEADING
; SPACES. FIRST CHAR MUST BE HEX. CONTINUES
; SHIFT UNTIL A NON-HEX CHAR RECEIVED & THEN
; RETURNS WITH THE LATTER IN A.
; PRESERVES B,C,D,E.
;
;
GNHL0: SUB A
;
GNHL: PUSH BC ;SAVE
LD HL,0 ;CLR BUFFER
; STRIP LEADING SPACES & GET CHAR
CALL SKSG
; FIRST CHAR MUST BE HEX
CALL HEXSH ;IF HEX, SHIFT INTO HL
JP C,ERROR ;O/W, ERROR
GN1: CALL GCHR
CALL HEXSH ;IF HEX SHIFT INTO HL
LD A,B ;RESTORE CHAR
JR NC,GN1 ;IF HEX, CONTINUE
POP BC ;IF NON-HEX, DONE
RET
;
;
; IF A CONTAINS HEX CHAR, SHIFTS BINARY EQUIVALENT
; INTO HL. IF NOT HEX, RET WITH CY SET. SAVES
; ORIGINAL CHAR IN B
;
HEXSH: LD B,A
SUB '0' ; < '0'?
RET C
ADD '0'-['G'+CASE]
RET C
SUB 'A'-'G'
JR NC,HX1 ;OK IF >= 'A'
ADD ['A'+CASE]-['9'+1]
RET C
HX1: ADD '9'+1-'0'
; THE A-REG NOW CONTAINS THE HEX DIGIT IN BINARY.
; (THE HIGH-ORDER NIBBLE OF A IS 0.)
HXSH4: ADD HL,HL ;SHIFT 4 BITS INTO HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
OR L
LD L,A
RET
;
;
; RETURNS WITH A NON-SPACE IN THE A-REG.
; IF ENTERED WITH A-REG CONTAINING A NULL
; OR A SPACE, GETS NEW CHARS UNTIL FIRST
; NON-SPACE OCCURS. ALTERS AF.
;
SKSG0: SUB A
;
SKSG: OR A ;DOES A CONTAIN NULL?
SK1: CALL Z,GCHR
CP 20H ;SPACE?
JR Z,SK1
CP CR
RET
;
;
; PRINT SPACE FOLLOWED BY THE NUMBER POINTED
; TO BY HL. ALTERS A ONLY.
;
PSNM: CALL SPACE
; (CONTINUE BELOW)
; PRINTS THE NUMBER POINTED TO BY HL.
; PRESERVES ALL REGISTERS BUT A.
PNM: LD A,(HL)
JR P2HEX
;
;
; PRINT THE NUMBER IN HL.
; PRESERVES ALL BUT A.
;
PSNHL: CALL SPACE
;
PNHL: LD A,H
CALL P2HEX
LD A,L
; ; (CONTINUE BELOW)
;
;PRINT THE NUMBER IN THE A-REGISTER.
;PRESERVES ALL REGISTERS.
;
P2HEX: CALL P1HEX
RRA
P1HEX: RRA
RRA
RRA
RRA
PUSH AF
AND 0FH ;MASK
CP 10D ; < 9?
JR C,PH1
ADD 7 ;A THRU F
PH1: ADD 30H ;ASCII BIAS
CALL PCHR ;PRINT IT
POP AF
RET
;
;
;PRINT MESSAGE. ENTER WITH ADDR OF MSG
;IN HL. THE MESSAGE IS TERMINATED
;AFTER PRINTING A CHARACTER WHOSE
;PARITY BIT WAS SET.
;PRESERVES FLAGS, INCREMENTS HL.
;
PMSG: PUSH AF ;SAVE
PS1: LD A,(HL)
INC HL
CALL PCHR
RLA ;LAST CHARACTER?
JR NC,PS1 ;IF NOT, LOOP
POP AF
RET
;
;
;MOVE FROM ONE LOCATION TO ANOTHER. ENTER
;WITH SOURCE ADDR IN HL, DEST IN DE, BYTE
;COUNT IN BC. PRESERVES ALL REGISTERS.
;
MVE: PUSH HL ;SOURCE
PUSH DE ;DEST
PUSH BC ;BYTE COUNT
LDIR
POP BC
POP DE
POP HL
RET
;
;
; COMMAND
;
; GO EXECUTION BEGINS AT USER PC.
;
; COMMAND
;
; GO (ADDR1>/(ADDR2> ...
; EXECUTION BEGINS AT ADDR1 WITH BREAKPOINTS SET
; AT ADDR2,... ,ADDRN.
GO:
; B GETS NBRKPT+1 (MAX. NUMBER OF BP + 1)
; C, THE BREAKPOINT FLAG, GETS 0 (NO HP SET)
LD BC,[[NBRKPT+1] SHL 8]+0
GO1: CALL SKSG ;WAIT FOR NON-SPACE
JR Z,RETN ;RETN IF CR
CP '/' ;BP?
JR NZ,GO3
LD C,A ;SET BRKPT FLAG (2FH)
LD HL,RSTLC ;TRANSFER
LD (HL),0C3H ;'JP SVMS' TO
LD HL,SVMS
LD (RSTLC+1),HL ;RST LOC
SUB A
GO3: CALL GNHL ;GET ADDR
BIT 5,C ; FLAG SET?
EX DE,HL
PUSH IX
POP HL
JR Z,GO5 ;JUMP IF NO BP
;
DEC B ;IF TOO MANY BP,
JP Z,ERROR ;ERROR.
LD L,(HL) ;HL = BPSP
;
INC HL ;BUMP BPSP
EX DE,HL ;DE = BPSP, HL= BP ADDR
LDI
DEC HL
LD (HL),0C7H+RSTLC ;RST INSTRUCTION
EX DE,HL ;HL = BPSP
LD (HL),E ;BP ADDR TO STACK
INC HL
LD (HL),D
INC HL
LD (HL),BPMRK ;PUNCTUATION (BP SET)
LD (IX),L
JR GO1
; CHANGE USER PC
GO5: DEC HL
LD (HL),D
DEC HL
LD (HL),E
JR GO1 ;BACK FOR MORE
;
RETN: POP HL ;STRIP ADDR FROM STK
POP HL ;UHL'
POP DE ;UDE'
POP BC ;UBC'
POP AF ;UAF'
EXX
EX AF,AF'
;
POP AF ;UIN
LD I,A ; UI
DI
JR NC,RT1
EI
;IFF NOW RESTORED
RT1: POP IY ;UIY
POP IX ;UIX
POP DE ;USP
;
;COPY THE REMAINDER OF THE SYS STACK
;TO THE USER STACK. IF THIS TRANSFER
;IS MADE WITHOUT ERROR, SWITCH TO THE
;USER STACK. OTHERWISE, RETAIN THE
;SYSTEM STACK.
;
LD HL,10D
LD B,L
ADD HL,SP
EX DE,HL
RT2: DEC DE
DEC HL
LD A,(DE)
LD (HL),A
CP (HL)
JR NZ,RT3
DJNZ RT2
LD SP,HL
;
RT3: POP HL
POP DE
POP BC
POP AF
RET
; COMMAND. DISPLAY REGISTERS.
;
; DR
;
; COMMAND. DISPLAY MEMORY.
;
; DM
;
DISPL: LD BC,[['A'+CASE] SHL 8]+80H ;[FOR DR]
JR NZ,SUBR2 ;IF NOT 'M', DR
;
;
DSPM: CALL L2NCR0 ;GET OPERANDS
DSPM1: LD D,16 ;BYTE COUNT
CALL PCADDR ;ADDRESS
DM2: CALL PSNM ;MEM CONTENTS
CPI ;INC HL & DEC BC
JP PO,CRLF
DEC D
JR Z,DSPM1
LD A,D
AND 3
CALL Z,SPACE
CALL Z,SPACE
JR DM2
;
;
; COMMAND. SUBSTITUTE MEMORY LOCATION.
;
; SM
;
; COMMAND. SUBSTITUTE USER-REGISTER.
;
; S
;
; REGISTER NAMES: P [PC] , S [SP]
; A, F, B, C, D, E, H [HL]
; I, N [1FF], X [IX], Y [IY]
; A',F',B',C',D',E',H' [HL'].
;
SUBST: JR NZ,SUBR ;IN NOT 'M', SR
SUBM: SUB A
LD B,A ;1-BYTE MASK
CALL L1NCR
EX DE,HL ;HL GETS ADDR
SM1: CALL Z,PCADDR
CALL Z,SPACE
; PRINT CURRENT VALUE, REQUEST NEW VALUE &
; PRINT IT IF GIVEN
CALL GSUBV
RET Z ;IF CR, DONE.
INC HL
LD A,7 ;PRINT ADDRESS IF IT
AND L ;IS A MULTIPLE OF 8
JR SM1
;
;
SUBR: LD B,A
CALL GCHR
CP ''''
JR NZ,SR2
INC C ;TURN ON THE PRIME-FLAG
SUBR2: SUB A
SR2: CALL SKSGCR ;WAIT FOR CR
SR3: LD A,B
SUB 'A'+CASE ;CHECK THE RANGE
JP C,ERROR
CP 'Y'-'A'+1
JP NC,ERROR
LD E,A
LD D,0
LD HL,RGTBL
ADD HL,DE
LD A,(HL)
OR A
JR Z,SR6 ;IF ENTRY = 0, SKIP
LD E,0
BIT 0,C ;PRIME?
JR Z,SR4
BIT PF,(HL) ;YES. PRIMEABLE REG?
JR Z,SR6 ;IF NOT, SKIP.
LD E,DUAF-DUAF2
SR4: AND 1FH ;STRIP FLAGS FROM ENTRY
ADD E
LD E,A
PUSH BC ;SAVE
LD A,B ;PRINT REG NAME
CALL PCHR
CP 'H'+CASE
LD A,'L'+CASE
CALL Z,PCHR
XOR 'L'+CASE XOR '=' ;CLEAR CY, A = '='.
BIT 0,C ; PRIME?
JR Z,SR5
LD A,''''
SR5: CALL PCHR
LD B,(HL) ;SAVE ORIGINAL ENTRY
PUSH IX
POP HL ;STACK FRAME
SBC HL,DE ;HL -> USER REG
CALL GSUBV ;PRINT VALUE, REQUEST NEW
LD A,B ;SAVE
POP BC
RET Z ;DONE IF CR
;
SR6: INC B ;NEXT REG
RLCA ;Y OR H?
JR NC,SR3 ;IF NEITHER, LOOP
RLCA ;YES, IS IT Y?
SUBR3: CALL CRLF ; [ENTRY FOR DISPLAYING PC
JR C,SR8
LD B,'A'+CASE ;YES, IT IS Y.
INC C ;TURN ON PRIME-FLAG
JR SR3
SR8: BIT 0,C ;NO. H OR H'?
JR Z,SR3 ;IF H, LOOP.
RET ;IT IS H'. DONE.
; ENTER WITH HL POINTING TO MEMORY &
; B CONTAINING THE 1-BYTE OR 2-BYTE FLAG.
; PRINTS SPACE, CONTENTS OF (HL), & ALSO (HL-1) FOR
; 2-BYTE REGS, GETS SUBSTITUTION VALUE & LOADS IT.
; RETURNS WITH Z-FLAG SET 1FF THE DELIMITER IS
; A CARRIAGE-RETURN.
; PRESERVES BC & HL.
;
GSUBV: CALL PNM ;PRINT (HL)
BIT B2F,B ;2-BYTE REG?
JR Z,GS1
DEC HL
CALL PNM ;LO BYTE
GS1: LD A,C ;SUBST-OR-DISPLAY FLAG
RLCA
JR C,GS2 ;IF DISPLAY, EXIT.
LD A,'.'
CALL PCHR
CALL GCHR
CP '.'+1 ;SUBSTITUTION?
GS2: CALL C,PCHR ;IF NOT, PRINT ANOTHER.
JR C,GS3
EX DE,HL
CALL GNHL ;NEW VALUE
EX DE,HL
LD (HL),E
BIT B2F,B
JR Z,GS3
INC HL
LD (HL),D
GS3: CP CR
CALL NZ,SPACE
RET
;
;
;...SUBDM 00 7E 5 585 BY 5 100 DBE++
;
;
; COMMAND
; SELECT UART-A OR UART-B.
;
; UA
; UB
;
UART: CALL L1NCR ;A OR B?
LD A,E
CP 0BH
JR NZ,UARTA
LD A,80H
OUT APARLP,A
RET
;
UARTA: SUB A
OUT BPARLP,A
RET
;
;
; COMMAND
; READ BINARY INPUT FROM DATA PORT
;
READB: CALL L2NCR ;GET MEM ADDRS
RB1: CALL CHKIN ;GET INPUT
JR Z,RB1
LD (HL),A ;TO MEM
CPI
RET PO
JR RB1
;
;
; COMMAND
; WRITE BINARY OUTPUT TO DATA PORT
WRITB: CALL L2NCR ;GET MEM ADDRS
WB1: LD A,(HL)
CALL PBYTE
CPI
RET PO
JR WB1
;
;
; COMMAND
; PRINT NULLS ON THE CURRENT DEVICE.
;
; N
;
NULLS: CALL L1NCR
LD B,E
SUB A
N2: CALL PCHR
DJNZ N2
RET
;
;
; COMMAND
; OUT
;
OUTP: CALL GNHL
EX DE,HL ;E GETS DATA
CALL L1NCR ;GET PORT NUMBER
;
LD C,E ; TO C
OUT (C),L
RET
;
; BAUD RATES.
; WITH THE CROMEMCO TUART: 19200, 9600, 4800,
; 2400, 1200, 300, 150, 110.
;
; WITH THE 3P+S: 2400, 300, 110.
;
;
BAUDRS: DB 94H,0CEH,0A2H,92H,88H,84H,82H,1
;
;
LFNN: DB LF,0,0 OR 80H
;
;
PRMPT: DB ':' OR 80H
; THE COMMAND TBL MUST IMMEDIATELY FOLLOW
;
; THE PROMPT MESSAGE
DW DISPL ;DISPLAY: DM, DR
DW ERROR ;E
DW ERROR
DW GO ;GO; GO/WITH BREAKPOINTS
DW ERROR
DW INITBAUD ;INITIALIZE BAUD RATE
DW ERROR ;J
DW ERROR ;K
DW ERROR ;L
DW MOVE ;MOVE A BLOCK OF MEMORY
DW NULLS ;NULLS
DW OUTP ;OUTPUT
DW PROG ;PROGRAM
DW ERROR ;Q
DW READB ;READ BINARY OR ASCII
DW SUBST ;SUBSTITUTE: SM, SA, SB.
DW ERROR ;T
DW UART ;UART: UA, UB
DW VERIF ;VERIFY BLOCKS OF MEMORY
DW WRITB ;WRITE BINARY OR ASCII
;
PM: EQU 1 SHL PF ;PRIMEABLE-REG MASK
B1M: EQU 0 ;1-BYTE REG MASK
B2M: EQU 1 SHL B2F ;2-BYTE REG MASK
CRM: EQU 1 SHL CRF ;CARRIAGE-RETURN MASK
RGTBL: DB -DUAF OR PM ;A
DB -DUBC OR PM ;B
DB -DUBC+1 OR PM ;C
DB -DUDE OR PM ;D
DB -DUDE+1 OR PM ;E
DB -DUAF+1 OR PM ;F
DB 0
DB -DUHL OR PM OR B2M OR CRM ;H [HL]
DB -DUIN OR B1N ;I
DB 0
DB 0
DB 0
DB 0
DB -DUIN+1 OR B1M ;N [INTERRUPT FF]
DB 0
DB -DUPC OR B2M ;PC
DB 0
DB 0
DB -DUSP OR B2M ;SP
DB 0
DB 0
DB 0
DB 0
DB -DUIX OR B2M ;X [IX]
DB -DUIY OR B2M OR CRM ;Y [IY]
;
;
HEAD: DB CR,CR, 'CROMEMCO ZM1.','4' OR 80H
END CSTART