NEW
PREFIX
AUTO 4,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF BIN/SH
*--------------------------------------
HISTORY.MAX		.EQ 256
CORE.STACK.MAX	.EQ 128
PUSHD.STACK.MAX	.EQ 8
*--------------------------------------
C...			.EQ 0
C..				.EQ 1
C.CD			.EQ 2
C.NOHUP			.EQ 3
C.DATE			.EQ 4
C.ECHO			.EQ 5
C.EXIT			.EQ 6
C.GETKEY		.EQ 7
C.MD			.EQ 8
C.PAUSE			.EQ 9
C.PWD			.EQ 10
C.RD			.EQ 11
C.READ			.EQ 12
C.REN			.EQ 13
C.SET			.EQ 14
C.SLEEP			.EQ 15
C.SHIFT			.EQ 16
C.TIME			.EQ 17
C.PUSHD			.EQ 18
C.POPD			.EQ 19
C.FUNC			.EQ 20
C.CALL			.EQ 21
C.BREAK			.EQ 22
C.SWITCH		.EQ 23
C.CASE			.EQ 24
C.DEFAULT		.EQ 25
*--------------------------------------
C.FOR			.EQ 26
C.FOR.LIST			.EQ 0
C.FOR.FILE			.EQ 2
C.FOR.EXEC			.EQ 4
C.WHILE			.EQ 27
C.IF			.EQ 28
C.NEXT			.EQ 29
C.LOOP			.EQ 30
C.ELSE			.EQ 31
C.FI			.EQ 32
C.END			.EQ 33
*--------------------------------------
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.BADEXP		.EQ $C7
E.BADFTYPE		.EQ $C8
E.FUNDEF		.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

M32.ACC			.BS 4
M32.ARG			.BS 4
M32.TMP			.BS 4

ZPPtr1			.BS 2
ZPPtr2			.BS 2

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.PRINTENV	.DA MSG.PRINTENV
L.MSG.PID		.DA MSG.PID
L.FMT.DATE		.DA FMT.DATE
L.FMT.TIME		.DA FMT.TIME
L.FMT.GETKEY	.DA FMT.GETKEY
J.ESC			.DA CL.BS			left arrow
				.DA HIS.GetNext			
				.DA HIS.GetPrev
				.DA CL.NAK			right arow
L.IN			.DA IN
L.CMD			.DA CMD
L.ENDCMD		.DA ENDCMD
J.CMD			.DA CMD...
				.DA CMD..
				.DA CMD.CD
				.DA CMD.NOHUP
				.DA CMD.DATE
				.DA CMD.ECHO
				.DA CMD.EXIT
				.DA CMD.GETKEY
				.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.TIME
				.DA CMD.PUSHD
				.DA CMD.POPD
				.DA CMD.FUNC
				.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
J.NEXT			.DA CMD.NEXT.LIST
				.DA CMD.NEXT.FILE
				.DA CMD.NEXT.EXEC				
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.N
				.DA EXP.OP.UNARY.Z
L.EXP.OP.BINARY	.DA EXP.OP.BINARY
L.EXP.OP.MATH	.DA EXP.OP.MATH
J.EXP.OP.MATH	.DA M32.Add
				.DA M32.Sub
				.DA M32.Mul
				.DA M32.Div
				.DA M32.Mod
L.EXP.OP.LOGIC	.DA EXP.OP.LOGIC
L.HOME			.DA HOME
L.HOME.PROFILE	.DA HOME.PROFILE
L.PS1			.DA PS1
L.M32.Printf	.DA M32.Printf
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

				ldy #S.PS.hARGV
				lda (pPS),y
				>SYSCALL GetMemPtr

				jsr IO.Load
				bcs CS.INIT.RTS
				phx
				ldy #S.PS.hARGV
				lda (pPS),y
				>SYSCALL GetMemPtr
				plx
				jsr CMD.CALL.YAX
				bra CS.RUN.LOOP
*--------------------------------------
.1				jsr CMD.CD.HOME
				jsr HIS.Init
				bcs CS.INIT.RTS

				>PUSHWI K.VER
				>PUSHBI 2
				>LDYA L.MSG.GREETINGS
				>SYSCALL printf
				bcs CS.INIT.RTS
				
				>PUSHEA.G StatBuf
				>LDYA L.HOME.PROFILE
				>SYSCALL STAT
				bcs CS.RUN.LOOP			no profile...

				>LDYA L.HOME.PROFILE
				jsr IO.Load
				bcs CS.RUN.LOOP
				>LDYA L.HOME.PROFILE
				jsr CMD.CALL.YAX		exec profile and continue
				
*				bcs CS.RUN.LOOP
*--------------------------------------
CS.RUN.LOOP		>SLEEP

