Files
Digital-Research-Source-Code/CONTRIBUTIONS/MOSS 2.2/8800-Manual/MOSS22.TXT
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

1529 lines
52 KiB
Plaintext

;
;CP/M MACRO ASSEM 2.0 #001 MOSS 2.2 MONITOR
;
TITLE 'MOSS 2.2 MONITOR'
PAGE 68
MACLIB Z80
;
.8080
; MOSS MONITOR (VERSION 2.2)
;
; 20 JUNE 1980
; ALL RIGHTS RESERVED BY ROBERT B. MASON
;
; OCR PDF Document 09-20-2014 by Larry Kraemer
;
F000 MOSS ORG 0F000H
F000 ROM EQU 0F000H ;ROM START ADDRESS
0000 WSVEC EQU 0 ;VECTOR FOR WARM RESTART
0002 NBKPTS EQU 2 ;NUMBER OF BREAKPOINTS
0013 CTRLS EQU 13H ;ASCII DC3
000D CR EQU 0DH ;ASCII CARRIAGE RETURN
000A LF EQU 0AH ;ASCII LINE FEED
000C FMFD EQU 0CH ;ASCII FORM FEED
0007 BELL EQU 7 ;ASCII CNTRL CHAR TO RING THE BELL
0003 IOBYTE EQU 3 ;ADDRESS OF I/O CONTROL BYTE
0020 SDATA EQU 20H ;SERIAL DATA PORT BASE ADDRESS
0021 SINTEN EQU SDATA+1 ;SERIAL INTERRUPT ENABLE REGISTER
0022 SIDENT EQU SDATA+2 ;SERIAL INTERRUPT IDENTIFICATION REGIS
0023 SLCTRL EQU SDATA+3 ;SERIAL LINE CONTROL REGISTER
0024 SMDMCT EQU SDATA+4 ;SERIAL MODEM CONTROL REGISTER
0025 SLSTAT EQU SDATA+5 ;SERIAL LINE STATUS REGISTER
0026 SMDMST EQU SDATA+6 ;SERIAL MODEM STATUS REGISTER
;
;
0006 SPSV EQU 6 ;STACK POINTER SAVE LOCATION
;
;
; REGISTER STORAGE DISPLACEMENTS FROM
; NORMAL SYSTEM STACK LOCATION.
;
0015 = ALOC EQU 15H
0013 = BLOC EQU 13H
0012 = CLOC EQU 12H
0011 = DLOC EQU 11H
0010 = ELOC EQU 10H
0014 = FLOC EQU 14H
0031 = HLOC EQU 31H
0030 = LLOC EQU 30H
0034 = PLOC EQU 34H
0017 = SLOC EQU 17H
0035 = TLOC EQU 35H
0025 = TLOCX EQU 25H
0020 = LLOCX EQU 20H
0009 = APLOC EQU 9
000B = BPLOC EQU 11
000A = CPLOC EQU 10
000D = DPLOC EQU 13
000C = EPLOC EQU 12
0008 = FPLOC EQU 8
000F = HPLOC EQU 15
000E = LPLOC EQU 14
0007 = XLOC EQU 7
0005 = YLOC EQU 5
0002 = RLOC EQU 2
0003 = ILOC EQU 3
;
; JUMP TARGETS FOR BASIC INPUT/OUTPUT
;
F000 C35BF0 CBOOT: JMP INIT ;COLD START
F003 C346F6 CONIN: JMP CI ;CONS0LE INPUT
F006 C356F6 READER: JMP RI ;READER INPUT
F009 C300F6 CONOUT: JMP CO ;CONSOLE OUTPUT
F00C C37CF6 PUNCH: JMP PO ;PUNCH OUTPUT
F00F C310F6 LIST: JMP LO ;LIST OUTPUT
F012 C323F6 CONST: JMP CSTS ;CONSOLE STATUS
F015 C36AF1 JMP IOCHK ;PUT IOBYTE INTO (A)
F018 C365F1 JMP IOSET ;(C) HAS A NEW IOBYTE
F01B C38AF0 JMP MEMCK ;MEMORY LIMIT CHECK
F01E C394F6 JMP RTS ;IODEF- DEFINE USER I/O ENTRY POINTS
F021 C394F6 JMP RTS ;SPCL- I/O CONTROL
F024 C3CFF3 JMP REST ;BREAKPOINT ENTRY POINT
;
; TBL CONTAINS THE ADDRESSES OF THE ACTION ROUTINES
; THE EXECUTIVE USES IT TO LOOK UP THE DESIRED ADDRESS.
F027 F8F0 TBL: DW ASGN
F029 09F1 DW QPRT
F02B 09F1 DW QPRT
F02D ACP1 DW DISP
F02F F6F4 DW EOF
F031 3CF1 DW FILL
F033 FDF1 DW GOTO
F035 D0F5 DW HEXN
F037 4DF2 DW INPT
F039 09F1 DW QPRT
F03B 09F1 DW QPRT
F03D 0EF5 DW LEADER
F03F 5DF2 DW MOVE
F041 09F1 DW QPRT
F043 55F2 DW OUPT
F045 09F1 DW QPRT
F047 21F5 DW QUERY
F049 4CF5 DW READ
F04B 67F2 DW SUBS
F04D 8FF2 DW MTEST
F04F 09F1 DW QPRT
F051 91F1 DW COMP
F053 8DF5 DW WRITE
F055 ECF2 DW XMNE
F057 99F4 DW I8250
F059 82F1 DW BYE
;
; THE COLD INITIALIZATION CODE
;
F05B F3 INIT: DI ;DISABLE INTERRUPTS
F05C 313F00 LXI SP,3FH ;USE STACK TO INITIALIZE RESTARTS
F05F 2100C3 LXI H,JMP*256 ; WITH RESTART ERROR VECTORS
F062 11B2F6 LXI D,RSTER
F065 0610 MVI B,16 ;16 TIMES (64 BYTES)
F067 D5 INIT1: PUSH D
F065 E5 PUSH H
DJNZ INIT1
F069+10FC
F06B 3195F0 LXI SP,FAKE-2 ;SET UP TEMPORARY STACK
F06E 3E00 MVI A,0 ;SKIP THE NEXT INST
F06F ORG $-1 ;SAVE A BYTE HERE
;
; MEMSIZ 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 AND RETURNS THE VALUE IN (H,L).
F06F C5 MEMSIZ: PUSH B ;MOITOR START LOCATION
F070 0100F0 LXI B,ROM
F073 21FFFF LXI H,-1 ;START OF MEMORY ADDRESS SPACE
F076 24 MEMSZ1: INR H
F077 7E MOV A,M
F075 2F CMA
F079 77 MOV M,A
F07A BE CMP M
F07B 2F CMA
F07C 77 MOV M,A
JRNZ MEMSZ2
F07D+2004
F07F 7C MOV A,H ;SEE IF ON MONITOR BORDER
F080 B8 CMP B
JRNZ MEMSZ1
F081+20F3
F083 25 MEMSZ2: DCR H ;TAKE OFF WORKSPACE
F084 01DEFF LXI B,EXIT-ENDX-3*NBKPTS+1
F087 09 DAD B
F088 C1 POP B ;(B,C) IS UNPREDICTABLE DURING INIT
F089 C9 RET
;
; ROUTINE MEMCHK FINDS THE CURRENT TOP OF CONTIGUOUS MEMORY
; (LESS THE MONITOR WORKSPACE) AND RETURNS THE VALUE.
;
F08A E5 MEMCK: PUSH H ;SAVE (H,L)
F08B CD6FF0 CALL MEMSIZ ;GET THE RAM SIZE
F08E 7D MOV A,L
F08F D63C SUI 60 ;TAKE OFF WORK SPACE
JRNC MEMCKO
F091+3001
F093 25 DCR H
F094 44 MEMCKO: MOV B,H
F095 E1 POP H
F096 C9 RET
;
F097 99F0 FAKE: DW FAKE+2
F099 F9 SPHL
F09A 1145F4 LXI D,EXIT
F09D EB XCHG
F09E 011D00 LXI B,ENDX-EXIT
LDIR
F0A1+EDB0
F0A3 010600 LXI B,3*NBKPTS
F0A6 D5 PUSH D
F0A7 E1 POP H
F0A8 2B DCX H
LDIR
F0A9+EDB0
F0AB 21E8FF LXI H,-24
F0AE 39 DAD SP
F0AF E5 PUSH H
F0B0 23 INX H ;ADJUST USER STACK LOCATION
F0B1 23 INX H
F0B2 220600 SHLD SPSV ;SAVE THE STACK INITIAL VALUE
F0B5 160A MVI D,10 ;INITIALIZE REGISTER STORAGE AREA
F0B7 C5 INIT2: PUSH B
F0B8 15 DCR D ;LOOP CONTROL
JRNZ INIT2
F0B9+20FC
; INSERT I/O INIT CODE HERE
F0BB CD94F6 CALL RTS
F0BE CD9FF4 CALL I8250 ;INITIALIZE THE 8250
F0C1 CD94F6 CALL RTS
F0C4 2190F4 LXI H,LOGMSG ;LOG ONTO THE SYSTEM
F0C7 CD95F6 CALL PRTWD
F0CA+1843 JMPR WINIT ;GO TO MONITOR EXECUTIVE
;
; ROUTINE EXF READS ONE PARAMETER. IT EXPECTS THE FIRST
; CHARACTER OF THE PARAMETER TO BE IN THE A REGISTER
; ON ENTRY.
F0CC 0601 EXF: MVI B,1 ;SET UP FOR ONE PARAMETER
F0CE 210000 LXI H,0
JMPR EX1 ;FIRST CHARACTER IN A ALREADY
;
F0DI+180C ; ROUTINE EXPR READS PARAMETERS FROM THE CONSOLE
; AND DEVELOPS A 16 BIT HEXADECIMAL FOR EACH ONE.
; THE NUMBER OF PARAMETERS WANTED IS IN THE B REG
; ON ENTRY. A CARRIAGE RETURN WILL TERMINATE THE
; ENTRY SEQUENCE. A BLANK OR A 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 AND CAUSE A WARM BOOT OF THE MON.
;
AS3: DJNZ AS2 ;PART OF THE ASSIGN CODE
F0D3+ 1079
EX3: JRNZ QPRT ;NON-ZERO IS ERROR
F0D5+2032
F0D7 05 EXPR1: DCR B ;MORE PARAMETERS?
F0D8 C8 RZ ;NO, RETURN
F0D9 210000 EXPR: LXI H,0 ;INITIALIZE PARAMETER
F0DC CD7BF3 EX0: CALL ECHO ;GET NEXT NUMBER
F0DF 4F EX1: MOV C,A ;SAVE CHAR FOR LATER USE
F0E0 CDB0F3 CALL NIBBLE
JRC EX2 ;NOT A NUMBER, JUMP
F0E3+3808
F0E5 29 DAD H ;MULTIPLY BY 16
F0E6 29 DAD H
F0E7 29 DAD H
F0E8 29 DAD H
F0E9 B5 ORA L ;ADD ON NEW DIGIT
F0EA 6F MOV L,A
JMPR EX0 ;GO GET NEXT DIGIT
F0EB+18EF
F0ED E3 EX2: XTHL ;PUT UNDER RETURN ADDRESS ON STACK
F0EE E5 PUSH H ;RESTORE RETURN ADDRESS
F0EF 79 MOV A,C ;REGET THE LAST CHARACTER
F0F0 CDC3F3 CALL P2C ;TEST FOR DELIMITER
JRNC EX3 ;JUMP IF NOT CARRIAGE RETURN
F0F3+30E0
DJNZ QPRT ;CARRET WITH MORE PARAM MEANS ERROR
F0F5+1012
F0F7 C9 RET
;
; MAIN ACTION ROUTINES
;
; LOGICAL ASSIGNMENT OF PERIPHERALS
;
;THIS ROUTINE CONTROLS THE ASSIGNMENT OF PHYSICAL
;PERIPHERALS TO THE FOUR LOGICAL DEVICE TYPES. IT
;ALTERS IOBYTE (MEMORY LOCATION 0003) TO MATCH THE
;CURRENT ASSIGNMENT. THE FOUR LOGICAL DEVICES ARE
;CONSOLE, READER LIST, AND PUNCH. IN ALL CASES,
;THE TTY DEVICE IS SET UP AS THE DEFAULT DEVICE.
;
F0F8 CD7BF3 ASGN: CALL ECHO ;GET THE LOGICAL DEVICE DESIRED
F0FB 216EF1 LXI H,ALT ;START OF CONVERSION TABLE
F0FE 110500 LXI D,APT-ALT ;DISTANCE BETWEEN LOGICAL CHOICE
F101 0604 MVI B,4 ;NUMBER OF LOGICAL CHOICES
F103 BE ASO: CMP M ;IS THS ONE IT?
JRZ AS1 ;YES, JUMP
F104+2842
F106 19 DAD D ;NO, GO TO NEXT LOGICAL ENTRY
DJNZ ASO
F107+10FA
F109 218CF4 QPRT: LXI H,QMSG ;GET ADDRESS OF QUESTION MARK MSG
F10C CD98F6 CALL PRTWA ;PRNT IT
; THE WARM START CODE
F10F 2A0600 WINIT: LHLD SPSV ;RESET THE STACK
F112 F9 SPHL
F113 210FF1 WINITA: LXI H,WINIT ;RESET RETURN AND WARM START VECTOR
F116 E5 PUSH H
F117 220100 SHLD WSVEC+1
F11A 3EC3 MVI A,0C3H
F11C 320000 STA WSVEC
F1IF CDA9F6 CALL CRLF ;START A NEW LINE
F122 CD78F3 CALL DECHO ;GET THE COMMAND
F125 D641 SUI 'A' ;GET RID OF ASCII ZONE
JRC QPRT ;BAD COMMAND
F127+38E0
F129 FE1A CPI 'Z'-'A'+1 ;CHECK UPPER LIMIT
JRNC QPRT ;BAD COM AND
F12B+30DC
F12D 87 ADD A ;DOUBLE IT FOR TABLE OFFSET
F12E 5F MOV E,A ;SET UP FOR DOUBLE ADD
F12F 1600 MVI D,0
F131 0602 MVI B,2 ;SET UP FOR TWO PARAMETERS
F133 2127F0 LXI H,TBL ;GET ACTION ROUTINE ADDRESS
F136 19 DAD D
F137 7E MOV A,M ;LOAD H,L INDIRECT
F138 23 INX H
F139 66 MOV H,M
F13A 6F MOV L,A
FI3B E9 PCHL ;GO TO ACTION ROUTINE
;
; FILL ACTION ROUTINE
;
;THIS ROUTINE FILLS A BLOCK OF MEMORY WITH A USER-
;DETERMINED CONSTANT. IT EXPECTS THREE PARAMETERS
;TO BE ENTERED IN THE FOLLOWING ORDER:
;
;START ADDRESS
;FINISH ADDRESS
;FILL VALUE
;
F13C CD86F3 FILL: CALL EXPR3 ;GET THREE PARAMETERS
F13F 71 FIO: MOV M,C ;PUT DOWN THE FILL VALUE
F140 CD8FF3 CALL HILO ;INCREMENT AND CHECK THE POINTER
F143 30FA JRNC FIO ;NOT DONE YET, JUMP
F145 D1 POP D ;RESTORE STACK POINTER IN CASE
JMPR WINIT ; STACK WAS OVERWRITTEN
F146+18C7
F148 50 AS1: MOV D,B ;SAVE THE COUNTER RESIDUE
F149 0604 MVI B,4 ;LOOP CONTROL
F14B CD78F3 CALL DECHO ;GET THE NEW ASSIGNMENT
F14E 23 AS2: INX H ;INCREMENT POINTER
F14F BE CMP M ;SEE IF THIS IS IT
JRNZ AS3
F150+2081
F152 68 MOV L,B ;SAVE THE RESIDUE TO FORM ASGT
F153 2D DCR L ;ADJUST VALUE
F154 42 MOV B,D ;REGET THE LOGICAL RESIDUE
F155 2603 MVI H,3 ;SET UP THE IOBYTE MASK
F157 05 DCR B ;ADJUST THIS ONE ALSO
F158+2804 JRZ AS5 ;NO SHFT NEEDED
;
F15A 29 AS4: DAD H ;SHIFT THE MASKS INTO POSITION
F15B 29 DAD H
DJNZ AS4 ;NOT DONE YET, JUMP
F15C+10FC
F15E 3A0300 AS5: LDA IOBYTE
F161 B4 ORA H ;MASK THE DESIRED ASSIGNMENT IN
F162 AC XRA H ;LOGICAL ASGT BITS NOW OFF
F163 B5 ORA L ;PUT IN NEW VALUE
F164 4F MOV C,A
F165 79 IOSET: MOV A,C
F166 320300 STA IOBYTE ;SAVE NEW ASSIGNMENTS
F169 C9 RET
F16A 3A0300 IOCHK: LDA IOBYTE
F16D C9 RET
;
F16E 4C ALT: DB 'L' ;LOGICAL LIST DEVICE TABLE
F16F 32 DB '2' ;USER DEVICE #2
F170 31 DB '1' ;USER DEVICE #1
F171 4C DB 'L' ;LIST TO HIGH SPEED PRINTER
F172 54 DB 'T' ;LIST TO TTY
F173 50 APT: DB 'P' ;LOGICAL PUNCH DEVICE TABLE
F174 32 DB '2' ;USER DEVICE #2
F175 31 DB '1' ;USER DEVICE #1
F176 50 DB 'P' ;PUNCH TO HIGH SPEED PUNCH
F177 54 DB 'T' ;PUNCH TO TTY
F178 52 ART: DB 'R' ;LOGICAL READER DEVICE TABLE
F179 32 DB '2' ;USER DEVICE #2
F17A 31 DB '1' ;USER DEVICE #1
F17B 50 DB 'P' ;READER TO HIGH SPEED READER
F17C 54 DB 'T' ;READER TO TTY
F17D 43 ACT: DB 'C' ;LOGICAL CONSOLE DEVICE TABLE
FI7E 31 DB '1' ;USER DEVICE #1
F17F 42 DB 'B' ;CONSOLE TO BATCH (PRINTER OR PTR)
F180 43 DB 'C' ;CONSOLE TO CRT
F181 54 DB 'T' ;CONSOLE TO TTY
;
; THE BYE ROUTINE IS USED TO PREVENT UNAUTHORIZED USAGE
; OF THE SYSTEM. THE SYSTEM LOCKS UP AND WILL NOT
; RESPOND TO ANYTHING OTHER THAN TWO ASCII BELL
; CHARACTERS. WHEN IT SEES THEM CONSECUTIVELY
; CONTROL IS RETURNED TO THE MONITOR WITHOUT ALTERING
; ANYTHING.
;
F182 0602 BYE: MVI B,2 ;SET UP FOR TWO CHARACTERS
F184 CD8FF6 BYE1: CALL CONI ;GO READ THE CONSOLE
F187 FEO7 CPI BELL ;SEE IF AN ASCII BELL
JRNZ BYE ;NO, START OVER AGAIN
F189+20F7
F18B CD7EF3 CALL ECH1 ;ECHO THE BELL
DJNZ BYE1 ;NOT YET, GET NEXT ONE
F18E+10F4
F190 C9 RET ;RETURN TO MONITOR
;
; COMPARE ROUTINE
;
;THIS ROUTINE COMPARES TWO BLOCKS OF MEMORY AGAINST EACH
; OTHER. IF A DIFFERENCE IN THE RELATIVE ADDRESS
; CONTENTS IS DETECTED THE ADDRESS OF THE FIRST
; BLOCK IS DISPLAYED ALONG WITH ITS CONTENTS AND
; THE CONTENTS OF THE OTHER BLOCK'S SAME RELATIVE
; ADDRESS.
F191 CD86F3 COMP: CALL EXPR3 ;GO GET THREE PARAMETERS
F194 0A CMPA: LDAX B ;GET SOURCE 2 DATA
F195 C5 PUSH B ;SAVE SOURCE 2 POINTER
F196 46 MOV B,M ;READ SOURCE 1 DATA
F197 B8 CMP B ;COMPARE DATA
JRZ CMPB ;JUMP IF OK
F198+280C
F19A F5 PUSH PSW ;SAVE SOURCE 2 DATA
F19B CDFBF5 CALL LADRB ;WRITE THE ADDRESS
F19E 78 MOV A,B ;GET SOURCE 1 DATA
F19F CDF4F5 CALL DASH1 ;FORMAT
F1A2 F1 POP PSW ;REGET SOURCE 2 DATA
F1A3 CDE6F5 CALL HEX1 ;OUTPUT IT
F1A6 C1 CMPB: POP B
F1A7 CD9BF3 CALL HILOXB ;INCREMENT SOURCE I POINTER AND SEE IF
JMPR CMPA ;JUMP IF NOT DONE YET
F1AA+18E8
;
; DISPLAY ACTION ROUTINE
; THIS ROUTINE DISPLAYS A BLOCK OF MEMORY ON THE
; CURRENT CONSOLE DEVICE (CONSOLE DUMP). THE USER
; MUST SPECIFY THE START AND FINISH ADDRESSES.
; THE DISPLAY IS ORGANIZED TO DISPLAY UP TO 16 BYTES
; PER DISPLAY LTNE WITH ALL COLUMNS ALIGNED SO
; EACH COLUMN HAS THE SAME LAST HEX DIGIT IN ITS ADDRESS
;
F1AC CDA4F6 DISP: CALL EXLF ;GO GET BLOCK LIMITS
F1AF CDFBF5 DIS1: CALL LADRB ;DISPLAY THE START ADDRESS
F1B2 7D MOV A,L ;SEE IF ON 16 BYTE BOUNDARY
F1B3 CDF0F1 CALL TRPLSP ;SKIP OVER TO RIGHT COLUMN
F1B6 E5 PUSH H ;SAVE (H,L)
F1B7 7E DIS2: MOV A,M ;GET THE CONTENTS
F1B8 CDE6F5 CALL HEX1 ;OUTPUT IT
F1BB CD8FF3 CALL HILO ;INCREMENT CHECK POINTER
F1BE+382A JRC DIS7 ;DONE IF CARRY SET
F1C0 CDFEF5 CALL BLK ;MAKE COLUMNS
F1C3 7D MOV A,L ;READY FOR NEW LINE?
F1C4 E60F ANI 0FH
JRNZ DIS2
F1C6+20EF
F1C8 E1 DIS3: POP H ;REGET LINE START ADDRESS
F1C9 7D MOV A,L ;SKIP OVER TO RIGHT SPACE
F1CA E60F ANI 0FH
F1CC CDF5F1 CALL TRPL2
F1CF 7E DIS4: MOV A,M ;GET MEMORY VALUE
F1DO E67F ANI 7FH ;STRIP OFF PARITY BIT
F1D2 4F MOV C,A ;SET UP FOR OUTPUT
F1D3 FE20 CPI ' ' ;SEE IF PRINTABLE IN ASCII
JRC DIS5 ;JUMP IF' SO
F1D5+3804
F1D7 FE7E CPI 7EH
JRC DIS6
F1D9+3802
F1DB 0E2E DIS5: MVI C,'.' ;ELSE, PRINT A DOT
F1DD CD09F0 DIS6: CALL CONOUT
F1E0 CD9CF3 CALL HILOX ;INCREMENT (H,L) AND SEE IF DONE
F1E3 7D MOV A,L ;NOT DONE, READY FOR NEW LINE?
F1E4 E60F ANI 0FH
JRNZ DIS4 ;JUMP IF NOT
F1E6+20E7
JMPR DIS1 ;DO THE NEXT LINE
F1E8+18C5
F1EA 93 DIS7: SUB E ;SKIP OVER TO START ASCII PRINTOUT
F1EB CDF0F1 CALL TRPLSP
JMPR DIS3 ;GO PRINT THE ASCII
F1EE+18D8
;
F1F0 E60F TRPLSP: ANI 0FH ;ISOLATE THE LOW FOUR BITS
F1F2 47 MOV B,A ;PREPARE TO SPACE OVER TO RIGHT COLUMN
F1F3 87 ADD A ;TRIPLE THE COUNT
F1F4 80 ADD B
F1F5 47 TRPL2: MOV B,A ;PUT BACK INTO B
F1F6 04 INR B ;ADJUST COUNTER
F1F7 CDFEF5 TRPL1: CALL BLK ;DO THE SPACING
DJNZ TRPL1 ;NO, DO ANOTHER COLUMN
F1FA+10FB
F1FC C9 RET
;
; GO TO ACTION ROUTINE
;
; GOTO COMMAND TRANSFERS CONTROL TO A SPECIFIED ADDRESS.
; IT ALLOWS THE SELECTIVE SETTING OF UP TO TWO BREAKPOINTS
; AS WELL AS ALLOWING ANY CONSOLE INPUT TO BREAKPOINT
; THE RUN, AS LONG AS INTERRUPT 1 IS ACTIVE.
;
F1FD CDC0F3 GOTO: CALL PCHK ;SEE IF OLD ADDRESS WANTED
F200+3837 JRC GO3 ; YES, JUMP
F202+2810 JRZ GO0 ; YES, BUT SET SOME BREAKPOINTS
F204 CDCCF0 CALL EXF ;GET NEW GOTO ADDRESS
F207 D1 POP D
F208 213400 LXI H,PLOC ;PUT ADDRESS IN PC LOCATION
F2OB 39 DAD SP
F2OC 72 MOV M,D ;LOW BYTE
F2OD 2B DCX H
F2OE 73 MOV M,E ;HIGH BYTE
F2OF 79 MOV A,C
F210 FE0D CPI CR ;SEE IF A CR WAS LAST ENTERED
JRZ GO3
F212+2825
F214 0602 GO0: MVI B,NBKPTS
F216 213500 LXI H,TLOC ;POINT TO TRAP STORAGE
F219 39 DAD SP
F21A C5 GO1: PUSH B ;SAVE NUMBER OF BREAKPOINTS
F21B E5 PUSH H ;SAVE STORAGE POINTER
F21C 0602 MVI B,2 ;SET UP TO GET A TRAP ADDRESS
F21E CDD7F0 CALL EXPR1 ;GET A TRAP ADDRESS
F221 D1 POP D ;GET THE TRAP ADDRESS INTO (D,E)
F222 E1 POP H ;REGET THE STORAGE ADDRESS
F223 7A MOV A,D ;INSURE THE TRAP ADDRESS ISN'T ZERO
F224 B3 ORA E
JRZ GO2 ;JUMP IF SO
F225+280A
F227 73 MOV M,E ;SAVE THE BREAKPOINT ADDRESS
F228 23 INX H
F229 72 MOV M,D
F22A 23 INX H
F22B 1A LDAX D ;SAVE THE INSTRUCTION FROM THE BP ADDR
F22C 77 MOV M,A
F22D 23 INX H
F22E 3ECF MVI A,RST OR 8 ;INSERT THE BREAKPOINT
F230 12 STAX D
F231 79 GO2: MOV A,C ;REGET THE DELIMITER TO SEE
F232 FE0D CPI CR ; IF WE ARE DONE SETTING BREAKPOINTS
F234 C1 POP B ; UNLOAD THE STACK FIRST
JRZ GO3 ;YES, JUMP
P235+2802
DJNZ GO1 ;JUMP IF NOT AT BP LIMIT
F237+10E1
F239 CDA9F6 GO3: CALL CRLF
F23C E1 POP H ;GET RID OF STACK JUNK
F23D 2143F4 LXI H,RS9
F240 E5 PUSH H
F2041 21CFF3 LXI H,REST
F2044 220900 SHLD 9 ;SET BREAKPOINT JUMP VECTOR ADDRESS
F247 211800 LXI H,24 ;FIND REGISTER SET ROUTINE ADDRESS
F24A 39 DAD SP
F24B D1 POP D ;ADJUST THE STACK
F24C E9 PCHL ;GO TO THE DESIRED PLACE
;
; GENERAL PURPOSE INPUT/OUTPUT ROUTINES
;
;THESE ROUTINES ALLOW BYTE BY BYTE INPUT OR OUTPUT FROM
; THE CURRENT CONSOLE DEVICE. THEY ARE INVOKED BY
; THE MONITOR "I" OR "O" COMMAND.
F24D CDD7F0 INPT: CALL EXPR1 ;GET INPUT PORT NUMBER
F250 C1 POP B ;GET PORT # INTO C REGISTER
INP E ;READ VALUE INTO E REGISTER
F251+ED58
JMPR BITS2 ;GO DO A BINARY PRINT OF THE VALUE
F253+1851
F255 CDD9F0 OUPT: CALL EXPR ;GET THE ADDRESS AND DATA FOR OUTPUT
F258 D1 POP D ;DATA VALUE INTO E
F259 C1 POP B ;PORT INTO C
OUTP E ;DO THE OUTPUT
F25A+ED59
F25C C9 RET
;
; MOVE ROUTINE
; THIS ROUTINE EXPECTS THREE PARAMETERS, ENTERED IN THE
; SOURCE FIRST BYTE ADDRESS
; SOURCE LAST BYTE ADDRESS
; DESTINATION FIRST BYTE ADDRESS
;
F25D CD86F3 MOVE: CALL EXPR3 ;GET THREE PARAMETERS
F260 7E MOV1: MOV A,M ;GET NEXT BYTE
F261 02 STAX B ;MOVE IT
F262 CD9BF3 CALL HILOXB ;GO INCREMENT CHECK SOURCE POINTER
JMPR MOV1 ;NOT THERE YET, GO DO IT AGAIN
F265+18F9
;
; SUBSTITUTE ACTION ROUTINE
;
; THIS ROUTINE ALLOWS THE USER TO INSPECT ANY MEMORY LOCATION
; AND ALTER THE CONTENTS TF DESIRED AND IF THE ADDRESS
; IS IN RAM. THE CONTENtS MAY BE LEFT UNALTERED
; BY ENTERING A SPACE, COMMA OR A CARRIAGE RETURN. IF
; A CARRIAGE RETURN IS ENTER~D THE ROUTINE IS TERMINATE
; IF A SPACE OR COMMA IS ENTER~D, THE ROUTINE
; PROCEEDS TO THE NEXT LOCATION AND PRESENTS THE USER
; WITH AN OPPORTUNITY TO ALTER IT.
;
F267 CDD7F0 SUBS: CALL EXPR1 ;GO GET ONE PARAMETER
F26A E1 POP H ;GET THE START ADDRESS
F26B 7E SUB1: MOV A,M ;GET THE CONTENTS OF THE ADDRESS
F26C CDF4F5 CALL DASH1 ;DISPLAY IT ON CONSOLE AND A DASH
F26F CDC0F3 CALL PCHK ;GET CHECK CHARACTER
F272 D8 RC ;DONE IF CARRIAGE RETURN
JRZ SUB2 ;NO CHANGE IF BLANK OR
F273+280F
F275 FE0A CPI LF ;SEE IF PREVIOUS BYTE WANTED
JRZ SUB3 ;YES, DO IT
F277+280D
F279 E5 PUSH H ;SAVE MEMORY POINTER
F27A CDCCF0 CALL EXF ;GO GET REST OF NEW VALUE
F27D D1 POP D ;NEW VALUE TO E REGISTER
F27E E1 POP H ;RESTORE MEMORY POINTER
F27F 73 MOV M,E ;PUT DOWN NEW VALUE
F280 79 MOV A,C ;GET THE DELIMITER
F281 FE0D CPI CR ;SEE IF DONE (CARRIAGE RETURN)
F283 C8 RZ ;YES, RETURN TO MONITOR
F284 23 SUB2: INX H ;NO INCREMENT MEMORY PONTER
F285 23 INX H ;ALLOW A FALL THROUGH ON THE NEXT INST
F286 2B SUB3: DCX H ;ADJUST (H,L) AS APPROPRIATE
F287 7D MOV A,L ;GET LO ADDRESS BYTE
F288 E607 ANI 7 ;SEE IF ON A BOUNDARY
F28A CCFBF5 CZ LADRB ;CALL IF ON THE BOUNDARY
JMPR SUB1 ;GO DO THE NEXT LOCATION
F28D+18DC
;
; MTEST ROUTINE 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 OPERATVENESS.
;
F28F CDA4F6 MTEST: CALL EXLF
F292 7E MTEST1: MOV A,M ;READ A BYTE
F293 F5 PUSH PSW ;SAVE IT
F294 2F CMA ;COMPLEMENT IT
F295 77 MOV M,A ;WRITE IT
F296 AE XRA M ;RESULT SHOULD BE ZERO
F297 C4A1F2 CNZ BITS ;LOG ERROR IF NOT
F29A F1 MTEST2: POP PSW
F29B 77 MOV M,A ;RESTORE ORIGINAL BYTE
F29C CD9CF3 CALL HILOX ;PONT TO NEXT AND SEE IF DONE
JMPR MTEST1 ;NO, CONTINUE
F29F+18F1
F2A1 D5 BITS: PUSH D ;SAVE (D,E)
F2A2 5F MOV E,A ;SAVE ERROR PATTERN IN E
F2A3 CDFBF5 CALL LADRB ;FIRST PRINT THE ADDRESS
F2A6 0608 BITS2: MVI B,8 ;LOOP CONTROL FOR 8 BITS
F2A8 7B BITS1: MOV A,E ;GET NEXT BIT
F2A9 07 RLC ; INTO CARRY
F2AA 5F MOV E,A ;SAVE REST
F2AB 3E18 MVI A,'0'/2 ;BUILD ASCII 1 OR 0
F2AD 17 RAL ; CARRY DETERMINES WHICH
F2AE 4F MOV C,A ;NOW, OUTPUT IT
F2AF CD09F0 CALL CONOUT
DJNZ BITS1 ;DO IT AGAIN
F2B2+10F4
F2B4 D1 POP D
F2B5 C9 RET
;
; EXAMINE REGISTERS COMMAND INSPECTS THE VALUES OF THE
; THE REGISTERS STORED BY THE LAST ENCOUNTERED BREAKPOINT.
; THE VALUES MAY BE MODIFIED IF DESIRED.
;
F2B6 23 XAA: INX H ;SKIP OVER TO NEXT ENTRY
F2B7 23 INX H
F2B8 34 XA: INR M ;SEE IF AT END OF TABLE
F2B9 C8 RZ ;COULDN'T FIND MATCH, QUIT
F2BA F2C1F2 JP XAB ;SORT OUT BIT 7 OF TABLE
F2BD F680 ORI 80H ;SET IT ON TEST VALUE
JMPR XAC
F2BF+1802
F2C1 E67F XAB: ANI 7FH ;RESET BIT 7
F2C3 3 XAC: DCR M ;TO BE PULLED OUT IN ROM
F2C4 BE CMP M ;SEE IF THIS IS IT
JRNZ XAA ;NO, GO TRY AGAIN
F2C5+20EF
F2C7 CDFEF5 CALL BLK ;YES PREPARE TO SHOW CURRENT VALUE
F2CA CD15F3 CALL PRTVAL ;GO PRINT THE VALUE
F2CD CDF7F5 CALL DASH ;PROMPT A NEW VALUE
F2D0 CDC0F3 CALL PCHK ;GET THE INPUT
F2D3 D8 RC ;DONE IF CARRIAGE RETURN
JRZ XF ;JUMP IF NO CHANGE DESIRED
F2D4+2812
F2D6 E5 PUSH H ;TO BE CHANGED, SAVE POINTER
F2D7 CDCCF0 CALL EXF ;GET THE NEW VALUE
F2DA E1 POP H ; INTO (H,L)
F2DB 7D MOV A,L ;GET THE N~W LOW BYTE
F2DC 13 INX D ;ADJUST POINTER
F2DD 12 STAX D ;PUT IT DOWN
F2DE E3 XTHL ;RECOVER THE TABLE POINTER
F2DF 7E MOV A,M ;GET THE ATTRIBUTES
F2E0 E3 XTHL ;SET THE STACK STRAIGHT
F2E1 07 RLC ;SEE IF 8 BIT REGISTER
JRNC XE ;JUMP IF SO
F2E2+3003
F2E4 13 INX D ;REGISTER PAIR, DO OTHER 8 BITS
F2E5 7C MOV A,H
F2E6 12 STAX D
F2E7 E1 XE: POP H ;RESTORE THE TABLE POINTER
F2E8 79 XF: MOV A,C ;SEE IF IT WAS A CR
F2E9 FE0D CPI CR
F2EB C8 RZ ;DONE IF SO
F2EC 213DF3 XMNE: LXI H,ACTBL ;GET ADDRESS OF REGISTER LOOK-UP TABLE
F2EF CDC0F3 XMNE1: CALL PCHK ;FIND OUT WHAT ACTION IS WANTED
JRC XG ;SHOW ALL IF CARRIAGE RETURN
F2F2+380B
F2F4+28F9 JRZ XMNE1 ;IGNORE BLANKS OR COMMAS
F2F6 FE27 CPI '''' ;SEE IF PRIMES WANTED
JRNZ XA ;NO, MUST BE SINGLE REGISTER
F2F8+20BE
F2FA 2155F3 LXI H,PRMTB ;YES, SET TABLE ADDRESS
JMPR XMNE1 ; AND FIND OUT WHICH ONE
F2FD+18F0
F2FF 7E XG: MOV A,M
F300 4F MOV C,A
F301 3C INR A ;SEE IF AT END OF TABLE
F302 C8 RZ ;DONE IF SO
F303 FCA9F6 CM CRLF ;START A NEW LINE IF BIT 7 IS SET
F306 CD09F0 CALL CONOUT
F309 CDF7F5 CALL DASH ;PROMPT FOR A NEW VALUE
F30C CD15F3 CALL PRTVAL ;GO PRINT THE VALUE
F30F CDFEF5 CALL BLK ;FORMATTER
F312 23 INX H ;POINT TO NEXT ENTRY
JMPR XG ;DO THE NEXT VALUE
F313+18EA
F315 23 PRTVAL: INX H ;POINT TO NEXT ENTRY
F316 7E MOV A,M ;GET OFFSET AND ATTRIBUTES BYTE
F317 E63F ANI 3FH ;ISOLATE THE OFFSET
F319 C602 ADI 2 ;ALLOW FOR RETURN ADDRESS
F31B EB XCHG ;RE-SWAP POINTERS
F31C 6F MOV L,A ;BUILD THE ADDRESS OF THE REQ CONTENTS
F31D 2600 MVI H,0
F31F 39 DAD SP
F320 EB XCHG ;RE-SWAP THE POINTERS
F321 7E MOV A,M ;NOW FIND OUT ATTRIBUTES
F322 0601 MVI B,1 ;SET UP FOR SINGLE REG VALUE
F324 07 RLC
JRNC PV1 ;JUMP IF SINGLE REGISTER VALUE WANTED
F325+300E
F327 04 INR B ;SET UP FOR REGISTER PAIR
F328 07 RLC
JRNC PV1 ;JUMP IF REGISTER PAIR IS NEXT
F329+300A
F32B E5 PUSH H ;SPECIAL CASE FOR MEMORY REGISTER
F32C 1A LDAX D ;BUILD ADDRESS IN (H,L)
F32D 67 MOV H,A
F32E 1B DCX D
F32F 1A LDAX D
F330 6F MOV L,A
F331 7E MOV A,M ;GET THE MEMORY VALUE
F332 E1 POP H ;RESTORE (H,L)
DJNZ PV2 ;ALWAYS JUMP
F333+1001
F335 1A PV1: LDAX D ;GET THE REGISTER CONTENTS
F336 CDE6F5 PV2: CALL HEX1 ;OUTPUT THE VALUE
F339 1B DCX D ;ADJUST THE MEMORY POINTER
DJNZ PV1
F33A+10F9
F33C C9 RET
;
F33D C115 ACTBL: DB 80H+'A',ALOC
F33F 4213 DB 'B',BLOC
F341 4312 DB 'C',CLOC
F343 4411 DB 'D',DLOC
F345 4510 DB 'E',ELOC
F347 4614 DB 'F',FLOC
F349 4831 DB 'H',HLOC
F34B 4C30 DB 'L',LLOC
F34D CDF1 DB 80H+'M',HLOC+0C0H
F34F 50B4 DB 'P',PLOC+80H
F351 5397 DB 'S',SLOC+80H
F353 4903 DB 'I',ILOC
;
; REST OF Z 80 REGISTER OFFSETS
;
F355 C109 PRMTB: DB 80H+'A',APLOC
F357 420B DB 'B',BPLOC
F359 430A DB 'C',CPLOC
F35B 440D DB 'D',DPLOC
F35D 450C DB 'E',EPLOC
F35F 4608 DB 'F',FPLOC
F361 480F DB 'H',HPLOC
F363 4C0E DB 'L',LPLOC
F365 CDCF DB 80H+'M',HPLOC+0C0H
F367 5887 DB 'X',XLOC+80H
F369 5985 DB 'Y',YLOC+80H
F36B 5202 DB 'R',RLOC
F36D FF DB 0FFH
;
; GENERAL PURPOSE ROUTINES
;
;
; ROUTINE CONV CONVERTS THE LOW ORDER NIBBLE OF THE
; ACCUMULATOR TO ITS ASCII EQUIVALENT. IT
; PUTS THE RESULT INTO C FOR LATER OUTPUT.
;
F36E E60F CONV: ANI 0FH ;STRIP OFF BITS 4 7
F370 C690 ADI 90H ;PUT ON THE ASCII ZONE
F372 27 DAA
F373 CE40 ACI 40H
F375 27 DAA
F376 4F MOV C,A ;PUT IN OUTPUT PASS REGISTER
F377 C9 RET
;
; ROUTINE ECHO READS A BYTE FROM A HALF DUPLEX CONSOLE
; DEVICE THEN ECHOES THE CHARACTER BACK TO THE
; CONS0LE.
;
F378 CDF7F5 DECHO: CALL DASH ;PRINT A DASH
F37B CD8FF6 ECHO: CALL CONI ;CONSOLE READ, WRITE ROUTINE
F37E C5 ECH1: PUSH B ; SAVE (B,C)
F37F 4F MOV C,A ; PASS CHARACTER IN C REGISTER
F380 CD09F0 CALL CONOUT ; OUTPUT IT
F383 79 MOV A,C ; PUT CHARACTER BACK INTO A
F384 C1 POP B ; RESTORE (B,C)
F385 C9 RET
;
; ROUTINE EXPR3 GETS THREE PARAMETERS, DOES A CR LF AND
; THEN LOADS (B,C), (D,E), AND (H,L) WITH THE PARAMETERS.
F386 04 EXPR3: INR B ;2 IS ALREADY IN THE B REGISTER
F387 CDD9F0 CALL EXPR ;GET THE PARAMETERS
F38A C1 POP B ;PUT PARAMETERS INTO REGISTERS
F38B D1 POP D
F38C C3AAF6 JMP CRLFA ;GO DO THE CARRIAGE RETURN SEQUENCE
;
; ROUTINE HILO INCREMENTS (H,L) IT THEN CHECKS FOR (AND
; DISALLOWS) A WRAP AROUND SITUATION. IF IT OCCURS,
; THE CARRY BIT WILL BE SET ON RETURN. IF NO WRAP-
; AROUND OCCURRED (H,L)IS COMPARED TO (D,E) AND
; THE FLAG BITS SET ACCORDINGLY.
F38F 23 HILO: INX H ;INCREMENT (H,L)
F390 7C MOV A,H ;TEST IF ZERO
F391 B5 ORA L ; IN (H,L)
F392 37 STC ;SET CARRY FOR (H,L)=0
F393 C8 RZ ;RETURN TF (H,L)=0
F394 7B MOV A,E ;COMPARE(H,L) TO (D,E)
F395 95 SUB L
F396 7A MOV A,D
F397 9C SBB H
F398 C9 RET ;RETURN WITH FLAGS SET
;
; ROUTINE HILOX INCREMENTS (H,L), COMPARES IT TO (D,E) AND
; IF EQUAL RETURNS CONTROL TO THE MONITOR EXECUThVE.
; OTHERWISE, CONTROL RETURNS TO THE CALLING ROUTINE.
;
F399 D1 HILOD: POP D ;GET RID OF RETURN ADDRESS
F39A C9 RET ;RETURN TO MONITOR
F39B 03 HILOXB: INX B ;INCREMENT (B,C)
F390 CD8FF3 HILOX: CALL HILO ;INC AND CHECK (H,L)
JRC HILOD ;DONE IF CARRY SET
F39F+38F8
F3A1 CD12F0 CALL CONST ;SEE IF CONSOLE BREAK PENDING
F3A4 B7 ORA A
F3A5 C8 RZ ;NONE RETURN TO CONTINUE
F3A6 CD8FF6 CALL CONI ;SEE IF WAIT OR BREAK
F3A9 FE13 CPI CTRLS
JRNZ HILOD ;JUMP IF BREAK
F3AB+20EC
F3AD C38FF6 JMP CONI ;GO WAIT FOR NEXT CHARACTER
;
; ROUTINE NIBBLE CONVERTS THE ASCII CHARACTERS 0-9 AND
; A-F TO THEIR EQUIVALENT HEXADECIMAL VALUE. IF
; THE CHARACTER IS NOT IN RANGE, THE CARRY BIT IS SET TO
; FLAG THE ERROR.
F3B0 D630 NIBBLE: SUI '0' ;ASCII TO HEX CONVERSION
F3B2 D8 RC ; DONE IF OUT OF RANGE
F3B3 FE17 CPI 'G'-'0' ;CHECK UPPER END
F3B5 3F CMC ; TOGGLE THE CARRY BIT
F3B6 D8 RC ; DONE IF OUT OF RANGE
F3B7 FE0A CPI '9'-'0'+1 ;SEE IF NUMERIC
F3B9 3F CMC ; TOGGLE THE CARRY BIT
F3BA D0 RNC ; DONE IF SO
F3BB D607 SUI 'A'-'9'-1 ;SUBTRACT THE ALPHA BIAS
F3BD FE0A CPI 10 ; SET CARRY FOR INVALID CHAR
F3BF C9 RET
;
; ROUTINE PCHK READS A CHARACTER FROM THE CONSOLE, THEN
; CHECKS IT FOR A DELIMITER. IF IT IS NOT
; A DELIMTTER A NON ZERO CONDITION IS RETURNED.
; IF IT IS A DELIMITER, A ZERO CONDITION IS RETURNED.
; FURTHER TF THE DELIMITER IS A CARRIAGE RETURN
; THE CARRY BIT IS SET. A BLANK OR A COMMA RESET'S
; THE CARRY BIT.
;
F3C0 CD7BF3 PCHK: CALL ECHO ;GET, TEST FOR DELIMITER
F3C3 FE20 P2C: CPI ' ' ; BLANK?
F3C5 C8 RZ ; YES, DONE
F3C6 FE2C CPI ',' ; NO COMMA?
F3C8 C8 RZ ; YES, DONE
F3C9 FE0D CPI CR ; NO CARRIAGE RETURN?
F3CB 37 STC ; SHOW IT IN CARRY BIT
F3CC C8 RZ ; DONE IF CR
F3CD 3F CMC ; CLEAR CARRY FOR NO DELIMITER
F3CE C9 RET
;
; ROUTINE REST TRAPS ALL OF THE REGISTER CONTENTS WHENEVER A
; RESTART 1 INSTRUCTION IS EXECUTED. THE TRAPPED CONTEN
; ARE STORED IN THE SYSTEM STACK AREA FOR LATER ACCESS AND
; USE BY THE GOTO AND THE EXAMINE REGISTERS COMMANDS.
;
; INSERT INTERRUPT DISABLER SOFTWARE AT START OF REST:
F3CF E5 REST: PUSH H ;SAVE ALL THE REGISTERS
F3D0 D5 PUSH D
F3D1 C5 PUSH B
F3D2 F5 PUSH PSW
F3D3 CD6FF0 CALL MEMSIZ ;GET THE MONITOR'S STACK LOCATION
F3D6 EB XCHG
F3D7 210A00 LXI H,10 ;GO UP 10 BYTES IN THE STACK
F3DA 39 DAD SP ; TO SKIP OVER TEMP REGISTER SAVE
F3DB 0604 MVI B,4 ;PICK OFF THE REGISTER VALUES
F3DD EB XCHG
F3DE 2B RS1: DCX H
F3DF 72 MOV M,D ;SAVE IN WORK AREA
F3E0 2B DCX H
F3E1 73 MOV M,E
F3E2 D1 POP D
DJNZ RS1
F3E3+10F9
F3E5 C1 POP B ;GET THE BREAKPOINT LOCATION
F3E6 0B DCX B
F3E7 F9 SPHL ;SET THE MONITOR STACK
F3E8 212500 LXI H,TLOCX ;SET UP TO RESTORE BREAKPOINTS
F3EB 39 DAD SP
F3EC D5 PUSH D
F3ED 1602 MVI D,NBKPTS ;LOOP CONTROL F0R N BREAKPOINTS
F3EF 7E RS2: MOV A,M
F3F0 91 SUB C ;SEE IF A SOFTWARE TRAP
F3F1 23 INX H
F3F2 7E MOV A,M
F3F3 98 SBB B ;MAYBE, TRY REST OF ADDRESS
JRZ RS5 ;FOUND ONE, JUMP TO RESET IT
F3F4+2806
F3F6 23 RS3: INX H ;NOT FOUND, TRY NEXT ONE
F3F7 23 INX H
F3F5 15 DCR D
JRNZ RS2
F3F9+20F4
F3FB 03 RS4: INX B ;NONE FOUND
F3FC 212000 RS5: LXI H,LLOCX
F3FF D1 POP D
F400 39 DAD SP
F401 73 MOV M,E ;STORE USER (H,L)
F402 23 INX H
F403 72 MOV M,D
F404 C5 PUSH B ;SAVE (B,C)
F405 0E2A MVI C,'*' ;TYPE THE BREAK INDICATION
F407 CD09F0 CALL CONOUT
F40A D1 POP D ;REGET THE BREAKPOINT LOCATION
F40B 3EF4 MVI A,RS9/256
F40D BA CMP D ;SEE IF A RET BREAKPOINT
JRZ RS6
F40E+2809
F410 23 INX H
F411 23 INX H
F412 73 MOV M,E ;RESTORE USER PROGRAM COUNTER
F413 23 INX H
F414 72 MOV M,D
F415 EB XCHG ;PRINT THE BREAKPOINT LOCATION
F416 CDE1F5 CALL LADR
F419 212500 RS6: LXI H,TLOCX
F41C 39 DAD SP
F41D 010002 LXI B,NBKPTS*256
F42O 5E RS7: MOV E,M ;RESTORE BREAKPOINTED LOCATIONS
F421 71 MOV M,C ;RESET SYSTEM BP SAVE AREA
F422 23 INX H
F423 56 MOV D,M
F424 71 MOV M,C
F425 23 INX H
F426 7B MOV A,E
F427 B2 ORA D
JRZ RS8 ;DO NOTHING IF ZERO
F428+2802
F42A 7E MOV A,M
F42B 12 STAX D
F42C 23 RS8: INX H ;SAME THING FOR OTHER
DJNZ RS7 ; BREAKPOINT
F42D+10F1
F42F+08 EXAF ;NOW SAVE THE Z-80 UNIQUES
EXX
F430+D9
F431 E5 PUSH H
F432 D5 PUSH D
F433 C5 PUSH B
F434 F5 PUSH PSW
PUSHIX
F435+DDE5
PUSHIY
F437+FDE5
LDAI
F439+ED57
F43B 47 MOV B,A
LDAR
F43C+ED5F
F43E 4F MOV C,A
F43F C5 PUSH B
F440 C313F1 JMP WINITA ;RETURN TO MONITOR
F443 E5 RS9: PUSH H ;RET BREAKPOINT ENCOUNTERED, ADJUST TH
F444 CF RST 1 ;DO THE BREAKPOINT
F445 C1 EXIT: POP B
F446 79 MOV A,C
STAR
F447+ED4F
F449 78 MOV A,B
STAI
F44A+ED47
POPIX
F44C+DDE1
POPIY
F44E+FDE1
F450 F1 POP PSW
F451 C1 POP B
F452 D1 POP D
F453 E1 POP H
EXAF
F454+08
EXX
F455+D9
F456 D1 POP D
F457 C1 POP B
F458 F1 POP PSW
F459 E1 POP H
F45A F9 SPHL
F45B 00 DB 0 ;PLACE FOR EI
F45C 210000 LXI H,0
F45F C30000 JMP 0
F462 = ENDX: EQU $
;
;ERROR HANDLERS
;
; THREE TYPES OF ERRORS ARE DETECTED: A RESTART
; ERROR AN I/O ASSIGNMENT ERROR AND CERTAIN PROGRAM
; ERRORS (DETERMINED BY THE PARTCULAR ROUTINE WHERE
; THE ERROR CONDITION WAS ENCOUNTERED.) EACH CAUSES
; A UNIQUE MESSAGE TO BE PRINTED, THEN DOES A WARM
; INITIALIZATION OF THE MONITOR. THE I/O ERROR
; CAUSES THE I/O ASSIGNMENTS TO BE RESET TO DEFAULT ASSI
F462 AF IOER: XRA A ;SET IOBYTE TO DEFAULT VALUE
F463 320300 STA IOBYTE
F466 216CF4 LXI H,IOMSG ;GET ADDRESS OF I/O ERROR MSG
F469 C3B5F6 JMP COMERR ;GO PROCESS IT
F46C 492F4F2045 IOMSG: DB 'I/O ER','R'+80H
;
; BYTE ROUTINE READS TWO ASCII CHARACTERS FROM THE
; CURRENT PAPER TAPE READER AND ASSEMBLES THEM INTO TWO
; HEXADECIMAL BYTES OF DATA. IT UPDATES A CHECKSUM
; ACCUMULATED IN REGISTER D.
F473 CDE8F6 BYTE: CALL BYT ;GET NEXT BYTE
F476 B0 ORA B ;COMBINE THEM
F477 47 MOV B,A
F478 82 ADD D ;UPDATE CHECKSUM
F479 57 MOV D,A
F47A 78 MOV A,B ;RESTORE BYTE
F47B C9 RET
;
F47C 0E0D PEOL: MVI C,CR
F47E CD7CF6 CALL PO
F481 0E0A MVI C,LF
F483 C37CF6 JMP PO ;GO PUNCH THE OUTPUT
;
; RIX ROUTINE READS ONE CHARACTER FROM THE CURRENT
; PAPER TAPE READER AND STRIPS OFF THE PARITY BIT.
F486 CD56F6 RIX: CALL RI
F489 E67F ANI 7FH
F48B C9 RET
F48C 3F3F3FBF QMSG: DB '???','?'+80H
F490 4D4F535320 LOGMSG: DB 'MOSS VERS 2.2'
F49D 0D8A DB CR,LF+80H
;
; INITIALIZATION CODE FOR THE 8250 ASYNCHRONOUS COMMUNICATION
; ELEMENT. THIS CODE WILL INITIALIZE THE BAUD RATE OF THE
; 8250, AS WELL AS THE WORD FORMAT. 8 DATA BTTS I STOP BIT
; AND NO PARITY ARE SELECTED. EITHER 2 OR 3 CARIAGE RETURNS
; MUST BE ENTERED TO ESTABLISH THE CORRECT BAUD RATE.
F49F 3E0F I8250: MVI A,0FH ;SET UP THE 8250
F4A1 D324 OUT SMDMCT
F4A3 114000 LXI D,40H ;SET UP TO TIME THE START BIT
F4A6 62 MOV H,D
F4A7 6A MOV L,D ;ZEROES TO (H,L)
F4A8 DB26 I8250A: IN SMDMST ;WAIT FOR START BIT
F4AA A3 ANA E
JRZ I8250A
F4AB+28FB
F4AD DB26 I8250B: IN SMDMST ;NOW, TIME THE START BIT DURATION
F4AF 23 INX H
F4B0 A3 ANA E
F4B1 A3 ANA E
F4B2 C2ADF4 JNZ I8250B
F4B5 E5 PUSH H ;SAVE COUNT IN CASE OF 4 MHZ
F4B6 29 DAD H ;PREPARE THE 2 MHZ DIVISOR
F4B7 5C MOV E,H ;SET UP THE FUDGE FACTOR
F4B8 19 DAD D ;APPLY THE FUDGE FACTOR
F4B9 19 DAD D
F4BA E5 PUSH H ;SAVE FOR LATER USE
F4BB 29 DAD H ;WAIT FOR 8 BIT TIMES
F4BC 29 DAD H
F4BD DB20 I8250C: IN SDATA ;WASTE SOME TIME
F4BF 2B DCX H
F4CO 7D MOV A,L
F4C1 B4 ORA H
F4C2 C2BDF4 JNZ I8250C
F4C5 E1 POP H ;REGET 2 MHZ DIVISOR
F4C6 3E83 I8250D: MVI A,83H ;SET DIVISOR REGISTER ACCESS
F4C8 D323 OUT SLCTRL
F4CA 7D MOV A,L ;SET THE DIVISOR
F4CB D320 OUT SDATA
F4CD 7C MOV A,H
F4CE D321 OUT SINTEN
F4D0 3E03 MVI A,3 ;SET DATA REGISTER ACCESS
F4D2 D323 OUT SLCTRL
F4D4 AF XRA A ;DISABLE INTERRUPTS
F4D5 D321 OUT SINTEN
F4D7 D325 OUT SLSTAT ;AND RESET ERROR FLAGS
F4D9 CDCEF6 CALL TTYIN ;GET A CHARACTER
F4DC E67F ANI 7FH ;STRIP OFF ANY PARITY BIT
F4DE FE0D CPI 0DH ;SEE IF IT IS A CARRIAGE RETURN
F4EO E1 POP H ;SET THE STACK STRAIGHT
F4E1 C8 RZ ;DONE IF CARRIAGE RETURN RECEIVED
F4E2 5D MOV E,L ;ELSE, MUST BE 4 MHZ SYSTEM
F4E3 54 MOV D,H ; SO, COUNT=COUNT*5/4
F4E4 CDEEF4 CALL DIV2
F4E7 CDEEF4 CALL DIV2
F4EA 19 DAD D
F4EB E5 PUSH H
JMPR I8250D ;GO SET THE NEW DIVISOR
F4EC+18D8
;
;
F4EE B7 DIV2: ORA A ;CLEAR THE CARRY BIT
F4EF 7C MOV A,H ;DO A 16 BIT RIGHT SHIFT
F4F0 1F RAR
F4F1 67 MOV H,A
F4F2 7D MOV A,L
F4F3 1F RAR
F4F4 6F MOV L,A
F4F5 C9 RET
;
; EOF ROUTINE PUNCHES AN END OF FILE RECORD (INTEL HEX
; FORMAT) ONTO THE CURRENTLY ASSIGNED PAPER TAPE PUNCH
; DEVICE. AN ENTRY POINT ADDRESS FOR THE FILE WILL ALSO
; BE PUNCHED, IF SPECIFIED.
;
F4F6 CDA4F6 EOF: CALL EXLF ;GET JUMP ADDRESS
F4F9 D5 PUSH D ;SAVE THE # OF TRAILER NULLS
F4FA CDC8F5 EOFA: CALL PSOR ;PUNCH START OF RECORD
F4FD AF XRA A ;ZERO OUT THE CHECKSUM
F4FE 57 MOV D,A
F4FF CDF6F6 CALL PBADR ;OUTPUT THE RECORD LENGTH AND EP
F502 3E01 MVI A,1 ;PUNCH RECORD TYPE = 1
F504 CDFEF6 CALL PBYTE
F507 AF XRA A
F508 92 SUB D ;OUTPUT THE CHECKSUM
F509 CDFEF6 CALL PBYTE
JMPR LEO ;GO DO THE TRAILER
F5OC+1803
;
; LEADER ROUTINE 'PUNCHES' SIX INCHES (OR AS SPECIFIED)
; OF LEADER ON THE PAPER TAPE PUNCH. NULLS ARE PUNCHED
; TO FORM THE LEADER (OR TRAILER).
F50E CDD7F0 LEADER: CALL EXPR1 ;SEE IF SOME OTHER LENGTH WANTED
F511 C1 LEO: POP B ;GET THE VALUE
F512 78 MOV A,B
F513 B1 ORA C ;TEST FOR DEFAULT SELECT
F514 41 MOV B,C ;MOVE NEW VALUE IN JUST IN CASE
F515 0E00 MVI C,0 ;GET A NULL CHARACTER
JRNZ LE1 ;JUMP IF NEW VALUE WANTED
F517+2002
F519 063C MVI B,60 ;DEFAULT SET 60 NULLS
F51B CD0CF0 LE1: CALL PUNCH ;PUNCH ONE NULL
DJNZ LE1 ;KEEP GOING TIL DONE
F51E+10FB
F520 C9 RET
;
; QUERY ROUTINE WILL TELL THE OPERATOR WHAT HIS CURRENT LOGICAL
; PHYSICAL PERIPHERAL DEVICE ASSIGNMENTS ARE. NO PARAME
; (OTHER THAN A CARRIAGE RETURN) ARE REQUIRED ON ENTRY.
F521 3A0300 QUERY: LDA IOBYTE ;GET THE ASSIGNMENT CONTROL BYTE
F524 0604 MVI B,4 ;SET UP FOR FOUR LOGICAL DEVICES
F526 217DF1 LXI H,ACT ;ADDRESS OF CONVERSION TABLE
F529 11FBFF LXI D,ALT-APT ;NEGATIVE OFFSET FOR LOGICAL TABLE
F52C F5 QUE1: PUSH PSW
F52D CDFEF5 CALL BLK ;FORMAT THE PRINT OUT
F530 4E MOV C,M ;GET THE CURRENT LOGICAL DEVICE CODE
F531 CD09F0 CALL CONOUT ;OUTPUT IT
F534 CDF7F5 CALL DASH ;OUTPUT A DASH
F537 F1 POP PSW ;REGET THE CONTROL BYTE
F538 F5 PUSH PSW ;RESAVE IT
F539 E5 PUSH H ;SAVE THE TABLE POINTER
F53A 23 QUE2: INX H ;ADJUST POINTER TO CURRENT PHYSICAL DE
F53B 3C INR A
F53C E603 ANI 3 ;BITS 0 AND 1 ARE 0 WHEN ON CURRENT AS
JRNZ QUE2 ;NOT THERE YET, TRY AGAIN
F53E+20FA
F540 4E MOV C,M ;FOUND IT, NOW PRINT IT
F541 CD09F0 CALL CONOUT
F544 E1 POP H
F545 F1 POP PSW ;GO TO NEXT LOGICAL DEVICE
F546 1F RAR ;ADJUST THE IOBYTE
F547 1F RAR
F548 19 DAD D ;ADJUST THE TABLE POINTER
DJNZ QUE1 ;GO DO NEXT LOGICAL DEVICE
F549+10E1
F54B C9 RET ;RETURN TO MONITOR
;
; READ ROUTINE READS AN INTEL HEX FORMAT PAPER TAPE FROM
; THE CURRENT PAPER TAPE READER. IF A NON ZERO ADDRESS
; IS SPECIFIED IN THE END OF FILE RECORD CONTROL WILL
; BE TRANSFERRED TO THAT ADDRESS. OTHERWISE, CONTROL
; WILL REVERT TO THE EXECUTIVE.
F54C CDD7F0 READ: CALL EXPR1 ;GET OFFSET BIAS
F54F E1 REDO: POP H ; INTO (H,L)
F550 E5 PUSH H ;SAVE THE BIAS
F551 CD86F4 RED1: CALL RIX ;READ A BYTE
F554 DE3A SBI ':' ;LOOK FOR START OF RECORD
JRNZ RED1 ;JUMP TO KEEP LOOKING
F556+20F9
F558 57 MOV D,A ;INITIALIZE CHECKSUM
F559 CD73F4 CALL BYTE ;GET RECORD LENGTH
JRZ RED3 ;JUMP IF EOF RECORD
F55C+2823
F55E 5F MOV E,A ;ELSE, ASSUME DATA RECORD
F55F CD73F4 CALL BYTE ;GET LOAD ADDRESS HIGH BYTE
F562 F5 PUSH PSW ;SAVE IT
F563 CD73F4 CALL BYTE ;GET LOAD ADDRESS LOW BYTE
F566 C1 POP B ;BUILD ADDRESS IN (B,C)
F567 4F MOV C,A
F568 09 DAD B ;ADD ON THE BIAS
F569 CD73F4 CALL BYTE ;SKIP OVER RECORD TYPE
F56C CD73F4 RED2: CALL BYTE ;GET A DATA BYTE
F56F 77 MOV M,A ;PUT IT INTO MEMORY
F570 2F CMA ;D0 A QUICK CHECK
F571 AE XRA M ; RESULT SHOULD BE ZERO
F572 C4A1F2 CNZ BITS ;IF ERROR PRINT ADDRESS AND DATA
F575 23 INX H ;INCREMENT MEMORY POINTER
F576 1D DCR E ;RECORD LENGTH FOR LOOP CONTROL
JRNZ RED2 ;DO REST OF THE RECORD
F577+20F3
F579 CD73F4 CALL BYTE ;GET THE CHECKSUM
F57C C209F1 JNZ QPRT ;ABORT IF ERROR
JMPR REDO ;GO DO NEXT RECORD
F57F+18CE
F581 CD73F4 RED3: CALL BYTE ;EOF RECORD GET ENTRY POINT
F584 67 MOV H,A ;HIGH BYTE TO (H)
F585 CD73F14 CALL BYTE ;GET THE LOW BYTE
F588 6F MOV L,A
F589 B4 ORA H ;SEE IF IT IS ZERO
F58A D1 POP D ;RESTORE THE STACK
F58B C8 RZ ;RETURN TO MONITOR IF EP=0
F58C E9 PCHL ;ELSE, GO TO THE ENTRY POINT
;
; WRITE ROUTINE IS USED TO PUNCH AN INTEL HEX FORMAT
; PAPER TAPE ON THE CURRENT ASSIGNED PUNCH UNIT.
;
F58D CD86F3 WRITE: CALL EXPR3 ;GET 3 PARAMETERS, DO CRLF
F590 AF XRA A ;SEE IF RECORD LENGTH CHANGE
F591 47 MOV B,A ;SET HIGH BYTE TO ZERO
F592 B1 ORA C ;NOW SEE IF CHANGE WANTED
JRNZ WRI1 ;YES, JUMP AND SET IT UP
F593+2002
F595 0E10 MVI C,16 ;NO, DEFAULT TO 16 BYTES/RECORD
F597 E5 WRI1: PUSH H ;SAVE MEMORY POINTER
F598 09 DAD B ;ADD THE RECORD LENGTH
F599 B7 ORA A ;CLEAR THE CARRY BIT
DSBC D ;SEE IF FULL RECORD REMAINS
F59A+ED52
F59C E1 POP H ;RESTORE (H,L)
F59D+380A JRC WRI2 ;GO DO A FULL RECORD
F59F D5 PUSH D ;SAVE LAST BYTE ADDRESS
F5AO EB XCHG ;SWAP (D,E) AND(H,L)
F5A1 B7 ORA A ;RESET THE CARRY BIT
DSBC D ;FIND # OF BYTE REMAINING
F5A2+ED52
F5A4 23 INX H ;ADJUST TO INCLUDE LAST BYTE
F5A5 E3 XTHL ;SWAP TOP OF STACK
F5A6 EB XCHG ;SET (D,E) (H,L) TO NORMAL
F5A7 C1 POP B ;NEW RECORD LENGTH TO (B,C)
F5A8 D8 RC ;DONE IF ZERO LENGTH RECORD
F5A9 C5 WRI2: PUSH B ;SAVE LOOP COUNT
F5AA D5 PUSH D
F5AB 50 MOV D,B ;ZERO THE CHECKSUM
F5AC 41 MOV B,C ;MOVE LOOP CONTROL TO B
F5AD CDC8F5 CALL PSOR ;PUNCH START OF RECORD
F5BO 78 MOV A,B ;GET RECORD LENGTH
F5B1 CDF6F6 CALL PBADR ;PUNCH IT
F5B4 AF XRA A ;PUNCH RECORD TYPE '0'
F5B5 CDFEF6 CALL PBYTE
F5B8 7E WRI3: MOV A,M ;GET NEXT DATA BYTE
F5B9 23 INX H ;BUMP THE POINTER
F5BA CDFEF6 CALL PBYTE ;PUNCH THE DATA
DJNZ WRI3 ;DO REST OF RECORD
F5BD+10F9
F5BF AF XRA A ;NOW, DO THE CHECKSUM
F5CO 92 SUB D
F5C1 CDFEF6 CALL PBYTE ;PUNCH IT
F5C4 D1 POP D ;RESTORE THE REGISTERS
F5C5 C1 POP B
JMPR WRI1 ;GO DO NEXT RECORD
F5C6+18CF
F5C8 CD7CF4 PSOR: CALL PEOL
F5CB 0E3A MVI C,':'
F5CD C37CF6 JMP PO
;
; HEXN ROUTINE
;
;THIS ROUTINE ADDS AND SUBTRACTS TWO HEXADECIMAL 16 BIT
; UNSIGNED NUMBERS AND DISPLAYS THE RESULTS ON THE
; CONSOLE.
F5DO CDA4F6 HEXN: CALL EXLF ;GET THE TWO NUMBERS
F5D3 E5 PUSH H ;SAVE IT FOR THE SUBTRACT
F5D4 19 DAD D ;ADD THEM
F5D5 CDFBF5 CALL LADRB ;OUTPUT THEM
F5D8 E1 POP H ;REGET THE FIRST NUMBER
F5D9 B7 ORA A ;CLEAR THE CARRY BIT
DSBC D ;DO THE SUBTRACT
F5DA+ED52
JMPR LADR ;GO OUTPUT THE RESULT
F5DC+1803
;
; ROUTINE LADR PRINTS THE CONTENTS OF (H,L) ON THE
; CURRENT CONSOLE EITHER AT THE SART OF A NEW
; LINE (EP = LADRA) OH AT THE CURRENT LOCATION (EP =
; LADR).
F5DE CDA9F6 LADRA: CALL CRLF ;START A NEW LINE
F5E1 7C LADR: MOV A,H ;GET HIGH TWO DIGITS
F5E2 CDE6F5 CALL HEX1 ;PRNT THEM
F5E5 7D MOV A,L ;GET LOW TWO DIGITS
F5E6 F5 HEX1: PUSH PSW ;SAVE THE LOW DIGIT
F5E7 0F RRC ;PUT HIGH NIBBLE INTO BITS 0-3
F5E8 0F RRC
F5E9 0F RRC
F5EA 0F RRC
F5EB CDEFF5 CALL HEX2 ;GO PRINT SINGLE DIGIT
F5EE F1 POP PSW ;REGET THE LOW DIGIT
F5EF CD6EF3 HEX2: CALL CONV ;GO INSERT ASCII ZONE
JMPR CO ;DO THE CHARACTER OUTPUT
F5F2+180C
;
; ROUTINE DASH TYPES A DASH ON THE CURRENT CONSOLE DEVICE.
;
F5F4 CDE6F5 DASH1: CALL HEX1 ;FIRST, PRINT ACCUM AS TWO HEX DIGITS
F5F7 0E2D DASH: MVI C,'-' ;GET AN ASCII DASH
JMPR CO ;GO TYPE IT
F5F9+18O5
;
; IOBYTE HANDLERS
;
F5FB ORG MOSS+5FBH
F5FB CDDEF5 LADRB: CALL LADRA ;OUTPUT (H,L) AS 4 ASCII DIGITS
F5FE 0E20 BLK: MVI C,' ' ;OUTPUT A BLANK
F600 3A0300 CO: LDA IOBYTE
F603 E603 ANI 3 ;ISOLATE CONSOLE ASGT
F605 CADEF6 JZ TTYOUT ;TTY DEVICE ACTIVE
F608 FE02 CPI 2
F60A FA62F4 JM CRTOUT ;CRT ACTIVE
F6OD C262F4 JNZ CUSO1 ;USER CONSOLE 1 ACTIVE
F610 3A0300 LO: LDA IOBYTE
F613 E6C0 ANI 0C0H ;ISOLATE LIST ASGT
F615 CADEF6 JZ TTYOUT ;TTY DEVICE ACTIVE
F618 FE80 CPI 80H
F61A FA62F4 JM CRTOUT ;CRT ACTIVE
F61D CA62F4 JZ LPRT ;LINE PRINTER ACTIVE
F620 C362F4 JMP LUSE1 ;USER PRINTER 1 ACTIVE
;
F623 3A0300 CSTS: LDA IOBYTE
F626 E603 ANI 3 ;ISOLATE CONSOLE ASGT
F628 CAC6F6 JZ TTST ;TTY ACTIVE
F62B FE02 CPI 2
F62D FA62F4 JM CRTST ;CRT ACTIVE
F630 C262F4 JNZ CUST1 ;USER CONSOLE 1 ACTIVE
;
F633 3A0300 BATST: LDA IOBYTE
F636 E60C ANI 0CH ;ISOLATE BATCH ASGT
F638 CAC6F6 JZ TTST ;TTY ACTIVE
F63B FE08 CPI 8
F63D FA62F4 JM PTRST ;PAPER TAPE READER ACTIVE
F64O CA62F4 JZ RUST1 ;USER READER 1 ACTIVE
F643 C362F4 JMP RUST2 ;USER READER 2 ACTIVE
;
F646 3A0300 CI: LDA IOBYTE
F649 E603 ANI 3 ;ISOLATE CONSOLE ASGT
F64B CACEF6 JZ TTYIN ;TTY DEVICE ACTIVE
F64E FE02 CPI 2
F650 FA62F4 JM CRTIN ;CRT ACTIVE
F653 C262F4 JNZ CUSI1 ;USER CONSOLE 1 ACTIVE
;
F656 3A0300 RI: LDA IOBYTE
F659 E60C ANI 0CH ;ISOLATE BATCH ASGT
F65B CACEF6 JZ TTYRDR ;TTY ACTIVE
F65E FE08 CPI 8
F660 FA62F4 JM PTRIN ;PAPER TAPE READER ACTIVE
F663 CA62F4 JZ RUSI1 ;USER READER I ACTIVE
F666 C362F4 JMP RUSI2 ;USER READER 2 ACTIVE
;
F669 3A0300 LSTAT: LDA IOBYTE
F66C E6C0 ANI 0C0H ;ISOLATE THE LIST DEVICE ASSIGNMENT
F66E CAD6F6 JZ TTOST
F671 FE80 CPI 80H
F673 FA62F4 JM CRTOST
F676 CA62F14 JZ LPRST
F679 C362F4 JMP LUST1
;
F67C 3A0300 PO: LDA IOBYTE
F67F E630 ANI 30H ;ISOLATE PUNCH ASGT
F681 CADEF6 JZ TTPNCH ;TTY ACTIVE
F684 FE20 CPI 20H
F686 FA62F4 JM HSP ;HIGH SPEED PUNCH ACTIVE
F689 CA62F4 JZ PUSO1 ;USER PUNCH 1 ACTIVE
F68C C362F4 JMP PUSO2 ;USER PUNCH 2 ACTIVE
;
; ROUTINE CONI READS THE CONSOLE AND STRIPS OFF THE ASCII
; PARITY BIT.
;
F68F CD46F6 CONI: CALL CI ;GET THE NEXT CHARACTER
F692 E67F ANI 7FH ;STRIP OFF THE PARITY BIT
F694 C9 RTS: RET
;
; ROUTINE PRTWD PRINTS AN ASCII STRING ONTO THE CONSOLE.
; THE STRING MUST BE TERMINATED BY BIT 7 SET IN THE
; LAST CHARACTER OF THE STRING. THE STRING WILL START
; A NEW LINE (EP = PRTWD) OR CONTINUE ON THE SAME
; LINE (EP = PRTWA)
F695 CDA9F6 PRTWD: CALL CRLF ;START A NEW LINE
F698 C5 PRTWA: PUSH B ;SAVE (B,C)
F699 4E PRTA: MOV C,M ;GET NEXT CHARACTER FROM MEMORY
F69A CD00F6 CALL CO ;OUTPUT IT
F69D 23 INX H ;INCREMENT MEMORY POINTER
F69E 79 MOV A,C
F69F 07 RLC ;TEST FOR BIT 7 DELIMITER
JRNC PRTA ;NO DELIMITER, GO DO NEXT CHARACTER
F6AO+30F7
F6A2 C1 PRTB: POP B ;RESTORE (B,C)
F6A3 C9 RET
;
; ROUTINE EXLF READS TWO PARAMETERS, PUTS THEM INTO THE
' D,E AND H,L REGISTERS, THEN DOES A CARRIAGE RETURN,
; LINE FEED SEQUENCE.
;
F6A4 CDD9F0 EXLF: CALL EXPR ;GO GET TWO PARAMETERS
F6A7 D1 POP D
F6A8 E1 POP H
;
; ROUTINE CRLF GENERATES A CARRIAGE RETURN, LNE FEED
; SEQUENCE ON THE CURRENT CONSOLE TO START A NEW LINE
; IT INCLUDES TRHEE NULL CHARACTERS FOR TTY TYPE
; DEVICES FOR THE HEAD MOVEMENT TIME.
;
F6A9 E5 CRLF: PUSH H ;SAVE THE CONTENTS OF (H,L)
F6AA 21C2F6 CRLFA: LXI H,CRMSG ;ADDRESS OF CR,LF MESSAGE
F6AD CD98F6 CALL PRTWA ; OUTPUT IT
F6BO E1 POP H ;RESTORE (H,L)
F6B1 C9 RET
;
F6B2 21BBF6 RSTER: LXI H,RSTMSG ;GET ADDRESS OF RESTART ERROR MSG
F6B5 CD95F6 COMERR: CALL PRTWD ;PRINT IT ON NEW LINE
F6B8 C30000 JMP WSVEC ;GO TO WARM BOOT
F6BB 5253542045 RSTMSG: DB 'RST ER','R'+80H
F6C2 0D0A0080 CRMSG: DB CR,LF,0,80H
;
; I/O DRIVERS FOR THE 8250 ASYNC COMM ELEMENT
;
F6C6 DB25 TTST: IN SLSTAT ;GET 8250 LINE STATUS
F6C8 E601 ANI 1 ;SEE IF RECEIVE DATA AVAILABLE
F6CA C8 RZ ;RETURN IF NOT
F6CB C6FE ADI 0FEH ;FLAG THAT DATA IS AVAILABLE
F6CD C9 RET
;
F6CE DB25 TTYIN: IN SLSTAT ;GET 8250 LINE STATUS
F6D0 1F RAR ;MOVE RX DATA READY BIT INTO CARRY
JRNC TTYIN ;LOOP UNTIL DATA IS IN
F6D1+30FB
F6D3 DB20 IN SDATA ;READ THE DATA
F6D5 C9 RET
;
F6D6 DB25 TTOST: IN SLSTAT ;GET 8250 LINE STATUS
F6D8 E620 ANI 20H ;ISOLATE TX BUFFER EMPTY BIT
F6DA C8 RZ ;RETURN IF NOT EMPTY
F6DB C6BF ADI 0BFH ;FLAG THE EMPTY STATE
F6DD C9 RET
;
F6DE DB25 TTYOUT: IN SLSTAT ;GET 8250 LINE STATUS
F6EO E620 ANI 20H ;ISOLATE THRE BIT
JRZ TTYOUT ;WAIT UNTIL ONE OF THE REGISTERS EMPTI
F6E2+28FA
F6E4 79 MOV A,C ;MOVE THE DATA OVER
F6E5 D320 OUT SDATA ;OUTPUT THE DATA
F6E7 C9 RET
;
; EQUATES FOR ADDITIONAL CONSOLE DEVICES
F462 = CRTIN EQU IOER
F462 = CRTOUT EQU IOER
F462 = CRTST EQU IOER
F462 = CRTOST EQU IOER ;UNASSIGNED CRT OUTPUT STATUS
F462 = CUSI1 EQU IOER ;UNASSIGNED USER CONSOLE (INPUT)
F462 = CUSO1 EQU IOER ;UNASSIGNED USER CONSOLE (OUTPUT)
F462 = CUST1 EQU IOER
;
; EQUATES FOR ADDITIONAL PAPER TAPE PUNCH DEVICES
F6DE = TTPNCH EQU TTYOUT ;UNASSIGNED TELETYPE PUNCH
F462 = HSP EQU IOER ;UNASSIGNED HIGH SPEED PUNCH
F462 = HSPST EQU IOER ;UNASSIGNED HJGH SPEED PUNCH STATUS
F462 = PUSO1 EQU IOER ;UNASSIGNED USER PUNCH 1
F462 = PUSO2 EQU IOER ;UNASSIGNED USER PUNCH 2
;
; EQUATES FOR ADDITIONAL LIST DEVICES
F462 = LPRT EQU IOER ;UNASSIGNED LINE PRINTER
F462 = LPRST EQU IOER ;UNASSIGNED PRINTER STATUS
F462 = LUSE1 EQU IOER ;LIST DEVICE 1
F462 = LUST1 EQU IOER ;LIST DEVICE 1 STATUS
;
; EQUATES FOR ADDITIONAL PAPER TAPE READER DEVICES
F6CE = TTYRDR EQU TTYIN ;UNASSIGNED TELETYPE PAPER TAPE READER
F462 = PTRIN EQU IOER ;UNASSIGNED HIGH SPEED PAPER TAPE READ
F462 = PTRST EQU IOER ;UNASSIGNED HS PTR STATUS
F462 = RUSI1 EQU IOER ;UNASSIGNED PAPER TAPE READER 1
F462 = RUST1 EQU IOER ;UNASSIGNED PAPER TAPE READER 1 (STATUS)
F462 = RUSI2 EQU IOER ;UNASSIGNED PAPER TAPE READER 2
F462 = RUST2 EQU IOER ;UNASSIGNED PAPER TAPE READER 2 (STATUS)
;
F6E8 CDF0F6 BYT: CALL RIBBLE ;READ AND CONVERT ONE CHARACTER
F6EB 07 RLC ;SHIFT INTO HIGH NIBBLE
F6EC 07 RLC
F6ED 07 RLC
F6EE 07 RLC
F6EF 47 MOV B,A ;SAVE IN B TEMPORARILY
F6F0 CD86F4 RIBBLE: CALL RIX ;READ A CHARACTER
F6F3 C3B0F3 JMP NIBBLE ;GO CONVERT TO HEX DIGIT
;
; PADR ROUTINE PUNCHES (H,L) AS FOUR ASCII CHARACTERS.
; IT IS USED TO PUT THE ADDRESS INTO AN INTEL HEX
; FORMAT RECORD.
;
F6F6 CDEEF6 PBADR: CALL PBYTE
F6F9 7C PADR: MOV A,H
F6FA CDFEF6 CALL PBYTE
F6FD 7D MOV A,L
;
; PBYTE ROUTINE PUNCHES (A) AS TWO ASCII CHARACTERS ON
; THE CURRENT PUNCH DEVICE.
;
F6FE F5 PBYTE: PUSH PSW ;SAVE THE BYTE
F6FF 0F RRC ;DO HIGH NIBBLE FIRST
F700 0F RRC
F701 0F RRC
F702 0F RRC
F703 CD6EF3 CALL CONV ;CONVERT TO ASCII
F706 CD0CF0 CALL PUNCH ;PUNCH IT
F709 F1 POP PSW ;GET LOW NIBBLE
F70A F5 PUSH PSW ;RESAVE F0R CHECKSUM
F70B CD6EF3 CALL CONV ;CONVERT TO ASCII
F70E CD0CF0 CALL PUNCH ;PUNCH IT
F711 F1 POP PSW
F712 82 ADD D ;UPDATE CHECKSUM
F713 57 MOV D,A
F714 C9 RET
;
F715 END