						;
						;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
