home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-10-26 | 51.4 KB | 1,838 lines |
- TITLE 'AMYX DEBUG 3/6/85 1346'
- ;
- ; *********************************************
- ; * *
- ; * AMYX DEBUG *
- ; * *
- ; * An assembly language debugger for Z80 *
- ; * CP/M. Written by *
- ; * *
- ; * Richard Amyx *
- ; * 994 North Second Street *
- ; * San Jose, CA 95112 *
- ; * (408) 287-8572 *
- ; * *
- ; * Given to Micro Cornucopia for inclu- *
- ; * sion in its public domain library. *
- ; * May not be reproduced or distributed *
- ; * for profit. *
- ; * *
- ; *********************************************
- ;
- ;****************************************************************************
- ;
- ; TEST VERSION FOR MICRO C USE ONLY 3/6/85.
- ; ----------NOT FOR DISTRIBUTION----------
- ;
- ;****************************************************************************
- ;
- ;
- ORG 100H
- ;
- ;----------------------------------------------------------------------------
- ; RELOCATION AND INITIALIZATION ROUTINE
- ;----------------------------------------------------------------------------
- ;
- LD (SYSSP),SP ; SAVE SYSTEM SP
- LD SP,LOCSP ; USE LOCAL STACK HERE
- LD HL,CODBEG ; SOURCE
- LD DE,DESTIN ; DESTINATION
- LD BC,CODSIZ ; BYTE COUNT
- LDIR ; WHOOSH!
- LD HL,BRKTBL+O ; ZERO ALL BREAKPOINTS
- LD B,12 ; 12 BYTES FOR 6 ADDRESSES
- BRKZER: LD (HL),0
- INC HL
- DJNZ BRKZER
- CALL NEWLIN+O ; DROP CURSOR A LINE
- LD DE,MOVED ; POINT TO MOVED MESSAGE
- CALL MSGOUT+O ; PRINT IT
- CALL NEWLIN+O ; DROP CURSOR A LINE
- LD DE,XMES
- CALL MSGOUT+O
- CALL NEWLIN+O
- LD DE,INVOK0 ; PRINT FIRST PART OF INVOKE
- CALL MSGOUT+O ; MESSAGE
- LD HL,DESTIN ; PRINT START ADDRESS
- LD A,H
- CALL HX2ASC+O
- LD A,L
- CALL HX2ASC+O
- LD DE,INVOK1 ; PRINT SECOND PART OF INVOKE MESSAGE
- CALL MSGOUT+O
- LD HL,RELTOP ; TOP OF RELOCATED CODE
- LD A,H ; PRINT ADDRESS
- CALL HX2ASC+O
- LD A,L
- CALL HX2ASC+O
- LD DE,INVOK2 ; PRINT LAST PART OF INVOKE MESSAGE
- CALL MSGOUT+O
- LD HL,38H ; PUT JUMP
- LD (HL),0C3H ; CODE AT 38H
- LD HL,DESTIN ; PUT DEBUG ADDRESS
- LD (39H),HL ; IN CP/M JUMP TO DDT LOCATION
- CALL NEWLIN+O ; DROP A LINE
- LD SP,(SYSSP) ; GET SYSTEM SP BACK
- RET ; RELOCATED; RETURN TO CCP
- ; WITHOUT WARM BOOT
- ;
- ;
- RELTOP: EQU 0C000H ; TOP OF RELOCATED CODE
- ;
- MOVED: DEFM 'AMYX DEBUG Version 1.0$'
- XMES: DEFM 'Test version for Micro C 3/6/85$'
- INVOK0: DEFM 'Loaded and relocated to $'
- INVOK1: DEFM 'H - $'
- INVOK2: DEFM 'H.$'
- ;
- ;----------------------------------------------------------------------------
- ; BEGIN ACTUAL DEBUG CODE
- ;----------------------------------------------------------------------------
- ;
- CODBEG: JP ENTRY+O ; BEGINNING OF CODE TO RELOCATED
- ;
- ;
- ; BIOS EQUATES
- ;
- WBOOT EQU 0
- BDOS EQU 5
- CONIN EQU 1 ; CHARACTER IN FROM KEYBOARD
- CONOUT EQU 2 ; SINGLE CHARACTER TO CONSOLE
- PSTR EQU 9 ; PRINT STRING ON CONSOLE
- LININ EQU 10 ; READ CONSOLE BUFFER
- ;
- ;
- ; CHARACTERS
- ;
- BELL EQU 7
- BS EQU 8
- LF EQU 10
- CR EQU 13
- SPACE EQU 20H
- CLRSCR EQU 26 ; KAYPRO ^Z CLEAR SCREEN CHAR
- HOME: EQU 30 ; KAYPRO HOME CURSOR CHAR
- ;
- ;
- ; KAYPRO CURSOR POSITIONS
- ;
- COMCUR: EQU 3720H ; COMMAND LINE HEX CURSOR POSITION
- ERRCUR: EQU 3742H ; ERROR MESSAGE HEX CURSOR POSITION
- BRKCUR: EQU 3520H ; BREAKPOINT LINE CURSOR POSITION
- MODCUR: EQU 3729H ; MEMORY MODIFY INPUT CURSOR
- MEMCUR: EQU 2D26H ; MEMORY DISPLAY CURSOR POS
- ;
- ;
- ; MESSAGES
- ;
- MAF: DEFM 'AF : $'
- MBC: DEFM 'BC : $'
- MDE: DEFM 'DE : $'
- MHL: DEFM 'HL : $'
- MAFP: DEFM 'AF'': $'
- MBCP: DEFM 'BC'': $'
- MDEP: DEFM 'DE'': $'
- MHLP: DEFM 'HL'': $'
- MIX: DEFM 'IX : $'
- MIY: DEFM 'IY : $'
- MSP: DEFM 'SP : $'
- MPC: DEFM 'PC : $'
- MCOM: DEFM 'Command? $'
- BADCOM: DEFM 'BAD COMMAND!$'
- BRKMSG: DEFM 'Breakpoints: $'
- BRKFUL: DEFM 'BREAKPOINTS FULL!$'
- NOTFND: DEFM 'STRING NOT FOUND.$'
- MODMSG: DEFM 'Modify: $'
- BLANK: DEFM ' $' ;26 SPACES
- COMCHR: DEFM 'IHLSPXY' ; OK COM BUFF CHARS
- PTR: DEFM '=> $'
- ;
- ;
- ; VARIABLES
- ;
- SYSSP: DEFW 0 ; SYSTEM STACK POINTER
- SYSPC: DEFW 0 ; SYSTEM PROGRAM COUNTER
- MEMSEL: DEFW 0100H ; DEFAULT MEM DISPLAY ADDRESS
- CBUFCT: DEFB 0 ; COMMAND BUFFER COUNTER
- COMBUF: DEFS 32 ; 32-CHARACTER COMMAND BUFFER
- TMPWRD: DEFW 0 ; TEMPORARY STORAGE AS NEEDED
- LINECT: DEFB 8 ; LINE COUNTER FOR DISMEM
- CURSOR: DEFW 0 ; CURSOR SAVE FOR DISMEM
- BRKTBL: DEFS 12 ; SPACE FOR 6 BREAKPOINT ADDRESSES
- CODSAV: DEFS 6 ; THE CODE REPLACED BY BREAKPOINTS
- BRKCNT: DEFB 0 ; COUNTER FOR BREAKPOINT TABLES
- START: DEFW 0 ; ALL-PURPOSE START ADDRESS
- ENDADD: DEFW 0 ; ALL-PURPOSE END ADDRESS
- BYTCNT: DEFW 0 ; ALL-PURPOSE BYTE COUNT
- SCHSTR: DEFS 11 ; 11-BYTE SEARCH STRING BUFFER
- MODFLG: DEFB 0 ; MODIFY MEMORY FLAG
- COMFLG: DEFB 0 ; NZ = COMMAND IN PROGRESS
- ;
- ;----------------------------------------------------------------------------
- ; START MAIN PROGRAM
- ;----------------------------------------------------------------------------
- ;
- ENTRY: LD (SYSSP+O),SP ; SAVE CALLING PROGRAM SP
- LD SP,LOCSP+O ; SET UP THE LOCAL STACK
- PUSH AF ; NOW SAVE EVERYTHING IN LOCAL STACK.
- PUSH BC ; AF = LOCSP-17 & 18; BC = LOCSP-19 & 20
- PUSH DE ; DE = LOCSP-15 & 16 { HIGH BYTE IS AT }
- PUSH HL ; HL = LOCSP-13 & 14 { LOWER ADDRESS }
- EX AF,AF' ; EXCHANGE REGISTERS
- EXX
- PUSH AF ; AF' = LOCSP-11 & 12
- PUSH BC ; BC' = LOCSP-9 & 10
- PUSH DE ; DE' = LOCSP-7 & 8
- PUSH HL ; HL' = LOCSP-5 & 6
- PUSH IX ; IX = LOCSP-3 & 4
- PUSH IY ; IY = LOCSP-1 & 2
- LD HL,(SYSSP+O) ; SYSTEM SP TO HL
- LD C,(HL) ; PC LOW AT SP TO C
- INC HL ; SP+1 IS HIGH BYTE OF USER PC
- LD B,(HL) ; PC HIGH TO B
- LD (SYSPC+O),BC ; SAVE USER PC HERE
- LD (TMPWRD+O),SP ; PRESERVE CURRENT LOCAL SP
- LD SP,(SYSSP+O) ; DISCARD DEBUG-CAUSED USER
- POP HL ; PC FROM BOTTOM OF SYSTEM STACK
- LD (SYSSP+O),SP ; SAVE ADJUSTED SP
- LD SP,(TMPWRD+O) ; RESTORE CURRENT LOCAL SP
- LD E,27 ; SAVE
- CALL CHROUT+O ; USER
- LD E,'B' ; CURSOR
- CALL CHROUT+O ; POSITION
- LD E,'6'
- CALL CHROUT+O
- ;
- ;
- ; CHECK FOR BREAKPOINTS AND INSTALL IF SET
- ;
- LD HL,BRKTBL+O ; POINT TO BREAKPOINT TABLE
- LD B,6 ; NUMBER OF BREAKPOINTS TO CHECK
- XOR A ; ZERO THE
- LD (BRKCNT+O),A ; BREAKPOINT COUNTER
- CHKBR1: LD E,(HL) ; LOW BKPT BYTE IN E
- INC HL ; POINT TO HIGH BYTE
- LD D,(HL) ; HIGH BKPT BYTE IN D
- LD A,D ; SEE IF CONTENTS OF TABLE ENTRY
- OR E ; IS ZERO
- CALL NZ,SETBRK+O ; IF NOT, INSTALL IT
- INC HL ; POINT TO NEXT LOW BYTE
- LD A,(BRKCNT+O) ; BUMP BREAKPOINT
- INC A ; COUNTER
- LD (BRKCNT+O),A
- DJNZ CHKBR1 ; GO UNTIL SIX CHECKED
- ;
- ;
- ; FIX BREAKPOINT ON ENTRY FOR CORRECT PC & SP DISPLAYS,
- ; AND FOR CORRECT EXECUTION ON GO. FIRST, CHECK TO SEE
- ; WHETHER ENTRY TO DEBUG CAME FROM A BREAKPOINT OR A
- ; CODED RST 38H.
- ;
- LD DE,(SYSPC+O) ; GET THE SYSTEM PC
- DEC DE ; ONE LESS IF FROM BKPT
- CALL MATCH+O ; SEE IF IT'S A BREAKPOINT
- JR NZ,ENTRY0 ; IT ISN'T, SO GO TO DISPLAY
- LD B,0 ; IT IS--FIRST FIX CODE
- LD A,(BRKCNT+O) ; PUT BREAKPOINT COUNTER
- LD C,A ; IN BC
- LD HL,CODSAV+O ; POINT TO SAVED CODE TABLE
- ADD HL,BC ; ADD OFFSET
- LD A,(HL) ; SAVED CODE TO A
- LD (DE),A ; THEN TO PROGRAM ADDRESS
- LD (SYSPC+O),DE ; SAVE THE ADJUSTED PC
- ;
- ;
- ; BEGIN OPENING SCREEN DISPLAY
- ;
- ENTRY0: LD E,CLRSCR ; CLEAR SCREEN
- CALL CHROUT+O
- ENTRY1: LD DE,MAF+O ; POINT TO AF MESSAGE
- CALL MSGOUT+O ; SEND IT
- LD (TMPWRD+O),SP ; PUT LOCAL SP IN IX--NOTHING SHOULD BE
- LD IX,(TMPWRD+O) ; PUSHED OR CALLED AT THIS POINT.
- CALL DISPAF+O ; DISPLAY AF HEX VALUES AND
- ; FLAG INDICATIONS
- CALL NEWLIN+O ; MOVE CURSOR TO NEXT LINE
- LD DE,MBC+O ; POINT TO BC MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISPBC+O ; DISPLAY HEX VALUES, INDIRECTS,
- ; AND ASCII REPRESENTATIONS.
- CALL NEWLIN+O ; DROP CURSOR FOR NEXT LINE
- LD DE,MDE+O ; POINT TO DE MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISPDE+O ; DISPLAY DE VALUES
- CALL NEWLIN+O ; CURSOR TO NEXT LINE
- LD DE,MHL+O ; POINT TO HL MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISPHL+O ; DISPLAY HL VALUES
- CALL NEWLIN+O ; CURSOR TO NEXT LINE
- LD DE,MAFP+O ; POINT TO AF' MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISAFP+O ; DISPLAY AF' VALUES
- CALL NEWLIN+O ; CURSOR TO NEXT LINE
- LD DE,MBCP+O ; POINT TO BC' MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISBCP+O ; DISPLAY BC' VALUES
- CALL NEWLIN+O ; CURSOR TO NEXT LINE
- LD DE,MDEP+O ; POINT TO DE' MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISDEP+O ; DISPLAY DE' VALUES
- CALL NEWLIN+O ; CURSOR TO NEXT LINE
- LD DE,MHLP+O ; POINT TO HL' MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISHLP+O ; DISPLAY HL' VALUES
- CALL NEWLIN+O ; CURSOR TO NEXT LINE
- LD DE,MIX+O ; POINT TO IX MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISPIX+O ; DISPLAY IX VALUES
- CALL NEWLIN+O ; CURSOR TO NEXT LINE
- LD DE,MIY+O ; POINT TO IY MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISPIY+O ; DISPLAY IY VALUES
- CALL NEWLIN+O ; CURSOR TO NEXT LINE
- LD DE,MSP+O ; POINT TO SP MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISPSP+O ; DISPLAY SP VALUES
- CALL NEWLIN+O ; CURSOR TO NEXT LINE
- LD DE,MPC+O ; POINT TO PC MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DISPPC+O ; DISPLAY PC CONTENTS
- LD HL,(MEMSEL+O) ; GET ADDRESS OF MEMORY FOR DISPLAY
- CALL DISMEM+O ; GO DISPLAY 128 BYTES OF MEMORY
- CALL NEWLIN+O ; CURSOR TO NEXT LINE
- CALL DISBRK+O ; DISPLAY BREAKPOINTS
- JP COMRET+O ; AND HEAD FOR COMMAND ENTRY
- ;
- ;
- ; BEGIN COMMAND PROCESSING MODULE
- ;
- COMAND: LD BC,COMCUR ; GET HEX COMMAND CURSOR POS
- CALL POSCUR+O ; POSITION CURSOR
- LD DE,MCOM+O ; POINT AT "Command?" MESSAGE
- CALL MSGOUT+O
- KEYIN: XOR A ; CLEAR A
- LD (CBUFCT+O),A ; ZERO COUNTER
- LD HL,COMBUF+O-1 ; SET BUFFER POINTER FOR 1ST CHAR
- KEYIN1: CALL KBD+O ; GET A CHARACTER
- ;
- ;
- ; CHECK FOR IMMEDIATE COMMANDS
- ;
- CP 'Q' ; CANCEL COMMAND? (ALWAYS ACTIVE)
- JP Z,COMRET+O ; YES, WIPE LINE & START OVER
- LD C,A ; SAVE CHAR IN C
- LD A,(COMFLG+O) ; IS A COMMAND IN PROGRESS?
- OR A ; NZ = YES
- LD A,C ; GET CHAR BACK
- JP NZ,CKCHAR+O ; YES, SKIP TO CHAR CHECK
- CP '+' ; PAGE MEMORY FORWARD?
- JP Z,MPAGE+O ; YES, GO TO MEMORY PAGE
- CP '=' ; TREAT SAME AS +
- JR NZ,CFM ; NOT '='--CHECK FOR -
- LD A,'+' ; MAKE = A + FOR 2ND COMPARE
- JP MPAGE+O ; AND GO TO PAGE MEM
- CFM: CP '-' ; PAGE MEMORY BACKWARD?
- JP Z,MPAGE+O ; YES, GO TO MEMORY PAGE
- CP 'G' ; CONTINUE FROM BREAKPOINT?
- JP Z,DBEND+O ; YES, GO TO END
- CP 'O' ; SINGLE-STEP?
- JP Z,SSTEP+O ; SIMON SAYS TAKE ONE STEP
- CP 'Z' ; CLEAR ALL BREAKPOINTS?
- JP Z,CLRBRK+O ; YES, GO DO IT.
- ;
- ;
- ; NOT AN IMMEDIATE COMMAND--PUT CHAR IN COMMAND BUFFER IF OK
- ;
- LD (COMFLG+O),A ; INDICATES COMMAND IN PROCESS
- CP 'D' ; DISPLAY MEMORY?
- JP Z,AD2BUF+O ; D OK; ADD TO BUFFER
- CP 'M' ; MODIFY MEMORY?
- JP Z,AD2BUF+O ; M OK; ADD TO BUFFER
- CP 'B' ; SET BREAKPOINT?
- JP Z,AD2BUF+O ; B OK; ADD TO BUFFER
- CP 'F' ; FIX (CLEAR) ONE BKPT?
- JP Z,AD2BUF+O ; F OK; ADD TO BUFFER
- CP 'J' ; JUMP TO ADDRESS?
- JP Z,AD2BUF+O ; J OK; ADD TO BUFFER
- CP 'L' ; FILL MEMORY?
- JP Z,AD2BUF+O ; L OK; ADD TO BUFFER
- CP 'R' ; MODIFY REGISTER?
- JP Z,AD2BUF+O ; R OK; ADD TO BUFFER
- CP 'T' ; BLOCK MOVE?
- JP Z,AD2BUF+O ; T OK; ADD TO BUFFER
- CP 'S' ; SEARCH STRING?
- JP Z,AD2BUF+O ; S OK; ADD TO BUFFER
- CP 'H' ; HEX ARITHMETIC?
- JP Z,AD2BUF+O ; H OK; ADD TO BUFFER
- JP BADCHR+O ; BEEP AND IGNORE
- ;
- ;
- ; CHECK CHARACTERS BEFORE ADDING TO BUFFER
- ; MUST BE HEX DIGIT, REGISTER IDENTIFIER,
- ; PERIOD, BS, OR CR. SPACE OK BUT NOT ADDED
- ; TO BUFFER.
- ;
- CKCHAR: OR A ; CLEAR CARRY FLAG
- CP '0' ; BELOW 0?
- JR NC,CK1 ; 0 OR ABOVE, KEEP GOING
- CP '.' ; IS IT A PERIOD
- JR Z,AD2BUF ; YES, ADD IT TO BUFFER
- CP '-' ; IS IT MINUS SIGN?
- JR Z,AD2BUF ; YES, ADD IT TO BUFFER
- CP '+' ; IS IT PLUS SIGN?
- JR Z,AD2BUF ; YES, ADD IT TO BUFFER
- CP 39 ; IS IT AN APOSTROPHE?
- JR Z,AD2BUF ; YES, ADD IT TO BUFFER
- CP 32 ; IS IT SPACE?
- JP Z,KEYIN1+O ; OK, BUT DON'T PUT IN BUFFER
- CP 13 ; IS IT CR?
- JP Z,COMDEC+O ; YES, END ENTRY, DECODE COMMAND
- CP 8 ; IS IT BACKSPACE?
- JR NZ,BADCHR ; NO, IT'S A BOO-BOO
- LD A,(CBUFCT+O) ; GET BUFFER COUNT
- OR A ; IS THE BUFFER EMPTY?
- JR Z,BADCHR ; YES, DON'T BACK UP ANY MORE
- DEC A ; DECREMENT BUFFER COUNTER
- LD (CBUFCT+O),A ; SAVE NEW VALUE
- DEC HL ; DECREMENT BUFFER POINTER
- JP KEYIN1+O ; GO FOR NEW CHARACTER
- CK1: CP 58 ; 0 TO 9?
- JR NC,CK2 ; ABOVE 9, KEEP GOING
- JR AD2BUF ; BETWEEK 0 & 9, ADD TO BUFFER
- CK2: CP 'A' ; BETWEEN 9 AND A?
- JR NC,CK3 ; ABOVE A, KEEP GOING
- JR BADCHR ; BETWEEN 9 & A, NO GOOD
- CK3: CP 'G' ; ABOVE F?
- JR NC,CK4 ; YES, ONE MORE CHECK
- JR AD2BUF ; NO, PUT IT IN BUFFER
- CK4: PUSH HL ; SAVE BUFFER TABLE LOCATION
- LD HL,COMCHR+O ; POINT TO CHARACTER TABLE
- LD BC,7 ; 7 CHARS TO CHECK
- CPIR ; IHLSPXY?
- POP HL ; BUFFER TABLE LOCATION BACK
- JR Z,AD2BUF ; YES, ADD TO BUFFER
- BADCHR: CALL BEEP+O ; BEEP KEYBOARD
- LD E,BS ; PRINT A
- CALL CHROUT+O ; BACKSPACE
- JP KEYIN1+O ; THEN GO FOR NEW CHAR
- ;
- ;
- ; COMMAND OR CHARACTER OK--ADD IT TO COMMAND BUFFER
- ;
- AD2BUF: LD C,A ; SAVE CHAR IN C
- LD A,(CBUFCT+O) ; GET BUFFER COUNT
- INC A ; BUMP COUNT
- CP 33 ; BUFFER FULL?
- JR NC,BADCHR ; YES, BEEP & IGNORE
- LD (CBUFCT+O),A ; SAVE COUNT
- LD A,C ; GET CHAR BACK
- INC HL ; BUMP BUFFER POINTER
- LD (HL),A ; PUT CHAR IN BUFFER
- JP KEYIN1+O ; GO FOR NEXT CHARACTER
- ;
- ;
- ; COMMAND DECODE
- ;
- COMDEC: LD A,(MODFLG+O) ; ARE WE DOING MODIFY MEMORY?
- OR A ; (1 = YES)
- JP NZ,MODME2+O ; YES, GO STRAIGHT TO IT
- LD HL,COMBUF+O ; POINT TO COMMAND BUFFER
- LD A,(HL) ; GET COMMAND
- LD E,A ; SAVE IT IN E
- LD A,(CBUFCT+O) ; GET BUFFER COUNT
- DEC A ; SUBTRACT ONE CHARACTER
- LD (CBUFCT+O),A ; SAVE NEW COUNT
- INC HL ; POINT TO NEXT BUFFER CHARACTER
- LD A,E ; GET COMMAND BACK
- CP 'D' ; IS IT DISPLAY?
- JP Z,DSPLAY+O ; YES, GO DO IT
- CP 'M' ; IS IT MODIFY MEMORY?
- JP Z,MODMEM+O ; YES, GO DO IT
- CP 'B' ; IS IT SET BREAKPOINT?
- JP Z,BRAKPT+O ; YES, GO DO IT
- CP 'F' ; IS IT CLEAR ONE BKPT?
- JP Z,FIXBRK+O ; YES, GO DO IT
- CP 'J' ; IS IT JUMP TO ADDRESS?
- JP Z,JUMP+O ; YES, GO DO IT
- CP 'L' ; IS IT FILL MEMORY?
- JP Z,FILL+O ; YES, GO DO IT
- CP 'R' ; IS IT MODIFY REGISTER?
- JP Z,REGMOD+O ; YES, GO DO IT
- CP 'T' ; IS IT BLOCK MOVE
- JP Z,MOVE+O ; YES, GO DO IT
- CP 'S' ; IS IT SEARCH STRING?
- JP Z,SEARCH+O ; YES, GO DO IT
- CP 'H' ; IS IT HEX ARITHMETIC?
- JP Z,HARITH+O ; YES, GO DO IT
- ;
- ;----------------------------------------------------------------------------
- ; COMMAND ACTION
- ;----------------------------------------------------------------------------
- ;
- ; PAGE MEMORY FORWARD OR BACK
- ;
- MPAGE: LD HL,(MEMSEL+O) ; CURRENTLY SELECTED MEMORY TO HL
- LD BC,80H ; ONE PAGE TO BC
- CP '+' ; IS IT FORWARD?
- JR Z,MPAGE1 ; YES, ADD TO ADDRESS
- SBC HL,BC ; IF NO, MUST BE BACK
- JR MPAGE2
- MPAGE1: ADD HL,BC
- MPAGE2: LD (MEMSEL+O),HL ; PUT NEW ADDR IN MEMSEL
- CALL DISMEM+O ; GO DISPLAY IT
- JP COMRET+O
- ;
- ;
- ; DISPLAY SELECTED ADDRESS, WITH THAT ADDRESS IN CENTER
- ; OF DISPLAY.
- ;
- DSPLAY: CALL GETWRD+O ; GET DISPLAY ADDR FROM COM BUF
- CALL COMCHK+O ; BE SURE COMMAND WAS OK
- JP NZ,COMRET+O ; GET OUT IF BAD COMMAND
- EX DE,HL ; PUT ADDRESS IN HL
- LD BC,30H ; PUT SELECTED ADDR IN
- SBC HL,BC ; MIDDLE OF DISPLAY
- LD (MEMSEL+O),HL ; SAVE IT AS CURRENT
- CALL DISMEM+O ; DISPLAY IT
- JP COMRET+O ; DONE; GO BACK
- ;
- ;
- ; MODIFY SELECTED BYTE OF MEMORY
- ;
- MODMEM: LD BC,COMCUR ; COMMAND LINE CURSOR POS
- CALL POSCUR+O ; POSITION CURSOR
- LD DE,MODMSG+O ; POINT TO MODIFY MESSAGE
- CALL MSGOUT+O ; PRINT IT
- CALL GETWRD+O ; GET ADDRESS TO MODIFY
- PUSH DE ; SAVE IT A SEC
- CALL GETBYT+O ; GET NEW BYTE
- LD C,E ; SAVE IT IN C
- POP DE ; GET ADDR BACK
- CALL COMCHK+O ; BE SURE COMMAND WAS OK
- JP NZ,COMRET+O ; GET OUT IF NOT
- LD A,C ; GET BYTE BACK
- EX DE,HL ; PUT ADDR IN HL
- PUSH HL ; SAVE UNADJUSTED ADDR
- LD (HL),A ; LOAD MODIFIED BYTE
- LD BC,30H ; ADJUST FOR
- SBC HL,BC ; CENTER OF DISPLAY
- LD (MEMSEL+O),HL ; SAVE THE ADDRESS AS SELECTED MEMORY
- CALL DISMEM+O ; PRINT NEW MEMORY DISPLAY
- LD A,1 ; SET MODIFY
- LD (MODFLG+O),A ; MEMORY FLAG
- MODME1: LD BC,MODCUR ; MODIFY CURSOR POSITION
- CALL POSCUR+O ; POSITION CURSOR
- LD DE,BLANK+O ; BLANK LAST
- CALL MSGOUT+O ; ENTRY
- LD BC,MODCUR ; PUT CURSOR BACK TO
- CALL POSCUR+O ; MODIFY POSITION
- POP HL ; GET LAST MODIFIED ADDR
- INC HL ; UPDATE IT
- PUSH HL ; SAVE IT AGAIN
- LD A,H ; PRINT
- CALL HX2ASC+O ; IT
- LD A,L
- CALL HX2ASC+O
- LD E,SPACE ; PRINT A
- CALL CHROUT+O ; SPACE
- JP KEYIN+O ; GET NEXT BYTE FROM KBD
- MODME2: LD HL,COMBUF+O ; POINT TO COMMAND BUFFER
- LD A,(HL) ; GET FIRST CHARACTER
- CP '.' ; END OF COMMAND?
- JP Z,COMRET+O ; YUP
- CALL GETBYT+O ; DECODE BYTE
- POP HL ; GET ADDR TO MODIFY
- LD (HL),E ; CHANGE IT
- PUSH HL ; SAVE ADDR AGAIN
- LD HL,(MEMSEL+O) ; GET DISPLAY MEM ADDR
- CALL DISMEM+O ; UPDATE DISPLAY
- JR MODME1 ; GO FOR NEXT BYTE
- ;
- ;
- ; SET BREAKPOINT FROM KEYBOARD ENTRY
- ;
- BRAKPT: CALL GETWRD+O ; GET BREAKPOINT ADDRESS
- CALL COMCHK+O ; MAKE SURE COMMAND WAS OK
- JP NZ,COMRET+O ; GET OUT IF NOT
- LD HL,BRKTBL+O ; SEE IF THERE'S A ZERO ENTRY
- LD B,6 ; WE CAN USE IN THE
- XOR A ; BREAKPOINT TABLE
- LD (BRKCNT+O),A
- PUSH DE ; SAVE THE BKPT ADDR
- BRAKP1: LD E,(HL) ; GET A LOW BYTE
- INC HL ; POINT TO HIGH BYTE
- LD A,(HL) ; PUT IT IN A
- OR E ; IS IT EMPTY?
- JR Z,BRAKP2 ; YES, GO FILL IT
- LD A,(BRKCNT+O) ; NOT ZERO, SO
- INC A ; BUMP BREAKPOINT COUNTER AND
- LD (BRKCNT+O),A ; SET UP TABLE POINTER FOR
- INC HL ; NEXT LOW BYTE,
- DJNZ BRAKP1 ; THEN GO CHECK IT.
- CALL BEEP+O ; NO ROOM IF LOOP FINISHES
- POP DE ; RESTORE STACK
- LD BC,ERRCUR ; GET ERROR CURSOR POSITION
- CALL POSCUR+O ; PLACE CURSOR
- LD DE,BRKFUL+O ; POINT TO BREAKPOINT FULL MSG
- CALL MSGOUT+O ; PRINT IT
- CALL DELAY+O ; WAIT THREE SECONDS
- JP COMRET+O ; AND GO FOR NEXT COMMAND
- BRAKP2: POP DE ; GET BKPT ADDR BACK
- LD (HL),D ; HIGH BKPT BYTE TO TABLE
- DEC HL ; MOVE TO LOW BYTE ADDR
- LD (HL),E ; LOW BKPT BYTE TO TABLE
- CALL SETBRK+O ; INSTALL BKPT AND SAVE CODE
- LD BC,BRKCUR ; POSITION CURSOR FOR
- CALL POSCUR+O ; BREAKPOINT DISPLAY
- CALL DISBRK+O ; WRITE IT
- JP COMRET+O ; DONE; GO FOR NEW COMMAND.
- ;
- ;
- ; SINGLE-STEP ROUTINE
- ; FIRST, CHECK FOR JUMP INSTRUCTIONS
- ;
- SSTEP: LD HL,(SYSPC+O) ; GET USER PC ADDR
- LD D,(HL) ; SAVE (PC) IN D
- LD A,D ; BRING IT TO A
- CP 0C3H ; JP UNCONDITIONAL?
- JR NZ,SSTE01 ; NO, GO ON
- JP SETSS2+O ; SET BKPT AND GO
- SSTE01: LD (TMPWRD+O),SP ; GET SP--NOTHING ON STACK
- CP 0E9H ; JP (HL)? (DISP=12)
- JR NZ,SSTE02 ; NO, GO ON
- LD HL,(TMPWRD+O) ; SP TO HL
- LD BC,12 ; HL DISPLACEMENT
- ADD HL,BC ; HERE'S USER HL
- JP SETSS3+O ; SET BKPT AND GO
- SSTE02: CP 0DDH ; JP (IX)? (DISP=2)
- JR NZ,SSTE03 ; NO, GO ON
- INC HL ; NEXT USER PROGRAM ADDR
- LD A,(HL) ; GET THE BYTE
- CP 0E9H ; ONE MORE TEST
- JR Z,SSTE18 ; YES, JP (IX).
- DEC HL ; NOT A JUMP--RETURN HL
- LD A,D ; GET BYTE BACK IN A
- JP SSTEP0+O ; GO TO REGULAR S-S
- SSTE18: LD HL,(TMPWRD+O) ; SP TO HL
- LD BC,2 ; IX DISPLACEMENT
- ADD HL,BC ; HERE'S USER IX
- JP SETSS3+O ; SET BKPT AND GO
- SSTE03: CP 0FDH ; JP (IY)? (DISP=0)
- JR NZ,SSTE04 ; NO, GO ON
- INC HL ; NEXT USER PROGRAM ADDR
- LD A,(HL) ; GET THE BYTE
- CP 0E9H ; ONE MORE TEST
- JR Z,SSTE19 ; YES, JP (IY).
- DEC HL ; NO JUMP--RETURN HL
- LD A,D ; GET BYTE BACK IN A
- JP SSTEP0+O ; GO TO REGULAR S-S
- SSTE19: LD HL,(TMPWRD+O) ; SP TO HL--IT IS USER IY
- JP SETSS3+O ; SET BKPT AND GO
- SSTE04: LD IX,(TMPWRD+O) ; SP TO IX--SET UP FOR JR
- LD C,(IX+18) ; FLAGS TO C
- CP 0C2H ; JP NZ?
- JR NZ,SSTE05 ; NO, GO ON
- BIT 6,C ; Z FLAG SET?
- JP NZ,SSTEP0+O ; YES, NO JUMP
- JP SETSS2+O ; SET BKPT AND GO
- SSTE05: CP 0CAH ; JP Z?
- JR NZ,SSTE06 ; NO, GO ON
- BIT 6,C ; Z FLAG SET?
- JP Z,SSTEP0+O ; NO, NO JUMP
- JP SETSS2+O ; SET BKPT AND GO
- SSTE06: CP 0D2H ; JP NC?
- JR NZ,SSTE07 ; NO, GO ON
- BIT 0,C ; C FLAG SET?
- JP NZ,SSTEP0+O ; YES, NO JUMP
- JP SETSS2+O ; SET BKPT AND GO
- SSTE07: CP 0DAH ; JP C?
- JR NZ,SSTE08 ; NO, GO ON
- BIT 0,C ; C FLAG SET
- JP Z,SSTEP0+O ; NO, NO JUMP
- JP SETSS2+O ; SET BKPT AND GO
- SSTE08: CP 0E2H ; JP PO?
- JR NZ,SSTE09 ; NO, GO ON
- BIT 2,C ; P FLAG SET
- JP NZ,SSTEP0+O ; YES, NO JUMP
- JP SETSS2+O ; SET BKPT AND GO
- SSTE09: CP 0EAH ; JP PE?
- JR NZ,SSTE10 ; NO, GO ON
- BIT 2,C ; P FLAG SET?
- JP Z,SSTEP0+O ; NO, NO JUMP
- JP SETSS2+O ; SET BKPT AND GO
- SSTE10: CP 0F2H ; JP P?
- JR NZ,SSTE11 ; NO, GO ON
- BIT 7,C ; S FLAG SET?
- JP NZ,SSTEP0+O ; YES, NO JUMP
- JP SETSS2+O ; SET BKPT AND GO
- SSTE11: CP 0FAH ; JP M?
- JR NZ,SSTE12 ; NO, GO ON
- BIT 7,C ; S FLAG SET?
- JP Z,SSTEP0+O ; NO, NO JUMP
- JP SETSS2+O ; SET BKPT AND GO
- SSTE12: CP 18H ; JR UNCONDITIONAL?
- JR NZ,SSTE13 ; NO, GO ON
- JP SETJR+O ; GET ADDR FOR JR
- SSTE13: CP 38H ; JR C?
- JR NZ,SSTE14 ; NO, GO ON
- BIT 0,C ; C FLAG SET?
- JP Z,SSTEP0+O ; NO, NO JUMP
- JP SETJR+O ; GET ADDR FOR JR
- SSTE14: CP 30H ; JR NC?
- JR NZ,SSTE15 ; NO, GO ON
- BIT 0,C ; C FLAG SET?
- JP NZ,SSTEP0+O ; YES, NO JUMP
- JP SETJR+O ; GET ADDR FOR JR
- SSTE15: CP 28H ; JR Z?
- JR NZ,SSTE16 ; NO, GO ON
- BIT 6,C ; Z FLAG SET?
- JP Z,SSTEP0+O ; NO, NO JUMP
- JP SETJR+O ; GET ADDR FOR JR
- SSTE16: CP 20H ; JR NZ?
- JR NZ,SSTE17 ; NO, GO ON
- BIT 6,C ; Z FLAG SET?
- JP NZ,SSTEP0+O ; YES, NO JUMP
- JR SETJR ; GET ADDR FOR JR
- SSTE17: CP 10H ; DJNZ?
- JR NZ,SSTEP0 ; NO JUMP
- OR B ; B=0?
- JR Z,SSTEP0 ; YES, NO JUMP
- SETJR: PUSH BC ; IN CASE OF DJNZ
- LD B,0 ; ZERO B
- INC HL ; NEXT INSTRUCTION ADDR
- LD A,(HL) ; REL JUMP TO A
- CP 82H ; NEGATIVE JUMP?
- JR NC,JRNEG ; YES, NEGATIVE
- LD C,A ; POSITIVE JUMP
- ADD HL,BC ; JUMP ADDR-1 NOW IN HL
- JR SETJR1
- JRNEG: CPL ; MAKE RELATIVE
- ADD A,1 ; JUMP POSITIVE
- LD C,A ; POSITIVE AMOUNT TO C
- SBC HL,BC ; THEN SUBTRACT
- SETJR1: INC HL ; ADJ FOR -2 IN JR
- POP BC ; GET BC BACK
- EX DE,HL ; PUT JUMP ADDR IN DE
- JP SETSS4 ; SET BKPT AND GO
- ;
- ; NO JUMPS, SO FIND OUT HOW LONG THE INSTRUCTION IS
- ;
- SSTEP0: INC HL ; NEXT ADDRESS
- LD E,(HL) ; SAVE (PC+1) IN E
- LD A,D ; GET (PC) BACK
- LD HL,TAB21+O ; POINT TO 1ST 2-BYTE TABLE
- LD BC,LENT21 ; NO. BYTES TO CHECK
- CPIR ; SEE IF (PC) IS 2-BYTE INST
- JR Z,ENDTWO ; YES, A 2-BYTE INST
- CP 0DDH ; NOT SURE YET--IS IT DD?
- JR Z,CK22 ; IT'S DD--TEST NEXT BYTE
- CP 0EDH ; NOT SURE YET--IS IT ED?
- JR Z,CK22 ; IT'S ED--TEST NEXT BYTE
- CP 0FDH ; NOT SURE YET-IS IT FD?
- JR NZ,SSTEP1 ; NOT FD--TRY 3-BYTE INST
- CK22: LD A,E ; 2ND INST BYTE TO A
- LD HL,TAB22+O ; POINT TO 2ND 2-BYTE TABLE
- LD BC,LENT22 ; NO. BYTES TO CHECK
- CPIR ; SEE IF (PC+1) IS 2-BYTE INST
- JR NZ,SSTEP1 ; NOT 2 BYTES; TRY 3
- ENDTWO: LD B,2 ; IT'S A 2-BYTE INST
- JP SETSS+O ; GO SET IT UP
- SSTEP1: LD A,D ; GET (PC) BACK
- LD HL,TAB31+O ; POINT TO 1ST 3-BYTE TABLE
- LD BC,LENT31 ; NO. BYTES TO CHECK
- CPIR ; SEE IF (PC) IS 3-BYTE INST
- JR Z,ENDTHR ; YES, A 3-BYTE INST
- CP 0DDH ; NOT SURE YET--IS IT DD?
- JR Z,CK32 ; IT'S DD--TEST NEXT BYTE
- CP 0EDH ; NOT SURE YET--IS IT ED?
- JR Z,CK32 ; IT'S ED--TEST NEXT BYTE
- CP 0FDH ; NOT SURE YET--IS IT FD?
- JR NZ,SSTEP2 ; NOT FD--TRY 4-BYTE INST
- CK32: LD A,E ; 2ND INST BYTE TO A
- LD HL,TAB32+O ; POINT TO 2ND 3-BYTE TABLE
- LD BC,LENT32 ; NO. BYTES TO CHECK
- CPIR ; SEE IF (PC+1) IS 3-BYTE INST
- JR NZ,SSTEP2 ; NOT 3 BYTES; TRY 4
- ENDTHR: LD B,3 ; IT'S A 3-BYTE INST
- JP SETSS+O ; GO SET IT UP
- SSTEP2: LD A,D ; GET (PC) BACK
- CP 0DDH ; LOOKING FOR 4-BYTE INST
- JR Z,CK42 ; IT'S DD--TEST NEXT BYTE
- CP 0EDH ; IS IT ED?
- JR Z,CK42 ; IT'S ED--TEST NEXT BYTE
- CP 0FDH ; IS IT FD?
- JR NZ,ONEBYT ; NO, MUST BE 1-BYTE INST
- CK42: LD A,E ; 2ND INST BYTE TO A
- LD HL,TAB42+O ; POINT TO 4-BYTE TABLE
- LD BC,LENT42 ; NO. BYTES TO CHECK
- CPIR ; SEE IF (PC+1) IS 4-BYTE INSTR
- JR NZ,ONEBYT ; NOT 4; MUST BE 1
- LD B,4 ; IT'S A 4-BYTE INST
- JR SETSS ; GO SET IT UP
- ONEBYT: LD B,1 ; IT'S A 1-BYTE INST
- ; WE'VE FOUND OUT WHERE THE NEXT INSTRUCTION IS.
- ; NOW INSTALL IT AS A BREAKPOINT, USING THE
- ; FIRST BREAKPOINT TABLE ADDRESS.
- SETSS: LD DE,(SYSPC+O) ; PUT USER PC IN DE
- SETSS1: INC DE ; MOVE TO NEXT ADDR ACCORDING
- DJNZ SETSS1 ; TO THE INSTRUCTION LENGTH
- JR SETSS4 ; THEN SET BKPT AND GO
- SETSS2: INC HL ; NEXT ADDRESS
- SETSS3: LD E,(HL) ; LOW JUMP BYTE TO E
- INC HL ; NEXT ADDRESS
- LD D,(HL) ; HIGH JUMP BYTE TO D
- SETSS4: LD HL,BRKTBL+O ; POINT TO THE BKPT TABLE
- LD (HL),E ; LOW ADDR BYTE TO TABLE
- INC HL ; BUMP TABLE ADDRESS
- LD (HL),D ; HIGH ADDR BYTE TO TABLE
- XOR A ; ZERO
- LD (BRKCNT+O),A ; BREAKPOINT COUNTER
- CALL SETBRK+O ; SET BKPT AT NEXT INST
- JP DBEND+O ; THEN EXECUTE A "GO"
- ;
- ;
- ; CLEAR (ZERO) ALL BREAKPOINTS
- ; FIRST RESTORE USER PROGRAM CODE
- ;
- CLRBRK: LD B,6 ; CHECK 6 TABLE ENTRIES
- LD HL,BRKTBL+O ; POINT TO BREAK TABLE
- XOR A ; ZERO
- LD (BRKCNT+O),A ; BREAKPOINT COUNTER
- CLRBR1: LD E,(HL) ; LOW BKPT BYTE TO E
- INC HL ; NEXT ADDR
- LD A,(HL) ; HIGH BKPT BYTE TO A
- OR E ; IS THERE AN ENTRY HERE?
- JR Z,CLRBR2 ; NO, CHECK NEXT ENTRY
- LD D,(HL) ; BKPT ADDR NOW IN DE
- CALL REPBRK+O ; RESTORE USER CODE
- CLRBR2: LD A,(BRKCNT+O) ; BUMP
- INC A ; BREAKPOINT
- LD (BRKCNT+O),A ; COUNTER
- INC HL ; NEXT TABLE ENTRY
- DJNZ CLRBR1 ; GO UNTIL 6 CHECKED
- ; THEN ZERO BREAKPOINT TABLE
- LD DE,BRKTBL+O ; START ADDR AT BREAK TABLE
- LD HL,BRKTBL+O+11 ; 12 ADDRESSES TO CLEAR
- XOR A ; ZERO A
- CALL LOAD+O ; ZERO THE TABLE
- LD BC,BRKCUR ; GET BKPT LINE CURSOR POS
- CALL POSCUR+O ; POSITION CURSOR
- CALL DISBRK+O ; SHOW CLEARED BKPTS
- JP COMRET+O ; DONE
- ;
- ;
- ; CLEAR (ZERO) A SPECIFIED BREAKPOINT
- ;
- FIXBRK: CALL GETWRD+O ; GET BKPT ADDR TO FIX
- CALL COMCHK+O ; BE SURE COMMAND WAS OK
- JP NZ,COMRET+O ; GET OUT IF BAD COMMAND
- CALL MATCH+O ; SEE IF IT'S A VALID BKPT
- LD A,(BRKCNT+O) ; GET BREAKPOINT COUNTER
- CP 6 ; DID WE TRY ALL W/ NO MATCH?
- JR NZ,FIXBR1 ; NO, THERE'S A MATCH
- CALL COMCH1+O ; NO MATCH--DO BAD COMMAND
- JP COMRET+O ; AND GET OUT
- FIXBR1: LD (HL),0 ; HIGH ADDR BYTE FROM COMPARE
- DEC HL
- LD (HL),0 ; LOW ADDR BYTE FROM COMPARE
- CALL REPBRK+O ; RESTORE USER CODE
- LD BC,BRKCUR ; GET BKPT LINE CURSOR POS
- CALL POSCUR+O ; POSITION CURSOR
- CALL DISBRK+O ; SHOW CLEARED BKPT
- JP COMRET+O ; AND RETURN
- ;
- ;
- ; JUMP TO SPECIFIED ADDRESS
- ;
- JUMP: CALL GETWRD+O ; GET JUMP ADDRESS
- CALL COMCHK+O ; BE SURE COMMAND IS OK
- JP NZ,COMRET+O ; GET OUT IF NOT
- LD (SYSPC+O),DE ; MAKE JUMP ADDR USER PC
- JP DBEND+O ; THEN DO A "GO"
- ;
- ;
- ; FILL DESIGNATED AREA OF MEMORY WITH SPECIFIED BYTE
- ;
- FILL: CALL GETWRD+O ; GET FILL START ADDRESS
- LD (START+O),DE ; SAVE START
- CALL GETWRD+O ; GET FILL END ADDRESS
- LD (ENDADD+O),DE ; SAVE END ON STACK
- CALL GETBYT+O ; GET FILL BYTE
- LD C,E ; SAVE IT IN C DURING CHECK
- CALL COMCHK+O ; BE SURE COMMAND WAS OK
- JP NZ,COMRET+O ; GET OUT IF NOT
- LD HL,(ENDADD+O) ; GET END ADDR BACK
- LD DE,(START+O) ; GET START ADDR BACK
- LD A,C ; GET FILL BYTE BACK
- CALL LOAD+O ; FILL THE MEMORY AREA
- JP COMRET+O ; DONE
- ;
- ;
- ; MODIFY REGISTER CONTENTS
- ;
- REGMOD: LD B,(HL) ; NEXT CHAR TO B
- CALL NXTCHR+O ; POINT TO NEXT CHAR
- LD A,(HL) ; NEXT CHAR TO A
- ADD A,B ; "HASH" REG IDENTIFIER
- CP 163 ; SP?
- JR NZ,REGM01 ; NO, TRY PC
- LD C,0FFH ; DUMMY DISPLACEMENT FOR SP
- JR REGM03 ; GO FOR NEW REG CONTENTS
- REGM01: CP 147 ; PC?
- JR NZ,REGM02 ; NO, TRY REGULAR REGISTERS
- LD C,0FEH ; DUMMY DISPLACEMENT FOR PC
- JR REGM03 ; GO FOR NEW REG CONTENTS
- REGM02: PUSH HL ; SAVE COM BUFF POINTER
- LD HL,REGTAB+O ; POINT TO REG ID TABLE
- LD BC,10 ; 10 VALUES TO CHECK
- CPIR ; CHECK THEM
- POP HL ; GET COM BUFF POINTER BACK
- JR NZ,BADREG ; NO MATCH; BAD COMMAND
- SLA C ; TIMES 2 FOR DISPLACEMENT
- REGM03: LD A,(CBUFCT+O) ; PREPARE
- DEC A ; FOR
- LD (CBUFCT+O),A ; CALL TO
- INC HL ; GETWRD
- CALL GETWRD+O ; GET NEW REG WORD
- CALL COMCHK+O ; BE SURE ADDRESS WAS OK
- JP NZ,COMRET+O ; GET OUT IF NOT
- LD A,C ; CHECK FOR SP & PC
- CP 0FFH ; SP?
- JR NZ,REGM04 ; NO, TRY PC
- LD (SYSSP+O),DE ; CHANGE USER SP
- JR REGM99 ; END COMMAND
- REGM04: CP 0FEH ; PC?
- JR NZ,REGM05 ; NO, REGULAR REGISTER
- LD (SYSPC+O),DE ; CHANGE USER PC
- JR REGM99 ; END COMMAND
- REGM05: LD (TMPWRD+O),SP ; SP TO HL--NOTHING
- LD HL,(TMPWRD+O) ; ON STACK HERE
- LD B,0 ; ZERO B
- ADD HL,BC ; ADD DISPLACEMENT
- LD (HL),E ; LOW BYTE TO STACK
- INC HL
- LD (HL),D ; HIGH BYTE TO STACK
- REGM99: LD E,HOME ; HOME
- CALL CHROUT+O ; CURSOR
- JP ENTRY1+O ; THAT'S ALL FOR REGMOD
- BADREG: CALL COMCH1+O ; BAD COMMAND
- JP COMRET+O ; GET OUT
- ;
- ;
- ; BLOCK MOVE--START ADDR, END ADDR, DESTINATION
- ;
- MOVE: CALL GETWRD+O ; GET MOVE START ADDR
- LD (START+O),DE ; SAVE START
- CALL GETWRD+O ; GET MOVE END ADDR
- LD (TMPWRD+O),HL ; SAVE COM BUF POSITION
- EX DE,HL ; END ADDR NOW IN HL
- LD DE,(START+O) ; START ADDR IN DE
- SBC HL,DE ; GOING FOR BYTE COUNT
- CALL C,COMCH1+O ; OOPS--START>END
- JP C,COMRET+O ; SO GET OUT
- INC HL ; HERE'S BYTE COUNT
- PUSH HL ; "EX BC,HL"
- POP BC ; BYTE COUNT IN BC
- LD HL,(TMPWRD+O) ; GET COM BUF POINTER BACK
- CALL GETWRD+O ; GET DEST ADDR
- CALL COMCHK+O ; CHECK COMMAND
- JP NZ,COMRET+O ; GET OUT IF BAD
- LD HL,(START+O) ; SOURCE TO HL
- LDIR ; MOVE 'EM
- JP COMRET+O ; AND DONE
-
- ;
- ;
- ; SEARCH FOR STRING IN MEMORY--START, END, UP TO 11 BYTES
- ;
- SEARCH: LD A,(HL) ; GET 1ST COM BUF CHAR
- CP '.' ; REPEAT LAST SEARCH?
- JR NZ,SEARC9 ; NO, DECODE COMMAND
- LD HL,(TMPWRD+O) ; YES, GET LAST FOUND ADDR
- LD BC,(BYTCNT+O) ; GET STRING LENGTH
- ADD HL,BC ; HL NOW PAST LAST FIND
- LD (START+O),HL ; MAKE THIS THE NEW START
- JR SEARC8 ; NOW GO TO SEARCH
- SEARC9: CALL GETWRD+O ; GET SEARCH START ADDR
- LD (START+O),DE ; SAVE START ADDRESS
- CALL GETWRD+O ; GET SEARCH END ADDR
- LD (ENDADD+O),DE ; SAVE END ADDR
- LD BC,0 ; ZERO BC
- LD DE,SCHSTR+O-1 ; POINT TO STRING BUFFER
- SEARC1: LD A,(HL) ; GET NEXT COMMAND BYTE
- CP '.' ; END OF STRING?
- JR Z,SEARC2 ; YES, START SEARCH
- PUSH DE ; I NEED A REGISTER!
- LD E,A ; SAVE CHARACTER
- LD A,(CBUFCT+O) ; GET BUFFER COUNTER
- CP 0 ; IF IT'S NEGATIVE, USER
- LD A,E ; {GET CHAR BACK}
- POP DE ; {GET DE BACK}
- CALL M,COMCH1+O ; FORGOT THE END PERIOD
- JP M,COMRET+O ; SO GET OUT
- INC DE ; ELSE GO TO NEXT STRING SPACE
- PUSH DE ; SAVE STRING POINTER
- CALL GETBYT+O ; GET NEXT STRING BYTE
- LD A,E ; PUT THE BYTE IN A
- POP DE ; GET STRING POINTER BACK
- LD (DE),A ; PUT IT IN STRING BUFFER
- INC BC ; BUMP BYTE COUNT
- JR SEARC1 ; GO FOR NEXT BYTE
- SEARC2: LD A,(CBUFCT+O) ; ADJUST BUFFER COUNT
- DEC A ; FOR
- LD (CBUFCT+O),A ; THE PERIOD
- CALL COMCHK+O ; THEN CHECK COMMAND
- JP NZ,COMRET+O ; GET OUT IF BAD
- LD (BYTCNT+O),BC ; SAVE STRING LENGTH
- SEARC8: LD HL,(START+O) ; POINT TO START ADDR
- DEC HL ; PREP FOR INC
- SEARC3: LD DE,SCHSTR+O ; POINT TO STRING
- LD BC,(BYTCNT+O) ; GET STRING LENGTH
- LD A,(DE) ; GET 1ST STRING BYTE
- SEARC4: INC HL ; NEXT MEMORY ADDR
- CALL ENDTST+O ; PAST END POINT?
- JR C,SEARC6 ; YES, STOP
- CP (HL) ; MATCH?
- JR NZ,SEARC4 ; NO, TRY NEXT MEM ADDR
- LD (TMPWRD+O),HL ; YES, SAVE "FOUND" ADDR
- SEARC5: INC HL ; NEXT MEMORY ADDR
- DEC BC ; ONE FOUND
- LD A,B ; TEST FOR
- OR C ; ZERO
- JR Z,SEARC7 ; ALL FOUND; STOP
- CALL ENDTST+O ; PAST END?
- JR C,SEARC6 ; YES, STOP
- INC DE ; NEXT STRING POSITION
- LD A,(DE) ; GET STRING BYTE
- CP (HL) ; MATCH?
- JR Z,SEARC5 ; YES, TRY NEXT
- DEC HL ; LAST MISS COULD BE 1ST HIT
- JR SEARC3 ; START STRING OVER
- SEARC6: LD BC,ERRCUR ; ERROR MESSAGE POSITION
- CALL POSCUR+O ; POSITION CURSOR
- LD DE,NOTFND+O ; POINT TO NOT FOUND MSG
- CALL MSGOUT+O ; PRINT IT
- CALL BEEP+O ; BEEP KEYBOARD
- CALL DELAY+O ; HOLD MSG 3 SEC
- JP COMRET+O ; BYE-BYE
- SEARC7: LD HL,(TMPWRD+O) ; GET FOUND ADDR
- LD BC,30H ; ADJUST
- SBC HL,BC ; FOR DISPLAY
- LD (MEMSEL+O),HL ; SET IT UP FOR DISPLAY
- CALL DISMEM+O ; DISPLAY FOUND POSITION
- JP COMRET+O ; AND DONE
- ;
- ; TEST FOR END OF STRING SEARCH AREA
- ;
- ENDTST: PUSH HL ; SAVE CURRENT MEMORY POINTER
- PUSH DE ; AND STRING POSITION
- EX DE,HL ; MEMORY POINTER TO DE
- LD HL,(ENDADD+O) ; SEARCH END ADDR
- SBC HL,DE ; PAST END?
- POP DE ; GET CURRENT
- POP HL ; CONDITIONS BACK
- RET ; CALLER CHECKS FLAG
- ;
- ;
- ; PERFORM HEX ADDITION AND SUBTRACTION FOR USER
- ;
- HARITH: CALL GETWRD+O ; GET THE FIRST NUMBER
- PUSH DE ; SAVE IT ON STACK
- LD A,(HL) ; ARITHMETIC OPERATOR
- LD (TMPWRD+O),A ; SAVE IT HERE
- CALL NXTCHR+O ; ADJ FOR OPERATOR
- CALL GETWRD+O ; GET SECOND NUMBER
- POP HL ; 1ST NO. NOW IN HL
- CALL COMCHK+O ; CHECK COMMAND
- JP NZ,COMRET+O ; GET OUT IF BAD
- LD A,(TMPWRD+O) ; GET OPERATOR BACK
- CP '-' ; SUBTRACT?
- JR Z,HARIT1 ; YES, GO DO IT
- ADD HL,DE ; NO, ADD
- JR HARIT2
- HARIT1: SBC HL,DE ; SUBTRACT.
- HARIT2: LD BC,COMCUR+20 ; CURSOR POSITION
- CALL POSCUR+O ; FOR ANSWER
- LD E,'=' ; PRINT
- CALL CHROUT+O ; EQUAL SIGN
- LD E,SPACE ; PRINT
- CALL CHROUT+O ; A SPACE
- LD A,H ; PRINT
- CALL HX2ASC+O ; THE
- LD A,L ; ANSWER
- CALL HX2ASC+O
- CALL KBD+O ; WAIT FOR KEYPRESS
- JP COMRET+O ; THEN GO HOME
- ;
- ;
- ; RETURN TO COMMAND LINE FROM COMMAND ACTION
- ;
- COMRET: LD BC,COMCUR ; GET COMMAND CURSOR POSITION
- CALL POSCUR+O ; POSITION CURSOR
- LD B,3 ; 3 TIMES TO CLEAR 1 LINE
- COMRE1: LD DE,BLANK+O ; POINT TO BLANK LINE
- CALL MSGOUT+O ; BLANK COMMAND LINE
- DJNZ COMRE1
- XOR A ; ZERO A
- LD (MODFLG+O),A ; CLEAR MODIFY MEMORY FLAG
- LD (COMFLG+O),A ; CLEAR COMMAND FLAG
- JP COMAND+O ; GO TO START OF COMMAND MODULE
-
- ;
- ;----------------------------------------------------------------------------
- ; RETURN TO USER PROGRAM
- ; END OF DEBUG MAIN PROGRAM CODE
- ;----------------------------------------------------------------------------
- ;
- DBEND: LD E,27 ; RESTORE
- CALL CHROUT+O ; USER
- LD E,'C' ; CURSOR
- CALL CHROUT+O ; POSITION
- LD E,'6'
- CALL CHROUT+O
- LD (TMPWRD+O),SP ; PRESERVE CURRENT LOCAL SP
- LD HL,(SYSPC+O) ; REPLACE CORRECT RETURN ADDR
- LD SP,(SYSSP+O) ; ON BOTTOM OF USER
- PUSH HL ; STACK
- LD (SYSSP+O),SP ; SAVE NEW SYSTEM SP
- LD SP,(TMPWRD+O) ; RESTORE CURRENT LOCAL SP
- POP IY ; RESTORE ALL REGISTERS
- POP IX
- POP HL ; FIRST THE PRIME REGISTERS
- POP DE
- POP BC
- POP AF
- EX AF,AF' ; THEN THE REGULAR REGISTERS
- EXX
- POP HL
- POP DE
- POP BC
- POP AF
- LD SP,(SYSSP+O) ; RESTORE THE SYSTEM SP
- ;
- ; RETURN TO CALLING PROGRAM
- ;
- RET ; TO CALLING PROGRAM
- ;
- ;
- ;----------------------------------------------------------------------------
- ; DEBUG-SPECIFIC SUBROUTINES
- ;----------------------------------------------------------------------------
- ;
- ; DISPLAY AF HEX VALUES AND FLAG REPRESENTATIONS
- ;
- DISPAF: LD H,(IX+19) ; PUT ENTRY A REGISTER IN A
- LD L,(IX+18) ; ENTRY F REGISTER IN L
- DPRIM: CALL ONLYRG+O ; PRINT REGISTER HEX VALUES
- LD E,SPACE ; PRINT TWO SPACES
- CALL CHROUT+O
- CALL CHROUT+O
- LD A,L ; FLAGS INTO A
- BIT 7,A ; CHECK SIGN FLAG
- JR Z,DISAF1 ; PRINT DASH IF ZERO
- LD E,'S' ; PRINT S IF SET
- JR DISAF2
- DISAF1: LD E,'-' ; PRINT HYPHEN IF NOT SET
- DISAF2: CALL CHROUT+O
- LD A,L ; GET FLAGS AGAIN
- BIT 6,A ; CHECK ZERO FLAG
- JR Z,DISAF3 ; PRINT DASH IF ZERO
- LD E,'Z' ; PRINT Z IF SET
- JR DISAF4
- DISAF3: LD E,'-'
- DISAF4: CALL CHROUT+O
- LD E,'x' ; BIT 5 NOT USED--DON'T CARE
- CALL CHROUT+O
- LD A,L ; GET FLAGS AGAIN
- BIT 4,A ; CHECK HALF-CARRY FLAG
- JR Z,DISAF5 ; PRINT DASH IF ZERO
- LD E,'H' ; PRINT H IF SET
- JR DISAF6
- DISAF5: LD E,'-'
- DISAF6: CALL CHROUT+O
- LD E,'x' ; BIT 3 NOT USED--DON'T CARE
- CALL CHROUT+O
- LD A,L ; GET FLAGS AGAIN
- BIT 2,A ; CHECK PARITY/OVERFLOW FLAG
- JR Z,DISAF7 ; PRINT DASH IF ZERO
- LD E,'P' ; PRINT P IF SET
- JR DISAF8
- DISAF7: LD E,'-'
- DISAF8: CALL CHROUT+O
- LD A,L ; GET FLAGS AGAIN
- BIT 1,A ; CHECK NEGATIVE FLAG
- JR Z,DISAF9 ; PRINT DASH IF ZERO
- LD E,'N' ; PRINT N IF SET
- JR DISAF0
- DISAF9 LD E,'-'
- DISAF0 CALL CHROUT+O
- LD A,L ; GET FLAGS ONE LAST TIME
- BIT 0,A ; CHECK CARRY FLAG
- JR Z,DISAFA ; PRINT DASH IF ZERO
- LD E,'C' ; PRINT C IF SET
- JR DISAFB
- DISAFA: LD E,'-'
- DISAFB: CALL CHROUT+O
- RET ; FLAG REPRESENTATIONS DONE
- ;
- ;
- ; DISPLAY HEX CONTENTS OF BC, INDIRECTS, AND ASCII REPRESENTATIONS
- ;
- DISPBC: LD H,(IX+17) ; PUT ENTRY B REGISTER IN H
- LD L,(IX+16) ; PUT ENTRY C REGISTER IN L
- JP REGRET+O
- ;
- ; DISPLAY HEX CONTENTS OF DE,INDIRECTS, AND ASCII REPRESENTATIONS
- ;
- DISPDE: LD H,(IX+15) ; PUT ENTRY D REGISTER IN H
- LD L,(IX+14) ; PUT ENTRY C REGISTER IN L
- JP REGRET+O
- ;
- ; DISPLAY HEX CONTENTS OF HL
- ;
- DISPHL: LD H,(IX+13) ; ENTRY H TO H
- LD L,(IX+12) ; ENTRY L TO L
- JP REGRET+O
- ;
- ; DISPLAY AF' VALUES
- ;
- DISAFP: LD H,(IX+11) ; ENTRY A' TO H
- LD L,(IX+10) ; ENTRY F' TO L
- JP DPRIM+O
- ;
- ; DISPLAY BC' VALUES
- ;
- DISBCP: LD H,(IX+9) ; ENTRY B' TO H
- LD L,(IX+8) ; ENTRY C' TO L
- JP REGRET+O
- ;
- ; DISPLAY DE' VALUES
- ;
- DISDEP: LD H,(IX+7) ; ENTRY D' TO H
- LD L,(IX+6) ; ENTRY E' TO L
- JP REGRET+O
- ;
- ; DISPLAY HL' VALUES
- ;
- DISHLP: LD H,(IX+5) ; ENTRY H' TO H
- LD L,(IX+4) ; ENTRY L' TO L
- JP REGRET+O
- ;
- ; DISPLAY IX VALUES
- ;
- DISPIX: LD H,(IX+3) ; ENTRY IXH TO H
- LD L,(IX+2) ; ENTRY IXL TO L
- JP REGRET+O
- ;
- ; DISPLAY IY VALUES
- ;
- DISPIY: LD H,(IX+1) ; ENTRY IYH TO H
- LD L,(IX) ; ENTRY IYL TO L
- JP REGRET+O
- ;
- ; DISPLAY SP VALUES
- ;
- DISPSP: LD HL,(SYSSP+O) ; SYSTEM SP TO HL
- JP REGRET+O
- ;
- ; DISPLAY PC CONTENTS
- ;
- DISPPC: LD HL,(SYSPC+O) ; SYSTEM PC TO HL
- JP REGRET+O
- ;
- ;
- ; DISPLAY THE SELECTED AREA OF MEMORY
- ; ON ENTRY, STARTING ADDRESS IS IN HL
- ;
- DISMEM: LD A,8 ; SET UP LINE COUNTER
- LD (LINECT+O),A
- LD BC,MEMCUR ; GET DISPLAY CURSOR POS
- DISME1: LD (CURSOR+O),BC ; SAVE CURSOR POSITION
- CP 5 ; ARE WE ON SELECTED LINE?
- JR NZ,DISME2 ; NO, GO ON
- DEC C ; MOVE CURSOR
- DEC C ; BACK 3
- DEC C ; POSITIONS
- CALL POSCUR+O ; POSITION CURSOR
- LD DE,PTR+O ; POINT TO POINTER
- CALL MSGOUT+O ; PRINT IT
- JR DISME3 ; THEN GO TO NUMBERS
- DISME2: CALL POSCUR+O ; PUT THE CURSOR THERE
- DISME3: LD A,H ; HIGH ADDR BYTE TO A
- CALL HX2ASC+O ; PRINT HEX VALUE
- LD A,L ; LOW ADDR BYTE TO A
- CALL HX2ASC+O ; PRINT HEX VALUE
- CALL DISREG+O ; PRINT THE ADDRESS CONTENTS
- LD A,(LINECT+O) ; GET LINE COUNT
- DEC A ; ONE LINE DONE
- RET Z ; RETURN IF DONE
- LD (LINECT+O),A ; SAVE NEW LINE COUNT
- LD BC,(CURSOR+O) ; GET THE CURSOR POSITION
- INC B ; MOVE IT DOWN ONE LINE
- JR DISME1 ; GO FOR NEXT LINE
- ;
- ;
- ; DISPLAY REGISTER CONTENTS AND INDIRECTS;
- ; RETURN TO REGISTER CALLING POINT
- ;
- REGRET: CALL ONLYRG+O ; DISPLAY REGISTER CONTENTS
- CALL DISREG+O ; DISPLAY REGISTER INDIRECTS
- RET
- ;
- ;
- ; DISPLAY CONTENTS OF ACTUAL REGISTER ONLY. ON ENTRY,
- ; CONTENTS OF SELECTED REGISTER ARE IN HL.
- ;
- ONLYRG: LD A,H ; MOVE REG HIGH BYTE TO A
- CALL HX2ASC+O ; PRINT ITS HEX REPRESENTATION
- LD E,SPACE ; PRINT A SPACE
- CALL CHROUT+O
- LD A,L ; MOVE REG LOW BYTE TO A
- CALL HX2ASC+O ; PRINT HEX REPRESENTATION
- RET ; THAT'S ALL WE NEED HERE
- ;
- ;
- ; PRINTS THE SIXTEEN INDIRECT VALUES AND ASCII CHARACTERS
- ; ON ENTRY, THE REGISTER TO BE DISPLAYED MUST BE IN HL
- ;
- DISREG: LD E,'-' ; PRINT A HYPHEN
- CALL CHROUT+O
- LD E,'>' ; AND A RIGHT CARET
- CALL CHROUT+O
- LD BC,16 ; BYTE COUNT
- LOOP01: LD A,(HL) ; GET A BYTE
- CALL HX2ASC+O ; PRINT IT
- LD E,SPACE ; PRINT A SPACE
- CALL CHROUT+O
- INC HL ; PREPARE FOR NEXT BYTE
- DEC C ; DECREMENT BYTE COUNT
- LD A,C ; NEED TO DO A COMPARE
- CP 8 ; HAVE WE JUST DONE THE 8TH BYTE?
- JR NZ,DISRG1 ; NO, GO ON
- LD E,SPACE ; YES, PRINT A SPACE
- CALL CHROUT+O
- JR LOOP01 ; AND GO FOR ANOTHER BYTE
- DISRG1: OR A ; ARE WE DONE?
- JR NZ,LOOP01 ; NO, GO FOR ANOTHER BYTE
- LD E,SPACE ; YES, PRINT ANOTHER SPACE
- CALL CHROUT+O
- LD BC,16 ; GET THE BYTE COUNT AGAIN
- SBC HL,BC ; SET HL BACK TO WHERE WE STARTED
- LOOP02: LD A,(HL) ; GET A CHARACTER
- CP 32 ; IS IT A CONTROL CHARACTER?
- JR C,DISRG5 ; YES, PRINT A PERIOD
- CP 127 ; IS IT A GRAPHICS CHARACTER?
- JR NC,DISRG5 ; YES, PRINT A PERIOD
- JR DISRG2 ; NO, IT HAS AN ASCII REPRESENTATION
- DISRG5: LD E,'.' ; YES, PRINT A PERIOD
- JR DISRG3 ;
- DISRG2: LD E,A ; ASCII CHARACTER TO E
- DISRG3: CALL CHROUT+O ; PRINT PERIOD OR CHARACTER
- INC HL ; PREPARE FOR NEXT CHARACTER
- DEC C ; DECREMENT BYTE COUNT
- LD A,C ; FOR THE COMPARES
- CP 8 ; DID WE JUST PRINT THE 8TH CHARACTER?
- JR NZ,DISRG4 ; NO, JUST CONTINUE
- LD E,SPACE ; YES, PRINT A SPACE
- CALL CHROUT+O
- JR LOOP02 ; AND GO FOR ANOTHER BYTE
- DISRG4: OR A ; WELL, THEN, ARE WE DONE?
- JR NZ,LOOP02 ; NO, GO FOR ANOTHER
- RET ; YES, RETURN
- ;
- ;
- ; DISPLAY BREAKPOINTS
- ;
- DISBRK: LD DE,BRKMSG+O ; POINT TO BREAKPOINT MSG
- CALL MSGOUT+O ; PRINT IT
- LD HL,BRKTBL+O ; POINT TO BREAKPOINT TABLE
- LD B,6 ; NUMBER OF ADDRESSES TO DISPLAY
- DISBR1: INC HL ; HIGH BYTE OF BREAKPOINT ADDR
- LD A,(HL) ; INTO A
- CALL HX2ASC+O ; PRINT IT
- DEC HL ; LOW BYTE OF BREAKPOINT ADDR
- LD A,(HL) ; INTO A
- CALL HX2ASC+O ; PRINT IT
- LD E,SPACE ; PRINT A SPACE
- CALL CHROUT+O
- INC HL ; MOVE TO NEXT BREAKPOINT
- INC HL
- DJNZ DISBR1 ; GO FOR IT IF NOT DONE
- RET ; ELSE RETURN
- ;
- ;
- ; THESE SUBROUTINES DECODE 4-CHARACTER ASCII ADDRESSES FROM
- ; THE COMMAND BUFFER. GETWRD RETURNS A 2-BYTE (ONE WORD)
- ; VALUE IN DE; GETBYT RETURNS A 1-BYTE VALUE (TREATED AS A
- ; "LOW" BYTE) IN THE E REGISTER. ON ENTRY, THE COMMAND
- ; BUFFER POINTER (ADDRESS) IS IN HL.
- ;
- GETWRD: CALL GETBYT+O ; GET THE FIRST (HIGH) BYTE
- LD D,A ; AND PUT IT IN D; THEN FALL
- ; THROUGH FOR 2ND (LOW) BYTE
- GETBYT: PUSH BC ; PRESERVE BC
- LD A,(HL) ; GET 1ST CHARACTER
- CALL NXTCHR+O ; ADJUST COUNTER & POINTER
- CALL ASC2HX+O ; CHANGE FROM ASCII TO HEX
- SLA A ; SHIFT IT TO BITS 7-4
- SLA A ; TO BECOME THE HIGH
- SLA A ; NIBBLE OF THE HEX NUMBER
- SLA A
- LD B,A ; SAVE IT IN B
- LD A,(HL) ; GET 2ND CHARACTER
- CALL NXTCHR+O ; ADJUST COUNTER & POINTER
- CALL ASC2HX+O ; CHANGE FROM ASCII TO HEX
- ADD A,B ; COMBINE WITH HIGH NIBBLE
- LD E,A ; PUT 2ND (LOW) BYTE IN E
- POP BC ; RETRIEVE BC
- RET ; ONE BYTE DONE
- ;
- ;
- ; ADJUST COMMAND BUFFER COUNTER AND POINT TO NEXT
- ; CHARACTER IN THE COMMAND BUFFER
- ;
- NXTCHR: PUSH BC ; SAVE BC
- LD C,A ; SAVE CHAR IN C
- LD A,(CBUFCT+O) ; GET BUFFER COUNTER
- DEC A ; SUBTRACT 1 FOR THIS CHARACTER
- LD (CBUFCT+O),A ; SAVE NEW COUNT
- LD A,C ; GET CHAR BACK
- INC HL ; POINT TO NEXT CHAR
- POP BC ; GET BC BACK AGAIN
- RET ; AND RETURN
- ;
- ;
- ; CHECKS COMMANDS AFTER DECODING BY SPECIFIC COMMAND
- ; MODULES TO BE SURE THERE ARE NO MISSING OR EXTRA
- ; CHARACTERS. THE COMMAND BUFFER COUNTER SHOULD BE 0
- ; AFTER ANY COMMAND HAS BEEN DECODED.
- ;
- COMCHK: LD A,(CBUFCT+O) ; GET COMMAND BUFFER COUNT
- OR A ; SHOULD BE 0 IF COMMAND OK
- RET Z ; RETURN OK
- COMCH1: PUSH AF ; SAVE NZ FLAG FOR RETURN
- CALL BEEP+O ; BEEP KEYBOARD
- LD BC,ERRCUR ; POSITION CURSOR
- CALL POSCUR+O ; FOR ERROR MESSAGE
- LD DE,BADCOM+O ; POINT TO BAD COMMAND MESSAGE
- CALL MSGOUT+O ; SEND IT
- CALL DELAY+O ; WAIT 3 SECONDS
- POP AF ; GET NZ FLAG BACK
- RET ; RETURN WITH BAD NEWS
- ;
- ;
- ; SET BREAKPOINT IN CODE. BREAKPOINT ADDRESS IS IN DE ON ENTRY
- ;
- SETBRK: PUSH BC ; WE'LL NEED THESE
- PUSH HL ; FOR A BIT
- LD B,0 ; ZERO B
- LD A,(BRKCNT+O) ; GET BREAKPOINT COUNTER
- LD C,A ; PUT IT IN C
- LD HL,CODSAV+O ; POINT TO CODE SAVE TABLE
- ADD HL,BC ; ADD OFFSET
- LD A,(DE) ; PROGRAM CODE TO A
- CP 0FFH ; IS IT ALREADY A BREAK?
- JR Z,SETBR1 ; YES, DON'T PUT IN CODSAV
- LD (HL),A ; THEN TO SAVE TABLE
- EX DE,HL ; BKPT ADDR TO HL
- LD (HL),0FFH ; BKPT INSTALLED
- SETBR1: POP HL ; RESTORE
- POP BC ; REGISTERS
- RET ; AND RETURN
- ;
- ;
- ; LOOK FOR ADDRESS IN BREAKPOINT TABLE
- ; ADDRESS TO TEST IS IN DE ON ENTRY
- ;
- MATCH: LD HL,BRKTBL+O ; POINT TO BREAKPOINT TABLE
- LD B,6 ; MAX 6 ENTRIES TO CHECK
- XOR A ; ZERO BREAKPOINT
- LD (BRKCNT+O),A ; COUNTER
- MATCH1: LD A,(HL) ; TABLE ENTRY LOW BYTE TO A
- CP E ; CHECK AGAINST BKPT LOW BYTE
- JR NZ,MATCH2 ; NO LB MATCH; GO TO NEXT ENTRY
- INC HL ; LOW BYTE MATCHES
- LD A,(HL) ; SO TRY HIGH
- CP D
- RET Z ; THIS IS THE ONE; RETURN
- JR MATCH3 ; NO HIGH BYTE MATCH
- MATCH2: INC HL ; NO LOW BYTE MATCH
- MATCH3: LD A,(BRKCNT+O) ; INCREMENT
- INC A ; BREAKPOINT
- LD (BRKCNT+O),A ; COUNTER
- INC HL ; AND TABLE POINTER
- DJNZ MATCH1 ; CONTINUE
- RET ; FROM HERE IF NO MATCH AT ALL
- ;
- ;
- ; LOAD SPECIFIED AREA OF MEMORY WITH SPECIFIED BYTE
- ; ON ENTRY, START ADDRESS IS IN DE, END ADDRESS IS IN HL,
- ; AND BYTE IS IN A
- ;
- LOAD: LD (DE),A ; LOAD BYTE INTO START ADDR
- INC DE ; NEXT ADDR TO LOAD
- PUSH HL ; DON'T LOSE END ADDR
- SBC HL,DE ; FILLED ALL YET?
- POP HL ; GET IT BACK
- JR NC,LOAD ; NO, DO NEXT
- RET ; YES, DONE
- ;
- ;
- ; RESTORE USER CODE TO PROGRAM FOR
- ; CLEAR BREAKPOINT ROUTINES
- ; ON ENTRY, BREAKPOINT ADDRESS IS IN DE
- ;
- REPBRK: PUSH BC ; SAVE CALLER COUNTER
- PUSH HL ; AND BKPT TABLE ADDR
- LD B,0 ; ZERO B
- LD A,(BRKCNT+O) ; GET BREAKPOINT COUNTER
- LD C,A ; PUT IT IN C
- LD HL,CODSAV+O ; POINT TO SAVED CODE TABLE
- ADD HL,BC ; ADD OFFSET
- LD A,(HL) ; GET SAVED CODE BYTE
- LD (DE),A ; AND PUT IT BACK IN PROGRAM
- POP HL ; GET BKPT ADDR BACK
- POP BC ; AND CALLER COUNTER
- RET
- ;
- ;
- ;----------------------------------------------------------------------------
- ; GENERAL SUBROUTINES/PRIMITIVES
- ;----------------------------------------------------------------------------
- ;
- ; GENERAL RETURN SUBROUTINE FOR BDOS FUNCTIONS
- ;
- GENRET: POP HL ; ONE RETURN FOR ALL THE
- POP DE ; ROUTINES THAT PUSH THESE
- POP BC ; REGISTERS
- RET
- ;
- ;
- ; GET CHARACTER FROM KEYBOARD
- ;
- KBD: PUSH BC ; PUSH REGISTERS
- PUSH DE ; FOR BDOS CALL
- PUSH HL
- LD C,CONIN ; GET CHAR FROM KEYBOARD
- CALL BDOS
- CP 96 ; LOWER CASE?
- JR C,KBD2 ; NO, GO AHEAD
- SUB 32 ; MAKE IT UPPER CASE
- KBD2: JR GENRET ; RETURN
-
- ;
- ;
- ; ONE CHARACTER TO SCREEN--ON ENTRY, CHARACTER MUST BE IN E REG
- ;
- CHROUT: PUSH BC ; SAVE THE REGISTERS
- PUSH DE
- PUSH HL
- LD C,CONOUT ; CONSOLE OUT FUNCTION
- CALL BDOS ; SEND CHAR TO SCREEN
- JP GENRET+O ; POP REGISTERS AND RETURN
- ;
- ;
- ; MESSAGE TO SCREEN--ON ENTRY, MESSAGE ADDRESS MUST BE IN DE
- ;
- MSGOUT: PUSH BC ; SAVE THE REGISTERS
- PUSH DE
- PUSH HL
- LD C,PSTR ; CONSOLE STRING OUT FUNCTION
- CALL BDOS ; SENT MESSAGE TO SCREEN
- JP GENRET+O ; POP REGISTERS AND RETURN
- ;
- ;
- ; CONVERT HEX VALUE TO ASCII REPRESENTATION
- ; ON ENTRY, CHARACTER MUST BE IN A REGISTER
- ;
- HX2ASC: PUSH BC ; PRESERVE BC
- LD B,A ; SAVE HEX NO. IN B
- SRL A
- SRL A
- SRL A
- SRL A ; BITS 4-7 NOW IN 0-3
- CALL HX2AS1+O ; SEND HIGH HEX NIBBLE TO SCREEN
- LD A,B ; GET HEX NO. BACK
- AND 0FH ; MASK OFF LOW NIBBLE
- CALL HX2AS1+O ; SEND LOW HEX NIBBLE TO SCREEN
- POP BC ; RESTORE BC
- RET ; SUBROUTINE DONE
- ; TRANSLATE HEX NIBBLE TO ASCII CHARACTER
- HX2AS1: CP 10 ; IS THE NIBBLE > 10?
- JR NC,LETTER ; IT'S A LETTER IF IT IS
- ADD A,48 ; MAKE IT ASCII FOR A NUMBER
- JR NIBOUT ; AND PRINT IT
- LETTER: ADD A,55 ; MAKE IT ASCII FOR A LETTER
- NIBOUT: LD E,A ; REALLY GO PRINT IT NOW
- CALL CHROUT+O
- RET ; HEX. CHAR PRINTED
- ;
- ;
- ; CONVERT ONE ASCII CHARACTER TO ITS HEX VALUE;
- ; I.E., 'F' BECOMES 0FH. THE CHARACTERS COMING
- ; IN HERE HAVE ALREADY BEEN CHECKED FOR PROPER
- ; RANGE IN THE COMMAND ENTRY MODULE
- ;
- ASC2HX: CP 58 ; IS IT A DIGIT?
- JR NC,ASC2H1 ; NO, MUST BE A LETTER
- SUB 30H ; ADJUST FOR DIGIT
- RET
- ASC2H1: SUB 37H ; ADJUST FOR LETTER
- RET
- ;
- ;
- ; PRINT CR LF
- ;
- NEWLIN: LD E,CR
- CALL CHROUT+O
- LD E,LF
- CALL CHROUT+O
- RET
- ;
- ;
- ; KAYPRO PROTOCOL TO POSITION CURSOR--
- ; CURSOR HEX Y AND X POSITIONS ARE PASSED IN BC
- ;
- POSCUR: LD E,27 ; KAYPRO CURSOR POSITION PROTOCOL--
- CALL CHROUT+O ; PRINT ESC '=' 'Y' 'X'
- LD E,'='
- CALL CHROUT+O
- LD E,B ; CURSOR Y POSITION
- CALL CHROUT+O
- LD E,C ; CURSOR X POSITION
- CALL CHROUT+O
- RET ; CURSOR NOW IN POSITION
- ;
- ;
- ; BEEP KEYBOARD
- ;
- BEEP: PUSH DE ; DON'T LOSE DE
- LD E,BELL ; PRINT BELL
- CALL CHROUT+O
- POP DE ; DE BACK
- RET
- ;
- ;
- ; DELAY APPROX 0.5 SEC FOR EACH COMPLETION OF 0FFFFH
- ; COUNT IN HL
- ;
- DELAY: LD B,6 ; DO INNER LOOP 6 TIMES
- DELAY1: LD HL,0FFFFH ; APPROX 0.5 SEC FOR
- DELAY2: DEC HL ; THE INNER LOOP
- LD A,H
- OR L ; HL = 0?
- JR NZ,DELAY2 ; NO, GO AGAIN
- DJNZ DELAY1 ; GO UNTIL B=0.
- RET
- ;
- ;----------------------------------------------------------------------------
- ; TABLES
- ;----------------------------------------------------------------------------
- ;
- ; "HASHED" REGISTER IDENTIFIERS FOR MODIFY REGISTER
- ; CONTENTS COMMAND
- ;
- REGTAB: DEFB 135 ; AF
- DEFB 133 ; BC
- DEFB 137 ; DE
- DEFB 148 ; HL
- DEFB 104 ; AF'
- DEFB 105 ; BC'
- DEFB 107 ; DE'
- DEFB 111 ; HL'
- DEFB 161 ; IX
- DEFB 162 ; IY
- ;
- ;
- ; BYTE TABLES FOR SINGLE-STEPPING
- ;
- TAB21: DEFB 0CBH ; IF THE INSTRUCTION BYTE
- DEFB 06H ; IS ANY OF
- DEFB 0EH ; TAB21
- DEFB 10H ; THEN IT'S A
- DEFB 16H ; 2-BYTE
- DEFB 18H ; INSTRUCTION
- DEFB 1EH
- DEFB 20H
- DEFB 26H
- DEFB 28H
- DEFB 2EH
- DEFB 30H
- DEFB 36H
- DEFB 38H
- DEFB 3EH
- DEFB 0C6H
- DEFB 0D3H
- DEFB 0D6H
- DEFB 0DBH
- DEFB 0DEH
- DEFB 0E6H
- DEFB 0EEH
- DEFB 0F6H
- DEFB 0FEH
- T21END: EQU $ ; FOR CHANGES AND CALCULATION
- ;
- ;
- TAB22: DEFB 09H ; IF THE 1ST INSTRUCTION
- DEFB 19H ; BYTE IS DD, ED, OR FD
- DEFB 23H ; AND THE NEXT
- DEFB 29H ; BYTE IS ONE OF
- DEFB 2BH ; TAB22,
- DEFB 39H ; THEN IT'S A
- DEFB 0E1H ; 2-BYTE
- DEFB 0E3H ; INSTRUCTION.
- DEFB 0E5H
- DEFB 0E9H
- DEFB 0F9H
- DEFB 40H
- DEFB 41H
- DEFB 42H
- DEFB 44H
- DEFB 45H
- DEFB 46H
- DEFB 47H
- DEFB 48H
- DEFB 49H
- DEFB 4AH
- DEFB 4DH
- DEFB 50H
- DEFB 51H
- DEFB 52H
- DEFB 56H
- DEFB 57H
- DEFB 58H
- DEFB 59H
- DEFB 5AH
- DEFB 5EH
- DEFB 60H
- DEFB 61H
- DEFB 62H
- DEFB 67H
- DEFB 68H
- DEFB 69H
- DEFB 6AH
- DEFB 6FH
- DEFB 72H
- DEFB 78H
- DEFB 79H
- DEFB 7AH
- DEFB 0A0H
- DEFB 0A1H
- DEFB 0A2H
- DEFB 0A3H
- DEFB 0A8H
- DEFB 0A9H
- DEFB 0AAH
- DEFB 0ABH
- DEFB 0B0H
- DEFB 0BAH
- DEFB 0B2H
- DEFB 0B3H
- DEFB 0B8H
- DEFB 0B9H
- DEFB 0BAH
- DEFB 0BBH
- T22END: EQU $ ; FOR CHANGES AND CALCULATION
- ;
- ;
- TAB31: DEFB 01H ; IF THE INSTRUCTION BYTE
- DEFB 11H ; IS ANY OF
- DEFB 21H ; TAB31,
- DEFB 22H ; THEN IT'S A
- DEFB 2AH ; 3-BYTE
- DEFB 31H ; INSTRUCTION.
- DEFB 32H
- DEFB 3AH
- DEFB 0C2H
- DEFB 0C3H
- DEFB 0C4H
- DEFB 0CAH
- DEFB 0CCH
- DEFB 0CDH
- DEFB 0D2H
- DEFB 0D4H
- DEFB 0DAH
- DEFB 0DCH
- DEFB 0E2H
- DEFB 0E4H
- DEFB 0EAH
- DEFB 0ECH
- DEFB 0F2H
- DEFB 0F4H
- DEFB 0FAH
- DEFB 0FCH
- T31END: EQU $ ; FOR CHANGES AND CALCULATION
- ;
- TAB32: DEFB 34H ; IF THE 1ST INSTRUCTION
- DEFB 35H ; BYTE IS DD, ED, OR FD
- DEFB 46H ; AND THE NEXT BYTE
- DEFB 4EH ; IS ONE OF
- DEFB 56H ; TAB32,
- DEFB 5EH ; THEN IT'S A
- DEFB 66H ; 3-BYTE
- DEFB 6EH ; INSTRUCTION
- DEFB 70H
- DEFB 71H
- DEFB 72H
- DEFB 73H
- DEFB 74H
- DEFB 75H
- DEFB 77H
- DEFB 7EH
- DEFB 86H
- DEFB 8EH
- DEFB 96H
- DEFB 9EH
- DEFB 0A6H
- DEFB 0AEH
- DEFB 0B6H
- DEFB 0BEH
- T32END: EQU $ ; FOR CHANGES AND CALCULATION
- ;
- ;
- TAB42: DEFB 21H ; IF THE 1ST INSTRUCTION
- DEFB 22H ; BYTE IS DD, ED, OR FD
- DEFB 2AH ; AND THE NEXT BYTE
- DEFB 36H ; IS ONE OF
- DEFB 0CBH ; TAB42,
- DEFB 43H ; THEN IT'S A
- DEFB 4BH ; 4-BYTE
- DEFB 53H ; INSTRUCTION
- DEFB 5BH
- DEFB 73H
- DEFB 7BH
- T42END: EQU $ ; FOR CHANGES AND CALCULATION
- ;
- ; TABLE LENGTHS FOR CPIR
- ;
- LENT21: EQU T21END-TAB21 ; LENGTH OF 1ST 2-BYTE TABLE
- LENT22: EQU T22END-TAB22 ; LENGTH OF 2ND 2-BYTE TABLE
- LENT31: EQU T31END-TAB31 ; LENGTH OF 1ST 3-BYTE TABLE
- LENT32: EQU T32END-TAB32 ; LENGTH OF 2ND 3-BYTE TABLE
- LENT42: EQU T42END-TAB42 ; LENGTH OF 4-BYTE TABLE
- ;
- ;----------------------------------------------------------------------------
- ; STACK
- ;----------------------------------------------------------------------------
- ;
- ; SET LOCAL STACK SPACE
- ;
- DEFS 64 ; 32-WORD LOCAL STACK
- LOCSP: DEFB 0 ; START OF STACK
- ;
- ;----------------------------------------------------------------------------
- ; ABSOLUTE END OF DEBUG CODE
- ;----------------------------------------------------------------------------
- CODEND EQU $
- ;
- ;
- ;----------------------------------------------------------------------------
- ; CALCULATIONS/EQUATES FOR RELOCATION AND OFFSET
- ;----------------------------------------------------------------------------
- ;
- CODSIZ EQU CODEND-CODBEG ; AMOUNT OF CODE TO RELOCATE
- DESTIN EQU RELTOP-CODSIZ-2 ; RELOCATION DESTINATION
- O EQU DESTIN-CODBEG ; OFFSET FOR CALLS AND JUMPS
- ;
- ;----------------------------------------------------------------------------
- END ; OF DEBUG