NEW
  AUTO 3,1
*---------------------------------------
SRC.ParseLine	jsr OUT.PrintBufReset

				>STZ.G OUT.bEquate

				jsr SRC.GetChar
				bcs .8

				cmp #'*'				Comment?
				beq .8

				cmp #';'				Comment?
				beq .8

				jsr SRC.DoCheck
				bcs .7					TRUE

				lda (ZPLinePtr)

.1				cmp #C.SPACE			false....skip label processing
				beq SRC.ParseLine.DirOp			no label....

.2				jsr SRC.GetNextChar
				bcs .8

				cmp #C.SPACE
				bne .2

				bra SRC.ParseLine.DirOp

.7				>LDA.G ASM.MA.ON
				bpl SRC.ParseLine.LABEL

				jmp MAC.Learn

.8				clc
SRC.ParseLine.RTS
				rts
*---------------------------------------
SRC.ParseLine.LABEL
				jsr SRC.GetChar
				cmp #C.SPACE			no label...go scan dir/opcode
				beq SRC.ParseLine.DirOp

				tax						save char...
				cpx #'.'				local symbol?
				bne	.1

				>LDA.G MAC.StkPtr
				bne SRC.ParseLine.InvLbl	illegal in MACRO
				bra .2

.1				cpx #':'				private symbol?
				bne .8

				>LDA.G MAC.StkPtr
				beq SRC.ParseLine.InvLbl	illegal OUTSIDE macro

.2				>LDA.G SYM.BufPtr			Not relative to Global label...
				beq SRC.ParseLine.InvLbl

				jsr SRC.GetNextChar
				bcs SRC.ParseLine.InvLbl

				jsr SRC.GetDecimal8
				bcs SRC.ParseLine.InvLbl

				jsr SYM.NewLocalA
				bcs SRC.ParseLine.RTS
				bra SRC.ParseLine.DirOp

.8				jsr SYM.NewGlobal
				bcs SRC.ParseLine.RTS
*---------------------------------------
SRC.ParseLine.DirOp
				jsr SRC.GetNextCharNB	Scan for an Opcode...
				bcs SRC.ParseLine.Ok
				cmp #'.'
				bne .5

				jsr SRC.GetNextChar
				bcs SRC.ParseLine.InvDir

				>LDYA L.T.DIRECTIVES
				jsr SRC.GetKeyword

				bcs SRC.ParseLine.InvDir

				jsr SRC.DoCheck
				bcs .1					TRUE, always execute

				cpx #12					.DO?
				beq .1

				cpx #20					.ELSE?
				beq .1

				cpx #30					.FIN?
				bne SRC.ParseLine.Ok

.1				jmp (J.DIRECTIVES,x)

.5				pha
				jsr SRC.DoCheck
				pla
				bcc SRC.ParseLine.Err	FALSE, skip all

				cmp #'>'
				bne SRC.ParseLine.OpCode
				jmp MAC.Exec

SRC.ParseLine.Ok
				clc
SRC.ParseLine.Err
				rts

SRC.ParseLine.InvLbl
				lda #E.INV.LABEL
				sec
				rts
SRC.ParseLine.InvDir
				lda #E.INV.DIR
				sec
				rts
*---------------------------------------
SRC.ParseLine.OpCode
				>LDYA ZPOpsPtr
				>STYA ZPOpDefPtr

.1				lda (ZPOpDefPtr)		End Of OpCode List

				ldy #1

				ora (ZPOpDefPtr),y
				beq .9

				lda ZPOpDefPtr
				clc
				adc #2
				sta ZPPtr2
				lda ZPOpDefPtr+1
				adc #0
				sta ZPPtr2+1
				lda (ZPPtr2)
				tax

				ldy #0

.2				lda (ZPLinePtr),y
				beq .7

				cmp #'a'
				bcc .3

				cmp #'z'+1
				bcs .3

				eor #$20

