;BREF/ASM - BASIC cross reference utility
	TITLE	'<BREF - Xreference for BASIC>'
;
*GET SVCMAC
;
CR	EQU	13
LF	EQU	10
ETX	EQU	3
REM	EQU	08FH
DATA	EQU	84H
INDENT	EQU	16
DSP@	EQU	2		;SVC # for output device
PRT@	EQU	6
TOF	EQU	12
PRMERR	EQU	44
;
	ORG	2600H
;
FCB	DC	32,0
;
PRMTBL	DB	80H
	DB	40H.OR.16.OR.4
	DB	'LINE'		;Do line #s
LRESP:	DB	0
	DW	LPARM
	DB	40H.OR.16.OR.3
	DB	'VAR'		;Do variables
VRESP:	DB	0
	DW	VPARM
	DB	40H.OR.1
	DB	'P'		;Printer parm
PRESP:	DB	0
	DW	PPARM
	DB	80H.OR.1
	DB	'W'		;Width for prt
WRESP:	DB	0
	DW	WPARM
	DW	0
;
;
TOPMEM	DW	0
LOPOS	DW	0		;Current lowest found
CURLIN	DW	0		;Line in use
LASTNUM	DW	0
CCOUNT	DB	1		;Chars printed this line
LCOUNT	DB	0		;Lines prted this page
PAGE	DW	0
START$	DW	-1		;Be sure is biggest
LAST	DW	0		;Where last was found
NUMBUF	DB	',      ',3
LINBUF	DB	'     )',3
;
;
SIGNON$	DB	'BREF '
*GET CLIENT:3
NAMREQ$	DB	'File spec required',CR
NOTBAS$	DB	'Not a BASIC program file',CR
NOMEM$	DB	'Out of memory - can''t cross reference',CR
MEMERR$	DB	'Error in original program',CR
CMDR$	DB	'BREF only valid at DOS level',CR
;
NAMREQ:	LD	HL,NAMREQ$
	DB	0DDH
NOTBAS:	LD	HL,NOTBAS$
	DB	0DDH
NOMEM:	LD	HL,NOMEM$
	DB	0DDH
MERR:	LD	HL,MEMERR$
	DB	0DDH
CMDR:	LD	HL,CMDR$
	@@LOGOT
	JR	ABORT
;
IOERR:	OR	0C0H		;Short error msg
	LD	C,A
	@@ERROR
ABORT:	LD	HL,-1		;Show aborted
	JR	EXIT1
EXIT:	LD	HL,0
EXIT1:	LD	SP,$-$
SAVSTK	EQU	$-2
	@@CKBRKC
	RET
;
;	Break hit, see if tof needed
;
ABORT1:	LD	A,(PRESP)	;Are we printing?
	OR	A
	JR	Z,ABORT		;No, done if so
	LD	C,TOF
	@@PRT			;Else do TOF
	JR	ABORT
;
;
BEGIN:	LD	(SAVSTK),SP	;Save stack for exit
	@@CKBRKC
	JP	NZ,ABORT
	PUSH	HL		;Save cmdline
	LD	HL,SIGNON$
	@@DSPLY
	@@FLAGS			;Get flag table
	PUSH	IY
	POP	DE
	LD	HL,'K'-'A'	;Get kflag$
	ADD	HL,DE
	LD	(KFLAG),HL
	LD	HL,'S'-'A'
	ADD	HL,DE
	LD	(SFLAG),HL	;Save for open
	LD	A,(IY+'C'-'A')
	BIT	4,A		;Only lib commands?
	JP	NZ,CMDR
	LD	B,0		;Get high$
	LD	H,B
	LD	L,B
	@@HIGH$
	DEC	HL
	LD	(TOPMEM),HL	;Save size
	POP	HL
BG0:	LD	A,(HL)		;Bypass spaces
	CP	' '
	JR	NZ,BG0A
	INC	HL
	JR	BG0
