TITLE M5b Z-80 MONITOR 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. ; ;**************************************************************************** ; ; Revision status: ; ; 1.0 - Release ; 1.1 - ; Add Double D deselect upon reset code. ; Change printer port. ; 1.2 - 20 FEB 83 GRH ; Add delay before turning off boot image, in case logic ; too slow. ; 1.3 - 17 MAR 84 GRH ; Change to allow Boot command parameter passing to boot ROM. ; ; 1.4 - 2 JUN 84 GRH ; Fix bug in line printer status subroutine which hung the ; line printer by sensing the status incorrectly. ; 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.6 - 6 DEC 85 GRH ; Add code to disable all Jade controllers from 40H to 43H after ; reset. ; 1.7 - 8 FEB 86 GRH ; Remove time delay from power up reset code to allow ISHA to access ; ram. ; Remove the auto-boot from reset function. ; ; 1.8 - 29 MAY 86 GRH ; Add Cromemco PRI printer driver as primary printer. ; Change IOBYTE definitions. ; Remove initialization of Jade FDC port 40H in anticipation of ; Cromemco bank select useage. ; ; 1.9 - 16 AUG 86 GRH ; Fix bug in PRI driver which caused new Oki 93 to be busy. ; ; 1.10- 8 FEB 87 GRH ; Fix bug in register restore routine which caused IX & IY to be ; swapped prior to GOTO. ; Change restart error to vector to breakpoint after message. ; ; 1.11- 27 DEC 87 GRH ; Add bank memory management routines. ; ; 1.12 20 JUL 88 GRH ; Add Monitor function call restart. ; ; 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. ; VERSN EQU 120 ;**************************************************************************** FORM FALSE EQU 0 TRUE EQU NOT FALSE ; ; INCLUDE SYSTEM DEFINITION FILES ; ;*MACLIB ASMBTOOL.MLB ;*INCLUDE ZMONROM.DEF ;*INCLUDE DKBTROM.DEF ;*INCLUDE CLOKROM.DEF ;*INCLUDE NAKEDT.DEF ;*INCLUDE MONBOARD.DEF ;*INCLUDE BIGZ.DEF ;*INCLUDE JDDCONT.DEF ;*INCLUDE PRI.DEF ; LIST OFF *MACLIB ASMBTOOL.MLB *INCLUDE ZMONROM.DEF *INCLUDE DKBTROM.DEF *INCLUDE CLOKROM.DEF *INCLUDE NAKEDT.DEF *INCLUDE MONBOARD.DEF *INCLUDE BIGZ.DEF *INCLUDE JDDCONT.DEF *INCLUDE PRI.DEF LIST ON ;============================================================================ ; ; ASSEMBLE TIME VARIABLES ; ;============================================================================ ; ; ASSEMBLY-TIME CONSTANTS ; ; ; BREAKPOINTS ; NBKPTS EQU 2 ;NUMBER OF BREAKPOINTS BP_RST EQU 8 ;BREAKPOINT RESTART # BP_RSTV EQU BP_RST ;BREAKPOINT RESTART VECTOR LOCATION BP_RSTI EQU 0C7H + BP_RSTV ;BREAKPOINT INSTRUCTION ; ; MONITOR FUNCTION CALL ; MFUNRST EQU 20H ;FUNCTION RESTART VECTOR # MFUNRSV EQU MFUNRST ;FUNCTION RESTART VECTOR LOCATION MFUNRSI EQU 0C7H + MFUNRST ;FUNCTION RESTART INSTRUCTION ; ; BANK SELECTION ; BNKREG EQU BZ_XADR ;MEMORY BANK SELECT REGISTER PORT ADDRESS (BIG Z) DEFBNK EQU 0 ;DEFAULT Z-80 EXECUTION BANK ; ; MONITOR ADDRESSES ; MONROM EQU 0F800H ;ROM START ADDR DK_ROM EQU DK_RNUM ;ROM # OF DISK ROM XDBROM EQU DK_RNUM ;DEFAULT BOOT ROM # ; ; PAGE 0 LOCATIONS ; WSVEC EQU 0 ;VECTOR NUMBER FOR WARM RESTART ; IOBYTE EQU 3 ;ADDR OF I/O CONTROL BYTE IOBYTV EQU 00H ;DEFAULT IOBYTE VALUE ; ; MEMORY BANK DATA IN PAGE 0 ; THIS_BNK EQU 001BH ;BANK # FOR THIS BANK (CONSTANT) THIS_STK EQU 001CH ;STACK PTR WHILE THIS BANK IS SELECTED PREV_BNK EQU 001EH ;LINK BACK TO PREVIOUS BANK ;============================================================================ ; ; CONSTANTS ; ;============================================================================ CTRLS EQU 13H ;ASCII DC3 CR EQU 0DH LF EQU 0AH BELL EQU 7 ;============================================================================ ; ; VARIABLES ; ;============================================================================ ; ; SAVE 128 BYTES FOR MONITOR ; ORG MONROM - 128 MONSTK EQU $ ; ; REGISTER IMAGE STORAGE ; RLOC DS 1 ;R ILOC DS 1 ;I YLOC DS 2 ;IY XLOC DS 2 ;IX FPLOC DS 1 ;F' APLOC DS 1 ;A' CPLOC DS 1 ;C' BPLOC DS 1 ;B' EPLOC DS 1 ;E' DPLOC DS 1 ;D' LPLOC DS 1 ;L' HPLOC DS 1 ;H' ELOC DS 1 ;E DLOC DS 1 ;D CLOC DS 1 ;C BLOC DS 1 ;B FLOC DS 1 ;F ALOC DS 1 ;A SLOC DS 2 ;SP ; LLOC DS 1 ;L HLOC DS 1 ;H PLOC DS 2 ;PC BNKLOC DS 1 ;PC BANK # ; ; BANKED MEMORY MANAGEMENT ; CBANK DS 1 ;CURRENT EXECUTION BANK DBANK DS 1 ;DESTINATION BANK # FOR MOVE SBANK DS 1 ;SOURCE BANK # FOR MOVE BNKCHG DS 1 ;BANK CHANGED FLAG (0: NOT, /0: CHANGED) ; ; BREAKPOINTS ; STRUCT 0 BPADDR DS 2 ;ADDRESS OF BREAKPOINT BPABNK DS 1 ;BANK # OF BREAKPOINT BPDATA DS 1 ;DATA DISPLACED BY RESTART INSTRUCTION BP_REC DS 0 ;NUMBER OF BYTES IN RECORD ENDM TLOC: REPT NBKPTS DS BP_REC ENDM ; ; BANK #S ASSOCIATED WITH ARGUMENTS ; ARGPTR DS 2 ;PTR TO CURRENT ARGUMENT'S BANK A1_BNK DS 1 ;ARG #1 BANK A2_BNK DS 1 A3_BNK DS 1 SUBTTL JUMP TARGETS FOR MONITOR ENTRY ORG MONROM ; ; COLD START VECTOR ; PHASECK MR_CBOOT CBOOT JP INIT ;COLD START ; ; CHARACTER I/O (6) ; PHASECK MR_CONIN STDIN: CONIN JP CI ;CONSOLE INPUT JP MONFUNC ;EXECUTE FUNCTION PHASECK MR_CONOUT STDOUT: CONOUT JP CO ;CONSOLE OUTPUT RET ;WAS PUNCH DS 2 PHASECK MR_LSTOUT STDLST: LIST JP LO ;LIST OUTPUT PHASECK MR_CONSTS STDINS: CONST JP CSTS ;CONSOLE STATUS ; ; MEMORY MANAGEMENT (5) ; JP GETMEM ;RETURN MEMORY DATA (WAS IOCHK) JP PUTMEM ;STORE MEMORY DATA (WAS IOSET) JP BNKSEL ;SELECT MEMORY BANK FOR EXECUTION (WAS MEMCK) JP XMOVE ;SELECT MEMORY BANKS FOR MOVE (WAS RTS) JP BMOVE ;MEMORY BLOCK MOVE (WAS RTS) DS 3 ;XBANK ;EXECUTE BANK FUNCTION ; ; MORE CHARACTER I/O ; PHASECK MR_LSTSTS STDLSTS: LPSTAT: JP LSTAT ;LINE PRINTER STATUS RETURN ; ; MONITOR PROCEDURE VECTORS ; JP REST ;BREAKPOINT ENTRY DS 3 ;EXIT ;EXECUTE REGISTERS PROCEDURE (GOTO) ; DS 3 ;RESTART ERROR ENTRY SUBTTL MONITOR BOARD SHADOW ROM SELECTION PROCEDURE ;---------------------------------------------------------------------------- ; ; EXECUTE SHADOW ROM FUNCTION ; THE OUTPUT INSTRUCTION IN THE FOLLOWING CODE MUST RESIDE AT THE ; ADDRESS JUST PRIOR TO THE ROM CODE TO EXECUTE. IN THIS CASE, F833H. ; ENTRY- A<2..0>= ROM NUMBER ; ;---------------------------------------------------------------------------- DS 2 SWPROM: PUSH AF ;BALANCE STACK IN CASE SWAP NOT DONE IF $ <> MR_XOVER CONMSG **** WARNING! Xover Address Mismatch! **** ENDIF OUT (M2_RSEL),A POP AF RET SUBTTL MEMORY MANAGEMENT ROUTINES ;**************************************************************************** ; ; BANK SELECT PROCEDURE ; NOTE: THIS FUNCTION IS ONLY FOR CP/M 3.0 COMPATABILITY. ALL OTHER ; ROUTINES SHOULD USE GETMEM, PUTMEM & XROM ROUTINES. ; ENTRY- A= BANK ADDRESS ; ;**************************************************************************** BNKSEL: ; ; SELECT NEW BANK ; OUT (BNKREG),A ; ; STORE IN BANK PAGE 0 ; LD (THIS_BNK),A ; ; DONE ; RET ;**************************************************************************** ; ; SET BANKS FOR A FOLLOWING MOVE CALL (CP/M 3.0 COMPATABLE) ; ENTRY- B= SOURCE BANK ; C= DESTINATION BANK ; EXIT - A= ? ; ;**************************************************************************** XMOVE: ; ; STORE BANK #S ; LD (DBANK),BC ; ; SET BANKS CHANGED FLAG ; LD A,-1 LD (BNKCHG),A ; ; DONE ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; MEMORY TO MEMORY MOVE FUNCTION ; NOTE: THIS FUNCTION IS NOT CP/M 3.0 COMPATABLE. HL & DE ARE REVERSED ; (Z-80 COMPATABLE) ; ENTRY- HL= SOURCE PTR ; DE= DESTINATION PTR ; BC= BYTE COUNT ; EXIT - HL & DE= NEXT BYTES TO MOVE PTRS ; A, BC= ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ BMOVE: ; ; IF BANK NOT SELECTED PRIOR TO CALL THEN USE FASTER INTRA-BANK MOVE ; LD A,(BNKCHG) OR A,A JP NZ,BMOVE2 ; LDIR ; ; DONE WITH SIMPLE CASE ; RET ; ; ; ELSE USE INTER-BANK MOVE ; BMOVE2: ; ; SAVE CURRENT BANK # ; LD A,(THIS_BNK) LD (CBANK),A ; ; CLEAR INTER-BANK MOVE FLAG FOR NEXT TIME ; XOR A,A LD (BNKCHG),A ; ; IF IN SAME BANK THEN USE INTRA_BANK MOVE ON IT ; PUSH HL ;SAVE PTR LD HL,(DBANK) LD A,H CP A,L POP HL ;PTR JP NZ,NTSAME ; ; SELECT BANK OF MOVE ; DI ;NO INTERRUPTS WHILE BANK SWAPPED ; OUT (BNKREG),A ;A STILL HAS BANK (BOTH SAME, REMEMBER?) ; LDIR ; ; DONE, RESTORE BANK TO CURRENT BANK WHEN CALLED ; BMOVE3: LD A,(CBANK) ;RESELECT CURRENT BANK & RETURN OUT (BNKREG),A ; EI ;ALLOW INTERRUPTS NOW RET ; ; ; BANKS NOT THE SAME, DO DISCRETE MOVE ; NTSAME: ; ; SAVE COUNT ; PUSH BC ;SAVE COUNT EXX POP BC EXX ; ; FETCH BANKS ; LD BC,(DBANK) ; ; NO INTERRUPTS WHILE MOVING ; DI ; ; TOP OF MOVE LOOP ; BMOVE4: LD A,B ;SELECT SOURCE BANK OUT (BNKREG),A LD A,(HL) EX AF,AF' ; LD A,C ;SELECT DESTINATION BANK OUT (BNKREG),A EX AF,AF' LD (DE),A ; INC HL ;NEXT BYTE INC DE ; EXX ;CHECK FOR DONE DEC BC LD A,C OR A,B EXX JP NZ,BMOVE4 ; ; DONE ; JP BMOVE3 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; RETURN BANKED MEMORY DATA FUNCTION ; ENTRY- HL= OFFSET PTR ; E= BANK # ; EXIT - A= DATA ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ GETMEM: ; ; SAVE REGISTER ; PUSH BC ; ; SAVE CURRENT BANK FOR RETURN ; LD A,(THIS_BNK) LD B,A ; ; SELECT BANK ; LD A,E DI ;NO INTERRUPTS OUT (BNKREG),A ; ; FETCH DATA ; LD C,(HL) ; ; RESTORE BANK ; LD A,B OUT (BNKREG),A ; ; RETURN DATA ; LD A,C ; ; DONE ; POP BC EI RET ;**************************************************************************** ; ; STORE DATA INTO BANKED MEMORY PROCEDURE ; ENTRY- HL= OFFSET PTR ; E= BANK # ; C= DATA ; EXIT - A= ? ; ;**************************************************************************** PUTMEM: ; ; SAVE REG ; PUSH BC ; ; SAVE CURRENT BANK TO RETURN TO ; LD A,(THIS_BNK) LD B,A ; ; SELECT BANK ; LD A,E DI ;NO INTERRUPTS WHILE BANK SWAPPED OUT (BNKREG),A ; ; STORE DATA ; LD (HL),C ; ; RESTORE BANK ; LD A,B OUT (BNKREG),A ; EI ; ; DONE ; POP BC RET SUBTTL MONITOR FUNCTION CALL DISPATCHER ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; ENTRY- A= FUNCTION # ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ MONFUNC: 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 GETMEM ;1: RETURN BANKED MEMORY DATA DW PUTMEM ;2: STORE DATA INTO BANKED MEMORY DW MFUNERR ;3: SPARE DW XMOVE ;4: SET BLOCK MOVE BANKS DW BMOVE ;5: BANKED BLOCK MOVE DW MFUNERR ;6: EXECUTE BANK ; DW MFUNERR ;7: EXECUTE CHAR DEVICE DRIVER FUNCTIONS DW D_FUNS ;8: EXECUTE DISK DEVICE DRIVER FUNCTIONS DW V_FUNS ;9: EXECUTE MISC DEVICE DRIVER FUNCTIONS ; DW D_EXIOPB ;10: EXECUTE IOPB ; MAXFUNS EQU ($ - FUNTABL) / 2 SUBTTL MONITOR FUNCTIONS ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; RETURN VERSION FUNCTION ; EXIT - HL= VERSION # (123D = 1.23) ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ RETVERS: LD HL,VERSN RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; MISCELLANEOUS DRIVER FUNCTIONS ; ENTRY- D= DRIVER FUNCTION # ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ V_FUNS: ; ; SET ROM # ; LD A,CLK_ROM ; ; GO EXECUTE THE ROM ENTRY ; JP SWPROM ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DISK DRIVER FUNCTIONS ; ENTRY- D= DRIVER FUNCTION # ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ D_FUNS: ; ; SET ROM # ; LD A,XDBROM AND 7 ; ; GO EXECUTE THE ROM ENTRY ; JP SWPROM ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; MISCELLANEOUS DRIVER FUNCTIONS ; ENTRY- IX= IOPB PTR ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ D_EXIOPB: ; ; SET ROM # ; LD A,DK_ROM ; ; GO EXECUTE THE ROM ENTRY ; LD D,4 ;SET IOPB EXECUTE FUNCTION 1ST JP SWPROM SUBTTL INITIALIZATION CODE ;---------------------------------------------------------------------------- ; ; THIS IS THE COLD START INIT CODE ; ;---------------------------------------------------------------------------- INIT: ; ; INSURE INTERRUPTS DISABLED ; DI ; ; REMOVE PAGE 0 IMAGE ; OUT (M2_CLDRES),A ; ; REMOVE JADE DOUBLE D WINDOW(S) ; LD A,DD_FREE ;REMOVE DD WINDOW, IF PRESENT OUT (DD_PRT3),A OUT (DD_PRT5),A OUT (DD_PRT8),A ; ; SET MEMORY BANK ; LD A,DEFBNK OUT (BNKREG),A ; ; SET MONITOR COMMAND ARGUMENT DEFAULTS ; LD HL,A1_BNK LD (ARGPTR),HL LD (HL),A ;A STILL HAS DEFAULT BANK # INC HL LD (HL),A INC HL LD (HL),A ; ; INITIALIZE RESTART VECTORS IN PAGE 0 ; LD SP,003FH ;USE STACK TO INIT RESTARTS LD HL,0C300H LD DE,RSTER LD B,16 ;64 BYTES ; INIT1: PUSH DE PUSH HL DJNZ INIT1 ; ; SET STACK ; LD SP,MONSTK ; ; SET MEMORY BANK CONSTANT ; LD (THIS_BNK),A ;A STILL HAS DEFAULT BANK # ; ; INIT ALL BANKS ; LD E,A ;START WITH ALL Z80 BANKS LD HL,THIS_BNK ;POINT TO LOCATION TO STORE BANK # BNKS_INIT: LD C,E ;STORE IT CALL PUTMEM ; INC E ;NEXT BANK ; LD A,0FFH ;IF NOT LAST BANK THEN REPEAT CP A,E JR NZ,BNKS_INIT ; ; INITIALIZE IOBYTE ; LD A,IOBYTV ;SET TO INITIAL IOBYTE VALUE LD (IOBYTE),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 ; ; SET BANK STACK ; LD (THIS_STK),SP ; ; 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 ; ; INSERT I/O INIT CODE HERE ; ; ; OUTPUT SIGN-ON MESSAGE ; LD HL,LOGMSG ;OUTPUT SIGN-ON CALL PRTWD ; ; FALL INTO WARM START LOOP ; ;---------------------------------------------------------------------------- ; ; THE WARM START CODE ; ;---------------------------------------------------------------------------- WINIT: ; ; FIRST RESTORE THE LOCAL STACK TO THE GLOBAL RAM ; LD SP,MONSTK ; ; RESTORE BANK TO DEFAULT BANK ; LD A,DEFBNK CALL BNKSEL ; ; PUT THE RETURN ON THE STACK FOR COMMANDS WHICH ARE SUBROUTINES ; LD HL,WINIT PUSH HL ; ; RESTORE THE WARM START RESTART VECTOR IN PAGE 0 ; LD (WSVEC + 1),HL LD A,0C3H LD (WSVEC),A ; ; INIT FUNCTION CALL VECTOR ; LD HL,MONFUNC LD (MFUNRSV + 1),HL LD (MFUNRSV),A ; ; INIT BREAKPOINT VECTOR ; LD HL,REST LD (BP_RSTV),A LD (BP_RSTV +1),HL ; ; 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 CLI ; ;---------------------------------------------------------------------------- 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,XDBROM ;PASS IN DEFAULT BOOT ROM ADDR ; BOOTCC: LD D,1 ;SET BOOT FUNCTION # LD A,C ;BITS 2..0 = ROM # AND A,7 ;MASK OF EXTRANEOUS BITS & CLEAR ERROR FLAG CALL SWPROM ; 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) CALL PUTMEM ;STORE THE FILL VALUE POP DE ; ; IF NOT LAST LOCATION THEN REPEAT ; CALL HILO JR NC,FIO ; ; ELSE DONE ; JR 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 CONOUT ; ; 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 A,(BNKLOC) CALL BNKSEL ; LD HL,(PLOC) PUSH HL ; ; DO INTERRUPT & REFRESH REGISTERS AS CLOSE TO EXIT AS POSSIBLE ; LD HL,(RLOC) LD A,H LD I,A LD A,L ; ; DO AF ; LD HL,(FLOC) PUSH HL LD R,A ;MINIMIZE REFRESH REGISTER CHANGE POP AF ; ; FINALLY RESTORE HL & EXECUTE THE REQUESTED CODE ; LD HL,(LLOC) ; ; RESERVE SPACE FOR A EI INSTRUCTION TO BE PATCHED IN ; DB 0 ;'NOP' OR PLACE FOR 'EI' ; RET ;---------------------------------------------------------------------------- ; ; 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 CALL PUTMEM ; 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 CONOUT CALL DASH ; ; DISPLAY REGISTER VALUE ; POP HL CALL PRTVAL CALL BLK INC HL ;NEXT ENTRY JR XG 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 CONOUT 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 CONOUT 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 CONST ;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 ;**************************************************************************** ; ; 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: ; ; SAVE 8080 REGS FIRST SO WE CAN WORK ; PUSH AF LD A,R ;DO REFRESH REGISTER AS SOON AS POSSIBLE LD (LLOC),HL POP HL LD (FLOC),HL ; LD L,A ;REFRESH REGISTER LD A,I LD H,A LD (RLOC),HL ; LD (ELOC),DE LD (CLOC),BC ; ; FETCH RETURN ADDRESS FROM PGM STACK ; POP BC ; ; SAVE SP AT BREAKPOINT ; LD (SLOC),SP ; ; BACK UP RETURN ADDRESS TO POINT TO RESTART INSTRUCTION ; DEC BC ; ; SET UP LOCAL STACK ; LD SP,MONSTK ;SET THE MONITOR STACK ; ; 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 CONOUT ; ; 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 ; RS6: 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 ;---------------------------------------------------------------------------- ; ; 3 TYPES OF ERRORS ARE DETECTED: A RESTART ERROR; AN I/O ASSIGNMENT ; ERROR; & CERTAIN PROGRAM ERRORS (DETERMINED BY PARTICULAR ROUTINE WHERE THE ; ERROR CONDITION WAS ENCOUNTERED) EACH CAUSES A UNIQUE MESSAGE TO BE ; PRINTED, THEN DOES A WARM INIT OF THE MONITOR. THE I/O ERROR CAUSES THE ; I/O ASSIGNMENTS TO BE RESET TO THE DEFAULT ASSIGNMENT. ; ;---------------------------------------------------------------------------- IOER: LD A,IOBYTV ;SET IOBYTE TO DEFAULT LD (IOBYTE),A LD HL,IOMSG JR COMERR ;---------------------------------------------------------------------------- ; ; UNINITIALIZED RESTART ERROR HANDLER ; ;---------------------------------------------------------------------------- RSTER: PUSH AF PUSH HL LD HL,RSTMSG CALL PRTWD POP HL POP AF JP REST ;---------------------------------------------------------------------------- ; ; COMMON ERROR HANDLER ; ENTRY- HL= MESSAGE PTR ; ;---------------------------------------------------------------------------- COMERR: CALL PRTWD JP WSVEC ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; 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 ; ; THIS RETURN DOES DOUBLE DUTY AS A STUB ; RTS: 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: ; ; SAVE REGISTER ; PUSH BC ; ; TOP OF PRINTING LOOP ; PRTA: LD C,(HL) ;FETCH CHAR ; RES 7,C ;MAKE SURE BIT 7 = 0 CALL CO ; LD A,(HL) ;IF BIT 7 = 1 THEN STOP INC HL RLCA JR NC,PRTA ; ; RESTORE & RETURN ; POP BC RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; 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 PRTWA ; ; 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: CALL CRLF ; ; ENTRY TO CONTINUE AT CURRENT CURSOR LOCATION ; LADR: ; ; DISPLAY BANK # ; LD A,E CALL HEX1 ; CALL COLON ; ; DO HIGH BYTE 1ST ; LD A,H CALL HEX1 ; ; NOW DO LOW BYTE ; LD A,L ; ; FALL INTO BYTE OUTPUT PROCEDURE ; ;**************************************************************************** ; ; DISPLAY HEX BYTE ON SYSTEM CONSOLE PROCEDURE ; ENTRY- A= BYTE TO DISPLAY ; ;**************************************************************************** HEX1: ; ; SAVE LOW NIBBLE ; PUSH AF ; ; DO HIGH NIBBLE 1ST ; RRCA RRCA RRCA RRCA CALL HEX2 ; ; NOW DO LOW NIBBLE ; POP AF HEX2: CALL CONV JR CO ;**************************************************************************** ; ; CONV ROUTINE CONVERTS THE LOW ORDER NIBBLE OF THE ; ACCUMULATOR TO ITS ASCII EQUIVALENT. ; ENTRY- A= NUMBER (LO NIBBLE) ; EXIT - A= C= ASCII NUMBER ; ;**************************************************************************** CONV: AND A,0FH ADD A,90H ;PUT INTO ASCII ZONE DAA ;AH, THE UBIQUITOUS DAA CONVERT ADC A,40H DAA LD C,A RET ;**************************************************************************** ; ; DISPLAY A COLON ON SYSTEM CONSOLE PROCEDURE ; ;**************************************************************************** COLON: LD C,':' JP CO ;**************************************************************************** ; ; 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 ; SUBTTL IOBYTE HANDLERS ;**************************************************************************** ; ; CONSOLE OUTPUT SELECTOR ; ENTRY- (IOBYTE BIT 0..1): 0: CON0, 1: CON1, 2: CON2, 3: CON3 ; C= CHAR ; ;**************************************************************************** CO: LD A,(IOBYTE) AND A,3 JP Z,CO0 ;CONSOLE 0 CP A,2 JP M,CO1 ;CONSOLE 1 JP Z,CO2 ;CONSOLE 2 JP CO3 ;CONSOLE 3 ;**************************************************************************** ; ; CONSOLE STATUS INPUT SELECTOR ; ENTRY- (IOBYTE BIT 0..1)= 0: CON0, 1: CON1, 2: CON2, 3: CON3 ; EXIT - A= 0: NOT READY, FFH: CHAR READY ; ;**************************************************************************** CSTS: LD A,(IOBYTE) AND A,3 JP Z,CSTS0 ;CONSOLE 0 CP A,2 JP M,CSTS1 ;CONSOLE 1 JP Z,CSTS2 ;CONSOLE 2 JP CSTS3 ;CONSOLE 3 ;**************************************************************************** ; ; CONSOLE INPUT SELECTOR ; ENTRY- (IOBYTE BIT 0..1)= 0: CON0, 1: CON1, 2: CON2, 3: CON3 ; EXIT - A= CHAR (CTRL-Z: EOF) ; ;**************************************************************************** CI: LD A,(IOBYTE) AND A,3 JP Z,CI0 ;CONSOLE 0 CP A,2 JP M,CI1 ;CONSOLE 1 JP Z,CI2 ;CONSOLE 2 JP CI3 ;CONSOLE 3 ;**************************************************************************** ; ; LIST DEVICE OUTPUT SELECTOR ; ENTRY- (IOBYTE BIT 6..7)= 0: LST0, 40H: LST1, 80H: LST2, C0H: CON ; C= CHAR ; ;**************************************************************************** LO: LD A,(IOBYTE) AND A,0C0H JP Z,LO0 ;PRINTER 0 CP A,80H JP M,LO1 ;PRINTER 1 JP Z,LO2 ;PRINTER 2 JP CO ;CONSOLE ;**************************************************************************** ; ; LIST DEVICE STATUS INPUT SELECTOR ; ENTRY- (IOBYTE BIT 6..7)= 0: LST0, 40H: LST1, 80H: LST2, C0H: CON ; EXIT - A= 0: BUSY, FFH: READY ; ;**************************************************************************** LSTAT: LD A,(IOBYTE) AND A,0C0H JP Z,LSTAT0 ;PRINTER 0 CP A,80H JP M,LSTAT1 ;PRINTER 1 JP Z,LSTAT2 ;PRINTER 2 LD A,-1 ;CONSOLE (ASSUME READY) RET ;**************************************************************************** ; ; SERIAL CHANNEL INPUT SELECTOR ; ENTRY- (IOBYTE BIT 2..3)= 0: SC0, 4: SC1, 8: SC2, 0CH: SC3 ; EXIT - A= CHAR AND 7FH (CTRL-Z: EOF) ; ;**************************************************************************** RI: LD A,(IOBYTE) AND A,0CH JP Z,SI0 ;SERIAL CHANNEL 0 CP A,8 JP M,SI1 ;SERIAL CHANNEL 1 JP Z,SI2 ;SERIAL CHANNEL 2 JP SI3 ;SERIAL CHANNEL 3 ;**************************************************************************** ; ; SERIAL CHANNEL OUTPUT SELECTOR ; ENTRY- (IOBYTE BIT 4..5)= 0: SC0, 10H: SC1, 20H: SC2, 30H: SC3 ; C= CHAR ; ;**************************************************************************** PUNO: LD A,(IOBYTE) AND A,30H JP Z,SO0 ;SERIAL CHANNEL 0 CP A,20H JP M,SO1 ;SERIAL CHANNEL 1 JP Z,SO2 ;SERIAL CHANNEL 2 JP SO3 ;SERIAL CHANNEL 3 SUBTTL PRIMITIVE I/O DRIVERS ;**************************************************************************** ; ; PRIMARY CONSOLE DEVICE (CON0) ; ;**************************************************************************** CI0: CALL CSTS0 ;IF CHAR NOT READY THEN WAIT JR Z,CI0 ; IN A,(NT_DATA) ;ELSE RETURN CHAR RET CO0: IN A,(NT_STAT) ;IF NOT READY TO ACCEPT CHAR THEN WAIT AND A,1 SHL NT_BUSY JR NZ,CO0 ; LD A,C ;OUTPUT CHAR & RETURN OUT (NT_DATA),A RET CSTS0: IN A,(NT_STAT) ;IF NOT CHAR NOT READY THEN RETURN 0 AND A,1 SHL NT_READY RET Z ; LD A,-1 ;ELSE RETURN -1 RET ;**************************************************************************** ; ; ALTERNATE CONSOLE DEVICE (CON1) ; ;**************************************************************************** CI1: EQU CI0 CO1: EQU CO0 CSTS1: EQU CSTS0 ;**************************************************************************** ; ; ALTERNATE CONSOLE DEVICE (CON2) ; ;**************************************************************************** CO2: EQU CO0 ;IOER CSTS2: EQU CSTS0 ;IOER CI2: EQU CI0 ;IOER ;**************************************************************************** ; ; ALTERNATE CONSOLE DEVICE (CON3) ; ;**************************************************************************** CO3: EQU CO0 ;IOER CSTS3: EQU CSTS0 ;IOER CI3: EQU CI0 ;IOER ;**************************************************************************** ; ; LIST DEVICE 1 (LST1) ; ;**************************************************************************** LO0: CALL LSTAT0 ;WAIT FOR BUSY=FALSE JR Z,LO0 ; LD A,C ;OUTPUT CHARACTER OUT (PRI_1DO),A LD A,NOT [1 SHL PRI_1CSB] ;OUTPUT STROBE OUT (PRI_2CNT),A LD A,0BFH OUT (PRI_2CNT),A ;CLEAR STROBE RET LSTAT0: LD A,0BFH ;THIS PRINTER NEEDS STB=F FOR BUSY OUT (PRI_2CNT),A ; TO WORK PROPERLY ; IN A,(PRI_1ST) ;FETCH STATUS CPL AND A,[1 SHL PRI_1BSB] ;TEST BUSY RET Z ; LD A,-1 RET ;**************************************************************************** ; ; LIST DEVICE 1 (LST1) ; ;**************************************************************************** LO1: EQU IOER LSTAT1: EQU IOER ;**************************************************************************** ; ; LIST DEVICE 2 (LST2) ; ;**************************************************************************** LO2: EQU IOER LSTAT2: EQU IOER ;**************************************************************************** ; ; SERIAL CHANNEL 0 (SC0) ; ;**************************************************************************** SI0: EQU IOER SO0: EQU IOER ;**************************************************************************** ; ; SERIAL CHANNEL 1 (SC1) ; ;**************************************************************************** SI1: EQU IOER SO1 EQU IOER ;**************************************************************************** ; ; SERIAL CHANNEL 2 (SC1) ; ;**************************************************************************** SI2 EQU IOER SO2 EQU IOER ;**************************************************************************** ; ; SERIAL CHANNEL 3 (SC1) ; ;**************************************************************************** SI3: EQU IOER SO3: EQU IOER SUBTTL MESSAGES CRMSG: DM CR,LF RSTMSG: DM 'RST ERR ' BOOTEM: DM 'BOOT LOAD ERR',CR,LF IOMSG: DM 'I/O ERR ' QMSG: DM LF,'^??' LOGMSG: DB '65K BANKED ZMON V. ' PVERS VERSN DM CR,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 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 QPRT ;K DW QPRT ;L DW MOVE ;M MOVE MEMORY DW QPRT ;N DW OUPT ;O OUTPUT DATA TO OUTPUT PORT DW QPRT ;P DW QPRT ;Q DW QPRT ;R DW SUBS ;S SUBSTITUTE MEMORY DW MTEST ;T TEST MEMORY DW QPRT ;U DW COMP ;V VERIFY (COMPARE) MEMORY DW QPRT ;W 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 END