NEW
  AUTO 3,1
*---------------------------------------
* Global Symbol Record: (6+ bytes)
*  0 : Len
*  1 : Flags:
*		b7=0=pending,1=resolved
*		b6=R/W (.SE)
*		b2,b1,b0 : Size (in bytes)
*  2-5 : 32 bits Value
*  6+  : Local Symbols.....
*---------------------------------------
* Local/Private Symbol Record: (6 bytes)
*  0 : Local ID (1->255)
*  1 : Macro Context ID (private)
*  2-5 : 32 bits Value (PC)
*---------------------------------------
SYM.Init		>SYSCALL SListNew
				bcs .9

				>STA.G SYM.hList
				>LDYAI 256
				>SYSCALL GetMem
				bcs .9
				>STYA ZPSymbolBuf
				txa
				>STA.G SYM.hBuf
.9				rts
*---------------------------------------
SYM.Quit		>LDA.G SYM.hBuf
				beq .1

				>SYSCALL FreeMem

.1				>LDA.G SYM.hList
				beq .8

				>SYSCALL SListFree

.8				rts
*---------------------------------------
SYM.NewGlobal	>LDA.G ASM.PASS
				bne SYM.GetGlobal

				jsr SYM.StoreGlobal		Store previous if any
				bcs .99

				>STZ.G MAC.CtxID
				>STA.G MAC.CtxNextID

				>PUSHB.G SYM.hList
				>PUSHW ZPLinePtr		Pass #1: try to add global...
				>SYSCALL SListNewKey
				bcs .9					Already Defined

				>STYA.G SYM.ID

				txa
*				clc
				adc ZPLinePtr
				sta ZPLinePtr
				bcc .1
				inc ZPLinePtr+1

.1				stz SRC.ACC.F
				jsr SYM.PC2Acc
				jsr SYM.Acc2Global

				lda #SYMG
				>STA.G SYM.BufPtr
				tay
				lda #0
				sta (ZPSymbolBuf),y

				.DO ASMDBG=1
				lda #'1'
				>SYSCALL putchar
				jsr SYM.Dump.G
				jsr OUT.PrintCR
				.FIN
				clc
				rts

.9				cmp #E.DUPKEY
				bne .99
				lda #E.SYMBOL.REDEF
.99
SYM.NewGlobal.RTS
				rts
*---------------------------------------
SYM.GetGlobal	>PUSHB.G SYM.hList		Pass #2: should be already defined...
				>PUSHW ZPLinePtr
				>SYSCALL SListLookup
				bcs SYM.NewGlobal.RTS

				>STYA.G SYM.ID

				txa
*				clc
				adc ZPLinePtr
				sta ZPLinePtr
				bcc .1
				inc ZPLinePtr+1

.1				>PUSHB.G SYM.hList		Pass #2: Restore full context
				>PUSHW.G SYM.ID
				>PUSHW ZPSymbolBuf
				>PUSHWI $ffff			all
				>PUSHWZ					from Start
				>SYSCALL SListGetData
				bcs .99

				lda (ZPSymbolBuf)
				and #SYMG.F.EQU
				bne .8

				>LDA.G ASM.PC
				ldy #SYMG.V
				cmp (ZPSymbolBuf),y
				bne .7

				>LDA.G ASM.PC+1
				ldy #SYMG.V+1
				cmp (ZPSymbolBuf),y
				beq .8

.7				lda #E.OUT.OF.SYNC
				sec
				rts

.8				.DO ASMDBG=1
				lda #'2'
				>SYSCALL putchar
				jsr SYM.Dump.G
				jsr OUT.PrintCR
				.FIN

				lda #SYMG
				>STA.G SYM.BufPtr

				>STZ.G MAC.CtxID
				>STA.G MAC.CtxNextID

				clc
				rts

.9				lda #E.UNDEF.SYMBOL
				sec
.99				rts
*---------------------------------------
SYM.LookupGlobal
				>PUSHB.G SYM.hList
				>PUSHW ZPLinePtr
				>SYSCALL SListLookup
				bcs .4

				>STYA ZPPtr1			KeyID

				txa
*				clc
				adc ZPLinePtr
				sta ZPLinePtr
				bcc .1
				inc ZPLinePtr+1

