;SYS9/ASM - LS-DOS 6.2
	TITLE	<SYS9 - LS-DOS 6.2>
;
*LIST	OFF			;Get SYS5/EQU
*GET	SYS5/EQU:2		;Xref from sys5
*LIST	ON
*GET	COPYCOM:3		;Copyright message
	ORG	0A0H
;
SAVONE	DS	1
SAVTWO	DS	1
	DS	1		;Space for saved byte (1)
NXTADR	DS	2
NXTBYT	DS	1
DSPADR	DS	2
AFREG	DS	6		;AF, BC, DE
HLREG	DS	2		;HL
	DS	8		;AF', BC', DE', HL'
IXREG	DS	2		;IX
IYREG	DS	2		;IY
SPREG	DS	1		;SP
REGSAV	DS	1
PCREG	DS	2		;PC
;
	ORG	1E00H
;
SYS9	AND	70H
	RET	Z		;Back on zero entry
	LD	HL,(EXTDBG$)	;P/u hook address
	XOR	A		;See if already resident
	LD	DE,-ORARET@
	ADC	HL,DE		;ADD does not effect Z
	RET	NZ		;Ret if resident already
	LD	HL,(HIGH$)	;Change high$ to provide
	LD	(DEBUGE+2),HL	;Stuff last byte used
	LD	BC,LAST-DEBUGE	;Room for relocating
	XOR	A		;  this module to high
	SBC	HL,BC
	LD	(HIGH$),HL
	INC	HL		;Pt to new entry point
	PUSH	HL		;Save it for later
	EX	DE,HL		;Move extended debug
	LD	HL,DEBUGE	;  up to top of core
	LDIR
	POP	HL		;Rcvr pointer to ept
	LD	(EXTDBG$),HL	;  & reset sysres vector
	RET
;
;	Start of extended debug utility
;
DEBUGE	JR	NEXT
	DW	$-$
	DB	6,'EXTDBG'
	DW	0,0
;
;	'n'ext aaaa - position to next relative block
;	 used in stepping through a program file
;	 dumped to core in load module format
;
NEXT	CP	'n'-'0'
	JR	NZ,ENTER
	LD	HL,(NXTADR)	;Init if no further input
	CALL	HEXIN@		;Arg aaaa entered?
	INC	HL		;Bump from type to length
	LD	D,0
	LD	E,(HL)		;P/u block length
	LD	A,E
	CP	3		;Len= 0,1,2?
	JR	NC,NEX1		;If len=0,1,2 (256-8),
	INC	D		;  next block is +257-259
NEX1	INC	DE		;Bump by one for len byte
	ADD	HL,DE		;Add length to index
	LD	(NXTADR),HL	;Next block
	LD	A,L		;Now set up the display
	AND	0C0H		;Address
	LD	L,A
	LD	(DSPADR),HL
	RET
;
;	Enter hex data into memory
;
ENTER	CP	'e'-'0'		;'e'nter <addr>
	JR	NZ,LOCATE
	LD	HL,(NXTADR)	;Pt to current address
	CALL	HEXIN@		;Get new address to enter
	LD	(NXTADR),HL
	RET	C		;Back on <ENTER>
	JR	NZ,ENT1		;Go if new addr
	CALL	WR2HEX@		;  else dsply default
	CALL	WRSPA@
ENT1	LD	A,1EH		;Clear the line
	CALL	@DSP
ENT2	CALL	WR1HEX@		;Set up the display
	DEC	HL
	LD	A,'-'
	CALL	@DSP
	EX	DE,HL
	CALL	HEXIN@		;Get the modify info
	EX	DE,HL
	JR	Z,ENT3		;No change if no new data
	LD	(HL),E		;  else update byte
ENT3	RET	C		;Back if <ENTER> pressed
	INC	HL
	LD	(NXTADR),HL	;Index to next address
	JR	ENT2
;
;	'l'ocate aaaa,dd
;
LOCATE	CP	'l'-'0'
	JR	NZ,TYPE
	LD	HL,(NXTADR)	;Default current address
	INC	HL
	CALL	HEXIN@		;Prompt new address
	LD	(NXTADR),HL
	JR	NZ,LOC1		;Go if new addr
	PUSH	AF		;Save flags
	CALL	WR2HEX@		;Display default
	LD	A,','
	CALL	@DSP
	POP	AF
	LD	A,(NXTBYT)	;P/u default byte
	LD	L,A
