NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR $2000
				.TF	bin/asm
*---------------------------------------
ASMDBG			.EQ 0
SYMDBG			.EQ 0
*---------------------------------------
PAGE.LEN		.EQ 23
DO.MAXDEPTH		.EQ 8
IN.MAXDEPTH		.EQ 4
MA.MAXDEPTH		.EQ 8
*---------------------------------------
				.INB inc/macros.i
				.INB inc/a2osx.i
				.INB inc/mli.i
				.INB inc/mli.e.i
*---------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ZPTmpBuf		.BS 2
ZPLineBuf		.BS 2
ZPLinePtr		.BS 2
ZPSymbolBuf		.BS 2

ZPAMPtr			.BS 2
ZPRPtr			.BS 2
ZPOpsPtr		.BS 2
ZPOpDefPtr		.BS 2

ZPMacroStk		.BS 2
ZPMacroBuf		.BS 2
ZPMacroArgBuf	.BS 2
ZPMacroArgCnt	.BS 1

DIR.Byte		.BS 1

DIR.Word		.BS 2
SYM.LocalOfs	.BS 2
ZPPtr1			.BS 2
ZPPtr2			.BS 2

ZS.END			.ED
*---------------------------------------
* Symbols
*---------------------------------------
SYMG.F			.EQ 0
SYMG.F.RW			.EQ %10000000
SYMG.F.EQU			.EQ %01000000
SYMG.F.LOCALS		.EQ %00100000
SYMG.F.FWREF		.EQ %00010000
SYMG.V			.EQ 1 					DWORD
*
SYMG			.EQ 5
*---------------------------------------
SYML.ID			.EQ 0					1..255
SYML.CtxID		.EQ 1					0 if local, !0 if private
SYML.O			.EQ 2					WORD
*
SYML			.EQ 4
*---------------------------------------
ASM.T.AM		.EQ 0
ASM.T.R			.EQ 2
ASM.T.O			.EQ 4
*---------------------------------------
E.SYNTAX.ERROR	.EQ $A0
E.SYM.TOO.LONG	.EQ $A1
E.VAL.TOO.BIG	.EQ $A2
E.LINE.TOO.LONG	.EQ $A3
E.INV.LABEL		.EQ $A4
E.INV.DIR		.EQ $A5
E.ILLEGAL.DIR	.EQ $A6
E.INV.OPCODE	.EQ $A7
E.INV.AM.SYN	.EQ $A8
E.INV.AM		.EQ $A9
E.INV.AM.4.OC	.EQ $AA
E.RANGE			.EQ $AB
E.UNDEF.SYMBOL	.EQ $AC
E.SYMBOL.REDEF	.EQ $AD
E.TOO.MANY.DO	.EQ $AE
E.ELSE.WITHOUT.DO	.EQ $AF
E.TOO.MANY.LOCAL	.EQ $B0
E.MISSING.EXP	.EQ $B1
E.EXP.SYN.ERROR	.EQ $B2
E.MACRO.INV.DEF	.EQ $B3
E.MACRO.TOO.BIG	.EQ $B4
E.MACRO.INV		.EQ $B5
E.MACRO.TOO.MANY	.EQ $B6
*
E.OUT.OF.SYNC	.EQ $B8
E.INV.SYM		.EQ $B9
E.INV.ARGS		.EQ $BA
E.INV.CPU.FILE	.EQ $BC
E.SRC.INV.TYPE	.EQ $BD
E.SRC.TOO.MANY.IN	.EQ $BE
E.SRC.UNEXP.EOF	.EQ $BF
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp (.1,x)
				.DA #$61			6502,Level 1 (65c02)
				.DA #1				BIN Layout Version 1
				.DA #0				S.PS.F.EVENT
				.DA #0
				.DA CS.END-CS.START		CS
				.DA DS.END-DS.START		DS
				.DA #64					SS
				.DA #ZS.END-ZS.START	ZP
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1				.DA CS.INIT
				.DA CS.RUN
				.DA CS.DOEVENT
				.DA	CS.QUIT