BG0A:	PUSH	HL		;Save cmdline ptr
BG1:	LD	A,(HL)		;Look for parms
	CP	CR		;EOL?
	JR	Z,CKNAME
	CP	'('		;Parm start
	JR	Z,DOPARM
	INC	HL
	JR	BG1
DOPARM:	LD	DE,PRMTBL	;Parameters
	@@PARAM
	JR	NZ,IOERR	;Quit on error
	LD	A,(PRESP)	;See if printer used
	OR	A
	JR	NZ,CKWDTH	;Go if it was
	LD	A,80		;Screen, use 80 chars
	LD	(WPARM),A
	JR	CKNAME
CKWDTH:	BIT	6,A		;Was a flag resp?
	LD	A,PRMERR
	JP	Z,IOERR		;Quit if not
	LD	HL,HBUF2	;Get the time
	@@TIME
	LD	HL,HBUF3	; and date
	@@DATE
	XOR	A		;NOP out return
	LD	(CKPAGE),A
	LD	BC,80		;Get width
WPARM	EQU	$-2
	LD	A,B
	OR	A		;Width > 255?
BADW:	LD	A,44		;Init parameter error
	JP	NZ,IOERR	;Parm error
	LD	A,C		;Get width
	LD	B,C		;Save width in B
	CP	32		;Least width we allow
	JR	C,BADW
	SUB	22		;Sub off name field
	LD	E,A
	LD	C,7
	@@DIV8			;Divide it
	LD	A,E		;Remainder to A
	LD	C,6		;Adjustment
	OR	A		;Zero
	JR	Z,ADJW		;Go and adust
	DEC	C
	DEC	A
	JR	Z,ADJW
	DEC	A		;This is good
	JR	Z,CKNAME
	LD	C,A		;This is adjustment
ADJW:	LD	A,B		;Get orig width
	SUB	C
	LD	(WPARM),A
CKNAME:	POP	HL		;Get back cmd line
	LD	DE,FCB
	LD	B,0		;Char counter
	PUSH	DE		;Save fcb start
BG2:	LD	A,(HL)		;Get a char
	CP	' '+1		;Line end?
	JR	C,GOTNAM
	CP	'('		;Parm start?
	JR	Z,GOTNAM
	LD	(DE),A		;Else got a char, save
	INC	DE
	INC	B
	INC	HL
	JR	BG2
GOTNAM:	LD	A,CR
	LD	(DE),A		;Term. file name
	INC	B
	DEC	B		;Be sure some name found
	JP	Z,NAMREQ	;Quit if not
	POP	DE		;Pt to FCB
	LD	H,D
	LD	L,E
	@@FSPEC
	PUSH	DE
	LD	HL,HBUF1
FSP0:	LD	A,(DE)
	CP	CR+1		;Move filename for header
	JR	C,FSP1
	LD	(HL),A
	INC	HL
	INC	DE
	JR	FSP0
FSP1:	POP	DE		;Recover FCB
	LD	HL,$-$		;No file open bit
SFLAG	EQU	$-2
	SET	0,(HL)
	LD	HL,BUFF$
	LD	B,0
	@@OPEN
	JP	NZ,IOERR
;
	LD	A,(TOPMEM+1)	;Get highest page
	LD	B,A
	LD	HL,FCB+4	;Buffer ptr
RDLP:	@@READ
	JR	NZ,RD1		;Go if some error
	INC	(HL)		;Bump read buffer
	LD	A,(HL)
	CP	B		;Top of mem?
	JR	NZ,RDLP
	JP	NOMEM		;Quit if no more mem
RD1:	CP	1CH		;EOF error
	JR	Z,RD2		;Ok if so
	CP	1DH
	JP	NZ,IOERR	;Quit on read error
RD2:	LD	A,(BUFF$)	;Ck first char
	INC	A
	JP	NZ,NOTBAS	;Quit if not basic pgm
	LD	A,(HL)		;Get last page used
	LD	(MEMCK),A	;In case not bas pgm
