NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF bin/sh
*--------------------------------------
HISCNT.MAX		.EQ 10
HISBUF.MAX		.EQ 256
CORE.STACK.MAX	.EQ 128
PUSHD.STACK.MAX	.EQ 4
CODE.STACK.MAX	.EQ 4
*--------------------------------------
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.MD			.EQ 7
C.PAUSE			.EQ 8
C.PWD			.EQ 9
C.RD			.EQ 10
C.READ			.EQ 11
C.REN			.EQ 12
C.SET			.EQ 13
C.SLEEP			.EQ 14
C.SHIFT			.EQ 15
C.PUSHD			.EQ 16
C.POPD			.EQ 17
C.FUNCTION		.EQ 18
C.CALL			.EQ 19
C.BREAK			.EQ 20
C.SWITCH		.EQ 21
C.CASE			.EQ 22
C.DEFAULT		.EQ 23
*--------------------------------------
C.FOR			.EQ 24
C.FOR.LIST			.EQ 0
C.FOR.FILEEXEC		.EQ 1
C.WHILE			.EQ 25
C.IF			.EQ 26
C.NEXT			.EQ 27
C.LOOP			.EQ 28
C.ELSE			.EQ 29
C.FI			.EQ 30
C.END			.EQ 31
C.ALIAS			.EQ 32
*--------------------------------------
C.CLEXEC		.EQ 63
*--------------------------------------
				.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
ZPTmpW			.BS 2

ZPPtr1			.BS 2
ZPPtr2			.BS 2

LOAD.hCode		.BS 1
LOAD.hArgs		.BS 1
LOAD.ArgCnt		.BS 1

bState			.BS 1

bState.ExitOnEOF	.EQ %10000000
bState.Pause		.EQ %01000000
bState.PipeIn		.EQ %00100000
bState.PipeOut		.EQ %00010000

bState.SET.C		.EQ %00000100
bState.SET.E		.EQ %00000010
bState.SET.X		.EQ %00000001

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.HIS		.DA MSG.HIS
L.MSG.HISPROMPT	.DA MSG.HISPROMPT
L.MSG.HISROMPTCLR	.DA MSG.HISROMPTCLR
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.MSG.ALIAS		.DA MSG.ALIAS
L.MSG.FS		.DA MSG.FS
L.FMT.DATE		.DA FMT.DATE
L.FMT.Long		.DA FMT.Long
L.FMT.Byte		.DA FMT.Byte
J.ESC			.DA CL.BS
				.DA HIS.GetPrev		up
				.DA HIS.GetNext		down
				.DA CL.FS
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
				.DA CMD.ALIAS
L.CORE.IO		.DA CORE.IO
J.CORE.IO		.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.PtrZero		.DA PtrZero
L.PS1			.DA PS1
L.HOME			.DA HOME
L.EXECC			.DA EXECC
				.DA 0
*--------------------------------------
CS.INIT			clc
				rts
*--------------------------------------
CS.RUN			jsr CL.Init
				jsr CORE.Init

*				lda #0
*				jsr GetArgV
*				>STYA.G SH

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

				lda #bState.ExitOnEOF
				tsb bState

				lda #0
				jsr CMD.SHIFTA			Remove $0 = /bin/sh

				jsr GetArgV
				>STYA ZPPtr1

				lda (ZPPtr1)
				cmp #'-'
				bne .1

				ldy #1
				lda (ZPPtr1),y
				jsr ToUpperCase

				cmp #'C'
				bne .19

				iny
				lda (ZPPtr1),y
				bne .19

*				lda #0
				jsr CMD.SHIFTA			Remove $0 = -C

				jsr GetArgV
				jmp CS.RUN.CMDLINE

.19				lda #E.CSYN
				sec
				rts
*--------------------------------------
.1				jsr GetArgV				Load SH batch file
				>SYSCALL LoadTxtFile
				bcs .9

				phx						X = loaded file hMem
				jsr GetArgV				Y,A = Args
				plx
				jsr CMD..EXEC.YAX		Execute . Batch file
				bcc CS.RUN.LOOP

