NEW
  AUTO 3,1
*---------------------------------------
MAC.Init		lda #SL..+SL._
				>SYSCALL SListNew
				bcs .9

				>STA.G MAC.hList

				>LDYAI 256
				>SYSCALL GetMem
				bcs .9

				txa
				>STA.G MAC.hBuf

				>LDYAI 256
				>SYSCALL GetMem
				bcs .9

				>STYA ZPMacroArgBuf
				txa
				>STA.G MAC.hArgBuf

				>LDYAI MA.MAXDEPTH*6
				>SYSCALL GetMem
				bcs .9

				>STYA ZPMacroStk
				txa
				>STA.G MAC.hStk

.9				rts
*---------------------------------------
MAC.Quit		>LDA.G MAC.StkPtr
				beq .10

				jsr MAC.Pop
				bra MAC.Quit

.10				>LDA.G MAC.hStk
				beq .1

				>SYSCALL FreeMem

.1				>LDA.G MAC.hBuf
				beq .2

				>SYSCALL FreeMem

.2				>LDA.G MAC.hArgBuf
				beq .3

				>SYSCALL FreeMem

.3				>LDA.G MAC.hList
				beq .8

				>SYSCALL SListFree

.8				clc
				rts
*---------------------------------------
MAC.Learn		>LDA.G MAC.hBuf
				>SYSCALL GetMemPtr
				>STYA ZPMacroBuf

				>STZ.G MAC.BufPtr
				sta (ZPMacroBuf)
				lda (ZPLinePtr)
				cmp #C.SPACE			No label, scan to DIR/OP if any
				bne .1

				jsr SRC.GetNextCharNB
				bcs .8

				lda #C.SPACE			Store ONE blank
				jsr MAC.AddChar
				bcs .90

				lda (ZPLinePtr)			get back non blank char
				bra .2

.1				jsr MAC.AddChar
				bcs .99

				jsr SRC.GetNextChar
				bcs .80

				cmp #C.SPACE
				bne .1

				jsr MAC.AddChar
.90				bcs .99

				jsr SRC.GetNextCharNB
				bcs .80

.2				cmp #'.'				Directive ?
				bne .4

				ldy #1
				lda (ZPLinePtr),y
				beq .3

				cmp #'E'
				beq .21

				cmp #'e'
				bne .3

.21				iny
				lda (ZPLinePtr),y
				beq .3

				cmp #'M'
				beq .22

				cmp #'m'
				bne .3

.22				>STZ.G ASM.MA.ON
.8				clc
				rts

.80				lda #C.CR
				jmp MAC.AddChar

.3				lda (ZPLinePtr)

.4				jsr MAC.AddChar
				bcs .99

				jsr SRC.GetNextChar
				bcs .80

				cmp #C.SPACE
				bne .4

				jsr SRC.GetNextChar
				bcs .8

				cmp #C.SPACE
				beq .80					Comments...

				pha
				lda #C.SPACE
				jsr MAC.AddChar
				pla

				bcs .99

.5				jsr MAC.AddChar			Store ARG....
				bcs .99

				jsr SRC.GetNextChar
				bcs .80

				cmp #C.SPACE
				bne .5
				bra .80					End of Line

.99				rts
*---------------------------------------
MAC.AddChar		tax
				>LDA.G ASM.PASS			If Pass#2, ignore
				bne .8

				>LDA.G MAC.BufPtr
				tay
				txa
				sta (ZPMacroBuf),y
				>INC.G MAC.BufPtr
				txa
				beq .1

				cmp #C.CR
				bne .8

.1				>PUSHB.G MAC.hList
				>PUSHW.G MAC.ID
				>PUSHW ZPMacroBuf
				>LDA.G MAC.BufPtr
				tay
				lda #0
				>PUSHYA
				>SYSCALL SListAddData
				rts

.8				clc
				rts
*---------------------------------------
MAC.Exec		jsr SRC.GetNextChar		skip '>'
				bcs .90

				>PUSHB.G MAC.hList
				>PUSHW ZPLinePtr
				>PUSHWI 0				ScopeID
				>SYSCALL SListLookup
				bcs .90

				>STYA ZPPtr1			MAC.ID

				jsr SRC.SkipX

.1				jsr SRC.GetChar
				bcs .8

				cmp #C.SPACE
				bne .92

				jsr SRC.GetNextChar
				beq .8					eol..

				cmp #C.SPACE			some arg...
				bne .8

.2				jsr SRC.GetNextChar		comment....skip
				bcc .2

.8				jmp MAC.Push

.90				lda #E.MACRO.INV
*				sec
				rts

.92				lda #E.SYNTAX.ERROR
				sec
MAC.Exec.RTS	rts
*---------------------------------------
MAC.ReadLine	>LDA.G MAC.hBuf
				>SYSCALL GetMemPtr
				>STYA ZPMacroBuf

				jsr MAC.Get				ZPMacroArgBuf = args

				>PUSHB.G MAC.hList
				>PUSHW ZPPtr1			Mac ID
				>PUSHW ZPMacroBuf
				>PUSHWZ					len = 0 (string mode)
				>PUSHW ZPPtr2			offset
				>SYSCALL SListGetData
				bcs MAC.Exec.RTS

				pha
				tya
				sec						+1 for CR
				adc ZPPtr2
				sta ZPPtr2
				pla
				adc ZPPtr2+1
				sta ZPPtr2+1

				ldy #0

				stz DIR.Byte

.1				lda (ZPMacroBuf)
				beq .8

				cmp #C.CR
				beq .8

				inc ZPMacroBuf
				bne .2
				inc ZPMacroBuf+1

