Files
RomWBW/Source/HBIOS/dbgmon.asm
Wayne Warthen f8c800e527 Create DSKY Driver Framework
Added a new driver category for DSKY (Display/Keypad) devices.  Existing DSKY devices were converted into drivers ICM and PKD.  These devices were previously DSKY and DSKYNG.

This removes substantial code duplication and recovers significant space in romldr and dbgmon.
2023-06-28 15:06:53 -07:00

1903 lines
52 KiB
NASM

;___ROM_MONITOR_PROGRAM_______________________________________________________
;
; ORIGINAL CODE BY: ANDREW LYNCH (LYNCHAJ@YAHOO COM) 13 FEB 2007
;
; MODIFIED BY : DAN WERNER 03 09.2009
;
;__REFERENCES_________________________________________________________________
; THOMAS SCHERRER BASIC HARDWARE TEST ASSEMBLER SOURCES FROM THE Z80 INFO PAGE
; INCLUDING ORIGINAL SCHEMATIC CONCEPT
; HTTP://Z80.INFO/Z80SOURC.TXT
; CODE SAMPLES FROM BRUCE JONES PUBLIC DOMAIN ROM MONITOR FOR THE SBC-200C
; HTTP://WWW.RETROTECHNOLOGY.COM/HERBS_STUFF/SD_BRUCE_CODE.ZIP
; INSPIRATION FROM JOEL OWENS "Z-80 SPACE-TIME PRODUCTIONS SINGLE BOARD COMPUTER"
; HTTP://WWW.JOELOWENS.ORG/Z80/Z80INDEX.HTML
; GREAT HELP AND TECHNICAL ADVICE FROM ALLISON AT ALPACA_DESIGNERS
; HTTP://GROUPS.YAHOO.COM/GROUP/ALPACA_DESIGNERS
; INTEL SDK-85 ROM DEBUG MONITOR
;_____________________________________________________________________________
;
#INCLUDE "std.asm"
;
BUFLEN .EQU 40 ; INPUT LINE LENGTH
;
;__MAIN_PROGRAM_______________________________________________________________
;
; ORG 00100h ; FOR DEBUG IN CP/M (AS .COM)
.ORG MON_LOC
;
;__ENTRY JUMP TABLE___________________________________________________________
;
JP DSKY_ENTRY
JP UART_ENTRY
;
ENA_XM .EQU TRUE ; INCLUDE XMODEM
;
ENA_MBC6502 .EQU FALSE ; ENABLE OR DISABLE MBC6502 OPTION
;
;__UART_ENTRY_________________________________________________________________
;
; SERIAL MONITOR STARTUP
;_____________________________________________________________________________
;
UART_ENTRY:
LD SP,MON_STACK ; SET THE STACK POINTER
;EI ; INTS OK NOW
LD HL,UART_ENTRY ; RESTART ADDRESS
CALL INITIALIZE ; INITIALIZE SYSTEM
LD HL,TXT_READY ; POINT AT TEXT
CALL PRTSTRH ; SHOW WE'RE HERE
;
;__SERIAL_MONITOR_COMMANDS____________________________________________________
;
; B - BOOT SYSTEM
; D XXXX YYYY - DUMP MEMORY IN RANGE XXXX-YYYY
; F XXXX YYYY ZZ - FILL MEMORY IN RANGE XXXX-YYYY WITH ZZ
; H - HALT SYSTEM
; I XXXX - SHOW VALUE AT PORT XXXX
; K - ECHO KEYBOARD INPUT
; L - LOAD INTEL HEX FORMAT DATA
; M XXXX YYYY ZZZZ - MOVE MEMORY BLOCK XXXX-YYYY TO ZZZZ
; O XXXX YY - OUTPUT VALUE YY TO PORT XX
; P XXXX - PROGRAM RAM STARTING AT XXXX, PROMPT FOR VALUES
; R XXXX - RUN A PROGRAM AT ADDRESS XXXX
; S XX - SET ACTIVE BANK TO XX
; T XXXX - X-MODEM TRANSFER TO MEMORY LOCATION XXXX
; U - SET BANK TO PREVIOUS BANK
; 6 XX - TRANSFER CONTROL TO MBC6502 UNIT XX
; X - EXIT MONITOR
;
;__COMMAND_PARSE______________________________________________________________
;
; PROMPT USER FOR COMMANDS, THEN PARSE THEM
;_____________________________________________________________________________
;
SERIALCMDLOOP:
LD SP,MON_STACK ; RESET STACK
CALL NEWLINE
#IF (BIOS == BIOS_WBW)
LD A,($FFE0) ; DISPLAY CURRENTLY ACTIVE
CALL PRTHEXBYTE ; BANK IN LOW MEMORY
#ENDIF
LD A,'>'
CALL COUT
LD HL,KEYBUF ; SET POINTER TO KEYBUF AREA
CALL GETLN ; GET A LINE OF INPUT FROM THE USER
LD HL,KEYBUF ; RESET POINTER TO START OF KEYBUF
LD A,C ; GET LINE LENGTH ENTERED
OR A ; ZERO?
JR Z,SERIALCMDLOOP ; NOTHING ENTERED, LOOP
LD A,(HL) ; LOAD FIRST CHAR INTO A (THIS SHOULD BE THE COMMAND)
INC HL ; INC POINTER
CP 'B' ; IS IT "B" (Y/N)
JP Z,BOOT ; IF YES BOOT
CP 'R' ; IS IT "R" (Y/N)
JP Z,RUN ; IF YES GO RUN ROUTINE
CP 'P' ; IS IT "P" (Y/N)
JP Z,PROGRM ; IF YES GO PROGRAM ROUTINE
CP 'O' ; IS IT AN "O" (Y/N)
JP Z,POUT ; PORT OUTPUT
#IF (ENA_XM)
CP 'T' ; IS IT A "T" (Y/N)
JP Z,XMLOAD ; XMODEM TRANSFER
#ENDIF
CP 'L' ; IS IT A "L" (Y/N)
JP Z,HXLOAD ; INTEL HEX FORMAT LOAD DATA
CP 'I' ; IS IT AN "I" (Y/N)
JP Z,PIN ; PORT INPUT
CP 'D' ; IS IT A "D" (Y/N)
JP Z,DUMPMEM ; DUMP MEMORY
CP 'K' ; IS IT A "K" (Y/N)
JP Z,KLOP ; LOOP ON KEYBOARD
CP 'M' ; IS IT A "M" (Y/N)
JP Z,MOVEMEM ; MOVE MEMORY COMMAND
CP 'F' ; IS IT A "F" (Y/N)
JP Z,FILLMEM ; FILL MEMORY COMMAND
CP '?' ; IS IT A "?" (Y/N)
JP Z,HELP ; HELP COMMAND
CP 'H' ; IS IT A "H" (Y/N)
JP Z,HALT ; HALT COMMAND
#IF (BIOS == BIOS_WBW)
CP 'S' ; IS IT A "S" (Y/N)
JP Z,SETBNK ; SET BANK COMMAND
CP 'U' ; IS IT A "U" (Y/N)
JP Z,UNSETBNK ; UNSET (REVERT) BANK COMMAND
#IF ((PLATFORM = PLT_MBC) & ENA_MBC6502)
CP '6' ; IS IT A "6" (Y/N)
JP Z,MBC6502 ; TRANSFER TO MBC6502 COMMAND
#ENDIF
#ENDIF
CP 'X' ; IS IT A "X" (Y/N)
JP Z,EXIT ; EXIT COMMAND
LD HL,TXT_COMMAND ; POINT AT ERROR TEXT
CALL PRTSTRH ; PRINT COMMAND LABEL
JR SERIALCMDLOOP
;
;__INITIALIZE_________________________________________________________________
;
; INITIALIZE SYSTEM
; AT ENTRY, HL SHOULD HAVE ADDRESS OF DESIRED RESTART ADDRESS
;_____________________________________________________________________________
;
INITIALIZE:
;
#IF (BIOS == BIOS_UNA)
; INSTALL UNA INVOCATION VECTOR FOR RST 08
LD A,$C3 ; JP INSTRUCTION
LD (8),A ; STORE AT 0x0008
LD HL,($FFFE) ; UNA ENTRY VECTOR
LD (9),HL ; STORE AT 0x0009
#ENDIF
;
RET
;
;__BOOT_______________________________________________________________________
;
; PERFORM BOOT ACTION
;_____________________________________________________________________________
;
BOOT:
#IF (BIOS == BIOS_UNA)
LD BC,$01FB ; UNA FUNC = SET BANK
LD DE,0 ; ROM BANK 0
CALL $FFFD ; DO IT (RST 08 NOT SAFE HERE)
JP 0 ; JUMP TO RESTART ADDRESS
#ELSE
;LD A,BID_BOOT ; BOOT BANK
;LD HL,0 ; ADDRESS ZERO
;CALL HB_BNKCALL ; DOES NOT RETURN
LD B,BF_SYSRESET ; SYSTEM RESTART
LD C,BF_SYSRES_COLD ; COLD START
CALL $FFF0 ; CALL HBIOS
#ENDIF
;
;__EXIT_______________________________________________________________________
;
; PERFORM EXIT ACTION
;_____________________________________________________________________________
;
EXIT:
#IF (BIOS == BIOS_UNA)
JR BOOT
#ELSE
LD B,BF_SYSRESET ; SYSTEM RESTART
LD C,BF_SYSRES_WARM ; WARM START
CALL $FFF0 ; CALL HBIOS
#ENDIF
;
;__HALT_______________________________________________________________________
;
; PERFORM HALT ACTION
;_____________________________________________________________________________
;
HALT:
DI
HALT
;
;__SETBNK_____________________________________________________________________
;
; PERFORM SET BANK ACTION
;_____________________________________________________________________________
;
#IF (BIOS == BIOS_WBW)
;
SETBNK:
#IF (INTMODE == 1)
LD HL,TXT_IMERR
CALL PRTSTR
#ELSE
LD A,($FFE0) ; GET AND SAVE
LD (BNKSAV),A ; CURRENT BANK
CALL BYTEPARM ; GET BANK NUMBER
JP C,ERR ; HANDLE DATA ENTRY ERROR
LD C,A ; PUT IN C FOR FOR FUNC CALL
LD B,BF_SYSSETBNK ; SET BANK FUNCTION
CALL $FFF0 ; C HAS BANK, DO IT
#ENDIF
JP SERIALCMDLOOP ; NEXT COMMAND
;
;__UNSETBNK___________________________________________________________________
;
; PERFORM UNSET BANK ACTION - REVERT TO BANK BEFORE PREVIOUS SET
;_____________________________________________________________________________
;
UNSETBNK:
#IF (INTMODE == 1)
LD HL,TXT_IMERR
CALL PRTSTR
#ELSE
LD A,(BNKSAV)
LD C,A ; PUT IN C FOR FOR FUNC CALL
LD B,BF_SYSSETBNK ; SET BANK FUNCTION
CALL $FFF0 ; C HAS BANK, DO IT
#ENDIF
JP SERIALCMDLOOP ; NEXT COMMAND
;
BNKSAV .DB 00H ; OLD BANK FROM BEFORE SET
;
#ENDIF
;
;__RUN________________________________________________________________________
;
; TRANSFER OUT OF MONITOR, USER OPTION "R"
; SYNTAX: R <ADDR> [<A-VALUE> [<BC-VALUE>]]
;_____________________________________________________________________________
;
RUN:
CALL WORDPARM ; GET START ADDRESS
JP C,ERR ; HANDLE ERRORS
PUSH DE ; SAVE VALUE
CALL BYTEPARM ; GET OPTIONAL
PUSH AF ; A REGISTER VALUE
CALL WORDPARM ; GET OPTIONAL
PUSH DE ; BC REGISTER VALUE
CALL NONBLANK ; LOOK FOR EXTRANEOUS PARAMETERS
CP 0 ; TEST FOR TERMINATING NULL
JP NZ,ERR ; ERROR IF NOT TERMINATING NULL
POP BC ; RECOVER BC REGISTER VALUE TO PASS
POP AF ; RECOVER A REGISTER VALUE TO PASS
POP HL ; RECOVER START ADDRESS
;
LD DE,PREG1 ; SETUP A RETURN
PUSH DE ; ADDRESS
;
JP (HL) ; GO
;
PREG1: PUSH BC ; SAVE
PUSH DE ; REGISTERS
PUSH HL ; FOR DISPLAY
;
CALL NEWLINE
CALL PRTHEXBYTE ; DISPLAY A
CALL PC_SPACE ; REGISTER
;
LD B,3
PREG2: POP HL ; DISPLAY
CALL PHL ; HL DE BC
CALL PC_SPACE ; REGISTER
DJNZ PREG2
JP SERIALCMDLOOP
;
;__PROGRM_____________________________________________________________________
;
; PROGRAM RAM LOCATIONS, USER OPTION "P"
;_____________________________________________________________________________
;
PROGRM:
CALL WORDPARM ; GET STARTING LOCATION
JP C,ERR ; HANDLE SYNTAX ERRORS
PUSH DE ; SAVE VALUE
CALL NONBLANK ; LOOK FOR EXTRANEOUS PARAMETERS
CP 0 ; TEST FOR TERMINATING NULL
JP NZ,ERR ; ERROR IF NOT TERMINATING NULL
PROGRM1:
CALL NEWLINE
POP HL
PUSH HL
CALL PHL
CALL PC_COLON ; DISPLAY
CALL PC_SPACE ; CURRENT
POP HL ; VALUE
PUSH HL
LD A,(HL)
CALL PRTHEXBYTE
CALL PC_SPACE
LD HL,KEYBUF ; GET AND
CALL GETLN ; SAVE NEW
LD HL,KEYBUF ; VALUE
CALL NONBLANK
CP 0
JP Z,SERIALCMDLOOP
CALL BYTEPARM
JR C,PROGRM2 ; SYNTAX ERROR
POP DE
LD (DE),A
INC DE
PUSH DE
JR PROGRM1
PROGRM2:
LD HL,TXT_BADNUM
CALL PRTSTR
JR PROGRM1
;
;__KLOP_______________________________________________________________________
;
; READ FROM THE SERIAL PORT AND ECHO, MONITOR COMMAND "K"
;_____________________________________________________________________________
;
KLOP:
CALL NEWLINE ;
KLOP1:
CALL KIN ; GET A KEY
CP CHR_ESC ; IS <ESC>?
JP Z,SERIALCMDLOOP ; IF SO, ALL DONE
CALL COUT ; OUTPUT KEY TO SCREEN
JR KLOP1 ; LOOP
;
#IF (ENA_XM)
;
;__XMLOAD_____________________________________________________________________
;
; LOAD A FILE INTO MEMORY FROM THE SERIAL PORT USING X-MODEM PROTOCOL
;
SOH: .EQU 'A'-40h ; ^A CTRL-A
EOT: .EQU 'D'-40h ; ^D = End of Transmission
ACK: .EQU 'F'-40h ; ^F = Positive Acknowledgement
NAK: .EQU 'U'-40h ; ^U = Negative Acknowledgement
CAN: .EQU 'X'-40h ; ^X = Cancel
;
CPKTN .DB 0 ; CALCULATED PACKET NUMBER
CPKTN1C .DB 0 ; CALCULATED PACKET NUMBER COMPLEMENT
RETRYC .DB 0 ; RETRY COUNT
RPKTN: .DB 0 ; RECEIVED PACKET NUMBER
RPKTN1C:.DB 0 ; RECEIVED PACKET NUMBER COMPLEMENT
PKTCS .DB 0 ; CHECKSUM
;
PSADDR: .DW 0 ; START OF PACKET ADDR
;
XMLOAD: CALL WORDPARM ; GET STARTING LOCATION
JP C,ERR ; HANDLE SYNTAX ERRORS
PUSH DE ; SAVE VALUE
CALL NONBLANK ; LOOK FOR EXTRANEOUS PARAMETERS
CP 0 ; TEST FOR TERMINATING NULL
JP NZ,ERR ; ERROR IF NOT TERMINATING NULL
;
LD HL,TXT_READY ; READY FOR
CALL PRTSTR ; TRANSFER
CALL NEWLINE
;
LD BC,$F8F0 ; GET CPU SPEED
CALL $FFF0 ; CALL HBIOS
; RST 08 ; AND MULTIPLY
LD A,L ; BY 4
PUSH AF
ADD A,A ; TO CREATE
ADD A,A ; TIMEOUT DELAY
LD (TMOFCT),A ; FACTOR
POP AF
;
LD BC,$FE01 ; SET FIRST NUMBER TO 1
LD (CPKTN),BC ; ALSO STORE THE 1-COMPLEMENT
;
POP DE ; POINT TO WHERE TO SAVE THE PACKET
LD (PSADDR),DE ; SAVE IF FOR THE CHECKSUM CALCULATION
;
GETNP: LD HL,RETRYC ; WE RETRY 20 TIMES BEFORE GIVING UP
LD (HL),20
;
NPLOOP: LD B,6 ; 6 SECONDS OF TIMEOUT BEFORE EACH NEW BLOCK
CALL GCTO
JP NC,NOTOUT ; NO TIMEOUT ?
;
DEC (HL) ; REACHED MAX NUMBER OF RETRIES?
JP Z,FAILRT ; YES, PRINT MESSAGE AND EXIT
;
LD A,NAK ; SEND A NAK TO THE UPLOADER
CALL COUT
JR NPLOOP ; LOOP UNTIL WE GET A GET A CHARACTOR OR TIMEOUT
;
NOTOUT: CP EOT ; DID UPLOADER SAY WE'RE FINISHED?
JP Z,XMDONE ; YES, THEN WE'RE DONE
CP CAN ; UPLOADER WANTS TO FAIL TRANSFER?
JP Z,FAILCN ; YES, THEN WE'RE ALSO DONE
CP SOH ; DID WE GET A START-OF-NEW-PACKET?
JR NZ,NPLOOP ; NO, GO BACK AND TRY AGAIN
;
LD HL,RPKTN ; WE SAVE PACKET NUMBER HERE
;
CALL GCTO1 ; WAIT ONE SECOND FOR A CHARACTER
LD (HL),A ; SHOULD BE PACKET NUMBER
INC HL
JR C,FAILTO ; TIMOUT ERROR?
;
CALL GCTO1 ; WAIT ONE SECOND FOR A CHARACTER
LD (HL),A ; SHOULD BE PACKET NUMBER COMPLEMENT
JR C,FAILTO ; TIMOUT ERROR?
LD C,128 ; GET 128 MORE CHARACTERS FOR A FULL PACKET
PCKRCV: CALL GCTO1 ; WAIT ONE SECOND FOR A CHARACTER
JR C,FAILTO ; TIMOUT ERROR?
LD (DE),A ; SAVE THE RECEIVED CHAR
INC DE
DEC C
JP NZ,PCKRCV
;
CALL GCTO1 ; WAIT ONE SECOND FOR A CHARACTER
JR C,FAILTO ; TIMOUT ERROR?
LD (PKTCS),A ; SHOULD BE CHECKSUM
;
LD HL,(PSADDR) ; CALCULATE CHECKSUM FROM 128 BYTES OF DATA
LD B,128
XOR A
CSLOOP: ADD A,(HL) ; JUST ADD UP THE BYTES
INC HL
DJNZ CSLOOP
;
LD (PSADDR),DE ; SAVE THE NEW PACKET START ADDRESS
;
LD HL,PKTCS
XOR (HL) ; HL POINTS TO THE RECEIVED CHECKSUM SO
JR NZ,FAILCS ; BY XORING IT TO OUR SUM WE CHECK FOR EQUALITY
;
LD HL,(CPKTN) ; CHECK
LD BC,(RPKTN) ; AGREEMENT
; XOR A ; PACKET
SBC HL,BC ; NUMBERS
JR NZ,FAILPN
;
LD HL,CPKTN ; UPDATE THE PACKET COUNTERS
INC (HL)
INC HL
DEC (HL)
;
LD A,ACK ; TELL UPLOADER THAT WE'RE HAPPY WITH WITH
CALL COUT ; PACKET AND GO BACK AND FETCH SOME MORE
JP GETNP
;
FAILRT: LD HL,TXT_RETRYERR ; FAILED ON RETRY
JR XMERR
FAILCN: LD HL,TXT_CANCLERR ; TRANSFER CANCELLED
JR XMERR
FAILCS: LD HL,TXT_CKSUMERR ; CHECKSUM ERROR
JR XMERR
FAILPN: LD HL,TXT_PKNUMERR ; PACKET NUMBER ERROR
JR XMERR
FAILTO: LD HL,TXT_TMOUTERR ; TIMEOUT ERROR
JR XMERR
;
XMDONE: LD A,ACK ; TELL REMOTE
CALL COUT ; WE'RE DONE
LD HL,TXT_LOADED ; TELL USER
XMERR: CALL PRTSTR ; WE'RE DONE
JP SERIALCMDLOOP ; BACK TO MENU
;
; WAITS FOR UP TO B SECONDS FOR A CHARACTER TO BECOME AVAILABLE AND
; RETURNS IT IN A WITHOUT ECHO AND CARRY CLEAR. IF TIMEOUT THEN CARRY
; IT SET.
;
; 4MHZ 20 SECONDS TMOFCT = 16
; 10MHZ 20 SECONDS TMOFCT = 39
;
GCTO1: LD B,1 ; WAIT 1 SECOND FOR SERIAL INPUT
GCTO: CALL CST ; IF THERE IS A
OR A ; CHARACTER AVAILABLE
JR NZ,GETCHRX ; EXIT NOW OTHERWISE POLL
GCTOA: PUSH BC
LD BC,255 ; C=CONSTANT (255) FOR INNER TIMING LOOP
TMOFCT: .EQU $-1 ; B=SPEED FACTOR WHICH GETS UPDATED AT START
GCTOB: PUSH BC
LD B,C
GCTOC: PUSH BC
CALL CST
OR A ; A CHAR AVAILABLE?
JR NZ,GETCHR ; YES, GET OUT OF LOOP
POP BC
DJNZ GCTOC
POP BC
DJNZ GCTOB
POP BC
DJNZ GCTO
SCF ; SET CARRY SIGNALS
RET ; TIMEOUT OCCURRED
GETCHR: POP BC
POP BC
POP BC
GETCHRX:CALL CIN ; GET THE CHARACTER
OR A ; CLEAR CARRY
RET ; SIGNALS SUCCESS
TXT_PKNUMERR .TEXT "\r\nPacket Number Error$"
TXT_TMOUTERR .TEXT "\r\nTimeout Error$"
TXT_RETRYERR .TEXT "\r\nRetry Error$"
TXT_CANCLERR .TEXT "\r\nTransfer Cancelled$"
#ENDIF
;
;__HXLOAD_____________________________________________________________________
;
; LOAD INTEL HEX FORMAT FILE FROM THE SERIAL PORT, USER OPTION "H"
;
; [INTEL HEX FORMAT IS:
; 1) COLON (FRAME 0)
; 2) RECORD LENGTH FIELD (FRAMES 1 AND 2)
; 3) LOAD ADDRESS FIELD (FRAMES 3,4,5,6)
; 4) RECORD TYPE FIELD (FRAMES 7 AND 8)
; 5) DATA FIELD (FRAMES 9 TO 9+2*(RECORD LENGTH)-1
; 6) CHECKSUM FIELD - SUM OF ALL BYTE VALUES FROM RECORD LENGTH TO AND
; INCLUDING CHECKSUM FIELD = 0 ]
;
; EXAMPLE OF INTEL HEX FORMAT FILE
; EACH LINE CONTAINS A CARRIAGE RETURN AS THE LAST CHARACTER
; :18F900002048454C4C4F20574F524C4420FF0D0AFF0D0A3EFF0D0A54BF
; :18F918006573742050726F746F7479706520524F4D204D6F6E69746FF1
; :18F9300072205265616479200D0AFF0D0A434F4D4D414E4420524543F2
; :18F948004549564544203AFF0D0A434845434B53554D204552524F52CD
; :16F96000FF0A0D20202D454E442D4F462D46494C452D20200A0DA4
; :00000001FF
;_____________________________________________________________________________
;
HXLOAD:
CALL NEWLINE ; SHOW READY
HXLOADLINE:
CALL CIN ; GET THE FIRST CHARACTER, EXPECTING A ':'
CP ':' ; IS IT COLON ':'? WAIT FOR START OF NEXT LINE OF INTEL HEX FILE
JR NZ,HXLOADLINE ; IF NOT, GO BACK TO WAIT
LD E,0 ; RESET THE CHECKSUM BYTE <E>
CALL HEXINS ; FIRST TWO CHARACTERS IS THE RECORD LENGTH FIELD <D>
LD D,A ; LOAD RECORD LENGTH COUNT INTO D
CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS <H>
LD H,A ; PUT VALUE IN H REGISTER
CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS <L>
LD L,A ; PUT VALUE IN L REGISTER
CALL HEXINS ; GET NEXT TWO CHARACTERS, RECORD FIELD TYPE
DEC A ; RECORD FIELD TYPE 01 IS END OF FILE
JR Z,HXLOADEXIT ; MUST BE THE END OF THAT FILE
INC A ; RECORD FIELD TYPE 00 IS DATA
JR NZ,HXLOADTYPERR ; RECORD TYPE IS INCORRECT, ERROR OUT
HXLOADDATA:
CALL HEXINS ; GET NEXT TWO CHARACTERS, ASSEMBLE INTO BYTE
LD (HL),A ; MOVE CONVERTED BYTE IN A TO MEMORY LOCATION
INC HL ; INCREMENT POINTER TO NEXT MEMORY LOCATION
DEC D ; DECREMENT LINE CHARACTER COUNTER
JR NZ,HXLOADDATA ; AND KEEP LOADING INTO MEMORY UNTIL LINE IS COMPLETE
CALL HEXINS ; GET NEXT TWO CHARACTERS, ASSEMBLE INTO CHECKSUM BYTE
LD A,E ; RECALL THE CHECKSUM BYTE
OR A ; IT SHOULD BE ZERO
JR Z,HXLOADLINE ; ZERO, SO WE HAVE NO ERROR, GO GET ANOTHER LINE
HXLOADCHKERR:
LD HL,TXT_CKSUMERR ; GET "CHECKSUM ERROR" MESSAGE
CALL PRTSTR ; PRINT MESSAGE FROM (HL) AND TERMINATE THE LOAD
JP SERIALCMDLOOP ; RETURN TO PROMPT
HXLOADTYPERR:
LD HL,TXT_RECORDERR ; GET "RECORD TYPE ERROR" MESSAGE
CALL PRTSTR ; PRINT MESSAGE FROM (HL) AND TERMINATE THE LOAD
JP SERIALCMDLOOP ; RETURN TO PROMPT
HXLOADEXIT:
CALL HEXINS ; GET LAST TWO CHARACTERS, ASSEMBLE INTO CHECKSUM BYTE
LD A,E ; RECALL THE CHECKSUM BYTE
OR A ; IT SHOULD BE ZERO
JR NZ,HXLOADCHKERR ; CHECKUM IS INCORRECT, ERROR OUT
LD HL,TXT_LOADED ; GET "LOADED" MESSAGE
CALL PRTSTR ; PRINT MESSAGE FROM (HL)
JP SERIALCMDLOOP ; RETURN TO PROMPT
;
;__POUT_______________________________________________________________________
;
; OUTPUT TO AN I/O PORT, MONITOR COMMAND "O"
; SYNTAX: O <PORT> <VALUE>
; NOTE: A WORD VALUE IS USED FOR THE PORT NUMBER BECAUSE THE
; Z80 WILL ACTUALLY PLACE 16 BITS ON THE BUS USING
; THE B AND C REGISTERS WITH AN "OUT (C),A" INSTRUCTION
;_____________________________________________________________________________
;
POUT:
CALL WORDPARM ; GET PORT NUMBER
JP C,ERR ; HANDLE ERRORS
PUSH DE ; SAVE IT FOR NOW
CALL BYTEPARM ; GET VALUE TO WRITE
JP C,ERR ; HANDLE ERRORS
POP BC ; RESTORE PORT NUMBER TO BC
OUT (C),A ; SEND VALUE TO PORT
JP SERIALCMDLOOP ; DONE, BACK TO COMMAND LOOP
;
;__PIN________________________________________________________________________
;
; INPUT FROM AN I/O PORT, MONITOR COMMAND "I"
; SYNTAX: I <PORT>
; NOTE: A WORD VALUE IS USED FOR THE PORT NUMBER BECAUSE THE
; Z80 WILL ACTUALLY PLACE 16 BITS ON THE BUS USING
; THE B AND C REGISTERS WITH AN "IN A,(C)" INSTRUCTION
;_____________________________________________________________________________
;
PIN:
CALL WORDPARM ; GET PORT NUMBER
JP C,ERR ; HANDLE ERRORS
PUSH DE ; SAVE IT
CALL NEWLINE ;
POP BC ; RESTORE TO BC
IN A,(C) ; GET PORT VALUE
CALL PRTHEXBYTE ; DISPLAY IT
JP SERIALCMDLOOP ; DONE, BACK TO COMMAND LOOP
;
;__DUMPMEM____________________________________________________________________
;
; PRINT A MEMORY DUMP, USER OPTION "D"
; SYNTAX: D <START ADR> [END ADR]
; IF NO END ADDRESS, DUMP 100H BYTES
;_____________________________________________________________________________
;
DUMPMEM:
CALL WORDPARM ; GET START ADDRESS
JP C,ERR ; HANDLE ERRORS
PUSH DE ; SAVE IT
CALL WORDPARM ; GET END ADDRESS
POP HL ; RECOVER START
JR NC,GDATA ;
;
LD D,H ; DEFAULT TO 100H
LD E,L ; BYTES IF NO
INC D ; END ADDRESS
DEC DE ; IS GIVEN
;
GDATA:
INC DE ; BUMP DE FOR LATER COMPARE
CALL NEWLINE ;
BLKRD:
CALL PHL ; PRINT START LOCATION
CALL PC_COLON
CALL PC_SPACE
LD C,16 ; SET FOR 16 LOCS
PUSH HL ; SAVE STARTING HL
NXTONE:
EXX ;
LD C,E ;
IN A,(C) ;
EXX ;
AND 7FH ;
CP CHR_ESC ;
JP Z,SERIALCMDLOOP ;
CP 19 ;
JR Z,NXTONE ;
LD A,(HL) ; GET BYTE
CALL PRTHEXBYTE ; DISPLAY IT
CALL PC_SPACE ;
UPDH:
INC HL ; POINT NEXT
DEC C ; DEC LOC COUNT
JR NZ,NXTONE ; IF LINE NOT DONE
; NOW PRINT 'DECODED' DATA TO RIGHT OF DUMP
PCRLF:
CALL PC_SPACE ; SPACE IT
LD C,16 ; SET FOR 16 CHARS
POP HL ; GET BACK START
PCRLF0:
LD A,(HL) ; GET BYTE TO PRINT
CP $20 ; CONTROL CHAR (UNPRINTABLE)?
JR C,PDOT ; IF SO, PRINT A DOT
CP $7F ; 127 OR MORE (UNPRINTABLE)?
JR NC,PDOT ; IF SO, PRINT A DOT
JR PCHAR ; PRINT ACTUAL CHAR
PDOT:
LD A,2EH ; OTHERWISE SUBSTITUTE A DOT
PCHAR:
CALL COUT ; PRINT IT
INC HL ;
LD A,D ;
CP H ;
JR NZ,UPDH1 ;
LD A,E ;
CP L ;
JP Z,SERIALCMDLOOP ;
;
;IF BLOCK NOT DUMPED, DO NEXT CHARACTER OR LINE
UPDH1:
DEC C ; DEC CHAR COUNT
JR NZ,PCRLF0 ; DO NEXT
CONTD:
CALL NEWLINE ;
JR BLKRD ;
;
;__MOVEMEM____________________________________________________________________
;
; MOVE MEMORY, USER OPTION "M"
; SYNTAX: M <SRC-START> <SRC-END> <TGT>
;_____________________________________________________________________________
;
MOVEMEM:
CALL WORDPARM ; GET WORD VALUE INTO DE (MOVE SRC START ADR)
JP C,ERR ; SYNTAX ERROR IF HEXWORD FAILED
PUSH DE ; SAVE IT
CALL WORDPARM ; GET WORD VALUE INTO DE (MOVE SRC END ADR)
JP C,ERR ; SYNTAX ERROR IF HEXWORD FAILED
PUSH DE ; SAVE IT
CALL WORDPARM ; GET WORD VALUE INTO DE (MOVE TGT ADR)
JP C,ERR ; SYNTAX ERROR IF HEXBYTE FAILED
PUSH DE ; SAVE IT
CALL NONBLANK ; LOOK FOR EXTRANEOUS PARAMETERS
CP 0 ; TEST FOR TERMINATING NULL
JP NZ,ERR ; ERROR IF NOT TERMINATING NULL
POP DE ; TGT ADR TO DE
POP BC ; SRC END ADR TO BC
POP HL ; SRC START ADR TO HL
DEC HL ; PRE-DECREMENT
DEC DE ; PRE-DECREMENT
MOVEMEM1:
INC HL ; BUMP CUR SRC ADR
INC DE ; BUMP CUR TGT ADR
LD A,(HL) ; GET SOURCE VAUEE
LD (DE),A ; WRITE TO TARGET LOC
LD A,H ; CHECK MSB OF END ADR
CP B ;
JR NZ,MOVEMEM1 ; NO MATCH, LOOP
LD A,L ; CHECK LSB OF END ADR
CP C ;
JR NZ,MOVEMEM1 ; NO MATCH, LOOP
JP SERIALCMDLOOP ; LSB AND MSB MATCH, ALL DONE
;
;__FILLMEM____________________________________________________________________
;
; FILL MEMORY, USER OPTION "M"
; SYNTAX: F <START> <END> <VALUE>
;_____________________________________________________________________________
;
FILLMEM:
CALL WORDPARM ; GET WORD VALUE INTO DE (FILL START ADR)
JP C,ERR ; SYNTAX ERROR IF HEXWORD FAILED
PUSH DE ; SAVE IT
CALL WORDPARM ; GET WORD VALUE INTO DE (FILL END ADR)
JP C,ERR ; SYNTAX ERROR IF HEXWORD FAILED
PUSH DE ; SAVE IT
CALL BYTEPARM ; GET BYTE VALUE (FILL VALUE) INTO A
JP C,ERR ; SYNTAX ERROR IF HEXBYTE FAILED
LD C,A ; FILL VALUE TO C
CALL NONBLANK ; LOOK FOR EXTRANEOUS PARAMETERS
CP 0 ; TEST FOR TERMINATING NULL
JP NZ,ERR ; ERROR IF NOT TERMINATING NULL
POP DE ; END ADR TO DE
POP HL ; START ADR TO HL
DEC HL ; PRE-DECREMENT
FILLMEM1:
INC HL ; BUMP CUR ADR
LD A,C ; FILL VALUE TO A
LD (HL),A ; WRITE FILL VALUE TO CUR ADR (HL)
LD A,H ; CHECK MSB OF END ADR
CP D ;
JR NZ,FILLMEM1 ; NO MATCH, LOOP
LD A,L ; CHECK LSB OF END ADR
CP E ;
JR NZ,FILLMEM1 ; NO MATCH, LOOP
JP SERIALCMDLOOP ; LSB AND MSB MATCH, ALL DONE
;
;__HELP_______________________________________________________________________
;
; SYNTAX HELP, USER OPTION "H"
;_____________________________________________________________________________
;
HELP:
LD HL,TXT_HELP ; POINT AT SYNTAX HELP TEXT
CALL PRTSTR ; DISPLAY IT
JP SERIALCMDLOOP ; AND BACK TO COMMAND LOOP
;
;__MBC6502____________________________________________________________________
;
; TRANSFER CONTROL TO MBC6502
;_____________________________________________________________________________
;
;
#IF (BIOS == BIOS_WBW)
#IF ((PLATFORM = PLT_MBC) & ENA_MBC6502)
MBC6502:
CALL BYTEPARM ; GET BYTE VALUE (FILL VALUE) INTO A
CPL ; UNIT 0 = FFH, 1 = FEH ETC
LD C,A
;
IN A,(C) ; EXECUTE
NOP ; TRANSFER
;
LD A,($FFE0) ; GET PREVIOUS BANK
OUT (MPCL_RAM),A ; SET RAM PAGE SELECTOR
OUT (MPCL_ROM),A ; SET ROM PAGE SELECTOR
;
JP SERIALCMDLOOP ; AND BACK TO COMMAND LOOP
#ENDIF
#ENDIF
;
;__ERR________________________________________________________________________
;
; SYNTAX ERROR
;_____________________________________________________________________________
;
ERR:
LD HL,TXT_ERR ; POINT AT ERROR TEXT
CALL PRTSTRH ; DISPLAY IT
JP SERIALCMDLOOP ; AND BACK TO COMMAND LOOP
;
;__BYTEPARM___________________________________________________________________
;
; ATTEMPT TO GET A BYTE PARM, VALUE RETURNED IN A
; CF SET ON ERROR
;_____________________________________________________________________________
;
BYTEPARM:
CALL NONBLANK ; SKIP LEADING BLANKS
JP Z,ERR ; SYNTAX ERROR IF PARM NOT FOUND
CALL ISHEX ; HEX CHAR?
JR NZ,BYTEPARM1 ; IF NOT, ERR
JP HEXBYTE ; RETURN VIA HEXBYTE
BYTEPARM1:
SCF ; SIGNAL ERROR
RET ; RETURN
;
;__WORDPARM___________________________________________________________________
;
; ATTEMPT TO GET A WORD PARM, VALUE RETURNED IN DE
; CF SET ON ERROR
;_____________________________________________________________________________
;
WORDPARM:
CALL NONBLANK ; SKIP LEADING BLANKS
JP Z,ERR ; SYNTAX ERROR IF PARM NOT FOUND
CALL ISHEX ; HEX CHAR?
JR NZ,BYTEPARM1 ; IF NOT, ERR
JP HEXWORD ; RETURN VIA HEXWORD
;
;__GETLN______________________________________________________________________
;
; READ A LINE OF TEXT FROM THE SERIAL PORT, HANDLE <BS>, TERM ON <CR>
; EXIT IF TOO MANY CHARS STORE RESULT IN HL. CHAR COUNT IN C.
;_____________________________________________________________________________
;
GETLN:
LD C,0 ; ZERO CHAR COUNTER
PUSH DE ; SAVE DE
GETLNLOP:
; ENTRY LOOP
CALL KIN ; GET A KEY
CP CHR_CR ; IS <CR>?
JR Z,GETLNDONE ; YES, EXIT
CP CHR_BS ; IS <BS>?
JR Z,GETLNBS ; IF SO, HANDLE IT
CP CHR_DEL ; IS <DEL>?
JR Z,GETLNBS ; IF SO, HANDLE AS <BS>
CP ' ' ; UNEXPECTED CONTROL CHAR?
JR C,GETLNLOP ; IF SO, IGNORE IT AND GET NEXT
LD B,A ; SAVE CHAR IN B FOR NOW
LD A,C ; GET COUNTER
CP BUFLEN - 1 ; MAX OF BUFLEN CHARS LESS SPACE FOR TERM NULL
JR Z,GETLNOVF ; IF AT MAX, HANDLE OVERFLOW
LD A,B ; GET INPUT CHAR BACK
CALL COUT ; OUTPUT KEY TO SCREEN
LD (HL),A ; STORE CHAR IN BUFFER
INC HL ; INC POINTER
INC C ; INC CHAR COUNTER
JR GETLNLOP ; GET NEXT CHAR
GETLNOVF:
; OVERFLOW
LD A,CHR_BEL ; BELL CHARACTER
CALL COUT ; SEND IT TO CONSOLE
JR GETLNLOP ; LOOP
GETLNBS:
; BACKSPACE
LD A,C ; A=C
OR A ; ZERO?
JR Z,GETLNLOP ; IF EMPTY LINE, IGNORE BS & LOOP
DEC HL ; BACKUP BUF PTR 1 CHAR
DEC C ; DECREMENT CHAR COUNTER
LD A,CHR_BS ; BACKSPACE
CALL COUT ; TO CONSOLE
LD A,20H ; BLANK OUT CHAR ON TERM
CALL COUT ; TO CONSOLE
LD A,CHR_BS ; BACKSPACE
CALL COUT ; TO CONSOLE
JR GETLNLOP ; GET NEXT KEY
; DONE
GETLNDONE:
LD (HL),00H ; STORE NULL IN BUFFER
POP DE ; RESTORE DE
RET ;
;
;__KIN________________________________________________________________________
;
; READ FROM THE SERIAL PORT AND ECHO & CONVERT INPUT TO UCASE
;_____________________________________________________________________________
;
KIN:
CALL CIN
AND 7FH ; STRIP HI BIT
CP 'A' ; KEEP NUMBERS, CONTROLS
RET C ; AND UPPER CASE
CP 7BH ; SEE IF NOT LOWER CASE
RET NC
AND 5FH ; MAKE UPPER CASE
RET
;
;__NONBLANK___________________________________________________________________
;
; FIND NEXT NONBLANK CHARACTER IN BUFFER AT (HL)
;_____________________________________________________________________________
;
NONBLANK:
LD A,(HL) ; GET NEXT CHAR
CP ' ' ; COMPARE TO BLANK
RET NZ ; DONE IF NOT BLANK
INC HL ; BUMP TO NEXT CHAR
JR NONBLANK ; AND LOOP
;
;__ISHEX______________________________________________________________________
;
; CHECK BYTE AT (HL) FOR HEX CHAR, RET Z IF SO, ELSE NZ
;_____________________________________________________________________________
;
ISHEX:
LD A,(HL) ; CHAR TO AS
CP '0' ; < '0'?
JR C,ISHEX1 ; YES, NOT 0-9, CHECK A-F
CP '9' + 1 ; > '9'
JR NC,ISHEX1 ; YES, NOT 0-9, CHECK A-F
XOR A ; MUST BE 0-9, SET ZF
RET ; AND DONE
ISHEX1:
CP 'A' ; < 'A'?
JR C,ISHEX2 ; YES, NOT A-F, FAIL
CP 'F' + 1 ; > 'F'
JR NC,ISHEX2 ; YES, NOT A-F, FAIL
XOR A ; MUST BE A-F, SET ZF
RET ; AND DONE
ISHEX2:
OR $FF ; CLEAR ZF
RET ; AND DONE
;
;__HEXBYTE____________________________________________________________________
;
; GET ONE BYTE OF HEX DATA FROM BUFFER IN HL, RETURN IN A
;_____________________________________________________________________________
;
HEXBYTE:
LD C,0 ; INIT WORKING VALUE
HEXBYTE1:
CALL ISHEX ; DO WE HAVE A HEX CHAR?
JR NZ,HEXBYTE3 ; IF NOT, WE ARE DONE
LD B,4 ; SHIFT WORKING VALUE (C := C * 16)
HEXBYTE2:
SLA C ; SHIFT ONE BIT
RET C ; RETURN W/ CF SET INDICATING OVERFLOW ERROR
DJNZ HEXBYTE2 ; LOOP FOR 4 BITS
CALL NIBL ; CONVERT HEX CHAR TO BINARY VALUE IN A & INC HL
OR C ; COMBINE WITH WORKING VALUE
LD C,A ; AND PUT BACK IN WORKING VALUE
JR HEXBYTE1 ; DO ANOTHER CHARACTER
HEXBYTE3:
LD A,C ; WORKING VALUE TO A
OR A ; CLEAR CARRY
RET ; AND DONE
;
;__HEXWORD____________________________________________________________________
;
; GET ONE WORD OF HEX DATA FROM BUFFER IN HL, RETURN IN DE
;_____________________________________________________________________________
;
HEXWORD:
LD DE,0 ; INIT WORKING VALUE
HEXWORD1:
CALL ISHEX ; DO WE HAVE A HEX CHAR?
JR NZ,HEXWORD3 ; IF NOT, WE ARE DONE
LD B,4 ; SHIFT WORKING VALUE (DE := DE * 16)
HEXWORD2:
SLA E ; SHIFT LSB ONE BIT
RL D ; SHIFT MSB ONE BIT
RET C ; RETURN W/ CF SET INDICATING OVERFLOW ERROR
DJNZ HEXWORD2 ; LOOP FOR 4 BITS
CALL NIBL ; CONVERT HEX CHAR TO BINARY VALUE IN A & INC HL
OR E ; COMBINE WITH LSB
LD E,A ; AND PUT BACK IN WROKING VALUE
JR HEXWORD1 ; DO ANOTHER CHARACTER
HEXWORD3:
OR A ; CLEAR CARRY
RET ; AND DONE
;
;__NIBL_______________________________________________________________________
;
; GET ONE BYTE OF HEX DATA FROM BUFFER IN HL, RETURN IN A
;_____________________________________________________________________________
;
NIBL:
LD A,(HL) ; GET K B. DATA
INC HL ; INC KB POINTER
CP 40H ; TEST FOR ALPHA
JR NC,ALPH
AND 0FH ; GET THE BITS
RET
ALPH:
AND 0FH ; GET THE BITS
ADD A,09H ; MAKE IT HEX A-F
RET
;
;__HEXINS_____________________________________________________________________
;
; GET ONE BYTE OF HEX DATA FROM SERIAL PORT, CHECKSUM IN E, RETURN IN A
;_____________________________________________________________________________
;
HEXINS:
CALL NIBLS ; DO A NIBBLE
RLCA ; MOVE FIRST BYTE UPPER NIBBLE
RLCA ;
RLCA ;
RLCA ;
LD B,A ; SAVE ROTATED NIBBLE
CALL NIBLS ; DO NEXT NIBBLE
OR B ; COMBINE NIBBLES IN ACC TO BYTE
LD B,A ; SAVE BYTE
ADD A,E ; ADD TO CHECKSUM
LD E,A ; SAVE CHECKSUM
LD A,B ; RECOVER BYTE
RET ; DONE
NIBLS:
CALL CIN ; GET K B. DATA
SUB '0'
CP 10 ; TEST FOR ALPHA
RET C ; IF A<10 JUST RETURN
SUB 7 ; ELSE SUBTRACT 'A'-'0' (17) AND ADD 10
RET
;
;__PHL________________________________________________________________________
;
; PRINT THE HL REG ON THE SERIAL PORT
;_____________________________________________________________________________
;
PHL:
LD A,H ; GET HI BYTE
CALL PRTHEXBYTE ; DISPLAY IT
LD A,L ; GET LOW BYTE
CALL PRTHEXBYTE ; DISPLAY IT
RET ; DONE
;
;__PRTSTRH____________________________________________________________________
;
; PRINT STRING AT HL W/ MINI HELP SUFFIX
;_____________________________________________________________________________
;
PRTSTRH:
CALL PRTSTR
LD HL,TXT_MINIHELP
JP PRTSTR
;
#IF (BIOS == BIOS_UNA)
;
;__COUT_______________________________________________________________________
;
; OUTPUT CHARACTER FROM A
;_____________________________________________________________________________
;
COUT:
; SAVE ALL INCOMING REGISTERS
PUSH AF
PUSH BC
PUSH DE
PUSH HL
;
; OUTPUT CHARACTER TO CONSOLE VIA UBIOS
LD E,A
LD BC,$12
CALL $FFFD
;
; RESTORE ALL REGISTERS
POP HL
POP DE
POP BC
POP AF
RET
;
;__CIN________________________________________________________________________
;
; INPUT CHARACTER TO A
;_____________________________________________________________________________
;
CIN:
; SAVE INCOMING REGISTERS (AF IS OUTPUT)
PUSH BC
PUSH DE
PUSH HL
;
; INPUT CHARACTER FROM CONSOLE VIA UBIOS
LD BC,$11
CALL $FFFD
LD A,E
;
; RESTORE REGISTERS (AF IS OUTPUT)
POP HL
POP DE
POP BC
RET
;
;__CST________________________________________________________________________
;
; RETURN INPUT STATUS IN A (0 = NO CHAR, !=0 CHAR WAITING)
;_____________________________________________________________________________
;
CST:
; SAVE INCOMING REGISTERS (AF IS OUTPUT)
PUSH BC
PUSH DE
PUSH HL
;
; GET CONSOLE INPUT STATUS VIA UBIOS
LD BC,$13
CALL $FFFD
LD A,E
;
; RESTORE REGISTERS (AF IS OUTPUT)
POP HL
POP DE
POP BC
RET
;
#ELSE
;
;__COUT_______________________________________________________________________
;
; OUTPUT CHARACTER FROM A
;_____________________________________________________________________________
;
COUT:
; SAVE ALL INCOMING REGISTERS
PUSH AF
PUSH BC
PUSH DE
PUSH HL
;
; OUTPUT CHARACTER TO CONSOLE VIA HBIOS
LD E,A ; OUTPUT CHAR TO E
LD C,CIO_CONSOLE ; CONSOLE UNIT TO C
LD B,BF_CIOOUT ; HBIOS FUNC: OUTPUT CHAR
CALL $FFF0 ; HBIOS OUTPUTS CHARACTER
;
; RESTORE ALL REGISTERS
POP HL
POP DE
POP BC
POP AF
RET
;
;__CIN________________________________________________________________________
;
; INPUT CHARACTER TO A
;_____________________________________________________________________________
;
CIN:
; SAVE INCOMING REGISTERS (AF IS OUTPUT)
PUSH BC
PUSH DE
PUSH HL
;
; INPUT CHARACTER FROM CONSOLE VIA HBIOS
LD C,CIO_CONSOLE ; CONSOLE UNIT TO C
LD B,BF_CIOIN ; HBIOS FUNC: INPUT CHAR
CALL $FFF0 ; HBIOS READS CHARACTER
LD A,E ; MOVE CHARACTER TO A FOR RETURN
;
; RESTORE REGISTERS (AF IS OUTPUT)
POP HL
POP DE
POP BC
RET
;
;__CST________________________________________________________________________
;
; RETURN INPUT STATUS IN A (0 = NO CHAR, !=0 CHAR WAITING)
;_____________________________________________________________________________
;
CST:
; SAVE INCOMING REGISTERS (AF IS OUTPUT)
PUSH BC
PUSH DE
PUSH HL
;
; GET CONSOLE INPUT STATUS VIA HBIOS
LD C,CIO_CONSOLE ; CONSOLE UNIT TO C
LD B,BF_CIOIST ; HBIOS FUNC: INPUT STATUS
CALL $FFF0 ; HBIOS RETURNS STATUS IN A
;
; RESTORE REGISTERS (AF IS OUTPUT)
POP HL
POP DE
POP BC
RET
;
#ENDIF
;
;__WORK_AREA__________________________________________________________________
;
; RESERVED RAM FOR MONITOR WORKING AREA
;_____________________________________________________________________________
;
KEYBUF: .FILL BUFLEN,0
;
;__TEXT_STRINGS_______________________________________________________________
;
; SYSTEM TEXT STRINGS
;_____________________________________________________________________________
;
;TXT_PROMPT .TEXT "\r\n>$"
TXT_READY .TEXT "\r\n\r\nMonitor Ready$"
TXT_COMMAND .TEXT "\r\nUnknown Command$"
TXT_ERR .TEXT "\r\nSyntax Error$"
TXT_IMERR .TEXT "\r\nCommand not available under interrupt mode 1$"
TXT_CKSUMERR .TEXT "\r\nChecksum Error$"
TXT_RECORDERR .TEXT "\r\nRecord Type Error$"
TXT_LOADED .TEXT "\r\nLoaded$"
TXT_BADNUM .TEXT " *Invalid Hex Byte Value*$"
TXT_MINIHELP .TEXT " (? for Help)$"
TXT_HELP .TEXT "\r\nMonitor Commands (all values in hex):"
.TEXT "\r\nB - Boot system"
.TEXT "\r\nD xxxx [yyyy] - Dump memory from xxxx to yyyy"
.TEXT "\r\nF xxxx yyyy zz - Fill memory from xxxx to yyyy with zz"
.TEXT "\r\nH - Halt system"
.TEXT "\r\nI xxxx - Input from port xxxx"
.TEXT "\r\nK - Keyboard echo"
.TEXT "\r\nL - Load Intel hex data"
.TEXT "\r\nM xxxx yyyy zzzz - Move memory block xxxx-yyyy to zzzz"
.TEXT "\r\nO xxxx yy - Output value yy to port xxxx"
.TEXT "\r\nP xxxx - Program RAM at address xxxx"
.TEXT "\r\nR xxxx [[yy] [zzzz]] - Run code at address xxxx"
.TEXT "\r\n Pass yy and zzzz to register A and BC"
#IF (BIOS == BIOS_WBW)
.TEXT "\r\nS xx - Set bank to xx"
.TEXT "\r\nU - Set bank to previous bank"
#ENDIF
#IF (ENA_XM)
.TEXT "\r\nT xxxx - X-modem transfer to memory location xxxx"
#ENDIF
#IF (BIOS == BIOS_WBW)
#IF ((PLATFORM == PLT_MBC) & ENA_MBC6502)
.TEXT "\r\n6 xx - Transfer control to MBC6502 unit xx"
#ENDIF
#ENDIF
.TEXT "\r\nX - Exit monitor"
.TEXT "$"
;
#IF DSKYENABLE
;
KY_PR .EQU KY_FW ; USE [FW] FOR [PR] (PORT READ)
KY_PW .EQU KY_BK ; USE [BW] FOR [PW] (PORT WRITE)
;
;__DSKY_ENTRY_________________________________________________________________
;
; DSKY FRONT PANEL STARTUP
;_____________________________________________________________________________
;
DSKY_ENTRY:
; SHOULD WE DO SOMETHING HERE TO CONFIRM THAT A DSKY
; IS ACTUALLY OPERATING???
LD SP,MON_STACK ; SET THE STACK POINTER
LD HL,DSKY_ENTRY ; RESTART ADDRESS
CALL INITIALIZE
;
;__FRONT_PANEL_STARTUP________________________________________________________
;
; START UP THE SYSTEM WITH THE FRONT PANEL INTERFACE
;_____________________________________________________________________________
;
CALL DSKY_BEEP
;
;__COMMAND_PARSE______________________________________________________________
;
; PROMPT USER FOR COMMANDS, THEN PARSE THEM
;_____________________________________________________________________________
;
FRONTPANELLOOP:
LD HL,CPUUP ; SET POINTER TO CPU UP MSG
CALL DSKY_SHOW ; DISPLAY UNENCODED
CALL DSKY_HIGHLIGHTCMDKEYS
CALL DSKY_L1ON
CALL KB_GET ; GET KEY FROM DSKY
PUSH AF
CALL DSKY_L1OFF
POP AF
FRONTPANELLOOP1:
CP KY_PR ; IS PORT READ?
JP Z,DOPORTREAD ; YES, JUMP
CP KY_PW ; IS PORT WRITE?
JP Z,DOPORTWRITE ; YES, JUMP
CP KY_DE ; IS DEPOSIT?
JP Z,DODEPOSIT ; YES, JUMP
CP KY_EX ; IS EXAMINE?
JP Z,DOEXAMINE ; YES, JUMP
CP KY_GO ; IS GO?
JP Z,DOGO ; YES, JUMP
CP KY_BO ; IS BOOT?
JP Z,DOBOOT ; YES, JUMP
JR FRONTPANELLOOP ; LOOP
;
;__DOBOOT_____________________________________________________________________
;
; PERFORM BOOT FRONT PANEL ACTION
;_____________________________________________________________________________
;
DOBOOT:
LD HL,MSGBOOT ; SET POINTER TO BOOT MESSAGE
CALL DSKY_SHOW ; DISPLAY UNENCODED
JP BOOT ; DO BOOT
;
;__DOPORTREAD_________________________________________________________________
;
; PERFORM PORT READ FRONT PANEL ACTION
; PANEL TEMPLATE "Po88 88"
; POS 01234567
;_____________________________________________________________________________
;
DOPORTREAD:
CALL DSKY_HIGHLIGHTNUMKEYS
CALL GETPORT ; GET PORT INTO A
PORTREADLOOP:
LD C,A ; STORE PORT IN "C"
LD DE,DISPLAYBUF+2 ; POINT TO POS 2 IN BUF
CALL PUTVALUE ; DISPLAY PORT NUM
IN A,(C) ; GET PORT VALUE FROM PORT IN "C"
INC DE ; ADVANCE BUF PTR
INC DE ; ... TO LAST TWO POSITIONS
CALL PUTVALUE ; DISPLAY PORT VALUE
CALL ENCDISPLAY ; DISPLAY BUFFER CONTENTS
PORTREADGETKEY:
CALL KB_GET ; GET KEY FROM KB
JR PORTREADGETKEY ; NO VALID KEY, LOOP
;
;__DOPORTWRITE________________________________________________________________
;
; PERFORM PORT WRITE FRONT PANEL ACTION
; PANEL TEMPLATE "Po88 88"
; POS 01234567
;_____________________________________________________________________________
;
DOPORTWRITE:
CALL DSKY_HIGHLIGHTNUMKEYS
CALL GETPORT ; GET PORT INTO A
PORTWRITELOOP:
LD L,A ; SAVE PORT NUM
LD DE,DISPLAYBUF+2 ; POINT TO POS 2 IN BUF
CALL PUTVALUE ; DISPLAY PORT NUM
CALL GETVALUE ; INPUT A BYTE VALUE, RETURN IN "A"
LD C,L ; RESTORE PORT NUM
OUT (C),A ; OUTPUT VALUE TO PORT STORED IN "C"
LD DE,DISPLAYBUF+6 ; DISPLAY WRITTEN PORT VALUE
CALL PUTVALUE ; ... WITHOUT DP'S
CALL ENCDISPLAY ; DISPLAY BUFFER CONTENTS
PORTWRITEGETKEY:
CALL KB_GET ; GET KEY FROM KB
JR PORTWRITEGETKEY ; NO VALID KEY, LOOP
;
;__DOGO_______________________________________________________________________
;
; PERFORM GO FRONT PANEL ACTION
;_____________________________________________________________________________
;
DOGO:
CALL DSKY_HIGHLIGHTNUMKEYS
CALL GETADDR ; GET ADDRESS INTO HL
PUSH HL
CALL DSKY_HIGHLIGHTKEYSOFF
LD HL,GOTO ; POINT TO "GO" MSG
CALL INITBUF
POP HL
LD DE,DISPLAYBUF+4
LD A,H
CALL PUTVALUE
LD A,L
CALL PUTVALUE
CALL ENCDISPLAY ; DISPLAY
JP (HL) ; AND RUN
;
;__DOEXAMINE__________________________________________________________________
;
; PERFORM EXAMINE FRONT PANEL ACTION
; PANEL TEMPLATE "8888 88"
; POS 01234567
;_____________________________________________________________________________
;
DOEXAMINE:
CALL DSKY_HIGHLIGHTNUMKEYS
CALL GETADDR ; GET ADDRESS INTO HL
EXAMINELOOP:
LD DE,DISPLAYBUF+0
LD A,H
CALL PUTVALUE
LD A,L
CALL PUTVALUE
LD A,$10
LD (DE),A
INC DE
LD (DE),A
INC DE
LD A,(HL) ; GET VALUE FROM ADDRESS IN HL
CALL PUTVALUE
CALL ENCDISPLAY ; DISPLAY BUFFER ON DISPLAYS
CALL DSKY_HIGHLIGHTFWDKEYS
EXAMINEGETKEY:
CALL KB_GET ; GET KEY FROM KB
CP KY_EN ; [EN] PRESSED, INC ADDRESS AND LOOP
JR Z,EXAMINEFW ;
JR EXAMINEGETKEY ; NO VALID KEY, LOOP
EXAMINEFW:
INC HL ; HL++
JR EXAMINELOOP ;
;
;__DODEPOSIT__________________________________________________________________
;
; PERFORM DEPOSIT FRONT PANEL ACTION
; PANEL TEMPLATE "8888 88"
; POS 01234567
;_____________________________________________________________________________
;
DODEPOSIT:
CALL DSKY_HIGHLIGHTNUMKEYS
CALL GETADDR ; GET ADDRESS INTO HL
DEPOSITLOOP:
LD DE,DISPLAYBUF+0
LD A,H
CALL PUTVALUE
LD A,L
CALL PUTVALUE
LD A,$10
LD (DE),A
INC DE
LD (DE),A
CALL GETVALUE ;
LD (HL),A ;
LD DE,DISPLAYBUF+6 ; DISPLAY WRITTEN MEM VALUE
CALL PUTVALUE ; ... WITHOUT DP'S
CALL ENCDISPLAY ; DISPLAY BUFFER CONTENTS
CALL DSKY_HIGHLIGHTFWDKEYS
DEPOSITGETKEY:
CALL KB_GET ; GET KEY FROM KB
CP KY_EN ; [EN] PRESSED, INC ADDRESS AND LOOP
JR Z,DEPOSITFW ;
JR DEPOSITGETKEY ; NO VALID KEY, LOOP
DEPOSITFW:
INC HL ;
JR DEPOSITLOOP ;
;
;__GETADDR____________________________________________________________________
;
; GET ADDRESS FROM FRONT PANEL
; PANEL TEMPLATE "Adr 8888"
; POS 01234567
;_____________________________________________________________________________
;
GETADDR:
LD HL,ADDR ; INITIALIZE DISPLAYBUF
CALL INITBUF
JR GETVALW
;
;__GETVAL16___________________________________________________________________
;
; GET 16 BIT VALUE FROM FRONT PANEL
; PANEL TEMPLATE "????8888"
; POS 01234567
;_____________________________________________________________________________
;
GETVALW:
LD A,$80 ;
LD (DISPLAYBUF+4),A ;
LD (DISPLAYBUF+5),A ;
LD (DISPLAYBUF+6),A ;
LD (DISPLAYBUF+7),A ;
GETVALW1:
CALL ENCDISPLAY ;
GETVALWLOOP:
CALL KB_GET ;
CP $10 ;
JP M,GETVALWNUM ; NUMBER PRESSED, STORE IT
CP KY_EN ; [EN] PRESSED, DONE
JR Z,GETVALWDONE ;
JR GETVALWLOOP ; INVALID KEY, LOOP
GETVALWNUM:
OR $80 ; SET DP
LD C,A ;
LD A,(DISPLAYBUF+5) ; SHIFT BYTES IN DISPLAY BUF TO THE LEFT
LD (DISPLAYBUF+4),A ;
LD A,(DISPLAYBUF+6) ;
LD (DISPLAYBUF+5),A ;
LD A,(DISPLAYBUF+7) ;
LD (DISPLAYBUF+6),A ;
LD A,C ; DISPLAY KEYSTROKE IN RIGHT MOST DISPLAY (0)
LD (DISPLAYBUF+7),A ;
JR GETVALW1 ;
GETVALWDONE:
LD A,(DISPLAYBUF+6) ; GET DIGIT IN DISPLAY 6
AND $0F
SLA A ; ROTATE IT TO HIGH NIBBLE
SLA A ;
SLA A ;
SLA A ;
LD C,A ; STORE IT IN "C"
LD A,(DISPLAYBUF+7) ; GET DIGIT IN DISPLAY 7
AND $0F
OR C ; ADD IN NIBBLE STORED IN C
LD L,A ; STORE IT IN LOW BYTE OF ADDRESS POINTER
LD A,(DISPLAYBUF+4) ; GET DIGIT IN DISPLAY 4
AND $0F
SLA A ; ROTATE IT TO HIGH NIBBLE
SLA A ;
SLA A ;
SLA A ;
LD C,A ; STORE IT IN "C"
LD A,(DISPLAYBUF+5) ; GET DIGIT IN DISPLAY 5
AND $0F
OR C ; ADD IN NIBBLE STORED IN "C"
LD H,A ; STORE BYTE IN HIGH BYTE OF ADDRESS POINTER
RET
;
;__GETPORT____________________________________________________________________
;
; GET PORT FROM FRONT PANEL
; PANEL TEMPLATE "Port 88"
; POS 01234567
;_____________________________________________________________________________
;
GETPORT:
LD HL,PORT ; INITIALIZE DISPLAYBUF
CALL INITBUF
JR GETVALUE
;
;__GETVALUE___________________________________________________________________
;
; GET 8 BIT VALUE FROM FRONT PANEL
; PANEL TEMPLATE "??????88"
; POS 01234567
;_____________________________________________________________________________
;
GETVALUE:
LD A,$80 ;
LD (DISPLAYBUF+6),A ;
LD (DISPLAYBUF+7),A ;
GETVALUE1:
CALL ENCDISPLAY ;
GETVALUELOOP:
CALL KB_GET ;
CP $10 ;
JP M,GETVALUENUM ; NUMBER PRESSED, STORE IT
CP KY_EN ; [EN] PRESSED, DONE
JR Z,GETVALUEDONE ;
JR GETVALUELOOP ; INVALID KEY, LOOP
GETVALUENUM:
OR $80 ; SET DP
LD C,A ;
LD A,(DISPLAYBUF+7) ;
LD (DISPLAYBUF+6),A ;
LD A,C ;
LD (DISPLAYBUF+7),A ;
JR GETVALUE1 ;
GETVALUEDONE:
LD A,(DISPLAYBUF+6) ;
AND $0F
RLCA ;
RLCA ;
RLCA ;
RLCA ;
LD C,A ;
LD A,(DISPLAYBUF+7) ;
AND $0F
OR C ;
RET
;
;__PUTVALUE___________________________________________________________________
;
; INSERT HEX DIGITS OF A INTO AN ENCODED DSKY DISPLAY BUFFER
; AT POSTION SPECIFIED BY DE. ON RETURN, DE POINTS TO NEXT
; POSITION IN DISPLAY BUFFER.
;_____________________________________________________________________________
;
PUTVALUE:
PUSH AF ; SAVE INCOMING VALUE
RLCA ; HIGH NIBBLE -> LOW NIBBLE
RLCA ; ...
RLCA ; ...
RLCA ; ...
AND $0F ; ISOLATE LOW NIBBLE
LD (DE),A ; PLACE DIGIT VALUE IN BUFFER
INC DE ; NEXT BUFFER POSITION
POP AF ; RECOVER ORIGINAL VALUE
AND $0F ; ISOLATE LOW NIBBLE
LD (DE),A ; PLACE DIGIT VALUE IN BUFFER
INC DE ; NEXT BUFFER POSITION
RET ; DONE
;
;__KB_GET_____________________________________________________________________
;
; GET A SINGLE KEY AND DECODE
;
;_____________________________________________________________________________
;
KB_GET:
PUSH BC
PUSH DE
PUSH HL ; SAVE HL
CALL DSKY_GETKEY ; GET A KEY
LD A,E ; PUT KEY CODE IN A
CP KY_EN ; ENTER?
JR Z,KB_GET1 ; IF YES, RET TO CALLER
CP $10 ; HEX DIGIT?
JR C,KB_GET1 ; IF YES, RET TO CALLER
; NOT A DIGIT OR [EN], BAIL OUT TO MAIN LOOP TO HANDLE IT
LD SP,MON_STACK ; CLEAR STACK
JP FRONTPANELLOOP1 ; RESTART AT MAIN LOOP
KB_GET1:
POP HL ; RESTORE HL
POP DE
POP BC
RET
;
;__INITBUF____________________________________________________________________
;
; INITIALIZE DISPLAY BUFFER FROM VALUE AT ADDRESS IN HL
;_____________________________________________________________________________
;
INITBUF:
LD DE,DISPLAYBUF
LD BC,8
LDIR
RET
;
;__ENCDISPLAY_________________________________________________________________
;
; DISPLAY CONTENTS OF DISPLAYBUF ENCODED PER SEGDECODE TABLE
;_____________________________________________________________________________
;
ENCDISPLAY:
PUSH HL
LD HL,DISPLAYBUF
JR ENCBUF0
;
;__ENCBUF_____________________________________________________________________
;
; DISPLAY CONTENTS OF BUFFER AT HL ENCODED PER SEGDECODE TABLE
;_____________________________________________________________________________
;
ENCBUF:
PUSH HL ; SAVE HL
ENCBUF0:
PUSH AF ; SAVE AF
PUSH BC ; SAVE BC
PUSH DE ; SAVE DE
LD DE,DSKY_BUF ; DESTINATION FOR DECODED BYTES
LD B,8 ; NUMBER OF BYTES TO DECODE
ENCBUF1:
LD A,(HL) ; GET SOURCE BYTE
INC HL ; BUMP TO NEXT BYTE FOR NEXT PASS
PUSH AF ; SAVE IT
AND $80 ; ISOLATE HI BIT (DP)
LD C,A ; SAVE IN C
POP AF ; RECOVER ORIGINAL
AND $7F ; REMOVE HI BIT (DP)
PUSH HL ; SAVE POINTER
LD HL,SEGDECODE ; POINT TO DECODE TABLE
CALL ADDHLA ; OFFSET BY INCOMING VALUE
LD A,(HL) ; GET DECODED VALUE
OR C ; RECOMBINE WITH DP VALUE
LD (DE),A ; SAVE IN DEST BUF
INC DE ; INC DEST BUF PTR
POP HL ; RESTORE POINTER
DJNZ ENCBUF1 ; LOOP THRU ALL BUF POSITIONS
LD HL,DSKY_BUF ; POINT TO DECODED BUFFER
CALL DSKY_SHOW ; DISPLAY IT
POP DE ; RESTORE DE
POP BC ; RESTORE BC
POP AF ; RESTORE AF
POP HL ; RESTORE HL
RET
;
;_____________________________________________________________________________
;
; DSKY INTERFACE ROUTINES
;_____________________________________________________________________________
;
DSKY_GETKEY:
LD B,BF_DSKYGETKEY
RST 08
RET
;
DSKY_SHOW:
LD B,BF_DSKYSHOWSEG
RST 08
RET
;
DSKY_BEEP:
LD B,BF_DSKYBEEP
RST 08
RET
;
DSKY_L1ON:
LD E,1
JR DSKY_STATLED
DSKY_L1OFF:
LD E,0
DSKY_STATLED:
LD B,BF_DSKYSTATLED
LD D,0
RST 08
RET
;
DSKY_PUTLED:
LD B,BF_DSKYKEYLEDS
RST 08
RET
;
DSKY_HIGHLIGHTFWDKEYS:
LD HL,DSKY_HIGHLIGHTFWDKEYLEDS
JR DSKY_PUTLED
;
DSKY_HIGHLIGHTCMDKEYS:
LD HL,DSKY_HIGHLIGHTCMDKEYLEDS
JR DSKY_PUTLED
;
DSKY_HIGHLIGHTNUMKEYS:
LD HL,DSKY_HIGHLIGHTNUMKEYLEDS
JR DSKY_PUTLED
;
DSKY_HIGHLIGHTKEYSOFF:
LD HL,DSKY_HIGHLIGHTKEYLEDSOFF
JR DSKY_PUTLED
;
DSKY_HIGHLIGHTFWDKEYLEDS .DB $00,$00,$00,$30,$00,$00,$00,$00
DSKY_HIGHLIGHTCMDKEYLEDS .DB $20,$00,$20,$3F,$00,$00,$00,$00
DSKY_HIGHLIGHTNUMKEYLEDS .DB $1F,$3F,$1F,$30,$00,$00,$00,$00
DSKY_HIGHLIGHTKEYLEDSOFF .DB $00,$00,$00,$00,$00,$00,$00,$00
;
CPUUP .DB $40,$39,$73,$3E,$00,$3E,$73,$40 ; "-CPU UP-" (RAW SEG)
MSGBOOT .DB $7F,$5C,$5C,$78,$82,$00,$00,$00 ; "Boot! " (RAW SEG)
ADDR .DB $17,$18,$19,$10,$00,$00,$00,$00 ; "Adr 0000" (ENCODED)
PORT .DB $13,$14,$15,$16,$10,$10,$00,$00 ; "Port 00" (ENCODED)
GOTO .DB $1A,$14,$10,$10,$00,$00,$00,$00 ; "Go 0000" (ENCODED)
;
;_HEX_7_SEG_DECODE_TABLE______________________________________________________
;
; SET BIT 7 TO DISPLAY W/ DECIMAL POINT
;_____________________________________________________________________________
;
SEGDECODE:
;
; POS $00 $01 $02 $03 $04 $05 $06 $07
; GLYPH '0' '1' '2' '3' '4' '5' '6' '7'
.DB $3F, $06, $5B, $4F, $66, $6D, $7D, $07
;
; POS $08 $09 $0A $0B $0C $0D $0E $0F
; GLYPH '8' '9' 'A' 'B' 'C' 'D' 'E' 'F'
.DB $7F, $67, $77, $7C, $39, $5E, $79, $71
;
; POS $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $1A
; GLYPH ' ' '-' '.' 'P' 'o' 'r' 't' 'A' 'd' 'r' 'G'
.DB $00, $40, $00, $73, $5C, $50, $78, $77, $5E, $50, $3D
;
DISPLAYBUF: .FILL 8,0
DSKY_BUF .FILL 8,0
;
#ELSE
;
DSKY_ENTRY:
JP EXIT
;
#ENDIF
;
;==================================================================================================
; UTILITY FUNCTIONS
;==================================================================================================
;
;
CHR_BEL .EQU 07H
CHR_CR .EQU 0DH
CHR_LF .EQU 0AH
CHR_BS .EQU 08H
CHR_ESC .EQU 1BH
CHR_DEL .EQU 7FH
;
;__________________________________________________________________________________________________
;
; UTILITY PROCS TO PRINT SINGLE CHARACTERS WITHOUT TRASHING ANY REGISTERS
;
PC_SPACE:
PUSH AF
LD A,' '
JR PC_PRTCHR
PC_COLON:
PUSH AF
LD A,':'
JR PC_PRTCHR
PC_CR:
PUSH AF
LD A,CHR_CR
JR PC_PRTCHR
PC_LF:
PUSH AF
LD A,CHR_LF
JR PC_PRTCHR
PC_PRTCHR:
CALL COUT
POP AF
RET
NEWLINE2:
CALL NEWLINE
NEWLINE:
CALL PC_CR
CALL PC_LF
RET
PRTSTR:
LD A,(HL)
INC HL
CP '$'
RET Z
CALL COUT
JR PRTSTR
;
; PRINT THE HEX BYTE VALUE IN A
;
PRTHEXBYTE:
PUSH AF
PUSH DE
CALL HEXASCII
LD A,D
CALL COUT
LD A,E
CALL COUT
POP DE
POP AF
RET
;
; CONVERT BINARY VALUE IN A TO ASCII HEX CHARACTERS IN DE
;
HEXASCII:
LD D,A
CALL HEXCONV
LD E,A
LD A,D
RLCA
RLCA
RLCA
RLCA
CALL HEXCONV
LD D,A
RET
;
; CONVERT LOW NIBBLE OF A TO ASCII HEX
;
HEXCONV:
AND 0FH ;LOW NIBBLE ONLY
ADD A,90H
DAA
ADC A,40H
DAA
RET
;
; ADD HL,A
;
; A REGISTER IS DESTROYED!
;
ADDHLA:
ADD A,L
LD L,A
RET NC
INC H
RET
;
;
;
.FILL 16,0 ; SET MINIMUM STACK DEPTH
SLACK .EQU (MON_END - $)
.FILL SLACK,00H
;
MON_STACK .EQU $
;
.ECHO "DBGMON space remaining: "
.ECHO SLACK
.ECHO " bytes.\n"
;
.END