.1				jsr CheckSleep
				beq .3

				>LDA.G bSET.C
				bne CS.RUN.LOOP

				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 CS.RUN.LOOP
				
				lda (pData)				batch mode ?
				beq CS.RUN.LOOP
				
				>LDA.G bSET.C
				beq .8
				bra CS.RUN.LOOP

.3				>LDA.G bPause
				bpl .6
				
.4				>SYSCALL GetChar
				bcs	.9					I/O err
				
.5				cmp #3					Ctrl-C
				bne .60
				
				lda (pData)				batch mode ?
				beq .61
				
				>LDA.G bSET.C
				beq .8
				bra .61
				
.60				tax
				
				>LDA.G bPause
				asl
				bpl .61					not from PAUSE command
				
				cpx #C.CR
				bne .4
				
.61				>STZ.G bPause
				bra .62

.6				>LDA.G bReadMode		read mode ?
				bne .7
				
.62				lda (pData)				batch mode ?
				beq CS.RUN.INTERACTIVE
				
				jmp CS.RUN.BATCH
.7				jmp CS.RUN.READ

.8				lda #3					User Interrupt
				sec
.9				rts
*--------------------------------------
CS.RUN.INTERACTIVE
				>LDA.G bExitOnEOF
				beq .10

				jmp CS.RUN.LOOP.EXIT
				
.10				jsr IO.Reset
				jsr CL.Reset
				jsr CL.PrintPrompt
				bcs .9

.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
				
				>PUSHBI 0
				>LDYA L.MSG.PROMPTCRLF
				>SYSCALL printf
				bcs .9
				
				lda (ZPCLBuf)
				beq .8					Empty line

				jsr HIS.Add

				>LDYA ZPCLBuf
				>SYSCALL strdup
				bcs .8
				
				phx
				
				ldy #S.PS.hARGV
				lda (pPS),y
				>SYSCALL GetMemPtr		Y,A =ARGV
				
				plx
				jsr CMD.CALL.YAX		X = Copy of CL

.6				jsr CORE.Run
				
.8				jmp CS.RUN.LOOP.END

.9				rts			
*--------------------------------------
CS.RUN.READ		jsr CL.RESET
				
.1				>SYSCALL GetChar
				bcs CS.RUN.READ.9

				jsr CL.CHARIN

				>LDA.G CL.bReady
				bpl .1

				lda (ZPCLBuf)
				bne .2
				
				>LDYA ZPVarNamePtr
				>SYSCALL UnSetEnv
				bra .7
				
.2				>PUSHW ZPCLBuf

				>LDYA ZPVarNamePtr
				>SYSCALL SetEnv
				
.7				php
				pha

				>STZ.G bReadMode
				>STA.G bREAD.S
				
				pla
				plp
				
.8				jmp CS.RUN.LOOP.END
CS.RUN.READ.9	rts
*--------------------------------------
CS.RUN.BATCH	>LDA.G bSET.C
				bne .2

				ldy #S.PS.hStdIn
				lda (pPS),y
				>SYSCALL feof
				bcs .2					unsupported
				
				tay
				bne .2
				
				>SYSCALL GetChar
				bcs CS.RUN.READ.9
				
				cmp #3					test Ctrl-c
				bne .1

				bra CS.RUN.LOOP.END		CS

.1				cmp #19					test Ctrl-s
				bne .2

				lda #$80
				>STA.G bPause
				clc
				jmp CS.RUN.LOOP.END

.2				>LDA.G bSET.X
				beq .5

				ldy #$ff
				
.3				iny
				lda (ZPInputBufPtr),y
				sta (ZPArgVBuf),y
				beq .4
				eor #C.CR
				bne .3
				sta (ZPArgVBuf),y
				
.4				>PUSHW ZPArgVBuf
				>PUSHBI 2
				>LDYA L.MSG.TRACE
				>SYSCALL printf
				bcs CS.RUN.LOOP.RTS

.5				jsr CORE.Run
				bcc CS.RUN.LOOP.END

				tay							0 = EOF
				bne CS.RUN.LOOP.END

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

				>LDA.G bSET.E
				bmi CS.RUN.LOOP.80
				jsr IO.PrintBatchErrMsg
				bcs CS.RUN.LOOP.RTS
				
				ldy #S.PS.RC
				lda (pPs),y
				
				jsr IO.PrintErrMsg
				bcs CS.RUN.LOOP.RTS

CS.RUN.LOOP.80	lda (pData)
				bne .8
				
				>LDA.G bExitOnEOF
				bmi CS.RUN.LOOP.EXIT

.8				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 HIS.Quit
				jsr CL.Quit
				jsr CORE.Quit
				clc
				rts
*--------------------------------------
CheckSleep		ldy #Sleep+3
				lda (pData),y
				dey
				ora (pData),y
				dey
				ora (pData),y
				dey
				ora (pData),y
				rts
