NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR $2000
				.TF	bin/asm
*---------------------------------------
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

ZPPtr1			.BS 2
ZPPtr2			.BS 2

ZS.END			.ED
*---------------------------------------
* Symbols
*---------------------------------------
SYMG.F			.EQ 0
SYMG.F.FWREF		.EQ %10000000
SYMG.F.RW			.EQ %01000000
SYMG.F.LOCALS		.EQ %00100000
SYMG.SIZE		.EQ 1					1,2,3,4
SYMG.V			.EQ 2
*
SYMG			.EQ 6 					DWORD
*---------------------------------------
SYML.ID			.EQ 0					1..255
SYML.MacroID	.EQ 1
SYML.V			.EQ 2					DWORD
*
SYML			.EQ 6
*---------------------------------------
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.INV.OPCODE	.EQ $A6
E.INV.AM.SYN	.EQ $A7
E.INV.AM		.EQ $A8
E.INV.AM.4.OC	.EQ $A9
E.RANGE			.EQ $AA
E.UNDEF.SYMBOL	.EQ $AB
E.SYMBOL.REDEF	.EQ $AC
E.TOO.MANY.DO	.EQ $AD
E.ELSE.WITHOUT.DO	.EQ $AE
E.TOO.MANY.LOCAL	.EQ $AF
E.MISSING.EXP	.EQ $B0
E.EXP.SYN.ERROR	.EQ $B1
E.MACRO.INV.DEF	.EQ $B2
E.MACRO.TOO.BIG	.EQ $B3
E.MACRO.INV		.EQ $B4
E.MACRO.TOO.MANY	.EQ $B5
*
E.INV.ARGS		.EQ $BA
E.INV.T.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.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.PSTR		.DA MSG.PSTR
L.MSG.CRLF		.DA MSG.CRLF
L.MSG.WORD		.DA MSG.WORD
L.MSG.ACC		.DA MSG.ACC
L.MSG.SRC.FILE	.DA MSG.SRC.FILE
L.MSG.OBJ.FILE	.DA MSG.OBJ.FILE
L.MSG.T.FILE	.DA MSG.T.FILE
L.SRC.AM.StrBuf	.DA SRC.AM.StrBuf
L.ASM.6502		.DA ASM.6502
L.ASM.CPU.FILE	.DA ASM.CPU.FILE
L.FIO.Stat		.DA FIO.Stat
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.DA
				.DA DIR.DO
				.DA DIR.DU
				.DA DIR.DU
				.DA DIR.ED
				.DA DIR.EL
				.DA DIR.EM
				.DA DIR.EN
				.DA DIR.EP
				.DA DIR.EQ
				.DA DIR.FI
				.DA DIR.HS
				.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.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.LOW
				.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			ldy #S.PS.ARGC
				lda (pPs),y
				beq .99

				lda #1
				>SYSCALL ArgV
				>PUSHYA
				>PUSHWI 0				Allocate
				>SYSCALL RealPath
				txa
				>STA.G SRC.hFILENAME

				jsr FIO.Init
				bcs .9

				jsr SYM.Init
				bcs .9

				jsr MAC.Init
				bcs .9

				jsr OUT.Init

				>LDYAI 256
				>SYSCALL getmem
				bcs .9
				>STYA ZPLineBuf
				txa
				>STA.G SRC.hLineBuf

				>LDYAI 256
				>SYSCALL getmem
				bcs .9
				>STYA ZPTmpBuf
				txa
				>STA.G SRC.hTmpBuf
				
				clc
				rts
				
.99				>PUSHW L.MSG.HELP
				>PUSHBI 0
				>SYSCALL printf
				lda #E.INV.ARGS
				sec
.9				rts
*--------------------------------------
CS.RUN			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.COUNT		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
				jsr SYM.Reset
				jsr MAC.Reset
				
.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.COUNT		end of root file ?
				bne .8					no continue back to previous file

				jsr SYM.StoreGlobal		Make sure last Global flushed

				>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
				
				jsr OUT.PrintLine
.8				clc
				rts

.9				pha
				jsr OUT.PrintLineErr

				jsr SYM.StoreGlobal		Make sure last Global flushed
				jsr SYM.Dump
				pla
				sec
				rts
*--------------------------------------
CS.DOEVENT		sec
				rts