.1				>LDA.G SYM.ID
				cmp ZPPtr1
				bne .3

				iny
				lda (pData),y
				cmp ZPPtr1+1
				bne .3

				ldy #SYMG-1

.2				lda (ZPSymbolBuf),y
				sta SRC.ACC.F,y
				dey
				bne .2					Keep ACC.F unchanged

				clc
.99				rts

.3				>PUSHB.G SYM.hList
				>PUSHW ZPPtr1			KeyID
				>PUSHW L.SRC.ACC.SIZE
				>PUSHWI SYMG-1			Get only Global value
				>PUSHWI	1				Skip SYMG.F
				>SYSCALL SListGetData
				rts

.4				>LDA.G ASM.PASS			pass#2?
				bne .9					yes, undefined symbol

				lda #SYMG.F.FWREF
				tsb SRC.ACC.F

				lda #2
				sta SRC.ACC.SIZE
				
				lda #$ff
				sta SRC.ACC
				sta SRC.ACC+1

.5				jsr SRC.GetNextChar
				bcs .8

				jsr SRC.IsLetterOrDigit
				bcc .5

				cmp #'.'
				beq .5

				cmp #'_'
				beq .5

.8				clc
				rts

.9				lda #E.UNDEF.SYMBOL
				sec
				rts
*---------------------------------------
SYM.StoreGlobal	>LDA.G ASM.PASS
				bne .8

				>LDA.G SYM.BufPtr
				beq .8

				>PUSHB.G SYM.hList
				>PUSHW.G SYM.ID
				>PUSHW ZPSymbolBuf

				>LDA.G SYM.BufPtr
				tay
				lda #0
				cpy #SYMG
				beq .1

				iny						Add 1 for \0 after locals/privates
				bne .1
				inc

.1				>PUSHYA

				>SYSCALL SListAddData
				bcs .9

				>STZ.G SYM.BufPtr

.8				clc
.9				rts
*---------------------------------------
SYM.UpdateGlobal
				>PUSHB.G SYM.hList
				>PUSHW.G SYM.ID
				>PUSHW ZPSymbolBuf

				>LDA.G SYM.BufPtr
				tay
				lda #0
				cpy #SYMG
				beq .1

				iny						Add 1 for \0 after locals/privates
				bne .1
				inc

.1				>PUSHYA

				>SYSCALL SListSetData
				bcs .9
				
				>STZ.G SYM.BufPtr
.9				rts
*---------------------------------------
SYM.PC2Acc		ldy #ASM.PC+3
				ldx #3

.1				lda (pData),y
				sta SRC.ACC,x
				dey
				dex
				bpl .1

				lda #2
				sta SRC.ACC.SIZE

				rts
*---------------------------------------
SYM.Acc2Global	ldy #SYMG-1

.2				lda SRC.ACC.F,y
				sta (ZPSymbolBuf),y
				dey
				bpl .2

				rts
*---------------------------------------
SYM.NewLocalA	tax						Save Local ID

				>LDA.G SYM.BufPtr		not in a global label
				beq .91

				>LDA.G ASM.PASS
				bne .20
*---------------------------------------
				jsr SYM.LookupLocalX	Pass #1: try to add
				bcc .9					Already Defined

				>LDA.G SYM.BufPtr
*				sec
				adc #SYML
				bcs .90

				ldy #ASM.PC+4

.1				dey
				lda (pData),y
				pha
				cpy #ASM.PC
				bne .1

				>LDA.G MAC.CtxID		Get Macro Context ID

				pha

				>LDA.G SYM.BufPtr
				tay
				txa						Get Back ID
				sta (ZPSymbolBuf),y

				ldx #5					MAC ID + PC (4)

.2				pla
				iny
				sta (ZPSymbolBuf),y
				dex
				bne .2

				iny
				lda #0
				sta (ZPSymbolBuf),y		ending \0
				tya

				>STA.G SYM.BufPtr

				lda (ZPSymbolBuf)
				ora #SYMG.F.LOCALS
				sta (ZPSymbolBuf)

.8				clc
				rts

.91				lda #E.INV.LABEL
				sec
				rts

.90				lda #E.TOO.MANY.LOCAL
				sec
				rts

.9				lda #E.SYMBOL.REDEF
				sec
				rts
*---------------------------------------
.20				>LDA.G SYM.BufPtr		Pass #2: setup SYM.BufPtr in case of .EQ
				clc
				adc #SYML
				sta (pData),y

				rts