.3				iny
				cmp (ZPPtr2),y
				bne .7

				dex
				bne .2

				lda (ZPLinePtr),y
				beq .8					End of Line, no AM

				cmp #C.SPACE			A space after opcode ?
				bne .7

				tya
				sec						skip OP + ' '
				adc ZPLinePtr
				sta ZPLinePtr
				bcc .5
				inc ZPLinePtr+1

.5				jsr SRC.GetChar
				bcs .8					Nothing after OP ' '

				cmp #C.SPACE			OP '  ' ?
				beq .8

				bra SRC.ParseLine.AM

.7				lda ZPOpDefPtr
				clc
				adc (ZPOpDefPtr)
				tax
				lda ZPOpDefPtr+1
				ldy #1
				adc (ZPOpDefPtr),y
				stx ZPOpDefPtr
				sta ZPOpDefPtr+1
				bra .1

.8				lda #$ff
				>STA.G SRC.AMID
				jsr SRC.ParseLine.AMCheck4OP
				bcs .99

				jmp SRC.ParseLine.Emit
.9				lda #E.INV.OPCODE
				sec
.99				rts
*---------------------------------------
SRC.ParseLine.AM
				stz SRC.AM.StrBuf

.1				jsr SRC.IsAMReserved
				bcs .2

				jsr SRC.AddToBuf
				bra .7

.2				jsr SRC.IsLetter		Any register?
				bcs .6					no, try something else

				>LDYA ZPRPtr			Check in register table
				jsr SRC.GetKeyword
				bcs .6

				lda (ZPPtr1)			get register len
				tax
.4				inc ZPPtr1
				bne .5

				inc ZPPtr1+1

.5				lda (ZPPtr1)
				jsr SRC.AddToBuf
				dex
				bne .4

				bra .74

.6				jsr EXP.ResetAcc

				jsr EXP.Eval
				bcs .99

				>LDA.G EXP.Prefix
				beq .75

				jsr SRC.AddToBuf

.75			ldx SRC.ACC.SIZE
			beq *					SHOULD NEVER APPEND

				jsr SRC.GetACCSize

.72				lda #'a'

.71				jsr SRC.AddToBuf
				dex
				bne .71

.74				jsr SRC.GetChar
				bcs .8

				cmp #C.SPACE
				bne .1

				bra .8

.7				jsr SRC.GetNextChar
				bcs .8

				cmp #C.SPACE
				bne .1

.8				jsr SRC.ParseLine.AMCheck
				bcs .9

				jsr SRC.ParseLine.AMCheck4OP
				bcc .88

.80				jsr SRC.ExpandAddress
				cpx #5
				bne .8

.9				lda #E.INV.AM
				sec
.99				rts

.88				jmp SRC.ParseLine.Emit
*---------------------------------------
SRC.ParseLine.AMCheck
				>LDYA ZPAMPtr			Check if AM is valid for CPU
				>STYA ZPPtr1
				ldx #0

.1				inx
				lda (ZPPtr1)
				beq .9

				cmp SRC.AM.StrBuf
				bne .7

				tay

.2				lda (ZPPtr1),y
				cmp SRC.AM.StrBuf,y
				bne .6

				dey
				bne .2

				txa
				>STA.G SRC.AMID

				clc
				rts

.6				lda (ZPPtr1)
.7				sec
				adc ZPPtr1
				sta ZPPtr1
				bcc .1
				inc ZPPtr1+1
				bra .1
.9				sec
				rts
*---------------------------------------
SRC.ParseLine.AMCheck4OP
				lda ZPOpDefPtr			Skip nextLoHi,L,"ADC"
				ldx ZPOpDefPtr+1

				clc
				adc #2					Skip nextLoHi
				bcc .11
				inx

.11				sec						skip LEN Byte
				ldy #2					LEN Byte
				adc (ZPOpDefPtr),y
				bcc .10
				inx

.10				sta ZPPtr1

				stx ZPPtr1+1
				lda (ZPPtr1)			AMID...

.1				>CMP.G SRC.AMID
				beq .8

				lda ZPPtr1				Skip AMID,L,"39aa"
				ldx ZPPtr1+1
				inc						AMID....
				bne .12
				inx

