Compucolor.org – Virtual Media

Listing of file='MONITR.SRC;01' on disk='vmedia/source_1-sector.ccvf'

;	MANAZIRS MONITOR FOR 6.78 AND 8.79
;
;
; THE FOLLOWING IS AN EXPLANATION OF THE COMMANDS AND
; SYMBOLOGY USED.
;-<REGISTER MODIFY COMMAND>=X<REGISTER IDENTIFIER>
;-<REGISTER IDENTIFIER>=A!B!C!D!E!F!H!L!M!P!S!
;-<ASCII MEMORY COMMAND>=A< # >,< # >
;-<COMPARE MEMORY COMMAND>=C< # >,< # >,< # >
;-<DISPLAY MEMORY COMMAND>=D< # >,< # >
;-<EXIT MONITOR COMMAND>=E
;-<NON-DESTRUCTIVE MEMORY TEST COMMAND>=N< # >,< # >
;-<SEARCH MEMORY COMMAND>=W< # >,< # >,< # >,< $ >
;-<FILL MEMORY COMMAND>=F< # >,< # >,< $ >
;-<PROGRAM EXECUTE COMMAND>=G< # >,< # >,< # >
;-<HEXADECIMAL ARITHEMETIC COMMAND>=H< # >,< # >
;-<MOVE MEMORY COMMAND>=M< # >,< # >,< # >
;-<SUBSTITUTE MEMORY COMMAND>=S< # >
;
;-SYSTEM SIGNS ON WITH <CR><LF><.>
;
LF	EQU	10	; <ASCII LINEFEED>
KTST	EQU	0024H	; KEYBOARD SCANNER
CR	EQU	0DH	; <ASCII CARRIAGE RETURN>
INPCRT	EQU	81C5H	; JUMP VECTOR #31
KBDFL	EQU	81DFH	; HOLDS NUMBER OF JUMP VECTOR FOR THE
			;  KEYBOARD
KBRDY	EQU	81FFH	; KEYBOARD READY FLAG
STACK	EQU	0BFFFH	; STACK POINTER
UVEC	EQU	81BFH	; "ECS USER" VECTOR
RST1J	EQU	81C8H	; RESTART VECTOR JUMPS HERE FROM ROM
;
	ORG	0BA00H
;
TAP:	DS	2	; A REGISTER & FLAGS
TBC:	DS	2	; B & C REGISTERS
TDE:	DS	2	; D & E REGISTERS
TSP:	DS	2	; SP REGISTER
THL:	DS	2	; H & L REGISTERS
TPC:	DS	2	; PC REGISTER
T1A:	DS	2	; TRAP 1 ADDRESS
	DS	1	; TRAP 1 VALUE
	DS	2	; TRAP 2 ADDRESS
	DS	1	; TRAP 2 VALUE
CHARIN:	DS	1	; TEMPORARY CHARACTER STORAGE
;
START1:	DI		;DISABLE INT
	LDA	092AH	;TEST LOCATION
	CPI	01FH	;TEST VALUE IN 8.79
	JNZ	CIINIT	;IF NOT 0BAH, IS 6.78
	LXI	H,OLDVEC  ;IF 0BAH, IS 8.79 SO
	LXI	D,NEWVEC  ;OVERLAY.
	LXI	B,LENTH	  ;BYTE COUNT

OVLAY:	LDAX	D
	MOV	M,A
	INX	H
	INX	D
	DCX	B
	MOV	A,B
	ORA	C
	JNZ	OVLAY
	EI
	JMP	CIINIT	;INIT ADDR

;
OLDVEC:

LO:	JMP	3392H
OSTR:	JMP	33F4H
CMPDH:	JMP	3453H
ADHLA:	JMP	3518H
SUBHD:	JMP	3459H
LBYT:	JMP	339BH
NIBL:	JMP	33B3H
BLK:	JMP	34B3H
;
LENTH	EQU	$-OLDVEC
;

NEWVEC:

	JMP	17C8H	;LO
	JMP	182AH	;OSTR
	JMP	1889H	;CMPDH
	JMP	194EH	;ADHLA
	JMP	188FH	;SUBHD
	JMP	17D1H	;LBYT
	JMP	17E9H	;NIBL
	JMP	18E9H	;BLK