*---------------------------------------
SYM.LookupLocalX
				lda (ZPSymbolBuf)
				and #SYMG.F.LOCALS
				beq .99

				ldy #SYMG

.1				phy
				lda (ZPSymbolBuf),y
				beq .9

				txa
				cmp (ZPSymbolBuf),y
				bne .3

				>LDA.G MAC.CtxID

				ply
				phy

				iny
				cmp (ZPSymbolBuf),y
				bne .3

				ldx #0

.2				iny
				lda (ZPSymbolBuf),y
				sta SRC.ACC,x
				inx
				cpx #4

				bne .2

				pla

				clc
				rts

.3				pla
				clc
				adc #SYML
				tay
				bra .1

.9				ply
.99				lda #E.UNDEF.SYMBOL
				sec
				rts
*---------------------------------------
SYM.Dump.End	>PUSHW L.MSG.SUMMARY
				>PUSHW ZPPtr2
				>PUSHBI 2
				jmp OUT.Print

SYM.Dump.8		clc
				rts
*---------------------------------------
SYM.Dump		>LDA.G bListAll
				bmi SYM.Dump.1

				>LDA.G ASM.LI.ON
				bpl SYM.Dump.8

SYM.Dump.1		>LDYA L.MSG.SYMBOLS
				>SYSCALL PutS

				stz ZPPtr2
				stz ZPPtr2+1

.1				>LDYA ZPPtr2
				>STYA ZPPtr1

				>PUSHB.G SYM.hList
				>PUSHW ZPPtr1
				>PUSHW ZPTmpBuf
				>SYSCALL SListGetByID
				bcs SYM.Dump.End

				>STYA ZPPtr2			Save Next ID

				>PUSHB.G SYM.hList
				>PUSHW ZPPtr1			KeyID
				>PUSHW ZPSymbolBuf
				>PUSHWI $ffff			All
				>PUSHWZ					from Start
				>SYSCALL SListGetData
				bcs .9

				jsr SYM.Dump.GLP

				bcc .1

.9				rts
*---------------------------------------
SYM.Dump.GLP	jsr SYM.Dump.G
				bcs .9

				>LDYA ZPTmpBuf			Label
				>SYSCALL PutS

				ldx #5
				lda (ZPSymbolBuf)

				bit #SYMG.F.LOCALS
				beq .2

				jsr SYM.Dump.LP
				bcs .9

.2				cpx #5					already CR printed ?
				beq .8

				jmp OUT.PrintCR

.8				clc
.9				rts
*---------------------------------------
SYM.Dump.G		ldy #SYMG.SIZE			Get Symbol Size
				lda (ZPSymbolBuf),y

				pha

				asl
				tax
				>PUSHB L.MSG.EQU0+1,x
				>PUSHB L.MSG.EQU0,x

				pla
				pha
				tax						byte count

				clc
				adc #SYMG.V

				tay

.2				dey
				lda (ZPSymbolBuf),y
				>PUSHA
				dex
				bne .2

				pla						Byte Count

.3				>PUSHA

				>SYSCALL PrintF
				rts
*---------------------------------------
SYM.Dump.LP		ldy #SYMG

				ldx #5

.1				lda (ZPSymbolBuf),y
				beq .8

				phy

				phx

				tax						ID

				iny
				lda (ZPSymbolBuf),y		MacID
				bne .3

				>PUSHW L.MSG.LSYMBOL
				txa
				>PUSHA

				jsr SYM.Dump.PushValueY

				lda #5
				bra .5

.3				>PUSHW L.MSG.PSYMBOL
				txa
				>PUSHA

				>PUSHB (ZPSymbolBuf),y

				jsr SYM.Dump.PushValueY

				lda #6

.5				>PUSHA

				>SYSCALL PrintF

				plx
				dex
				bne .6

				jsr OUT.PrintCR
				ldx #5

.6				pla
				clc
				adc #SYML
				tay

				bra .1

.8				rts
*---------------------------------------
SYM.Dump.PushValueY
				ldx #4

				iny
				iny
				iny
				iny

.1				lda (ZPSymbolBuf),y
				>PUSHA
				dey
				dex
				bne .1

				rts
*---------------------------------------
MAN
SAVE usr/src/bin/asm.s.sym
LOAD usr/src/bin/asm.s
ASM
