NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF bin/sh
*--------------------------------------
HISTORY.MAX		.EQ 256
CORE.STACK.MAX	.EQ 128
PUSHD.STACK.MAX	.EQ 4
*--------------------------------------
C...			.EQ 0
C..				.EQ 2
C.CD			.EQ 4
C.NOHUP			.EQ 6
C.DATE			.EQ 8
C.ECHO			.EQ 10
C.EXIT			.EQ 12
C.MD			.EQ 14
C.PAUSE			.EQ 16
C.PWD			.EQ 18
C.RD			.EQ 20
C.READ			.EQ 22
C.REN			.EQ 24
C.SET			.EQ 26
C.SLEEP			.EQ 28
C.SHIFT			.EQ 30
C.PUSHD			.EQ 32
C.POPD			.EQ 34
C.FUNCTION		.EQ 36
C.CALL			.EQ 38
C.BREAK			.EQ 40
C.SWITCH		.EQ 42
C.CASE			.EQ 44
C.DEFAULT		.EQ 46
*--------------------------------------
C.FOR			.EQ 48
C.FOR.LIST			.EQ 0
C.FOR.FILEEXEC		.EQ 1
C.WHILE			.EQ 50
C.IF			.EQ 52
C.NEXT			.EQ 54
C.LOOP			.EQ 56
C.ELSE			.EQ 58
C.FI			.EQ 60
C.END			.EQ 62
*--------------------------------------
C.CLEXEC		.EQ 63
*--------------------------------------
E.CSYN			.EQ $C0
E.ESYN			.EQ $C1
E.STACKERROR	.EQ $C2
E.STKOVERFLOW	.EQ $C3
E.NOWHILE		.EQ $C4
E.NOFOR			.EQ $C5
E.NOIF			.EQ $C6
E.BADFTYPE		.EQ $C7
E.FUNDEF		.EQ $C8
E.UNEXPEOF		.EQ $C9
*--------------------------------------
				.INB INC/MACROS.I
				.INB INC/A2OSX.I
				.INB INC/MLI.I
				.INB INC/MLI.E.I
*--------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ZPCLBuf			.BS 2
ZPInputBuf		.BS 2
ZPInputBufPtr	.BS 2
ZPInputCmdPtr	.BS 2
ZPArgVBuf		.BS 2
ZPArgVBufPrev	.BS 2
ZPArgVBufPtr	.BS 2
ZPVarNamePtr	.BS 2

CORE.PSFlags	.BS 1
CORE.IntCmd		.BS 1
CORE.Operator	.BS 1
CORE.LogicOp	.BS 1
CORE.TestResult	.BS 1
CORE.PrevTestResult	.BS 1

ZPPtr1			.BS 2
ZPPtr2			.BS 2
ZPTmpW			.BS 2

M32.ACC			.BS 4

ZS.END			.ED
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp (.1,x)
				.DA #$61				6502,Level 1 (65c02)
				.DA #1					BIN Layout Version 1
				.DA #S.PS.F.EVENT		S.PS.F
				.DA #0
				.DA CS.END-CS.START		Code Size (without Constants)
				.DA DS.END-DS.START		Data SegmentSize
				.DA #64					Stack Size
				.DA #ZS.END-ZS.START	Zero Page Size
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1				.DA CS.INIT
				.DA CS.RUN
				.DA CS.DOEVENT
				.DA	CS.QUIT
*--------------------------------------
L.MSG.GREETINGS	.DA MSG.GREETINGS
L.MSG.PROMPT	.DA MSG.PROMPT
L.MSG.PROMPTCRLF	.DA MSG.PROMPTCRLF
L.MSG.TRACE		.DA MSG.TRACE
L.MSG.ECHOCRLF	.DA MSG.ECHOCRLF
L.MSG.BATCHLINE	.DA MSG.BATCHLINE
L.MSG.BATCHERR	.DA MSG.BATCHERR
L.MSG.ERROR		.DA MSG.ERROR
L.MSG.PID		.DA MSG.PID
L.FMT.DATE		.DA FMT.DATE
L.FMT.Long		.DA FMT.Long
L.FMT.Byte		.DA FMT.Byte
J.ESC			.DA CL.BS			left arrow
				.DA HIS.GetNext			
				.DA HIS.GetPrev
				.DA CL.NAK			right arrow