;
;
;	- PROGRAM ENTRY POINT
;
;
;	CIINIT - THE CHARACTER INPUT INITIALIZATION ROUTINE
;		SETS UP THE PARAMETERS NECESSARY FOR THE
;		'CHRINT' AND 'CI' ROUTINES.
;
CIINIT:	MVI	A,31	; SETUP JUMP VECTOR #31
	STA	KBDFL	; STORE IN KEYBOARD FLAG
	MVI	A,0C3H	; LITERALLY 'JMP'
	STA	INPCRT
	LXI	H,CHRINT; GET ADDRESS OF 'CHRINT' ROUTINE
	SHLD	INPCRT+1; PLACE ADDRESS AFTER 'JMP'
	XRA	A
	STA	KBRDY	; CLEAR KEYBOARD READY FLAG
	STA	CHARIN	; CLEAR TEMPORARY CHARACTER STORAGE
	LXI	H,CIINIT; GET ADDRESS OF 'CIINIT' ROUTINE
	SHLD	UVEC+1	; PLACE ADDRESS AFTER 'JMP'
	MVI	A,0C3H	; LITERALLY 'JMP'
	STA	UVEC	; STORE 'JMP'
;
;	- SET USER MEMORY FOR REGISTERS, STACK POINTER,
;	  AND RESTART FOR BREAKPOINTS.
;
;
BEGIN:
	LXI	H,TAP	; POINT TO USER PSW
	MVI	B,T1A+6-TAP	; SET COUNT
BG1:	MVI	M,0	; INITIALIZE ...
	INX	H	; ... USER'S REGISTERS
	DCR	B	; FINISHED?
	JNZ	BG1	; NO?: LOOP!
	LXI	H,STACK	; INITIALIZE ...
	SHLD	TSP	; ... USER'S SP
	SPHL		; SET SP
	MVI	A,0C3H	; GET 'JMP'
	STA	RST1J	; STORE IN RAM
	LXI	H,RESTART	; RESTART ADDRESS
	SHLD	RST1J+1	; STORE RESTART ADDRESS IN RAM
;
;	- TYPE SIGN-ON.
;
SIGNON:	LXI	H,VERS	; ADDRESS OF MESSAGE
	CALL	OSTR
	JMP	START
VERS:	DB	12,LF,29,13H,'COMPUCOLOR'
	DB	17H,' II'
	DB	15H,' MONITOR '
	DB	16H,'V'
	DB	'1.0 ',20,'BY R. M. MANAZIR'
	DB	239
;
;	- MAIN COMMAND LOOP.
;
START:
	LXI	H,CRTBL	; CR,LF,GRN,239
	CALL	OSTR
	DI		; DISABLE INTERRUPTS
	LXI	SP,STACK; SET SP
	XRA	A
	CALL	CIX	; GET A CHARACTER
	CALL	LO
	SUI	'A'	; TEST FOR A-X
	JM	START	; LESS THAN A, ERROR
	CPI	'X'-'A'+1
	JP	ERROR	; GREATER THAN X, ERROR
	CALL	GTABL
	JMP	START
;
;	- COMMAND BRANCH TABLE.
;
TBL:
	DW	ASCII	; A - ASCII DISPLAY OF MEMORY
	DW	ERROR	; B
	DW	COMPR	; C - COMPARE MEMORY
	DW	DISP	; D - DISPLAY MEMORY
	DW	EXIT	; E - EXIT MONITOR
	DW	FILL	; F - FILL MEMORY
	DW	GOTO	; G - GO TO ADDRESS
	DW	HEXN	; H - SUM DIFFERENCE
	DW	ERROR	; I
	DW	ERROR	; J
	DW	ERROR	; K
	DW	ERROR	; L
	DW	MOVE	; M - MOVE MEMORY
	DW	NDMT	; N - NON-DESTRUCTIVE MEMORY TEST
	DW	ERROR	; O
	DW	ERROR	; P
	DW	ERROR	; Q
	DW	ERROR	; R
	DW	SUBS	; S - SUBSTITUTE MEMORY
	DW	ERROR	; T
	DW	ERROR	; U
	DW	ERROR	; V
	DW	SRCH	; W - FIND BYTE/WORD/THREE BYTES
	DW	X	; X - EXAMINE & MODIFY REGISTERS
;
;	- CARRIAGE RETURN TABLE
;
	DB	6,7,'?'	; ERROR
CRTBL:	DB	CR,LF,6,2,'.'
	DB	239	; TERMINATOR
;
GTABL:	MVI	C,2	; SET FOR 2 VARIABLES
	LXI	H,TBL
	PUSH	H