L.MSG.HELP		.DA MSG.HELP
L.MSG.CRLF		.DA MSG.CRLF
L.MSG.OUT0		.DA MSG.OUT0
				.DA MSG.OUT1
				.DA MSG.OUT2
				.DA MSG.OUT3
L.MSG.EQU0		.DA MSG.EQU0
				.DA MSG.EQU1
				.DA MSG.EQU2
				.DA MSG.EQU3
				.DA MSG.EQU4
L.MSG.PASS		.DA MSG.PASS
L.MSG.LINENUM	.DA MSG.LINENUM
L.MSG.ERROR		.DA MSG.ERROR
L.MSG.SYMBOLS	.DA MSG.SYMBOLS
L.MSG.LSYMBOL	.DA MSG.LSYMBOL
L.MSG.PSYMBOL	.DA MSG.PSYMBOL
L.MSG.SUMMARY	.DA MSG.SUMMARY
L.MSG.END		.DA MSG.END
L.MSG.WARN1		.DA MSG.WARN1
				.DO ASMDBG=1
L.MSG.DBG		.DA MSG.DBG
				.FIN
				.DO SYMDBG=1
L.MSG.SYMDBG	.DA MSG.SYMDBG
				.FIN
L.MSG.SRC.FILE	.DA MSG.SRC.FILE
L.MSG.OBJ.FILE	.DA MSG.OBJ.FILE
L.MSG.CPU.FILE	.DA MSG.CPU.FILE
L.SRC.AM.StrBuf	.DA SRC.AM.StrBuf
L.ASM.6502		.DA ASM.6502
L.ASM.CPU.FILE	.DA ASM.CPU.FILE
L.SRC.ACC.F		.DA SRC.ACC.F
L.T.DIRECTIVES	.DA T.DIRECTIVES
J.DIRECTIVES	.DA DIR.AC
				.DA DIR.AS
				.DA DIR.AT
				.DA DIR.AZ
				.DA DIR.BS
				.DA DIR.CS
				.DA DIR.CZ
				.DA DIR.DA
DIR.DO.ID	.EQ *-J.DIRECTIVES
				.DA DIR.DO
				.DA DIR.DU
				.DA DIR.DU
				.DA DIR.ED
DIR.EL.ID	.EQ *-J.DIRECTIVES
				.DA DIR.EL
				.DA DIR.EM
				.DA DIR.EN
				.DA DIR.EP
				.DA DIR.EQ
DIR.FI.ID	.EQ *-J.DIRECTIVES
				.DA DIR.FI
				.DA DIR.HS
				.DA DIR.HX
				.DA DIR.IN
				.DA DIR.IN
				.DA DIR.IN
				.DA DIR.IN
				.DA DIR.IN
				.DA DIR.IN
				.DA DIR.IN
				.DA DIR.IN
				.DA DIR.IN
				.DA DIR.IN
				.DA DIR.IN
				.DA DIR.LI
				.DA DIR.LI
				.DA DIR.MA
				.DA DIR.OP
				.DA DIR.OR
				.DA DIR.PG
				.DA DIR.PH
				.DA DIR.PS
				.DA DIR.SE
				.DA DIR.TA
				.DA DIR.TF
				.DA DIR.TI
				.DA DIR.US
L.T.LI			.DA T.LI
J.LI			.DA DIR.LI.ON
				.DA DIR.LI.OFF
				.DA DIR.LI.CON
				.DA DIR.LI.COFF
				.DA DIR.LI.MON
				.DA DIR.LI.MOFF
				.DA DIR.LI.XON
				.DA DIR.LI.XOFF
J.EXP.MOD		.DA EXP.MOD.8.1		#/^<>
				.DA EXP.MOD.8.2
				.DA EXP.MOD.8.3
				.DA EXP.MOD.24
				.DA EXP.MOD.32
J.EXP.OP		.DA EXP.OP.EOR 		^!|&<=>+-*/
				.DA EXP.OP.ORA
				.DA EXP.OP.ORA
				.DA EXP.OP.AND
				.DA EXP.OP.LWR
				.DA EXP.OP.EQU
				.DA EXP.OP.GRT
				.DA EXP.OP.ADD
				.DA EXP.OP.SUB
				.DA EXP.OP.MUL
				.DA EXP.OP.DIV
				.DA 0