;
;	Program is loaded intact. Now, strip all but
;	variable and line numbers.
;
	LD	DE,BASE-1	;Where to put good stuff
	LD	HL,BUFF$	;First pgm byte
MAINLP:	INC	HL		;Next mem ptr
	LD	A,(HL)
	INC	HL
	OR	(HL)		;Ck for end
	JP	Z,GOTEND
	INC	HL
	LD	A,$-$		;Top loaded page
MEMCK	EQU	$-1
	CP	H
	JP	C,NOTBAS	;Go if past end
	INC	DE		;Posn for line #
	LD	A,(HL)
	LD	(DE),A
	INC	HL
	INC	DE
	LD	A,(HL)
	LD	(DE),A
	INC	HL
	INC	DE
	XOR	A		;Mark nothing in line
	LD	(DE),A
LINLP:	LD	A,(HL)		;Get char fm line
	OR	A
	JR	Z,MAINLP	;Go on line end
	CP	REM		;Ck for remark
	JR	Z,BYREM		;Bypass if so
	CP	DATA		;Data statement?
	JR	Z,BYDATA
	CP	'"'		;Ck for string
	JR	Z,BYSTR
	CP	0EH		;Line number?
	JR	Z,DOLINE	;Store it if so
	CP	'A'		;See if variable
	JR	C,LIN1		;Nope, ck more
	CP	'Z'+1
	JR	C,DOVAR		;Go if variable start
LIN1:	CP	11H		;Now ck one byte numbers
	JR	C,LIN2
	CP	1BH
	JR	NC,LIN2		;Not a 1 byter
	INC	HL		;Is one byter, bypass
	JR	LINLP
LIN2:	CP	0FH		;Other 1 byte type
	JR	NZ,LIN3
	INC	HL
	INC	HL		;Bypass 0F and byte
	JR	LINLP
LIN3:	CP	0BH		;2 byte type
	JR	Z,BYTWO
	CP	0CH
	JR	Z,BYTWO
	CP	1CH
	JR	Z,BYTWO
	CP	1DH		;Single prec.
	JR	NZ,LIN4		;Go if not
	INC	HL		;Bypass type byte
	INC	HL
BYTWO:	INC	HL
	INC	HL
	INC	HL
	JR	LINLP
LIN4:	CP	1FH		;double prec.?
	JR	NZ,LIN5		;Nope
	LD	A,9		;8 + type
	ADD	A,L
	LD	L,A
	JR	LINLP
LIN5:	CP	0FFH		;Two byte token?
	JR	NZ,LIN6
	INC	HL		;Bypass it and
LIN6:	INC	HL		; the 2nd half
	JR	LINLP
;
BYREM:	LD	C,0FFH		;Can't be found in rem
	JR	BYPASS
BYSTR:	LD	C,'"'		;End of string
BYPASS:	INC	HL		;Nxt char
	LD	A,(HL)		;Get a char
	OR	A		;Line end?
	JR	Z,MAINLP	;Go if so
	CP	C		;Term char?
	JR	NZ,BYPASS	;Nope, do another
	INC	HL		;Else bypass it
	JP	LINLP		; and back to cking
;
;	Bypass data to a colon or line end
;
BYDATA:	LD	C,':'		;This is end char
BYP1:	INC	HL		;Get next char
	LD	A,(HL)
	OR	A		;End?
	JP	Z,MAINLP
	CP	C		;End of data statement?
	JR	NZ,BYP2		;More if not
	INC	HL
	JP	LINLP
BYP2:	CP	'"'		;Start of string data?
	JR	NZ,BYP1		;No, do another
BYP3:	INC	HL
	LD	A,(HL)		;Find end quote
	OR	A
	JP	Z,MAINLP	;Go if line end
	CP	'"'
	JR	NZ,BYP3
	JR	BYP1
;
;	Extract a line # reference
;
DOLINE:	INC	HL		;Pt to #
	LD	(DE),A		;Show is #
	INC	DE
	LD	B,2