.12				sec						LEN byte...
				ldy #1					String...
				adc (ZPPtr1),y
				bcc .2
				inx

.2				sta ZPPtr1
				stx ZPPtr1+1
				lda (ZPPtr1)
				bne .1

				lda #E.INV.AM.4.OC
				sec
				rts

.8				>LDYA ZPPtr1
				>STYA ZPOpDefPtr
				clc
				rts
*---------------------------------------
SRC.ParseLine.Emit
				stz SRC.ACCTMP			index in ACC

				ldy #1
				lda (ZPOpDefPtr),y
				sta SRC.ACCTMP+1		Char Count in AM

				iny

.2				lda (ZPOpDefPtr),y
				cmp #'a
				bcs .4					lowercase, go compute address

				jsr SRC.IsDigit16
				asl
				asl
				asl
				asl
				sta SRC.ACCTMP+2
				iny
				dec SRC.ACCTMP+1
				lda (ZPOpDefPtr),y
				jsr SRC.IsDigit16
				ora SRC.ACCTMP+2

.3				jsr OUT.EmitByte
				bcs .9

				iny
				dec SRC.ACCTMP+1
				bne .2

*				clc
				rts

.4				bne .5					cmp #'a'....

				ldx SRC.ACCTMP
				inc SRC.ACCTMP
				lda SRC.ACC,x
				bra .3

.5				cmp #'r
				bne .7

				jsr SRC.ComputeRel8
				bcs .6

				lda SRC.ACC
				bra .3