*---------------------------------------
CS.INIT			clc
				rts
*--------------------------------------
CS.RUN			jsr CS.RUN.ARGS
				bcs .9

				jsr FIO.Init
				bcs .9

				jsr SYM.Init
				bcs .9

				jsr MAC.Init
				bcs .9

				jsr OUT.Init
				bcs .9

.1				>SLEEP
				jsr CS.RUN.LOOP
				bcc .1

.9				rts
*--------------------------------------
CS.RUN.LOOP		ldy #S.PS.hStdIn
				lda (pPS),y
				>SYSCALL FEOF
				bcs .99

				tay
				bne .13

				>SYSCALL GetChar
				bcs .99

				cmp #$03				Ctrl-C
				beq .99					Abort....beq=CS

				cmp #$13				Ctrl-S
				bne .11

				>LDA.G bPause
				eor	#$ff
				sta (pData),y

				bpl .12

				clc
				rts

.13				>LDA.G bPause
				bpl .11

				clc
.99				rts

.11				>STZ.G bPause

.12				>LDA.G SRC.Depth		root file is already opened?
				bne .10

				>PUSHW L.MSG.PASS
				>LDA.G ASM.PASS
				inc
				>PUSHA
				>PUSHBI 1
				jsr OUT.Print

				>LDA.G SRC.hFILENAME
				>SYSCALL GetMemPtr
				jsr FIO.OpenFile
				bcs .99

				jsr DIR.Reset

				>STZ.G MAC.StkPtr
				>STZ.G SYM.BufPtr

.10				>LDYA ZPLineBuf
				>STYA ZPLinePtr

				>LDA.G MAC.StkPtr
				beq .20

.15				jsr MAC.ReadLine
				bcc .2

				cmp #E.EMPTYKEY
				bne .9

				jsr MAC.Pop
				bne .15

.20				jsr FIO.ReadLine
				bcc .2

				cmp #MLI.E.EOF			End Of File?
				bne .9

				jsr FIO.FileClose
				>LDA.G SRC.Depth		end of root file ?
				bne .8					no continue back to previous file

				jsr SYM.StoreGlobal		Make sure last Global flushed
				bcs .9

				>LDA.G ASM.PASS			End of pass #2 ??
				bne .1

				inc
				sta (pData),y

				clc
				rts

.1				jsr SYM.Dump

				>LDYA L.MSG.END
				>SYSCALL PutS
				lda #0					End of assembly, exit with no error
				sec
				rts

.2				jsr SRC.ParseLine
				bcs .9

				jmp OUT.PrintLine

.8				clc
				rts

.9				pha
				jsr OUT.PrintLineErr
				pla
				sec
				rts
*--------------------------------------
CS.RUN.ARGS		ldy #S.PS.ARGC
				lda (pPS),y
				beq .90

.1				inc ZPPtr1

				lda ZPPtr1
				>SYSCALL ArgV
				bcs .8

				>STYA ZPPtr2

				lda (ZPPtr2)
				cmp #'-'
				beq .2

				>PUSHW ZPPtr2
				>PUSHWZ				Allocate
				>SYSCALL RealPath
				bcs .99
				txa
				>STA.G SRC.hFILENAME
				bra .1

.2				ldy #2
				lda (ZPPtr2),y
				bne .90

				dey
				lda (ZPPtr2),y

				cmp #'a'
				bcc .20
				
				cmp #'z'+1
				bcs .20

				eor #$20

.20				cmp #'L'
				bne .3

				lda #$ff
				>STA.G bListAll
				bra .1

.3				cmp #'T'
				bne .90

				inc ZPPtr1
				lda ZPPtr1
				>SYSCALL ArgV
				bcs .90

				lda ZPPtr1
				>STA.G ArgDstFile
				bra .1

.8				>LDA.G SRC.hFILENAME
				beq .90

				clc
				rts

