Compucolor.org – Virtual Media

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


;MONITOR.SRC;1
;7/4/80 LAST REV 7/6/83

;COMPUCOLOR II MONITOR VERSION 1.0

;EXTRACTED FROM ISC'S CPU OPERATING SYSTEM
;BY RICK MANAZIR.
;13 GRANDVIEW ST.
;SOUTHWICK, MASS.  01077
;(413) 569-6621

;PLEASE SEND OR COMMUNICATE WITH ME IF YOU ADD TO OR
;MODIFY THIS PROGRAM.

BEL	EQU	7
LF	EQU	10
FF	EQU	12
CR	EQU	13
KTST	EQU	0024H	;KEYBOARD SCANNER
INPCRT	EQU	81C5H	;JUMP VECTOR #31
KBDFL	EQU	81DFH	;HOLDS NUMBER OF JUMP VECTOR FOR THE
			;KEYBOARD
KBRDY	EQU	81FFH	;KEYBOARD READY FLAG
UVEC	EQU	81BFH	;"ECS USER" VECTOR
RST1J	EQU	81C8H	;RESTART VECTOR JUMPS HERE FROM ROM

	ORG	0F000H

AVP:	DW	KBDFL
	PUSH	H
	LXI	H,0
	DAD	SP
	SHLD	FCSSP
	LXI	SP,STACK

	LDA	1
	CPI	6CH
	JZ	CIINIT	;NOT 8.79
OVRLAY:	LXI	H,JMPTAB
	LXI	D,TAB879
	LXI	B,TAB879-JMPTAB
MOVBYT:	LDAX	D
	MOV	M,A
	INX	H
	INX	D
	DCX	B
	MOV	A,B
	ORA	C
	JNZ	MOVBYT
	JMP	CIINIT

JMPTAB	EQU	$
OSTR:	JMP	33F4H
LBYT:	JMP	339BH
NIBL:	JMP	33B3H
CMPDH:	JMP	3453H
ADHLA:	JMP	3518H
LO:	JMP	3392H
SUBHD:	JMP	3459H
BLK:	JMP	34B3H
CRLF:	JMP	338BH
ESC1:	JMP	053AH

TAB879	EQU	$
	JMP	182AH	;OSTR
	JMP	17D1H	;LBYT
	JMP	17E9H	;NIBL
	JMP	1889H	;CMPDH
	JMP	194EH	;ADHLA
	JMP	17C8H	;LO
	JMP	188FH	;SUBHD
	JMP	18E9H	;BLK
	JMP	17C1H	;CRLF
	JMP	2420H	;ESC1

;	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,AVP	;START ADDRESS
	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	CR,LF,29,13H,'COMPUCOLOR'
	DB	17H,' II'
	DB	15H,' MONITOR '
	DB	16H,'V'
	DB	'1.0 ',20,'BY R. M. MANAZIR.'
	DB	18,' HIT H FOR HELP'
	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
	ANI	0DFH	;MAKE UPPER CASE
	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	HELP	;H - HELP
	DW	ERROR	;I
	DW	ERROR	;J
	DW	ERROR	;K
	DW	ERROR	;L
	DW	MOVE	;M - MOVE MEMORY
	DW	HEXN	;N - SUM AND DIFFERENCE
	DW	ERROR	;O
	DW	ERROR	;P
	DW	ERROR	;Q
	DW	X	;R - EXAMINE & MODIFY REGISTERS
	DW	SUBS	;S - SUBSTITUTE MEMORY
	DW	NDMT	;T - NON-DESTRUCTIVE MEMORY TEST
	DW	ERROR	;U
	DW	ERROR	;V
	DW	SRCH	;W - FIND BYTE/WORD/THREE BYTES
	DW	ERROR	;X

;	- CARRIAGE RETURN TABLE

	DB	22,'?'	;ERROR
CRTBL:	DB	BEL,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
	MOV	M,A	;STORE IN 'CHARIN'
CFIN:	POP	PSW	;RESTORE USED REGISTERS
	POP	H	;
	EI		;ENABLE INTERRUPTS
	RET		;RETURN FROM INTERRUPT

;	- EVALUATE EXPRESSION: <EXPR>,<EXPR>,<EXPR>.

EXPR:	LXI	H,0	;INITIAL VALUE
EX0:	CALL	CIX	;GET A CHARACTER
	CALL	EDTHEX
	CPI	'.'
	JNZ	EXLO
	XRA	A
	STA	KBRDY
	STA	CHARIN
	JMP	EX0
EXLO:	CALL	LO
EX111:	CPI	'g'
	JNC	EX1	;> LOWER CASE 'F'
	CPI	'a'
	JC	EX1	;< LOWER CASE 'A'
	ANI	0DFH	;MAKE UPPER CASE
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	EX111

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

;	- PRINT CONTENTS OF HL IN HEX ON CONSOLE DEVICE

LADR:	MOV	A,H	;PRINT MSB
	CALL	LBYT
	MOV	A,L	;PRINT LSB
	JMP	LBYT

;	- SET CARRY IF HL > DE

HILO:	INX	H
	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.