.9				rts
*--------------------------------------
.2				jsr CMD.CD.HOME
				jsr HIS.Init
				bcs .9

				>PUSHW L.MSG.GREETINGS
				>PUSHW A2osX.KVER
				>PUSHBI 2
				>SYSCALL PrintF
				bcs .9

				>LDYA L.HOME.PROFILE
				>SYSCALL LoadTxtFile
				bcs CS.RUN.LOOP			No profile...

				phx						X = loaded file hMem
				jsr GetArgV				Y,A = Args
				plx
				jsr CMD..EXEC.YAX		Execute . ${home}.profile
*--------------------------------------
CS.RUN.LOOP		>SLEEP

.1				jsr CheckSleep
				beq .3

				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 bState
				and #bState.SET.C
				bne CS.RUN.LOOP

.8				lda #3					User Interrupt
				sec
.9				rts
*--------------------------------------
.3				lda bState
				and #bState.Pause
				beq .6

				>SYSCALL GetChar
				bcs	.9					I/O err

				cmp #3					Ctrl-C
				bne .4

				lda (pData)				batch mode ?
				beq .5

				lda bState
				and #bState.SET.C
				beq .8

				bra .5

.4				cmp #19					test Ctrl-S
				bne .40

				lda #bState.Pause
				tsb bState
				bra CS.RUN.LOOP

.40				cmp #C.CR
				bne .5

				jsr CheckLFAfterCR		Check for any extra LF
				bcs .9

.5				lda #bState.Pause
				trb bState
*--------------------------------------
.6				lda (pData)				batch mode ?
				bne CS.RUN.BATCH
*--------------------------------------
CS.RUN.INTERACTIVE
				jsr IO.Reset
				jsr CL.Reset
				jsr CL.ReadResetV

				>STZ.G HIS.Ptr

				jsr CL.PrintPrompt
				bcs CS.RUN.CMDLINE.9

.1				>SYSCALL GetChar
				bcs CS.RUN.CMDLINE.9	I/O error

.2				cmp #C.EOF				....or Ctrl-D
				beq CS.RUN.CMDLINE.9	CS

				jsr CL.CHARIN

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

				>LDYA L.MSG.PROMPTCRLF
				jsr IO.OutYA
				bcs CS.RUN.CMDLINE.9

				lda (ZPCLBuf)
				beq CS.RUN.LOOP.END		Empty line

				jsr HIS.Add

				>LDYA ZPCLBuf

CS.RUN.CMDLINE	>SYSCALL StrDup
				bcs CS.RUN.CMDLINE.9

				phx
				jsr GetArgV
				plx						Y,A=ARGV, X=strdup

				jsr CORE.Load.YAX		Exec CL
				bcs CS.RUN.CMDLINE.9

				lda #$C0+C.CLEXEC
				jsr STK.Push

				bra CS.RUN.LOOP.RUN

CS.RUN.CMDLINE.9
				rts
*--------------------------------------
CS.RUN.BATCH	lda bState
				and #bState.SET.X
				beq CS.RUN.LOOP.RUN

				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

CS.RUN.LOOP.RUN	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 bState
				and #bState.SET.E
				bne CS.RUN.LOOP.80

.1				jsr STK.Get
				bcs .8

				cmp #$C0+C.CLEXEC
				beq .8

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

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

				jsr STK.PopCtx
				bcc .1

.7				jsr IO.PrintBatchErrMsg
				bcs CS.RUN.LOOP.RTS

				jsr STK.Pull
				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 bState
				and #bState.ExitOnEOF
				bne 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 hAliases
				beq .10

				>SYSCALL SListFree

.10				>LDA.G HIS.hBuf
				beq .1

				>SYSCALL StrVFree

.1				ldy #CL.hBuf
				jsr .7

.2				jsr CMD.POPD
				bcc .2

				ldy #CORE.hArgVBuf

.7				lda (pData),y
				beq .8

				>SYSCALL FreeMem

.8				clc
				rts
*--------------------------------------
GetCWD			ldy #S.PS.hCWD
				bra GetArgV.1
*--------------------------------------
GetArgV			ldy #S.PS.hARGV

GetArgV.1		lda (pPS),y
				>SYSCALL GetMemPtr
				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.cmd
				.INB usr/src/bin/sh.s.core
				.INB usr/src/bin/sh.s.exp
				.INB usr/src/bin/sh.s.his
				.INB usr/src/bin/sh.s.io
				.INB usr/src/bin/sh.s.stk