*--------------------------------------
CS.QUIT			jsr FIO.FileClose
				bne CS.QUIT 

				jsr MAC.Quit

				jsr SYM.Quit
				
				ldy #ASM.T.hMem
				jsr .7

				ldy #SRC.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	>PSTR "AC"
				>PSTR "AS"
				>PSTR "AT"
				>PSTR "AZ"
				>PSTR "BS"
				>PSTR "DA"
				>PSTR "DO"
				>PSTR "DU"
				>PSTR "DUMMY"
				>PSTR "ED"
				>PSTR "ELSE"
				>PSTR "EM"
				>PSTR "EN"
				>PSTR "EP"
				>PSTR "EQ"
				>PSTR "FIN"
				>PSTR "HS"
				>PSTR "IN"
				>PSTR "INB"
				>PSTR "INB1"
				>PSTR "INB2"
				>PSTR "INB3"
				>PSTR "INB4"
				>PSTR "INB5"
				>PSTR "INB6"
				>PSTR "INB7"
				>PSTR "INB8"
				>PSTR "INB9"
				>PSTR "LI"
				>PSTR "LIST"
				>PSTR "MA"
				>PSTR "OP"
				>PSTR "OR"
				>PSTR "PG"
				>PSTR "PH"
				>PSTR "SE"
				>PSTR "TA"
				>PSTR "TF"
				>PSTR "TI"
				>PSTR "US"
				.HS 00
*---------------------------------------
T.LI			>PSTR "ON"
				>PSTR "OFF"
				>PSTR "CON"
				>PSTR "COFF"
				>PSTR "MON"
				>PSTR "MOFF"
				>PSTR "XON"
				>PSTR "XOFF"
				.HS 00
*---------------------------------------
SRC.MOD.RESERVED	>PSTR "#/^<>"
SRC.EXP.RESERVED	>PSTR "^!|&<=>+-*/"
SRC.AM.RESERVED		>PSTR "[](),"
*---------------------------------------
ASM.6502		.AZ "6502"
MSG.HELP		.AS "A2osX-Macro Assembler (S-C MASM 3.0 Based)\r\n"
				.AS "Usage : ASM <src file> [type TXT ($04) or S-C/BAS ($FA)]\r\n"
				.AS "   -L : Override .LIST (C,M,X)OFF\r\n"
				.AZ "   -T <target file> : Override .TF directive\r\n"
MSG.PASS		.AZ "**** Pass:#%d ****"
MSG.SRC.FILE	.AZ "**** Reading SRC File:%s"
MSG.OBJ.FILE	.AZ "**** Writing OBJ File:%s, Type=%02x"
MSG.T.FILE		.AZ "**** Loading CPU File:%s"
MSG.OUT0		.AZ "%H-        "
MSG.OUT1		.AZ "%H-%h      "
MSG.OUT2		.AZ "%H-%h %h   "
MSG.OUT3		.AZ "%H-%h %h %h"
MSG.EQU0		.AZ "  [       ?] "
MSG.EQU1		.AZ "  [      %h] "
MSG.EQU2		.AZ "  [    %h%h] "
MSG.EQU3		.AZ "  [  %h%h%h] "
MSG.EQU4		.AZ "  [%h%h%h%h] "
MSG.LINENUM		.AZ " %05D "
MSG.ERROR		.AZ "**** Fatal Error $%h"
MSG.SYMBOLS		.AZ "Symbol Table:"
MSG.LSYMBOL		.AZ " .%d=%h%h%h%h"
MSG.PSYMBOL		.AZ " :%d(%d)=%h%h%h%h"
MSG.SUMMARY		.AZ "\r\nSymbol Table Size : %5D Bytes.\r\n"
MSG.END			.AZ "End Of Assembly."
MSG.PSTR		.AS "{%S}"
MSG.CRLF		.AZ "\r\n"
MSG.WORD		.AZ ">$%H"
MSG.ACC			.AZ "%b,%d,%h%h%h%h\r\n"
*---------------------------------------
ASM.CPU.FILE	.BS 65

FIO.Stat		.BS S.STAT

SRC.ACC.F		.BS 1
SRC.ACC.SIZE	.BS 1
SRC.ACC			.BS 4

SRC.ARG.SIZE	.BS 1
SRC.ARG			.BS 4

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

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

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

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

DST.hFILENAME	.BS 1
DST.hREFNUM		.BS 1
DST.hBUFFER		.BS 1
DST.hFILETYPE	.BS 1

DIR.Word		.BS 2
DIR.Byte		.BS 1

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

ASM.T.hMem		.BS 1

ASM.PASS		.BS 1

ASM.DO.ON		.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.bInGlobal	.BS 1
SYM.GlobalID	.BS 2
SYM.hGlobalBuf	.BS 1
SYM.GlobalPtr	.BS 1

SYM.LookupID	.BS 2

MAC.hList		.BS 1
MAC.hBuf		.BS 1
MAC.BufPtr		.BS 1
MAC.hStk		.BS 1
MAC.StkPtr		.BS 1
MAC.hArgBuf		.BS 1
MAC.CtxID		.BS 1
MAC.ID			.BS 2
MAC.Depth		.BS 1
MAC.CtxIDS		.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