DOL1:	LD	A,(HL)		;LSB
	LD	(DE),A
	INC	HL
	INC	DE
	DJNZ	DOL1		;Do two bytes
	XOR	A
	LD	(DE),A
	JP	LINLP		;Do some more
;
;	Extract a variable and save it
;
DOVAR:
	LD	A,1		;Var. marker
	LD	(DE),A
	INC	DE
DOV1:	LD	A,(HL)		;Get var. char
	CALL	VALID		;Get a char
	JR	NZ,DOVEND	;Go on non-var char
	LD	(DE),A		;Save char
	INC	DE
	INC	HL
	CP	'('		;This will also end variable
	JR	Z,DOVEND
	JR	DOV1
DOVEND:	XOR	A		;Mark var. end
	LD	(DE),A
	JP	LINLP		;Back to it
;
;	Check for valid variable chars - NZ on end
;
VALID:	CP	'.'		;Valid char
	RET	Z
	CP	'A'
	JR	C,VAL1		;Not a letter
	CP	'Z'+1
	JR	C,VALZ		;Yes - back
VAL1:	CP	'0'
	JR	C,SPCL		;Not digit, ck more
	CP	'9'+1
	JR	C,VALZ		;Yes, a number
SPCL:	CALL	CKSPCL		;Ck for special
	RET			;Return result
VALZ:	CP	A		;Set Z
	RET
;
CKSPCL:	CP	'!'
	RET	Z
	CP	'#'
	RET	Z
	CP	'$'
	RET	Z
	CP	'%'
	RET	Z
	CP	'('
	RET
;
;	Reached end of compresion stage
;
GOTEND:	INC	DE		;Put in double FF
	LD	A,0FFH
	LD	(DE),A
	INC	DE
	LD	(DE),A
;
	LD	IX,CCOUNT	;Pt to chars this line
	LD	BC,0		;Printer on or off
PPARM	EQU	$-2
	LD	A,B
	OR	C
	LD	A,PRT@		;In case is on
	JR	Z,NOPRT
	LD	(DEVTYP),A	;Switch on printer
	CALL	PRTHDR		;Print the header
;
;	Now ck and see what to print
;	Variables first, then numbers
;
NOPRT:	LD	BC,-1		;Variable parm, defualt on
VPARM	EQU	$-2
	LD	A,B
	OR	C
	CALL	NZ,SHOWV	;Go if var. turned on
;
	LD	HL,0FFFFH
	LD	(LAST),HL	;Set up for numbers
	LD	A,H		;Zero chars this line
	LD	(IX),A
	LD	A,(PRESP)	;See if printing
	OR	A
	JR	Z,DON		;Go if not
	LD	C,CR		; else print a blank line
	CALL	DSP
;
DON:	LD	BC,0		;Init line refs off
LPARM	EQU	$-2
	LD	A,B
	OR	C		;See if parm was on
	LD	C,0EH		;Number id key
	CALL	NZ,SHOWN	;Show numbers if on
;
	LD	A,(PRESP)	;Printing?
	OR	A
	JR	Z,END1		;Go if not
	LD	C,TOF
	CALL	DEVOUT
END1:	JP	EXIT
;
;	Find and display variables
;	to the output device.
;
SHOWV:	LD	HL,BASE-1	;Compressed data
	LD	DE,START$	;Init to largest
SVLP:	INC	HL		;Pt to line #
	LD	A,(HL)		;See if end
	LD	C,A		; and save line #
	INC	HL
	LD	B,(HL)		;MSB line #
	LD	(CURLIN),BC	; Save line #
	INC	BC		;Check for FFFF
	LD	A,C
	OR	B		;See if at end of pgm
	JP	Z,PASEND	;Have lowest, cause at end
	PUSH	HL
	CALL	CKPAWS		;Pause or break
	LD	HL,0FFFFH
	LD	(LASTNUM),HL	;Show new line
	LD	A,0
	LD	(NOTFST),A	;New first number dsp
	POP	HL
	INC	HL		;1st char of line