CIX:	MVI	A,29	;FOREGROUND
	CALL	LO
	CALL	RED
CI:	EI		;ENABLE INTERRUPTS
	LDA	CHARIN	;GET CHARACTER
	CPI	0	;HAVE A CHARACTER?
	JZ	CI	;IF NOT, HANG FOR CHARACTER
	CALL	EDIT
	CPI	'.'
	JNZ	CIOK
	XRA	A
	STA	KBRDY
	STA	CHARIN
	JMP	CI
CIOK:	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

;	- CHECK FOR BREAK/LINEFEED

ABTEST:	LDA	KBRDY
	CPI	50H
	JNZ	AB02
	CALL	BELL
AB01:	LDA	KBRDY
	CPI	50H
	JZ	AB01
AB02:	CPI	80H
	RNZ
	LDA	CHARIN
	PUSH	PSW
	XRA	A
	STA	CHARIN
	STA	KBRDY
	CALL	BELL
	POP	PSW
	CPI	10
	RNZ
	POP	H	;CANCEL RETURN
	JMP	START

;	- DISPLAY ASCII VALUES OF MEMORY

ASCII:	CALL	EXPR	;GET TWO ADDRESSES
	CALL	CRLF
	CALL	YELLOW
	LXI	H,MSGDSP+2
	CALL	OSTR
	POP	D	;GET HIGH ADDRESS
	POP	H	;GET LOW ADDRESS
ASC1:	CALL	CRLF
	CALL	YELLOW
	CALL	LADR	;PRINT MEMORY ADDRESS
	CALL	GREEN
ASCL:	CALL	BLK	;PRINT SPACE
	MOV	A,M
	CPI	80H	;ASCII ONLY
	JNC	ASCNO
	CPI	20H	;DON'T WANT CTRL
	JNC	AOK1
ASCNO:	CALL	RED
	CALL	DASH
	MVI	A,18	;GREEN
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

;	- 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:	CALL	CRLF
	CALL	DSP01
	CALL	BLK
	CALL	BLK
	CALL	BLK
	CALL	BLK
	CALL	DSP01
	CALL	ABTEST
	JMP	CMP2

DSP01:	XCHG		;EXCHANGE HL & DE
	CALL	YELLOW
	CALL	LADR	;PRINT ADDRESS
	CALL	BLK
	CALL	GREEN
	MOV	A,M	;PRINT DATA
	PUSH	PSW
	CALL	LBYT
	CALL	BLK
	CALL	BLK
	POP	PSW
	CPI	80H
	JNC	DSPDSH
	CPI	20H
	JC	DSPDSH
	JMP	DSPCHR
DSPDSH:	CALL	RED
	CALL	DASH
	MVI	A,18	;GREEN
DSPCHR:	CALL	LO
DSPRET:	RET

;	- DISPLAY MEMORY IN HEX ON CRT.

DISP:	CALL	EXPR	;GET TWO ADDRESSES
	CALL	CRLF
	LXI	H,MSGDSP
	CALL	OSTR
	POP	D	;GET HIGH ADDRESS
	POP	H	;GET LOW ADDRESS
DI0:	CALL	CRLF
	CALL	YELLOW
DI1:	CALL	LADR	;PRINT MEMORY ADDRESS
	CALL	GREEN
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

;	- EXIT FROM MONITOR

EXIT:	CALL	BELL
	CALL	CRLF
	MVI	B,0
	LXI	H,KBDFL
	SHLD	8200H
	LHLD	FCSSP
	SPHL
	POP	H
	MVI	A,44H
	JMP	ESC1

;	- 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
	CALL	CMPDH
	RZ
	INX	H
	JMP	FI0

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

;	- PRINT LIST OF COMMANDS ON SCREEN

HELP:	PUSH	H
	LXI	H,MSGH00
HLOOP:	MOV	A,M
	CPI	0FFH
	JZ	HRET	;END OF HELP MESSAGES
	CALL	LO
	INX	H
	JMP	HLOOP
HRET:	POP	H
	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
	STAX	B
	CALL	CMPDH
	RZ
	INX	B
	INX	H
	JMP	MV0

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

;	- MODIFY MEMORY WITH KEYBOARD INPUTS

SUBS:	DCR	C	;INITIALLY SET FOR TWO VALUES
	CALL	EXPR	;GET ONE ADDRESS
	CALL	P2C
	POP	H
	RC
SU0:	CALL	YELLOW
	MOV	A,M
	CALL	LBYT	;DISPLAY DATA
	CALL	DASH
	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

;	- COMPUTE HEXADECIMAL SUM AND DIFFERENCE.

HEXN:	CALL	EXPR	;GET TWO NUMBERS
	POP	D
	POP	H
	CALL	CRLF
	CALL	YELLOW
	CALL	LADR	;1ST
	MVI	A,'+'
	CALL	LO
	PUSH	H
	LXI	H,0
	DAD	D
	CALL	LADR	;2ND
	MVI	A,'='
	CALL	LO
	CALL	GREEN
	POP	H
	PUSH	H
	DAD	D
	CALL	LADR	;BOTH
	POP	H
	CALL	BLK
	CALL	BLK
	CALL	YELLOW
	CALL	LADR	;1ST
	PUSH	H
	CALL	DASH
	LXI	H,0
	DAD	D
	CALL	LADR	;2ND
	MVI	A,'='
	CALL	LO
	CALL	GREEN
	POP	H
	CALL	SUBHD
	JMP	LADR	;BOTH