.90				>PUSHW L.MSG.HELP
				>PUSHBI 0
				>SYSCALL PrintF

				lda #E.INV.ARGS
				sec
.99				rts
*--------------------------------------
CS.DOEVENT		sec
				rts
*--------------------------------------
CS.QUIT			>LDA.G SRC.Depth
				beq .1

				jsr FIO.FileClose
				bra CS.QUIT

.1				>LDA.G DST.hREFNUM
				beq .2

				>SYSCALL FClose

.2				jsr MAC.Quit

				jsr SYM.Quit

				ldy #ASM.hCPUFILE
				jsr .7

				ldy #SRC.hFILENAME
				jsr .7

				ldy #DST.hFILENAME
				jsr .7

				ldy #SRC.hLineBuf
				jsr .7

				ldy #SRC.hTmpBuf

.7				lda (pData),y
				beq .8
				>SYSCALL FreeMem

.8				clc
				rts
*---------------------------------------
				.INB usr/src/bin/asm.s.dir
				.INB usr/src/bin/asm.s.exp
				.INB usr/src/bin/asm.s.fio
				.INB usr/src/bin/asm.s.mac
				.INB usr/src/bin/asm.s.out
				.INB usr/src/bin/asm.s.src
				.INB usr/src/bin/asm.s.sym
*---------------------------------------
CS.END
T.DIRECTIVES	.PS "AC"
				.PS "AS"
				.PS "AT"
				.PS "AZ"
				.PS "BS"
				.PS "CS"
				.PS "CZ"
				.PS "DA"
				.PS "DO"
				.PS "DU"
				.PS "DUMMY"
				.PS "ED"
				.PS "ELSE"
				.PS "EM"
				.PS "EN"
				.PS "EP"
				.PS "EQ"
				.PS "FIN"
				.PS "HS"
				.PS "HX"
				.PS "IN"
				.PS "INB"
				.PS "INB1"
				.PS "INB2"
				.PS "INB3"
				.PS "INB4"
				.PS "INB5"
				.PS "INB6"
				.PS "INB7"
				.PS "INB8"
				.PS "INB9"
				.PS "LI"
				.PS "LIST"
				.PS "MA"
				.PS "OP"
				.PS "OR"
				.PS "PG"
				.PS "PH"
				.PS "PS"
				.PS "SE"
				.PS "TA"
				.PS "TF"
				.PS "TI"
				.PS "US"
				.HS 00
*---------------------------------------
T.LI			.PS "ON"
				.PS "OFF"
				.PS "CON"
				.PS "COFF"
				.PS "MON"
				.PS "MOFF"
				.PS "XON"
				.PS "XOFF"
				.HS 00
*--------------------------------------
DIR.EscChars	.AS "abefnrtv"
				.HS 5C27223F25			\'"?%
DIR.EscChars.L	.EQ *-DIR.EscChars
DIR.EscCodes	.HS 07081B0C0A0D090B
				.HS 5C27223F25
*---------------------------------------
SRC.MOD.RESERVED	.PS "#/^<>"
SRC.EXP.RESERVED	.PS "^!|&<=>+-*/"
SRC.AM.RESERVED		.PS "[](),"
*---------------------------------------
DIR.SYS			.AZ "SYS"
ASM.6502		.AZ "6502"
*---------------------------------------
MSG.HELP		.CS "A2osX-Macro Assembler (S-C MASM 3.1 Dialect)\r\n"
				.CS "Usage : ASM <src file> [type TXT ($04) or S-C/BAS ($FA)]\r\n"
				.CS "   -L : Override .LIST (C,M,X)OFF\r\n"
				.CS "   -T <target file> : Override .TF directive"
