; << ZAPPLE 2-K MONITOR SYSTEM >> ; by ; ; TECHNICAL DESIGN LABS, INC. ; RESEARCH PARK ; PRINCETON, NEW JERSEY 08540 ; ; COPYRIGHT JULY 1976 BY TDL INC. ; ; ASSEMBLED BY ROGER AMIDON ; ; ;BASE: EQU 0F000H ; WW: NOW DEFINED IN WRAPPER USER: EQU BASE+800H ; TITLE ; RST7: EQU 38H ;RST 7 (LOCATION FOR TRAP) ;WW IOBYT: EQU 76H ;R/W PORT FOR TEMP. STORAGE IOBYT: EQU SIO_SCR ; WW - USING UART SPR FOR TEMP. STORAGE ;WW SENSE: EQU 7AH ;PORT FOR INITIAL I/O CMNFIGURATIOL (IN) ;WW SWITCH: EQU 0FFH ;FRONT PANEL SENSE SWITCHES ;WW RCP: EQU 7AH ;READER CONTROL PORT (OUT) ;WW NN: EQU 0F8H ;"I" REGISTER INITIAL VALUE ; ; EXTERNAL EQUATES ; NAME ZAPPLE EXT COLOC EXT LNLOC EXT LULOC EXT PTPL EXT PULOC EXT CSLOC EXT CILOC EXT RPTPL EXT RULOC ; ; ; ; ;-TELEPRINTER ; ; WW: VALUES BELOW MODIFIED FOR N8VEM STD UART PORTS TTI: EQU SIO_RBR ;DATA IN PORT TTO: EQU SIO_THR ;DATA OUT PORT TTS: EQU SIO_LSR ;STATUS PORT (IN) TTYDA: EQU $01 ;DATA AVAILABLE MASK BIT TTYBE: EQU $20 ;XMTR BUFFER EMPTY MASK ; ;-C.R.T. SYSTEM ; CRTI: EQU 51H ;DATA PORT (IN) CRTS: EQU 50H ;STATUS PORT (IN) CRTO: EQU 51H ;DATA PORT (OUT) CRTDA: EQU 40H ;DATA AVAILABLE MASK CRTBE: EQU 80H ;XMTR BUFFER EMPTY MASK ; ;-CASSETTE SYSTEM ; RCSD: EQU 61H ;DATA IN PORT RCSS: EQU 60H ;STATUS PORT (IN) RCSDA: EQU 40H ;DATA AVAILABLE MASK PCASO: EQU 61H ;DATA PORT (OUT) PCASS: EQU 60H ;CONTROL PORT (OUT) PCSBE: EQU 80H ;XMTR BUFFER EMPTY MASK ; ; ; FALSE: EQU 0 ;ISN'T SO TRUE: EQU NOT FALSE ;IT IS SO CR: EQU 0DH ;ASCII CARRIAGE RETURN LF: EQU 0AH ;ASCII LINE FEED BELL: EQU 7 ;DING RUB: EQU 0FFH ;RUB OUT FIL: EQU 00 ;FILL CHARACTER AFTER CRLF MAX: EQU 7 ;NUMBER OF QUES IN EOF ; ; ; CMSK: EQU 11111100B ;CONSOLE DEVICE RMSK: EQU 11110011B ;STORAGE DEVICE (IN) PMSK: EQU 11001111B ;STORAGE DEVICE (OUT) LMSK: EQU 00111111B ;LIST DEVICE ; ; ;-CONSOLE CONFIGURATION CTTY: EQU 0 ;TELEPRINTER CCRT: EQU 1 ;C.R.T. BATCH: EQU 2 ;READER FOR INPUT, LIST FOR OUTPUT CUSE: EQU 3 ;USER DEFINED ; ;-STORAGE INPUT CONFIGURATION RTTY: EQU 0 ;TELEPRINTER READER RPTR: EQU 4 ;HIGH-SPEED RDR (EXTERNAL ROUTINE) RCAS: EQU 8 ;CASSETTE RUSER: EQU 0CH ;USER DEFINED ; ;-STORAGE OUTPUT CONFIGURATION PTTY: EQU 0 ;TELEPRINTER PUNCH PPTP: EQU 10H ;HIGH-SPEED PUNCH (EXTERNAL ROUTINE) PCAS: EQU 20H ;CASSETTE PUSER: EQU 30H ;USER DEFINED ; ;-LIST DEVICE CONFIGURATION LTTY: EQU 0 ;TELEPRINTER PRINTER LCRT: EQU 40H ;C.R.T. SCREEN LINE: EQU 80H ;LINE PRINTER (EXTERNAL ROUTINE) LUSER: EQU 0C0H ;USER DEFINED ; ; ; VECTOR FOR USER DEFINED ROUTINES ; ;.LOC: USER ;CILOC: .BLKB 3 ;CONSOLE INPUT ;COLOC: .BLKB 3 ;CONSOLE OUTPUT ;RPTPL: .BLKB 3 ;HIGH-SPEED READER ;RULOC: .BLKB 3 ;USER DEFINED STORAGE (INPUT) ;PTPL: .BLKB 3 ;HIGH-SPEED PUNCH ;PULOC: .BLKB 3 ;USER DEFINED STORAGE (OUTPUT) ;LNLOC: .BLKB 3 ;LINE PRINTER ;LULOC: .BLKB 3 ;USER DEFINED PRINTER ;CSLOC: .BLKB 3 ;CONSOLE INPUT STATUS ROUTINE ;J: =. ; ; PROGRAM CODE BEGINS HERE ; ; .ORG BASE ; WW: MODIFIED FOR TASM SYNTAX JP BEGIN ;GO AROUND VECTORS ; ; ; ; THESE VECTORS MAY BE USED BY USER WRITTEN ; PROGRAMS TO SIMPLIFY THE HANDLING OF I/O ; FROM SYSTEM TO SYSTEM. WHATEVER THE CURRENT ; ASSIGNED DEVICE, THESE VECTORS WILL PERFORM ; THE REQUIRED I/O OPERATION, AND RETURN TO ; THE CALLING PROGRAM. (RET) ; ; THE REGISTER CONVENTION USED FOLLOWS- ; ; ANY INPUT OR OUTPUT DEVICE ; CHARACTER TO BE OUTPUT IN 'C' REGISTER. ; CHARACTER WILL BE IN 'A' REGISTER UPON ; RETURNING FROM AN INPUT OR OUTPUT. ; 'CSTS'- ; RETURN TRUE (0FFH IN 'A' REG.) IF THERE IS ; SOMETHING WAITING, AND ZERO (00) IF NOT. ; 'IOCHK'- ; RETURN WITH THE CURRENT I/O CONFIGURATION ; BYTE IN 'A' REGISTER. ; 'IOSET'- ; ALLOWS A PROGRAM TO DYNAMICALLY ALTER THE ; CURRENT I/O CONFIGURATION, AND REQUIRES ; THE NEW BYTE IN 'C' REGISTER. ; 'MEMCK'- ; RETURNS WITH THE HIGHEST ALLOWED USER ; MEMORY LOCATION. 'B'=HIGH BYTE, 'A'=LOW. ; 'TRAP'- ; THIS IS THE 'BREAKPOINT' ENTRY POINT, ; BUT MAY BE 'CALLED'. IT WILL SAVE ; THE MACHINE STATE. RETURN CAN BE MADE WITH ; A SIMPLE 'G[CR]' ON THE CONSOLE. ; JP CI ;CONSOLE INPUT JP RI ;READER INPUT JP CO ;CONSOLE OUTPUT JP PUO ;PUNCH OUTPUT JP LO ;LIST OUTPUT JP CSTS ;CONSOLE STATUS JP IOCHK ;I/O CHECK JP IOSET ;I/O SET JP MEMCK ;MEMORY LIMIT CHECK TRAP: JP RESTART ;BREAKPOINT ; ; ANNOUNCEMENT OF MONITOR NAME & VERSION MSG: DB CR,LF,FIL,FIL,FIL DB "Zapple V" ; WW: CHANGED TO DQUOTES DB "1.1" ; WW: CHANGED TO DQUOTES MSGL: EQU $-MSG ; ; LET US BEGIN ; ; ; *NOTE- THE CODE UP TO THE 'IN SENSE' MAY ; BE REPLACED BY ENOUGH CODE TO INITIALIZE ; AN ACIA OR SIO DEVICE. ADDITIONAL DEVICES ; MAY BE INITIALIZED USING THE 'Q' COMMAND. ; (OR STANDARD ROUTINES FOR INITILIZATION ; MAY BE LOADED & EXECUTED IN THE USER AREA). ; BEGIN: ;WW LD A,NN ;FOR 'I' REG. IF NEEDED. ;WW LD I,A ;WW NOP ;SPARE BYTE ;WW XOR A ;CLEAR READER CONTROL PORT ;WW OUT RCP,A ; ;WW IN A,SENSE ;INITIALIZE I/O CONFIGURARTION LD A,$FF ; WW - INIT IOBYT TO $FF (NOTE IT IS INVERTED WHEN USED) OUT IOBYT,A LD SP,AHEAD-4 ;SET UP A FAKE STACK JP MEMSIZ+1 ;GET MEMORY SIZE DEFW AHEAD AHEAD: LD SP,HL ;SET TRUE STACK EX DE,HL LD BC,ENDX-EXIT LD HL,EXIT LDIR ;MOVE TO RAM EX DE,HL LD BC,-5FH ;SET UP A USER'S STACK VALUE ADD HL,BC PUSH HL ;PRE-LOAD USER'S STACK VALUE LD HL,0 ;INITIALIZE OTHER REGISTERS LD B,10 ; (16 OF THEM) STKIT: PUSH HL ; TO ZERO DJNZ STKIT HELLO: LD B,MSGL ;SAY HELLO TO THE FOLKS CALL TOM ;OUTPUT SIGN-ON MSG START: LD DE,START ;MAIN 'WORK' LOOP PUSH DE ;SET UP A RETURN TO HERE CALL CRLF LD C,'>' CALL CO STARO: CALL TI ;GET A CONSOLE CHARACTER AND 7FH ;IGNORE NULLS JR Z,STARO ;GET ANOTHER SUB 'A' ;QUALIFY THE CHARACTER RET M ;Z ADD A ;A*2 LD B,0 LD C,A ;POINT TO PLACE ON TABLE LD HL,TBL ;POINT TO COMMAND TABLE ADD HL,BC ;ADD IN DISPLACEMENT LD E,(HL) INC HL LD D,(HL) EX DE,HL ;D&E=ROUTINE ADDRESS LD C,2 ;SET C UP JP (HL) ;GO EXECUTE COMMAND ; ; ; TBL: DEFW ASSIGN ;A - ASSIGN I/O DEFW BYE ;B - SYSTEM SHUT-DOWN DEFW COMP ;C - COMPARE MEMORY VS. READER INPUT DEFW DISP ;D - DISPLAY MEMORY ON CONS. IN HEX DEFW EOF ;E - END OF FILE TAG FOR HEX DUMPS DEFW FILL ;F - FILL MEMORY WITH A CONSTANT DEFW GOTO ;G - GOTO [ADDR] <,>BREAKPOINTS (2) DEFW HEXN ;H - HEX MATH. , DEFW ERROR ;I * USER DEFINED, INSERT VECTOR ; J=J ;VECTOR ADDR DEFW TEST ;J - NON-DESTRUCTIVE MEMORY TEST DEFW ERROR ;K * USER DEFINED, INSERT VECTOR ; J=J+3 ;VECTOR ADDR DEFW LOAD ;L - MOVE A BINARY FORMAT FILE DEFW MOVE ;M - MOVE BLOCKS OF MEMORY DEFW NULL ;N - PUNCH NULLS ON PUNCH DEVICE DEFW ERROR ;O * USER DEFINED, INSERT VECTOR ; J=J+3 ;VECTOR ADDR DEFW PUTA ;P - 'PUT' ASCII INTO MEMORY. DEFW QUERY ;Q - QI(N)=DISP. N; QO(N,V)=OUT N,V DEFW READ ;R - READ A HEX FILE (W/CHECKSUMS) DEFW SUBS ;S - SUBSTITUTE &/OR EXAMINE MEMORY DEFW TYPE ;T - TYPE MEMORY IN ASCII DEFW UNLD ;U - MEMORY TO PUNCH (BINARY FORMAT) DEFW VERIFY ;V - COMPARE MEMORY AGAINST MEMORY DEFW WRITE ;W - MEMORY TO PUNCH (HEX FORMAT) DEFW XAM ;X - EXAMINE & MODIFY CUP REGISTERS DEFW WHERE ;Y - FIND SEQUENCE OF BYTES IN RAM DEFW SIZE ;Z - ADDRESS OF LAST R/W LOCATION ; ; ; ; THIS ROUTINE CONTROLS THE CONFIGURATION ; OF THE VARIOUS I/O DRIVERS & DEVICES. THIS IS ; ACCOMPLISHED VIA A HARDWARE READ/WRITE PORT. ; THIS PORT IS INITIALIZED UPON SIGN-ON ; BY THE VALUE READ ON PORT 'SENSE'. IF MAY BE ; DYNAMICALLY MODIFIED THROUGH CONSOLE COMMANDS. ; ; THE VALUE ON THE 'IOBYT' PORT REPRESENTS THE ; CURRENT CONFIGURATION. IT IS STURCTURED THUSLY: ; ; 000000XX - WHERE XX REPRESENTS THE CURRENT CONSOLE ; 0000XX00 - WHERE XX REPRESENTS THE CURRENT READER ; 00XX0000 - WHERE XX REPRESENTS THE CURRENT PUNCH ; XX000000 - WHERE XX REPRESENTS THE CURRENT LISTER ; ; WHEN USING A MEMORY LOCATION FOR IOBYT, THE ; POLARITY IS REVERSED. FOR AN I/O PORT, ; WHEN XX = 11, THE DEVICE IS ALWAYS THE ; TELEPRINTER. WHEN XX = 00, THE DEVICE IS ALWAYS ; USER DEFINED. SEE OPERATOR'S MANUAL FOR FURTHER ; DETAILS. ; ASSIGN: CALL TI ;GET DEVICE NAME LD HL,LTBL ;POINT TO DEVICE TABLE LD BC,400H ;4 DEVICES TO LOOK FOR LD DE,5 ;4 DEV. + IDENT. ..A0: CP (HL) ;LOOK FOR MATCH JR Z,..A1 ADD HL,DE ;GO THRU TABLE INC C ;KEEP TRACK OF DEVICE DJNZ ..A0 JR ..ERR ;WRONG IDENTIFIER ..A1: LD E,C ;SAVE DEVICE NUMBER ..A2: CALL TI ;SCAN PAST '=' CP '=' JR NZ,..A2 CALL TI ;GET NEW ASSIGNMENT LD BC,400H ;4 POSSIBLE ASSIGNMENTS ..A3: INC HL ;POINT TO ASSIGNMENT NAME CP (HL) ;LOOK FOR PROPER MATCH JR Z,..A4 ;MATCH FOUND INC C ;KEEP TRACK OF ASSIGNMENT NMBR DJNZ ..A3 ..ERR: JP ERROR ;NO MATCH, ERROR ..A4: LD A,3 ;SET UP A MASK INC E ..A5: DEC E ;DEVICE IN E JR Z,..A6 ;GOT IT SLA C ;ELSE MOVE MASKS SLA C RLA RLA ;A=DEVICE MASK JR ..A5 ..A6: CPL ;INVERT FOR AND'ING LD D,A ;SAVE IN D ..A7: CALL PCHK ;WAIT FOR [CR] JR NC,..A7 CALL IOCHK ;GET PRESENT CONFIGURATION AND D ;MODIFY ONLY SELECTED DEVICE OR C ;'OR' NEW BIT PATTERN LD C,A ;NEW CONFIGURATION ; ; THIS ALLOWS USER PROGRAMS TO MODIFY ; THE I/O CONDIGURATIMN DYNAMICALLY ; DURING EXECUTION. ; IOSET: LD A,C ;NEW I/O BYTE PASSED IN C REE CPL ;WE SAVE THE INVERTED BYTE OUT IOBYT,A ;IN AN I/O PORT LATCH RET ; ; THIS RETURNS THE CURRENT I/O ; CONFIGURATION IN THEE A REG. ; IOCHK: IN A,IOBYT ;GET SAVED VALUE CPL ;AND INVERT IT AGAIN XOR A ; WW RET ; ; ; THIS ROUTINE IS USED AS A SIMPLE MEANS TO PREVENT ; UNAUTHORIZED SYSTEM OPERATION. THE SYSTEM LOCKS UP, ; MONITORING FOR A 'CONT.-SHIFT-N', AT WHICH TIME IT ; WILL SIGN-ON AGAIN. NO REGISTER ASSIGHNMENTS OR I/O ; CONFIGURATIONS WILL BE ALTERED. ; BYE: CALL CRLF ..BY: CALL KI CP 1EH ;CONTROL-SHIFT-N JR NZ,..BY POP DE ;REMOVE THE RETURN JP HELLO ;AND SIGN-ON AGAIN ; ; THIS ALLOW ENTERING OF ASCII TEXT INTO MEMORY ; FROM THE CONSOLE DEVICE. THE PARITY BIT IS CLEARED, ; AND ALL WILL BE STORED EXCEPT THE BACK-ARROR [ ] ; WHICH DELETES THE PREVIOUS CHARACTER, AND ; CONTROL-D, WHICH RETURNS CONTROL TO THE MONITOR. ; THIS COMMAND, COMBINED WITH THE 'Y' COMMAND, ; PROVIDES A RUDIMENTARY TEXT PROCESSING ABILITY. ; PUTA: CALL EXPR1 ;GET THE STARTING ADDR. CALL CRLF POP HL ...A1: CALL KI ;GET A CHARACTER CP 4 ;CONTROL-D? (EOT) JP Z,LFADR ;YES, STOP & PRINT CP 5FH ;ERASE MISTAKE? JR Z,...A3 ; YES. LD (HL),A ;ELSE STORE IT IN MEMORY LD C,A INC HL ...A2: CALL CO ;ECHO ON CONSOLE JR ...A1 ...A3: DEC HL LD C,(HL) JR ...A2 ;ECHO & CONTINUE ; ; THIS ROUTINE COMPARES THE READER INPUT ; DEVICE WITH THE MEMORY BLOCK SPECIFIED. ; IT TESTS ALL EIGHT BITS, AND ANY DISCREPENCIES ; WILL BE OUTPUT TO THE CONSOLE. THIS IS USEFUL ; WHEN USED WITH THE BINARY DUMP DORMAT TO BOTH ; VERIFY PROPER READING & STORAGE, OR TO DETECT ; PROGRAM CHANGES SINCE IT WAS LAST LOADED. ; COMP: CALL EXLF ;GET START ' STOP ADDR. ..C: CALL RIFF ;GET A FULL READER BYTE CP (HL) ;8 BIT COMPARE CALL NZ,CERR ;CALL IF INVALID COMPARE CALL HILOX ;SEE IF RANGE SATISFIED JR ..C ; ; THIS SUBROUTINE IS USED TO DISPLAY THE ; CURRENT LOCATION OF THE 'M' REGISTER POINTER (HL) , ; AND THE VALUE AT THE LOCATION, AND THE CONTENTS ; OF THE ACCUMULATOR. USED BY TWO ROUTINES. ; CERR: LD B,A ;SAVE ACC. CALL HLSP ;DISPLAY H&L LD A,(HL) CALL LBYTE ;PRINT 'M' CALL BLK ;SPACE OVER LD A,B CALL LBYTE ;PRINT ACC. JP CRLF ;CRLF & RETURN ; ; THIS DISPLAYS THE CONTENTS OF MEMORY IN BASE HEX ; WITH THE STARTING LOCATION ON EACH LINE. (BETWEEN ; THE TWO PARAMEETERS GIVEN). 16 BYTES PER LINE MAX. ; DISP: CALL EXLF ;GET DISPLAY RANGE ..D0: CALL LFADR ;CRLF & PRINT ADDR. ..D1: CALL BLK ;SPACE OVER LD A,(HL) CALL LBYTE CALL HILOX ;RANGE CHECK LD A,L AND 0FH ;SEE IF TIME TO CRLF JR NZ,..D1 JR ..D0 ; ; THIS OUTPUTS THE END OF FILE (EOF) PATTERN ; FOR THE CHECKSUM LOADER. IT IS USED AFTER ; PUNCHING A BLOCK OF MEMORY WITH THE 'W' ; COMMAND. AN ADDRESS PARAMETER MAY BE GIVEN, ; AND UPON READING, THIS ADDRESS WILL BE ; AUTOMATICALLY PLACED INT THE 'P' COUNTER. THE ; PROGRAM CAN THEN BE RUN WITH A SIMPLE 'G[CR]' ; COMMAND. ; EOF: CALL EXPR1 ;GET OPTIONAL ADDR. CALL PEOL ;CRLF TO PUNCH LD C,':' ;FILE MARKER CUE CALL PUO XOR A ;ZERO LENGTH CALL PBYTE POP HL CALL PADR ;PUNCH OPTIONAL ADDR. LD HL,0 ;FILE TYPE=0 CALL PADR ;PUNCH IT JP NULL ;TRAILER & RETURN ; ; THIS COMMAND WILL FILL A BLOCK OF MEMORY ; WITH A VALUE. IE; FO,1FFF,0 FILLS FROM ; <1> TO <2> WITH THE BYTE <3>. HANDY FOR ; INITIALIZING A BLOCK TO A SPECIFIC VALUE, OR ; MEMORY TO A CONSTANT VALUE BEFOR LOADING ; A PROGRAM. (ZERO IS ESPECIALLY USEFUL.) ; FILL: CALL EXPR3 ;GET 3 PARAMEETERS ..F: LD (HL),C ;STORE THE BYTE CALL HILO JR NC,..F POP DE ;RESTORE STACK JP START ; IN CASE OF ACCIDENTS ; ; THIS COMMAND ALLOWS EXECUTION OF ANOTHER ; PROGRAM WHILE RETAINING SOME MONITOR ; CONTROL BY SETTING BREAKPOINTS. ; ; TO SIMPLY EXECUTE, TYPE 'G[CR]'. TO SET ; A BREAKPOINT TRAP, ADD THE ADDRESS (ES) TO THE ; COMMAND. IE; G,[CR]. TWO BREAKPOINTS ; ARE ALLOWED, ENOUGH TO SATISFY MOST REQUIREMENTS. ; ONCE A BREAKPOINT HAS BEEN REACHED, THE ; REGISTERS MAY BE EXAMINED OR MODIFIED. THE ; PROGRAM CAN THEN BE CONTINUED BY TYPING ONLY ; A 'G[CR]'. OR ANOTHER BREAKPOINT COULD BE ; IMPLEMENTED AT THAT TIME BY TYPING 'G,[CR]'. ; ; *NOTE: THIS IS SOFTWARE CONTROLLED, AND THE ; BREAKPOINT MUST OCCUR ON AN INSTRUCTION ; BYTE. ; GOTO: CALL PCHK ;GET A POSSIBLE ADDRESS JR C,..G3 ;CR ENTERED JR Z,..G0 ;DELIMETER ENTERED CALL EXF ;GET ONE EXPRESSION POP DE LD HL,PLOC ;PLACE ADDRESS IN 'P' LOCATION ADD HL,SP LD (HL),D ;HIGH BYTE DEC HL LD (HL),E ;LOW BYTE LD A,B CP CR ;SEE IF LAST CHARACTER WAS A CR JR Z,..G3 ;YES, LEAVE ..G0: LD D,2 ;TWO BREAKPOINTS MAX LD HL,TLOC ;POINT TO TRAP STORAGE ADD HL,SP ..G1: PUSH HL ;SAVE STORAGE POINTER CALL EXPR1 ;GET A TRAP ADDRESS LD E,B ;SAVE DELIMITER POP BC ;TRAP ADDR. POP HL ;STORAGE LD A,B ;LOOK AT TRAP ADDR OR C JR Z,..G2 ;DON'T SET A TRAP AT 0 LD (HL),C ;SAVE BKPT ADDR INC HL LD (HL),B INC HL LD A,(BC) ;PICK UP INST. BYTE LD (HL),A ;SAVE THAT TOO INC HL LD A,0FFH ;RST 7 LD (BC),A ;SOFTWARE INTERUPT ..G2: LD A,E ;LOOK AT DEELIMITER CP CR JR Z,..G2A DEC D ;COUNT BKPTS JR NZ,..G1 ;GET ONE MORE ..G2A: LD A,0C3H ;SET UP JUMP INSTRUCTION LD (RST7),A ; AT RESTART TRAP LOC. LD HL,TRAP ; TO MONITOR VECTOR LD (RST7+1),HL ..G3: CALL CRLF POP DE ;CLEAR SYSTEM RETURN LD HL,22 ;FIND 'EXIT' ROUTINE ADD HL,SP ;UP IN STACK JP (HL) ;GO SOMPLACE ; ; THIS IS A 'QUICKIE' MEMORY TEST TO SPOT ; HARD MEMORY FAILURES, OR ACCIDENTLY ; PROTECTED MEEMORY LOCATIONS. IT IS NOT ; MEANT TO BE THE DEFINITIVE MEMORY DIAGNOSTIC. ; IT IS, HOWEVER, NON-DESTRUCTIVEE. ERRORS ARE ; PRINTED ON THE CONSOLE AS FOLLOWS- ; 00000100 WHERE <1> IS THE BAD BIT. ; BIT LOCATION OF THE FAILURE IS EASILY ; DETERMINED. NON-R/W MEMORY WILL RETURN ; WITH- 11111111 ; TEST: CALL EXLF ;GET TWO PARAMS ...T1: LD A,(HL) ;READ A BYTE LD B,A ;SAVE IN B REG. CPL LD (HL),A ;READ/COMPLIMENT/WRITE XOR (HL) ; & COMPARE JR Z,...T2 ;SKIP IF ZERO (OK) PUSH DE ;SAVE END POINTER LD D,B ;SAVE BYTE LD E,A ;SET-UP TO DISPLAY CALL HLSP ;PRINT BAD ADDR CALL BITS ;PRINT BAD BIT LOC. CALL CRLF LD B,D ;RESTORE BYTE POP DE ;RESTORE DE ...T2: LD (HL),B ;REPLACE BYTE CALL HILOX ;RANGE TEST JR ...T1 ; ; THIS COMMAND MOVES MASS AMOUNTS OF MEMORY ; FROM <1> THRU <2> TO THE ADDRESS STARTING ; AT <3>. THIS ROUTINE SHOULD BE USED WITH ; SOME CAUTION, AS IT COULD SMASH MEMORY IF ; CARLESSLY IMPLEMENTED. ; ; M<1>,<2>,<3> ; MOVE: CALL EXPR3 ;GET 3 PARAMTERS ..M: LD A,(HL) ;PICK UP LD (BC),A ;PUT DOWN INC BC ;MOVE UP CALL HILOX ;CHECK IF DONE JR ..M ; ; THIS COMMAND READS THE CHECK-SUMMED HEX FILES ; FOR BOTH THE NORMAL INTEL FORMAT AND THE TDL ; RELOCATING FORMAT. ON BOTH FILES, A 'BIAS' MAY ; BE ADDED, WHICH WILL CAUSE THE OBJECT CODE TO ; BE PLACED IN A LOCATION OTHER THAN ITS ; INTENDED EXECUTION LOCATION. THE BIAS IS ADDED ; TO WHAT WOULD HAVE BEEN THE NORMAL LOADING ; LOCATION, AND WILL WRAP AROUND TO ENABLE ; LOADING ANY PROGRAM ANYWHERE IN MEMORY. ; ; WHEN LOADING A RELOCATABLE FILE, AN ADDITIONAL ; PARAMETER MAY BE ADDED, WHICH REPRESENTS THE ; ACTUAL EXECUTION ADDRESS DESIRED. THIS ALSO MAY ; BE ANY LOCATION IN MEMORY. ; ; EXAMPLES: ; ; R[CR] =0 BIAS, 0 EXECUTION ADDR. ; R[CR] =<1>BIAS, 0 EXECUTION ADDR. ; R,[CR] =0 BIAS, <1> EXECUTION ADDR. ; R,[CR] =<1>BIAS, <2>EXECUTION ADDR. ; READ: CALL EXPR1 ;GET BIAS, IF ANY LD A,B ;LOOK AT DELIMITER SUB CR ;ALL DONE? LD B,A ;SET UP RELOCATION OF 0 LD C,A ; IF CR ENTERED POP DE ;BIAS AMOUNT JR Z,..R0 ;CR ENTERED CALL EXPR1 ;GET RELOCATION POP BC ;ACTUAL RELOCATION VALUE ..R0: EX DE,HL EXX ;HL'=BIAS, BC'=RELOCATION CALL CRLF LOD0: CALL RIX ;GET A CHARACTER SUB ':' ;ABSOLUTE FILE CUE? LD B,A ;SAVE CUE CLUE AND 0FEH ;KILL BIT 0 JR NZ,LOD0 ; NO, KEEP LOOKING LD D,A ;ZERO CHECKSUM CALL SBYTE ;GET FILE LENGTH LD E,A ;SAVE IN E REG. CALL SBYTE ;GET LOAD MSB PUSH AF ;SAVE IT CALL SBYTE ;GET LOAD LSB EXX ;CHANGE GEARS POP DE ;RECOVER MSB LD E,A ;FULL LOAD ADDR PUSH BC ;BC'=RELOCATION PUSH DE ;DE'=LOAD ADDR PUSH HL ;HL'=BIAS ADD HL,DE ; BIAS+LOAD EX (SP),HL ;RESTORE HL' POP IX ; X=BIAS+LOAD EXX ;DOWNSHIFT POP HL ;HL=LOAD ADDR CALL SBYTE ;GET FILE TYPE DEC A ;1=REL. FILE, 0=ABS. LD A,B ;SAVE CUE BIT POP BC ;BC=RELOCATION JR NZ,..A ;ABSOLUTE FILE ADD HL,BC ;ELSE RELMCATE ADD IX,BC ;BOTH X & HL ..A: INC E ;TEST LENGHT DEC E ;0=DONE JR Z,DONE DEC A ;TEST CUE JR Z,LODR ;RELATIVE ..LI: CALL SBYTE ;NEXT CALL STORE ;STORE IT JR NZ,..L1 ;MORE COMING LOD4: CALL SBYTE ;GET CHECKSUM JR Z,LOD0 ;GOOD CHECKSUM ERR3: PUSH IX POP HL ;TRANSFER CALL LADR ;PRINT CURRENT LOAD ADDR ERR2: JP ERROR ;ABORT DONE: LD A,H ;DON'T MODIFY IF ZERO OR L RET Z EX DE,HL ;ELSE STORE IN PC LD HL,PLOC ADD HL,SP LD (HL),D ;IN STACK AREA DEC HL LD (HL),E RET LODR: LD L,1 ;SET-UP BIT COUNTER ..L1: CALL LODCB ;GET THE BIT JR C,..L3 ;DOUBLE BIT ..L5: CALL STORE ;WRITE IT JR NZ,..L1 JR LOD4 ;TEST CHECKSUM ..L3: LD C,A ;SAVE LOW BYTE CALL LODCB ;NEXT CONTROL BIT LD B,A ;SAVE HIGH BYTE EXX PUSH BC ;GET RELOCATION EXX EX (SP),HL ;INTO HL ADD HL,BC ;RELOCATE LD A,L ;LOW BYTE CALL STORE ;STORE IT LD A,H ;HIGH BYTE POP HL ;RESTORE HL JR ..L5 ;DO THIS AGAIN LODCB: DEC L ;COUNT BITS JR NZ,..LC1 ;MORE LEFT CALL SBYTE ;GET NEXT DEC E ;COUNT BYTES LD H,A ;SAVE THE BITS LD L,8 ;8 BITS/BYTE ..LC1: CALL SBYTE ;GET A DATA BYTE SLA H ;TEST NEXT BIT RET SBYTE: PUSH BC ;PRESERVE BC CALL RIBBLE ;GET A CONVERTED ASCII CHAR. RLCA RLCA RLCA RLCA ;MOV IT TO HIGH NIBBLE LD C,A ;SAVE IT CALL RIBBLE ;GET OTHER HALF OR C ;MAKE WHOLE LD C,A ;SAVE AGAIN IN C ADD D ;UPDATE CHECKSUM LD D,A ;NEW CHECKKSUM LD A,C ;CONVERTED BYTE POP BC RET STORE: LD (IX),A ;WRITE TO MEMORY CP (IX) ;VALID WRITE? JR NZ,ERR3 ; NO. INC IX ;ADVANCE POINTER DEC E ;COUNT DOWN RET ; ; THIS ROUTINE ALLOWS BOTH INSPECTION OF & ; MODIFICATION OF MEMORY ON A BYTE BY BYTE ; BASIS. IT TAKES ONE ADDRESS PARAMETER, ; FOLLOWED BY A SPACE. THE DATA AT THAT ; LOCATION WILL BE DISPLAYED. IF IT IS ; DESIRED TO CHANGE IT, THE VALUE IS THEN ; ENTERED. A FOLLOWING SPACE WILL DISPLAY ; THE NEXT BYTE. A CARRIAGE RETURN [CR] ; WILL TERMINATE THE COMMAND. THE SYSTEM ; ADDS A CRLF AT LOCATIONS ENDING WITH EITHER ; XXX0 OR XXX8 TO AID IN DTERMINING THE ; PRESENT ADDRESS, IT IS PRINTED AFTER ; EACH CRLF. A BACKARROW [ ] WILL BACK ; UP THE POINTER AND DISPLAY THE ; PREVIOUS LOCATION. ; SUBS: CALL EXPR1 ;GET STARTING ADDR POP HL ..S0: LD A,(HL) CALL LBYTE ;DISPLAY THE BYTE CALL COPCK ;MODIFY? RET C ; NO, ALL DONE JR Z,..S1 ;DON'T MODIFY CP 05FH ;BACKUP? JR Z,..S2 PUSH HL ;SAVE POINTER CALL EXF ;GET NEW VALUE POP DE ;VALUE IN EE POP HL LD (HL),E ;MODIFY LD A,B ;TEST DELIMITER CP CR RET Z ;DONE ..S1: INC HL ..S3: LD A,L ;SEE IF TIME TO CRLF AND 7 CALL Z,LFADR ;TIME TO CRLF JR ..S0 ..S2: DEC HL ;DECREMENT POINTER JR ..S3 ;AND PRINT DATA THERE. ; ; THIS ROUTINE TRANSLATES THE DATA IN ; MEMORY TO AN ASCII FORMAT. ALL NON- ; PRINTING CHARACTERS AREE CONVERTED TO ; PERIODS. [.] ; THERE ARE 64 CHARACTERS PER LINE. ; TYPE: CALL EXLF ;DISPLAY RANGE ..T0: CALL LFADR ;DISPLAY ADDRESS LD B,64 ;CHARACTERS PER LINE ..T1: LD A,(HL) AND 7FH ;KILL PARITY BIT CP ' ' ;RANGE TEST JR NC,..T3 ;=>SPACEE ..T2: LD A,'.' ;REPLACE NON-PRINTING ..T3: CP 07CH ;ABOVE LOWER CASE z JR NC,..T2 LD C,A ;SEND IT CALL CO CALL HILOX ;MORE TO GO? DJNZ ..T1 ;SEE FI TIME TO CRLF JR ..T0 ;YES ; ; THIS IS A HEXADECIMAL SEARCH ROUTINE. IT ; TAKES NO ADDRESS PARAMETERS. AS MANY ; BYTES MAY BE ENTERED, SEPERATED BY A COMMA, ; AS DESIRED. THE MAXIMUM IS 255, BUT 3-4 IS ; TYPICAL, AND MORE THAN 12 WOULD BE UNUSUAL. ; THE ENTIRE MEMORY IS SEARCHED STARTING ; FROM ZERO, AND ALL STARTING ADDRESSES OF EACH ; OCCURANCE OF THE SEARCH STRING ARE PRINTED ; ON THE CONSOLE DEVICE. ; WHERE: LD D,0 ;COUNT SEARCH STRING ...W0: CALL EXPR1 ;GET ONE BYTE POP HL ;PICK IT UP LD H,L ;STICK IN HIGH BYTE PUSH HL ;PUT IT IN STACK INC SP ;ADJUST STACK INC D ;COUNT UP LD A,B ;TEST DELIMITER SUB CR JR NZ,...W0 ;MORE TO GO LD B,A ;CHEAP ZEROS LD C,A LD H,A LD L,D ;GET BYTE COUNT IN L DEC L ;-1 ADD HL,SP ;BYTES STORED IN STACKK PUSH HL PUSH BC FINDC: PUSH BC ;SAVE THAT POINTER CALL CRLF POP BC ;RESTORE FIND: POP HL ;HL=SEARCH ADDR POP IX ;X=SEARCH BYTE POINTER LD E,D ;RESET COUNTER LD A,(IX) ;GET THE FIRST SEARCH BYTE CPIR ;COMPARE, INCR., & REPEAT JP PO,DONE ;ODD PARITY=DONE PUSH IX ;SAVE POINTERS PUSH HL FOUND: DEC E JR Z,TELL ;FOUND ALL LD A,(IX-1) ;LOOK AT NEXT MATCH CP (HL) ;TEST NEXT JR NZ,FIND ;NO MATCH INC HL ;BUMP POINTER DEC IX JR FOUND ;TEST NEXT MATCH TELL: POP HL PUSH HL DEC HL PUSH BC ;SAVE SEARCH COUNT LIMIT CALL LADR ;TELL CONSOLE POP BC ;RESTORE JR FINDC DONE2: INC SP DEC E ;RESET STACK JR NZ,DONE2 RET ; ; THIS ROUTINE DUMPS MEMORY IN THE STANDARD ; INTEL HEX-FILE FORMAT. A START & END ; PARAMETER IS REQUIRED. AT THE CONCLUSION ; OF THE DUMP, AND "END OF FILE" SHOULD BE ; GENERATED WITH THE "E" COMMAND. ; WRITE: CALL EXLF ;GET TWO PARAMETERS CALL WAIT ;PAUSE IF TTY CONFIGURATION ..W0: CALL PEOL ;CRLF TO PUNCH LD BC,':' ;START OF FILE CALL PUO ;PUNCH IT PUSH DE ;SAVE PUSH HL ;POINTERS ..W1: INC B ;CALCULATE FILE LENGTH CALL HILO JR C,..W4 ;SHORT FILE LD A,24 ;24 BYTES PER FILE SUB B ;ENOUGH YET? JR NZ,..W1 ; NO. POP HL ;GET START ADDR BACK. CALL ..W2 ;SEND THE BLOCK POP DE ;RESTORE END OF FILE POINTER JR ..W0 ;KEEP GOING ..W2: LD D,A ;INITIALIZE CHECKSUM LD A,B ;FILE LENGTH CALL PBYTE ;PUNCH IT CALL PADR ;PUNCH ADDRESS XOR A ;FILE TYPE=0 CALL PBYTE ;PUNCH IT ..W3: LD A,(HL) ;GET A DATA BYTE CALL PBYTE ;PUNCH IT INC HL ;POINT TO NEXT BYTE DJNZ ..W3 ;DECREMENT FILE COUNT XOR A SUB D ;CALCULATE CHECKSUM JP PBYTE ;PUNCH IT, RETURN ..W4: POP HL ;CLEAR STACK POP DE ; OF POINTERS XOR A ;SET UP A JR ..W2 ;FINISH UP & RETURN ; ; ; THIS ROUTINE ALLOWS DISPLAYING THE ; USER'S CPU REGISTERS. THEY ALSO MAY BE ; USING THE REGISTER NAME AFTER TYPEINT THE "X". ; I.E. XA 00- ; THE REGISTER MAY BE SKIPPED OVER, OR MODIFIED, ; SIMILARLY TO THE "S" COMMAND. ; ; TO DISPLAY THE "NORMAL" SYSTEM STATUS, ; SIMPLY TYPE "X[CR]". TO DISPLAY THE ; ADDISTIONAL Z-80 REGISTERS, FOLLOW ; THE "X" WITH AN APOSTROPHE. I.E. "X'[CR]", ; OR TO EXAMINE A SINGLE "PRIME" REGISTER, ; TYPE THE REGISTER IDENTIFIER AFTER THE ; APOSTROPHE. I.E. X'X 0000- ; ; THESE REGISTER VALUES ARE PLACED INTO THE CPU ; UPON EXECUTING ANY "GO" COMMAND. [G] ; XAM: CALL TI LD HL,ACTBL CP CR ;FULL REG. DISPLAY JR Z,..X6 CP 2CH ;SEE IF PRIMES WANTED JR NZ,..X0 LD HL,PRMTB CALL TI CP CR ;FULL REG. DISPLAY JR Z,..X6 ..X0: CP (HL) ;TEST FOR REGISTER NAME JR Z,..X1 BIT 7,(HL) ;SEE IF END OF TABLE JP NZ,ERROR INC HL INC HL JR ..X0 ..X1: CALL BLK ..X2: INC HL LD A,(HL) LD B,A ;SAVE FOR FLAGS AND 3FH ;CLEAR FLAGS FOR BIAS EX DE,HL LD L,A ;DISPLACEMENT FROM STACK LD H,0 ADD HL,SP EX DE,HL INC HL LD A,(DE) ;PICK UP REG. VALUE CALL LBYTE ;PRINT IT BIT 7,B JR Z,..X3 DEC DE LD A,(DE) CALL LBYTE ..X3: CALL COPCK ;MODIFY RET C ;CR ENTERED, ALL DONE JR Z,..X5 ;SKIP TO NEXT REG. PUSH HL PUSH BC CALL EXF ;GET NEW VALUE POP HL POP AF PUSH BC PUSH AF LD A,L LD (DE),A POP BC BIT 7,B ;SEE IF 8 BIT OR 16 BIT REG. JR Z,..X4 ;8 BIT INC DE LD A,H ;HIGH BYTE OF 16 BIT REG. LD (DE),A ..X4: POP BC POP HL LD A,B ;TEST DELIMITER CP CR RET Z ;CR ENTRED, ALL DONE ..X5: BIT 7,(HL) ;SEE IF END OF TABLE RET NZ ;RETURN IF SO JR ..X2 ..X6: CALL CRLF ..X7: CALL BLK LD A,(HL) INC HL OR A RET M LD C,A CALL CO LD C,'=' CALL CO LD A,(HL) LD B,A ;SAVE FLAGS AND 3FH ;CLEAR UP FOR OFFSET INC HL EX DE,HL LD L,A LD H,0 ADD HL,SP EX DE,HL BIT 6,B ;TEST FOR SPECIAL "M" JR NZ,..X9 ;PRINT OUT ACTUAL "M" LD A,(DE) CALL LBYTE ;PRINT REG. VALUE BIT 7,B ;SINGLE OR DOUBLE? JR Z,..X7 ;SINGLE. DEC DE LD A,(DE) ..X8: CALL LBYTE JR ..X7 ..X9: PUSH HL ;SAVE HL LD A,(DE) ;GET REG. POINTER LD H,A ;HIGH BYTE DEC DE LD A,(DE) LD L,A ;LOW BYTE LD A,(HL) ;GET VALUE POP HL ;RESTORE HL JR ..X8 ;PRINT VALUE & CONTINUE ; ; THIS IS A MESSAGE OUTPUT ROUTINE. ; IT IS USED BY THE SIGN-ON AND THE CRLF. ; POINTER IS IN HL (WHEN ENTERED AT ; TOM1) AND LENGTH IN B REG. ; TOM: LD HL,MSG TOM1 LD C,(HL) ;GET A CHARACTER INC HL ;MOVE POINTER CALL CO ;OUTPUT IT DJNZ TOM1 ;KEEP GOILG TILL B=0 CALL CSTS ;SEE IF AN ABORT REQUEST OR A ; WAITING RET Z ;NO. ; ; SEE IF CONTROL-C IS WAITING ; ABMRT IF SO. CCHK: CALL KI CP 3 ;CONTROL-C? RET NZ ; ; SYSTEM ERROR ROUTINE. THIS ; WILL RESTORE THE SYTEM AFTER ; A SYSTEM ERROR HAS BEEN TAKEN. ; THE I/O CONFIGURATION IS NOT ; AFFECTED. ; ERROR: CALL MEMSIZ LD DE,-22 ;STACK POINTER OFFSET ADD HL,DE LD SP,HL LD C,'*' ;ANNOUNCE ERROR CALL CO JP START ;BACK TO WORK ; ; THIS GETS A READER CHARACTER, ; AND COMPARES IT WITH THE 'D' REG. ; IT ABORTS ON AND 'OUT-OF-DATA' ; CONDITION. ; RIFF: CALL RI ;GET READER CHARACTER JR C,ERROR ;ABORT ON CARRY CP D ;TEST D RET ; ; THIS ROUTINE WILL RETURN THE ; CURRENT VALUE OF THE HIGHEST ; READ/WRITE MEMORY LOCATION THAT ; IS AVAILABLE ON THE SYSTEM. ; IT WILL "SEARCH" FOR MEMORY ; STARTING AT THE BOTTOM OF MEMORY ; AND GO UPWARDS UNTIL NON-R/W MEMORY ; IS FOUND. ; SIZE: CALL MEMSIZ ;GET THE VALUE LD BC,ENDX-EXIT ADD HL,BC ;ADJUST IT ; ; ; CRLF BEFORE HLSP ROUTINE ; LFADR: CALL CRLF ; ; PRINT THE CURRENT VALUE OF H&L, ; AND A SPACE. ; HLSP: CALL LADR ; ; PRINT A SPACE ON THE CONSOLE ; BLK: LD C,' ' ; ; THIS IS THE MAIN CONSOLE ; OUTPUT ROUTINE ; CO: CALL IOCHK AND NOT CMSK JR NZ,CO0 ; ; TELEPRINTER CONFIGURATION ; I/O DRIVER. ; TTYOUT: IN A,TTS AND TTYBE JR Z,TTYOUT ; WW: NZ -> Z LD A,C OUT TTO,A RET CO0: DEC A ;CCRT? JR NZ,CO1 ; NO. ; ; C.R.T. CONFIGURATION DRIVER. ; CRTOUT: IN A,CRTS AND CRTBE JR NZ,CRTOUT LD A,C OUT CRTO,A RET ; CO1: DEC A ;BATCH JP NZ,COLOC ; NO, MUST BE USER ; ; LIST OUTPUT DRIVER ROUTINE ; -A USER VECTORED ROUTINE, USED ; BYT THE ASSEMBLER, ETC. ALSO, ; WHEN THE ASSIGNED MODE IS "BATCH", ; THIS IS THE ROUTINE USED FOR THE ; MONITOR OUTPUT THAT WOULD NORMALLY ; GO TO THE "CONSOLE". ; LO: CALL IOCHK AND NOT LMSK JR Z,TTYOUT CP LCRT JR Z,CRTOUT CP LINE JP Z,LNLOC ;EXTERNAL VECTOR JP LULOC ;USER DEFINED VECTOR ; ; SEND CRLF TO PUNCH DEVICE ; PEOL: LD C,CR CALL PUO LD C,LF ; ; PUNCH OUTPUT DRIVER ROUTINE ; PUO: CALL IOCHK AND NOT PMSK JR Z,TTYOUT ;PUNCH=TELEPRINTER CP PCAS ;CASSETTE? JR NZ,PO1 ; NO. ; PO0: IN A,PCASS AND PCSBE JR NZ,PO0 LD A,C OUT PCASO,A RET ; PO1: CP PPTP JP Z,PTPL ;EXTERNAL VECTOR JP PULOC ;USER VECTOR ; ; ; THIS IS A BINARY DUMP ROUTINE THAT MAY BE ; USED WITH BOTH PAPER-TAPE AND/OR CASSETTE ; SYSTEMS. IT PUNCHES A START-OF-FILE MARK ; AND THEN PUNCHES IN FULL 8-BITS DIRECTLY ; FROM MEMORY. IT IS FOLLOWED BY AN END-OF- ; FILE MARKER. THESE DUMPS MAY BE LOADED ; USING THE "L" COMMAND. THEY ARE USEFUL ; FOR FAST LOADING, AND MAY BE VERIFIED ; USING THE "C" (COMPARE) COMMAND. ; ; U,[CR] ; PUNCHES FROM THRU ; UNLD: CALL EXLF ;GET TWO PARAMETERS CALL WAIT ;PAUSE FOR PUNCH-ON (TTY) CALL LEAD ;PUNCH LEADER CALL MARK ;PUNCH FILE MARKER ..U: LD C,(HL) ;GET MEMORY BYTE CALL PUO ;PUNCH IT CALL HILO ;SEE IF DONE JR NC,..U CALL MARK ;PUNCH END OF FILE MARKER ; ; THIS PUNCHES NULLS (LEADER/TRAILER). ; IT RETURNS "QUIET" IN CASE THE PUNCH ; AND CONSOLE ARE THE SAME. ; NULL: CALL LEAD ;PUNCH NULLS ; ; THIS ROUTINE WILL PAUSE FOR ; A KEYBOARD CHARACTER. IT IS ; USED AS A DELAY TO GIVE THE ; OPERATOR TIME TO TURN ON THE ; TELEPRINTER PUNCH BEFORE SENDING ; A HEX FILE OR BINARY FILE TO ; THE PUNCH. IT WIL SIMPLY ; RETURN IF THE PUNCH & CONSOLE ; ARE NO BOTH ASSIGNED TO THE ; DEFAULT. (TELEPRINTER) ; WAIT: CALL IOCHK AND ~CMSK | ~PMSK ; WW: WAS "AND NOT CMSK OR NOT PMSK" RET NZ JP STARO ;RETURN "QUIET" ; ; CONVERT HEX TO ASCII ; CONV: AND 0FH ;LOW NIBBLE ONLY ADD 90H DAA ADC 40H DAA LD C,A RET ; ; GET TWO PARAMETERS, PLACE ; THEM IN DE & HL, AND THEN ; CRLF. ; EXLF: CALL EXPR POP DE POP HL ; ; CONSOLE CARRIAGE RETURN & ; LINE FEED ROUTINE. ; ; THE NUMBER OF FILL CHARACTERS ; MAY BE ADJUSTED TO 0-3 BY THE ; VALUE PLACED IN THE B REG. MINIMUM ; VALUE FOR "B" IS TWO (2). MAXIMUM ; IS FIVE (5). ; CRLF: PUSH HL ;SAVE HL ;WW LD B,4 ;CRLF LENGTH (SET FOR 2 FILLS) LD B,2 ; WW - CHANGE TO ZERO FILLS CALL TOM ;SEND CRLF POP HL RET ; ; I ; TEST THE CURRENT CONSOLES ; KEYBOARD FOR A KEY-PRESS ; RETURN TRUE (0FFH IN A REG) ; IF THERE IS A CHARACTER ; WAITING IN THE UART. ; CSTS: CALL IOCHK AND NOT CMSK JR NZ,CS0 IN A,TTS JR CS1 CS0: DEC A ;CCRT JR NZ,CS3 IN A,CRTS CS1: AND TTYDA LD A,FALSE CS2: RET Z ; WW: NZ -> Z CPL RET CS3: DEC A ;BATCH RET Z JP CSLOC ;USED DEFINED FUNCTION ; ; GET THREE PARAMETERS AND ; CRLF. ; EXPR3: INC C CALL EXPR CALL CRLF POP BC POP DE POP HL RET ; ; GET ONE PARAMETER. ; NO CRLF. ; EXPR1: LD C,1 ; ; THIS IS THE MAIN "PARAMETER-GETTING" ROUTINE. ; THIS ROUTINE WILL ABORT ON A NON-HEX CHARACTER. ; IT TAKES THE MOST RECENTELY TYPED FOUR VALID ; HEX CHARACTERS, AND PLACES THEM UP ON THE STACK. ; (AS ONE 16 BIT VALUE, CONTAINED IN TWO ; 8-BIT BYTES.) IF A CARRIAGE RETURN IS ENTERED, ; IT WILL PLACE THE VALUE OF "0000" IN THE STACK. ; EXPR: LD HL,0 ;INITIALIZE HL TO ZERO EX0: CALL TI ;GET SOMETHING FROM CONSOLE EX1: LD B,A ;SAVE IT CALL NIBBLE ;CONVERT ASCII TO HEX JR C,..EX2 ;ILLEGAL CHARACTER DECTECTED ADD HL,HL ;MULTIPLY BY 16 ADD HL,HL ADD HL,HL ADD HL,HL OR L ;OR IN THE SINGLE NIBBLE LD L,A JR EX0 ;GET SOME MORE ..EX2: EX (SP),HL ;SAVE UP IN STACK PUSH HL ;REPLACE THE RETURN LD A,B ;TEST THE DELIMITER CALL QCHK JR NC,..EX3 ;CR ENTERED DEC C ;SHOULD GO TO ZERO RET Z ; RETURN IF IT DOES ..EX3: JP NZ,ERROR ;SOMETHING WRONG DEC C ;DO THIS AGAIN? JR NZ,EXPR ; YES. RET ;ELSE RETURN EXF: LD C,1 LD HL,0 JR EX1 ; ; RANGE TESTING ROUTINES. ; CARRY SET INDICATES RANGE EXCEEDED. ; HILOX: CALL HILO RET NC ;OK POP DE ;RETURN ONE LEVEL BACKK RET ; HILO: INC HL ;INCREMENT HL LD A,H ;TEST FOR CROSSING 64K BORDER OR L SCF ;CARRY SET=STOP RET Z ;YES, BORDER CROSSED LD A,E ;NOW, TEST HL VS. DE SUB L LD A,D SBC H RET ;IF CARRY WAS SET, THEN STOP ; ; HEXADECIMAL MATH ROUTINE ; ; THIS ROUTINE IS USEFUL FOR ; DETERMINING RELATIVE JUMP ; OFFSETS. IT RETURNS THE SUM ; & DIFFERENCE OF TWO PARAMETERS. ; ; H, ; ; X+Y X-Y ; HEXN: CALL EXLF PUSH HL ;SAVE HL FOR LATER ADD HL,DE ;GET SUM CALL HLSP ;PRINT IT POP HL ;THIS IS LATER OR A ;CLEAR CARRY SBC HL,DE ;GET DIFFERENCE & PRINT IT ; ; PRINT H&L ON CONSOLE ; LADR: LD A,H CALL LBYTE LD A,L LBYTE: PUSH AF RRCA RRCA RRCA RRCA CALL ..2 POP AF ..2: CALL CONV JP CO ; THIS ROUTINE SENDS EIGHT RUBOUTS ; TO THE PUNCH DEVICE. ; MARK: LD BC,08FFH ;SET-UP B&C JR LE0 ; ; THIS ROUTINE SENDS BLANKDS TO THE ; PUNCH DEVICE. ; LEAD: LD BC,4800H ;PRESET SOME NULLS LE0: CALL PUO DJNZ LE0 RET ; ; THIS ROUTINE RETURNS TO A USER ; PROGRAM THE CURRENT TOP OF ; MEMORY VALUE MINUS WORKSPACE ; AREA USED BY THE MONITOR. ; MEMCK: PUSH HL CALL MEMSIZ LD A,L SUB 2CH JR NC,...B DEC H ...B: LD B,H POP HL RET ; ; THIS IS A CALLED ROUTINE USED ; TO CALCULATE THE TOP OF MEMORY ; STARTING FROM THE BOTTOM OF ; MEMORY, AND SEARCHING UPWARD UNTIL ; FIRST R/W MEMORY IS FOUND, AND THEN ; CONTINUING UNTIL THE END OF THE R/W ; MEMORY. THIS ALLOWS R.O.M. AT ZERO, ; AND INSURES A CONTINUOUS MEMORY BLOCK ; HAS BEEN FOUND. ; IT IS USED BY THE ERROR ROUTINE TO ; RESET THE STACK POINTER AS WELL. ; MEMSIZ: PUSH BC ;WW LD BC,BASE ;POINT TO START OF MONITOR ;WW LD HL,-1 ;RAM SEARCH STARTINT PT. ;WW..M0: INC H ;FIRST FIND R/W MEMORY ;WW LD A,(HL) ;WW CPL ;WW LD (HL),A ;WW CP (HL) ;WW CPL ;WW LD (HL),A ;WW JR NZ,..M0 ;WW..M1: INC H ;R/W FOUND, NOW FIND END ;WW LD A,(HL) ;WW CPL ;WW LD (HL),A ;WW CP (HL) ;WW CPL ;WW LD (HL),A ;WW JR NZ,..M2 ;WW LD A,H ;TEST FOR MONITOR BORDER ;WW CP B ;WW JR NZ,..M1 ;NOT THERE YET ;WW..M2: DEC H ;BACK UP, SUBTRACT WORKSPACE LD HL,$EFFF ; WW - FIXED TOP OF MEMORY AT $F000 LD BC,EXIT-ENDX ADD HL,BC POP BC ;RESTORE BC RET ;VALUE IN HL ; ; RIBBLE: CALL RIX NIBBLE: SUB '0' ;QUALIFY & CONVERT RET C ;<0 CP 'G'-'0' ;>F? CCF ;PERVERT CARRY RET C CP 10 ;NMBR? CCF ;PERVERT AGAIN RET NC ;RETURN CLEAN SUB 'A'-'9'-1 ;ADJUST CP 0AH ;FILTER ":" THRU "@" RET ; ; SEND H&L VALUE TO PUNCH DEVICE ; PADR: LD A,H CALL PBYTE LD A,L ; ; PUNCH A SINGLE BYTE ; PBYTE: PUSH AF ;NIBBLE AT A TIME RRCA RRCA RRCA RRCA CALL CONV CALL PUO POP AF ;NEXT NIBBLE PUSH AF ;SAVE FOR CHECKSUM CALL CONV CALL PUO POP AF ;ORIGINAL BYTE HERE ADD D ;ADDED TO CHECKQUM LD D,A ;UPDATE CHECKSUM RET ; ; COPCK: LD C,'-' CALL CO ; PCHK: CALL TI ; ; TEST FOR DELIMITERS ; QCHK: CP ' ' ;RETURN ZERO IF DELIMITER RET Z CP ',' RET Z CP CR ;RETURN W/CARRY SET IF CR SCF RET Z CCF ;ELSE NON-ZERO, NO CARRY RET ; ; MAIN CONSOLE INPUT ROUTINE ; CI: CALL IOCHK AND ~CMSK ; WW: WAS "NOT CMSK" JR NZ,CI1 ; ; TELEPRINTER ROUTINE ; TTYIN: IN A,TTS AND TTYDA JR Z,TTYIN IN A,TTI RET ; CI1: DEC A ;CONSOLE=CRT? JR NZ,CI2 ; ; C.R.T. INPUT ROUTINE ; CRTIN: IN A,CRTS AND CRTDA JR Z,CRTIN IN A,CRTI RET ; CI2: DEC A ;BATCH? JP NZ,CILOC ;NO, MUST BE USER DEFINED ; ; ; READER INPUT ROUTINE, WITH ; TIME-OUT DELAY. INCLUDES ; PULSING OF HARDWARE PORT ; TO INDICATE REQUEST FOR ; READER DATA. ; RI: PUSH HL CALL IOCHK AND NOT RMSK ;WW CPL ;WW OUT RCP,A ;PULSE READER CONTROL PORT ;WW CPL ;CLEEAR IT ;WW OUT RCP,A JR NZ,RI3 ;NOT TTY LD H,A ;CLEAR FOR-TIME OUT TEST RI0: IN A,TTS AND TTYDA JR NZ,RI2 ; WW: Z -> NZ PUSH BC LD B,0 DL0: EX (SP),HL ;WASTE TIME EX (SP),HL ;FOR DELAY DJNZ DL0 POP BC DEC H ; JR NZ,RI0 ; WW JR RI0 ; WW - ELIMINATE TIMEOUT RI1: XOR A SCF POP HL RET RI2: IN A,TTI RID: OR A POP HL RET RI3: CP RCAS JR NZ,RI6 ;WW IN A,SWITCH ;READ INITIAL SENSE CONDX. ;WW LD L,A RI4: ;WW IN A,SWITCH ;SEE IF SW. ALTERED ;WW CP L ;WW JR NZ,RI1 ;ABORT IF SO IN A,RCSS AND RCSDA ;DATA YET? JR NZ,RI4 ;KEEP LOOKING RI5: IN A,RCSD JR RID RI6: POP HL CP RPTR JP Z,RPTPL ;EXTERNAL ROUTINE JP RULOC ;USER VECTOR ; ; THIS ROUTINE GETS READER INPUT ; AND KILLS THE PARITY BIT. ; RIX: CALL RIFF AND 7FH RET ; ; THIS ROUTINE READS A BINARY FILE ; IMAGE, IN THE FORM AS PUNCHED IN ; THE "U" (UNLOAD) COMMAND. IT TAKES ; ONE PARAMETER, WHICH IS THE STARTING ; ADDRESS OF THE LOAD, AND WILL PRINT ; THE LAST ADDRESS (+1) LOADED ON THE ; CONSOLE DEVICE. ; LOAD: CALL EXPR1 ;INITIAL LOAD ADDRESS POP HL CALL CRLF LD D,0FFH ;START-OF-FILE TAB ...L0: LD B,4 ;FIND AT LEAST FOUR 0FFH'S ...L1: CALL RIFF JR NZ,...L0 DJNZ ...L1 ...L2: CALL RIFF ;4 FOUND, NOW WAIT FOR NON-0FFH JR Z,...L2 LD (HL),A ;FIRST REAL DATA BYTE LD A,BELL ;TELL TTY OUT TTO,A ...L3: INC HL CALL RIFF JR Z,..EL ;POSSIBLE END OF FILE LD (HL),A JR ...L3 ..EL: LD E,1 ;INITIALIZE ..EL0: CALL RIFF JR NZ,..EL1 INC E ;COUNT QUES LD A,MAX ;LOOK FOR EOF CP E ;FOUND MAX? JR NZ,..EL0 ;NOPE JP LADR ;YEP, PRINT END ADDR ..EL1: LD (HL),D INC HL DEC E ;RESTORE JR NZ,..EL1 LD (HL),A ;REAL BYTE JR ...L3 ; ; THIS IS THE BREAKPOINT "TRAP" HANDLING ; ROUTINE. ALL USER REGISTERS ARE SAVED ; FOR DISPLAY PURPOSES, AND THE CONTENTS ; ARE RESTORED WHEN EXECUTING A "GO" (G) ; COMMAND. ; RESTART: PUSH HL ;PUSH ALL REGISTERS PUSH DE PUSH BC PUSH AF CALL MEMSIZ ;GET MONITOR'S STACK VALUE EX DE,HL LD HL,10 ;GO UP 10 BYTES IN STACK ADD HL,SP LD B,4 ;PICK OFF REG. EX DE,HL ...R0: DEC HL LD (HL),D ;SAVE IN WORKAREA DEC HL LD (HL),E POP DE DJNZ ...R0 POP BC DEC BC ;ADJUST P.C. VALUE LD SP,HL ;SET MONITOR STACK LD HL,TLOCX ADD HL,SP LD A,(HL) SUB C ;LOOK FOR A TRAP/MATCH INC HL JR NZ,..R1 LD A,(HL) SUB B JR Z,..R3 ;NO TRAP HERE ..R1: INC HL INC HL LD A,(HL) SUB C ;TEST FOR SECOND TRAP JR NZ,..R2 INC HL LD A,(HL) SUB B JR Z,..R3 ..R2: INC BC ;NO TRAPS SET, RE-ADJUST P.C. ..R3: LD HL,LLOCX ADD HL,SP LD (HL),E ;STORE USER H&L INC HL LD (HL),D INC HL INC HL LD (HL),C ;AND USER P.C. INC HL LD (HL),B PUSH BC LD C,'@' ;DISPLAY BREAK ADDRESS. CALL CO POP HL CALL LADR LD HL,TLOCX ADD HL,SP LD BC,200H ..R4: LD E,(HL) ;REPLACE BYTES TAKEN FOR TRAP LD (HL),C ;ZERO OUT STORAGE AREA INC HL LD D,(HL) LD (HL),C INC HL LD A,E OR D ;DO NOTHING IF ZERO JR Z,..R5 LD A,(HL) LD (DE),A ;STORE BYTE ..R5: INC HL ;SAME THING DJNZ ..R4 ;FOR OTHER BREAKPOINT EX AF,AF' ;GET ALTERNATE SET OF REG.'S EXX PUSH HL ;AND STORE IN WORKSPACE PUSH DE PUSH BC PUSH AF PUSH IX PUSH IY LD A,I ;GET INTERUPT VECTOR BYTE LD B,A LD A,R ;GET REFRESH BYTE LD C,A PUSH BC ;SAVE JP START ;BACK TO START ; ; THIS IS THE INTERNAL KEYBOARD ; HANDLING ROUTINE. IT WILL IGNORE ; RUBOUTS (0FFH) AND BLANKS (00), ; AND IT WILL NOT ECHO CR'S & N'S. ; (NO N'S FOR THE "NULL" COMMAND). ; IT CONVERTS LOWER CASE TO UPPER ; CASE FOR THE LOOK-UP OF COMMANDS. ; ; OTHER CHARACTERS ARE ECHOED AS THEY ; ARE RECEIVED. ; KI: CALL CI ;GET CHARACTER FROM CONSOLE AND 7FH ;CLEAR PARITY BIT RET ; TI: CALL KI INC A ;IGNORE RUBOUTS RET M DEC A ;IGNORE NULLS RET Z CP 'N' ;IGNORE N'S FOR NULL CMND RET Z CP 'n' JR Z,..T CP CR ;IGNORE CR'S RET Z PUSH BC LD C,A CALL CO LD A,C POP BC CP 'A'-1 ;CONVERT TO UPPER CASE RET C CP 'z'+1 RET NC ..T: AND 05FH RET ; ; THIS ROUTINE ALLOWS EXAMINATION OF ; ANY INPUT PORT, OR THE SEENDING OF ; ANY VALUE TO ANY PORT. ; ; QO,[CR] ; OUTPUT TO PORT , THE VALUE ; ; QI[CR] ; DISPLAY THE PORT ; QUERY: CALL TI CP 'O' JR Z,QUO CP 'I' JP NZ,ERROR CALL EXPR1 POP BC IN E,(C) BITS: LD B,8 ;DISPLAY 8 BITS CALL BLK ..Q2: SLA E LD A,'0'>>1 ; WW: WAS "LD A,'0' >1" ADC A ;MAKE "0" OR "1" LD C,A CALL CO DJNZ ..Q2 RET QUO: CALL EXPR POP DE POP BC OUT (C),E RET ; ; THIS ROUTINE VERIFIES THE CONTENTS ; OF ONE MEMORY BLOCK WITH ANOTHER. ; ; V,, ; VERIFY FROM <1> THRU <2> WITH ; THE CONTENTS OF MEMORY BEGINNING AT <3> ; VERIFY: CALL EXPR3 ;GET 3 PARAMENTERS VERI0: LD A,(BC) CP (HL) JR Z,..B PUSH BC CALL CERR ;DISPLAY ERRORS POP BC ..B: INC BC CALL HILOX JR VERI0 ; ; ; ; THE FIRST CHARACTER IS THE DEVICE NAME ; (ONE LETTER) AND THE NEXT FOUR ARE THE ; NAMES OF THE FOUR POSSIBLE DRIVERS TO BE ; ASSIGNED. ; LTBL: DB 'C' ;CONSOLE ASSIGNMENTS DB 'T' ;CTTY T=TELEPRINTER DB 'C' ;CCRT C=CRT (VIDEO MONITOR) DB 'B' ;BATCH= COMMANDS FROM READER DB 'U' ;CUSE USER ; DB 'R' ;READER ASSIGNMENTS DB 'T' ;RTTY DB 'P' ;RPTR P=PAPER TAPE DB 'C' ;RCAS C=CASSETTE DB 'U' ;RUSER USER ; DB 'P' ;PUNCH ASSIGNMENTS DB 'T' ;PTTY DB 'P' ;PPTP DB 'C' ;PCAS C=CASSETTE DB 'U' ;PUSER USER ; DB 'L' ;LIST ASSIGNMENTS DB 'T' ;LTTY LIST=TELEPRINTER DB 'C' ;LCRT LIST=CRT DB 'L' ;LINE PRINTER DB 'U' ;LUSER USER ; ; ; THIS IS A SHORT PROGRAM, EXECUTED ; UPON EXECUTING A "GO" COMMAND. IT ; IS PLACED IN THE WORK AREA WHEN ; THE MONITOR IS INITIALIZED, AS IT ; :REQUIRES RAM FOR PROPER OPERATION. ; EXIT: ;EXIT ROUTINE (LOADS ALL REGISTERS) 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 EX AF,AF' EXX POP DE POP BC POP AF POP HL LD SP,HL NOP ;RESERVED FOR ENABLE INTERUPTS LD HL,0 JP 0 ; DW 0 ;STORAGE AREA FOR TRAP DATA DB 0 DW 0 DB 0 ; ; DISPLACEMENTS OF REGISTER ; STORAGE FROM NORMAL STACK ; LOCATION. ; ENDX: ; 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 09H BPLOC: EQU 0BH CPLOC: EQU 0AH DPLOC: EQU 0DH EPLOC: EQU 0CH FPLOC: EQU 08H HPLOC: EQU 0FH LPLOC: EQU 0EH XLOC: EQU 07 YLOC: EQU 05 RLOC: EQU 02 ILOC: EQU 03 ; ; ; THIS IS THE TABLE USED TO DETERMINE ; A VALID REGISTER IDENTIFIER, AND IT'S ; DISPLACEMENT FROM THE STACK POINTER. ; ; POSITION ONE= REGISTER NAME, WITH BIT 7 INDICATING ; END OF TABLE. ; ; POSITION TWO= BIAS FROM CURRENT STACK LEVEL OR'ED ; WITH A TWO-BIT FLAG. 00XXXXXX=BYTE ; 10XXXXXX=WORD ; 11XXXXXX=SPECIAL FOR "M" REG. ; ACTBL: ;NORMAL SET OF REGISTERS (8080) ; ;PLUS THE INTERUPT REGISTER ("I") ; DB 'A',ALOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'B',BLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'C',CLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'D',DLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'E',ELOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'F',FLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'H',HLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'L',LLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'M',HLOC | 0C0H ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'P',PLOC | 080H ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'S',SLOC | 080H ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'I',ILOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM ; ; DB " RWA" ; PRMTB: ;ADDITIONAL SET OF REGISTERS (Z-80) ; DB 'A',APLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'B',BPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'C',CPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'D',DPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'E',EPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'F',FPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'H',HPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'L',LPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'M',HPLOC | 0C0H ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'X',XLOC | 080H ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'Y',YLOC | 080H ; WW: REPLACED "OR" WITH "|" FOR TASM DB 'R',RLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM DB 0C1H ; Z: ;WW END