L.CD..			.DA CD..
L.IN			.DA IN
L.CMD			.DA CMD
J.CMD			.DA CMD...
				.DA CMD..
				.DA CMD.CD
				.DA CMD.NOHUP
				.DA CMD.DATE
				.DA CMD.ECHO
				.DA CMD.EXIT
				.DA CMD.MD
				.DA CMD.PAUSE
				.DA CMD.PWD
				.DA CMD.RD
				.DA CMD.READ
				.DA CMD.REN
				.DA CMD.SET
				.DA CMD.SLEEP
				.DA CMD.SHIFT
				.DA CMD.PUSHD
				.DA CMD.POPD
				.DA CMD.FUNCTION
				.DA CMD.CALL
				.DA CMD.BREAK
				.DA CMD.SWITCH
				.DA CMD.CASE
				.DA CMD.DEFAULT
				.DA CMD.FOR
				.DA CMD.WHILE
				.DA CMD.IF
				.DA CMD.NEXT
				.DA CMD.LOOP
				.DA CMD.ELSE
				.DA CMD.FI
				.DA CMD.END
L.CORE.IO		.DA CORE.IO
J.CORE.IO		.DA CORE.IO.AMP
				.DA CORE.IO.IN
				.DA CORE.IO.OUTA
				.DA CORE.IO.OUT
				.DA CORE.IO.1OUTA
				.DA CORE.IO.1OUT
				.DA CORE.IO.2OUTA
				.DA CORE.IO.2OUT
L.EXP.BEGIN		.DA EXP.BEGIN
L.EXP.OP.UNARY	.DA EXP.OP.UNARY
J.EXP.OP.UNARY	.DA EXP.OP.UNARY.D
				.DA EXP.OP.UNARY.E
				.DA EXP.OP.UNARY.F
				.DA EXP.OP.UNARY.I
				.DA EXP.OP.UNARY.N
				.DA EXP.OP.UNARY.X
				.DA EXP.OP.UNARY.Z
L.EXP.OP.BINARY	.DA EXP.OP.BINARY
L.EXP.OP.MATH	.DA EXP.OP.MATH
L.EXP.OP.LOGIC	.DA EXP.OP.LOGIC
L.HOME.PROFILE	.DA HOME.PROFILE
L.HOME			.DA HOME
L.PS1			.DA PS1
L.ERR.Codes		.DA ERR.Codes
L.ERR.Messages	.DA ERR.Messages
				.DA 0
*--------------------------------------
CS.INIT			clc
CS.INIT.RTS		rts
*--------------------------------------
CS.RUN			jsr CL.Init
				jsr CORE.Init

				ldy #S.PS.ARGC
				lda (pPS),y
				beq .1					no arg, continue starting interactive

				lda #$ff
				>STA.G bExitOnEOF
				lda #0
				jsr CMD.SHIFTA			Remove $0=/bin/sh

				jsr GetArgV

				jsr IO.Load
				bcs CS.INIT.RTS

				jsr GetArgV

				jsr CORE.Load.YAX		Exec Batch file
				bcs CS.INIT.RTS
				lda #$C0+C..
				jsr CORE.StkPush
				bra CS.RUN.LOOP
*--------------------------------------
.1				jsr CMD.CD.HOME
				jsr HIS.Init
				bcs CS.INIT.RTS

				>PUSHW L.MSG.GREETINGS
				>PUSHB #K.VER
				>PUSHB /K.VER
				>PUSHBI 2
				>SYSCALL printf
				bcs CS.INIT.RTS

				>LDYA L.HOME.PROFILE
				jsr IO.Load
				bcs CS.RUN.LOOP			No profile...

				>LDYA L.HOME.PROFILE
				jsr CORE.Load.YAX		Exec profile and continue
				bcs CS.RUN.LOOP
				lda #$C0+C..
				jsr CORE.StkPush
*--------------------------------------
CS.RUN.LOOP		>SLEEP