MSG.CRLF		.CZ "\r\n"
MSG.PASS		.CZ "**** Pass:#%d"
MSG.SRC.FILE	.CZ "**** Reading SRC File:%s"
MSG.OBJ.FILE	.CZ "**** Writing OBJ File:%s, Type=%02x"
MSG.CPU.FILE	.CZ "**** Loading CPU File:%s"
MSG.OUT0		.CZ "%H-        "
MSG.OUT1		.CZ "%H-%h      "
MSG.OUT2		.CZ "%H-%h %h   "
MSG.OUT3		.CZ "%H-%h %h %h"
MSG.EQU0		.CZ "  [       ?] "
MSG.EQU1		.CZ "  [      %h] "
MSG.EQU2		.CZ "  [    %h%h] "
MSG.EQU3		.CZ "  [  %h%h%h] "
MSG.EQU4		.CZ "  [%h%h%h%h] "
MSG.LINENUM		.CZ " %05D "
MSG.ERROR		.CZ "**** Fatal Error $%h"
MSG.SYMBOLS		.CZ "**** Symbol Table:"
MSG.LSYMBOL		.CZ " .%d=%h%h%h%h"
MSG.PSYMBOL		.CZ " :%d(%d)=%h%h%h%h"
MSG.SUMMARY		.CZ "\r\n**** Symbol Table Size : %5D Bytes.\r\n"
MSG.END			.CZ "**** End Of Assembly."
MSG.WARN1		.CZ "**** WARN : Unoptimized adressing mode due to forward reference.\r\n"
				.DO ASMDBG=1
MSG.DBG			.CZ "\r\nCtxID=%d, ARG=%H%H <op> ACC=%H%H -> ACC %b [%h]\r\n"
				.FIN
				.DO SYMDBG=1
MSG.SYMDBG		.CZ "SymID=%H\r\n"
				.FIN
*---------------------------------------
ASM.CPU.FILE	.BS 65

SRC.ACC.SIZE	.BS 1

SRC.ACC.F		.BS 1
SRC.ACC			.BS 4
SRC.ARG.F		.BS 1
SRC.ARG			.BS 4

SRC.ACCTMP		.BS 4
SRC.AM.StrBuf	.BS 32
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
bPause			.BS 1
bListAll		.BS 1
ArgDstFile		.BS 1

SRC.hFILENAME	.BS 1
SRC.hLineBuf	.BS 1
SRC.hTmpBuf		.BS 1

SRC.Depth		.BS 1
SRC.hFILES		.BS IN.MAXDEPTH
SRC.hFILETYPES	.BS IN.MAXDEPTH

SRC.LINENUM		.BS 2
SRC.AMID		.BS 1

ASM.hCPUFILE	.BS 1

DST.hFILENAME	.BS 1
DST.hREFNUM		.BS 1
DST.AUXTYPE		.BS 2

EXP.Modifier	.BS 1
EXP.Prefix		.BS 1
EXP.Operator	.BS	1

ASM.PASS		.BS 1

ASM.DO.StackPtr	.BS 1
ASM.DO.Stack	.BS DO.MAXDEPTH

ASM.DU.ON		.BS 1
ASM.PH.ON		.BS 1

ASM.LI.ON		.BS 1
ASM.LI.CON		.BS 1
ASM.LI.MON		.BS 1
ASM.LI.XON		.BS 1

ASM.MA.ON		.BS 1

ASM.PC			.BS 4
ASM.PC.PH		.BS 4
ASM.PC.DU		.BS 4

SYM.hList		.BS 1
SYM.hBuf		.BS 1
SYM.BufPtr		.BS 1
SYM.ID			.BS 2

FWR.hList		.BS 1
FWR.ID			.BS 2

MAC.hList		.BS 1
MAC.hBuf		.BS 1
MAC.BufPtr		.BS 1
MAC.ID			.BS 2

MAC.hStk		.BS 1
MAC.StkPtr		.BS 1
MAC.hArgBuf		.BS 1
MAC.CtxID		.BS 1
MAC.CtxNextID	.BS 1
MAC.CtxStackPtr	.BS 1
MAC.CtxStack	.BS MA.MAXDEPTH

OUT.PC			.BS 4
OUT.Buf			.BS 4
OUT.bEquate		.BS 1
OUT.LineCnt		.BS 1

DS.END			.ED
*---------------------------------------
				.DO DS.END-DS.START>$FF
				ERROR:DS too big
				.FIN
*---------------------------------------
MAN
SAVE usr/src/bin/asm.s
ASM
