;
;  SYMBOLS.ASM
;
;  SYMBOL TABLE FORMAT:
;
; BYTE 0: FLAGS AND BITS 8 AND 0 OF VALUE
;         BIT 7 -- ALWAYS 1
;         BIT 6 -- UNDEFINED
;         BIT 5 -- GLOBAL
;         BIT 4 -- VALUE BIT 8
;         BIT 3 -- VALUE BIT 0
;	  BIT 2 -- FORWARD REFERENCE FLAG
;         BITS 1-0 -- ORIGIN NUMBER
;
; BYTE 1: BITS 7-1 OF VALUE
;
; BYTE 2: BITS 15-9 OF VALUE
;
;  PRINT THE SYMBOL TABLE
;
PRTABE	RTS
;
PRSTAB	LDA	#LOW[SYMTAB]
	STA	TABPTR
	LDA	#HIGH[SYMTAB]
	STA	TABPTR+1
PRTALN	JSR	CLEAR
	LDA	#0
PRTABL	STA	TXTPTR
	LDA	TABPTR+1
	LDX	TABPTR
	CPX	ENDSTAB
	SBC	ENDSTAB+1
	BCS	PRTABE
	JSR	GETVAL
	LDX	TXTPTR
	LDA	SVAL+1
	JSR	PRHEX
	LDA	SVAL
	JSR	PRHEX
	INX
	BIT	SFLGS
	BPL	SYMDFD
	LDA	#'U'
	STA	PRBUF,X
SYMDFD	INX
	LDA	#'L'
	BVC	SYMLCL
	LDA	#'E'
SYMLCL	STA	PRBUF,X
	LDA	#' '
	LDY	#2
SYMNLP	INX
	INY
	STA	PRBUF,X
	LDA	(TABPTR),Y
	BPL	SYMNLP
	STX	TXTPTR
	CLC
	TYA
	ADC	TABPTR
	STA	TABPTR
	LDA	#0
	ADC	TABPTR+1
	STA	TABPTR+1
	LDA	#0
NXTCOL	CLC
	ADC	#CWIDTH
	CMP	TXTPTR
	BCC	NXTCOL
	CMP	#PRTLEN-CWIDTH
	BCC	PRTABL
	LDA	#EOL
	STA	PRBUF+1,X
	JSR	LIST
	JMP	PRTALN
;
;  ADD A SYMBOL AND VALUE TO THE SYMBOL TABLE
;
ADDSYM	LDA	LABEL
	BEQ	NOSYM
	LDX	VALUE
	LDY	VALUE+1
	LDA	ISVAL
	BNE	USEVAL
	LDX	PC
	LDY	PC+1
USEVAL	STX	SVAL
	STY	SVAL+1
;
	LDX	#2
FESYM	INX
	LDA	LABEL-3,X
	STA	SYMBOL-3,X
	BNE	FESYM
	STX	SLEN
	JSR	FIND
	BCC	OLDSYM
	LDA	ENDSTAB+1
	STA	TEMP+1
	LDY	ENDSTAB		;POINT TO END OF SYMBOL TABLE
CPFS1	STY	TEMP
	LDY	#0
	LDA	(TEMP),Y	;AND MAKE ROOM FOR
	LDY	SLEN		;NEW ENTRY OF SLEN BYTES
	STA	(TEMP),Y
	LDY	TEMP
	BNE	DECFS1
	DEC	TEMP+1
DECFS1	DEY
FSNDCK	LDA	TEMP+1		;START OF NEW SYMBOL?
	CPY	TABPTR
	SBC	TABPTR+1
	BCS	CPFS1		;NO, MOVE ANOTHER BYTE
;
	LDA	SLEN
	TAY
	ADC	ENDSTAB		;POINT TO END OF
	STA	ENDSTAB		;LONGER SYMBOL TABLE
	LDA	#0
	ADC	ENDSTAB+1
	STA	ENDSTAB+1
NEWTXT	DEY
	LDA	SYMBOL-3,Y
	STA	(TABPTR),Y
	CPY	#3
	BNE	NEWTXT