SVLP1:	LD	A,(HL)		;Get type byte
	OR	A		;End of line?
	JR	Z,SVLP		;Go if so
	CP	1		;Got a match?
	JR	Z,CKVLOW	;See if it new low
	CP	0EH		;Number?
	JR	NZ,SVL1		;Go if not
	INC	HL		;Past type byte
	INC	HL		;Now past number
	INC	HL
	JR	SVLP1
SVL1:	CP	2		;Used up char?
	JP	NZ,MEMERR	;It has to be a 2
	INC	HL
	JR	SVLP1		;Skip it
;
;	See if this variable is lower than stored one
;
CKVLOW:	INC	HL		;Pt to variable
	PUSH	HL		;This is start of variable
	LD	(OLDDE),DE	;Save current low
CKVLP:	LD	A,(DE)		;Get old char
	CP	20H		;End of it?
	JR	C,VOLD		;Use old if so
	CP	(HL)		;Ck against new char
	JR	Z,CVL1		;Go if equal
	JR	NC,VNEW		;Use the new one
	JR	C,VOLD		;Use the old one
CVL1:	INC	DE
	INC	HL
;	LD	A,(HL)		;End of new?
;	CP	20H
;	JR	NC,CKVLP	;Go if not
	JR	CKVLP
	JR	VNEW		;Use old if so
VOLD:	POP	AF		;Get stack clean
	LD	DE,$-$		;Restore DE
OLDDE	EQU	$-2
	JR	VRET
VNEW:	LD	DE,(CURLIN)	;Get its line #
	LD	(LINE1),DE	;Save for dsply
	POP	DE		;Pt to new lowest
VRET:	LD	A,(HL)		;End of new variable?
	CP	20H
	JP	C,SVLP1		;Back on end
	INC	HL
	JR	VRET		;Loop all chars
;
;	End of pgm pass - see if any found
;
PASEND:	LD	HL,(LAST)	;Get last found
	LD	(LAST),DE	;This is now last
	OR	A
	SBC	HL,DE		;If a match, end of dsiplay
	RET	Z
	LD	A,(DE)		;Be sure one found!
	CP	0FFH
	RET	Z		;No variables if an FF
	LD	HL,$-$		;Get 1st ref line
LINE1	EQU	$-2
	LD	(CURLIN),HL
	LD	H,D		;Pt HL at refed var.
	LD	L,E
	CALL	OUTNAME		;Display the variable
	CALL	OUTNUM		; and show its 1st num.
	JR	VOUT1		;Now find all
VOUTLP:	INC	HL
	LD	A,(HL)
	LD	C,A
	INC	HL
	LD	B,(HL)
	LD	(CURLIN),BC
	INC	BC		;Check for FFFF
	LD	A,C
	OR	B
	JR	NZ,VOUT2	;More if not end
	LD	C,CR
	CALL	DSP
	LD	H,D		;Pt to variable
	LD	L,E
	DEC	HL		;Pt to type byte
VOUT4:	LD	(HL),2		;Blank it
	INC	HL
	LD	A,(HL)
	CP	20H
	JR	NC,VOUT4
	JP	SHOWV		;Do another pass
VOUT2:	INC	HL
VOUT1:	LD	A,(HL)		;Get a char
	OR	A
	JR	Z,VOUTLP
	CP	2		;Used up char?
	JR	Z,VOUT2		;Skip it if so
	CP	0EH		;Number reference?
	JR	NZ,VOUT3	;Go if not
	INC	HL
	INC	HL
	JR	VOUT2
VOUT3:	CP	1		;Must be varlable!
	JP	NZ,MEMERR	;If not, pgm was saved w/errors
	CALL	MATCH		;See if this is a match
	JR	VOUT1
;
;	Match	HL to DE for B chars
;
MATCH:	PUSH	DE		;Save start of cmp var.
	LD	B,$-$		;Len this var.
