	TITLE '	UGHBUG		VERSION 1.01		8 April 1987 '
	SBTTL '	Copyright 1986 by George Dinwiddie '
	PGLEN	55

;	
;	NOTICE : This monitor program may be copied and distributed on the 
;	condition that all copyright notices and this notice remain intact.  
;	This program is provided without any warranty or assumption of 
;	liability whatsoever.  If it doesn't work or it breaks something, I'm
;	sorry, but it's not my problem.
;	
;	On the positive side, if this program helps you, I am glad to be of 
;	assistance.  I ask only two favors.  First, if you fix any bugs or 
;	add any enhancements, please send me a copy.  (CP/M 8" SSSD or IBM-PC
;	5.25" are best for me.)  Secondly, if you use this program to help 
;	develop a commercial product, please remember me.  As a suggestion, a
;	$50.00 donation would be a bargain for you and welcome by me.  If you
;	would prefer, either a sample of your product or a donation more in 
;	line with the profits on your product would be ok, too.  If you use 
;	this program on a home project, I understand that you can't alway 
;	afford to pay for the value of good software.  My own CP/M computer 
;	would be worthless without the wonderful public domain software that 
;	I have received for free.  If you want to send me your favorite 
;	public domain goody, great.  In any event, you are welcome to this --
;	enjoy, enjoy.
;	
;		George Dinwiddie
;		10965 Trotting Ridge Way
;		Columbia, MD  21044
;
;REVISION HISTORY :
;
;Version 1.01  George Dinwiddie  8 April 1987.
; Fixed typo in BREAK routine; reported by Royce G. Simmons.
;Version 1.00  George Dinwiddie  12 January 1986.
;	First public release.  Fixed GO-from-break bug.
;Version 0.16  George Dinwiddie  26 January 1984
;	Added JUMPTABLE and HEXMATH functions.
;
;WISH LIST :
;
;    Load command ('L') to load ram from a hex file through the terminal
;    port.
;
;    Find command ('F') to search for sequences specified in hex or 
;    ascii.  I always intended to add this one but never did.  That's 
;    the reason the Insert command isn't a Fill command.
;    
;    Disassemble command (maybe 'U' for Unassemble).
;    
;    Single-line assembler.  It's amazing how good you get at hand 
;    assembly when you practice.  Still, it would be nice to have this.
;
;
;NOTE : Some labels are of the following form :
;	IF000	== IF
;	THN000	== THEN
;	ELS000	== ELSE
;	NDI000	== ENDIF
;

MONBASE		EQU	0000H	;4K MONITOR
APPBASE		EQU	2000H	;8K APPLICATION EPROM
RAMBASE		EQU	4000H	;8K RAM
UARTBASE	EQU	7800H	;TERMINAL (uart) LOCATION
UARTDATA	EQU	UARTBASE ; C/D* = A0
UARTCONT	EQU	(UARTBASE+1)
RAMEND		EQU	5FFFH	;END OF EXTERNAL RAMSPACE
BYTENUM		EQU	(RAMEND-8) ;FROM HERE ON USED BY BREAK ROUTINE
STACK		EQU	50H	;stack begins here

PCON		EQU	87H	;AVOCET ASSEMBLER DOESN'T KNOW PCON

;reserved internal ram locations
RESERVED	EQU	48H	;reserved internal ram
HIBYTE		EQU	RESERVED   ;TOP OF 16-BIT ADDRESS
LOBYTE		EQU	RESERVED+1 ;BOTTOM OF 16 BIT ADDRESS
FIRST		EQU	RESERVED+2 ;START ADDRESS HIGH (LOW IN RESERVED+3)
LAST		EQU	RESERVED+4 ;END ADDRESS HIGH (LOW IN RESERVED+5)
TO		EQU	RESERVED+6 ;TO ADDRESS HIGH (LOW IN RESERVED+7)

;reserved register bank (and aliases for those registers)
RESBANK		EQU	1	;register bank 1
REG0		EQU	8*RESBANK
REG1		EQU	REG0+1	;sometimes you can't use R1
REG2		EQU	REG0+2
REG3		EQU	REG0+3
REG4		EQU	REG0+4
REG5		EQU	REG0+5
REG6		EQU	REG0+6
REG7		EQU	REG0+7

;character equates
CR		EQU	0DH	;CARRIAGE RETURN
LF		EQU	0AH	;LINE FEED
SPACE		EQU	20H	;SPACE CHARACTER
TAB		EQU	09H	;TAB CHARACTER
DOT		EQU	2EH	;PERIOD
BACKSP		EQU	08H	;BACKSPACE
EOT		EQU	04H	;end of text

;***********************************************************

	ORG	MONBASE
START:	JMP	UGHBUG

	ORG	START+03H
	LJMP	RAMBASE+03H		;INTERRUPT VECTORS JUMP TO RAM
	ORG	START+0BH
	LJMP	RAMBASE+0BH
	ORG	START+13H
	LJMP	RAMBASE+13H
	ORG	START+1BH
	LJMP	RAMBASE+1BH
	ORG	START+23H
	LJMP	RAMBASE+23H

;*************************************************************

LJMPTBL:	LJMP	COOL
	LJMP	WARM

	LJMP	IN
	LJMP	INCH
	LJMP	INHEX
	LJMP	BYTES
	LJMP	BADDR
	LJMP	THRADR

	LJMP	OUT
	LJMP	OUTCH
	LJMP	OUTS
	LJMP	OUT2S
	LJMP	CRLF
	LJMP	OUT2H
	LJMP	OUTR0
	LJMP	OUTC2HS
	LJMP	PDATA

	LJMP	INC16
	LJMP	DEC16
	LJMP	CPY
	LJMP	BRKPT
	PAGE
MSIGNON:
	DB	CR, LF, 'Ughbug MCS-51 monitor, version 1.01'
	DB	CR, LF, 'copyright 1986 by George Dinwiddie.', LF, 04H
;*************************************************************

UGHBUG:	MOV	SP,#STACK
	MOV	STACK,SP	;store stack pointer for cool start
	SETB	RS0		;SELECT REGISTER BANK 1
	CLR	RS1
	CLR	A
	MOV	DPTR,#BYTENUM
	MOV	R0,#(RAMEND-BYTENUM+1)
CLEAR:	MOVX	@DPTR,A		;clear space used by break routine
	INC	DPTR
	DJNZ	R0,CLEAR
DLAY:	DJNZ	ACC,DLAY	;WAIT HERE FOR UART TO WAKE-UP
	DJNZ	R0,DLAY
	MOV	DPTR,#UARTCONT	;INIT UART
	CLR	A
	MOVX	@DPTR,A		;send three zeros because you don't know
	NOP			;in what crazy mode the ugh-art wakes up
	DJNZ	ACC,$-1
	MOVX	@DPTR,A
	NOP
	DJNZ	ACC,$-1
	MOVX	@DPTR,A
	NOP
	DJNZ	ACC,$-1
	MOV	A,#40H		;software reset uart
	MOVX	@DPTR,A
	CLR	A		;many thanks to Ernest Penzenstadler
	NOP			;for taming the infamous 8251A ugh-art!
	DJNZ	ACC,$-1
	MOV	A,#01001110B	;MODE
	MOVX	@DPTR,A
	MOVX	A,@DPTR		;GET STATUS
	JNB	ACC.0,$-1	;WAIT FOR TXRDY
	MOV	A,#00110111B	;COMMAND
	MOVX	@DPTR,A
	MOV	DPTR,#MSIGNON
	CALL	PDATA
COOL:	MOV	SP,STACK

;*************************************************************

WARM:
	MOV	DPTR,#MPROMPT	;WARM START
	CALL	PDATA
	CALL	INCH
	JNB	ACC.6,$+5	;JUMP IF NOT A LETTER
	CLR	ACC.5		;CONVERT LOWER TO UPPER CASE
	MOV	R7,A		;SAVE CHARACTER INPUT
	MOV	DPTR,#FUNTAB	;POINT TO FUNCTION TABLE
SCAN:	CLR	A
	MOVC	A,@A+DPTR
	JZ	WARM		;END OF TABLE
	CJNE	A,0FH,NEXT	;COMPARE WITH SAVED CHARACTER
	MOV	A,#01H
	MOVC	A,@A+DPTR	;GET HIGH BYTE OF JUMP
	MOV	R2,A		;SAVE IN R2
	MOV	A,#02H
	MOVC	A,@A+DPTR	;GET LOW BYTE OF JUMP
	MOV	R3,A		;SAVE IN R3
	PUSH	REG3		;PUSH R3 (LOW BYTE)
	PUSH	REG2		;PUSH R2 (HIGH BYTE)
	RET			;POP & JUMP
NEXT:	INC	DPTR
	INC	DPTR
	INC	DPTR
	JMP	SCAN

	PAGE

;*************************************************************

HELP:
	MOV	DPTR,#MHELP
	CALL	PDATA
	JMP	WARM

;*************************************************************

DUMP:	CALL	BADDR
	JNC	DMP3
	CLR	ACC.5		;CONVERT LOWER TO UPPER CASE
	CJNE	A,#'I',DMP1
	JMP	DUMPI		;DUMP INTERNAL RAM

DMP1:	JMP	WARM

DMP3:	MOV	FIRST,HIBYTE	;DUMP PROGRAM MEMORY
	MOV	(FIRST+1),LOBYTE
	MOV	LAST,#0FFH
	MOV	(LAST+1),#0FFH
	CJNE	A,#CR,DMP4	;DEFAULT IF NO END ADDRESS ENTERED
	JMP	(NEWLIN-6)

DMP4:	CALL	BADDR2
	JB	F0,DMP5		;CARRIAGE RETURN READ
	MOV	LAST,HIBYTE
	MOV	(LAST+1),LOBYTE
DMP5:	MOV	DPTR,#MINDEX
	LCALL	PDATA
NEWLIN:
	MOV	DPH,FIRST
	MOV	DPL,(FIRST+1)
	ANL	DPL,#0F0H
	CALL	CRLF
	MOV	R0,DPH
	CALL	OUTR0		;DISPLAY ADDRESS
	MOV	R0,DPL
	CALL	OUTR0
	CALL	OUT2S
SPACES:	MOV	A,(FIRST+1)	;BLANK LOCATIONS BEFORE FIRST
	XRL	A,DPL
	JZ	MORE		;JUMP IF EQUAL
	CALL	OUT3S
	INC	DPTR
	CALL	MIDCHK
	JMP	SPACES


MORE:	CALL	OUTC2HS
	MOV	A,LAST
	CJNE	A,DPH,MOREC
	MOV	A,(LAST+1)
	CJNE	A,DPL,MOREC
	JMP	ENDHEX

MOREC:	INC	DPTR
	CALL	MIDCHK
	JZ	DASCII		;NOW DUMP ASCII
	JMP	MORE

ENDHEX:	INC	DPTR
	CALL	MIDCHK
	JZ	DASCII		;NOW DUMP ASCII (LAST LINE)
	CALL	OUT3S
	JMP	ENDHEX

DASCII:	CALL	OUT4S		;SHOW ASCII EQUIVALENT
	MOV	DPH,FIRST
	MOV	DPL,(FIRST+1)
	ANL	DPL,#0F0H
DASCI1:	MOV	A,(FIRST+1)
	XRL	A,DPL
	JZ	DASCI2
	CALL	OUTS
	INC	DPTR
	CALL	MIDCHK
	JMP	DASCI1

DASCI2:	CLR	A
	MOVC	A,@A+DPTR
	MOV	B,A
	CLR	C
	SUBB	A,#SPACE
	JC	BAD3
	SUBB	A,#(7FH-SPACE)
	JC	OK3
BAD3:	MOV	B,#DOT
OK3:	MOV	A,B
	CALL	OUTCH

	MOV	A,LAST
	CJNE	A,DPH,DASCI3
	MOV	A,(LAST+1)
	CJNE	A,DPL,DASCI3
	JMP	WARM

DASCI3:	INC	DPTR
	CALL	MIDCHK
	JNZ	DASCI2
	MOV	A,#16
	ADD	A,(FIRST+1)
	ANL	A,#0F0H
	JNC	$+4
	INC	FIRST
	MOV	(FIRST+1),A
	JMP	NEWLIN

;*************************************************************

TABENT		EQU	11	;LENGTH OF SFR TABLE ENTRY
OFF1		EQU	6	;OFFSET TO HEX ADDRESS
OFF2		EQU	5	;OFFSET TO FETCH CONTENTS
OFF3		EQU	8	;OFFSET TO CHANGE CONTENTS

DUMPI:
	CALL	BADDR
	JNC	$+5
	LJMP	WARM

	MOV	FIRST,LOBYTE
	MOV	LAST,#0FFH
	XRL	A,#CR
	JZ	(LINE-6)
	CALL	BADDR2
	JB	F0,$+6		;CARRIAGE RETURN READ
	MOV	LAST,LOBYTE
	MOV	A,#7FH		;TOP OF RAM
	CLR	C
	SUBB	A,FIRST
	JC	DSFR		;DONE RAM--DO SFR'S
	MOV	DPTR,#MINDEX
	LCALL	PDATA
LINE:	CALL	CRLF
	MOV	A,#7FH		;TOP OF RAM
	CLR	C
	SUBB	A,FIRST
	JC	DSFR		;DONE RAM--DO SFR'S
	MOV	R0,FIRST
	ANL	REG0,#0F0H	;8=R0
	CALL	OUTR03S		;DISPLAY ADDRESS
SPICES:	MOV	A,FIRST		;SPACES BEFORE BEGINNING
	XRL	A,R0
	JZ	NXTBYT
	CALL	OUT3S
	INC	R0
	MOV	A,#07H
	ANL	A,R0
	JNZ	$+5
	LCALL	OUTS		;MIDDLE OF LINE
	JMP	SPICES

NXTBYT:	CALL	OUT2H
	CALL	OUTS
	MOV	A,R0
	XRL	A,LAST
	JNZ	$+5
	LJMP	WARM

	INC	R0
	MOV	A,#07H
	ANL	A,R0
	JNZ	$+5
	LCALL	OUTS		;MIDDLE OF LINE
	MOV	A,#0FH
	ANL	A,R0
	JNZ	NXTBYT		;NOT END OF LINE
	MOV	A,FIRST
	ANL	A,#0F0H
	ADD	A,#10H
	MOV	FIRST,A
	JMP	LINE

DSFR:	MOV	DPTR,#(SFRTAB-TABENT)
	MOV	R1,#6
	CALL	CRLF
DSFR1:	MOV	A,#TABENT
	ADD	A,DPL
	MOV	DPL,A
	JNC	$+4
	INC	DPH
	MOV	A,#OFF1		;OFFSET TO SFR HEX LOCATION
	MOVC	A,@A+DPTR
	CLR	C
	SUBB	A,FIRST
	JC	DSFR1		;NOT TO FIRST YET

DSFR5:	MOV	A,#OFF1
	MOVC	A,@A+DPTR	;GET HEX LOCATION OF SFR
	MOV	R0,FIRST
	XRL	A,R0
	JZ	DSFR10
	INC	FIRST		;WASN'T A VALID SFR
	MOV	A,FIRST
	JZ	(LINE-6)	;BACK TO RAM
	CJNE	A,LAST,DSFR5
	JMP	WARM		;DONE

DSFR10:	CALL	OUTR0
	MOV	A,#('=')
	CALL	OUTCH
	CALL	PDATA		;OUTPUT LOCATION LABEL (ALTERS DPTR)
	MOV	A,#(':')
	CALL	OUTCH
	MOV	A,#LOW(DSFR20)
	PUSH	ACC
	MOV	A,#HIGH(DSFR20)
	PUSH	ACC
	MOV	A,#(OFF2-4)	;OFFSET TO "MOV	R0,SFR"
	JMP	@A+DPTR

DSFR20:	CALL	OUTR0
	CALL	OUT2S
	DJNZ	R1,DSFR30
	MOV	R1,#6
	CALL	CRLF
DSFR30:	INC	FIRST
	MOV	A,#(TABENT-4)
	ADD	A,DPL
	MOV	DPL,A
	JNC	$+4
	INC	DPH
	MOV	A,FIRST
	JNZ	$+5
	LJMP	LINE
	DEC	A
	XRL	A,LAST
	JNZ	DSFR5
	JMP	WARM


;*************************************************************

COPY:	CALL	THRADR
	CALL	CPY
	JMP	WARM

;*************************************************************

VERIFY:	CALL	THRADR
VER10:	MOV	DPH,FIRST
	MOV	DPL,(FIRST+1)
	CLR	A
	MOVC	A,@A+DPTR
	MOV	R1,A
	MOV	DPH,TO
	MOV	DPL,(TO+1)
	CLR	A
	MOVC	A,@A+DPTR
	MOV	R2,A
	XRL	A,R1
	JZ	VER20		;JUMP IF EQUAL
	CALL	CRLF
	MOV	R0,#FIRST
	CALL	OUT2H
	MOV	R0,#(FIRST+1)
	CALL	OUT2H
	CALL	OUT2S
	MOV	R0,#REG1	;R1
	CALL	OUT2H
	CALL	OUT4S
	MOV	R0,#TO
	CALL	OUT2H
	MOV	R0,#(TO+1)
	CALL	OUT2H
	CALL	OUT2S
	MOV	R0,#REG2	;R2
	CALL	OUT2H
VER20:	MOV	A,FIRST
	CJNE	A,LAST,VER30
	MOV	A,(FIRST+1)
	CJNE	A,(LAST+1),VER30
	JMP	WARM
VER30:	MOV	R0,#(FIRST+1)
	CALL	INC16
	MOV	R0,#(TO+1)
	CALL	INC16
	JMP	VER10

;*************************************************************

ALTER:	CALL	BADDR
	JNC	ALT05
	JNB	F0,ALTEND	;ERROR
	CLR	ACC.5		;CONVERT LOWER TO UPPER CASE
	CJNE	A,#('I'),ALTEND	;ERROR
	JMP	SUBSTUT

ALT05:	MOV	FIRST,HIBYTE
	MOV	(FIRST+1),LOBYTE
ALT10:	CALL	CRLF
	MOV	R0,#FIRST	;SHOW ADDRESS
	CALL	OUT2H
	INC	R0
	CALL	OUT2H
ALT15:	CALL	OUTS
	MOV	DPH,FIRST
	MOV	DPL,(FIRST+1)
	CLR	A
	MOVC	A,@A+DPTR	;GET DATA
	MOV	R1,A
	MOV	R0,#REG1	;SHOW DATA
	CALL	OUT2H
	MOV	A,#('-')
	CALL	OUTCH
	CALL	BYTES
	JNC	ALT20
	XRL	A,#BACKSP
	JZ	BACKUP
	XRL	A,#BACKSP	;RESTORE A
	XRL	A,#DOT
	JZ	BACKUP
ALTEND:	JMP	WARM		;ERROR

ALT20:	JB	F0,ALT30	;<CR> OR SPACE
	MOV	A,LOBYTE
	MOVX	@DPTR,A		;CHANGE DATA
ALT30:	MOV	R0,#(FIRST+1)
	CALL	INC16
	MOV	A,B
	XRL	A,#CR
	JZ	ALT10
	MOV	A,(FIRST+1)
	ANL	A,#07H
	JZ	ALT10
	JMP	ALT15

BACKUP:	MOV	R0,#(FIRST+1)
	CALL	DEC16
	JMP	ALT10

;*************************************************************

MODIFY	CALL	BADDR
	MOV	DPH,HIBYTE
	MOV	DPL,LOBYTE
MOD10:	CALL	INCH
	CJNE	A,#BACKSP,NOTBS
	DEC	DPL
	MOV	A,#0FFH
	CJNE	A,DPL,MOD10
	DEC	DPH
	JMP	MOD10

NOTBS:	CJNE	A,#EOT,$+6
	LJMP	WARM
	MOVX	@DPTR,A
	INC	DPTR
	JMP	MOD10

;*************************************************************

SUBSTUT:
	CALL	BADDR
	MOV	R0,LOBYTE
IF010:	MOV	A,#7FH		;IF ADDRESS >= 80H OR <= F0H
	CLR	C
	SUBB	A,R0
	JNC	ELS010
	MOV	A,#0F0H
	CLR	C
	SUBB	A,R0
	JC	ELS010
THN010:	MOV	DPTR,#(SFRTAB-TABENT)
SUB60:	MOV	A,#TABENT	;INCREMENT TABLE POINTER
	ADD	A,DPL
	MOV	DPL,A
	JNC	$+4
	INC	DPH
	MOV	A,#OFF1		;FIND 1ST ENTRY >= R0
	MOVC	A,@A+DPTR
	CLR	C
	SUBB	A,R0
	JC	SUB60		;NOT FOUND YET
SUB65:	MOV	A,#OFF1		;INCREMENT R0 TO LINE IN TABLE
	MOVC	A,@A+DPTR
	XRL	A,R0
	JZ	SUB70		;FOUND IT
	INC	R0
	JMP	SUB65

ELS010:	JMP	LS010		;RELAY STATION

SUB70:	CALL	CRLF		;DISPLAY ADDRESS
	CALL	OUTR03S
	CALL	PDATA		;ALTERS DPTR (ADDS 4)
	MOV	A,#(':')
	CALL	OUTCH
	MOV	REG1,R0		;MOV	R1,R0
	MOV	A,#LOW(SUB80)
	PUSH	ACC
	MOV	A,#HIGH(SUB80)
	PUSH	ACC
	MOV	A,#(OFF2-4)
	JMP	@A+DPTR		;CRASHES R0

SUB80:	CALL	OUTR0		;DISPLAY DATA
	MOV	A,#('-')
	CALL	OUTCH
	MOV	R0,REG1		;RESTORE R0
	CALL	BYTES
IF020:	JNC	ELS020		;IF CHARACTER = DOT OR BACKSPACE
	MOV	A,B
	XRL	A,#BACKSP
	JZ	THN020
	MOV	A,B
	XRL	A,#DOT
	JZ	THN020
	JMP	WARM		;ERROR

THN020:				;THEN BACKUP
IF030:	CJNE	R0,#80H,ELS030
THN030:	MOV	R0,#7FH
	JMP	IF010

ELS030:	MOV	A,DPL
	CLR	C
	SUBB	A,#(TABENT+4)
	MOV	DPL,A
	JNC	$+4
	DEC	DPH
	MOV	A,#(OFF1)
	MOVC	A,@A+DPTR
	MOV	R0,A
	JMP	IF010

ELS020:
	JB	F0,SUB90
	SETB	F0
	MOV	R0,LOBYTE
	MOV	A,#LOW(SUB90)
	PUSH	ACC
	MOV	A,#HIGH(SUB90)
	PUSH	ACC
	MOV	A,#(OFF3-4)
	JMP	@A+DPTR		;CRASHES R0

SUB90:	MOV	R0,REG1		;RESTORE R0
IF035:	JB	F0,NDI035
THN035:	MOV	DPTR,#MNONO
	CALL	PDATA
NDI035:
IF040:	CJNE	R0,#0F0H,NDI040	;IF R0 = 0F
THN040:	MOV	R0,#0FFH	;THEN R0 = FFH
NDI040:
	INC	R0
	JMP	IF010


LS010:	CALL	CRLF
	CALL	OUTR03S
SUB20:	CALL	OUT2H
	MOV	A,#('-')
	CALL	OUTCH
	MOV	REG1,R0
	CALL	BYTES		;clobbers r0
	MOV	R0,REG1
IF050:	JNC	ELS050		;IF CHAR. = BACKSP. OR DOT
	MOV	A,B
	XRL	A,#BACKSP
	JZ	THN050
	MOV	A,B
	XRL	A,#DOT
	JZ	THN050
	JMP	WARM

THN050:				;THEN BACKUP
IF060:	MOV	A,R0
	JNZ	NDI060		;IF R0 = 0
THN060:	MOV	R0,#0F1H	;THEN R0 = F1H
NDI060:
NDI050:
	DEC	R0
F010:	JMP	IF010		;ALSO USED FOR RELAY

ELS050:
IF070:	JB	F0,NDI070	;IF NOT SPACE OR CR
THN070:	MOV	A,LOBYTE	;THEN CHANGE BYTE
	MOV	@R0,A
NDI070:	INC	R0
	MOV	A,#07H
	ANL	A,R0
	JZ	F010
	CALL	OUT2S
	JMP	SUB20
;*************************************************************

INSERT:	CALL	THRADR
	MOV	DPH,FIRST
	MOV	DPL,(FIRST+1)
INS10:	MOV	A,(TO+1)
	MOVX	@DPTR,A
	MOV	A,DPH
	CJNE	A,LAST,INS20
	MOV	A,DPL
	CJNE	A,(LAST+1),INS20
	JMP	WARM

INS20:	INC	DPTR
	JMP	INS10

;*************************************************************

BREAK:			;  REMOVE OLD BREAKPOINT
	MOV	DPTR,#BYTENUM
	CLR	A
	MOVC	A,@A+DPTR
	MOV	R1,A		;SAVE OLD BYTENUM IN R1
IF100:	JZ	NDI100		;IF THERE IS AN OLD BREAKPOINT
THN100:	MOV	FIRST,#HIGH(BYTENUM+1)	;THEN REMOVE IT
	MOV	FIRST+1,#LOW(BYTENUM+1)
	MOV	LAST,#HIGH(BYTENUM)
	MOV	A,#LOW(BYTENUM)
	ADD	A,R1		;ADD OLD BYTENUM
	MOV	LAST+1,A
	JNC	$+4
	INC	LAST
	MOV	DPTR,#(RAMEND-1)
	CLR	A
	MOVC	A,@A+DPTR
	MOV	TO,A
	MOV	DPTR,#RAMEND
	CLR	A
	MOVC	A,@A+DPTR
	CLR	C
	SUBB	A,R1		;SUBTRACT OLD BYTENUM
	MOV	TO+1,A
	JNC	$+4
	DEC	TO
	CALL	CPY
	CLR	A		;CLEAR END OF RAM
	MOV	DPTR,#BYTENUM
	MOV	R0,#(RAMEND-BYTENUM+1-3)	;LEAVE JUMP INSTRUCTION
CLEAR1:	MOVX	@DPTR,A
	INC	DPTR
	DJNZ	R0,CLEAR1
NDI100:
	CALL	BYTES		;INSTALL NEW BREAKPOINT
IF150:	JNC	NDI150		;IF NOT VALID HEX
	JMP	WARM		;THEN END

NDI150:
IF155:	JNB	F0,NDI155	;IF CR
	XRL	A,#SPACE
	JZ	NDI100		;AND NOT SPACE
	JMP	WARM		;THEN END

NDI155:	MOV	FIRST,HIBYTE
	MOV	FIRST+1,LOBYTE
	MOV	DPTR,#BYTENUM
	MOV	A,#3		;IN CASE OF DEFAULT
	MOVX	@DPTR,A
	MOV	R1,A		;SAVE DEFAULT NEW BYTENUM
IF160:	MOV	A,B
	XRL	A,#CR
	JZ	NDI160
THN160:	CALL	INHEX		;get BYTENUM
IF170:	JNC	ELS170		;if not valid hex
THN170:	MOV	A,B		;then check for space or CR
	XRL	A,#SPACE
	JZ	THN160
	MOV	A,B
	XRL	A,#CR
	JZ	NDI170
	MOV	DPTR,#BYTENUM
	CLR	A
	MOVX	@DPTR,A
	JMP	WARM

ELS170:	MOV	DPTR,#BYTENUM	;else accept only 3, 4 or 5
	MOVX	@DPTR,A
	MOV	R1,A		;SAVE NEW BYTENUM
	SUBB	A,#3
	JC	BAD4
	SUBB	A,#(6-3)
	JNC	BAD4
	JMP	NDI170

BAD4:	MOV	DPTR,#BYTENUM
	CLR	A
	MOVX	@DPTR,A
	JMP	WARM

NDI170:
NDI160:
				;FIRST,FIRST+1 AND HIBYTE,LOBYTE
				;  BOTH CONTAIN BREAK ADDRESS
				;R1 CONTAINS NEW BYTENUM
	MOV	DPTR,#(RAMEND-2)
	MOV	A,#02H		;"LJMP"
	MOVX	@DPTR,A
	MOV	A,FIRST+1
	ADD	A,R1		;ADD BYTENUM
	MOV	LAST+1,A
	MOV	DPTR,#RAMEND
	MOVX	@DPTR,A
	MOV	A,FIRST
	JNC	$+3
	INC	A
	MOV	LAST,A
	MOV	DPTR,#(RAMEND-1)
	MOVX	@DPTR,A
	MOV	R0,#(LAST+1)
	CALL	DEC16		;ADJUST (LAST,LAST+1)
	MOV	TO,#HIGH(BYTENUM+1)
	MOV	TO+1,#LOW(BYTENUM+1)
	CALL	CPY		;SAVE INSTRUCTIONS IN END OF RAM
	MOV	DPL,LOBYTE
	MOV	DPH,HIBYTE	;INSERT JUMP TO BRKPT
	MOV	A,#02H		;"LJMP"
	MOVX	@DPTR,A
	INC	DPTR
	MOV	A,#HIGH(BRKPT)
	MOVX	@DPTR,A
	INC	DPTR
	MOV	A,#LOW(BRKPT)
	MOVX	@DPTR,A
	JMP	WARM

;*************************************************************

BRKPT:	PUSH	ACC
	PUSH	PSW
	PUSH	B
	PUSH	DPH
	PUSH	DPL
	MOV	STACK,SP	;save current stack level for cool start
	SETB	RS0		;SELECT REGISTER BANK 1
	CLR	RS1
	MOV	DPTR,#MBRK1
	CALL	PDATA
	MOV	DPTR,#(BYTENUM)
	CLR	A
	MOVC	A,@A+DPTR
	MOV	R0,A
	MOV	DPTR,#(RAMEND)
	CLR	A
	MOVC	A,@A+DPTR
	CLR	C
	SUBB	A,R0
	MOV	B,A
	MOV	DPTR,#(RAMEND-1)
	CLR	A
	MOVC	A,@A+DPTR
	MOV	R0,A
	JNC	$+3
	DEC	R0
	CALL	OUTR0
	MOV	R0,B
	CALL	OUTR0
	MOV	DPTR,#MBRK2
	CALL	PDATA
	MOV	A,STACK
	CLR	C
	SUBB	A,#4
	MOV	R0,A
	CALL	OUT2H
	MOV	DPTR,#MBRK3
	CALL	PDATA
	INC	R0
	CALL	OUT2H
	MOV	DPTR,#MBRK4
	CALL	PDATA
	INC	R0
	CALL	OUT2H
	MOV	DPTR,#MBRK5
	CALL	PDATA
	INC	R0
	CALL	OUT2H
	INC	R0
	CALL	OUT2H
	MOV	DPTR,#MBRK6
	CALL	PDATA
	MOV	R0,#STACK
	CALL	OUT2H
	JMP	WARM

;*************************************************************

GO:	CALL	BYTES
	JNC	$+5
	LJMP	WARM

	JNB	F0,GXXXX
	CJNE	A,#CR,GO		;LOOK AGAIN IF SPACE
	MOV	HIBYTE,#HIGH(BYTENUM+1)
	MOV	LOBYTE,#LOW(BYTENUM+1)
	MOV	SP,STACK		;restore stack if necessary
	POP	DPL
	POP	DPH
	POP	B
	POP	PSW
	POP	ACC
GXXXX:
	PUSH	LOBYTE
	PUSH	HIBYTE
	RET

;*************************************************************

HEXMATH:
	CALL	BADDR
	JNC	$+5
	LJMP	WARM

	MOV	FIRST,HIBYTE
	MOV	(FIRST+1),LOBYTE
	CALL	BADDR
	JNC	$+5
	LJMP	WARM

	MOV	A,(FIRST+1)
	ADD	A,LOBYTE
	MOV	(LAST+1),A	;STORE LOW BYTE OF SUM
	MOV	A,FIRST
	ADDC	A,HIBYTE
	MOV	LAST,A		;STORE HIGH BYTE OF SUM

	MOV	A,(FIRST+1)
	CLR	C
	SUBB	A,LOBYTE
	MOV	(TO+1),A	;STORE LOW BYTE OF DIFFERENCE
	MOV	A,FIRST
	SUBB	A,HIBYTE
	MOV	TO,A		;STORE HIGH BYTE OF DIFFERENCE
	CALL	CRLF
	MOV	R0,#FIRST	;POINT TO ADDEND
	CALL	OUT4HS
	MOV	A,#'+'
	CALL	OUTCH
	CALL	OUTS
	MOV	R0,#HIBYTE	;POINT TO AUGEND
	CALL	OUT4HS
	MOV	A,#'='
	CALL	OUTCH
	CALL	OUTS
	MOV	R0,#LAST	;POINT TO SUM
	CALL	OUT4HS
	CALL	CRLF
	MOV	R0,#FIRST	;POINT TO SUBTRAHEND
	CALL	OUT4HS
	MOV	A,#'-'
	CALL	OUTCH
	CALL	OUTS
	MOV	R0,#HIBYTE	;POINT TO MINUEND
	CALL	OUT4HS
	MOV	A,#'='
	CALL	OUTCH
	CALL	OUTS
	MOV	R0,#TO		;POINT TO DIFFERENCE
	CALL	OUT4HS
	JMP	WARM

;*************************************************************

JUMPTABL:
	MOV	DPTR,#MJUMP
	CALL	PDATA
	JMP	WARM

	PAGE
;*************************************************************
;
;ROUTINE	PDATA
;	WRITES A MESSAGE TO THE TERMINAL
;	ENTER WITH DPTR POINTING TO BEGINNING OF MESSAGE
;	AND 04H AT END OF MESSAGE.
;
PDATA1:	CALL	OUTCH
	INC	DPTR
PDATA:	CLR	A
	MOVC	A,@A+DPTR
	CJNE	A,#EOT,PDATA1
	RET

;*************************************************************
;
;ROUTINE	IN
;	READ AN 8-BIT CHAR FROM 8251A UART
;
IN:	PUSH	DPH
	PUSH	DPL
	MOV	DPTR,#UARTCONT
	MOVX	A,@DPTR
	JNB	ACC.1,$-1	;WAIT FOR RX RDY
	DEC	DPL		;POINT TO DATA REGISTER
	MOVX	A,@DPTR
	POP	DPL
	POP	DPH
	RET

;*************************************************************
;
;ROUTINE	INCH
;	READ A CHARACTER, ZERO HIGH BIT, & ECHO BACK TO TERMINAL
;
INCH:	CALL	IN		;READ 8-BIT CHAR.
	ANL	A,#7FH		;ZERO HIGH BIT
	JMP	OUT		;ECHO BACK

;*************************************************************
;
;ROUTINE	OUTCH
;	OUTPUT A CHARACTER
;
OUTCH:	CALL	OUT
	JNC	NOINPU		;TEST FOR INPUT DURING OUTPUT
	CALL	IN		;GET RID OF THE CHARACTER
	JMP	COOL		;RESET STACK POINTER

NOINPU:	RET

;*************************************************************
;
;ROUTINE	OUT
;	SEND "A" REGISTER TO UART
;	SET CARRY IF RX BUFFER IS FULL
;
OUT:	PUSH	DPH
	PUSH	DPL
	PUSH	ACC		;SAVE OUTPUT BYTE
	MOV	DPTR,#UARTCONT
	MOVX	A,@DPTR
	JNB	ACC.0,$-1	;WAIT FOR TX EMPTY
	MOV	C,ACC.1		;MOV RX RDY TO CARRY
	DEC	DPL		;POINT TO DATA REGISTER
	POP	ACC		;RESTORE OUTPUT BYTE
	MOVX	@DPTR,A		;AND OUTPUT IT
	POP	DPL
	POP	DPH
	RET

	PAGE	30
;*************************************************************
;
;ROUTINE	INHEX
;	READS 1 ASCII HEX CHAR, CONVERTS TO BINARY IN ACC. &
;	STORES ORIGINAL CHAR IN B REG.
;	CARRY SET IF NOT VALID HEX, CLEARED OTHERWISE.
;
INHEX:	CALL	INCH		;GET CHARACTER
	MOV	B,A		;STORE IN B
	CJNE	A,#CR,NOTCR	;IF <CR> SEND <LF> ALSO
	MOV	A,#LF
	CALL	OUTCH
NOTCR:	MOV	A,B		;RESTORE CHARACTER
	JNB	ACC.6,$+5	;IF LOWER CASE
	CLR	ACC.5		;CONVERT TO UPPER CASE
	CLR	C
	SUBB	A,#'0'
	JC	BAD		; ACC < '0'
	SUBB	A,#10
	JNC	$+7		; ACC > '9'
	ADD	A,#10	;RESTORE
	LJMP	GOOD		; '0' <= ACC <= '9'

	ADD	A,#('0'+10-'A'+10)	;CORRECT FOR (-'0'-10) & MAP 'A' INTO 10
	JB	ACC.7,BAD	; '9' < ACC < 'A'
	CLR	C
	SUBB	A,#16
	JNC	BAD		; ACC > 'F'
	ADD	A,#16
GOOD:	CLR	C
	RET
BAD:	SETB	C
	RET

;*************************************************************
;
;ROUTINE	BYTES
;	READ IN TWO BYTE HEX NUMBER TO HIBYTE,LOBYTE
;	LAST CHARACTER READ RETURNED IN B REGISTER
;
;	ERROR CODES:		      CARRY:	F0:
;	LEADING <CR> OR SPACE		0	1	(CHAR IN ACC)
;	LEADING NONHEX CHARACTER	1	1	(CHAR IN ACC)
;	OTHER NONHEX CHARACTER		1	0	(CHAR IN ACC)
;
BYTES:	SETB	F0		;NO HEX READ YET
	CLR	A
	MOV	HIBYTE,A
	MOV	LOBYTE,A
MORE1:	CALL	INHEX
	JNC	OK1		;JUMP IF HEX DIGIT
	MOV	A,B		;LOOK AT ASCII
	CJNE	A,#CR,$+6
	LJMP	CR1

	CJNE	A,#SPACE,BAD1
CR1:	CLR	C
	RET

OK1:	CLR	F0
	MOV	R0,#LOBYTE	;POINTER
	XCHD	A,@R0		;PUT 0 DIGIT IN LOW END OF LOBYTE
	SWAP	A		;ACC NOW HAS DIGIT 1 IN HIGH END
	XCHD	A,@R0		;ACC NOW HAS DIGITS 1,0
	XCH	A,@R0		;ACC HAS DIGITS 2,X;LOBYTE DONE.
	DEC	R0		;POINT TO HIBYTE
	XCHD	A,@R0		;ACC NOW HAS DIGITS 2,3
	SWAP	A		;ACC HAS DIGITS 3,2
	XCH	A,@R0		;HIBYTE DONE
	JMP	MORE1		;LOOK FOR ANOTHER DIGIT

BAD1:	SETB	C
	RET

	PAGE	19
;*************************************************************
;
;ROUTINE	BUILD ADDRESS
;	READ IN A 16-BIT HEX NUMBER TO HIBYTE,LOBYTE.
;	RETURNS WITH CARRY & F0 SET IF A SECOND COMMAND CHARACTER
;	IS FOUND.  CHARACTER WILL BE IN ACCUMULATOR.
;	RETURNS WITH CARRY SET AND F0 CLEAR IF NON-HEX.
;
BADDR:	CALL	BYTES
	JNC	ADDROK
	JB	F0,ADDRNOK	;SECOND COMMAND CHARACTER
	JMP	WARM		;ERROR
ADDROK:	JB	F0,BADDR	;LEADING SPACE OR CR
ADDRNOK:
	RET

;*************************************************************
;
;ROUTINE	BUILD ADDRESS #2
;	READ IN A 16-BIT HEX NUMBER TO HIBYTE,LOBYTE.
;	IGNORES LEADING SPACES.  RETURNS WITH F0 SET IF
;	A LEADING CARRIAGE RETURN IS FOUND.
;
BADDR2:	CALL	BYTES
	JNC	$+5
	LJMP	WARM		;NON-HEX

	JNB	F0,ADDROK2	;NUMBER READ
	CJNE	A,#CR,BADDR2	;IGNORE LEADING SPACE
ADDROK2:
	RET

;*************************************************************
;
;ROUTINE	OUTPUT SPACES
;	OUTPUTS 1, 2, 3, OR 4 SPACES
;
OUT4S:	CALL	OUTS
OUT3S:	CALL	OUTS
OUT2S:	CALL	OUTS
OUTS:	MOV	A,#SPACE
	JMP	OUTCH

;*************************************************************
;
;ROUTINE	OUTPUT CODE, TWO HEX, SPACE
;	OUTPUTS PROGRAM MEMORY BYTE POINTED OUT BY DPTR
;	AS TWO ASCII CHARACTERS FOLLOWED BY A SPACE.
;	USES B REGISTER AS TEMP. STORE
;
OUTC2HS:
	CLR	A
	MOVC	A,@A+DPTR
	MOV	B,A		;TEMP STORE
	CALL	OUTHL
	MOV	A,B
	CALL	OUTHR
	JMP	OUTS

;*************************************************************
;
;ROUTINE	MIDCHK
;	INSERTS A SPACE IF LOW NYBBLE OF DPTR = 8.
;	RETURNS WITH LOW NYBBLE IN ACC.
;	DESTROYS B REGISTER.
;
MIDCHK:	MOV	A,DPL
	ANL	A,#0FH
	XRL	A,#08H
	JNZ	NOTMID
	XCH	A,B
	CALL	OUTS
	XCH	A,B
NOTMID:	XRL	A,#08H		;RESTORE A
	RET

	PAGE	14
;*************************************************************
;
;ROUTINES	OUTPUT HEX LEFT
;		OUTPUT HEX RIGHT
;	CONVERTS A NYBBLE IN ACC. TO ASCII AND SENDS IT
;
OUTHL:	SWAP	A
OUTHR:	ANL	A,#0FH
	JNB	ACC.3,H2	;<8
	JB	ACC.2,H1	;>=C
	JNB	ACC.1,H2	;<A
H1:	ADD	A,#07H
H2:	ADD	A,#('0')	;CONVERT TO ASCII
	JMP	OUTCH

	PAGE	9
;*************************************************************
;
;ROUTINE	OUTPUT TWO HEX
;	OUTPUTS	HEX CONTENTS OF LOCATION POINTED OUT BY R0
;
OUT2H:	MOV	A,@R0
	CALL	OUTHL
	MOV	A,@R0
	JMP	OUTHR

;*************************************************************
;
;ROUTINE	CRLF
;	SENDS A CARRIAGE RETURN AND A LINE FEED
;
CRLF:	MOV	A,#CR
	CALL	OUTCH
	MOV	A,#LF
	JMP	OUTCH

;*************************************************************
;
;ROUTINE	DECREMENT 16
;	DECREMENTS A 16-BIT NUMBER POINTED OUT BY R0.
;	ENTER WITH LOW BYTE @R0 & HIGH BYTE @(R0-1).
;	CARRY SET ON OVERFLOW, CLEARED OTHERWISE.
;
DEC16:	CLR	C
	DEC	@R0
	MOV	A,@R0
	CPL	A
	JNZ	DECEND
	DEC	R0
	DEC	@R0
	MOV	A,@R0
	CPL	A
	JNZ	DECEND
	SETB	C
DECEND:	RET

	PAGE	17
;*************************************************************
;
;ROUTINE	INCREMENT 16
;	INCREMENTS A 16-BIT NUMBER POINTED OUT BY R0.
;	ENTER WITH LOW BYTE @R0 & HIGH BYTE @(R0-1).
;	CARRY SET ON OVERFLOW, CLEARED OTHERWISE.
;
INC16:	CLR	C
	INC	@R0
	MOV	A,@R0
	JNZ	INCEND
	DEC	R0
	INC	@R0
	MOV	A,@R0
	JNZ	INCEND
	SETB	C
INCEND:	RET

	PAGE	20
;*************************************************************
;
;ROUTINE	THREE ADRESSES
;	GETS THREE 16-BIT HEX NUMBERS AND STORES THEM IN
;	"FIRST", "LAST", AND "TO" RESPECTIVELY.
;
THRADR:	CALL	BADDR
	JC	THRERR
	MOV	FIRST,HIBYTE
	MOV	(FIRST+1),LOBYTE
	CALL	BADDR
	JC	THRERR
	MOV	LAST,HIBYTE
	MOV	(LAST+1),LOBYTE
	CALL	BADDR
	JC	THRERR
	MOV	TO,HIBYTE
	MOV	(TO+1),LOBYTE
	RET
THRERR:	JMP	COOL

;*************************************************************
;
;ROUTINE	COPY
;	COPIES PROGRAM MEMORY LOCATED "FIRST" TO "LAST"
;	TO RAM LOCATION STARTING AT "TO"
;
CPY:	MOV	DPH,FIRST
	MOV	DPL,(FIRST+1)
	CLR	A
	MOVC	A,@A+DPTR
	MOV	DPH,TO
	MOV	DPL,(TO+1)
	MOVX	@DPTR,A		;PUT DATA
	MOV	A,FIRST
	CJNE	A,LAST,CPY2
	MOV	A,(FIRST+1)
	CJNE	A,(LAST+1),CPY2
	RET			;DONE

CPY2:	MOV	R0,#(FIRST+1)
	CALL	INC16
	MOV	R0,#(TO+1)
	CALL	INC16
	JMP	CPY

;*************************************************************
;
;ROUTINE	OUT, 2 HEX, 3 SPACES
;	OUTPUTS LOCATION POINTED OUT BY R0 FOLLOWED BY 3 SPACES
;
OUT2H3S:
	CALL	OUT2H
	JMP	OUT3S

	PAGE	11
;*************************************************************
;
;ROUTINE	OUTPUT R0
;	OUTPUTS THE CONTENTS OF R0
;	(8051 CAN'T ACCESS SFR'S INDIRECTLY--UGH)
;
OUTR0:	MOV	A,R0
	CALL	OUTHL
	MOV	A,R0
	JMP	OUTHR

	PAGE	9
;*************************************************************
;
;ROUTINE	OUTPUT R0, 3 SPACES
;	OUTPUTS THE CONTENTS OF R0 AND THREE SPACES
;
OUTR03S:
	CALL	OUTR0
	JMP	OUT3S

;*************************************************************
;
;ROUTINE	OUTPUT FOUR HEX, SPACE
;
;	OUTPUTS TWO CONSECUTIVE INTERNAL MEMORY LOCATIONS,
;	THE LOWER OF WHICH (HIGH BYTE OF NUMBER) IS POINTED
;	OUT BY R0.
;
OUT4HS:	CALL	OUT2H
	INC	R0
	CALL	OUT2H
	JMP	OUTS

	PAGE
;*************************************************************

FUNTAB:			;FUNCTION TABLE
	DB	'A'
	DW	ALTER
	DB	'B'
	DW	BREAK
	DB	'C'
	DW	COPY
	DB	'D'
	DW	DUMP
	DB	'G'
	DW	GO
	DB	'H'
	DW	HELP
	DB	'I'
	DW	INSERT
	DB	'J'
	DW	JUMPTABL
	DB	'M'
	DW	MODIFY
	DB	'V'
	DW	VERIFY
	DB	'#'
	DW	HEXMATH
	DB	00H	;END OF TABLE

;*************************************************************

SFRTAB:				;SPECIAL FUNCTION REGISTER TABLE
	DB	'P0  ',04H
	MOV	R0,P0  
	RET
	CLR	F0
	RET
	DB	'SP  ',04H
	MOV	R0,SP  
	RET
	CLR	F0
	RET
	DB	'DPL ',04H
	MOV	R0,DPL 
	RET
	MOV	DPL,R0
	RET
	DB	'DPH ',04H
	MOV	R0,DPH 
	RET
	MOV	DPL,R0
	RET
	DB	'PCON',04H
	MOV	R0,PCON
	RET
	MOV	PCON,R0
	RET
	DB	'TCON',04H
	MOV	R0,TCON
	RET
	MOV	TCON,R0
	RET
	DB	'TMOD',04H
	MOV	R0,TMOD
	RET
	MOV	TMOD,R0
	RET
	DB	'TL0 ',04H
	MOV	R0,TL0 
	RET
	MOV	TL0,R0
	RET
	DB	'TL1 ',04H
	MOV	R0,TL1 
	RET
	MOV	TL1,R0
	RET
	DB	'TH0 ',04H
	MOV	R0,TH0 
	RET
	MOV	TH0,R0
	RET
	DB	'TH1 ',04H
	MOV	R0,TH1 
	RET
	MOV	TH1,R0
	RET
	DB	'P1  ',04H
	MOV	R0,P1  
	RET
	MOV	P1,R0
	RET
	DB	'SCON',04H
	MOV	R0,SCON
	RET
	MOV	SCON,R0
	RET
	DB	'SBUF',04H
	MOV	R0,SBUF
	RET
	MOV	SBUF,R0
	RET
	DB	'P2  ',04H
	MOV	R0,P2  
	RET
	CLR	F0
	RET
	DB	'IE  ',04H
	MOV	R0,IE  
	RET
	MOV	IE,R0
	RET
	DB	'P3  ',04H
	MOV	R0,P3  
	RET
	MOV	P3,R0
	RET
	DB	'IP  ',04H
	MOV	R0,IP  
	RET
	MOV	IP,R0
	RET
	DB	'PSW ',04H
	MOV	R0,PSW 
	RET
	MOV	PSW,R0
	RET
	DB	'ACC ',04H
	MOV	R0,ACC 
	RET
	MOV	ACC,R0
	RET
	DB	'B   ',04H
	MOV	R0,B   
	RET
	MOV	B,R0
	RET

;*************************************************************

MPROMPT:
	DB	CR,LF,'UGH:',04H

MHELP:	DB	CR,LF,'REGISTER BANK 1 IS RESERVED'
	DB	CR,LF,'LAST 9 BYTES OF EXT. RAM USED BY BREAK ROUTINE'
	DB	CR,LF,'RAM @ 48H-50H IS USED BY MONITOR'
	DB	CR,LF,'RAM ABOVE 50H IS USED FOR STACK',LF
	DB	CR,LF,'COMMANDS ARE',LF
	DB	CR,LF,'A SSSS',TAB,TAB,TAB,'ALTER EXTERNAL MEMORY'
	DB	CR,LF,'AI SS',TAB,TAB,TAB,'ALTER INTERNAL MEMORY'
	DB	CR,LF,'B {AAAA {#}}',TAB,TAB,'BREAK @ AAAA (#=3,4,OR 5)
	DB	CR,LF,'C SSSS FFFF TTTT',TAB,'COPY BLOCK OF MEMORY'
	DB	CR,LF,'D SSSS {FFFF}',TAB,TAB,'DUMP PROGRAM MEMORY'
	DB	CR,LF,'DI SS {FF}',TAB,TAB,'DUMP INTERNAL MEMORY'
	DB	CR,LF,'G {AAAA}',TAB,TAB,'GO @ AAAA OR BREAKPOINT'
	DB	CR,LF,'H',TAB,TAB,TAB,'HELP'
	DB	CR,LF,'I SSSS FFFF HH',TAB,TAB,'INSERT "HH" INTO MEMORY'
	DB	CR,LF,'J', TAB, TAB,TAB, 'LIST JUMP TABLE'
	DB	CR,LF,'M SSSS',TAB,TAB,TAB,'MODIFY EXTERNAL MEMORY (ASCII)'
	DB	CR,LF,'V SSSS FFFF TTTT',TAB,'VERIFY MEMORY'
	DB	CR,LF,'# MMMM NNNN ',TAB,TAB,'HEX ADDITION & SUBTRACTION'
	DB	CR,LF,04H

MBRK1:	DB	CR,LF,'BREAK AT LOCATION ',04H
MBRK2:	DB	CR,LF,'ACC = ',04H
MBRK3:	DB	'    PSW = ',04H
MBRK4:	DB	'    B = ',04H
MBRK5:	DB	'    DPTR = ',04H
MBRK6:	DB	'    SP = ',04H

MINDEX:	DB	CR,LF,'      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F',04H

MNONO:	DB	CR,LF,'OOPS, THAT',27H,'S A NO-NO !',04H

MJUMP:
	DB	CR,LF, '0026	COOL',TAB, 'COOL START (RESET STACK POINTER)'
	DB	CR,LF, '0029	WARM',TAB, 'WARM START'
	DB	CR,LF, '002C	IN',TAB, 'GET A BYTE FROM THE UART'
	DB	CR,LF, '002F	INCH',TAB, 'GET A CHARACTER (ZERO PARITY)'
	DB	CR,LF, '0032	INHEX',TAB, 'GET A HEX CHAR (CARRY=NONHEX)'
	DB	CR,LF, '0035	BYTES',TAB, '2 BYTE HEX TO HI/LOBYTE'
	DB	CR,LF, '0038	BADDR',TAB, 'BUILD ADDRESS'
	DB	CR,LF, '003B	THRADR',TAB, 'THREE ADDRESSES'
	DB	CR,LF, '003E	OUT',TAB, 'OUTPUT BYTE IN ACC.'
	DB	CR,LF, '0041	OUTCH',TAB, 'OUTPUT CHARACTER IN ACC.'
	DB	CR,LF, '0044	OUTS',TAB, 'OUTPUT SPACE'
	DB	CR,LF, '0047	OUT2S',TAB, 'OUTPUT 2 SPACES'
	DB	CR,LF, '004A	CRLF',TAB, 'OUTPUT [CR] AND [LF]'
	DB	CR,LF, '004D	OUT2H',TAB, 'OUTPUT LOC. POINTED BY R0'
	DB	CR,LF, '0050	OUTR0',TAB, 'OUTPUT CONTENTS OF R0'
	DB	CR,LF, '0053	OUTC2HS',TAB, 'OUTPUT PROG. MEM. POINTED'
	DB	' BY DPTR, AND SPACE'
	DB	CR,LF, '0056	PDATA',TAB, 'OUTPUT MESSAGE POINTED BY DPTR'
	DB	CR,LF, '0059	INC16',TAB, 'INCREMENT 2 BYTE NO.'
	DB	' (R0=LOW BYTE)'
	DB	CR,LF, '005C	DEC16',TAB, 'DECREMENT 2 BYTE NO.'
	DB	' (R0+1=HIGH BYTE)'
	DB	CR,LF, '005F	CPY',TAB, 'BLOCK COPY'
	DB	CR,LF, '0062	BRKPT',TAB, 'BREAKPOINT ROUTINE'
	DB	04H
	END

