NEW AUTO 3,1 *-------------------------------------- CORE.Init lda #PUSHD.STACK tay sta (pdata),y lda #CODE.STACK tay sta (pdata),y .9 rts *-------------------------------------- CORE.FUNCRESET >LDA.G hFunctions beq .8 >SYSCALL SListFree >STZ.G hFunctions .8 rts *-------------------------------------- * stack-6,7 old InputBuf * stack-4,5 old InputBufPtr * stack-3 old ARGC * stack-2 old ARGV * stack-1 new hCode * stack *-------------------------------------- CORE.Load.YAX stx LOAD.hCode X = Code to Execute >SYSCALL ArgVDup Y,A = ArgV bcs .9 stx LOAD.hArgs X = hARGV sta LOAD.ArgCnt A = ARGC lda #8 jsr STK.Check bcs .9 >LDYA ZPInputBuf jsr STK.PushYA jsr STK.PushInputBufPtr ldy #S.PS.ARGC lda (pPS),y jsr STK.Push old ARGC ldy #S.PS.hARGV lda (pPS),y jsr STK.Push old hARGV ldy #S.PS.ARGC lda LOAD.ArgCnt new ARGC dec Skip ARG0 in count sta (pPS),y iny #S.PS.hARGV lda LOAD.hArgs sta (pPS),y new hARGV lda LOAD.hCode new code jsr STK.Push * lda LOAD.hCode >SYSCALL GetMemPtr >STYA ZPInputBuf >STYA ZPInputBufPtr * clc .9 rts *-------------------------------------- * http://heirloom.sourceforge.net/sh/sh.1.html *-------------------------------------- * CORE.Run * Input : ZPInputBufPtr (String) * Tokenize ZPArgVBuf * :LOOP * if CmdSep=| : * set hStdIn = hStdOut * set hStdOut = Std * GetCmd from line until | or EOL * if CmdSep=| : * create PIPE * set hStdOut -> PIPE * CORE.Exec & * :LOOP * else CORE.Exec *-------------------------------------- * SET VAR = `cmd args`, FOR VAR IN `cmd args` * create PIPE * set hStdOut -> PIPE * CORE.Exec `cmd args` & * set READMODE * set hStdIn = hStdOut * set hStdOut = Std *-------------------------------------- CORE.Run.EOF jsr STK.Pull bcs * cmp #$C0+C.. check CALL . CL context beq .1 cmp #$C0+C.CALL beq .1 cmp #$C0+C.CLEXEC bne .9 .1 jsr CMD.EXIT.FILE jsr IO.Reset lda #0 sec jmp CORE.Run.Exit Ending 0, CS,A=0 .9 lda #E.UNEXPEOF sec jmp CORE.Run.Exit CORE.Run.RTS rts *-------------------------------------- CORE.Run >LDYAI 256 >SYSCALL GetMem bcs CORE.Run.RTS >STYA ZPArgVBuf txa >STA.G CORE.hArgVBuf lda #bState.PipeIn+bState.PipeOut trb bState *-------------------------------------- CORE.Run.1 >LDYA ZPInputBufPtr Save Actual ptr for looping >STYA ZPInputCmdPtr >LDYA ZPArgVBuf Reset ArgV Buffer >STYA ZPArgVBufPtr lda #0 sta (ZPArgVBuf) sec ror CORE.IntCmd assume external lda #S.PS.F.HOLD sta CORE.PSFlags jsr CORE.GetCharNB bcs CORE.Run.EOF cmp #C.CR empty line ? bne .33 jsr CORE.GetNextChar skip CR... bra .8 .33 cmp #'#' commented line? bne CORE.Run.3 .12 jsr CORE.SkipLine .8 jmp CORE.Run.Exit0 EOL, CS,A=0 *-------------------------------------- CORE.Run.3 >LDA.G hAliases beq CORE.Run.4 >PUSHA >PUSHW ZPInputBufPtr >PUSHWZ ScopeID >SYSCALL SListLookup bcs CORE.Run.4 >STYA ZPTmpW Save KeyID txa jsr CORE.SkipCharsA ldy #hAliases jsr CORE.SListGetData bcs .9 jsr CORE.PushBufX bcc CORE.Run.3 .9 rts *-------------------------------------- CORE.Run.4 >LDYA L.CMD internal command ? jsr CORE.LookupInputBuf bcc .41 .40 jsr CORE.ArgV.Add external cmd, go check context bra .42 .41 stx CORE.IntCmd jsr CORE.SkipCharsA .42 jsr STK.Get bcs CORE.Run.5 no particular context, exec... tax lda CORE.IntCmd bmi .45 and #$3F cmp #C.SWITCH SWITCH....FI ? bcs CORE.Run.5 .45 txa bpl .43 context is FALSE, skip line asl bmi CORE.Run.5 parent context is true, exec .43 jsr CORE.GetCharNB bcs .44 EOF cmp #C.CR beq .44 cmp #';' TODO ";" beq .44 jsr CORE.GetNextChar bra .43 .44 jsr CORE.GetNextCharNB Skip EoL char jmp CORE.Run.Exit0 *-------------------------------------- CORE.Run.5 jsr CORE.GetCharNB bcs CORE.Run.6 Nothing to skip jsr CORE.IsEndCmd bcc .3 >LDYA L.CORE.IO jsr CORE.LookupInputBuf bcs .2 jsr CORE.SkipCharsA jsr CORE.IO.JMP bcc CORE.Run.5 bcs .9 .2 jsr CORE.ArgV.Add bcc CORE.Run.5 .9 lda #E.SYN sec jmp CORE.Run.Exit *-------------------------------------- .3 cmp #C.CR beq .7 cmp #';' beq .7 cmp #'|' bne .5 jsr CORE.GetNextCharNB '|' lda #bState.PipeOut tsb bState bra CORE.Run.6 .5 cmp #'&' bne .9 jsr CORE.GetNextChar Skip '&' bcs .50 cmp #'&' beq .6 && .50 lda #S.PS.F.HOLD Run in the background... trb CORE.PSFlags bra CORE.Run.6 .6 jsr CORE.GetNextChar Skip '&&' jsr CORE.ExecCmd bcc .60 jsr CORE.SkipLine jmp CORE.Run.Exit0 .60 jmp CORE.Run.1 .7 jsr CORE.GetNextCharNB Skip EoL char *-------------------------------------- CORE.Run.6 lda bState bit #bState.PipeOut beq .1 jsr IO.Pipe.Out bcs CORE.Run.Exit lda #S.PS.F.HOLD Run in the background... trb CORE.PSFlags lda #S.PS.F.CLOSEONX ...and child PS must close StdOut on exit tsb CORE.PSFlags .1 jsr CORE.ExecCmd bcs CORE.Run.Exit lda bState bit #bState.PipeIn beq .2 jsr IO.Pop.In restore Input piping app must close it lda #bState.PipeIn trb bState lda bState .2 bit #bState.PipeOut beq CORE.Run.Exit0 jsr IO.Pipe.In Set previous Pipe Out to StdIn for next CMD bcs CORE.Run.Exit lda #bState.PipeIn tsb bState bit CORE.IntCmd bmi .3 jsr IO.Reset.Out Internal : CLOSE output bra .4 .3 jsr IO.Pop.Out External : DONT Close Output, child process will close it .4 lda #bState.PipeOut trb bState .7 jmp CORE.Run.1 Loop with Pipe IN CORE.Run.Exit0 lda #0 clc CORE.Run.Exit php pha >LDA.G CORE.hArgVBuf beq .1 >SYSCALL FreeMem >STZ.G CORE.hArgVBuf .1 jsr IO.Reset pla plp rts *-------------------------------------- * Input : ZPArgVBuf *-------------------------------------- CORE.ExecCmd lda #0 sta (ZPArgVBufPtr) >LDYA ZPArgVBuf >STYA ZPArgVBufPtr lda CORE.IntCmd bmi CORE.ExecExtCmd asl tax jmp (J.CMD,x) *-------------------------------------- CORE.ExecExtCmd >PUSHW ZPArgVBuf >PUSHB CORE.PSFlags >SYSCALL ExecV bcs .9 tax CPID lda CORE.PSFlags and #S.PS.F.HOLD bne .1 lda bState bit #bState.PipeOut bne .1 ldy #S.PS.hStdErr lda (pPS),y >PUSHA >PUSHW L.MSG.PID txa >PUSHA >PUSHBI 1 >SYSCALL FPrintF rts .1 >SLEEP Suspend this PID ldy #S.PS.RC CPID will update S.PS.RC lda (pPS),y cmp #1 .9 rts *-------------------------------------- CORE.SkipLine jsr CORE.GetNextCharNB bcs .8 EOF cmp #C.CR EOL bne CORE.SkipLine jsr CORE.GetNextChar skip CR... .8 rts *-------------------------------------- * search ZPInputBufPtr/ZPArgVBufPtr in Y,A table *-------------------------------------- CORE.LookupInputBuf sec .HS 90 BCC CORE.LookupArgVBuf clc >STYA ZPPtr1 Keywords table >LDYA ZPArgVBufPtr bcc CORE.Lookup >LDYA ZPInputBufPtr CORE.Lookup >STYA ZPPtr2 ldx #0 .1 ldy #$ff .2 jsr .7 get next valid char in src text bcs .3 .20 jsr ToUpperCase eor (ZPPtr1),y match table char ? asl compare only 7 bits bne .4 no match...get next table keyword bcc .2 not last char in this keyword jsr .7 next char in text... bcc .4 valid....failed .8 tya Keyword Len clc rts .3 dey lda (ZPPtr1),y was last char in this keyword ? bmi .8 iny .41 jsr IncPtr1 skip chars to next keyword .4 lda (ZPPtr1) bpl .41 jsr IncPtr1 .6 inx lda (ZPPtr1) Array Ending 0, lookup failed bne .1 lda #E.SYN .9 sec rts .7 iny lda (ZPPtr2),y Get Src text char... beq .9 end of text jsr CORE.IsSpaceOrEndCmd bcc .9 end of valid chars clc CORE.ArgV.Add.RTS rts *-------------------------------------- * ArgV *-------------------------------------- CORE.ArgV.Add lda #C.SPACE sta ZPTmpW ldy #0 jsr CORE.GetCharNB bcs CORE.ArgV.Add.RTS cmp #'"' bne .10 sta ZPTmpW bra .1 .10 cmp #'(' bne .11 ldx #')' stx ZPTmpW bra .12 .11 cmp #'`' bne .12 sta ZPTmpW .12 sta (ZPArgVBufPtr),y iny .1 jsr CORE.GetNextChar bcs .7 .2 cmp ZPTmpW bne .3 jsr CORE.GetNextChar bra .7 .3 ldx ZPTmpW cpx #C.SPACE bne .6 jsr CORE.IsEndCmd bcc .7 .6 sta (ZPArgVBufPtr),y iny jsr CORE.GetNextChar bcc .2 .7 lda #0 sta (ZPArgVBufPtr),y >LDYA ZPArgVBufPtr >STYA ZPArgVBufPrev >PUSHYA >PUSHW ZPArgVBufPtr >SYSCALL Expand bcs .9 tya beq .8 Empty string.... sec adc ZPArgVBufPtr sta ZPArgVBufPtr bcc .8 inc ZPArgVBufPtr+1 clc .8 .9 rts *-------------------------------------- CORE.ArgV.Next lda (ZPArgVBufPtr) beq .8 >LDYA ZPArgVBufPtr >STYA ZPArgVBufPrev .1 jsr CORE.ArgV.NextChar lda (ZPArgVBufPtr) bne .1 jsr CORE.ArgV.NextChar lda (ZPArgVBufPtr) .8 rts *-------------------------------------- CORE.ArgV.NextChar inc ZPArgVBufPtr bne .8 inc ZPArgVBufPtr+1 .8 rts *-------------------------------------- * IO *-------------------------------------- CORE.IO.JMP txa asl tax jmp (J.CORE.IO,x) CORE.IO.IN lda #O.RDONLY+O.TEXT jsr CORE.IO.Open bcs CORE.IO.RTS jmp IO.Set.In CORE.IO.OUTA CORE.IO.1OUTA lda #O.WRONLY+O.APPEND+O.CREATE+O.TEXT bra CORE.IO.OUT.1 CORE.IO.OUT CORE.IO.1OUT lda #O.WRONLY+O.TRUNC+O.CREATE+O.TEXT CORE.IO.OUT.1 jsr CORE.IO.Open bcs CORE.IO.RTS jmp IO.Set.Out CORE.IO.2OUTA lda #O.WRONLY+O.APPEND+O.CREATE+O.TEXT bra CORE.IO.2OUT.1 CORE.IO.2OUT lda #O.WRONLY+O.TRUNC+O.CREATE+O.TEXT CORE.IO.2OUT.1 jsr CORE.IO.Open bcs CORE.IO.RTS jmp IO.Set.Err *-------------------------------------- CORE.IO.Open pha Open Mode jsr CORE.GetCharNB bcs .9 no arg left.... jsr CORE.ArgV.Add Get Filename >LDYA ZPArgVBufPrev >STYA ZPArgVBufPtr Discard filename plx jmp IO.FOpenYAX .9 pla lda #E.SYN sec CORE.IO.RTS rts *-------------------------------------- * Input Buffer *-------------------------------------- CORE.IsSpaceOrEndCmd cmp #C.SPACE beq CORE.IsEndCmd.8 CORE.IsEndCmd cmp #';' beq CORE.IsEndCmd.8 cmp #C.CR beq CORE.IsEndCmd.8 cmp #'&' beq CORE.IsEndCmd.8 cmp #'|' beq CORE.IsEndCmd.8 sec rts CORE.IsEndCmd.8 clc rts *-------------------------------------- CORE.GetCharNB jsr CORE.GetChar bcs CORE.GetNextCharNB.RTS jsr CORE.CheckCharNB bcc CORE.GetNextCharNB.RTS *-------------------------------------- CORE.GetNextCharNB jsr CORE.GetNextChar bcs CORE.GetNextCharNB.RTS jsr CORE.CheckCharNB bcs CORE.GetNextCharNB CORE.GetNextCharNB.RTS rts *-------------------------------------- CORE.CheckCharNB cmp #C.SPACE beq .9 cmp #C.LF beq .9 cmp #C.TAB beq .9 clc .9 rts *-------------------------------------- CORE.GetNextChar inc ZPInputBufPtr bne CORE.GetChar inc ZPInputBufPtr+1 *-------------------------------------- CORE.GetChar clc lda (ZPInputBufPtr) bne .8 jsr CORE.PopBuf bcc CORE.GetChar lda #0 .8 rts *-------------------------------------- CORE.SkipCharsA clc adc ZPInputBufPtr sta ZPInputBufPtr bcc .8 inc ZPInputBufPtr+1 .8 rts *-------------------------------------- CORE.PushBufX >LDA.G CODE.STACK cmp #CODE.STACK.MAX*5 beq .9 inc tay phx next hBuffer ldx #0 .1 lda ZPInputBuf,x ZPInputBuf sta (pData),y inx ZPInputBufPtr iny cpx #6 ZPInputCmdPtr bne .1 pla pha sta (pData),y tya >STA.G CODE.STACK pla >SYSCALL GetMemPtr >STYA ZPInputBuf >STYA ZPInputBufPtr * clc rts .9 lda #E.STKOVERFLOW * sec rts *-------------------------------------- CORE.PopBuf phy >LDA.G CODE.STACK cmp #CODE.STACK beq .9 tay lda (pData),y phy >SYSCALL FreeMem ply ldx #5 dey .1 lda (pData),y ZPInputBuf sta ZPInputBuf,x dey ZPInputBufPtr dex bpl .1 ZPInputCmdPtr tya >STA.G CODE.STACK ply * clc rts .9 ply lda #E.STACKERROR * sec rts *-------------------------------------- CORE.SListGetData >PUSHB (pData),y >PUSHW ZPTmpW KeyID >PUSHWZ Allocate >PUSHWI $ffff All >PUSHWZ from Start >SYSCALL SListGetData X = hMem rts *-------------------------------------- MAN SAVE usr/src/bin/sh.s.core LOAD usr/src/bin/sh.s ASM