VARLEN	EQU	$-1
	PUSH	BC
	LD	(BLNKST),HL	;In case is a match
	INC	HL		;Pt a varlable
MATLP:	LD	A,(DE)
	CP	(HL)		;Cp to new
	JR	NZ,NOMAT
	LD	A,(HL)
	CP	20H
	JR	C,NOMAT
	INC	DE
	INC	HL
	DJNZ	MATLP
	LD	A,(HL)		;Now must be end
	CP	20H
	JR	NC,NOMAT	;Nope, sorry
	LD	HL,$-$		;Where variable starts
BLNKST	EQU	$-2
	POP	BC
	PUSH	BC
	INC	B		;Include type byte
BLNKV:	LD	(HL),2		;Make no good
	INC	HL
	DJNZ	BLNKV
	XOR	A		;Set Z
NOMAT:	POP	BC
	POP	DE
	PUSH	AF		;Save flags
NOMAT1:	LD	A,(HL)		;Be sure HL past var.
	CP	20H
	JR	C,NOMAT2
	INC	HL
	JR	NOMAT1
NOMAT2:	POP	AF		;Recover flag
	RET	NZ
	CALL	OUTNUM		;Else show number
	RET
;
;
;	Display variable and return len in B
;
OUTNAME:
	LD	B,0		;Set counter
OUTN1:	LD	A,(HL)		;Get a char
	CP	20H		;End?
	JR	C,OUTN2
	LD	C,A		;Move letter for dsp
	INC	B		;Show good char
	LD	A,B		;Get count
	CP	15		;14 max
	JR	NC,OUTN1A	;Go if over
	CALL	DSP
OUTN1A:	INC	HL
	JR	OUTN1
OUTN2:	PUSH	HL
	PUSH	DE
	LD	A,B
	LD	(VARLEN),A
	LD	A,13		;Max -1
	SUB	B		;See if short var.
	JR	C,OUTN3		;Go if long
	INC	A		;Always one space
	CALL	SPACES
OUTN3:	LD	A,3
	CALL	SPACES
	POP	DE
	POP	HL
	RET
;
;	Display or print a char
;
DSP:	PUSH	DE
	CALL	DEVOUT		;Put char somewhere
	LD	A,C		;Get char sent
	CP	CR		;Was it a CR?
	JR	NZ,DSP1		;Go if not
	LD	A,1		;If it was, reset cc
	LD	(IX),A
	CALL	CKPAGE		;See if time now
	POP	DE
	RET
DSP1:	LD	A,(WPARM)	;Get the width
	LD	E,A
	LD	A,(IX)		;Get char printed
	INC	A		;Make one more
	CP	E		;Room for more?
	JR	Z,NEWLIN	;No - do a new line
	LD	(IX),A		;Save new count
	JR	DSPRET
NEWLIN:	LD	C,CR		;End the line
	CALL	DEVOUT
	CALL	CKPAGE		;See if time to page
	LD	C,'*'
	CALL	DEVOUT
	PUSH	BC
	LD	A,INDENT
	LD	B,A
	INC	A
	LD	(IX),A
	DEC	B
NEWLLP:	LD	C,' '
	CALL	DEVOUT
	DJNZ	NEWLLP
	POP	BC
DSPRET:	POP	DE
	RET
;	Either printer or screen
;
DEVOUT:	LD	A,DSP@
DEVTYP	EQU	$-1
	RST	40
	RET	Z
	JP	IOERR
;
SPACES:	PUSH	BC
	LD	B,A		;Get count
SPC1:	LD	C,' '
	CALL	DSP
	DJNZ	SPC1
	POP	BC
	RET
;
;	See if time to page
;
CKPAGE:	RET
	LD	A,(LCOUNT)
	INC	A
PG0:	LD	(LCOUNT),A
	CP	56		;Page if it is this
	RET	NZ		;Back if not
	PUSH	DE
	PUSH	HL
	PUSH	BC
	LD	B,10