*--------------------------------------
CS.END
*--------------------------------------
MSG.GREETINGS	.CZ "\r\nA2osX-SH %d.%d\r\n\r\n"
MSG.HIS			.CZ "\r\n%3d : %s"
MSG.HISPROMPT	.CZ "\r\n\r\n? "
MSG.HISROMPTCLR .CZ "\b\b"
MSG.PROMPT		.CZ "\e[?7h$ "			Enable Line Wrap
MSG.PROMPTCRLF	.CZ "\e[?7l\r\n"		Disable Line Wrap
MSG.TRACE		.CS ">"
MSG.BATCHLINE	.CZ "%s\r\n"
MSG.BATCHERR	.CZ "%s^\r\nLine #%D:"
MSG.ERROR		.CS "[$%h]:%s."
MSG.ECHOCRLF	.CZ "\r\n"
MSG.PID			.CZ "PID=%d\r\n"
MSG.ALIAS		.CZ '%s = "%s"\r\n'
MSG.FS			.CZ	"\e[C"
*--------------------------------------
FMT.DATE		.AZ "%A, %B %d %Y %H:%M:%S"
FMT.Long		.AZ "%L"
FMT.Byte		.AZ "%d"
*--------------------------------------
HOME.PROFILE	.AS "${HOME}.profile"
PtrZero			.HS 00
PS1				.AZ "${PS1}"
HOME			.AZ "${HOME}"
EXECC			.AZ "%s -C %s"
*--------------------------------------
IN.EscChars		.AS "DABC"
IN.EscCharsCnt	.EQ *-IN.EscChars
IN.EscCodes		.DA #C.BS,#C.VT,#C.LF,#21
*--------------------------------------
* \e[1~    - Home
* \e[2~    - Insert
* \e[3~    - Delete
* \e[4~    - End
* \e[5~    - PgUp
* \e[6~    - PgDn
*--------------------------------------
OUT.EscChars	.AS "abefnrtv"
				.HS 5C27223F			\'"?
OUT.EscCharsCnt	.EQ *-OUT.EscChars
OUT.EscCodes	.HS 07081B0C0A0D090B
				.HS 5C27223F
*--------------------------------------
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"
				.AT "ALIAS"
				.HS 00
CORE.IO			.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 "-LT"
				.AT "-LE"
				.AT "-GT"
				.AT "-GE"
				.AT "-EQ"
				.AT "-NE"
				.AT ".<"
				.AT "<="
				.AT ".>"
				.AT ">="
				.AT "="
				.AT "!="
				.HS 00
EXP.OP.MATH		.AT "*"
				.AT "/"
				.AT "MOD"
				.AT "+"
				.AT "-"
				.HS 00
EXP.OP.LOGIC	.AT "AND"
				.AT "OR"
				.HS 00
*--------------------------------------
EXP.OP.BINARY.BITS
				.DA #%100
				.DA #%110
				.DA #%001
				.DA #%011
				.DA #%010
				.DA #%101
*--------------------------------------
EXP.OP.MATH.FPU	.DA #FPU.lMUL,#FPU.lDIV,#FPU.lMOD,#FPU.lADD,#FPU.lSUB
*--------------------------------------
SET.FLAGS		.AS "CEX"
SET.VARS		.DA #bState.SET.C,#bState.SET.E,#bState.SET.X
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
CORE.STACK		.BS CORE.STACK.MAX+1	pData (0 = Stack Ptr)
PUSHD.STACK		.BS PUSHD.STACK.MAX+1
CODE.STACK		.BS CODE.STACK.MAX*7+1

*SH				.BS 2

hAliases		.BS 1
hFunctions		.BS 1

CORE.hArgVBuf	.BS 1

CL.hBuf			.BS 1
CL.Ptr			.BS 1
CL.Len			.BS 1
CL.bReady		.BS 1
CL.bEscMode		.BS 1
CL.MaxCnt		.BS 1
CL.bSilent		.BS 1

HIS.hBuf		.BS 1
HIS.Count		.BS 1
HIS.Ptr			.BS 1
HIS.Head		.BS 1

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

Sleep			.BS 4

*TimeBuf		.BS S.TIME				8 bytes
*M32.BUF		.BS 12					-1234567890\0
TimeBuf			.EQ *
M32.BUF			.EQ *
IO.FIFONAME		.BS 12					/dev/fifoXX\0
*--------------------------------------
DS.END			.ED
*--------------------------------------
MAN
SAVE usr/src/bin/sh.s
ASM