*--------------------------------------
RemoveStrFromArgV
				>STYA ZPPtr1
				>STYA ZPPtr2

				ldy #$ff
				
.1				iny						Compute ArgX len
				lda (ZPPtr1),y			
				bne .1
				
.2				tya
				sec
				adc ZPPtr1
				sta ZPPtr1
				bcc .3
				inc ZPPtr1+1
				
.3				ldy #$ff
				
.4				iny
				lda (ZPPtr1),y
				sta (ZPPtr2),y
				bne .4
				tya
				beq .8
				
				sec
				adc ZPPtr2
				sta ZPPtr2
				bcc .2
				inc ZPPtr2+1
				bra .2
				
.8				rts
*--------------------------------------
ToUpperCase		cmp #'a'
				bcc .8
				cmp #'z'+1
				bcs .8
				eor #$20
				
.8				clc						exit CC to allow Jmp to
				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.PRINTENV	.AZ "%s = %s\r\n"
MSG.PID			.AZ "PID=%d\r\n"
FMT.DATE		.AZ "%A (%w), %B %d %Y"
FMT.TIME		.AZ "%H:%M:%S (%I:%M:%S%p)"
FMT.GETKEY		.AZ "%d"		
*--------------------------------------
HOME			.AZ "${HOME}"
HOME.PROFILE	.AZ "${HOME}PROFILE"
PS1				.AZ "${PS1}"
				.HS 00					To Make It ArgV
*--------------------------------------
IN				.AZ "IN"
*--------------------------------------
CMD				.AZ ".."
				.AZ "."
				.AZ "CD"
				.AZ "NOHUP"
				.AZ "DATE"
				.AZ "ECHO"
				.AZ "EXIT"
				.AZ "GETKEY"
				.AZ "MD"
				.AZ "PAUSE"
				.AZ "PWD"
				.AZ "RD"
				.AZ "READ"
				.AZ "REN"
				.AZ "SET"
				.AZ "SLEEP"
				.AZ "SHIFT"
				.AZ "TIME"
				.AZ "PUSHD"
				.AZ "POPD"
				.AZ "FUNC"
				.AZ "CALL"
				.AZ "BREAK"
				.AZ "SWITCH"
				.AZ "CASE"
				.AZ "DEFAULT"
				.AZ "FOR"
				.AZ "WHILE"
				.AZ "IF"
				.AZ "NEXT"
				.AZ "LOOP"
				.AZ "ELSE"
				.AZ "FI"
ENDCMD			.AZ "END"
				.HS 00
*--------------------------------------
* https://www.tldp.org/LDP/abs/html/io-redirection.html
*--------------------------------------
CORE.IO			.AZ "&"
				.AZ "<"
				.AZ ">>"
				.AZ ">"
				.AZ "1>>"
				.AZ "1>"
				.AZ "2>>"
				.AZ "2>"
				.HS 00
*--------------------------------------
EXP.BEGIN		.AZ "!["
				.AZ "["
				.HS 00
EXP.OP.UNARY	.AZ "-D"
				.AZ "-E"
				.AZ "-F"
				.AZ "-N"
				.AZ "-Z"
				.HS 00
EXP.OP.BINARY	.AZ "="
				.AZ "!="
				.AZ ".<"
				.AZ "<="
				.AZ ".>"
				.AZ ">="
				.AZ "-EQ"
				.AZ "-NE"
				.AZ "-LT"
				.AZ "-LE"
				.AZ "-GT"
				.AZ "-GE"
				.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		.AZ "+"
				.AZ "-"
				.AZ "*"
				.AZ "/"
				.AZ "MOD"
				.HS 00
EXP.OP.LOGIC	.AZ "AND"
				.AZ "OR"
				.HS 00
*--------------------------------------
				.INB USR/SRC/SHARED/X.M32.S
				.INB USR/SRC/SHARED/X.ERRORS.S
*--------------------------------------
EscChars		.AS 'DBAC'
EscChars.Cnt	.EQ *-EscChars
EscChars.Remap	.DA #C.BS,#C.VT,#C.LF,#C.FS
M32.Printf		.AZ "%L"
*--------------------------------------
				.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

bReadMode		.BS 1
bFuncMode		.BS 1
bExitOnEOF		.BS 1

bEscMode		.BS 1
bPause			.BS 1

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

bREAD.S			.BS 1

Sleep			.BS 4
StatBuf			.BS S.STAT
TimeBuf			.BS S.TIME

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

CORE.IntCmd		.BS 1
CORE.hArgVBuf	.BS 1

CORE.PSFlags	.BS 1
CORE.ArgIndex	.BS 1
CORE.Test		.BS 1
CORE.TestOp		.BS 1
CORE.TestArg	.BS 1
CORE.Operator	.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

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