NEW
  AUTO 3,1
*---------------------------------------
MAC.Init		>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
				>SYSCALL SListLookup
				bcs .90

				>STYA ZPPtr1			MAC.ID
				txa
*				clc
				adc ZPLinePtr
				sta ZPLinePtr
				bcc .1
				inc ZPLinePtr+1

.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