LOC1	JR	C,LOC2		;Go if <ENTER> used
	CALL	HEXIN@		;  else get new byte
	JR	Z,LOC2		;Go if none entered
	LD	A,L
	LD	(NXTBYT),A	;  else set byte to find
	JR	LOC3
LOC2	LD	A,L		;Display byte info
	CALL	CV2HEX@
LOC3	LD	HL,(NXTADR)	;Set up for search
	LD	A,(NXTBYT)
	LD	BC,0		;Set loop to 64K
	CPIR			;Find a match
	RET	NZ		;Back if none
	DEC	HL
	LD	(NXTADR),HL	;Store new mod addr
	LD	A,L
	AND	0C0H
	LD	L,A
	LD	(DSPADR),HL
	RET
;
;	't'ype aaaa - type ascii into memory
;
TYPE	CP	't'-'0'
	JR	NZ,VERIFY
	LD	HL,(NXTADR)	;Default current address
	CALL	HEXIN@		;Prompt for new address
	LD	(NXTADR),HL
	RET	C		;Back on <ENTER>
	JR	NZ,TYP1		;Go if new addr
	CALL	WR2HEX@		;  else dsply default
TYP1	LD	A,1EH		;Clear to end of line
	CALL	@DSP
TYP2	CALL	WRSPA@
	CALL	DSPASC@		;Display current contents
	LD	A,'-'
	CALL	@DSP
	PUSH	HL		;Provide lower/upper
	CALL	GETASC@		;  case entry
	POP	HL		;  conversion
	RET	C
	CP	20H		;Advance on space
	JR	Z,TYP5
	LD	(HL),A		;Store new info
TYP5	INC	HL
	LD	(NXTADR),HL	;Advance the location
	JR	TYP2
;
;	'v'erify aaaa,bbbb,lth - verify block
;
VERIFY	CP	'v'-'0'
	JR	NZ,WORD
	LD	HL,(DSPADR)	;1st default start of dsp
	CALL	HEXIN@		;Prompt new start
	LD	(DSPADR),HL
	JR	NZ,VER1		;Go if address entered
	PUSH	AF
	CALL	WR2HEX@		;  else dsply default
	LD	A,','
	CALL	@DSP
	POP	AF
VER1	JR	C,VER2		;Jump if <ENTER> used prev.
	LD	HL,(NXTADR)	;2nd default current mod addr
	CALL	HEXIN@		;Prompt new 2nd start
	LD	(NXTADR),HL
	JR	NZ,VER2		;Go if entered
	PUSH	AF
	CALL	WR2HEX@		;  else dsply default
	LD	A,','
	CALL	@DSP
	POP	AF
VER2	LD	HL,0		;Default length to verify
	JR	C,VER3		;Go if <ENTER> sued prev
	CALL	HEXIN@		;Get new length
	JR	NZ,VER3		;Go if new len entered
	PUSH	HL
	CALL	WR2HEX@		;Dsply default len
	POP	HL
VER3	LD	B,H		;Xfer length to BC
	LD	C,L
	LD	HL,(DSPADR)	;Set up for compare
	LD	DE,(NXTADR)
VER4	LD	A,(DE)
	CP	(HL)		;Compare the two locations
	JR	NZ,VER5		;Go on non-match
	INC	DE		;  else inc pointers
	INC	HL		;  and loop for length
	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,VER4
VER5	LD	(NXTADR),DE	;Store non-match or end of
	LD	(DSPADR),HL	;  block
	RET
;
;	'w'ord aaaa,dddd - search for word dddd
;
WORD	CP	'w'-'0'
	JR	NZ,PRINT
	LD	HL,(NXTADR)	;Default current address
	INC	HL		;  but bypass next word
	INC	HL
	CALL	HEXIN@		;Get new start
	LD	(NXTADR),HL
	JR	NZ,WOR1		;Go if value entered
	PUSH	AF		;  else display default
	CALL	WR2HEX@
	LD	A,','
	CALL	@DSP
	POP	AF
	LD	A,(NXTBYT)	;Get next default
	LD	L,A
	LD	A,(SAVTWO+1)
	LD	H,A
WOR1	JR	C,WOR2		;Go if <ENTER>
	CALL	HEXIN@		;Get next value
	JR	Z,WOR2		;Go if default
	LD	A,L		;Store new value
	LD	(NXTBYT),A
	LD	A,H
	LD	(SAVTWO+1),A
	JR	WOR3
