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: (4 bytes)
*  0 : Local ID (1->255)
*  1 : Macro Context ID (private)
*  2-3 : 16 bits offset (PC)
*---------------------------------------
SYM.Init		lda #SL..+SL._
				>SYSCALL SListNew
				bcs .9

				>STA.G SYM.hList

				lda #SL..+SL._
				>SYSCALL SListNew
				bcs .9

				>STA.G FWR.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 FWR.hList
				beq .2

				>SYSCALL SListFree

.2				>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...
				>PUSHWI 0				ScopeID
				>SYSCALL SListNewKey
				bcs .9					Already Defined

				>STYA.G SYM.ID

				stz SRC.ACC.F

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

				phx

				jsr SYM.LookupFWFef
				bcs .1

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

.1				plx
				jsr SRC.SkipX

				jsr SYM.PC2Acc
				jsr SYM.Acc2Global

.80				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
				>PUSHWI 0				ScopeID
				>SYSCALL SListLookup
				bcs SYM.NewGlobal.RTS

				>STYA.G SYM.ID

				jsr SRC.SkipX

.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)		#SYMG.F
				bit #SYMG.F.EQU
				bne .8

*				bit #SYMG.F.FWREF
*				beq .2

*			>DEBUG

.2				>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				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
				>PUSHWI 0				ScopeID
				>SYSCALL SListLookup
				bcc .10

				>LDA.G ASM.PASS			pass#2?
				beq .11

				lda #E.UNDEF.SYMBOL
				sec
				rts

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

				lda #$FF
				sta SRC.ACC
				sta SRC.ACC+1

				jmp SYM.AddFWFef

.10				>STYA ZPPtr1			KeyID

				jsr SRC.SkipX

.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
				bpl .2

				clc
				rts

.3				>PUSHB.G SYM.hList
				>PUSHW ZPPtr1			KeyID
				>PUSHW L.SRC.ACC.F
				>PUSHWI SYMG
				>PUSHWZ
				>SYSCALL SListGetData
				bcs .90

				clc
				rts

.90				plx
.9				rts
*---------------------------------------
SYM.AddFWFef	jsr SYM.LookupFWFef
				bcc .8					Already Defined

				>PUSHB.G FWR.hList
				>PUSHW ZPLinePtr		Pass #1: try to add global...
				>PUSHWI 0				ScopeID
				>SYSCALL SListNewKey
				bcs .9

				>STYA.G FWR.ID

				jsr SRC.SkipX

				>PUSHB.G FWR.hList
				>PUSHW.G FWR.ID
				>PUSHW ZPSymbolBuf
				>PUSHWI 1
				>SYSCALL SListAddData
				rts

.8				jsr SRC.SkipX

				clc

.9				rts
*---------------------------------------
SYM.LookupFWFef	>PUSHB.G FWR.hList
				>PUSHW ZPLinePtr
				>PUSHWI 0				ScopeID
				>SYSCALL SListLookup
				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

				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

				ldy #SYMG.V

				sec

				pla
				sbc (ZPSymbolBuf),y
				sta SYM.LocalOfs

				iny
				pla
				sbc (ZPSymbolBuf),y
				sta SYM.LocalOfs+1

				iny
				pla
				sbc (ZPSymbolBuf),y
				bne .97

				iny
				pla
				sbc (ZPSymbolBuf),y
				bne .98

				>LDA.G MAC.CtxID		Get Macro Context ID

				pha

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

				pla
				iny
				sta (ZPSymbolBuf),y

				lda SYM.LocalOfs
				iny
				sta (ZPSymbolBuf),y

				lda SYM.LocalOfs+1
				iny
				sta (ZPSymbolBuf),y

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

				>STA.G SYM.BufPtr

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

				clc
				rts

.91				lda #E.INV.LABEL
				sec
				rts

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

.97				pla
.98				lda #E.RANGE

				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
*				clc
				rts
*---------------------------------------
SYM.LookupLocalX
				lda (ZPSymbolBuf)
				and #SYMG.F.LOCALS
				beq .99

				ldy #SYMG

.1				lda (ZPSymbolBuf),y
				beq .99

				phy						SYML.ID

				txa
				cmp (ZPSymbolBuf),y
				bne .4

				>LDA.G MAC.CtxID

				ply
				phy

				iny						SYML.CtxID
				cmp (ZPSymbolBuf),y
				bne .4

				ldy #SYMG.V
				ldx #0

.2				lda (ZPSymbolBuf),y
				sta SRC.ACC,x
				inx
				iny
				cpy #SYMG
				bne .2

				ply
				iny
				iny						SYML.O

				lda (ZPSymbolBuf),y
				clc
				adc SRC.ACC
				sta SRC.ACC

				iny
				lda (ZPSymbolBuf),y
				adc SRC.ACC+1
				sta SRC.ACC+1
				bcc .3

				inc SRC.ACC+2

.3				clc
				rts

.4				pla
				clc
				adc #SYML
				tay
				bra .1

.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
				lda #1
				sta 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		ldx #8

				ldy #SYMG.V+3

.10				lda (ZPSymbolBuf),y
				bne .1

				dey
				dex
				dex
				bne .10

.1				txa
				lsr
				pha

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

				pla
				beq .3

				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
				iny
				lda (ZPSymbolBuf),y
				sta SRC.ACC

				iny
				lda (ZPSymbolBuf),y
				sta SRC.ACC+1

				stz SRC.ACC+2
				stz SRC.ACC+3

				ldy #SYMG.V
				ldx #0

				clc

.1				lda (ZPSymbolBuf),y
				adc SRC.ACC,x
				sta SRC.ACC,x
				iny
				inx
				txa
				eor #4
				bne .1

				ldx #3

.2				lda	SRC.ACC,x
				>PUSHA
				dex
				bpl .2

				rts
*---------------------------------------
				.DO SYMDBG=1
SYM.Debug		>PUSHW L.MSG.SYMDBG
				>PUSHW.G SYM.ID
				>PUSHBI 2
				>SYSCALL PrintF
				rts
				.FIN
*---------------------------------------
MAN
SAVE usr/src/bin/asm.s.sym
LOAD usr/src/bin/asm.s
ASM