CODEX:	RLC		; DOUBLE
	CALL	ADHLA	; ADD A TO H&L
	MOV	A,M
	INX	H
	MOV	H,M
	MOV	L,A
	XTHL		; PUT ADDRESS ON STACK, RESTORE H&L
	XRA	A
	RET		; DISPATCH!
;
;	CHRINT - THE CHARACTER INTERRUPT ROUTINE IS VECTORED
;		TO FROM THE KEYBOARD INPUT ROUTINE THROUGH
;		THE JUMP VECTOR 'INPCRT' (#31).  THE CHARACTER
;		FROM THE KEYBOARD INPUT ROUTINE IS IN
;		REGISTER E.
;
CHRINT:	PUSH	H	; SAVE REGISTERS THAT WILL BE USED
	PUSH	PSW
	LXI	H,CHARIN; GET ADDRESS OF TEMP CHARACTER STORAGE
	XRA	A	; CLEAR A
	CMP	M	; TEST FOR 'CHARIN' = 0
	JNZ	CFIN	; IF NOT ZERO, THEN IGNORE INPUT
	MOV	A,E	; GET CHARACTER FROM E
	ANI	127	; STRIP UPPER BIT FOR ASCII
	MOV	M,A	; STORE IN 'CHARIN'
CFIN:	POP	PSW	; RESTORE USED REGISTERS
	POP	H	;
	EI		; ENABLE INTERRUPTS
	RET		; RETURN FROM INTERRUPT
;
;	- DISPLAY MEMORY IN HEX ON CRT.
;
DISP:	CALL	EXPR	; GET TWO ADDRESSES
	POP	D	; GET HIGH ADDRESS
	POP	H	; GET LOW ADDRESS
DI0:	CALL	CRLF	; GREEN
DI1:	CALL	LADR	; PRINT MEMORY ADDRESS
	MVI	A,13H	; YELLOW
	CALL	LO
DI2:	CALL	BLK	; PRINT SPACE
	MOV	A,M
	CALL	LBYT	; PRINT DATA
	CALL	ABTEST	; CHECK FOR BREAK
	CALL	HILO	; TEST FOR COMPLETION
	RC
	MOV	A,L
	ANI	0FH	; PRINT CR,LF,ADDRESS
	JNZ	DI2
	JMP	DI0
;
;	- FILL ROUTINE, FILL RAM MEMORY
;	- BLOCK WITH CONSTANT.
;
FILL:
	INR	C	; GET 3 PARAMETERS
	CALL	EXPR
	POP	B	; GET DATA IN C
	POP	D	; GET HIGH ADDRESS
	POP	H	; GET LOW ADDRESS
FI0:
	MOV	M,C	; STORE CONSTANT
	CALL	HILO	; TEST FOR COMPLETION
	JNC	FI0	; CONTINUE LOOP!
	RET
;
;	- MOVE A BLOCK OF RAM MEMORY.
;
MOVE:
	INR	C	; GET THREE ADDRESSES
	CALL	EXPR
	POP	B	; DESTINATION
	POP	D	; SOURCE END
	POP	H	; SOURCE BEGIN
MV0:
	MOV	A,M	; GET A DATA BYTE
	STAX	B	; STORE AT DESTINATION
	INX	B	; MOVE DESTINATION
	CALL	HILO	; TEST FOR COMPLETION
	JNC	MV0
	RET
;
;	- SUBSTITUTE ROUTINE, MODIFY RAM
;	- MEMORY WITH KEYBOARD INPUTS.
;
SUBS:
	DCR	C	; INITIALLY SET FOR TWO VALUES
	CALL	EXPR	; GET ONE ADDRESS
	CALL	P2C
	POP	H
	RC
SU0:
	MVI	A,18	; SET DISPLAY TO GREEN
	CALL	LO
	MOV	A,M
	CALL	LBYT	; DISPLAY DATA
	MVI	A,'-'
	CALL	LO
	CALL	PCHK	; CHECK DELIMITER
	RC		; CR ENTERED, RETURN
	JZ	SU1	; SPACE ENTERED,
	PUSH	H	; SAVE MEMORY AND
	CALL	EXF	; ..GET NEW VALUE
	POP	D	; E = VALUE
	POP	H	; RESTORE MEMORY
	MOV	M,E	; STORE NEW VALUE
	MOV	A,B	; TEST DELIMITER
	CPI	CR
	RZ		; CR ENTERED AFTER
SU1:
	INX	H
	JMP	SU0
;
;	- EXAMINE AND MODIFY CPU REGISTER.
;
X:
	CALL	CI	; GET REGISTER
	LXI	H,ACTBL	; POINT TO ACCESS
	CPI	CR
	JZ	X6	; FULL REGISTER DISPLAY
X0:
	CMP	M
	JZ	X1
	PUSH	PSW	; SAVE CHARACTER
	MOV	A,M	; NOT THE RIGHT CHARACTER
	ORA	A
	JM	ERROR	; END OF TABLE
	INX	H
	INX	H
	INX	H
	POP	PSW	; RETRIEVE CHARACTER
	JMP	X0
X1:
	CALL	BLK
X2:
	MVI	A,18	; SET DISPLAY TO GREEN
	CALL	LO
	CALL	X8
	INR	B
	MVI	A,'-'
	CALL	LO
	CALL	PCHK	; SKIP IF NULL E
	RC		; CR ENTERED, RETURN
	JZ	X5
	PUSH	H	; SAVE POINTER TO
	PUSH	B	; SAVE PRECISION
	CALL	EXF	; GET NEW REGISTER VALUE
	POP	H
	POP	PSW	; A = PRECISION
	PUSH	B	; B = DELIMITER
	PUSH	PSW	; A = PRECISION
	MOV	A,L
	STAX	D	; STORE LSB IN REGISTER
	POP	B	; RETRIEVE PRECISION
	DCR	B
	JZ	X4	; 8 BITS ONLY
	INX	D
	MOV	A,H
	STAX	D	; STORE MSB IN REGISTER
X4:
	POP	B	; RETRIEVE DELIMITER
	POP	H
X5:
	MOV	A,M	; TEST FOR END (0)
	ORA	A
	RM
	MOV	A,B	; TEST DELIMITER
	CPI	CR
	RZ
	JMP	X2
X6:
	CALL	CRLF
X7:
	CALL	BLK	; OUTPUT A SPACE
	MOV	A,M	; GET CHARACTER
	ORA	A	; SET CODES
	RM		; ALL DONE
	CALL	LO	; PRINT CHARACTER
	MVI	A,'='
	CALL	LO	; PRINT '='
	CALL	X8
	JMP	X7
X8:
	INX	H
	MOV	E,M	; GET LO BYTE OF ADDRESS
	MVI	D,TAP SHR 8	; SET HI BYTE OF ADDRESS
	INX	H	; POINT AT PRECISION
			; HL = TAB ADDRESS
			; DE = MEMORY ADDRESS
	MOV	B,M	; FETCH PRECISION
	INX	H	; POINT TO NEXT
	LDAX	D	; GET MSB OF DATA
	CALL	LBYT	; DISPLAY IT
	DCR	B
	RZ		; 8-BIT ALL DONE
	DCX	D	; POINT TO LSB
	LDAX	D	; FETCH IT
	JMP	LBYT	; DISPLAY IT
;
;	- GO TO <ADDRESS>, OPTIONALLY SET TRAPS.
;
GOTO:
	CALL	PCHK	; GET A CHARACTER
	JC	GO3	; CR ENTERED, EXIT
	JZ	GO0	; DON'T MODIFY PC
	CALL	EXF	; GET NEW PC VALUE
	POP	H	; GET SPECIFIED START ADDRESS
	SHLD	TPC	; SAVE IT
	MOV	A,B	; RETRIEVE DELIMITER
	CPI	CR
	JZ	GO3	; NO TRAPS TO BE SET
GO0:
	LXI	H,T1A	; POINT TO TRAPS
	MVI	D,2	; SET MAXIMUM OF TWO
GO1:
	PUSH	H	; SAVE ADDRESS 0
	MVI	C,1
	CALL	EXPR	; GET A TRAP ADDRESS
	MOV	E,B	; SAVE DELIMITER
	POP	B	; GET ADDRESS IN
	POP	H
	MOV	A,B
	ORA	C
	JZ	GO2	; DON'T ALLOW A
	MOV	M,C	; PUT TRAP ADDRESS
	INX	H
	MOV	M,B
	INX	H
	LDAX	B	; FETCH OPCODE
	MOV	M,A	; PUT IN TRAP ADDRESS
	INX	H
	MVI	A,0CFH	; <RST 1> INSTRUCTION
	STAX	B	; SET TRAP IN MEMORY
GO2:
	MOV	A,E	; TEST DELIMITER
	CPI	CR
	JZ	GO3	; ALL DONE
	DCR	D
	JNZ	GO1	; GO GET NEXT TRAP
GO3:
	CALL	CRLF
	DI		; DISABLE INTERRUPTS
	LXI	SP,TAP	; POINT TO USER'S PSW
	POP	PSW	; SET PSW
	POP	B	; SET B&C
	POP	D	; SET D&E
	POP	H	; GET SP VALUE
	SPHL		; SET SP
	LHLD	TPC	; GET PC VALUE
	PUSH	H	; PUSH ONTO STACK
	LHLD	THL	; SET H&L
	RET		; GO ! ! !
;
;	- COMPUTE HEXADECIMAL SUM AND DIFFERENCE.
;
HEXN:	CALL	EXPR	; GET TWO NUMBERS
	POP	D
	POP	H
	CALL	CRLF	; GREEN
	PUSH	H
	DAD	D
	CALL	LADR	; DISPLAY HL+DE
	CALL	BLK	; TYPE A SPACE
	POP	H
	CALL	SUBHD	; SUBTRACT D&E FROM H&L
	JMP	LADR	; DISPLAY HL-DE
;
;	- EVALUATE EXPRESSION: <EXPR>,<EXPR>,<EXPR>.
;
EXPR:	LXI	H,0	; INITIAL VALUE
EX0:	CALL	CIX	; GET A CHARACTER
	CALL	LO
EX1:	MOV	B,A	; SAVE DELIMITER
	CALL	NIBL	; CONVERT TO HEX
	JC	EX2	; NOT LEGAL CHARACTER
	DAD	H	; *2
	DAD	H	; *4
	DAD	H	; *8
	DAD	H	; *16
	ORA	L
	MOV	L,A
	JMP	EX0	; GET ANOTHER CHARACTER
EX2:	XTHL		; GET RETURN AND PUT HL ON STACK
	PUSH	H	; REPLACE RETURN
	MOV	A,B
	CALL	P2C	; TEST DELIMITER
	JNC	EX3
	DCR	C	; CR ENTERED
	JNZ	EXPR	; TOO FEW PARAMETERS
	RET
EX3:	JNZ	ERROR	; ILLEGAL DELIMITER
	DCR	C
	JNZ	EXPR
	RET
EXF:	CALL	LO	; ENTRY POINT FOR CONDITIONAL PARAMETER
	MVI	C,1
	LXI	H,0
	JMP	EX1
;
CIX:	MVI	A,29	; FOREGROUND
	CALL	LO
	MVI	A,17	; RED
	CALL	LO
	JMP	CI	; GO READ FROM CONSOLE
;
;	- TEST FOR NULL INPUT PARAMETER.
;
PCHK:	CALL	CIX	; GET A CHARACTER
P2C:	CPI	' '	; IS IT A SPACE?
	RZ		; YES? RETURN!
	CPI	','	; IS IT A COMMA?
	RZ		; YES? RETURN!
	CPI	CR	; IS IT A CARRIAGE RETURN?
	STC		; SET CARRY
	CMC		; COMPLEMENT CARRY
	RNZ		; NO? RETURN!
	STC		; SET CARRY
	RET		; RETURN
;
;	- CARRIAGE RETURN, LINEFEED
;
CRLF:	PUSH	H
	LXI	H,LFTBL
	CALL	OSTR
	POP	H
	RET
LFTBL:	DB	CR,LF,6,2,239
;
;	- PRINT CONTENTS OF HL IN HEX ON CONSOLE DEVICE
;
LADR:	MOV	A,H	; PRINT MSB
	CALL	LBYT
	MOV	A,L	; PRINT LSB
	JMP	LBYT
;
;	- COMPARE HL WITH DE.
;	- IF HL < DE THEN CARRY = 0, IF HL = DE THEN
;	- CARRY = 0, IF HL > DE THEN CARRY = 1.
;
HILO:	INX	H	; BUMP HL
	MOV	A,H	; TEST FOR HL = 0
	ORA	L
	STC
	RZ
	JMP	CMPDH
;
;	- ERROR EXIT.
;
ERROR:	LXI	H,CRTBL-3
	JMP	START+3
;
;	CI - THE CHARACTER INPUT ROUTINE GETS A CHARACTER
;		FROM THE TEMPORARY STORAGE LOCATION 'CHARIN',
;		CLEARS THE KEYBOARD READY FLAG AND RETURNS
;		WITH THE CHARACTER IN A.  IF THERE IS NO
;		CHARACTER IN 'CHARIN', THEN 'CI' WILL HANG
;		AND WAIT FOR A CHARACTER.
;
CI:	EI		; ENABLE INTERRUPTS
	LDA	CHARIN	; GET CHARACTER
	CPI	0	; HAVE A CHARACTER?
	JZ	CI	; IF NOT, HANG FOR CHARACTER
	PUSH	PSW	; SAVE CHARACTER
	XRA	A
	STA	KBRDY	; CLEAR KEYBOARD READY FLAG
	STA	CHARIN	; CLEAR TEMPORARY STORAGE FOR NEXT CHAR
	POP	PSW	; RESTORE CHARACTER
	RET		; ECHO CHARACTER FROM MAIN ROUTINE
;
;	- RESTART 1 CODE.
;	- (PROGRAMMED BREAKPOINT).
;
RESTART:DI		; DISABLE INTERRUPTS
	SHLD	THL	; SAVE H&L
	POP	H	; GET PC VALUE
	DCX	H	; ASSUME BREAKPOINT
	SHLD	TPC	; SAVE PC
	PUSH	PSW	; GET PSW ...
	POP	H	; ... INTO H&L
	SHLD 	TAP	; SAVE PSW
	LXI	H,0
	DAD	SP	; HL=SP
	LXI	SP,THL	; POINT TO STORAGE AREA
	PUSH	H	; SAVE SP VALUE
	PUSH	D	; SAVE D&E
	PUSH	B	; SAVE B&C
	SPHL		; RESET SP
	LHLD	TPC	; GET PC VALUE
	XCHG		; MOVE TO D&E
	LXI	H,T1A	; POINT TO BREAKPOINT AREA
	MOV	A,M	; TEST IF THIS IS
	SUB	E	; OR CONSOLE RE
	INX	H
	JNZ	RST1
	MOV	A,M
	SUB	D
	JZ	RST3
RST1:	INX	H
	INX	H
	MOV	A,M
	SUB	E
	JNZ	RST2
	INX	H
	MOV	A,M
	SUB	D
	JZ	RST3
RST2:	INX	D	; ADJUST PC VALUE
RST3:	XCHG		; HL=PC VALUE
	SHLD	TPC	; SAVE PC VALUE
	LXI	H,MSG
	CALL	OSTR
	LHLD	TPC
	CALL	LADR	; DISPLAY PC
	LXI	H,T1A	; POINT TO BREAKPOINT AREA
	MVI	D,2	; SET COUNT FOR TWO
RST4:	MOV	C,M	; GET LSB OF ADDRESS
	MVI	M,0	; CLEAR MEMORY
	INX	H
	MOV	B,M	; GET MSB OF ADDRESS
	MVI	M,0
	INX	H
	MOV	A,C
	ORA	B	; TEST FOR VALID
	JZ	RST5	; ADDRESS = 0, NO
	MOV	A,M	; GET OPCODE BYTE
	STAX	B	; REPLACE IT
RST5:	INX	H	; POINT TO NEXT REGISTER
	DCR	D
	JNZ	RST4	; REPEAT FOR TRAP
	MVI	A,CR
	CALL	X+3
	JMP	START
;
;	- EXIT FROM MONITOR
;
EXIT:	JMP	0	; CRT MODE
;
;	- CHECK FOR BREAK/LINEFEED
;
ABTEST:	LDA	KBRDY
	CPI	50H
	JZ	ABTEST
	CPI	80H
	RNZ
	XRA	A
	STA	KBRDY
	STA	CHARIN
	CPI	10
	RNZ
	JMP	EXIT
;
;	- DISPLAY ASCII VALUES OF MEMORY
;
ASCII:	CALL	EXPR	; GET TWO ADDRESSES
	POP	D	; GET HIGH ADDRESS
	POP	H	; GET LOW ADDRESS
ASC1:	CALL	CRLF	; GREEN
	CALL	LADR	; PRINT MEMORY ADDRESS
	MVI	A,13H	; YELLOW
	CALL	LO
ASCL:	CALL	BLK	; PRINT SPACE
	MOV	A,M
	ANI	7FH	; MAKE ASCII
	CPI	20H	; DON'T WANT CTRL
	JNC	AOK1
	MVI	A,'.'	; SWAP DOT FOR CNTL
AOK1:	CALL	LO	; OUTPUT CHARACTER
	CALL	BLK	; PRINT SPACE
	CALL	ABTEST	; CHECK FOR BREAK
	CALL	HILO	; COMPUTE END
	RC		; RETURN IF END
	MOV	A,L
	ANI	0FH	; CHECK TO SEE IF 16 ON CRT
	JNZ	ASCL
	JMP	ASC1
;
;	- NON-DESTRUCTIVE MEMORY TEST
;	- PROVIDE START AND END ADDRESSES
;	- CHECKS RAM ONLY. DO NOT TEST MONITOR
;	- SECTION OF RAM ( WILL RESULT IN PROGRAM
;	- HANGUP).
;
NDMT:	CALL	EXPR	; GET TWO ADDRESSES
	POP	D	; GET HIGH ADDRESS
	POP	H	; GET LOW ADDRESS
NDLOOP:	MOV	C,M	; SAVE MEMORY CONTENTS
	MVI	B,0FFH	; LOAD B WITH 'FF'
	MOV	M,B	; STORE IN MEMORY
	MOV	A,M	; STORE MEMORY IN ACCUMULATOR
	CMP	B	; COMPARE WITH B
	JNZ	MEMERR	; DISPLAY ERROR
	MVI	B,0	; LOAD B WITH '0'
	MOV	M,B	; STORE IN MEMORY
	MOV	A,M	; MOVE MEMORY TO ACCUMULATOR
	CMP	B	; COMPARE WITH B
	JNZ	MEMERR	; DISPLAY ERROR
	MOV	M,C	; RESTORE ORIGINAL MEMORY CONTENTS
	CALL	HILO	; COMPLETED?
	RC		; YES? RETURN!
	JMP	NDLOOP	; NO? CONTINUE!
;
;	- PRINT MEMORY ERROR AND LOCATION
;
MEMERR:	PUSH	H	; SAVE ADDRESS
	LXI	H,MSG1	; PRINT ERROR MESSAGE
	CALL	OSTR	; ..TO THE CRT
	POP	H	; RESTORE ADDRESS
	CALL	LADR	; PRINT ADDRESS
	RET
;
;	- SEARCH FOR BYTE/WORD/THREE BYTES
;
SRCH:	INR	C	; GET THREE BYTES
	INR	C	; ..AND THREE ADRESSES
	CALL	EXPR	;
	POP	H	; STORE THIRD BYTE
	MOV	A,H	;
	STA	THIRD	;
	POP	B	; BYTE/WORD
	POP	D	; SOURCE END
	POP	H	; SOURCE BEGIN
S1:	MOV	A,M	; MOVE MEMORY CONTENTS
	CMP	B	; COMPARE REGISTER B-1ST BYTE
	JNZ	S2	; NO MATCH - CHECK FOR MORE BYTES
	MOV	A,C	; IS THERE A
	CPI	0	; ..SECOND BYTE?
	JNZ	S4	; YES? COMPARE VALUE
	LDA	THIRD	; IS THERE A
	CPI	0	; ..THIRD BYTE?
	JNZ	S6	; YES? COMPARE VALUE
	CALL	SZ	; PRINT ADDRESS LOCATION OF MATCH
	JMP	SA	; CONTINUE
S2:	MOV	A,C	; IS THERE A
	CPI	0	; ..SECOND BYTE?
	JNZ	S3	; YES? COMPARE VALUE
	LDA	THIRD	; IS THERE A
	CPI	0	; ..THIRD BYTE?
	JNZ	S5	; YES? COMPARE VALUE
	JMP	SA	; NO? CONTINUE
S3:	INX	H	; INCREMENT MEMORY
S10:	LDA	THIRD	; IS THERE A
	CPI	0	; ..THIRD BYTE?
	JNZ	SA	; YES? CONTINUE
	DCX	H	; NO? DECREMENT MEMORY
	JMP	SA	; ..AND CONTINUE
S4:	INX	H	; INCREMENT MEMORY
	MOV	A,C	; COMPARE 2ND BYTE
	CMP	M	; ..WITH MEMORY
	JNZ	S10	; MATCH? NO? CHECK FOR THIRD BYTE
	INX	H	; YES? INCREMENT MEMORY
	LDA	THIRD	; ..COMPARE WITH
	CMP	M	; ..THIRD BYTE
	JZ	SX	; MATCH? YES? PRINT ADDRESS
	DCX	H	; NO? THEN
	CPI	0	;
	JZ	SY	;
	JMP	SA	; ..CONTINUE
S6:	INX	H	; INCREMENT MEMORY
	INX	H	; INCREMENT MEMORY
	LDA	THIRD	; COMPARE THIRD BYTE
	CMP	M	; ..WITH MEMORY
	JZ	SY	; MATCH? YES? PRINT ADDRESS
	DCX	H	; NO? DECREMENT MEMORY
	JMP	SA	; ..AND CONTINUE
S5:	INX	H	; INCREMENT MEMORY
	JMP	SA	; ..AND CONTINUE
SY:	DCX	H	; DECREMENT MEMORY
	CALL	SZ	; PRINT ADDRESS
	INX	H	; INCREMENT MEMORY
	JMP	SA	; ..AND CONTINUE
SX:	DCX	H	; DECREMENT MEMORY
	DCX	H	; DECREMENT MEMORY
	CALL	SZ	; PRINT ADDRESS
	INX	H	; INCREMENT MEMORY
	INX	H	; INCREMENT MEMORY
	JMP	SA	; ..AND CONTINUE
SZ:	CALL	CRLF	; GREEN AND CR,LF
	CALL	LADR	; PRINT ADDRESS
	CALL	ABTEST	; CHECK FOR BREAK
	RET		; RETURN
SA:	CALL	HILO	; CHECK IF END
	RC		; END? YES, RETURN
	JMP	S1	; NO? CONTINUE
;
;	- COMPARE MEMORY
;
COMPR:
	INR	C	; SET UP FOR THREE VALUES
	CALL	EXPR	; GET ADDRESSES
	POP	B	; MEMORY TO BE COMPARED
	POP	D	; SOURCE END
	POP	H	; SOURCE BEGIN
CMP1:	PUSH	D	; SAVE D
	PUSH	B	; SAVE B
	POP	D	; MOVE B TO D
	MOV	A,M	; MOVE MEMORY TO ACCUM.
	XCHG		; EXCHANGE HL&DE
	CMP	M	; COMPARE MEMORY TO ACCUM.
	JNZ	DSP	; JUMP IF NOT EQUAL
CMP2:	INX	H	; INCREMENT MEMORY COMPARED
	XCHG		; EXHANGE HL&DE
	PUSH	D	; SAVE D
	POP	B	; RESTORE B
	POP	D	; RESTORE D
	CALL	HILO	; CHECK IF END
	RC		; END? YES,RETURN
	JMP	CMP1	; NO? CONTINUE
DSP:	XCHG		; EXCHANGE HL & DE
	CALL	CRLF	; GREEN
	CALL	LADR	; PRINT ADDRESS
	MVI	A,' '	; PRINT SPACE
	CALL	LO	;
	MOV	A,M	; PRINT DATA
	CALL	LBYT	;
	MVI	A,' '	; PRINT SPACE
	CALL	LO	;
	XCHG		; EXCHANGE HL & DE
	CALL	LADR	; PRINT ADDRESS
	MVI	A,' '	; PRINT SPACE
	CALL	LO	;
	MOV	A,M	; PRINT DATA
	CALL	LBYT	;
	CALL	ABTEST	; CHECK FOR BREAK
	JMP	CMP2	; RETURN
;
;	- MEMORY ERROR MESSAGE
;
MSG1:	DB	17,'MEMORY ERROR @ ',239
;
;	- RESTART MESSAGE.
;
MSG:	DB	12,CR,LF,'BREAK @ ',239
;
;	- LOBYTE OF ADDRESSES OF REGISTER STORAGE AREA:
;
ALOC	EQU	TAP+1 AND 255
BLOC	EQU	TBC+1 AND 255
CLOC	EQU	TBC   AND 255
DLOC	EQU	TDE+1 AND 255
ELOC	EQU	TDE   AND 255
FLOC	EQU	TAP   AND 255
HLOC	EQU	THL+1 AND 255
LLOC	EQU	THL   AND 255
PLOC	EQU	TPC+1 AND 255
SLOC	EQU	TSP+1 AND 255
;
;	- TABLE FOR ACCESSING REGISTERS.
;	- 1 REGISTER IDENTIFIER.
;	- 2 LOBYTE OF STORAGE ADDRESS
;	- 3 PRECISION.
;
ACTBL:
	DB	'A',ALOC,1
	DB	'B',BLOC,1
	DB	'C',CLOC,1
	DB	'D',DLOC,1
	DB	'E',ELOC,1
	DB	'F',FLOC,1
	DB	'H',HLOC,1
	DB	'L',LLOC,1
	DB	'M',HLOC,2
	DB	'P',PLOC,2
	DB	'S',SLOC,2
	DB	0FFH	; TABLE TERMINATION
THIRD:	DS	1	; STORE SRCH THIRD BYTE
	END	CIINIT