TITLE M5b Z-80 DEBUGGER ROM LIST NOCOND ;**************************************************************************** ; ; SYSTEM MONITOR FOR M5b ; (c) 1982,1983 GRH ELECTRONICS, CUPERTINO, CA ; ;**************************************************************************** ; ; This Monitor program resides at the top of memory & allows memory ; modification & testing, program breakpoints, console, printer, punch & ; reader I/O drivers and transfer to system boot ROM residing in same memory ; area as this ROM. ; *INCLUDE ZBMH122.HDR ;**************************************************************************** ; ; Revision status: ; ; 1.0 - Release ; 1.3 - 17 MAR 84 GRH ; Change to allow Boot command parameter passing to boot ROM. ; 1.5 - 29 SEP 85 GRH ; Fix bug in Input command which caused monitor to crash. ; The jump to 'BITS2' expects DE to be on stack. ; 1.10- 8 FEB 87 GRH ; Fix bug in register restore routine which caused IX & IY to be ; swapped prior to GOTO. ; 1.20 29 DEC 88 GRH ; Add banked memory support: ; 1. Page 0 initialization. ; 2. Init bank register to bank 0F8H. ; 1.21 27 JAN 89 GRH ; Add new monitor function routines. ; ; 1.22 11-22-90 GRH ; Move code to separate ROM in order to gain space for I/O drivers and ; interrupt code. ; Add rom xover function as include file. ; Add function dispatcher for execution and breakpoint entries. ; Add disk read, write, & logon commands ; 1-13-91 grh ; Add clock set command. ; VERSN EQU 122 ;**************************************************************************** FORM FALSE EQU 0 TRUE EQU NOT FALSE ; ; INCLUDE SYSTEM DEFINITION FILES ; ;*MACLIB ASMBTOOL.MLB ;*INCLUDE MONBOARD.DEF ;*INCLUDE ZBMFUNS.DEF ;*INCLUDE COMIOPB2.DEF ; LIST OFF *MACLIB ASMBTOOL.MLB *INCLUDE MONBOARD.DEF *INCLUDE ZBMFUNS.DEF *INCLUDE COMIOPB2.DEF LIST ON *INCLUDE ZBMG122.DEF THIS_ROM EQU DEB_RNUM ;ROM # OF THIS ROM RESTNT EQU 0F82AH ;BREAKPOINT ENTRY LOCATION IN RESIDENT ROM SUBTTL EXTERNAL ENTRY POINTS ORG MONROM ; JP CINIT ;COLD START ; ; EXTERNAL FUNCTION ENTRY DURING INTERRUPT ; DS (MONROM + 6) - $ JP I_STUB ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; EXTERNAL FUNCTION STUB FOR USE DURING AN INTERRUPT WITHOUT THE ; RESIDENT ROM ENABLED. USE IN ALL NON-RESIDENT ROMS. ; ENTRY- A= FUNCTION # ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; I_STUB: ADD A,2 ;BIAS UP PUSH HL LD H,MR_RNUM ;USE RESIDENT ROM LD L,A EX (SP),HL CALL XROMF ;GO EXECUTE THE FUNCTION INC SP ;BALANCE STACK INC SP RET ;**************************************************************************** ; ; COLD INIT ONLY SWITCHES TO RESIDENT ROM ; ;**************************************************************************** ; CINIT: ; ; SET STACK ; LD SP,MONSTK ; ; RESET ROM FUNCTION SHOULD NOT RETURN ; LD HL,[MR_RNUM SHL 8] + 1 ;RESET PUSH HL CALL XROMF ; ; IF RETURNED THEN HALT ; HALT SUBTTL MONITOR BOARD SHADOW ROM SELECTION PROCEDURE *INCLUDE XROM.Z80 SUBTTL INITIALIZATION CODE ;############################################################################ ; ; SIGN-ON ; ;############################################################################ ; LOGMSG: DB CR,LF,' 65K Banked Debugger V. ' PVERS VERSN DM CR,LF ;---------------------------------------------------------------------------- ; ; THIS IS THE COLD START INIT CODE ; ;---------------------------------------------------------------------------- ; ROM_INIT: ; ; SET MONITOR COMMAND ARGUMENT DEFAULTS ; LD A,DEFBNK LD HL,A1_BNK LD (ARGPTR),HL LD (HL),A INC HL LD (HL),A INC HL LD (HL),A ; ; FILL BREAKPOINT ADDRESSES WITH 0 (LAST BYTE OF EXIT ROUTINE ; LD BC,[NBKPTS * BP_REC] - 1 LD HL,TLOC LD (HL),0 PUSH HL POP DE INC DE LDIR ; ; INITIALIZE REGISTER IMAGES TO 0 ; LD HL,RLOC LD B,BNKLOC - RLOC + 1 ; INIT2: LD (HL),C ;C HAS 0 FROM LAST LDIR FINISH INC HL DJNZ INIT2 ; ; NOW CHANGE SP & PC TO 0100H ; LD HL,0100H LD (PLOC),HL LD (SLOC),HL ; ; DONE ; RET SUBTTL MONITOR FUNCTION CALL DISPATCHER ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; ENTRY- A= FUNCTION # ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; FUNCH: CP A,MAXFUNS JR NC,MFUNERR ; ; FUNCTION SEEMS LEGAL, FETCH EXECUTION ADDRESS FROM TABLE ; PUSH HL ;SAVE POSSIBLE ARGUMENT ; LD HL,FUNTABL ADD A,A ADD A,L LD L,A LD A,0 ADC A,H LD H,A LD A,(HL) INC HL LD H,(HL) LD L,A ; ; RESTORE ARGUMENT & PUT EXECUTION ADDRESS ON STACK EX (SP),HL ; ; RETURN TO EXECUTION ADDRESS ; RET ; ; ; FUNCTION ERROR ; MFUNERR: LD A,-1 OR A,A RET ;############################################################################ ; ; MONITOR FUNCTION TABLE ; ;############################################################################ ; FUNTABL: DW RETVERS ;0: RETURN MONITOR ROM VERSION DW DEBUG ;1: EXECUTE THE DEBUGGER DW REST ;2: BREAKPOINT CONTINUE DW PUTHXN ;3: DISPLAY HEX NIBBLE ON CONSOLE DW PUTHXB ;4: DISPLAY HEX BYTE ON CONSOLE DW PUTHXW ;5: DISPLAY HEX WORD ON CONSOLE DW PUTHXA ;6: DISPLAY HEX ADDRESS ON CONSOLE DW PRTS ;7: DISPLAY BIT7 TERMINATED TEXT ON CONSOLE ; MAXFUNS EQU ($ - FUNTABL) / 2 SUBTTL DEBUGGER FUNCTIONS ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; RETURN VERSION FUNCTION ; EXIT - HL= VERSION # (123D = 1.23) ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; RETVERS: LD HL,VERSN RET ;**************************************************************************** ; ; PRTS ROUTINE OUTPUTS AN ASCII STRING ONTO THE CONSOLE. ; THE STRING MUST BE TERMINATED BY BIT 7 SET IN THE LAST CHAR OF THE STRING. ; ENTRY- HL= TEXT PTR ; ;**************************************************************************** ; PRTS: ; ; SAVE REGISTER ; PUSH BC ; ; TOP OF PRINTING LOOP ; PRTA: LD C,(HL) ;FETCH CHAR ; RES 7,C ;MAKE SURE BIT 7 = 0 CALL CO ; BIT 7,(HL) ;IF BIT 7 = 1 THEN STOP INC HL JR Z,PRTA ; ; RESTORE & RETURN ; POP BC RET ;**************************************************************************** ; ; DISPLAY ADDRESS PROCEDURE ; ENTRY- E:HL= ADDRESS VALUE TO DISPLAY ; ;**************************************************************************** ; PUTHXA: ; ; DISPLAY BANK # ; PUSH HL LD C,E CALL PUTHXB ; ; DISPLAY COLON ; LD C,':' CALL CO ; ; DISPLAY ADDRESS VALUE ; POP HL ; ; FALL INTO HEX WORD OUTPUT ; ;**************************************************************************** ; ; DISPLAY HEX WORD ON SYSTEM CONSOLE PROCEDURE ; ENTRY- HL= BYTE TO DISPLAY ; ;**************************************************************************** ; PUTHXW: ; ; SAVE LOW NIBBLE ; PUSH HL ; ; DO HIGH BYTE 1ST ; LD C,H CALL PUTHXB ; ; NOW DO LOW NIBBLE ; POP HL LD C,L ; ; FALL INTO BYTE OUTPUT ; ;**************************************************************************** ; ; DISPLAY HEX BYTE ON SYSTEM CONSOLE PROCEDURE ; ENTRY- C= BYTE TO DISPLAY ; ;**************************************************************************** ; PUTHXB: ; ; SAVE LOW NIBBLE ; PUSH BC ; ; DO HIGH NIBBLE 1ST ; RRC C RRC C RRC C RRC C CALL PUTHXN ; ; NOW DO LOW NIBBLE ; POP BC ; ; FALL INTO NIBBLE OUTPUT ; ;**************************************************************************** ; ; DISPLAY NIBBLE ON SYSTEM CONSOLE ; ENTRY- C<3..0>= NIBBLE ; EXIT - A= C= ? ; ;**************************************************************************** ; PUTHXN: LD A,C AND A,0FH ADD A,90H ;PUT INTO ASCII ZONE DAA ;AH, THE UBIQUITOUS DAA CONVERT ADC A,40H DAA LD C,A JP CO SUBTTL DEBUGGER COMMAND INPUT ;---------------------------------------------------------------------------- ; ; DEBUGGER FUNCTION ; ;---------------------------------------------------------------------------- ; DEBUG: ; ; OUTPUT SIGN-ON MESSAGE ; LD HL,LOGMSG ;OUTPUT SIGN-ON CALL PRTS ; ; WARM RESTART ENTRY ; WINIT: ; ; FIRST RESTORE THE LOCAL STACK TO THE GLOBAL RAM ; LD SP,MONSTK ; ; PUT THE RETURN ON THE STACK FOR COMMANDS WHICH ARE SUBROUTINES ; LD HL,WINIT PUSH HL ; ; INIT BREAKPOINT VECTOR ; LD A,0C3H LD HL,RESTNT ;RESIDENT ROM ENTRY VECTOR LD (BP_RSTV),A LD (BP_RSTV +1),HL ; ; SET DEFAULT BANK ; LD C,DEFBNK XRROM 9 ; ; GET COMMAND FROM USER ; CALL CRLF CALL DECHO ; ; IF COMMAND NOT ALPHA THEN ERROR ; SUB A,'A' JR C,QPRT ; CP A,'Z' - 'A' + 1 JR NC,QPRT ; ; USE COMMAND CHAR AS OFFSET TO TABLE OF COMMAND EXECUTION ADDRESSES ; ADD A,A ;OFFSET = INDEX * 2 ; LD E,A LD D,0 LD HL,TBL ;ADDRESS = (TABLE + OFFSET) ADD HL,DE ; LD A,(HL) ;FETCH ADDRESS INC HL LD H,(HL) LD L,A ; LD B,2 ;PASS IN DEFAULT OF 2 ARGUMENTS TO COMMAND ; JP (HL) ;EXECUTE THE COMMAND ;---------------------------------------------------------------------------- ; ; PRINT COMMAND ERROR MESSAGE & RETURN TO COMMAND INPUT ; ;---------------------------------------------------------------------------- ; QPRT: ; ; DISPLAY ERROR PROMPT ; LD HL,QMSG CALL PRTWA ; ; EXECUTE WARM RESTART ; JR WINIT SUBTTL COMMANDS ;---------------------------------------------------------------------------- ; ; BOOT COMMAND ; ALLOWS EXECUTION OF A BOOT PROM ; ; B<(ARG * 10H) + PROM #> ; ARG :: 0..FH (PASSED TO BOOT ROM) ; PROM # :: 0..7 (DEFAULT # = 02H) ; ;---------------------------------------------------------------------------- BOOTC: ; ; IF NO ARGS THEN USE DEFAULT ; CALL PCHK ;IF NO FURTHER INPUT THEN USE DEFAULT JR C,BOOTCD ; ; ELSE GET USER ARG ; CALL EXF ;GET USER BOOT # POP BC ; JR BOOTCC ; ; ; SPECIAL DISK BOOT CODE SWAPS ROMS FOR BOOT. ; IF BOOT SUCCESSFUL, DOES NOT RETURN. ; IF UNSUCCESSFUL, RETURNS CARRY IF ERROR, NO CARRY IF DISK NOT INSERTED. ; BOOTCD: LD C,DK_RNUM ;PASS IN DEFAULT BOOT ROM ADDR ; BOOTCC: LD L,1 + 2 ;SET BOOT FUNCTION # LD A,C ;BITS 2..0 = ROM # AND A,7 ;MASK OFF EXTRANEOUS BITS & CLEAR ERROR FLAG ; LD H,A PUSH HL CALL XROMF INC SP INC SP ; ; IF RETURNED THEN MUST BE ERROR ; LD HL,BOOTEM CALL C,PRTWD ; JR WINIT ;GO TO MONITOR EXEC ;---------------------------------------------------------------------------- ; ; FILL MEMORY COMMAND ; ; THIS ROUTINE FILLS A BLOCK OF MEMORY WITH A USER DEFINED CONSTANT. IT ; EXPECTS 3 PARAMETERS TO BE ENTERED IN THE FOLLOWING ORDER: ; START ADDR, FINISH ADDR, FILL VALUE ; ; F ; ;---------------------------------------------------------------------------- ; FILL: ; ; GET 3 ARGUMENTS ; CALL EXPR3 ;HL= PTR, DE= LAST ADDR, BC= VALUE ; ; TOP OF FILL LOOP ; FIO: PUSH DE LD DE,(A1_BNK) ; ; IF IN PROTECTED AREA THEN IGNORE ; LD A,H ;IF IN MONITOR RAM THEN IGNORE CP A,HIGH MONSTK JR NC,FILNO ; OR A,A ;ELSE IF NOT IN PAGE 0 THEN OK JP NZ,FILYES ; LD A,L ;ELSE IF IN 1ST 40H BYTES THEN IGNORE CP A,40H JR C,FILNO ; FILYES: CALL PUTMEM ;STORE THE FILL VALUE ; FILNO: POP DE ; ; IF NOT LAST LOCATION THEN REPEAT ; CALL HILO JR NC,FIO ; ; ELSE DONE ; JP WINIT ;---------------------------------------------------------------------------- ; ; VERIFY MEMORY COMMAND ; ; THIS ROUTINE COMPARES 2 BLOCKS OF MEMORY AGAINST EACH OTHER. IF A ; DIFFERENCE IN THE RELATIVE ADDRESS CONTENTS IS DETECTED, THE ADDRESS OF THE ; 1ST BLOCK IS DISPLAYED, ALONG WITH IT'S CONTENTS & THE CONTENTS OF THE ; OTHER BLOCK'S SAME RELATIVE ADDRESS. ; ; V ; ;---------------------------------------------------------------------------- ; COMP: ; ; GET 3 ARGUMENTS FROM USER ; CALL EXPR3 ;HL= SRC, DE= LAST, BC= SRC2 ; ; TOP OF VERIFY LOOP ; CMPA: PUSH DE ;SAVE LAST PUSH BC ;SWAP SRC & SRC2 PTRS EX (SP),HL ; ; FETCH SRC2 DATA ; LD DE,(A3_BNK) CALL GETMEM LD C,A ; ; FETCH SRC1 DATA ; EX (SP),HL LD DE,(A1_BNK) CALL GETMEM LD B,A ;GET SOURCE 1 DATA ; ; IF SRC1 == SRC2 THEN EXIT ; LD A,C CP A,B ;IF S2=S1 THEN EXIT JR Z,CMPB ; ; ELSE DISPLAY SRC1 & SRC2 DATA ; PUSH AF ;SAVE S2 DATA ; CALL LADRB ;OUTPUT S1BNK:S1ADR S1DTA- LD A,B CALL DASH1 ; CALL BLK ;DISPLAY S2BNK:S2ADR S2DTA POP AF EX (SP),HL PUSH AF LD DE,(A3_BNK) CALL LADR CALL BLK POP AF EX (SP),HL ; CALL HEX1 ;OUTPUT S2DTA ; CMPB: POP BC POP DE ; ; IF SRC == LAST THEN DONE ; CALL HILOXB RET C ; ; ELSE REPEAT ; JR CMPA ;---------------------------------------------------------------------------- ; ; DISPLAY MEMORY COMMAND ; ; THIS ROUTINE DISPLAYS A BLOCK OF MEMORY ON THE CONSOLE DEVICE. THE ; USER MUST SPECIFY THE START & FINISH ADDRESSES. THE DISPLAY IS ORGANIZED TO ; DISPLAY UP TO 16 BYTES PER DISPLAY LINE, WITH ALL COLUMNS ALIGNED SO EACH ; COLUMN HAS THE SAME LAST HEX DIGIT IN IT'S ADDR. ; ; D[ ] ; ;---------------------------------------------------------------------------- ; DISP: ; ; GET ARGUMENTS ; CALL EXLF ;GET BLOCK LIMITS ; ; TOP OF LINE LOOP ; DIS1: ; ; DISPLAY START ADDRESS ; PUSH DE LD DE,(A1_BNK) CALL LADRB POP DE ; ; START DISPLAY ON PROPER COLUMN ; LD A,L ;SEE IF ON 16 BYTE BOUNDARY CALL TRPLSP ;SKIP OVER TO RIGHT COLUMN ; ; SAVE PTR FOR CHAR DISPLAY ; PUSH HL ; ; TOP OF HEX DISPLAY LOOP ; DIS2: ; ; DISPLAY MEMORY DATA IN HEX ; PUSH DE ;FETCH BANK # IN E LD DE,(A1_BNK) CALL GETMEM ;FETCH DATA FROM E:HL TO A CALL HEX1 ;DISPLAY DATA IN A POP DE ; ; IF DONE THEN GO ON TO ASCII ; CALL HILO ;INC & CHECK PTR JR C,DIS7 ;DONE IF CARRY ; ; NEXT COLUMN ; CALL BLK ;MAKE COLUMNS ; ; IF NOT ON EVEN 16 BYTE BOUNDARY THEN REPEAT ; LD A,L ;READY FOR NEW LINE? AND A,0FH JR NZ,DIS2 ; ; DONE WITH HEX DISPLAY, DO ASCII ; DIS3: ; ; RESTORE PTR ; POP HL ; ; POSITION START ON PROPER COLUMN ; LD A,L ;SKIP OVER TO RIGHT SPACE AND A,0FH CALL TRPL2 ; ; DISPLAY CHAR ; DIS4: PUSH DE ;FETCH BANK IN E LD DE,(A1_BNK) CALL GETMEM ;FETCH DATA POP DE ; AND A,7FH ;IF PRINTABLE THEN OUTPUT LD C,A CP A,' ' JR C,DIS5 ; CP A,7EH JR C,DIS6 ; DIS5: LD C,'.' ;ELSE OUTPUT '.' ; DIS6: CALL CO ; ; IF DONE THEN ABORT ; CALL HILOX RET C ; ; ELSE IF NOT ON EVEN 16 BYTE BOUNDARY THEN REPEAT ; LD A,L AND A,0FH JR NZ,DIS4 ; ; ELSE NEXT LINE ; JR DIS1 ; ; ; PARTIAL HEX LINE, START ASCII ON PROPER COLUMN ; DIS7: SUB A,E ;SKIP OVER TO START ASCII CALL TRPLSP JR DIS3 ;---------------------------------------------------------------------------- ; ; GOTO COMMAND ; ; GOTO COMMAND TRANSFERS CONTROL TO A SPECIFIED ADDRESS IT ALLOWS THE ; SELECTIVE SETTING OF UP TO 2 BREAKPOINTS AS WELL AS ALLOWING ANY CONSOLE ; INPUT TO BREAKPONT THE RUN, AS LONG AS INTERRUPT 1 IS ACTIVE. ; ; G ;START EXECUTION AT WHATEVER IS IN PC REG (NO BPS) ; G ;START EXECUTION AT START_ADDR (NO BPS) ; G,[,] ;START EXECUTION AT START_ADDR WITH ; BREAKPOINT AT BP1 AND OPTIONAL BREAKPOINT AT BP2 ; G,[,] ;START EXECUTION AT PC VALUE WITH BREAKPOINT(S) AT ; BP1 & OPTIONAL BP2. ; ;---------------------------------------------------------------------------- ; GOTO: ; ; IF NO ARGS THEN USE CURRENT REGISTERS ; CALL PCHK JR C,GO3 ; ; IF NO GOTO ADDRESS THEN SET BREAKPOINTS ; JR Z,GO0 ; ; FETCH NEW GOTO ADDRESS & PUT INTO 'PC' REGISTER ; PUSH AF ;PRESET BANK # LD A,(BNKLOC) LD (A1_BNK),A ; CALL EXF POP DE ; LD (PLOC),DE ;PUT ADDR IN PC LOCATION LD A,(A1_BNK) LD (BNKLOC),A ; ; IF LAST CHAR == CR THEN NO MORE ARGS ; LD A,C ;IF LAST = CR THEN EXIT CP A,CR JR Z,GO3 ; ; GET & SET UP TO NBKPTS BREAKPOINTS ; GO0: LD B,NBKPTS LD HL,TLOC ;POINT TO TRAP STORAGE ; GO1: PUSH BC ;SAVE BREAKPOINTS REMAINING ; ; GET BREAKPOINT FROM USER ; PUSH HL ;STORAGE PTR LD B,2 CALL EXPR1 POP DE ;GET TRAP ADDR POP HL ;SPTR ; ; IF BREAKPOINT == 0 (NONE) THEN STOP ; LD A,(A1_BNK) ;INSURE 0 WASN'T SPEC'D OR A,D OR A,E JR Z,GO2 ; ; ELSE STORE BREAKPOINT ADDRESS IN TABLE ; LD (HL),E ;SAVE BP ADDR INC HL ; LD (HL),D INC HL ; LD A,(A1_BNK) LD (HL),A INC HL ; ; SAVE EXISTING LOCATION DATA IN TABLE ; PUSH HL ;SAVE REGS NEEDED FOR GETMEM & PUTMEM EX DE,HL ;HL= PTR ; LD E,A ;E= BANK # CALL GETMEM PUSH AF ;SAVE DATA ; ; SET BREAKPOINT TO RESTART INSTRUCTION WHILE HERE ; PUSH BC ;SAVE LAST CHAR IN C LD C,BP_RSTI CALL PUTMEM POP BC ; POP AF ;RESTORE DATA EX DE,HL ;DE= PTR POP HL ;HL= RECORD.DATA PTR ; LD (HL),A ;STORE DATA INTO TABLE INC HL ;NEXT TABLE RECORD ; ; IF NO MORE ARGS THEN DONE WITH BREAKPOINTS ; GO2: LD A,C CP A,CR POP BC ;BP COUNT JR Z,GO3 ; ; IF MORE ALLOWED THEN CONTINUE ; DJNZ GO1 ; ; GOT ALL ARGS, EXECTUTE THE GOTO ; GO3: CALL CRLF ;NEW LINE FOR PGM ; POP HL ;GET RID OF WINIT RETURN ADDRESS ; ; INSERT RESTART BREAKPOINT VECTOR TO RESTORE ROUTINE ; LD HL,BP_RSTV LD DE,(BNKLOC) LD C,0C3H CALL PUTMEM INC HL LD C,LOW REST CALL PUTMEM INC HL LD C,HIGH REST CALL PUTMEM ; ; THE FOLLOWING CODE RESTORES THE Z80 REGISTERS & EXECUTES THE 'PC' ; ; FIRST RESTORE THE Z80 ALTERNATE REGISTERS ; LD HL,(FPLOC) PUSH HL POP AF ; LD BC,(CPLOC) LD DE,(EPLOC) LD HL,(LPLOC) EX AF,AF' EXX ; ; NOW DO THE Z80 & 8080 REGISTERS ; LD IY,(YLOC) LD IX,(XLOC) ; LD DE,(ELOC) LD BC,(CLOC) ; ; DO STACK ; LD SP,(SLOC) ; ; PUSH PC ON STACK FOR RETURN INSTRUCTION TO EXECUTE ; LD BC,(BNKLOC) XRROM 9 ; LD HL,(PLOC) PUSH HL ; XRROM 8 ; ; IF RETURNED THEN ERROR ; JP WINIT ;---------------------------------------------------------------------------- ; ; INPUT FROM PORT COMMAND ; ; THESE ROUTINES ALLOW BYTE-BY-BYTE INPUT OR OUTPUT FROM THE CURRENT ; CONSOLE DEVICE. ; ; I ; ;---------------------------------------------------------------------------- ; INPT: ; ; GET PORT ARG FROM USER ; CALL EXPR1 ;GET INPUT PORT # INTO C CALL CRLF ;PUT DATA ON NEW LINE POP BC ; ; FETCH PORT DATA ; IN E,(C) JP BITS2 ;OUTPUT VALUE ;---------------------------------------------------------------------------- ; ; OUTPUT DATA TO PORT COMMAND ; ; O ; ;---------------------------------------------------------------------------- ; OUPT: ; ; GET ARGS FROM USER ; CALL EXPR ;GET DATA INTO E, PORT # INTO C POP DE POP BC ; ; OUTPUT TO PORT ; OUT (C),E ; ; DONE ; JP WINIT ;---------------------------------------------------------------------------- ; ; MOVE COMMAND ; ; THIS ROUTINE EXPECTS 3 PARAMETERS, ENTERED IN THE FOLLOWING SEQUENCE: ; SOURCE 1ST BYTE ADDR, SOURCE LAST BYTE ADDR & DESTINATION 1ST BYTE ADDR. ; ; M ; ;---------------------------------------------------------------------------- ; MOVE: ; ; GET ARGS FROM USER ; CALL EXPR3 ;HL= SRC, DE= SRC_LAST, BC= DEST ; ; TOP OF MOVE LOOP ; MOV1: ; ; MOVE 1 BYTE OF DATA ; PUSH DE ;SAVE LAST PTR PUSH BC ;SAVE DEST PTR ; LD DE,(A1_BNK) ;FETCH SRC DATA CALL GETMEM ; EX (SP),HL ;HL= DEST PTR LD DE,(A3_BNK) ;STORE SRC DATA IN DEST LD C,A ; ; IF DESTINATION == PROTECTED THEN IGNORE ; LD A,H ;IF IN MONITOR RAM THEN IGNORE CP A,HIGH MONSTK JR NC,MOVNO ; OR A,A ;ELSE IF NOT PAGE 0 THEN OK JP NZ,MOVYES ; LD A,L ;ELSE IF IN 1ST 40H BYTES THEN IGNORE CP A,40H JR C,MOVNO ; MOVYES: CALL PUTMEM ; MOVNO: EX (SP),HL ;HL= SRC PTR POP BC ;BC= DEST PTR POP DE ;DE= LAST PTR ; ; NEXT, IF SRC <= LAST THEN REPEAT ; CALL HILOXB JR NC,MOV1 ; ; ELSE DONE ; JP WINIT ;---------------------------------------------------------------------------- ; ; SUBSTITUTE MEMORY COMMAND ; ; THIS ROUTINE ALLOWS THE USER TO INSPECT ANY MEMORY LOCATION & ALTER ; THE CONTENTS, IF DESIRED & IF THE ADDRESS IS IN RAM. THE CONTENTS MAY BE ; LEFT UNALTERED BY ENTERING A SPACE, COMMA OR RETURN. IF A RETURN IS ; ENTERED, THE ROUTINE IS TERMINATED. IF A SPACE OR COMMA IS ENTERED, THE ; ROUTINE PROCEEDS TO THE NEXT LOCATION & PRESENTS THE USER WITH AN ; OPPORTUNITY TO ALTER IT. ; ; S ; ;---------------------------------------------------------------------------- ; SUBS: ; ; GET ADDRESS FROM USER ; CALL EXPR1 ;GET ADDR CALL CRLF ;START ON NEW LINE POP HL ; ; TOP OF LOOP ; SUB1: ; ; DISPLAY EXISTING CONTENTS ; LD DE,(A1_BNK) CALL GETMEM CALL DASH1 ; ; GET NEW VALUE FROM USER ; CALL PCHK ;GET NEW VALUE ; ; IF NONE THEN RETURN ; JP C,WINIT ;IF CHAR = CR THEN RETURN ; ; IF LAST CHAR == SPACE OR COMMA THEN SKIP STORE ; JR Z,SUB2 ;IF CHAR = ' ' OR ',' THEN EXIT ; ; ELSE IF LAST CHAR == LINE FEED THEN BACK UP ; CP A,LF ;IF CHAR = LF THEN BACK UP JR Z,SUB3 ; ; ELSE GET & STORE VALUE ; PUSH HL ;PTR CALL EXF ;CONTINUE HEX INPUT POP DE ;NEW VALUE POP HL ;PTR ; PUSH BC LD C,E LD DE,(A1_BNK) CALL PUTMEM ;LOAD VALUE ; POP BC ; ; IF LAST CHAR == CR THEN DONE ; LD A,C ;IF DELIM = CR THEN DONE CP A,CR JP Z,WINIT ; ; NEXT LOCATION ; SUB2: INC HL ;PTR = PTR + 2 INC HL ; ; PREVIOUS LOCATION ; SUB3: DEC HL ;PTR = PTR - 1 ; ; IF ON MODULO 8 BOUNDARY, START ON NEW LINE & DISPLAY ADDRESS ; LD A,L AND A,7 CALL Z,LADRB ; ; CONTINUE ; JR SUB1 ;---------------------------------------------------------------------------- ; ; MTEST COMMAND TESTS A SPECIFIED BLOCK OF MEMORY TO SEE IF ANY HARD ; DATA BIT FAILURES EXIST. IT IS NOT AN EXHAUSTIVE TEST, BUT JUST A QUICK ; INDICATION OF THE MEMORY'S OPERATIVENESS. ; ; T ; ;---------------------------------------------------------------------------- ; MTEST: ; ; GET ARGS FROM USER ; CALL EXLF ;HL= START, DE= LAST ; ; TOP OF LOOP ; MTEST1: PUSH DE LD DE,(A1_BNK) CALL GETMEM ;FETCH DATA PUSH AF ;SAVE IT CPL ;INVERT BITS LD C,A CALL PUTMEM ; ; TEST BY XORING WITH DATA, RESULT SHOULD BE 0 ; CALL GETMEM XOR A,C ; ; IF NOT 0 THEN DISPLAY DATA ('1' BIT IS ERROR) ; CALL NZ,BITS ;LOG ERR IF NOT ; ; RESTORE DATA IN MEMORY ; POP AF ;RESTORE BYTE LD C,A CALL PUTMEM POP DE ; ; IF NOT DONE THEN REPEAT ; CALL HILOX JR NC,MTEST1 ; ; DONE ; JP WINIT ;---------------------------------------------------------------------------- ; ; EXAMINE REGISTERS COMMAND ; INSPECTS THE VALUES OF THE REGISTERS STORED BY THE LAST ENCOUNTERED ; BREAKPOINT. THE VALUES MAY BE MODIFIED IF DESIRED. ; ; X ;DISPLAY ALL REGISTER VALUES ; ;r= A,B,C,D,E,F,H,L,M,P,S,I,'A,'B,'C,'D,'E,'H,'L,'M,X,Y,R ; ;d= HEX NUMBER TO PLACE INTO REGISTER r ; ;---------------------------------------------------------------------------- ; ; CHARS NOT MATCH, TRY NEXT TABLE ENTRY ; XAA: INC HL ;SKIP OVER TO NEXT ENTRY INC HL ; ; ; CONTINUATION FROM USER INPUT ; ENTRY- A= REGISTER REQUESTED CHAR ; XA: ; ; IF AT END OF TABLE THEN DONE ; INC (HL) ;DOES NOT CHANGE IN ROM VERSION RET Z ; ; MAKE USER REQUEST BIT 7 SAME AS TABLE'S ; JP P,XAB ;SORT OUT BIT 7 OF TABLE OR A,80H ;SET IT ON TEST VALUE JR XAC ; XAB: AND A,7FH ;RESET BIT 7 ; ; USER REQUESTED REGISTER SHOULD MATCH NOW ; XAC: ; ; IF CHAR NOT MATCH THEN EXIT ; CP A,(HL) JR NZ,XAA ;NO MATCH, TRY AGAIN ; ; CHARS MATCH, SET UP TO DISPLAY CURRENT DATA ; CALL BLK CALL PRTVAL CALL DASH ; ; GET USER DATA ; CALL PCHK ; ; IF USER ENTERED CR THEN DONE ; RET C ; ; IF NO CHANGE THEN EXIT ; JR Z,XF ; ; GET NEW DATA FROM USER ; PUSH HL ;PTR CALL EXF POP HL ;HL= DATA ; ; PREFETCH DATA IN A ; LD A,L ; ; IF BYTE REGISTER THEN GO DO BYTE STORE ; EX (SP),HL ;HL= ATTRIBUTE PTR BIT 7,(HL) JR Z,XBREG ; ; ELSE IF WORD REGISTER THEN GO DO WORD STORE ; BIT 6,(HL) JR Z,XWREG ; ; ELSE DO INDIRECT BYTE STORE ; EX (SP),HL ;HL= DATA EX DE,HL ;HL= PTR LD DE,(BNKLOC) ;E= PC BANK PUSH BC ;SAVE LAST CHAR LD C,A CALL PUTMEM POP BC JR XE ; ; ; WORD REGISTER WRITE ; XWREG: EX (SP),HL ;HL= DATA EX DE,HL ;DE= DATA, HL= PTR INC HL ;PRTVAL LEFT PTR TO LOW BYTE -1 LD (HL),E INC HL LD (HL),D JR XE ; ; ; BYTE REGISTER WRITE ; XBREG: EX (SP),HL ;HL= DATA INC DE ;PRTVAL LEFT PTR TO LOW BYTE -1 LD (DE),A ; ; VALUE STORE DONE, RESTORE PTR TO ATTRIBUTES/OFFSET BYTE OF TABLE ; XE: POP HL ; ; IF LAST CHAR == CR THEN DONE ; XF: LD A,C ;IF LAST = CR THEN RETURN CP A,CR RET Z ; ;---------------------------------------------------------------------------- ; ; THIS IS THE ACTUAL COMMAND ENTRY POINT ; ;---------------------------------------------------------------------------- ; XMNE: ; ; START AT BEGINNING OF TABLE ; LD HL,ACTBL ;ADDR OF REG LOOK-UP TABLE ; ; IF NO ARGS THEN DISPLAY ALL REGS ; XMNE1: CALL PCHK JR C,XG ;IF CHAR = CR THEN SHOW ALL ; ; ELSE IF LAST CHAR == DELIMITER THEN REPEAT FOR ANOTHER REGISTER ; JR Z,XMNE1 ;IF CHAR = ' ' OR ',' THEN IGNORE ; ; ELSE IF USER REQUESTS ALTERNATE REGISTER THEN REPEAT WITH ALT TABLE ; CP A,'''' ;IF NOT PRIMES THEN EXIT JR NZ,XA LD HL,PRMTB JR XMNE1 ; ; ; DISPLAY ALL REGISTER'S DATA ; XG: LD A,(HL) ;FETCH TABLE ENTRY LD C,A ; ; IF AT END OF TABLE THEN DONE ; INC A ;IF AT END OF TABLE THEN RETURN RET Z ; ; IF BIT 7 SET THEN DISPLAY NEW LINE ; CALL M,CRLF ;NEW LINE IF BIT 7 SET ; ; DISPLAY REGISTER ; LD C,(HL) PUSH HL CALL CO CALL DASH ; ; DISPLAY REGISTER VALUE ; POP HL CALL PRTVAL CALL BLK INC HL ;NEXT ENTRY JR XG ;---------------------------------------------------------------------------- ; ; READ DISK SECTOR COMMAND ;RB:A D:T S ; WHERE: B= LOAD ADDRESS BANK ; A= LOAD ADDRESS ; D= DRIVE # ; T= TRACK # {0..N-1} ; S= SECTOR # {1..N} ; ;---------------------------------------------------------------------------- ; DKREAD: ; ; SET COMMAND ; LD A,PB_READC LD (IOPB + PB_CMDO),A ; ; SET NO DOWNLOAD ; LD HL,0 ;XFER COUNT = 0 ; LD A,L ;ENABLE READ XFER ; ; GO TO COMMON CODE ; JR DODISK ;---------------------------------------------------------------------------- ; ; WRITE DISK SECTOR COMMAND ;WB:A D:T S ; WHERE: B= XFER ADDRESS BANK ; A= XFER ADDRESS ; D= DRIVE # ; T= TRACK # {0..N-1} ; S= SECTOR # {1..N} ; ;---------------------------------------------------------------------------- ; DKWRIT: ; ; SET COMMAND ; LD A,PB_WRITC LD (IOPB + PB_CMDO),A ; ; SET NO UPLOAD ; LD HL,1024 ;XFER COUNT = MAX ; LD A,1 SHL PB_INHX ;DISABLE READ XFER ; ; GO TO COMMON CODE ; JR DODISK ;---------------------------------------------------------------------------- ; ; LOGON DISK SECTOR COMMAND ;RB:A D:T S ; WHERE: B= ID SECTOR DATA LOAD ADDRESS BANK ; A= ID SECTOR DATA LOAD ADDRESS ; D= DRIVE # ; T= TRACK # {0..N-1} ; S= SECTOR # {1..N} ; ;---------------------------------------------------------------------------- ; DKLOG: ; ; SET COMMAND ; LD A,PB_LOGC LD (IOPB + PB_CMDO),A ; ; SET NO DOWNLOAD ; LD HL,0 ;XFER COUNT = 0 ; LD A,L ;ENABLE READ XFER ; ; GO TO COMMON CODE ; DODISK: LD (IOPB + PB_FLGO),A LD (IOPB + PB_BCNTO),HL ; ; FETCH ARGS ; CALL EXPR3 ; ; SET VARS ; LD (IOPB + PB_DMAO),HL LD (IOPB + PB_TRKO),DE LD (IOPB + PB_SECO),BC LD A,(A1_BNK) LD (IOPB + PB_DMAXO),A LD A,(A2_BNK) LD (IOPB + PB_DRVO),A ; ; EXECUTE ; LD HL,IOPB LD DE,(THIS_BNK) XKROM MF_XIOB ; ; IF ERROR THEN DISPLAY IT ; INC A JP Z,QPRT ; LD A,(IOPB + PB_STATO) OR A,A RET Z ; LD HL,IOPB LD DE,(THIS_BNK) XKROM MF_DIOB ; ; DONE ; RET ;---------------------------------------------------------------------------- ; ; DISPLAY CLOCK DATA COMMAND ;K ; ;---------------------------------------------------------------------------- ; DCLKC: ; ; START ON NEW LINE ; CALL CRLF ; ; FETCH TIME DATA ; XVROM MF_GTIM ; ; DISPLAY DATA ; PUSH AF PUSH BC ;HOURS CALL PUTHXB LD C,':' CALL CO ; POP BC ;MINUTES LD C,B CALL PUTHXB LD C,':' CALL CO ; POP AF ;SECONDS LD C,A CALL PUTHXB CALL BLK CALL BLK ; ; FETCH CALENDAR DATA ; XVROM MF_GCAL PUSH HL PUSH BC PUSH AF ; ; DISPLAY CALENDAR DATA ; LD C,B ;MONTH CALL PUTHXB CALL DASH ; POP AF ;DAY LD C,A CALL PUTHXB CALL DASH ; POP BC ;YEAR CALL PUTHXB ; CALL BLK CALL BLK POP BC ;DAY-OF-WEEK {0 (SUN)..6} CALL PUTHXB ; ; DONE ; RET ;---------------------------------------------------------------------------- ; ; SET CLOCK/CALENDAR COMMAND ;UH:M MM:D Y:DOW ; ; WHERE: H= HOURS (24 HR FORMAT) {0..17H} ; M= MINUTES {0..3BH} ; MM= MONTH {1..0CH} ; D= DAY {1..1FH} ; Y= YEAR {0..99} ; DOW= DAY OF WEEK {0:SUN, 1:MON,..6:SAT} ; ;---------------------------------------------------------------------------- ; SCLKC: ; ; FETCH ARGS ; CALL EXPR3 ; ; TEST VALIDITY ; LD A,(A1_BNK) ;HRS CP A,24 JR NC,SCABRT ; LD A,L ;MINS CP A,60 JR NC,SCABRT ; LD A,(A2_BNK) ;MONTH DEC A CP A,12 JR NC,SCABRT ; LD A,E ;DATE DEC A CP A,31 JR NC,SCABRT ; LD A,(A3_BNK) ;YEAR CP A,100 JR NC,SCABRT ; LD A,C ;DAY OF WEEK CP A,7 JR C,SCLK1 ; ; ILLEGAL ENTRY ; SCABRT: JP QPRT ; SCLK1: ; ; SAVE CALENDAR DATA ; PUSH BC PUSH DE ; ; SET TIME ; LD DE,(A1_BNK) ;E=HRS LD D,L ;D=MINS LD B,0 ;B=SECS LD A,52H XVROM MF_STIM ; ; SET CALENDAR ; POP DE ;DATE LD B,E ;B=DATE LD A,(A2_BNK) ;D=MONTH LD D,A POP HL ;L=DAY OF WEEK LD A,(A3_BNK) ;E=YEAR LD E,A XVROM MF_SCAL ; ; DONE ; RET SUBTTL PROCEDURES & FUNCTIONS ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; EXF FUNCTION READS 1 ARGUMENT. ; ENTRY- A= ARGUMENT 1ST CHAR ; EXIT - STACK= ARGUMENT ; ;---------------------------------------------------------------------------- ; EXF: ; ; SET UP FOR 1 ARGUMENT ; LD B,1 ; ; INIT BANK PTR ; LD HL,A1_BNK LD (ARGPTR),HL ; ; ACCUMULATOR = 0 ; LD HL,0 ; ; ENTER GETTER WITH CHAR IN A ALREADY ; JR EX1 ;**************************************************************************** ; ; EXPR3 ROUTINE GETS 3 ARGUMENTS FROM USER, DOES A CR-LF & THEN ; LOADS BC, DE & HL WITH THE PARAMS. ; ENTRY- B= 2 ; EXIT - HL= ARG1 ; DE= ARG2 ; BC= ARG3 ; ;**************************************************************************** ; EXPR3: ; ; BUMP ARG COUNT TO 3 ; INC B ;B HAS 2 ALREADY ; ; GET ARGS ; CALL EXPR ; ; RETURN VALUES FROM STACK ; POP BC POP DE JP CRLFA ;GO DO CRLF ;**************************************************************************** ; ; EXPR SUBR. READS PARAMETERS FROM THE CONSOLE & DEVELOPS A 16 BIT HEX ; FOR EACH ONE. A CARRIAGE RETURN WILL TERMINATE THE ENTRY SEQUENCE. A BLANK ; OR COMMA WILL END THE CURRENT PARAMETER ENTRY. EACH PARAMETER ONLY TAKES ; THE LAST 4 DIGITS TYPED IN. ANY EXCESS IS DISCARDED. A NON-HEX DIGIT WILL ; TERMINATE THE ENTRY SEQUENCE & CAUSE A WARM BOOT OF THE MON. ; ENTRY- B= # OF PARAMETERS NEEDED ; EXIT - STACK= PARAMETERS ; ;**************************************************************************** ; ; ; EXPR: LD HL,A1_BNK LD (ARGPTR),HL ; JR EXPR0 ; ; ; ; EXPR1: LD HL,A1_BNK LD (ARGPTR),HL JR EXPR1A ; ; ; IF LAST CHAR NOT VALID THEN ERROR ; EX3: JP NZ,QPRT ;NON 0 IS ERR ; ; IF NO ARGUMENTS LEFT THEN DONE ; EXPR1A: DEC B RET Z ; ; ARG = 0 ; EXPR0: LD HL,0 ; ; GET NEXT CHAR FROM USER ; EX0: CALL ECHO ;GET NEXT # ; ; CONVERT CHAR TO BINARY ; EX1: LD C,A ;SAVE CHAR FOR LATER CALL NIBBLE ; ; IF NOT NUMBER THEN EXIT LOOP ; JR C,EX2 ; ; ELSE ADD TO ARGUMENT ; ADD HL,HL ;ARG *= 16 ADD HL,HL ADD HL,HL ADD HL,HL OR A,L ;ADD IN NEW DIGIT LD L,A ; ; GET NEXT DIGIT ; JR EX0 ;GET NEXT ; ; ; NOT HEX NUMBER ENTERED, IF COLON THEN SAVE ACCUMULATOR IN BANK REGISTER ; EX2: LD A,C CP A,':' JR NZ,EX2A ; ; STORE BANK # ; LD A,L LD HL,(ARGPTR) LD (HL),A ; ; RESTART WITH ACCUMULATOR = 0 ; JR EXPR0 ; ; ; ELSE PUT VALUE UNDER RETURN ADDRESS ON STACK ; EX2A: EX (SP),HL PUSH HL ; ; BUMP TO NEXT ARG PAGE ; LD HL,(ARGPTR) INC HL LD (ARGPTR),HL ; ; IF LAST CHAR NOT CR THEN GET NEXT ARGUMENT ; LD A,C CALL P2C JR NC,EX3 ; ; ELSE IF COUNT NOT EXHUSTED THEN ERROR ; DJNZ EX2B ; ; ELSE RETURN ; RET ; ; ; RELATIVE JUMP EXTENSION ; EX2B: JP QPRT ;**************************************************************************** ; ; OUTPUT 3 SPACES EACH COLUMN TO POSITION ON COLUMN PROCEDURE ; ENTRY- A= NUMBER OF COLUMNS - 1 {0..15} ; EXIT - A, B= ? ; ;**************************************************************************** ; TRPLSP: ; ; COMPUTE NUMBER OF SPACES ; AND A,0FH ;LIMIT TO 0..15 LD B,A ;MULTIPLY BY 3 (X= X * 2 + X) ADD A,A ; COLUMN ADD A,B ; TRPL2: LD B,A INC B ;CONVERT N-1 TO N ; TRPL1: PUSH BC CALL BLK ;DO SPACING POP BC DJNZ TRPL1 ; ; DONE ; RET ;**************************************************************************** ; ; BITS PROCEDURE DISPLAYS ADDRESS AND DATA AS BINARY BITS ; ENTRY- HL= ADDRESS ; A= BINARY DATA ; EXIT - A= ? ; ;**************************************************************************** ; BITS ; ; SAVE REG ; PUSH DE ; ; SAVE DATA ; PUSH AF ; ; DISPLAY ADDRESS ; CALL LADRB ;OUTPUT ADDR ; ; DISPLAY DATA ; POP DE LD E,D CALL BITS2 ; ; RESTORE & DONE ; POP DE RET ;**************************************************************************** ; ; BITS2 PROCEDURE DISPLAYS DATA AS BINARY BITS ; ENTRY- E= BINARY DATA ; EXIT - B= ? ; ;**************************************************************************** ; BITS2: ; ; BIT COUNT = 8 ; LD B,8 ;BIT COUNT ; ; TOP OF OUTPUT LOOP ; BITS1: PUSH BC ; LD A,E ;USE MS BIT RLCA LD E,A ; ; CONVERT TO ASCII ; LD A,'0' / 2 ;BUILD ASCII 1 OR 0 RLA ; ; DISPLAY ASCII DATA ; LD C,A PUSH DE CALL CO POP DE ; ; IF NOT DONE THEN REPEAT ; POP BC DJNZ BITS1 ; ; DONE ; RET ;**************************************************************************** ; ; DISPLAY REGISTER CONTENTS PROCEDURE ; ENTRY- HL= PTR TO TABLE 'REGISTER' ; EXIT - HL= PTR TO LAST BYTE OF TABLE RECORD ; DE= PTR TO LOW BYTE OF VALUE -1 ; A, BC= ? ; ;**************************************************************************** ; PRTVAL: ; ; FETCH ADDRESS OFFSET OF REGISTER DATA ; INC HL ;SKIP REGISTER CHAR LD A,(HL) ;GET OFFSET & ATTRIBUTES ; AND A,3FH ;ISOLATE OFFSET LD DE,RLOC ADD A,E ;BUILD ADDR OF REG CONTENTS LD E,A LD A,0 ADC A,D LD D,A ; ; IF BIT 7 == 0 THEN SINGLE REGISTER (BYTE) VALUE ; LD A,(HL) ;NOW FIND ATTRIBUTES LD B,1 ;ASSUME BYTE VALUE RLCA JR NC,PV1 ;IF SINGLE REG THEN EXIT ; ; ELSE WORD VALUE ; INC B ; ; IF BIT 6 == 0 THEN DIRECT ADDRESS ; RLCA JR NC,PV1 ; ; ELSE INDIRECT ADDRESS, (HL) ; PUSH HL ;BUILD ADDR IN HL ; LD A,(DE) ;USE CONTENTS OF HL AS ADDRESS OF VALUE LD H,A ; DEC DE LD A,(DE) LD L,A ; LD DE,(BNKLOC) ;FETCH (HL) VALUE CALL GETMEM EX DE,HL ;DE= PTR ; POP HL ; ; THIS IS TRICK, DECRIMENTS TO BYTE VALUE AND JUMPS AT SAME TIME ; DJNZ PV2 ;ALLWAYS JUMP ; ; ; FETCH DATA ; PV1: LD A,(DE) ;GET REG CONTENTS ; ; DISPLAY DATA ; PV2: CALL HEX1 ;OUTPUT VALUE ; ; NOW DO LOW BYTE IF NEEDED ; DEC DE ;MEM PTR ; ; IF --BYTE_COUNT > 0 THEN REPEAT FOR LOW BYTE ; DJNZ PV1 ; ; ELSE DONE ; RET ;**************************************************************************** ; ; ECHO ROUTINE READS A BYTE FROM CONSOLE DEVICE & ECHOS THE CHAR BACK ; TO THE CONSOLE DEVICE. ; EXIT - A= CHAR ; ;**************************************************************************** ; ; 1ST ENTRY DISPLAYS A '-' FIRST ; DECHO: CALL DASH ;OUTPUT A '-' ; ; GET CHAR FROM USER ; ECHO: CALL CONI ; ; ECHO TO USER ; PUSH BC LD C,A ;OUTPUT CHAR CALL CO LD A,C ;RESTORE CHAR IN A POP BC ; ; DONE ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; HILO FUNCTION INCREMENTS HL. IT THEN CHECKS FOR (& DISALLOWS) A ; WRAP-AROUND SITUATION. IF IT OCCURS, THE CARRY BIT WILL BE SET ON RETURN. ; IF NO WRAP-AROUND OCCURRED, HL IS COMPARED TO DE & THE FLAGS SET ACCORDINGLY. ; ENTRY- HL= PTR ; DE= LAST LOCATION ; EXIT - HL = HL + 1 ; CF = HL == 0 OR HL > DE ; A = ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; HILO: ; ; BUMP HL ; INC HL ; ; IF HL == 0 THEN RETURN CF ; LD A,H ;IF HL = 0 THEN RETURN CF OR A,L SCF RET Z ; ; ELSE CP DE,HL ; LD A,E ;ELSE COMPARE HL TO DE SUB A,L LD A,D SBC A,H ; ; RETURN RESULTS ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; HILOXB ROUTINE BUMPS BC & HL. IT THEN CHECKS FOR (& DISALLOWS) A ; WRAP-AROUND SITUATION. IF IT OCCURS, THE CARRY BIT WILL BE SET ON RETURN. ; IF NO WRAP-AROUND OCCURRED, HL IS COMPARED TO DE & THE FLAGS SET ; ACCORDINGLY. IT ALSO TESTS FOR A KEYBOARD ABORT. ; ENTRY- HL = PTR ; DE = LAST PTR ; EXIT - HL = HL + 1 ; BC = BC + 1 ; CF = (HL == 0) OR (HL > DE) OR (CONSOLE ABORT) ; A= ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; HILOXB: ; ; BUMP BC 1ST ; INC BC ; ; FALL INTO HILOX ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; HILO FUNCTION INCREMENTS HL. IT THEN CHECKS FOR (& DISALLOWS) A ; WRAP-AROUND SITUATION. IF IT OCCURS, THE CARRY BIT WILL BE SET ON RETURN. ; IF NO WRAP-AROUND OCCURRED, HL IS COMPARED TO DE & THE FLAGS SET ; ACCORDINGLY. IT ALSO CHECKS FOR A KEYBOARD ABORT. ; ENTRY- HL = PTR ; DE = LAST PTR ; EXIT - HL = HL + 1 ; CF = (HL == 0) OR (HL > DE) OR (CONSOLE ABORT) ; A= ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; HILOX: ; ; BUMP & TEST HL ; CALL HILO RET C ;DONE IF CF ; ; NOT DONE, CHECK FOR CONSOLE ABORT ; CALL CIS ;IF NO CONSOLE BREAK THEN OR A,A ; RETURN RET Z ; ; IF CHAR != CONTROL-S THEN BREAK ; CALL CONI ;IF CHAR <> CTRL-S THEN BREAK CP A,CTRLS SCF RET NZ ; ; ELSE PAUSE ; CALL CONI ;ELSE WAIT FOR NEXT CHAR ; ; RETURN CONTINUE ; OR A,A RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; NIBBLE FUNCTION CONVERTS THE ASCII CHARACTERS 0-9 & A-F TO THEIR ; EQUIVALENT HEX VALUE. IF THE CHARACTER IS NOT IN RANGE, THE CARRY BIT IS ; SET TO FLAG THE ERR. ; ENTRY- A= ASCII-HEX CHAR ; EXIT - A= BINARY VALUE OF 'CHAR' ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; NIBBLE: ; ; IF CHAR < 0 THEN RETURN ERROR ; SUB A,'0' RET C ; ; IF CHAR > F THEN RETURN ERROR ; CP A,'G' - '0' CCF RET C ; ; IF CHAR <= 9 THEN RETURN OK ; CP A,'9' - '0' + 1 CCF RET NC ; ; ELSE IF CHAR < A THEN RETURN ERROR ; SUB A,'A' - '9' - 1 CP 10 ; ; ELSE RETURN CHAR - 7 ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; PCHK FUNCTION READS A CHARACTER FROM THE CONSOLE, THEN CHECKS IT FOR A ; SPECIAL CHARACTER. IF IT IS NOT A SPECIAL CHARACTER, A NON-ZERO CONDITION ; IS RETURNED. IF IT IS A SPECIAL CHARACTER, A ZERO CONDITION IS RETURNED. ; FURTHER, IF THE CHARACTER IS A CR, THE CARRY FLAG IS SET. A BLANK OR A ; COMMA RESETS THE CARRY FLAG. ; EXIT - A= CHAR ; NC, ZF= DELIMITER (' ' OR ',') ; CF, ZF= CR ; NC. NZ= ANY OTHER ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; PCHK: ; ; GET CHAR FROM USER ; CALL ECHO P2C: ; ; IF CHAR == SPACE THEN RETURN NC,ZF ; CP A,' ' ;IF CHAR = ' ' THEN RETURN RET Z ; ; IF CHAR == COMMA THEN RETURN NC, ZF ; CP A,',' RET Z ; ; IF CHAR == RETURN THEN RETURN CF, ZF ; CP A,CR SCF RET Z ; ; ELSE RETURN NC,NZ ; CCF ;ELSE RETURN NC RET ;**************************************************************************** ; ; CONTINUATION OF BREAKPOINT CODE STARTED IN RESIDENT ROM. ; REST ROUTINE TRAPS ALL OF THE REGISTER CONTENTS WHENEVER A BREAKPOINT ; RESTART INSTRUCTION IS EXECUTED. THE TRAPPED CONTENTS ARE STORED IN THE ; MONITOR VARIABLE AREA FOR LATER ACCESS AND USE BY THE GOTO & THE EXAMINE ; REGISTERS COMMANDS. ; ; INSERT INTERRUPT DISABLER SOFTWARE AT START OF REST. ; ;**************************************************************************** ; REST: ; ; SET UP TO RESTORE BREAKPOINT(S) ; LD HL,TLOC ;SET TABLE PTR LD D,NBKPTS ; RS2: LD A,C SUB A,(HL) ;SEE IF SOFTWARE TRAP INC HL LD A,B SBC A,(HL) ;MAYBE, TRY REST OF ADDR INC HL LD A,(THIS_BNK) SBC A,(HL) JR Z,RS5 ;FOUND 1, RESET IT ; ; NOT FOUND, SKIP TO NEXT RECORD ; INC HL ;SKIP BANK INC HL ;SKIP DATA ; DEC D JR NZ,RS2 ; ; NO BREAKPOINTS MATCH, ASSUME NOT SET ; INC BC ;BACK UP PTR TO RETURN ADDRESS ; RS5: ; ; DISPLAY BREAKPOINT INDICATOR ; PUSH BC LD C,'*' ;OUTPUT BREAK INDICATION CALL CO ; ; STORE PC ; POP DE LD (PLOC),DE LD A,(THIS_BNK) LD (BNKLOC),A ; ; DISPLAY BREAK ADDRESS ; EX DE,HL ;HL= ADDR LD E,A ;E= BANK CALL LADR ; ; CLEAR BREAKPOINTS ; LD HL,TLOC LD B,NBKPTS ; ; TOP OF RESTORATION LOOP ; RS7: LD E,(HL) ;FETCH BREAKPOINT ADDRESS LD (HL),0 ;CLEAR BREAKPOINT INC HL LD D,(HL) LD (HL),0 INC HL LD C,(HL) LD (HL),0 INC HL ;SET PTR TO DATA ; ; IF BREAKPOINT ALREADY CLEARED THEN SKIP RESTORE ; LD A,E ;IF LOC = 0:0 THEN SKIP RESTORE OR A,D OR A,C JR Z,RS8 ; ; ELSE RESTORE ORIGINAL DATA ; LD A,(HL) ;ELSE RESTORE ORIGINAL INSTR. PUSH HL EX DE,HL ;HL= MEMPTR LD E,C ;E= BANK LD C,A ;C= DATA CALL PUTMEM POP HL ; ; NEXT BREAKPOINT ; RS8: INC HL ;DO NEXT BP DJNZ RS7 ; ; SAVE THE Z80 UNIQUES ; EX AF,AF' EXX LD (LPLOC),HL LD (EPLOC),DE LD (CPLOC),BC PUSH AF POP HL LD (FPLOC),HL LD (XLOC),IX LD (YLOC),IY ; ; GOTO MONITOR ; JP WINIT ;RETURN TO MONITOR ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; CONI ROUTINE READS THE CONSOLE & STRIPS OFF THE PARITY BIT. ; EXIT - A= CHAR AND 7FH ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; CONI: ; ; GET CHAR FROM CONSOLE ; CALL CI ; ; MASK OUT BIT 7 ; AND A,7FH ; ; IF UPPER CASE THEN RETURN ; CP A,'a' RET C ; ; ELSE IF LOWER CASE THEN ; CP A,'z' + 1 RET NC ; ; CONVERT TO UPPER CASE ; AND A,5FH RET ;**************************************************************************** ; ; PRTWD ROUTINE OUTPUTS AN ASCII STRING ONTO THE CONSOLE. ; THE STRING MUST BE TERMINATED BY BIT 7 SET IN THE LAST CHAR OF THE STRING. ; ENTRY- HL= TEXT PTR ; ;**************************************************************************** ; ; 1ST ENTRY STARTS ON A NEW LINE ; PRTWD: CALL CRLF ; ; THIS ENTRY STARTS WHEREVER THE CURSOR IS ; PRTWA: EQU PRTS ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; EXLF FUNCTION READS 2 ARGUMENTS FROM THE SYSTEM CONSOLE AND RETURNS ; WITH THE CONSOLE CURSOR ON THE NEXT LINE. ; ENTRY- B= 2 ; EXIT - HL= ARG1 ; DE= ARG2 ; A, BC= ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; EXLF: ; ; GET THE ARGS ; CALL EXPR ; ; RETURN THE ARGS ; POP DE POP HL ; ; FOLLOW WITH A NEW LINE ; JP CRLF ;**************************************************************************** ; ; CRLF ROUTINE OUTPUTS A CR-LF ON THE CONSOLE DEVICE TO ; START A NEW LINE. ; ;**************************************************************************** ; CRLF: ; ; SAVE REG ; PUSH HL ; ; DISPLAY CRLF MESSAGE ; CRLFA: LD HL,CRMSG CALL PRTS ; ; RESTORE REG & RETURN ; POP HL RET ;**************************************************************************** ; ; LADR ROUTINE OUTPUTS THE ADDRESS VALUE ON THE CONSOLE, EITHER AT ; THE START OF A NEW LINE (LADRA) OR AT THE CURRENT CURSOR LOCATION (LADR). ; ENTRY- E:HL= ADDRESS VALUE TO DISPLAY ; ;**************************************************************************** ; ; 1ST ENTRY STARTS ON A NEW LINE ; LADRA: PUSH DE PUSH HL CALL CRLF POP HL POP DE ; ; ENTRY TO CONTINUE AT CURRENT CURSOR LOCATION ; LADR EQU PUTHXA JP PUTHXA ;**************************************************************************** ; ; DISPLAY HEX BYTE ON SYSTEM CONSOLE PROCEDURE ; ENTRY- A= BYTE TO DISPLAY ; ;**************************************************************************** ; HEX1: PUSH BC ;ADJUST REGS LD C,A CALL PUTHXB POP BC RET ;**************************************************************************** ; ; DASH ROUTINE OUTPUTS A '-' TO THE CONSOLE DEVICE ; ;**************************************************************************** ; ; 1ST ENTRY DISPLAYS DATA BYTE IN A FIRST ; DASH1: CALL HEX1 ;OUTPUT A AS HEX ; ; THIS ENTRY DISPLAYS ONLY THE DASH ; DASH: LD C,'-' JR CO ;**************************************************************************** ; ; PRINT ADDR PROCEDURE DISPLAYS A WORD VALUE FOLLOWED BY A SPACE. ; ENTRY- E:HL= WORD VALUE TO DISPLAY ; ;**************************************************************************** ; LADRB: ; ; DISPLAY WORD VALUE ; CALL LADRA ; ; FALL INTO DISPLAY BLANK PROCEDURE ; ;**************************************************************************** ; ; DISPLAY A BLANK (SPACE) ON THE SYSTEM CONSOLE PROCEDURE ; ;**************************************************************************** ; BLK: ; ; PASS A BLANK TO CO PROCEDURE ; LD C,' ' ; ; FALLS INTO CO SUBR ; ;**************************************************************************** ; ; CONSOLE OUTPUT ; ENTRY- C= CHAR ; ;**************************************************************************** ; CO: ; ; SAVE REGS ; PUSH HL PUSH DE PUSH BC XCROM MF_CO ; ; RESTORE REGS ; POP BC POP DE POP HL ; ; DONE ; RET ;**************************************************************************** ; ; CONSOLE STATUS INPUT ; EXIT - A= 0: NOT READY, FFH: CHAR READY ; ;**************************************************************************** ; CIS: XCROM MF_CIS ; ; DONE ; RET ;**************************************************************************** ; ; CONSOLE INPUT ; EXIT - A= CHAR (CTRL-Z: EOF) ; ;**************************************************************************** ; CI: XCROM MF_CI ; ; DONE ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; RETURN BANKED MEMORY DATA FUNCTION ; ENTRY- HL= OFFSET PTR ; E= BANK # ; EXIT - A= DATA ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; GETMEM: XRROM MF_GMEM ; ; DONE ; RET ;**************************************************************************** ; ; STORE DATA INTO BANKED MEMORY PROCEDURE ; ENTRY- HL= OFFSET PTR ; E= BANK # ; C= DATA ; EXIT - A= ? ; ;**************************************************************************** ; PUTMEM: XRROM MF_PMEM ; ; DONE ; RET SUBTTL MESSAGES CRMSG: DM CR,LF BOOTEM: DM 'BOOT LOAD ERR',CR,LF QMSG: DM LF,'^??' SUBTTL DATA CONSTANTS ;############################################################################ ; ; TBL CONTAINS THE ADDRESSES OF THE COMMANDS. ; THE EXECUTIVE USES IT TO LOOK UP THE DESIRED ADDR. ; ;############################################################################ ; TBL: DW QPRT ;A DW BOOTC ;B BOOT DISK DW QPRT ;C CHECKSUM MEMORY DW DISP ;D DISPLAY MEMORY DW QPRT ;E DW FILL ;F FILL MEMORY DW GOTO ;G GOTO PGM & SET BREAKPOINTS DW QPRT ;H DW INPT ;I DISPLAY INPUT PORT DATA DW QPRT ;J DW DCLKC ;K CLOCK/CALENDAR DISPLAY DW DKLOG ;L LOGON DISK DW MOVE ;M MOVE MEMORY DW QPRT ;N DW OUPT ;O OUTPUT DATA TO OUTPUT PORT DW QPRT ;P DW QPRT ;Q DW DKREAD ;R READ DISK SECTOR DW SUBS ;S SUBSTITUTE MEMORY DW MTEST ;T TEST MEMORY DW SCLKC ;U UPDATE CLOCK/CALENDAR DW COMP ;V VERIFY (COMPARE) MEMORY DW DKWRIT ;W WRITE DISK SECTOR DW XMNE ;X EXAMINE & CHANGE REGISTERS DW QPRT ;Y DW QPRT ;Z ;---------------------------------------------------------------------------- ; ; Z80 REGISTER OFFSET TABLE ; ;---------------------------------------------------------------------------- ; ACTBL: DB 80H + 'A',ALOC - RLOC DB 'B',BLOC - RLOC DB 'C',CLOC - RLOC DB 'D',DLOC - RLOC DB 'E',ELOC - RLOC DB 'F',FLOC - RLOC DB 'H',HLOC - RLOC DB 'L',LLOC - RLOC DB 80H + 'M',[HLOC - RLOC] + 0C0H DB 'P',[PLOC - RLOC + 1 ] + 80H DB 'S',[SLOC - RLOC + 1 ] + 80H DB 'I',ILOC - RLOC ; ; PRIME Z80 REGISTER OFFSETS ; PRMTB: DB 80H + 'A',APLOC - RLOC DB 'B',BPLOC - RLOC DB 'C',CPLOC - RLOC DB 'D',DPLOC - RLOC DB 'E',EPLOC - RLOC DB 'F',FPLOC - RLOC DB 'H',HPLOC - RLOC DB 'L',LPLOC - RLOC DB 'M' + 80H,[HPLOC - RLOC] + 0C0H DB 'X',[XLOC - RLOC + 1 ] + 80H DB 'Y',[YLOC - RLOC + 1 ] + 80H DB 'R',RLOC - RLOC ; ; BANK REGISTER ; DB 80H + 'K',BNKLOC - RLOC DB -1 IF ($ AND 7FFFH) < 7800H CONMSG **** Code Too Large ( > FFFFH)! **** ENDIF END