.2				cmp #']'
				bne .7

				bit DIR.Byte
				bmi .7

				lda (ZPMacroBuf)
				beq .9

				inc ZPMacroBuf
				bne .21
				inc ZPMacroBuf+1

.21				cmp #'#'
				bne .22

				lda ZPMacroArgCnt
				ora #$30
				bra .7

.22				cmp #'1'
				bcc .6

				cmp #'9'+1
				bcs .6

				and #$0f
				tax
				dec
				cmp ZPMacroArgCnt
				bcs .1

				jsr MAC.GetArgX
				bcs .1					no arg ]n, append nothing

.3				lda (ZPPtr1)
				sta (ZPLineBuf),y
				iny

				inc ZPPtr1
				bne .4
				inc ZPPtr1+1

.4				dex
				bne .3

				bra .1

.6				pha
				lda #']'
				sta (ZPLineBuf),y
				iny
				pla

.7				sta (ZPLineBuf),y
				iny
				bra .1

.8				lda #0
				sta (ZPLineBuf),y
				jmp MAC.Put

.9				lda #E.SYNTAX.ERROR
				sec
MAC.ReadLine.RTS
				rts
*---------------------------------------
MAC.Push		>LDA.G MAC.StkPtr
				cmp #MA.MAXDEPTH*6
				beq MAC.ReadLine.RTS

				>LDA.G MAC.CtxID
				pha

				>INC.G MAC.CtxStackPtr
				clc
				adc #MAC.CtxStack-1
				tay
				pla
				sta (pData),y

				>INC.G MAC.CtxNextID
				>STA.G MAC.CtxID

				ldy #$ff

.10				iny
				lda (ZPLinePtr),y
				bne .10

				iny
				iny

				lda #0

				>SYSCALL GetMem
				bcs MAC.ReadLine.RTS

				>STYA ZPPtr2
				phx						hArgs

				ldx #0					arg cnt

.1				ldy #$ff

				stz DIR.Byte			between " flag

.2				iny
				lda	(ZPLinePtr),y
				beq .3

				cmp #C.SPACE			end of args ?
				bne .21

				bit DIR.Byte
				beq .3

.20				sta	(ZPPtr2)
				inc ZPPtr2
				bne .2
				inc ZPPtr2+1
				bra .2

.21				cmp #'"'
				bne .22

				lda DIR.Byte
				eor #$ff
				sta DIR.Byte
				bra .2

.22				cmp #','
				bne .20

				bit DIR.Byte
				bmi .20

				lda #0
				sta	(ZPPtr2)

				inc ZPPtr2
				bne .23
				inc ZPPtr2+1

.23				tya
				beq .4

				inx

				sec
				adc ZPLinePtr
				sta ZPLinePtr
				bcc .1

				inc ZPLinePtr+1
				bra .1

.3				lda #0
				sta	(ZPPtr2)

				tya
				beq .4

				inx

.4				>LDA.G MAC.StkPtr
				tay

				pla						push hArgs
				sta (ZPMacroStk),y
				iny

				txa						push arg count
				sta (ZPMacroStk),y
				iny

				lda #0					push offset
				sta (ZPMacroStk),y
				iny
				sta (ZPMacroStk),y

				iny
				lda ZPPtr1+1			push MAC.ID
				sta (ZPMacroStk),y
				iny
				lda ZPPtr1
				sta (ZPMacroStk),y

				iny
				tya
				>STA.G MAC.StkPtr
				clc
				rts

.9				lda #E.MACRO.TOO.MANY
				sec
				rts
*---------------------------------------
MAC.Pop			>LDA.G MAC.StkPtr

				dec
				dec							mac id

				dec
				dec							offset

				dec							arg cnt
				dec							hArgs

				sta (pData),y				6 bytes off stack

				tay
				lda (ZPMacroStk),y
				>SYSCALL FreeMem

				>LDA.G MAC.CtxStackPtr
				clc
				adc #MAC.CtxStack-1
				tay
				lda (pData),y
				>STA.G MAC.CtxID
				>DEC.G MAC.CtxStackPtr

				clc
				rts
*---------------------------------------
MAC.Get			>LDA.G MAC.StkPtr

				tay

				dey
				lda (ZPMacroStk),y
				sta ZPPtr1
				dey
				lda (ZPMacroStk),y
				sta ZPPtr1+1			get mac ID

				dey
				lda (ZPMacroStk),y
				sta ZPPtr2
				dey
				lda (ZPMacroStk),y
				sta ZPPtr2+1			get offset

				dey
				lda (ZPMacroStk),y		get arg count
				sta ZPMacroArgCnt

				dey
				lda (ZPMacroStk),y
				>SYSCALL GetMemPtr

				>STYA ZPMacroArgBuf		get args
				rts
*---------------------------------------
MAC.Put			>LDA.G MAC.StkPtr

				tay

				dey						to arg cnt

				dey
				dey						skip mac ID

				lda ZPPtr2
				sta (ZPMacroStk),y
				dey

				lda ZPPtr2+1
				sta (ZPMacroStk),y		save offset
				clc
				rts
*---------------------------------------
MAC.GetArgX		phy

				>LDYA ZPMacroArgBuf
				>STYA ZPPtr1

.1				ldy #$ff

.2				iny
				lda (ZPPtr1),y
				bne .2

.3				dex
				beq .4

				tya
				beq .9

				sec
				adc ZPPtr1
				sta ZPPtr1
				bcc .1
				inc ZPPtr1+1
				bra .1

.4				tya
				tax
				beq .9

				ply
				clc
				rts

.9				ply
				sec
				rts
*---------------------------------------
MAN
SAVE usr/src/bin/asm.s.mac
LOAD usr/src/bin/asm.s
ASM