.1				jsr CheckSleep
				beq .2

				ldy #S.PS.hStdIn
				lda (pPS),y
				>SYSCALL feof
				bcs .9
				tay
				bne CS.RUN.LOOP
				>SYSCALL GetChar
				bcs .9					I/O err
				cmp #3					Ctrl-C
				bne .11
				lda (pData)				batch mode ?
				beq CS.RUN.LOOP
				>LDA.G bSET.C
				beq .8
				bra CS.RUN.LOOP
.11				cmp #19					test Ctrl-s
				bne CS.RUN.LOOP

				lda #$80
				>STA.G bPause
				bra CS.RUN.LOOP
*--------------------------------------
.8				lda #3					User Interrupt
				sec
.9				rts
*--------------------------------------
.2				>LDA.G bPause
				bpl .6

.3				>SYSCALL GetChar
				bcs	.9					I/O err

				cmp #3					Ctrl-C
				bne .4

				lda (pData)				batch mode ?
				beq .5

				>LDA.G bSET.C
				beq .8

				bra .5

.4				tax
				>LDA.G bPause
				asl						$ff ?
				bpl .5					not from PAUSE command

				cpx #C.CR
				bne .5
				jsr CheckLFAfterCR		Check for any extra LF
				bcs .9 
				
.5				>STZ.G bPause
*--------------------------------------
.6				lda (pData)				batch mode ?
				bne CS.RUN.BATCH
*--------------------------------------
CS.RUN.INTERACTIVE
				jsr IO.Reset
				jsr CL.Reset

				jsr CL.PrintPrompt
				bcs .9
				>STZ.G bREAD.S
				dec
				>STA.G READ.N

.1				>SYSCALL GetChar
				bcs .9						I/O error 
.2				cmp #C.EOF				....or Ctrl-D
				beq .9					CS

				jsr CL.CHARIN

				>LDA.G CL.bReady			Something to execute ?
				bpl .1

				>PUSHW L.MSG.PROMPTCRLF
				>PUSHBI 0
				>SYSCALL printf
				bcs .9
				lda (ZPCLBuf)
				beq .8					Empty line

				jsr HIS.Add

				>LDYA ZPCLBuf
				>SYSCALL strdup
				bcs .8
				
				jsr GetArgV				Y,A=ARGV, X=strdup

				jsr CORE.Load.YAX		Exec CL
				bcs .9
				lda #$C0+C.CLEXEC
				jsr CORE.StkPush

				jsr CORE.Run

.8				jmp CS.RUN.LOOP.END

.9				rts			
*--------------------------------------
CS.RUN.BATCH	>LDA.G bSET.X
				beq .5

				ldy #$ff

.3				iny
				lda (ZPInputBufPtr),y
				sta (ZPCLBuf),y
				beq .4

				eor #C.CR
				bne .3

				sta (ZPCLBuf),y

.4				>PUSHW L.MSG.TRACE
				>PUSHW ZPCLBuf
				>PUSHBI 2
				>SYSCALL printf
				bcs CS.RUN.LOOP.RTS

.5				jsr CORE.Run

CS.RUN.LOOP.END	ldy #S.PS.RC
				sta (pPs),y
				bcc CS.RUN.LOOP.80
				tay
				beq CS.RUN.LOOP.80		0 = EOF

				>LDA.G bSET.E
				bmi CS.RUN.LOOP.80

.1				jsr CORE.StkGet
				cmp #$C0+C.CLEXEC
				beq .8

				cmp #$C0+C..			in . ?
				beq .7

				cmp #$C0+C.CALL			in CALL ?
				beq .7
				
				jsr CORE.StkPopCtx
				bcc .1

.7				jsr IO.PrintBatchErrMsg
				bcs CS.RUN.LOOP.RTS
				
				jsr CORE.StkPull
				jsr CMD.EXIT.FILE

.8				jsr IO.PrintErrMsg
				bcs CS.RUN.LOOP.RTS

CS.RUN.LOOP.80	lda (pData)				something on stack ?
				bne CS.RUN.LOOP.88

				>LDA.G bExitOnEOF
				bmi CS.RUN.LOOP.EXIT

CS.RUN.LOOP.88	jmp CS.RUN.LOOP
CS.RUN.LOOP.EXIT
				ldy #S.PS.RC
				lda (pPs),y
				sec