PG1:	LD	C,CR
	CALL	DEVOUT
	DJNZ	PG1
	CALL	PRTHDR
	POP	BC
	POP	HL
	POP	DE
	RET
;
;
;	Print a header with line #
;
PRTHDR:	LD	HL,(PAGE)	;Get last page #
	INC	HL
	LD	(PAGE),HL
	LD	DE,HBUF4
	@@HEXDEC		;Put in header
	LD	HL,HBUF1
	@@PRINT
	JP	NZ,IOERR
	LD	A,2
	LD	(LCOUNT),A	;Show two gone already
	RET
;
;
;
;	Display a number
;
OUTNUM:	PUSH	HL
	PUSH	DE
	LD	DE,(CURLIN)
	LD	HL,(LASTNUM)	;Last one out
	LD	(LASTNUM),DE
	OR	A
	SBC	HL,DE		;See if same
	JR	Z,OUTNRET	;Go if dupe
	LD	HL,NUMBUF+2
	PUSH	HL
	EX	DE,HL
	@@HEXDEC
	POP	HL
	LD	A,0
NOTFST	EQU	$-1
	OR	A
	LD	A,1
	LD	(NOTFST),A	;Different on time 1
	JR	Z,OUTNU1	;Go if 1st time
	DEC	HL		;Back up to comma
	DEC	HL
OUTNU1:	LD	A,(HL)		;Get a char
	INC	HL
	LD	C,A
	CP	CR+1
	JR	C,OUTNRET	;Go if so
	CALL	DSP
	JR	OUTNU1
OUTNRET:	POP	DE
	POP	HL
	RET
;
CKPAWS:	LD	HL,$-$
KFLAG	EQU	$-2
	LD	A,(HL)
	BIT	0,A		;Break hit?
	JP	NZ,ABORT1	;Quit if so, ck prt on
	BIT	1,A		;Pause req?
	RET	Z		;Back if not
	PUSH	DE
	PUSH	BC
FLS:	@@KBD			;Wait til no key
	JR	Z,FLS
FLS1:	@@KEY			;Wait for a key
	CP	80H
	JP	Z,ABORT1	;Quit on break
	CP	60H		;Pause key?
	JR	Z,FLS1		;Yes, wait until not
	LD	A,(HL)		;Get KFLAG value
	AND	0F8H		;Remove keydown bits
	LD	(HL),A
	LD	B,11
	@@PAUSE			;Wait til off key
	LD	A,(HL)		;Get flag again
	POP	BC
	POP	DE
	AND	3		;Break or pause?
	JR	NZ,FLS		;Yes, get which and flush
	RET			; else cleared, back
;
;	Display line number refs to output device
;
SHOWN:	LD	HL,BASE-1	;Compressed data
	LD	DE,(START$)	;Highest number
SNLP:	INC	HL		;P/u line #
	LD	A,(HL)
	LD	C,A
	INC	HL
	LD	B,(HL)		; into BC
	LD	(CURLIN),BC	;Save line #
	INC	BC		;Check for FFFF
	LD	A,C
	OR	B		;See if pgm end
	JP	Z,NUMEND	;Go if it is
	PUSH	HL
	LD	HL,0
	LD	(LASTNUM),HL	;Show in new line
	LD	A,H
	LD	(NOTFST),A	;Set is 1st time
	CALL	CKPAWS
	POP	HL
SNLP3:	INC	HL
SNLP1:	LD	A,(HL)
	OR	A		;See if line end
	JR	Z,SNLP		;Do another if so
	CP	0EH		;Is is a line #
	JR	Z,CKNUM		;Go if it is
	CP	1		;Is it a variable
	JR	NZ,SN1		;Go if it's not
SNLP2:	INC	HL
	LD	A,(HL)
	CALL	VALID
	JR	Z,SNLP2		;Strip all var. chars
	JR	SNLP1		;End of variable
SN1:	CP	2		;Use up something?
	JP	NZ,MEMERR	;It must be!
	JR	SNLP3
