NEW AUTO 3,1 *-------------------------------------- .DUMMY .OR ZPTMP+8 7 Bytes PS.Flags .BS 1 PS.ArgV .BS 2 PS.ArgSize .BS 2 PS.NewPSPtr .BS 2 .ED */-------------------------------------- * # ExecL * ## C * `int execl(const char* cmdline, short int flags);` * ## ASM * `>PUSHB flags` * `>LDYA cmdline` * `>SYSCALL execl` * ## RETURN VALUE * A = Child PSID *\-------------------------------------- K.ExecL sty .1+1 sta .2+1 >PULLB PS.Flags >LDYAI 256 jsr K.GetMem bcs .99 stx .90+1 >STYA PS.ArgV >PUSHYA .1 ldy #$ff SELF MODIFIED .2 lda #$ff SELF MODIFIED jsr K.Str2StrV bcs .9 jsr PS.Exec .9 php pha .90 lda #$ff SELF MODIFIED jsr K.FreeMem pla plp .99 rts */-------------------------------------- * # ExecV * ## C * `int execv(const char* argv[], short int flags);` * ## ASM * `>PUSHB flags` * `>LDYA argv` * `>SYSCALL execv` * ## RETURN VALUE * A = Child PSID *\-------------------------------------- K.ExecV >STYA PS.ArgV >PULLB PS.Flags PS.Exec jsr PS.CreateChild A=PID,Child S.PS at PS.NewPSPtr,PS.Load.hMem bcs .9 sta .8+1 stz K.IOBuf If !=0 after PS.Load, it's a script jsr PS.Load bcs .90 jsr PS.AddArgV K.IOBuf= /.../SHELL, K.Buf256=/.../SCRIPT bcc .8 or K.IOBuf= 0, K.Buf256=/.../BINFILE .90 pha save error code >PUSHBI 2 lda .8+1 jsr K.Kill pla get back error code sec rts .8 lda #$ff SELF MODIFIED * clc .9 rts *-------------------------------------- * PS.CreateChild * in : * out : * A = PSID *-------------------------------------- PS.CreateChild ldx #0 bra .2 Skip PS0 .1 lda PS.Table.PID,x beq .4 Found an empty slot .2 inx cpx CORE.PSCount bne .1 cpx #K.PS.MAX bne .3 lda #E.OOH sec rts .99 plx rts .3 inc CORE.PSCount .4 inc CORE.LastPSID Get a PSID not already running beq .4 not = 0 lda CORE.LastPSID jsr CORE.GetPS Y=PS Index, X,A unmodified bcc .4 running...loop lda CORE.LastPSID sta PS.Table.PID,x phx save PS Index >LDYAI S.PS jsr K.GetMem0 Blank Everything in this S.PS bcs .99 >STYA PS.NewPSPtr txa plx sta PS.Table.hPS,x jsr Mem.SetOwner Set Ownership lda PS.Flags and #S.PS.F.CLOSEONX sta (PS.NewPSPtr) lda CORE.LastPSID ldy #S.PS.PID sta (PS.NewPSPtr),y lda #S.PS.F.NOHUP bit PS.Flags beq .5 lda PS.Table.hPS Select PS0 jsr K.GetMemPtr bra .6 .5 >LDYA pPs .6 >STYA ZPPtr1 ldy #S.PS.PID lda (ZPPtr1),y dey #S.PS.PPID sta (PS.NewPSPtr),y ldy #S.PS.hCWD copy hPREFIX... lda (ZPPtr1),y jsr K.GetMemPtr jsr K.StrDup bcs .9 jsr Mem.SetOwner Set Ownership txa ldy #S.PS.hCWD sta (PS.NewPSPtr),y jsr ENV.Dup dup hENV from parent PS bcs .9 ldy #S.PS.hENV sta (PS.NewPSPtr),y txa dey sta (PS.NewPSPtr),y ldy #S.PS.hStdIn .7 lda (ZPPtr1),y sta (PS.NewPSPtr),y iny cpy #S.PS.hStdErr+1 bne .7 ldy #S.PS.hSID lda (ZPPtr1),y sta (PS.NewPSPtr),y tax lda S.Table.hSession-1,x jsr K.GetMemPtr phy ldy #S.PS.ZP.SESSION+1 sta (PS.NewPSPtr),y dey pla sta (PS.NewPSPtr),y jsr Mem.IncRefCnt lda #S.PS.F.HOLD bit PS.Flags beq .8 ora (ZPPtr1) sta (ZPPtr1) HOLD parent PS lda CORE.LastPSID ldy #S.PS.CPID sta (ZPPtr1),y .8 * lda #S.PS.S.INIT * ldy #S.PS.S * sta (PS.NewPSPtr),y Make this PS Init.... lda CORE.LastPSID Exit with A=PSID clc rts .9 pha >PUSHBI 2 lda CORE.LastPSID jsr K.Kill pla sec rts *-------------------------------------- PS.Load ldy #$ff .1 iny lda (PS.ArgV),y beq .2 no / in path...try search in PATH cmp #'/' bne .1 >PUSHWI K.S.STAT >LDYA PS.ArgV found /, some path specified, no search >SYSCALL2 stat bcc .6 REAL path in K.Buf256 .99 rts .2 >LDYA PS.ArgV jsr ENV.Search.PATH Get fullpath in K.Buf256 bcc .6 >LDYA PS.ArgV jsr ENV.Search.CWD bcs .99 .6 lda K.S.STAT+S.STAT.P.TYPE cmp #S.FI.T.BIN beq PS.LoadBIN .7 cmp #S.FI.T.TXT beq PS.Load.SCRIPT * cmp #S.FI.T.SYS * bra * PS.Load.IBIN lda #E.IBIN .HS 2C PS.Load.IPATH lda #E.BADPATH sec PS.Load.RTS rts PS.Load.SCRIPT ldx #$ff .10 inx Save Script name in IOBuf lda K.Buf256,x sta K.IOBuf,x bne .10 jsr PS.LoadGetHeader bcs PS.Load.RTS >PUSHWI PS.Load.ROOT >PUSHWI K.Buf256 K.Buf256 = "$ROOT" jsr K.GetEnv bcs PS.Load.IPATH ldx #$ff .1 inx lda K.Buf256,x bne .1 ldy #0 .3 lda K.IOBuf+128,y Check HEADER= "#!/" cmp PS.Load.HEADER,y bne PS.Load.IBIN iny cpy #3 bne .3 .4 iny inx lda K.IOBuf+128-1,y sta K.Buf256-1,x K.Buf256 = "${ROOT}BIN/SHELL" beq .5 eor #C.CR bne .4 sta K.Buf256-1,x K.Buf256 = "${ROOT}BIN/SHELL\0" .5 >PUSHWI K.S.STAT >LDYAI K.Buf256 >SYSCALL2 stat bcs PS.Load.RTS lda K.S.STAT+S.STAT.P.TYPE cmp #S.FI.T.BIN bne PS.Load.IBIN *-------------------------------------- PS.LoadBIN jsr BIN.Load K.Buf256= "${ROOT}BIN/SHELL\0", K.IOBuf=/.../SCRIPT bcs .9 >STYA ZPPtr4 save PTR to Code Segment phy ldy #S.PS.ZP.CODE+1 sta (PS.NewPSPtr),y save pCode HI... dey pla sta (PS.NewPSPtr),y save pCode LO... txa ldy #S.PS.hCS sta (PS.NewPSPtr),y save CS hMem in S.PS * jsr MEM.GetMemByID * jsr Mem.SetOwner Set Ownership ldy #H.BIN.F Get Bin S.PS.F lda (ZPPtr4),y beq .1 ldy #S.PS.F update PS S.PS.F ora (PS.NewPSPtr),y sta (PS.NewPSPtr),y .1 ldy #H.BIN.DS.SIZE+1 lda (ZPPtr4),y Load DS.SIZE HI tax dey ora (ZPPtr4),y beq .2 DS.SIZE=0... lda (ZPPtr4),y tay txa Y,A = DS.SIZE ldx #S.MEM.F.INIT0+S.MEM.F.DATA jsr MEM.GetMem.YAX bcs .9 phy ldy #S.PS.ZP.DATA+1 sta (PS.NewPSPtr),y save pData HI... dey pla sta (PS.NewPSPtr),y save pData LO... txa ldy #S.PS.hDS sta (PS.NewPSPtr),y save DS hMem in S.PS jsr Mem.SetOwner Set Ownership .2 ldy #H.BIN.SS.SIZE lda (ZPPtr4),y Load SS.SIZE tay beq .3 SS.SIZE.LO=0, set as default $100 lda #$ff SS.SIZE.HI .3 inc ldx #S.MEM.F.NOCROSS+S.MEM.F.STACK jsr MEM.GetMem.YAX bcs .9 phy save pStack base LO ldy #S.PS.ZP.STACK+1 sta (PS.NewPSPtr),y save pStack HI... ldy #S.PS.ZP.LOCAL+1 sta (PS.NewPSPtr),y save pLocal HI... pla make pStack = Base... ldy #H.BIN.SS.SIZE ...plus Stack size * clc adc (ZPPtr4),y ldy #S.PS.ZP.STACK sta (PS.NewPSPtr),y txa ldy #S.PS.hSS sta (PS.NewPSPtr),y save SS hMem in S.PS clc Potentially CS from ADC (ZPPtr4),y jmp Mem.SetOwner Set Ownership .9 rts *-------------------------------------- PS.LoadGetHeader >PUSHWZ Aux type >PUSHBI S.FI.T.TXT >PUSHBI O.RDONLY >LDYAI K.IOBuf >SYSCALL2 fopen bcs .9 sta .1+1 >PUSHWI 128 >PUSHWI K.IOBuf+128 .1 lda #$ff SELF MODIFIED >SYSCALL2 fread php pha lda .1+1 >SYSCALL2 fclose pla plp .9 rts *-------------------------------------- PS.Load.ROOT .AZ "ROOT" PS.Load.HEADER .AZ "#!/" *-------------------------------------- * K.Buf256= /.../SHELL, K.IOBuf=/.../SCRIPT * - or - * K.Buf256=/.../BINFILE,K.IOBuf=0 * Buf256+IOBUF(?)+PS.ArgV[1,...] -> #S.PS.hARGV *-------------------------------------- PS.AddArgV ldy #$ff In both cases, remove ARGV[0] .60 iny lda (PS.ArgV),y bne .60 tya sec adc PS.ArgV sta PS.ArgV bcc .70 inc PS.ArgV+1 Skip old ARGV[0] = scriptename .70 >LDYAI K.Buf256 jsr K.strlen >STYA PS.ArgSize lda K.IOBuf is there a /BIN/SHELL ? beq .10 >LDYAI K.IOBuf jsr K.strlen jsr PS.AddYAp12ArgSize .10 ldx #0 For now, 0 args... lda K.IOBuf beq .11 +1 for scriptpath inx .11 >LDYA PS.ArgV >STYA ZPPtr1 .1 lda (ZPPtr1) beq .4 inx ldy #0 .2 iny lda (ZPPtr1),y bne .2 * lda #0 jsr PS.AddYAp12ArgSize jsr SHARED.AddYp1ToPtr1 bra .1 .4 txa ldy #S.PS.ARGC sta (PS.NewPSPtr),y >LDYA PS.ArgSize Add 1 for ending 0 iny bne .5 inc .5 iny Add ONE MORE ?????!!!! bne .51 inc .51 jsr K.GetMem bcs .9 >STYA ZPPtr2 Target Buffer txa ldy #S.PS.hARGV sta (PS.NewPSPtr),y >LDYAI K.Buf256 jsr PS.AddYAToStrV lda K.IOBuf beq .6 >LDYAI K.IOBuf jsr PS.AddYAToStrV .6 >LDYA PS.ArgV >STYA ZPPtr1 .7 lda (ZPPtr1) sta (ZPPtr2) beq .8 Ending \0 jsr PS.AddPtr1ToStrV bra .7 .8 clc .9 rts *-------------------------------------- PS.AddYAToStrV >STYA ZPPtr1 PS.AddPtr1ToStrV ldy #$ff .2 iny lda (ZPPtr1),y sta (ZPPtr2),y bne .2 jsr SHARED.AddYp1ToPtr1 jmp SHARED.AddYp1ToPtr2 *-------------------------------------- PS.AddYAp12ArgSize pha tya sec +1 for \0 adc PS.ArgSize sta PS.ArgSize pla adc PS.ArgSize+1 sta PS.ArgSize+1 rts */-------------------------------------- * # Kill * ## C * `int kill(short int pid, short int sig);` * ## ASM * `>PUSHB sig` * `lda pid` * `>SYSCALL kill` * ## RETURN VALUE * A = Child PSID *\-------------------------------------- K.Kill.PID .BS 1 *-------------------------------------- K.Kill cmp #0 beq .99 CS sta K.Kill.PID jsr CORE.GetPSByID bcs .99 >STYA ZPPtr1 >PULLA cmp #2+1 bcs .9 asl tax jmp (.1,x) .1 .DA K.Kill.0 .DA K.Kill.1 .DA K.Kill.2 .9 lda #E.SYN * sec rts .99 >RET 1 *-------------------------------------- K.Kill.1 ldy #S.PS.S lda #S.PS.S.QUIT sta (ZPPtr1),y K.Kill.0 clc rts K.Kill.2 ldy #S.PS.hSID lda (ZPPtr1),y tax lda S.Table.hSession-1,x jsr K.FreeMem ldx #5 .11 ldy .10,x lda (ZPPtr1),y beq .12 jsr K.FreeMem .12 dex bpl .11 lda (ZPPtr1) bit #S.PS.F.CLOSEONX beq .1 ldy #S.PS.hStdOut lda (ZPPtr1),y ldx #SYS.fclose jsr K.SYSCALL2 .1 lda K.Kill.PID ldx #0 .2 cmp PS.Table.PID,x beq .3 inx cpx CORE.PSCount bne .2 bra * .3 stz PS.Table.PID,x lda PS.TABLE.hPS,x stz PS.TABLE.hPS,x jmp K.FreeMem .10 .DA #S.PS.hSS,#S.PS.hDS,#S.PS.hCS .DA #S.PS.hARGV,#S.PS.hENV,#S.PS.hCWD */-------------------------------------- * # LoadTxtFile * Load TXT a file in memory (with ending 0) * ## C * `int loadtxtfile ( const char * filename, short int flags, short int ftype, int auxtype );` * ## ASM * **In:** * `>PUSHW auxtype` * `>PUSHB ftype` * `>PUSHB flags` * `>LDYA filename` * `>SYSCALL loadtxtfile` * ## RETURN VALUE * Y,A = File Length (without ending 0) * X = hMem of Loaded File *\-------------------------------------- .DUMMY .OR ZPTMP 5 Bytes FIO.bTXT .BS 1 FIO.hFILE .BS 1 FIO.MemPtr .BS 2 FIO.hMem .BS 1 .ED *-------------------------------------- K.LoadTxtFile sec .HS 90 BCC */-------------------------------------- * # LoadFile * Load a file in memory * ## C * `int loadfile ( const char * filename, short int flags, short int ftype, int auxtype );` * ## ASM * **In:** * `>PUSHW auxtype` * `>PUSHB ftype` * `>PUSHB flags` * `>LDYA filename` * `>SYSCALL loadfile` * ## RETURN VALUE * Y,A = File Length * X = hMem of Loaded File *\-------------------------------------- K.LoadFile clc ror FIO.bTXT ldx #SYS.FOpen jsr K.SYSCALL2 bcs .9 .12 sta FIO.hFILE pha >PUSHWI K.S.Stat pla ldx #SYS.FStat jsr K.SYSCALL2 bcs .11 lda K.S.Stat+S.STAT.SIZE+3 ora K.S.Stat+S.STAT.SIZE+2 bne .10 >LDYA K.S.Stat+S.STAT.SIZE bit FIO.bTXT Add 1 to buffer size for ending 0 bpl .1 iny bne .1 inc bne .1 .10 lda #E.FTB .11 bra .99 .1 jsr K.GetMem bcs .99 >STYA FIO.MemPtr stx FIO.hMem >PUSHW K.S.Stat+S.STAT.SIZE >PUSHW FIO.MemPtr lda FIO.hFILE ldx #SYS.FRead jsr K.SYSCALL2 bcc .2 pha lda FIO.hMem jsr K.FreeMem pla .99 pha lda FIO.hFILE ldx #SYS.FClose jsr K.SYSCALL2 pla sec .9 rts .2 sty .7+1 sta .8+1 bit FIO.bTXT bpl .5 pha set ending 0 tya * clc adc FIO.MemPtr sta .4+1 pla adc FIO.MemPtr+1 sta .4+2 .4 stz $ffff Self Modified .5 jsr .99 close file .7 ldy #$ff SELFMODIFIED .8 lda #$ff SELFMODIFIED ldx FIO.hMem clc rts */-------------------------------------- * # FileSearch * Search a file in the provided PATH list * And return, if found, the full path to it. * ## C * `int filesearch ( char * filename, char * searchpath, char * fullpath, stat * filestat);` * ## ASM * **In:** * `>PUSHWI filename` * `>PUSHWI fullpath` * `>PUSHWI searchpath` * `>PUSHWI filestat` * ## RETURN VALUE * CC : success * DstBuf = FilePath * DstStat = S.STAT * CS : not found *\-------------------------------------- K.FileSearch >PULLW .4+1 DstStat >PULLW .2+1 DstBuf >PULLW ENV.Search.2+1 path to search >PULLW ENV.Search.4+1 filename to find stz ENV.Search.98+1 jsr ENV.Search bcs K.FileSearch.RTS ldx #$ff .1 inx lda K.Buf256,x .2 sta $ffff,x Self Modified bne .1 ldx #S.STAT-1 .3 lda K.S.STAT,x .4 sta $ffff,x Self Modified dex bpl .3 * clc K.FileSearch.RTS rts *-------------------------------------- ENV.Search.CWD >STYA ENV.Search.4+1 filename to find ldy #S.PS.hCWD lda (PS.NewPSPtr),y jsr K.GetMemPtr >STYA ENV.Search.2+1 stz ENV.Search.98+1 bra ENV.Search ENV.Search.LIB ldx #0 .HS 2C BIT ABS ENV.Search.DRV ldx #2 .HS 2C BIT ABS ENV.Search.PATH ldx #4 >STYA ENV.Search.4+1 filename to find >PUSHW ENV.VARS,x >PUSHWI 0 allocate... jsr K.GetEnv get value for Search Path bcs K.FileSearch.RTS >STYA ENV.Search.2+1 stx ENV.Search.98+1 ENV.Search stz ENV.Search.1+1 ENV.Search.1 ldy #0 Self Modified Index in Search list string ldx #0 ENV.Search.2 lda $ffff,y SELF MODIFIED beq ENV.Search.3 end of string, try it.... iny cmp #':' beq ENV.Search.3 sta K.Buf256,x inx bra ENV.Search.2 ENV.Search.3 txa beq ENV.Search.98 String is empty....nothing to try sty ENV.Search.1+1 save current index ldy #0 ENV.Search.4 lda $ffff,y Self Modified, Append Filename... sta K.Buf256,x beq ENV.Search.5 iny inx bra ENV.Search.4 ENV.Search.5 >PUSHWI K.S.STAT >LDYAI K.Buf256 >SYSCALL2 stat bcs ENV.Search.1 Failed...retry next path... lda K.S.STAT+S.STAT.P.TYPE cmp #S.FI.T.DIR Dir ? beq ENV.Search.1 jsr ENV.Search.98 Discard Expanded hSrch list clc rts ENV.Search.98 lda #$ff SELF MODIFIED : Discard Search list beq .1 jsr K.FreeMem .1 lda #MLI.E.FNOTFND sec rts *-------------------------------------- ENV.VARS .DA .1 .DA .2 .DA .3 .1 .AZ "LIB" .2 .AZ "DRV" .3 .AZ "PATH" */-------------------------------------- * # GetMemStat * **In:** * Y,A = Ptr to 24 bytes buffer * ## RETURN VALUE * Buffer filled with memory stats *\-------------------------------------- K.GetMemStat >STYA ZPPtr1 ldy #23 ldx #7 .1 lda DevMgr.Stat,x sta (ZPPtr1),y dey dex bpl .1 sta SETREADAUX jsr .2 sta CLRREADAUX .2 ldx #7 .3 lda Mem.Table,x sta (ZPPtr1),y dey dex bpl .3 clc rts */-------------------------------------- * # StrVDup * **In:** * Y,A = Src StrV * ## RETURN VALUE * X = hMem of new StrV * A = Str Count *\-------------------------------------- K.StrVDup >STYA ZPPtr1 >STYA ZPPtr2 ldy #0 ldx #0 .1 lda (ZPPtr2),y beq .2 .11 iny bne .1 inx inc ZPPtr2+1 bra .1 .2 iny bne .3 inx inc ZPPtr2+1 .3 lda (ZPPtr2),y bne .11 txa jsr K.getmem bcs .9 >STYA ZPPtr2 phx ldx #0 ldy #0 .4 lda (ZPPtr1),y .5 sta (ZPPtr2),y beq .6 iny bne .4 inc ZPPtr1+1 inc ZPPtr2+1 bra .4 .6 inx iny bne .7 inc ZPPtr1+1 inc ZPPtr2+1 .7 lda (ZPPtr1),y bne .5 sta (ZPPtr2),y Ending \0 txa plx hMem clc .9 rts */-------------------------------------- * # Str2StrV * Expand String and convert to ArgV List * ## C * short int str2strv(char* args, char* argv[]) * ## ASM * `>PUSHW argv` * `>LDYA args` * `>SYSCALL Str2StrV` * ## RETURN VALUE * A = Arg count *\-------------------------------------- ARG.bInQuote .EQ ZPPtr3 *-------------------------------------- K.Str2StrV jsr K.Expand bcs .9 >STYA ZPPtr1 stx .80+1 >PULLW ZPPtr2 Get target buffer ldx #0 Arg Count stz ARG.bInQuote .1 jsr SHARED.GetCharPtr1 beq .8 cmp #C.SPACE beq .1 skip leading spaces .2 cmp #'"' found a quote ? bne .3 lda ARG.bInQuote eor #$ff sta ARG.bInQuote bra .7 skip quote and check next char .3 cmp #C.SPACE bne .6 regular char ...store... bit ARG.bInQuote bmi .6 between quotes... store space... inx Found one arg !!! lda #0 set this token End jsr SHARED.PutCharPtr2 bra .1 .6 jsr SHARED.PutCharPtr2 .7 jsr SHARED.GetCharPtr1 bne .2 inx .8 jsr SHARED.PutCharPtr2 set Argv[x] Ending 0 sta (ZPPtr2) set Array Ending 0 phx .80 lda #$FF SELF MODIFIED jsr K.FreeMem Discard expanded string pla get back Arg Count * clc rts .9 >RET 2 Discard target buffer *-------------------------------------- MAN SAVE USR/SRC/SYS/KERNEL.S.PS LOAD USR/SRC/SYS/KERNEL.S ASM