WOR2	CALL	WR2HEX@		;Display value
WOR3	LD	HL,(NXTADR)	;Start looking here
	LD	BC,0		;Init count to 64K
WOR4	LD	A,(NXTBYT)	
	CPIR			;Find first match
	RET	PO		;Return if none
	LD	A,(SAVTWO+1)	;Get 2nd half of word
	CP	(HL)		;Is a match?
	JR	NZ,WOR4		;Continue if not
	DEC	HL
	DEC	HL		;Pt 1 byte before
	LD	(NXTADR),HL	;  and save that address
	LD	A,L
	AND	0C0H
	LD	L,A
	LD	(DSPADR),HL	;New display start
	RET
;
;	'p'rint aaaa,bbbb - print memory
;
PRINT	CP	'p'-30H		;If command is not 'P',
PRI1	RET	NZ		;  back to SYS5
	CALL	HEXIN@		;Get start
	RET	Z		;Back if no start addr
	PUSH	HL
	CALL	HEXIN@		;Get end
	EX	(SP),HL
	POP	BC		;Start in HL, end in BC
	RET	Z		;Back if no end addr
	LD	A,L		;Round to multiple of 16
	AND	0F0H
	LD	L,A
	LD	A,0DH		;Send 2 blank lines to
	CALL	@PRTBYT		;  the printer
	CALL	@PRTBYT
PRI2	PUSH	HL		;Routine to write HL
	LD	A,H		;  as 4 hex digits
	RRA
	RRA
	RRA
	RRA
	AND	0FH
	ADD	A,90H
	DAA
	ADC	A,40H
	DAA
	CALL	@PRTBYT		;1st one done
	LD	A,H
	AND	0FH
	ADD	A,90H
	DAA
	ADC	A,40H
	DAA
	CALL	@PRTBYT		;2nd one done
	LD	A,L
	RRA
	RRA
	RRA
	RRA
	AND	0FH
	ADD	A,90H
	DAA
	ADC	A,40H
	DAA
	CALL	@PRTBYT		;3rd one done
	LD	A,L
	AND	0FH
	ADD	A,90H
	DAA
	ADC	A,40H
	DAA
	CALL	@PRTBYT		;4th one done
	LD	A,20H		;  & 2 spaces
	CALL	@PRTBYT
	CALL	@PRTBYT
	JR	PRI4
PRI3	JR	PRI2
;
;	Write a byte in hex
;
PRI4	LD	A,(HL)
	RRA
	RRA
	RRA
	RRA
	AND	0FH
	ADD	A,90H
	DAA
	ADC	A,40H
	DAA
	CALL	@PRTBYT		;Output it
	LD	A,(HL)
	AND	0FH
	ADD	A,90H
	DAA
	ADC	A,40H
	DAA
	CALL	@PRTBYT		;Output it
	LD	A,20H
	CALL	@PRTBYT		;  & a space
	INC	HL		;Pt to next byte
	LD	A,L		;Test multiple of 16
	AND	0FH
	JR	Z,PRI5
	AND	3		;Space on multiple of 4
	LD	A,20H
	CALL	Z,@PRTBYT
	JR	PRI4
PRI5	LD	A,20H		;Space at end of 16
	CALL	@PRTBYT
	POP	HL
PRI6	LD	A,(HL)		;Print in ASCII if
	CP	20H		;  printable; else
	JR	C,PRI7		;  convert to '.'
	CP	80H
	JR	C,PRI8
PRI7	LD	A,'.'
PRI8	CALL	@PRTBYT
	INC	HL		;Loop until 16 chars
	LD	A,L
	AND	0FH
	JR	NZ,PRI6
	LD	A,0DH		;  then a new line
	CALL	@PRTBYT
	PUSH	HL
	LD	A,L		;Check if HL is 0000
	OR	H
	JR	NZ,PRI9		;  is OK > continue
	POP	HL
	JR	PRI10		;Get OUT now
PRI9	XOR	A		;Ck on finished
	SBC	HL,BC
	POP	HL
	JR	C,PRI3
PRI10	LD	A,0DH		;3 new lines if done
	CALL	@PRTBYT
	CALL	@PRTBYT
	JP	@PRTBYT
;
LAST	EQU	$
	IFGT	$,DIRBUF$
	ERR	'Module too big'
	ENDIF
	ORG	MAXCOR$-2
	DW	LAST-SYS9	;Overlay size
;
	END	SYS9