;
;	See if this number is lowest
;
CKNUM:	INC	HL		;Pt to the number
	LD	A,(HL)		;Get lsb
	INC	HL
	PUSH	HL		;Save locn
	LD	H,(HL)		;Get msb
	LD	L,A		;Num now in HL
	PUSH	HL		;Save number
	OR	A
	SBC	HL,DE		;See if new is less
	JR	NC,NOLD		;Same, keep old
	POP	DE		;Make new lowest
	JR	CKN1
NOLD:	POP	AF		;Keep DE, dump HL
CKN1:	POP	HL		;Buffer posn
	JR	SNLP3
;
;	End of a pass, display new number ref
;
NUMEND:	LD	HL,(LAST)	;Get last number shown
	LD	(LAST),DE	;Make current last
	OR	A
	SBC	HL,DE		;If last=current,
	RET	Z		; we are done
	LD	A,D		;Be sure one found
	AND	E
	CP	0FFH
	RET	Z		;Back if none
	LD	HL,LINBUF	;Now display number
	PUSH	DE		;Save number
	PUSH	HL		;Save dsp buffer
	EX	DE,HL
	@@HEXDEC		;Make decimal
	POP	HL
	CALL	OUTNAME		;Show refed number
	POP	DE		;Restore #
	LD	HL,BASE-1	;Pt to start
NOUTLP:	INC	HL
	LD	A,(HL)		;Get line #
	LD	C,A
	INC	HL
	LD	B,(HL)		;Into BC
	LD	(CURLIN),BC
	INC	BC		;Check for FFFF
	LD	A,C
	OR 	B
	JR	NZ,NOUT2	;Go if not end
	LD	C,CR
	CALL	DSP
	JP	SHOWN
NOUT2:	INC	HL
NOUT1:	LD	A,(HL)		;Get a char
	OR	A
	JR	Z,NOUTLP	;Go on line end
	CP	0EH		;Number?
	JR	Z,NMAT		;Check match if so
	CP	1		;Variable?
	JR	NZ,NOUT4
NOUT3:	INC	HL		;Bypass variable
	LD	A,(HL)		;Get char
	CALL	VALID
	JR	Z,NOUT3
	JR	NOUT1
NOUT4:	CP	2		;Use up char?
	JR	Z,NOUT2		;Skip if so
	JP	MEMERR		;Else garbage!
NMAT:	LD	(BKNUM),HL	;Save blanking start
	INC	HL		;Pt to #
	LD	C,(HL)		;Get number
	INC	HL
	LD	B,(HL)		;Into bc
	PUSH	HL		;Save num end
	LD	H,B		;Xfer to HL
	LD	L,C
	OR	A
	SBC	HL,DE		;See if a match
	JR	NZ,NMAT1	;Go if not
	CALL	OUTNUM		;Show matching line #
	LD	HL,$-$		;Blank it out
BKNUM	EQU	$-2
	LD	B,3
BKNUM1:	LD	(HL),2		; by putting in 2's
	INC	HL
	DJNZ	BKNUM1
NMAT1:	POP	HL
	JP	NOUT2		;Back to loop
;
;	Garbage found, must be error in orig program
;
MEMERR:	LD	DE,ERRBUF1	;Install error line #
	LD	HL,(CURLIN)	;Get line we're on
	@@HEXDEC		;Make ascii
	LD	HL,ERRBUF$
	@@DSPLY
	JP	MERR		;Abort
;
ERRBUF$	DB	LF,'Line '
ERRBUF1	DB	'     , ',3
;
HBUF1	DC	24,' '
	DB	'- '
	DB	'Cross Reference - '
HBUF3	DC	10,' '
HBUF2	DC	10,' '
	DC	4,' '
	DB	'Page '
HBUF4	DB	'    1'
	DB	LF,CR
	DC	100,0
	ORG	$<-8+1<+8
;
BASE	DS	512
BUFF$	EQU	$
;
	END	BEGIN