CS.RUN.LOOP.RTS	rts
*--------------------------------------
CS.DOEVENT		lda (pEvent)
				bpl .9

				jsr CheckSleep
				beq .9

*				ldy #Sleep				already set by CheckSleep
				ldx #4
				clc
.1				lda (pData),y
				sbc #0
				sta (pData),y
				iny
				dex
				bne .1

.9				sec
				rts
*--------------------------------------
CS.QUIT			jsr CORE.FUNCRESET

				>LDA.G HIS.hBuf
				beq .1
	
				>SYSCALL FreeStkObj

.1				ldy #CL.hCLBuf
				jsr .7

				ldy #CORE.hArgVBuf

.7				lda (pData),y
				beq .8
				
				>SYSCALL FreeMem
				
.8				clc
				rts
*--------------------------------------
GetCWD			phx
				ldy #S.PS.hCWD
				bra GetArgV.1
*--------------------------------------
GetArgV			phx
				ldy #S.PS.hARGV

GetArgV.1		lda (pPS),y
				>SYSCALL GetMemPtr
				plx
				rts
*--------------------------------------
CheckLFAfterCR	ldy #S.PS.hStdIn		Check for any extra LF
				lda (pPS),y
				>SYSCALL feof
				bcs .9
				
				tay
				bne .9
				>SYSCALL GetChar
				
.9				rts
*--------------------------------------
CheckSleep		ldy #Sleep+3
				lda (pData),y
				dey
				ora (pData),y
				dey
				ora (pData),y
				dey
				ora (pData),y
				rts
*--------------------------------------
GetPtr1NextChar	lda (ZPPtr1)
				beq IncPtr1.8

IncPtr1			inc ZPPtr1
				bne IncPtr1.8
				inc ZPPtr1+1
IncPtr1.8		rts
*--------------------------------------
GetPtr1LenY		ldy #$ff
.1				iny
				lda (ZPPtr1),y
				bne .1
				rts
*--------------------------------------
GetPtr1NextString
				jsr GetPtr1LenY
*--------------------------------------
				tya
AddAp1Ptr1		sec

				adc ZPPtr1
				sta ZPPtr1
				bcc .8
				inc ZPPtr1+1
.8				rts
*--------------------------------------
ToUpperCase		cmp #'a'
				bcc .8
				cmp #'z'+1
				bcs .8
				eor #$20
.8				clc						exit CC to allow Jmp to
				rts
*--------------------------------------
IncPStack4		inc pStack
IncPStack3		inc pStack
				inc pStack
				inc pStack
				rts
*--------------------------------------
				.INB USR/SRC/BIN/SH.S.CL
				.INB USR/SRC/BIN/SH.S.HIS
				.INB USR/SRC/BIN/SH.S.CORE
				.INB USR/SRC/BIN/SH.S.IO
				.INB USR/SRC/BIN/SH.S.CMD
				.INB USR/SRC/BIN/SH.S.EXP
*--------------------------------------
CS.END
*--------------------------------------
MSG.GREETINGS	.AZ "\r\nA2osX-SH %d.%d\r\n\r\n"
MSG.PROMPT		.AZ "\e[?7h$ "			Enable Line Wrap
MSG.PROMPTCRLF	.AZ "\e[?7l\r\n"		Disable Line Wrap
MSG.TRACE		.AS ">"
MSG.BATCHLINE	.AZ "%s\r\n"
MSG.BATCHERR	.AZ "%s^\r\nLine #%D:"
MSG.ERROR		.AS "[$%h]:%S."
MSG.ECHOCRLF	.AZ "\r\n"
MSG.PID			.AZ "PID=%d\r\n"
FMT.DATE		.AZ "%A, %B %d %Y %H:%M:%S"
FMT.Long		.AZ "%L"
FMT.Byte		.AZ "%d"
*--------------------------------------
HOME.PROFILE	.AZ "${HOME}profile"
				.HS 00					To Make It ArgV