.6				>LDA.G ASM.PASS
				beq .3					Emit 00 if pending symbol (pass #1)

				bra .91

.7				cmp #'l
				bne .90

				jsr SRC.ComputeRel16
				bcs .8

				lda SRC.ACC
				jsr OUT.EmitByte
				bcs .9

				lda SRC.ACC+1
				bra .3

.8				>LDA.G ASM.PASS
				bne .91

*				lda #0
				jsr OUT.EmitByte
				bcs .9

				lda #0
				bra .3					Emit 00 00 if pending symbol (pass #1)

.90				lda #E.INV.CPU.FILE
				sec
				rts

.91				lda #E.RANGE
				sec
.9				rts
*---------------------------------------
SRC.AddToBuf	inc SRC.AM.StrBuf
				ldy SRC.AM.StrBuf
				sta SRC.AM.StrBuf,y
				rts
*---------------------------------------
SRC.ExpandAddress
				ldy SRC.AM.StrBuf

.1				lda SRC.AM.StrBuf,y
				sta SRC.AM.StrBuf+1,y
				dey
				cmp #'a'
				bne .1

				ldx #2					"aa"

				tya
				beq .8

.2				lda SRC.AM.StrBuf,y
				cmp #'a'
				bne .8

				inx						"aaa"
.3				dey
				bne .2

.8				inc SRC.AM.StrBuf
				rts
*---------------------------------------
SRC.ComputeRel8	lda #1
				jsr SRC.ComputeRel
				bcc .1

* positive : check 0<r<0000007F

				lda SRC.ACC+3
				ora SRC.ACC+2
				ora SRC.ACC+1
				bne .9

				lda SRC.ACC
				bmi .9

				clc
				rts

* negative : check FFFFFF80<r<FFFFFFFF

.1				lda SRC.ACC+3
				and SRC.ACC+2
				and SRC.ACC+1
				inc
				bne .9

				lda SRC.ACC
				bpl .9

				clc
				rts

.9				sec
				rts
*---------------------------------------
SRC.ComputeRel16
				lda #2
				jsr SRC.ComputeRel
				bcc .1

* positive : check 0<r<00007FFF

				lda SRC.ACC+3
				ora SRC.ACC+2
				bne .9

				lda SRC.ACC+1
				bmi .9

				clc
				rts

* negative : check FFFF8000<r<FFFFFFFF

.1				lda SRC.ACC+3
				and SRC.ACC+2
				inc
				bne .9

				lda SRC.ACC+1
				bpl .9

				clc
				rts

.9				sec
				rts
*---------------------------------------
SRC.ComputeRel	phy
				ldy #ASM.PC
				clc
				adc (pData),y
				sta SRC.ARG

				iny
				lda #0
				adc (pData),y
				sta SRC.ARG+1
				
				iny
				lda #0
				adc (pData),y
				sta SRC.ARG+2
				
				iny
				lda #0
				adc (pData),y
				sta SRC.ARG+3
				
				sec
				lda SRC.ACC
				sbc SRC.ARG
				sta SRC.ACC

				lda SRC.ACC+1
				sbc SRC.ARG+1
				sta SRC.ACC+1

				lda SRC.ACC+2
				sbc SRC.ARG+2
				sta SRC.ACC+2

				lda SRC.ACC+3
				sbc SRC.ARG+3
				sta SRC.ACC+3

				ply
				rts	
*---------------------------------------
SRC.GetDecimal8	jsr SRC.GetDecimal
				bcs .9

				lda SRC.ACC+1
				ora SRC.ACC+2
				ora SRC.ACC+3
				bne .99					Max .255

				lda SRC.ACC
				beq .99					.0 is not allowed

*				clc
				rts

.99				sec
.9				rts
*---------------------------------------
SRC.GetDecimal	jsr SRC.GetChar
				beq .99

				stz SRC.ACC+1
				stz SRC.ACC+2
				stz SRC.ACC+3
				jsr SRC.IsDigit10
				bcs .99

				and #$0F
				sta SRC.ACC

.1				jsr SRC.GetNextChar
				bcs .8

				cmp #C.SPACE
				beq .8

				jsr SRC.IsEXPReserved
				bcc .8

				jsr SRC.IsAMReserved
				bcc .8

				jsr SRC.IsDigit10
				bcs .9

				and #$0F
				pha
				jsr SRC.ACC10
				pla
				bcs .9

				adc SRC.ACC
				sta SRC.ACC
				bcc .1

				inc SRC.ACC+1
				bne .1

				inc SRC.ACC+2
				bne .1

				inc SRC.ACC+3
				bne .1

.9				lda #E.VAL.TOO.BIG
				sec
				rts

.8				clc
				rts

.99				lda #E.SYNTAX.ERROR
				sec
				rts
*---------------------------------------
SRC.GetHex		jsr SRC.GetNextChar	skip '$'
				bcs .99
				stz SRC.ACC+1
				stz SRC.ACC+2
				stz SRC.ACC+3
				jsr SRC.IsDigit16
				bcs .99

				sta SRC.ACC
.1				jsr SRC.GetNextChar
				bcs .8

				cmp #C.SPACE
				beq .8

				jsr SRC.IsEXPReserved
				bcc .8

				jsr SRC.IsAMReserved
				bcc .8

				jsr SRC.IsDigit16
				bcs .99

				ldx #4

.2				asl SRC.ACC
				rol SRC.ACC+1
				rol SRC.ACC+2
				rol SRC.ACC+3
				bcs .9

				dex
				bne .2

				ora SRC.ACC
				sta SRC.ACC
				bra .1

.8				clc
				rts

.9				lda #E.VAL.TOO.BIG
				sec
				rts

.99				lda #E.SYNTAX.ERROR
				sec
				rts
*---------------------------------------
SRC.GetOctal	jsr SRC.GetNextChar	skip '&'
				bcs .99

				stz SRC.ACC+1
				stz SRC.ACC+2
				stz SRC.ACC+3
				jsr SRC.IsDigit8
				bcs .99

				and #$0F
				sta SRC.ACC

.1				jsr SRC.GetNextChar
				bcs .8

				cmp #C.SPACE
				beq .8

				jsr SRC.IsEXPReserved
				bcc .8

				jsr SRC.IsAMReserved
				bcc .8

				jsr SRC.IsDigit8
				bcs .9

				asl
				asl
				asl
				asl
				asl

				ldx #3

.2				asl
				rol SRC.ACC
				rol SRC.ACC+1
				rol SRC.ACC+2
				rol SRC.ACC+3
				bcs .9

				dex
				bne .2
				bra .1

.8				clc
				rts

.9				lda #E.VAL.TOO.BIG
				sec
				rts

.99				lda #E.SYNTAX.ERROR
				sec
				rts
*---------------------------------------
SRC.GetBinary	jsr SRC.GetNextChar	skip '%'
				bcs .99

				stz SRC.ACC+1
				stz SRC.ACC+2
				stz SRC.ACC+3
				cmp #'1'
				beq .10

				cmp #'0'
				bne .99

.10				and #$01
				sta SRC.ACC

.1				jsr SRC.GetNextChar
				bcs .8

				cmp #'.'				allow %111.00.1
				beq .1

				cmp #C.SPACE
				beq .8

				jsr SRC.IsEXPReserved
				bcc .8

				jsr SRC.IsAMReserved
				bcc .8

				cmp #'1'
				beq .11

				cmp #'0'
				bne .8

.11				lsr
				rol SRC.ACC
				rol SRC.ACC+1
				rol SRC.ACC+2
				rol SRC.ACC+3
				bcc .1

.9				lda #E.VAL.TOO.BIG
				sec
				rts

.99				lda #E.SYNTAX.ERROR
				sec
				rts

.8				clc
				rts
*---------------------------------------
SRC.GetKeyword	>STYA ZPPtr1		KeyWord table

				ldx #0				Keyword.ID

.1				phx
				lda (ZPPtr1)
				beq .9				End Of table
				tax					KW len
				ldy #0

.3				lda (ZPLinePtr),y
				beq .6
				jsr SRC.IsKeywordLetterUC
				bcs .6
				iny
				cmp (ZPPtr1),y
				bne .7
				dex
				bne .3
				lda (ZPLinePtr),y	All chars match...
				beq .4				End of Line ?
				jsr SRC.IsKeywordLetterUC
				bcc .7				Additional letters...
.4				lda ZPLinePtr		found!
				clc
				adc (ZPPtr1)		skip KW in source line
				sta ZPLinePtr
				bcc .5
				inc ZPLinePtr+1
.5				plx					Keyword.ID
				clc
				rts

.6
.7				lda (ZPPtr1)
				sec					Add keyword Len+1
				adc ZPPtr1
				sta ZPPtr1
				bcc .8
				inc ZPPtr1+1
.8				plx					Keyword.ID
				inx
				inx
				bra .1
.9				plx
				sec
				rts
*---------------------------------------
SRC.IsAMReserved
				ldx SRC.AM.RESERVED
.1				cmp SRC.AM.RESERVED,x
				beq .8
				dex
				bne .1
				sec
				rts
.8				clc
				rts
*---------------------------------------
SRC.IsMODReserved
				ldx SRC.MOD.RESERVED
.1				cmp SRC.MOD.RESERVED,x
				beq .8
				dex
				bne .1
				sec
				rts
.8				clc
				rts
*---------------------------------------
SRC.IsEXPReserved
				ldx SRC.EXP.RESERVED
.1				cmp SRC.EXP.RESERVED,x
				beq SRC.IsEXPReserved.8
				dex
				bne .1
				sec
				rts
SRC.IsEXPReserved.8
				clc
				rts
*---------------------------------------
SRC.IsKeywordLetterUC
				cmp #'.'
				beq SRC.IsEXPReserved.8

				cmp #'_'
				beq SRC.IsEXPReserved.8

				cmp #'A'
				bcc .9
				cmp #'Z'+1
				bcc .99

				cmp #'a'
				bcc .9
				cmp #'z'+1
				eor #$20
				rts					CC if lowercase
.9				sec
.99				rts
*---------------------------------------
SRC.IsLetterOrDigit
				jsr SRC.IsDigit10
				bcc SRC.IsLetterRTS
*---------------------------------------
SRC.IsLetter	cmp #'A'
				bcc .9
				cmp #'Z'+1
				bcc SRC.IsLetterRTS

				cmp #'a'
				bcc .9
				cmp #'z'+1
				rts					CC if lowercase
.9				sec
SRC.IsLetterRTS	rts
*---------------------------------------
SRC.IsDigit16	jsr SRC.IsDigit10
				bcc .8
				cmp #'A'
				bcc .9
				cmp #'F'+1
				bcc .1
				cmp #'a'
				bcc .9
				cmp #'f'+1
				bcs .9

				eor #$20
.1
*				clc
				sbc #'A'-11			cc so A->10 (11-CC)
				clc
.8				and #$0F
				rts
.9				sec
				rts
*---------------------------------------
SRC.IsDigit10	cmp #'0'
				bcc .9
				cmp #'9'+1
				rts					cc if ok, cs if not
.9				sec
				rts
*---------------------------------------
SRC.IsDigit8	cmp #'0'
				bcc .9
				cmp #'7'+1
				rts					cc if ok, cs if not
.9				sec
				rts
*---------------------------------------
SRC.GetNextCharNB
				jsr SRC.GetNextChar
				bcs .9
				cmp #C.SPACE
				beq SRC.GetNextCharNB
				clc
.9				rts
*---------------------------------------
SRC.GetNextCharUC
				jsr SRC.GetNextChar
				bcs .9
				cmp #'a'
				bcc .8
				cmp #'z'+1
				bcs .8
				eor #$20			to Uppercase
.8				clc
.9				rts
*---------------------------------------
SRC.GetNextChar	lda (ZPLinePtr)
				beq SRC.GetChar.ERR
				cmp #$0D
				beq SRC.GetChar.ERR
				inc ZPLinePtr
				bne SRC.GetChar
				inc ZPLinePtr+1
SRC.GetChar		lda (ZPLinePtr)
				beq SRC.GetChar.ERR
				cmp #$0D
				beq SRC.GetChar.ERR
				clc
				rts
SRC.GetChar.ERR	sec
				rts
*---------------------------------------
SRC.ACC10		lda SRC.ACC				ACC*2-> ACC & ACCTMP
				asl
				sta SRC.ACC
				sta SRC.ACCTMP
				lda SRC.ACC+1
				rol
				sta SRC.ACC+1
				sta SRC.ACCTMP+1
				lda SRC.ACC+2
				rol
				sta SRC.ACC+2
				sta SRC.ACCTMP+2
				lda SRC.ACC+3
				rol
				sta SRC.ACC+3
				sta SRC.ACCTMP+3
				bcs .9

				ldx #2

.1				asl SRC.ACC			ACC=ACC*4
				rol SRC.ACC+1
				rol SRC.ACC+2
				rol SRC.ACC+3
				bcs .9

				dex
				bne .1

				lda SRC.ACC			CC from ROL SRC.ACC+3
				adc SRC.ACCTMP
				sta SRC.ACC
				lda SRC.ACC+1
				adc SRC.ACCTMP+1
				sta SRC.ACC+1
				lda SRC.ACC+2
				adc SRC.ACCTMP+2
				sta SRC.ACC+2
				lda SRC.ACC+3
				adc SRC.ACCTMP+3
				sta SRC.ACC+3		CS if overflow
.9				rts
*---------------------------------------
SRC.GetACCSize	lda SRC.ACC.F

				and #SYMG.F.FWREF
				beq .1

				ldx #2
				rts

.1				ldx SRC.ACC.SIZE

.2				lda SRC.ACC-1,x
				bne .8

				dex
				bne .2

				inx

.8				rts
*---------------------------------------
SRC.DoCheck		sec
				>LDA.G ASM.DO.StackPtr
				beq .8

				clc
				adc #ASM.DO.Stack-1
				tay
				lda (pData),y
				asl

.8				rts						CS if TRUE
*---------------------------------------
MAN
SAVE usr/src/bin/asm.s.src
LOAD usr/src/bin/asm.s
ASM
