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. ; VERSN EQU '11' ;**************************************************************************** FORM FALSE EQU 0 TRUE EQU NOT FALSE LSTINC EQU FALSE ; ; INCLUDE SYSTEM DEFINITION FILES ; ;*INCLUDE NAKEDT.DEF ;*INCLUDE MONBOARD.DEF ;*INCLUDE BIGZ.DEF ;*INCLUDE JDDCONT.DEF ;*INCLUDE IOBOARD.DEF ;*INCLUDE PRI.DEF ; LIST OFF *INCLUDE NAKEDT.DEF *INCLUDE MONBOARD.DEF *INCLUDE BIGZ.DEF *INCLUDE JDDCONT.DEF *INCLUDE IOBOARD.DEF *INCLUDE PRI.DEF LIST ON ;============================ ; ; ASSEMBLE TIME VARIABLES ; ;============================ ROM EQU 0F800H ;ROM START ADDR WSVEC EQU 0 ;VECTOR NUMBER FOR WARM RESTART NBKPTS EQU 2 ;NUMBER OF BREAKPOINTS DEFBNK EQU 0 ;DEFAULT Z-80 EXECUTION BANK ;============================ ; ; CONSTANTS ; ;============================ CTRLS EQU 13H ;ASCII DC3 CR EQU 0DH LF EQU 0AH BELL EQU 7 ; BNKREG EQU 0F4H ;MEMORY BANK SELECT REGISTER PORT ADDRESS (BIG Z) ;============================ ; ; VARIABLES ; ;============================ IOBYTE EQU 3 ;ADDR OF I/O CONTROL BYTE IOBYTV EQU 00H ;DEFAULT IOBYTE VALUE ; ; ; REGISTER STORAGE DISPLACEMENTS FROM NORMAL SYSTEM ; STACK LOCATION. ; ALOC EQU 15H BLOC EQU 13H CLOC EQU 12H DLOC EQU 11H ELOC EQU 10H FLOC EQU 14H HLOC EQU 31H LLOC EQU 30H PLOC EQU 34H SLOC EQU 17H TLOC EQU 35H TLOCX EQU 25H LLOCX EQU 20H ; APLOC EQU 9 BPLOC EQU 11 CPLOC EQU 10 DPLOC EQU 13 EPLOC EQU 12 FPLOC EQU 8 HPLOC EQU 15 LPLOC EQU 14 XLOC EQU 7 YLOC EQU 5 RLOC EQU 2 ILOC EQU 3 ;############################################################################ ; ; FIXED DATA AREA ; ;############################################################################ RESERVED EQU 6 ;CHANGE THIS TO RESERV SPACE ORG 0F800H - RESERVED 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) SPSV DS 2 ;STACK PTR SAVE LOCATION (WAS 6) SUBTTL MAIN PROGRAM ORG ROM ;-------------------------------------- ; ; JUMP TARGETS FOR BASIC I/O ; ;-------------------------------------- ; ; COLD START VECTOR ; CBOOT JP INIT ;COLD START ; ; CHARACTER I/O (6) ; CONIN JP CI ;CONSOLE INPUT READER JP RI ;READER CONOUT JP CO ;CONSOLE OUTPUT PUNCH JP PUNO ;PUNCH LIST JP LO ;LIST OUTPUT 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) ; ; BREAKPOINT VECTOR ; JP REST ;BREAKPOINT ENTRY ; ; MORE CHARACTER I/O ; LPSTAT: JP LSTAT ;LINE PRINTER STATUS RETURN DS 6 ;SAVE 2 SPARES ;------------------------------------------------ ; ; THE FOLLOWING CODE MUST RESIDE AT THE SAME ; ADDR AS THE BOOT ROM START CODE. ; ;------------------------------------------------ DBOOT: LD A,C ;PERFORM SWAP AND 7 ;CLEAR ERROR MSG IN CASE ROM NOT THERE & MASK OUT ROMSEL,A RET SUBTTL MEMORY MANAGEMENT ROUTINES ;**************************************************************************** ; ; BANK SELECT PROCEDURE ; ENTRY- A= BANK ADDRESS ; ;**************************************************************************** BNKSEL: OUT (BNKREG),A LD (CBANK),A RET ;**************************************************************************** ; ; SET BANKS FOR A FOLLOWING MOVE CALL ; ENTRY- B= SOURCE BANK ; C= DESTINATION BANK ; ;**************************************************************************** XMOVE: LD (DBANK),BC XOR A,A ;FLAG CHANGE DEC A LD (BNKCHG),A RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; MEMORY TO MEMORY MOVE FUNCTION ; ENTRY- HL= SOURCE PTR ; DE= DESTINATION PTR ; BC= BYTE COUNT ; EXIT - HL & DE= NEXT BYTES TO MOVE PTRS ; A, BC= ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ BMOVE: ; ; IF BANK SELECTED PRIOR TO CALL THEN EXECUTE LDIR ; LD A,(BNKCHG) ;IF BANK SELECTED THEN SKIP BANK SELECT OR A,A JP NZ,BMOVE2 ; EX DE,HL LDIR EX DE,HL ; RET ; ; ; CLEAR BANK CHANGE FLAG ; BMOVE2: XOR A,A LD (BNKCHG),A ; ; IF IN SAME BANK THEN USE BLOCK MOVE INSTRUCTION ; PUSH HL ;SAVE PTR LD HL,(DBANK) LD A,H CP A,L POP HL ;PTR JP NZ,NTSAME ; OUT (BNKREG),A ;A STILL HAS BANK ; EX DE,HL ;MOVE DATA LDIR EX DE,HL ; ; DONE, RESTORE BANK TO CURRENT BANK WHEN CALLED ; BMOVE3: LD A,(CBANK) ;RESELECT CURRENT BANK & RETURN OUT (BNKREG),A RET ; ; ; BANKS NOT THE SAME, DO DISCREET MOVE ; NTSAME: PUSH BC ;SAVE COUNT EXX POP BC EXX ; LD BC,(DBANK) ;FETCH BANKS ; BMOVE4: LD A,B ;SELECT SOURCE BANK OUT (BNKREG),A LD A,(DE) EX AF,AF' ; LD A,C ;SELECT DESTINATION BANK OUT (BNKREG),A EX AF,AF' LD (HL),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: ; ; SELECT BANK ; LD A,E OUT (BNKREG),A ; ; FETCH DATA ; LD A,(HL) ; ; RESTORE BANK ; PUSH AF LD A,(CBANK) OUT (BNKREG),A POP AF ; ; DONE ; RET ;**************************************************************************** ; ; STORE DATA INTO BANKED MEMORY PROCEDURE ; ENTRY- HL= OFFSET PTR ; E= BANK # ; C= DATA ; EXIT - A= ? ; ;**************************************************************************** PUTMEM: ; ; SELECT BANK ; LD A,E OUT (BNKREG),A ; ; STORE DATA ; LD (HL),C ; ; RESTORE BANK ; LD A,(CBANK) OUT (BNKREG),A ; ; DONE ; RET SUBTTL INITIALIZATION CODE ;-------------------------------------- ; ; THE COLD INITIALIZATION CODE ; ;-------------------------------------- INIT: ; ; INSURE INTERRUPTS DISABLED ; DI ; ; REMOVE PAGE 0 IMAGE ; OUT COLDRES,A ; ; FIX MEMORY BANK ; LD A,DEFBNK OUT (BNKREG),A LD (CBANK),A ; ; REMOVE JADE DOUBLE D WINDOW(S) ; LD A,DDFREE ;REMOVE DD WINDOW, IF PRESENT OUT (41H),A OUT (42H),A OUT (43H),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 TEMPORARY STACK ; LD SP,80H ; ; INITIALIZE IOBYTE ; LD C,IOBYTV ;SET TO INITIAL IOBYTE VALUE CALL IOSET ; ; SIZE AND DISPLAY MEMORY ; LD HL,USRMSG ;OUTPUT MEMORY= CALL PRTWD CALL MEMSIZ ;OUTPUT MEMORY SIZE PUSH HL ;SAVE VALUE FOR LATER ; ; COMPUTE # KS ; LD A,H ; /1024 SRL A SRL A LD C,0 ;TENS COUNT = 0 MEMLP: SUB 10 ;NUMBER = NUMBER - 10 JR C,MEM1 ; INC C ;IF < 10 THEN C = TENS DIGIT JR MEMLP ; MEM1: ADD '0' + 10 ;CONVERT TO + ASCII # LD B,A LD A,C ;IF TENS = 0 THEN OUTPUT SPACE ADD '0' CP '0' JR NZ,NOT0 LD A,' ' NOT0: LD C,A CALL CO LD C,B CALL CO LD C,'K' CALL CO CALL CRLF ; ; CONTINUATION OF THE SCS MONITOR, MOVE EXIT ROUTINE TO RAM ; POP HL ;MEMTOP LD SP,HL LD DE,EXIT EX DE,HL LD BC,ENDX - EXIT LDIR ; ; FILL BREAKPOINT ADDRESSES WITH 0 (LAST BYTE OF EXIT ROUTINE ; LD BC,NBKPTS * 3 PUSH DE POP HL DEC HL LDIR ; ; RESERVE REGISTER IMAGE SPACE FROM STACK TO EXIT ROUTINE JUST STORED ; LD HL,-24 ;BACK UP STACK BY SUBTRACTING ADD HL,SP PUSH HL ;SAVE SP ; INC HL ;ADJUST USER STACK LOCATION INC HL LD (SPSV),HL ;SAVE INITIAL STACK VALUE ; ; INITIALIZE REGISTER IMAGES TO 0 ; LD D,10 INIT2: PUSH BC ;BC HAS 0 FROM LAST LDIR FINISH DEC D JR NZ,INIT2 ; ; INSERT I/O INIT CODE HERE ; ; ; OUTPUT SIGN-ON MESSAGE ; LD HL,LOGMSG ;OUTPUT SIGN-ON CALL PRTWD JR WINIT ; ; 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: CALL DBOOT LD HL,BOOTEM CALL C,PRTWD ; JR WINIT ;GO TO MONITOR EXEC ;**************************************************************************** ; ; MEMSIZ SUBR CALCULATES THE TOP OF CONTIGUOUS RAM. IT SEARCHES FROM ; THE BOTTOM UP UNTIL A NON-RAM LOCATION IS FOUND. IT THEN TAKES OFF FOR ; MONITOR WORK SPACE NEEDS. ; EXIT - HL= MEMTOP PTR ; ;**************************************************************************** MEMSIZ: ; ; SAVE REG ; PUSH BC ;MONITOR START LOCATION ; ; INITIALIZE ; LD BC,ROM ;SAVE ROM PAGE TO COMPARE TO ; LD HL,-1 ;START AT LOCATION 0 ; ; NON-DESTRUCTIVE TEST UNTIL NO RAM OR MONITOR ROM BASE INCURRED ; MEMSZ1: INC HL LD A,(HL) CPL LD (HL),A ; CP (HL) CPL LD (HL),A ; JR NZ,MEMSZ2 ;NO RAM ; LD A,H ;SEE IF ON MONITOR BORDER CP A,B JR NZ,MEMSZ1 ; ; DONE WITH TEST, CALCULATE TOP OF FREE RAM ; MEMSZ2: ; ; POINT TO LAST RAM SPACE ; DEC HL ; ; ADJUST FOR MONITOR RESERVED AREA ; LD BC,[EXIT - ENDX] - [3 * NBKPTS] - RESERVED + 1 ADD HL,BC ;ABOVE CALCULATES TO NEGATIVE #, SO IS SUB ; ; RESTORE & RETURN ; POP BC ;UNPREDICTABLE DURING INIT RET ;**************************************************************************** ; ; MEMCHK SUBR FINDS THE CURRENT TOP OF CONTIGUOUS MEMORY (LESS THE ; MONITOR WORKSPACE) & RETURNS THE VALUE. ; EXIT - B= HIGH BYTE OF RAM ; A= LOW BYTE OF RAM ; ;**************************************************************************** MEMCK: PUSH HL CALL MEMSIZ ;GET THE RAM SIZE LD A,L ;TAKE OFF WORKSPACE SUB 60 JR NC,MEMCK0 DEC H MEMCK0: LD B,H POP HL RET ;************************************** ; ; EXF SUBR. READS 1 PARAMETER. ; ENTRY- A= PARAMETER 1ST CHAR ; EXIT - STACK= PARAMETER ; ;************************************** EXF: LD B,1 ;SET 1 PARAM LD HL,0 JR EX1 ;1ST CHAR IN A ALREADY ;**************************************************************************** ; ; 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 ; ;**************************************************************************** AS3: DJNZ AS2 ;PART OF THE ASSIGN CODE EX3: JR NZ,QPRT ;NON 0 IS ERR EXPR1: DEC B ;IF NO PARAMS THEN RETURN RET Z EXPR: LD HL,0 ;PARAM = 0 EX0: CALL ECHO ;GET NEXT # EX1: LD C,A ;SAVE CHAR FOR LATER CALL NIBBLE JR C,EX2 ;IF NOT NUMBER THEN EXIT ADD HL,HL ;PARAM = PARAM * 16 ADD HL,HL ADD HL,HL ADD HL,HL OR L ;ADD IN NEW DIGIT LD L,A JR EX0 ;GET NEXT ; EX2: EX (SP),HL ;PUT UNDER RETURN ADDR ON STACK PUSH HL LD A,C ;IF LAST CHAR = DELIM THEN EXIT CALL P2C JR NC,EX3 DJNZ QPRT ;ELSE IF MORE REQ'D THEN ERR RET ;ELSE RETURN ;---------------------------------------------------------------------------- ; ; LOGICAL ASSIGNMENT OF PERIPHERALS COMMAND ; ; THIS COMMAND CONTROLS THE ASSIGNMENT OF PHYSICAL PERIPHERALS TO THE ; 4 LOGICAL DEVICE TYPES. IT ALTERS (IOBYTE) TO MATCH THE CURRENT ASSIGNMENT. ; THE 4 LOGICAL DEVICES ARE CONSOLE, READER, LIST & PUNCH. IN ALL CASES, THE ; TTY DEVICE (SYSTEM CONSOLE) IS SET UP AS THE DEFAULT DEVICE. ; ; Ax ;x= C,R,P,L (CONSOLE,READER,PUNCH,LIST) ; Ax-y ;y= C: T,C,B,1 (TTY,CRT,BAT,UC1) ; R: T,P,1,2 (TTY,PTR,UR1,UR2) ; P: T,P,1,2 (TTY,PTP,UP1,UP2) ; L: T,L,1,2 (TTY,CRT,LPT,UL1) ; ;---------------------------------------------------------------------------- ASGN: CALL ECHO ;GET THE LOGICAL DEVICE DESIRED LD HL,ALT ;START OF CONVERSION TABLE LD DE,APT - ALT ; # OF ELEMENTS LD B,4 ; COUNT = # ENTRIES AS0: CP (HL) ;IF CHAR = TABLE[LOGICAL] THEN JR Z,AS1 ; EXIT ADD HL,DE ;ELSE NEXT LOGICAL ENTRY DJNZ AS0 QPRT: LD HL,QMSG ;OUTPUT ? MESSAGE CALL PRTWA ;---------------------------- ; ; THE WARM START CODE ; ;---------------------------- WINIT: LD SP,(SPSV) ;RESTORE THE STACK WINITA: LD HL,WINIT ;RESET RETURN & WARM START VECT PUSH HL LD (WSVEC + 1),HL LD A,0C3H LD (WSVEC),A CALL CRLF CALL DECHO ;GET COMMAND SUB 'A' ;IF CHAR <> 'A' -> 'F' THEN ERR JR C,QPRT CP 'Z' - 'A' + 1 JR NC,QPRT ADD A,A ;OFFSET = INDEX * 2 LD E,A LD D,0 LD B,2 ;PASS IN 2 PARAMS TO HANDLER LD HL,TBL ;ADDRESS = (TABLE + OFFSET) ADD HL,DE LD A,(HL) INC HL LD H,(HL) LD L,A JP (HL) ;---------------------------------------------------------------------------- ; ; 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: CALL EXPR3 ;GET 3 PARAMS FIO: LD (HL),C ;PUT DOWN THE FILL VALUE CALL HILO ;INC & CHECK THE PTR JR NC,FIO POP DE ;RESTORE SP IN CASE STACK JR WINIT ; WAS OVERWRITTEN ;---------------------------- ; ; ASSIGN CONTINUED ; ;---------------------------- AS1: LD D,B ;SAVE THE COUNTER RESIDUE LD B,4 CALL DECHO ;GET NEW ASSIGNMENT AS2: INC HL ;PTR = PTR + 1 CP (HL) ;IF CHAR <> (TABLE) THEN EXIT JR NZ,AS3 LD L,B ;SAVE THE RESIDUE TO FORM ASGNT DEC L LD B,D LD H,3 DEC B JR Z,AS5 ;NO SHIFT NEEDED AS4: ADD HL,HL ;SHIFT MASKS ADD HL,HL DJNZ AS4 AS5: LD A,(IOBYTE) OR H XOR H ;LOGICAL BITS NOW OFF OR L ;PUT IN NEW VALUE LD C,A ;************************************** ; ; SET IOBYTE SUBR ; ENTRY- C= NEW IOBYTE VALUE ; ;************************************** IOSET: LD A,C LD (IOBYTE),A ;SAVE NEW ASSIGNMENTS RET ;******************************************* ; ; RETURN IOBYTE VALUE SUBR ; EXIT - A= CURRENT IOBYTE VALUE ; ;******************************************* IOCHK: LD A,(IOBYTE) RET ;---------------------------------------------------------------------------- ; ; SLEEP COMMAND ; ; THE BYE ROUTINE IS USED TO PREVENT UNAUTHORIZED USAGE OF THE SYSTEM. ; THE SYSTEM LOCKS UP & WILL NOT RESPOND TO ANYTHING OTHER THAN 2 ASCII BELL ; CHARACTERS. WHEN IT SEES THEN CONSECUTIVELY, CONTROL IS RETURNED TO THE ; MONITOR WITHOUT ALTERING ANYTHING. ; ; Z ; ;---------------------------------------------------------------------------- BYE: LD B,2 ;SET UP FOR 2 CHARS BYE1: CALL CONI CP BELL ;IF NOT BELL THEN RESTART JR NZ,BYE CALL ECH1 ;ECHO THE BELL DJNZ BYE1 RET ;---------------------------------------------------------------------------- ; ; 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: CALL EXPR3 CMPA: LD A,(BC) ;GET SOURCE 2 DATA PUSH BC ;SAVE SOURCE 2 PTR LD B,(HL) ;GET SOURCE 1 DATA CP B ;IF S2=S1 THEN EXIT JR Z,CMPB PUSH AF ;SAVE S2 DATA CALL LADRB ;OUTPUT ADDR LD A,B CALL DASH1 ;FORMAT POP AF CALL HEX1 ;OUTPUT S2 CMPB: POP BC CALL HILOXB 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: CALL EXLF ;GET BLOCK LIMITS DIS1: CALL LADRB ;DISPLAY START ADDR LD A,L ;SEE IF ON 16 BYTE BOUNDARY CALL TRPLSP ;SKIP OVER TO RIGHT COLUMN PUSH HL DIS2: LD A,(HL) ;GET CONTENTS CALL HEX1 CALL HILO ;INC & CHECK PTR JR C,DIS7 ;DONE IF CARRY CALL BLK ;MAKE COLUMNS LD A,L ;READY FOR NEW LINE? AND 0FH JR NZ,DIS2 DIS3: POP HL ;RESTORE START OF LINE LD A,L ;SKIP OVER TO RIGHT SPACE AND 0FH CALL TRPL2 DIS4: LD A,(HL) ;OUTPUT MEMORY IN ASCII AND 7FH ;IF PRINTABLE THEN OUTPUT LD C,A CP ' ' JR C,DIS5 CP 7EH JR C,DIS6 DIS5: LD C,'.' ;ELSE OUTPUT '.' DIS6: CALL CONOUT CALL HILOX LD A,L ;READY FOR NEW LINE? AND 0FH JR NZ,DIS4 ;NO JR DIS1 ;YES ; DIS7: SUB A,E ;SKIP OVER TO START ASCII CALL TRPLSP JR DIS3 ; TRPLSP: AND 0FH ;ISOLATE LOW NIBBLE LD B,A ;PREPARE TO SPACE OVER TO RIGHT ADD A,A ; COLUMN ADD B TRPL2: LD B,A INC B TRPL1: CALL BLK ;DO SPACING DJNZ TRPL1 RET ;---------------------------------------------------------------------------- ; ; 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 ;SEE IF OD ADDR WANTED JR C,GO3 ; ; IF NO GOTO ADDRESS THEN SET BREAKPOINTS ; JR Z,GO0 ;YES, BUT SET BP ; ; FETCH NEW GOTO ADDRESS & PUT INTO 'PC' REGISTER ; CALL EXF ;GET NEW GOTO ADDR POP DE LD HL,PLOC ;PUT ADDR IN PC LOCATION ADD HL,SP LD (HL),D DEC HL LD (HL),E ; ; IF LAST CHAR == CR THEN NO MORE ARGS ; LD A,C ;IF LAST = CR THEN EXIT CP CR JR Z,GO3 ; ; GET & SET UP TO NBKPTS BREAKPOINTS ; GO0: LD B,NBKPTS LD HL,TLOC ;POINT TO TRAP STORAGE ADD HL,SP ; GO1: PUSH BC ;SAVE BREAKPOINTS REMAINING ; PUSH HL ;STORAGE PTR LD B,2 CALL EXPR1 POP DE ;GET TRAP ADDR POP HL ;SPTR ; LD A,D ;INSURE 0 WASN'T SPEC'D OR E JR Z,GO2 ; LD (HL),E ;SAVE BP ADDR INC HL LD (HL),D INC HL ; LD A,(DE) ;SAVE BP ADDR INSTRUCTION LD (HL),A INC HL ; LD A,0CFH ;INSERT THE BP LD (DE),A ; ; IF NO MORE ARGS THEN DONE WITH BREAKPOINTS ; GO2: LD A,C ;IF CHAR = CR THEN DONE BPING CP CR POP BC JR Z,GO3 ; ; IF MORE ALLOWED THEN CONTINUE ; DJNZ GO1 ;ELSE IF <2 BPS THEN LOOP ; ; GOT ALL ARGS, EXECTUTE THE GOTO ; GO3: CALL CRLF ;NEW LINE FOR PGM ; POP HL ;GET RID OF STACK JUNK ; ; PASS IN LOCATION OF RESTORE ROUTINE ; LD HL,RS9 PUSH HL ; ; INSERT RESTART BREAKPOINT VECTOR TO RST 8 ; LD HL,REST LD (9),HL ;SET BP VECTOR ADDR ; ; RESTORE ROUTINE IS ON STACK, SO COMPUTE ENTRY ADDRESS ; LD HL,24 ;FIND REG SET ROUTINE ADDR ADD HL,SP ; ; EXECUTE THE RESTORE & GOTO ; POP DE ;ADJUST STACK JP (HL) ;GO DO REG RESTORE ;---------------------------------------------------------------------------- ; ; INPUT FROM PORT COMMAND ; ; THESE ROUTINES ALLOW BYTE-BY-BYTE INPUT OR OUTPUT FROM THE CURRENT ; CONSOLE DEVICE. ; ; I ; ;---------------------------------------------------------------------------- INPT: CALL EXPR1 ;GET INPUT PORT # INTO C CALL CRLF ;PUT DATA ON NEW LINE POP BC IN E,(C) PUSH DE ;FIX BUG. BITS2 POPS DE BEFORE 'RET' JR BITS2 ;OUTPUT VALUE ;-------------------------------------- ; ; OUTPUT DATA TO PORT COMMAND ; ; O ; ;-------------------------------------- OUPT: CALL EXPR ;GET DATA INTO E, PORT # INTO C POP DE POP BC OUT (C),E RET ;---------------------------------------------------------------------------- ; ; 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: CALL EXPR3 MOV1: LD A,(HL) ;MOVE 1 BYTE LD (BC),A CALL HILOXB JR MOV1 ;------------------------------------------------ ; ; 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: CALL PCHK ;IF NO FURTHER INPUT THEN USE DEFAULT JP C,BOOTCD CALL EXF ;GET USER BOOT # POP BC JP BOOTCC ;---------------------------------------------------------------------------- ; ; 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: CALL EXPR1 ;GET ADDR CALL CRLF ;START ON NEW LINE POP HL SUB1: LD A,(HL) ;OUTPUT EXISTING CONTENTS CALL DASH1 CALL PCHK ;GET NEW VALUE RET C ;IF CHAR = CR THEN RETURN JR Z,SUB2 ;IF CHAR = ' ' OR ',' THEN EXIT CP LF ;IF CHAR = LF THEN BACK UP JR Z,SUB3 PUSH HL ;PTR CALL EXF ;CONTINUE HEX INPUT POP DE ;NEW VALUE POP HL ;PTR LD (HL),E ;LOAD VALUE LD A,C ;IF DELIM = CR THEN DONE CP CR RET Z SUB2: INC HL ;PTR = PTR + 2 INC HL SUB3: DEC HL ;PTR = PTR - 1 LD A,L ;IF ON MOD 8 BOUNDARY THEN AND 7 ; OUTPUT ADDR CALL Z,LADRB 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: CALL EXLF MTEST1: LD A,(HL) PUSH AF CPL LD (HL),A XOR (HL) ;RESULT SHOULD BE 0 CALL NZ,BITS ;LOG ERR IF NOT MTEST2: POP AF ;RESTORE BYTE LD (HL),A CALL HILOX JR MTEST1 ; BITS: PUSH DE LD E,A CALL LADRB ;OUTPUT ADDR BITS2: LD B,8 ;BIT COUNT BITS1: LD A,E RLCA LD E,A LD A,'0' / 2 ;BUILD ASCII 1 OR 0 RLA LD C,A CALL CONOUT DJNZ BITS1 POP DE RET ;---------------------------------------------------------------------------- ; ; 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 ; ;---------------------------------------------------------------------------- XAA: INC HL ;SKIP OVER TO NEXT ENTRY INC HL XA: INC (HL) ;IF AT END OF TABLE THEN RETURN RET Z JP P,XAB ;SORT OUT BIT 7 OF TABLE OR 80H ;SET IT ON TEST VALUE JR XAC ; XAB: AND 7FH ;RESET BIT 7 XAC: DEC (HL) ;TO BE PULLED OUT IN ROM CP (HL) JR NZ,XAA ;NO MATCH, TRY AGAIN CALL BLK CALL PRTVAL CALL DASH CALL PCHK ;GET NEW INPUT RET C ;IF CHAR = CR THEN RETURN JR Z,XF ;IF NO CHANGE THEN EXIT PUSH HL ;PTR CALL EXF POP HL LD A,L INC DE LD (DE),A EX (SP),HL ;RECOVER TABLE PTR LD A,(HL) ;GET THE ATTRIBUTES EX (SP),HL RLCA ;IF 8 BIT REG THEN EXIT JR NC,XE INC DE ;ELSE REG PAIR, DO OTHER 8 BITS LD A,H LD (DE),A XE: POP HL ;TABLE PTR XF: LD A,C ;IF LAST = CR THEN RETURN CP CR RET Z ; ; THIS IS THE ACTUAL COMMAND ENTRY POINT ; XMNE: LD HL,ACTBL ;ADDR OF REG LOOK-UP TABLE XMNE1: CALL PCHK JR C,XG ;IF CHAR = CR THEN SHOW ALL JR Z,XMNE1 ;IF CHAR = ' ' OR ',' THEN LOOP CP '''' ;IF NOT PRIMES THEN EXIT JR NZ,XA LD HL,PRMTB JR XMNE1 ; XG: LD A,(HL) LD C,A INC A ;IF AT END OF TABLE THEN RETURN RET Z CALL M,CRLF ;NEW LINE IF BIT 7 SET CALL CONOUT CALL DASH CALL PRTVAL CALL BLK INC HL ;NEXT ENTRY JR XG ; PRTVAL: INC HL ;NEXT ENTRY LD A,(HL) ;GET OFFSET & ATTRIBUTES AND 3FH ;ISOLATE OFFSET ADD A,2 ;ALLOW FOR RET ADDR EX DE,HL LD L,A ;BUILD ADDR OF REG CONTENTS LD H,0 ADD HL,SP EX DE,HL LD A,(HL) ;NOW FIND ATTRIBUTES LD B,1 ;SINGLE REG VALUE RLCA JR NC,PV1 ;IF SINGLE REG THEN EXIT INC B ;ELSE REG PAIR RLCA ;IF NOT (HL) THEN EXIT JR NC,PV1 PUSH HL ;BUILD ADDR IN HL LD A,(DE) LD H,A DEC DE LD A,(DE) LD L,A LD A,(HL) ;GET (HL) VALUE POP HL DJNZ PV2 ;ALLWAYS JUMP PV1: LD A,(DE) ;GET REG CONTENTS PV2: CALL HEX1 ;OUTPUT VALUE DEC DE ;MEM PTR DJNZ PV1 RET FORM SUBTTL GENERAL PURPOSE SUBROUTINES ;**************************************************************************** ; ; 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 0FH ADD A,90H ;PUT INTO ASCII ZONE DAA ;AH, THE UBIQUITOUS DAA CONVERT ADC A,40H DAA LD C,A RET ;*************************************************************** ; ; ECHO ROUTINE READS A BYTE FROM CONSOLE DEVICE & ECHOS ; THE CHAR BACK TO THE CONSOLE DEVICE. ; ;*************************************************************** DECHO: CALL DASH ;OUTPUT A '-' ECHO: CALL CONI ECH1: PUSH BC LD C,A ;OUTPUT CHAR CALL CONOUT LD A,C ;RESTORE CHAR IN A POP BC RET ;*************************************************************** ; ; EXPR3 ROUTINE GETS 3 PARAMETERS, DOES A CR-LF & THEN ; LOADS BC, DE & HL WITH THE PARAMS. ; ;*************************************************************** EXPR3: INC B ;B HAS 2 ALREADY CALL EXPR POP BC POP DE JP CRLFA ;GO DO CRLF ;**************************************************************************** ; ; HILO ROUTINE 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. ; ;**************************************************************************** HILO: INC HL LD A,H ;IF HL = 0 THEN RETURN CF OR L SCF RET Z LD A,E ;ELSE COMPARE HL TO DE SUB L LD A,D SBC A,H RET ;********************************************************** ; ; HILOX ROUTINE INCREMENTS HL, COMPARES IT TO DE & IF ; EQUAL, RETURNS CONTROL TO THE MONITOR EXEC. OTHERWISE, ; CONTROL RETURNS TO THE CALLING ROUTINE. ; ;********************************************************** HILOD: POP DE ;GET RID OF RETURN ADDR RET ;RETURN TO MONITOR HILOXB: INC BC HILOX: CALL HILO JR C,HILOD ;DONE IF CF CALL CONST ;IF NO CONSOLE BREAK THEN OR A ; RETURN RET Z CALL CONI ;IF CHAR <> CTRL-S THEN BREAK CP CTRLS JR NZ,HILOD JP CONI ;ELSE WAIT FOR NEXT CHAR ;*************************************************************** ; ; NIBBLE ROUTINE 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. ; ;*************************************************************** NIBBLE: SUB '0' RET C CP 'G' - '0' CCF RET C CP '9' - '0' + 1 CCF RET NC SUB 'A' - '9' - 1 CP 10 RET ;**************************************************************************** ; ; PCHK ROUTINE READS A CHARACTER FROM THE CONSOLE, THEN CHECKS IT FOR A ; DELIMITER. IF IT IS NOT A DELIMITER, A NON-ZERO CONDITION IS RETURNED. IF ; IT IS A DELIMITER, A ZERO CONDITION IS RETURNED. FURTHER, IF THE DELIMITER ; IS A CR, THE CARRY FLAG IS SET. A BLANK OR A COMMA RESETS THE CARRY FLAG. ; ;**************************************************************************** PCHK: CALL ECHO P2C: CP ' ' ;IF CHAR = ' ' THEN RETURN RET Z CP ',' ;IF CHAR = ',' THEN RETURN RET Z CP CR ;IF CHAR = CR THEN RETURN CF SCF RET Z CCF ;ELSE RETURN NC RET ;**************************************************************************** ; ; REST ROUTINE TRAPS ALL OF THE REGISTER CONTENTS WHENEVER A RESTART 1 ; INSTRUCTION IS EXECUTED. THE TRAPPED CONTENTS ARE STORED IN THE SYSTEM ; STACK 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 HL PUSH DE PUSH BC PUSH AF ; ; GET THE MONITOR STACK LOCATION ; CALL MEMSIZ ; ; SET UP PTR TO REGISTER SAVE AREA ABOVE STACK ; EX DE,HL LD HL,10 ;GO UP 10 BYTES IN STACK ADD HL,SP ; LD B,4 ;FOUR REGS EX DE,HL ; ; SAVE AF,BC,DE,HL ; RS1: DEC HL LD (HL),D ;SAVE IN WORK AREA DEC HL LD (HL),E POP DE DJNZ RS1 ; ; FETCH RETURN ADDRESS FROM PGM STACK ; POP BC ;GET BREAKPOINT LOCATION + 1 ; DEC BC ;BACK UP TO RESTART INSTRUCTION ; LD SP,HL ;SET THE MONITOR STACK ; LD HL,TLOCX ;RESTORE BP ADD HL,SP PUSH DE ; LD D,NBKPTS ; RS2: LD A,(HL) SUB C ;SEE IF SOFTWARE TRAP INC HL LD A,(HL) SBC A,B ;MAYBE, TRY REST OF ADDR JR Z,RS5 ;FOUND 1, RESET IT ; RS3: INC HL ;NOT FOUND, TRY NEXT 1 INC HL DEC D JR NZ,RS2 ; RS4: INC BC ;NONE FOUND ; RS5: LD HL,LLOCX ; POP DE ADD HL,SP LD (HL),E ;STORE USER (HL) INC HL LD (HL),D ; PUSH BC ; LD C,'*' ;OUTPUT BREAK INDICATION CALL CONOUT ; POP DE ;BP LOCATION LD A,RS9 / 256 CP D ;SEE IF A RET BP JR Z,RS6 ; INC HL INC HL LD (HL),E ;RESTORE USER PC INC HL LD (HL),D ; EX DE,HL ;OUTPUT BP LOCATION CALL LADR ; RS6: LD HL,TLOCX ADD HL,SP LD BC,NBKPTS * 256 ; RS7: LD E,(HL) ;RESTORE BP'D LOCATIONS LD (HL),C ;RESET SYSTEM SAVE AREA INC HL LD D,(HL) LD (HL),C INC HL LD A,E ;IF LOC = 0 THEN SKIP RESTORE OR D JR Z,RS8 ; LD A,(HL) ;ELSE RESTORE ORIGINAL INSTR. LD (DE),A ; RS8: INC HL ;DO NEXT BP DJNZ RS7 ; ; SAVE THE Z80 UNIQUES ; EX AF,AF' EXX PUSH HL PUSH DE PUSH BC PUSH AF PUSH IX PUSH IY LD A,I LD B,A LD A,R LD C,A PUSH BC ; ; GOTO MONITOR ; JP WINITA ;RETURN TO MONITOR ;---------------------------------------------------------------------------- ; ; THE FOLLOWING CODE IS MOVED TO THE MONITOR STACK AREA ; ;---------------------------------------------------------------------------- RS9: PUSH HL RST 8 ;FORCE BP ; ;---------------------------------------------------------------------------- ; ; THE FOLLOWING CODE RESTORES THE Z80 REGISTERS & EXECUTES THE 'PC' ; ;---------------------------------------------------------------------------- EXIT: ; ; FIRST RESTORE THE Z80 UNIQUES ; POP BC LD A,C LD R,A LD A,B LD I,A POP IY POP IX POP AF POP BC POP DE POP HL ; ; NOW DO THE 8080 REGS ; EX AF,AF' EXX POP DE POP BC POP AF POP HL ;STACK PTR LD SP,HL DB 0 ;'NOP' OR PLACE FOR 'EI' LD HL,0 ;'HL' REGISTER JP 0 ;'PC' REGISTER ; ENDX: EQU $ ;---------------------------------------------------------------------------- ; ; 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 ;**************************************************************************** ; ; QUERY ROUTINE WILL TELL THE OPERATOR WHAT HIS CURRENT LOGICAL-PHYSICAL ; PERIPHERAL DEVICE ASSIGNMENTS ARE. NO PARAMETERS (OTHER THAN A CR) ARE ; REQUIRED ON ENTRY. ; ;**************************************************************************** QUERY: LD A,(IOBYTE) LD B,4 LD HL,ACT ;ADDR OF CONVERSION TABLE LD DE,ALT - APT QUE1: PUSH AF CALL BLK LD C,(HL) ;GET CURRENT LOGICAL DEVICE CODE CALL CONOUT CALL DASH POP AF PUSH AF PUSH HL QUE2: INC HL INC A AND 3 ;BITS 0 & 1 ARE 0 WHEN ON CURRENT ASSGN JR NZ,QUE2 LD C,(HL) ;FOUND IT, NOW OUTPUT IT CALL CONOUT POP HL POP AF RRA RRA ADD HL,DE ;NEXT ENTRY DJNZ QUE1 RET ;******************************************************************** ; ; CONI ROUTINE READS THE CONSOLE & STRIPS OFF THE PARITY BIT. ; ;******************************************************************** CONI: CALL CI AND 7FH 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. ; THE STRING WILL START A NEW LNE (PRTWD) OR CONTINUE ON THE SAME LINE (PRTWA). ; ;**************************************************************************** PRTWD: CALL CRLF PRTWA: PUSH BC PRTA: LD C,(HL) 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 PRTB: POP BC RET ;*************************************************************** ; ; EXLF ROUTINE READS 2 PARAMETERS, PUTS THEM INTO THE DE ; & HL REGS, THEN DOES A CR-LF. ; ;*************************************************************** EXLF: CALL EXPR POP DE POP HL ;*************************************************************** ; ; CRLF ROUTINE OUTPUTS A CR-LF ON THE CONSOLE DEVICE TO ; START A NEW LINE. ; ;*************************************************************** CRLF: PUSH HL CRLFA: LD HL,CRMSG CALL PRTWA POP HL RET ;*************************************************************** ; ; LADR ROUTINE OUTPUTS THE CONTENTS OF HL ON THE CONSOLE ; EITHER AT THE START OF A NEW LINE (LADRA) OR AT THE CURRENT ; CURSOR LOCATION (LADR). ; ;*************************************************************** LADRA: CALL CRLF LADR: LD A,H CALL HEX1 LD A,L HEX1: PUSH AF RRCA RRCA RRCA RRCA CALL HEX2 POP AF HEX2: CALL CONV JR CO ;********************************************************** ; ; DASH ROUTINE OUTPUTS A '-' TO THE CONSOLE DEVICE ; ;********************************************************** DASH1: CALL HEX1 ;OUTPUT A AS HEX DASH: LD C,'-' JR CO ;*********************** ; ; PRINT ADDR SUBR ; ;*********************** LADRB: CALL LADRA BLK: LD C,' ' ;OUTPUT A SPACE ; 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 3 JP Z,CO0 ;CONSOLE 0 CP 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 3 JP Z,CSTS0 ;CONSOLE 0 CP 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 3 JP Z,CI0 ;CONSOLE 0 CP 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 0C0H JP Z,LO0 ;PRINTER 0 CP 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 0C0H JP Z,LSTAT0 ;PRINTER 0 CP 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 0CH JP Z,SI0 ;SERIAL CHANNEL 0 CP 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 30H JP Z,SO0 ;SERIAL CHANNEL 0 CP 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,(NTD) ;ELSE RETURN CHAR RET CO0: IN A,(NTS) ;IF NOT READY TO ACCEPT CHAR THEN WAIT AND 1 SHL NTBSY JR NZ,CO0 ; LD A,C ;OUTPUT CHAR & RETURN OUT (NTD),A RET CSTS0: IN A,(NTS) ;IF NOT CHAR NOT READY THEN RETURN 0 AND 1 SHL NTRDY 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 (PRI1DO),A LD A,NOT [1 SHL PRI1CSB] ;OUTPUT STROBE OUT (PRI2CNT),A LD A,0BFH OUT (PRI2CNT),A ;CLEAR STROBE RET LSTAT0: LD A,0BFH ;THIS PRINTER NEEDS STB=F FOR BUSY OUT (PRI2CNT),A ; TO WORK PROPERLY ; IN A,(PRI1ST) ;FETCH STATUS CPL AND A,[1 SHL PRI1BSB] ;TEST BUSY RET Z ; LD A,-1 RET ;************************************** ; ; LIST DEVICE 1 (LST1) ; ;************************************** LO1: CALL LSTAT1 ;IF BUSY THEN WAIT JR Z,LO1 ; LD A,C ;OUTPUT CHAR SET CENTDST,A OUT (CENTOUT),A RES CENTDST,A ;OUTPUT LOW TRUE STROBE OUT (CENTOUT),A SET CENTDST,A ;RESTORE STROBE OUT (CENTOUT),A RET LSTAT1: LD A,[1 SHL CENTDST] ;INSURE STROBE STARTS HIGH OUT (CENTOUT),A ; IN A,(CENTS) ;IF BUSY THEN RETURN 0 CPL ;REVERSE SENSE AND A,[1 SHL CENTBSY] RET Z ; LD A,-1 ;ELSE RETURN -1 RET ;************************************** ; ; 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 (SC2) ; ;************************************** SI2: EQU IOER SO2: EQU IOER ;************************************** ; ; SERIAL CHANNEL 3 (SC3) ; ;************************************** SI3: EQU IOER SO3: EQU IOER SUBTTL MESSAGES CRMSG: DM CR,LF RSTMSG: DM 'RST ERR ' BOOTEM: DM 'BOOT LOAD ERR',CR,LF USRMSG: DM 'MEMORY = ' IOMSG: DM 'I/O ERR ' QMSG: DM '????' LOGMSG: DM 'ZMON VERS 1.',HIGH VERSN,LOW VERSN,CR,LF SUBTTL DATA CONSTANTS ;############################################################################ ; ; TBL CONTAINS THE ADDRESSES OF THE COMMANDS. ; THE EXECUTIVE USES IT TO LOOK UP THE DESIRED ADDR. ; ;############################################################################ TBL: DW ASGN ;A ASSIGN PHYSICAL TO LOGICAL DEVICES 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 QUERY ;Q DISPLAY LOGICAL & PHYSICAL DEVICES 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 BYE ;Z SLEEP UNTILL BELL ;----------------------- ; ; IOBYTE TABLE ; ;----------------------- ALT: DB 'L' ;LOGICAL LIST DEVICE TABLE DB 'C' ; CONSOLE DB '2' ; LIST DEVICE 2 DB '1' ; LIST DEVICE 1 DB '0' ; LIST DEVICE 0 ; APT: DB 'P' ;LOGICAL PUNCH DEVICE TABLE DB '3' ; SERIAL CHANNEL 3 DB '2' ; SERIAL CHANNEL 2 DB '1' ; SERIAL CHANNEL 1 DB '0' ; SERIAL CHANNEL 0 ; ART: DB 'R' ;LOGICAL READER DEVICE TABLE DB '3' ; SERIAL CHANNEL 3 DB '2' ; SERIAL CHANNEL 2 DB '1' ; SERIAL CHANNEL 1 DB '0' ; SERIAL CHANNEL 0 ; ACT: DB 'C' ;LOGICAL CONSOLE DEVICE TABLE DB '3' ; CONSOLE 3 DB '2' ; CONSOLE 2 DB '1' ; CONSOLE 1 DB '0' ; CONSOLE 0 ;--------------------------------- ; ; Z80 REGISTER OFFSET TABLE ; ;--------------------------------- ACTBL: DB 80H + 'A',ALOC DB 'B',BLOC DB 'C',CLOC DB 'D',DLOC DB 'E',ELOC DB 'F',FLOC DB 'H',HLOC DB 'L',LLOC DB 80H + 'M',HLOC + 0C0H DB 'P',PLOC + 80H DB 'S',SLOC + 80H DB 'I',ILOC ; ; PRIME Z80 REGISTER OFFSETS ; PRMTB: DB 80H + 'A',APLOC DB 'B',BPLOC DB 'C',CPLOC DB 'D',DPLOC DB 'E',EPLOC DB 'F',FPLOC DB 'H',HPLOC DB 'L',LPLOC DB 'M' + 80H,HPLOC + 0C0H DB 'X',XLOC + 80H DB 'Y',YLOC + 80H DB 'R',RLOC DB -1 END