;
;  SAVE VALUE AND FLAGS IN SYMBOL TABLE ENTRY
;
PUTVAL	LDA	SVAL+1
	LSR	A
	PHP
	LDY	#2
	STA	(TABPTR),Y
	LDA	SVAL
	LSR	A
	DEY
	STA	(TABPTR),Y
	DEY
	TYA
	ROR	A
	PLP
	ROR	A
	LSR	A
	LSR	A
	ORA	SFLGS
	SEC
	ROR	A
	STA	(TABPTR),Y
NOSYM	RTS
;
;  CLEAR THE FORWARD REFERENCE FLAG
;
OLDSYM	LDY	#0
	LDA	(TABPTR),Y
	AND	#$FB		;CLEAR BIT 2 (FORWARD REF. FLAG)
	CMP	(TABPTR),Y
	BEQ	DUPSYM
	STA	(TABPTR),Y
	RTS
;
DUPSYM	LDA	#'D'		;ERROR ON SECOND DEFINITION
	STA	ADRERR
	RTS
;
;  RECOVER VALUE AND FLAGS FROM SYMBOL TABLE ENTRY
;
GETVAL	LDY	#0
	LDA	(TABPTR),Y	;GET FLAGS
	ASL	A
	PHA
	AND	#$CE		;EXTRACT FLAGS
	STA	SFLGS		;AND SAVE THEM
	PLA
	ASL	A
	ASL	A
	ASL	A		;SAVE BIT 8 IN CY
	PHP
	ASL	A		;PUT BIT 0 INTO CY
	INY
	LDA	(TABPTR),Y
	ROL	A		;MERGE BITS 0 AND 1-7
	STA	SVAL
	PLP
	INY
	LDA	(TABPTR),Y
	ROL	A		;MERGE BITS 8 AND 9-15
	STA	SVAL+1
SYMFND	RTS
;
;  FIND LOCATION FOR A SYMBOL IN THE TABLE
;
FIND	LDX	ENDSTAB
	STX	HIGHP
	LDA	ENDSTAB+1
	STA	HIGHP+1
	LDX	#LOW[SYMTAB]
	STX	LOWP
	LDA	#HIGH[SYMTAB]
	STA	LOWP+1
	STA	TABPTR+1
	STX	TABPTR
;
	CPX	HIGHP
	SBC	HIGHP+1
	BCS	SNFND
;
HALVE	SEC
	LDA	HIGHP
	ADC	LOWP
	STA	TABPTR
	LDA	HIGHP+1
	ADC	LOWP+1
	ROR	A
	ROR	TABPTR
	STA	TABPTR+1
	LDY	#0
	LDA	(TABPTR),Y
	BMI	GSTRT		;FOUND START OF A SYMBOL
NOT1ST	LDA	TABPTR
	BNE	FBKUP
	DEC	TABPTR+1
FBKUP	DEC	TABPTR
	LDA	(TABPTR),Y
	BPL	NOT1ST
;
GSTRT	LDY	#3
FCHRLP	LDA	(TABPTR),Y
	BMI	MTCHOK
	CMP	SYMBOL-3,Y		;MATCH?
	BCC	FADVC1		;TABLE ENT. < SYMBOL
	BNE	FBKUP1		;TABLE ENT. > SYMBOL
	INY
	BCS	FCHRLP
;
MTCHOK	CLC
	LDA	SYMBOL-3,Y
	BEQ	SYMFND		;SYMBOL FOUND (CY=0)
	BNE	FADVC2
;
FADVC1	INY
FADVC2	LDA	(TABPTR),Y
	BPL	FADVC1
	CLC
	TYA
	ADC	TABPTR
	LDY	TABPTR+1
	BCC	FADVNI
	INY
FADVNI	CPY	HIGHP+1
	BCC	FADVC3
	CMP	HIGHP
	BCC	FADVC3
	STA	TABPTR		;SYMBOL NOT FOUND (CY=1)
	STY	TABPTR+1
SNFND	RTS
;
FADVC3	STY	LOWP+1
	STA	LOWP
	BCC	HALVE
;
FBKUP1	LDA	LOWP
	CMP	TABPTR
	LDA	LOWP+1
	SBC	TABPTR+1
	BCS	SNFND		;SYMBOL NOT FOUND (CY=1)
	LDA	TABPTR
	STA	HIGHP
	LDA	TABPTR+1
	STA	HIGHP+1
	BCC	HALVE