PS1				.AZ "${PS1}"
HOME			.AZ "${HOME}"
*--------------------------------------
EscChars		.AS 'DBAC'
EscChars.Cnt	.EQ *-EscChars
EscChars.Remap	.DA #C.BS,#C.VT,#C.LF,#C.FS
*--------------------------------------
CD..			.AZ ".."
*--------------------------------------
IN				.AZ "IN"
*--------------------------------------
CMD				.AT ".."
				.AT "."
				.AT "CD"
				.AT "NOHUP"
				.AT "DATE"
				.AT "ECHO"
				.AT "EXIT"
				.AT "MD"
				.AT "PAUSE"
				.AT "PWD"
				.AT "RD"
				.AT "READ"
				.AT "REN"
				.AT "SET"
				.AT "SLEEP"
				.AT "SHIFT"
				.AT "PUSHD"
				.AT "POPD"
				.AT "FUNCTION"
				.AT "CALL"
				.AT "BREAK"
				.AT "SWITCH"
				.AT "CASE"
				.AT "DEFAULT"
				.AT "FOR"
				.AT "WHILE"
				.AT "IF"
				.AT "NEXT"
				.AT "LOOP"
				.AT "ELSE"
				.AT "FI"
				.AT "END"
				.HS 00
CORE.IO			.AT "&"
				.AT "<"
				.AT ">>"
				.AT ">"
				.AT "1>>"
				.AT "1>"
				.AT "2>>"
				.AT "2>"
				.HS 00
EXP.BEGIN		.AT "!["
				.AT "["
				.HS 00
EXP.OP.UNARY	.AT "-D"
				.AT "-E"
				.AT "-F"
				.AT "-I"
				.AT "-N"
				.AT "-X"
				.AT "-Z"
				.HS 00
EXP.OP.BINARY	.AT "="
				.AT "!="
				.AT ".<"
				.AT "<="
				.AT ".>"
				.AT ">="
				.AT "-EQ"
				.AT "-NE"
				.AT "-LT"
				.AT "-LE"
				.AT "-GT"
				.AT "-GE"
				.HS 00
EXP.OP.MATH		.AT "+"
				.AT "-"
				.AT "*"
				.AT "/"
				.AT "MOD"
				.HS 00
EXP.OP.LOGIC	.AT "AND"
				.AT "OR"
				.HS 00
*--------------------------------------
EXP.OP.BINARY.BITS
				.DA #%010
				.DA #%101
				.DA #%100
				.DA #%110
				.DA #%001
				.DA #%011

				.DA #%010
				.DA #%101
				.DA #%100
				.DA #%110
				.DA #%001
				.DA #%011

EXP.OP.MATH.FPU	.DA #FPU.ADD32,#FPU.SUB32,#FPU.IMUL32,#FPU.IDIV32,#FPU.IMOD32
*--------------------------------------
SET.FLAGS		.AS "CXE"
SET.VARS		.DA #bSET.C,#bSET.X,#bSET.E
*--------------------------------------
				.INB USR/SRC/SHARED/X.ERRORS.S
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
CORE.STACK		.BS CORE.STACK.MAX+1	pData (0 = Stack Ptr)
PUSHD.STACK		.BS PUSHD.STACK.MAX+1

hFuncList		.BS 1

bExitOnEOF		.BS 1

bPause			.BS 1

bSET.C			.BS 1
bSET.E			.BS 1
bSET.X			.BS 1

bREAD.S			.BS 1
READ.N			.BS 1

Sleep			.BS 4

CL.hCLBuf		.BS 1
CL.Ptr			.BS 1
CL.Len			.BS 1
CL.bReady		.BS 1
CL.bEscMode		.BS 1

CORE.hArgVBuf	.BS 1
CORE.bPipeIn	.BS 1
CORE.bPipeOut	.BS 1

HIS.hBuf		.BS 1
HIS.Count		.BS 1
HIS.Index		.BS 1

IO.hIn			.BS 1
IO.hOut			.BS 1
IO.hErr			.BS 1

*TimeBuf			.BS S.TIME				8 bytes
*M32.BUF		.BS 12					-1234567890\0
TimeBuf			.EQ *
M32.BUF			.EQ *
IO.FIFO			.BS 12					/DEV/FIFOxx\0
*--------------------------------------
DS.END			.ED
*--------------------------------------
MAN
SAVE USR/SRC/BIN/SH.S
ASM