;	- 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,L	;* WAS H BUT LO BYTE GOES TO L
	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
	CALL	GREEN
	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

;	- EXAMINE AND MODIFY CPU REGISTER.

X:	CALL	CIX	;GET REGISTER
	CALL	LO
	ANI	0DFH	;MAKE UPPER CASE
XEXCL:	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:	CALL	GREEN
	CALL	X8
	INR	B
	CALL	DASH
	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	GREEN
	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
	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

RED:	MVI	A,17
	JMP	LO

GREEN:	MVI	A,18
	JMP	LO

YELLOW:	MVI	A,19
	JMP	LO

BELL:	MVI	A,BEL
	JMP	LO

DASH:	MVI	A,'-'
	JMP	LO

EDIT:	CPI	'z'+1
	JNC	EDOT
	CPI	'a'
	RNC
	CPI	'Z'+1
	JNC	EDOT
	CPI	'A'
	RNC
	CPI	'9'+1
	JNC	EDOT
	CPI	'0'
	RNC
	CPI	' '
	RZ
	CPI	CR
	RZ
	CPI	FF
	RZ
	CPI	LF
	RZ
EDOT:	CALL	BELL
	MVI	A,'.'
	RET

EDTHEX:	CPI	'f'+1
	JNC	EDOT
	CPI	'a'
	RNC
	CPI	'F'+1
	JNC	EDOT
	CPI	'A'
	RNC
	CPI	'9'+1
	JNC	EDOT
	CPI	'0'
	RNC
	CPI	' '
	RZ
	CPI	CR
	RZ
HEXDOT:	CALL	BELL
	MVI	A,'.'
	RET

MSGH00:					;HELP MESSAGES
MSGH10:	DB	BEL,13,10,18
	DB	' DISPLAY #-# IN ASCII............'
	DB	17,'A# #',18,13,10
MSGH11:	DB	' COMPARE #-# WITH #..............'
	DB	17,'C# # #',18,13,10
MSGH12:	DB	' DISPLAY #-# IN HEX..............'
	DB	17,'D# #',18,13,10
MSGH13:	DB	' EXIT TO FCS.....................'
	DB	17,'E ',18,'REENTER W/(ESC) ^',13,10
MSGH16:	DB	' FILL #-# WITH $.................'
	DB	17,'F# # $',18,13,10
MSGH17:	DB	' GOTO #, BREAKPOINT(S) AT #, #...'
	DB	17,'G# # #',18,' BP(S) OPTIONAL',13,10
MSGH14:	DB	' HELP............................'
	DB	17,'H',18,13,10
MSGH19:	DB	' MOVE #-# TO #...................'
	DB	17,'M# # #',18,13,10
MSGH18:	DB	' HEX ARITHMETIC, #+#= AND #-#=...'
	DB	17,'N# #',18,13,10
MSGH20:	DB	' REGISTERS DISPLAY...............'
	DB	17,'R',18,13,10
MSGH2B:	DB	' REGISTER(S) CHANGE..............'
	DB	17,'R(REG) $',18,' SPACE(S) AFTER '
	DB	17,'R(REG)',18,13,10
MSGH21:	DB	' MEMORY CHANGE...................'
	DB	17,'S#',18,' SPACE(S) AFTER ',17,'S#',18,13,10
MSGH15:	DB	' MEMORY TEST #-#.................'
	DB	17,'T# #',18,13,10
MSGH22:	DB	' SEARCH #-# FOR 1, 2 OR 3 BYTES..'
	DB	17,'W# # # $',18,13,10

MSGH25:	DB	13,10,17,'  # ',19,'= HEX NUMBER, 2 BYTES, E.G., '
	DB	17,'81FE, 1FE, FE, E',13,10
MSGH2A:	DB	17,'  $ ',19,'= HEX NUMBER, 1 BYTE, E.G.,'
	DB	17,' 1F, F',13,10
MSGH26:	DB	17,'  # # ',19,'= START AND END ADDRESSES',13,10
MSGH27:	DB	17,'  # # # ',19,'= START, END OF 1ST BLOCK'
	DB	' AND START OF 2ND BLOCK',13,10
	DB	'  LOWER CASE ALPHA OK'
	DB	0FFH	;END OF HELP MESSAGES

MSGDSP:	DB	19,'      0  1  2  3  4  5  6  7  8  9  '
	DB	'A  B  C  D  E  F',239

MSG1:	DB	17,'MEMORY ERROR @ ',239

MSG:	DB	CR,LF,'BREAK @ ',239

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

;	- 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
CHARIN:	DS	1	;TEMPORARY CHARACTER STORAGE
FCSSP:	DS	2
	DS	100
STACK:

	END	AVP