NEW PREFIX AUTO 4,1 */-------------------------------------- * # ExpandStr * **In:** * Y,A = PTR to String to Expand (C-String) * ## RETURN VALUE * X = hMem to Expanded String (C-String) * Y,A = PTR to Expanded String *\-------------------------------------- .DUMMY .OR ZPDRV ENV.SearchPath .BS 2 ENV.BufLen .BS 1 ENV.bNoExp .BS 1 ENV.VarLen .BS 1 ENV.VarName .BS 16 .ED *-------------------------------------- K.ExpandStr stz .88+1 Reset Intermediate string... .1 >STYA ZPPtr2 stz ENV.BufLen init Expanded String len=0 stz .82+1 No var found yet stz ENV.bNoExp Reset no expand flag ldy #0 .10 stz ENV.VarLen stz .23+1 reset In var flag .11 lda (ZPPtr2),y End of CSTR? beq .8 iny cmp #''' bne .21 lda ENV.bNoExp eor #$ff sta ENV.bNoExp toggle flag bra .11 .21 bit ENV.bNoExp bpl .23 .22 jsr ENV.AddAToBuf bra .11 .23 ldx #$ff SELF MODIFIED already in a var? bne .3 yes... cmp #'$' no, found one ? bne .22 no, store... sta .82+1 Toggle Expanded flag sta .23+1 Set In Var flag bra .11 skip this char .3 cmp #'{' we are in var, "{" after "$"? bne .31 ldx ENV.VarLen No char in var yet ? beq .11 normal, "${" syntax is ok,skip bne .5 not allowed char in varname, end of var .31 cmp #'}' end of var? beq .50 jsr MEM.IsIDValid _,.,a-z,A-Z,0-9 ? bcc .32 yes, add to varname ldx ENV.VarLen bne .5 varname has already chars...end of var inx must be a $? or ?x.....go expand stx ENV.VarLen sta ENV.VarName bra .51 go Expand.... .32 ldx ENV.VarLen cpx #16 beq .11 varname longer than 15....ignore sta ENV.VarName,x inx stx ENV.VarLen bra .11 .5 dey last char was invalid...move back .50 ldx ENV.VarLen beq .52 var name is empty...start over .51 stz ENV.VarName,x phy save current index jsr ENV.GetValue ply restore index in string... .52 jmp .10 reset start flag and continue .8 ldx ENV.VarLen end of STR,are we in a var? beq .80 no...exit... stz ENV.VarName,x jsr ENV.GetValue yes, expand and add to STR .80 lda .88+1 working from our temp string ? beq .81 no... jsr K.FreeMem yes, discard.... .81 ldx ENV.BufLen stz K.Buf256,x >LDYAI K.Buf256 >SYSCALL StrDup bcs .9 stx .88+1 save this as temp string, in case of recurse .82 ldx #$ff SELF MODIFIED Did we expand something ? beq .88 jmp .1 Yes, start over with hPStr .88 ldx #$ff SELF MODIFIED * or exit with Y,A from STRDUP .9 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 filestat` * `>PUSHWI fullpath` * `>PUSHWI searchpath` * `>LDYAI filename` * ## RETURN VALUE * CC : success * DstBuf = FilePath * DstStat = S.STAT * CS : not found *\-------------------------------------- K.FileSearch pha >PULLW ENV.SearchPath >PULLW .2+1 DstBuf >PULLW .4+1 DstStat pla Y,A = filename jsr ENV.Search.YA 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 K.FileSearch.RTS rts *-------------------------------------- ENV.Search.LIB ldx #0 .HS 2C BIT ABS ENV.Search.DRV ldx #2 .HS 2C BIT ABS ENV.Search.PATH ldx #4 >STYA ZPPtr2 >LDYA ENV.VARS,x jsr K.GetEnv get value for Search Path bcs K.FileSearch.RTS >STYA ENV.SearchPath >LDYA ZPPtr2 ENV.Search.YA >STYA .4+1 >LDYA ENV.SearchPath jsr K.ExpandStr Y,A = Search Path, Expand it bcs .99 stx .98+1 >STYA .2+1 expanded search list ; stz .1+1 .1 ldy #$0 Self Modified Index in Search list string ldx #$0 .2 lda $ffff,y Self Modified, Search list string beq .3 end of string, try it.... iny cmp #':' beq .3 sta K.Buf256,x inx bra .2 .3 txa beq .98 String is empty....nothing to try sty .1+1 save current index ldy #$0 .4 lda $ffff,y Self Modified, Append Filename... sta K.Buf256,x beq .5 iny inx bra .4 .5 >LDYAI K.Buf256 jsr K.STAT.YA.JMP bcs .1 Failed...retry next path... lda K.S.STAT+S.STAT.P.TYPE cmp #S.FI.T.DIR Dir ? beq .1 jsr .98 Discard Expanded hSrch list clc .99 rts .98 lda #$ff SELF MODIFIED : Discard Expanded hSrch list jsr K.FreeMem lda #MLI.E.FNOTFND sec rts */-------------------------------------- * # PutEnv * Change or add an environment variable, string is 'NAME=VALUE' * ## C * `int putenv(char *string);` * ## ASM * **In:** * `>LDYA string` * `>SYSCALL putenv` * ## RETURN VALUE *\-------------------------------------- K.PutEnv >STYA ZPPtr1 NAME=VALUE ldy #0 .1 lda (ZPPtr1),y copy STR to K.Buf256 beq .9 cmp #'=' beq .2 sta K.Buf256,y iny bne .1 .2 lda #0 sta K.Buf256,y tya sec adc ZPPtr1 sta ZPPtr2 lda ZPPtr1+1 adc #0 sta ZPPtr2+1 >LDYAI K.Buf256 >STYA ZPPtr1 bra K.SetEnv.I .9 sec rts */-------------------------------------- * # SetEnv * Change or add an environment variable * ## C * `int setenv(const char *name, const char *value);` * ## ASM * **In:** * `>PUSHW value` * `>LDYA name` * `>SYSCALL setenv` * ## RETURN VALUE *\-------------------------------------- K.SetEnv jsr MEM.SPtr1PPtr2 K.SetEnv.I jsr K.UnsetEnv.I .1 jsr ENV.InitEnvP3 ZPPtr3 -> Env lda #1 sta ZPPtr4 stz ZPPtr4+1 ZPPtr4 = ENVSIZE = 1 .10 lda (ZPPtr3) End of ENV beq .15 jsr ENV.GetP3LenY jsr ENV.NextEnvP3Y jsr ENV.NextEnvP4Y bra .10 .15 ldy #$ff .16 iny lda (ZPPtr1),y bne .16 jsr ENV.NextEnvP4Y ZPPtr4 = ENVSIZE + VAR ldy #$ff .19 iny lda (ZPPtr2),y bne .19 jsr ENV.NextEnvP4Y ZPPtr4 = ENVSIZE + VALUE lda ZPPtr4 beq .20 inc ZPPtr4+1 .20 ldy #S.PS.ENVPAGECNT lda (pPs),y cmp ZPPtr4+1 bcs .22 env is large enough lda ZPPtr4+1 jsr ENV.Dup.A bcs .9 pha ldy #S.PS.hENV lda (pPs),y jsr K.Freemem pla ldy #S.PS.hENV sta (pPs),y txa dey S.PS.ENVPAGECNT sta (pPs),y bra .1 Start over .22 ldy #$ff .23 iny lda (ZPPtr1),y sta (ZPPtr3),y bne .23 jsr ENV.NextEnvP3Y ldy #$ff .24 iny lda (ZPPtr2),y sta (ZPPtr3),y bne .24 iny sta (ZPPtr3),y don't forget array ending 0 clc .9 rts */-------------------------------------- * # GetEnv * searches the environment list to find the environment variable name, * and returns a pointer to the corresponding value string. * ## C * `char *getenv(const char *name);` * ## ASM * **In:** * `>LDYA name` * `>SYSCALL getenv` * ## RETURN VALUE * CC : Y,A = PTR to VALUE (C-String) * CS : not found *\-------------------------------------- K.GetEnv >STYA ZPPtr1 jsr ENV.FindVarP1 bcs .9 jsr ENV.NextEnvP3 Skip NAME clc just in case ADC in NextEnvPtr3 disturb CC .9 >LDYA ZPPtr3 rts */-------------------------------------- * # UnsetEnv * Remove an environment variable * ## C * `int unsetenv(const char *name);` * ## ASM * **In:** * `>LDYA name` * `>SYSCALL unsetenv` * ## RETURN VALUE *\-------------------------------------- K.UnsetEnv >STYA ZPPtr1 Store VAR Name K.UnsetEnv.I jsr ENV.FindVarP1 bcs K.UnsetEnv.I.8 not found, quit jsr ENV.DelVarP3 Ptr3 -> ENVNAME K.UnsetEnv.I.8 clc K.UnsetEnv.I.9 rts *-------------------------------------- * PRIVATE *-------------------------------------- ENV.GetValue jsr ENV.ExpandSysVar bcc K.UnsetEnv.I.9 >LDYAI ENV.VarName jsr K.GetEnv bcs K.UnsetEnv.I.9 *-------------------------------------- ENV.AddYAToBuf >STYA ZPPtr3 *-------------------------------------- ENV.AddP3ToBuf ldx ENV.BufLen ldy #$ff dex .1 iny inx lda (ZPPtr3),y sta K.Buf256,x bne .1 stx ENV.BufLen rts *-------------------------------------- * ENV.ExpandSysVar * In: * ENV.VarLen,ENV.VarName * Out: * CC: Found * Append VALUE to K.Buf256 * CS: Not Found *-------------------------------------- ENV.ExpandSysVar ldx ENV.VarLen cpx #1 is name 1 char? bne .4 lda ENV.VarName jsr MEM.IsDigit $0...$9 ?? bcs .1 and #$0F jsr K.ArgV bcs K.UnsetEnv.I.8 Arg# is undefined, do not append anything jmp ENV.AddYAToBuf .1 ldx #ENV.SysVars.Cnt-1 .2 cmp ENV.SysVars,x beq .3 dex bpl .2 .9 sec rts .3 txa asl tax jmp (ENV.SysVarsJmp,x) .4 >LDYAI ENV.StrVars >STYA ZPPtr3 ldx #0 .5 lda (ZPPtr3) beq .9 cmp ENV.VarLen bne .7 tay .6 lda (ZPPtr3),y dey cmp ENV.VarName,y bne .7 tya bne .6 jmp (ENV.StrVarsJmp,x) .7 inx inx lda (ZPPtr3) sec adc ZPPtr3 sta ZPPtr3 bcc .5 inc ZPPtr3+1 bra .5 *-------------------------------------- ENV.SysVars .AS "*#?@$!" ENV.SysVars.Cnt .EQ *-ENV.SysVars *-------------------------------------- ENV.SysVarsJmp .DA ENV.SysVarsArgs .DA ENV.SysVarsArgC .DA ENV.SysVarsRC .DA ENV.SysVarsPPID .DA ENV.SysVarsPID .DA ENV.SysVarsCPID *-------------------------------------- ENV.StrVars >PSTR "USERNAME" >PSTR "GECOS" >PSTR "HOME" >PSTR "SHELL" >PSTR "PWD" >PSTR "UID" >PSTR "GID" .DA #0 *-------------------------------------- ENV.StrVarsJmp .DA ENV.StrVarsSession .DA ENV.StrVarsSession .DA ENV.StrVarsSession .DA ENV.StrVarsSession .DA ENV.StrVarsPWD .DA ENV.StrVarsUID .DA ENV.StrVarsGID *-------------------------------------- ENV.StrVarsPWD ldy #S.PS.hPREFIX lda (pPS),y jsr K.GetMemPtr jmp ENV.AddYAToBuf *-------------------------------------- ENV.StrVarsUID ldy #S.USR.UID .HS 2C ENV.StrVarsGID ldy #S.USR.GID lda (pSession),y bra ENV.SysVarsNum ENV.StrVarsSession >DEBUG lda pSession clc adc #S.USR.NAME sta ZPPtr3 lda pSession+1 adc /S.USR.NAME sta ZPPtr3+1 .1 dex dex bmi .3 ldy #$ff .2 iny lda (ZPPtr3),y bne .2 tya sec adc ZPPtr3 sta ZPPtr3 bcc .1 inc ZPPtr3+1 bra .1 .3 jmp ENV.AddP3ToBuf *-------------------------------------- ENV.SysVarsArgC ldy #S.PS.ARGC .HS 2C ENV.SysVarsRC ldy #S.PS.RC .HS 2C ENV.SysVarsPPID ldy #S.PS.PPID .HS 2C ENV.SysVarsPID ldy #S.PS.PID .HS 2C ENV.SysVarsCPID ldy #S.PS.CPID lda (pPS),y ENV.SysVarsNum stz .2+1 stz .3+1 ldx #8 sed .1 asl pha .2 lda #$ff Self Modified adc .2+1 sta .2+1 .3 lda #$ff Self Modified adc .3+1 sta .3+1 pla dex bne .1 cld lda .3+1 beq .4 jsr ENV.AddAToBuf30 .4 lda .2+1 pha lsr lsr lsr lsr beq .5 jsr ENV.AddAToBuf30 .5 pla and #$0f .8 jsr ENV.AddAToBuf30 clc rts *-------------------------------------- ENV.SysVarsArgs lda #1 jsr K.ArgV bcs .8 >STYA ZPPtr3 .1 lda (ZPPtr3) beq .8 .2 jsr ENV.AddP3ToBuf jsr ENV.NextEnvP3 lda (ZPPtr3) beq .8 lda #' ' jsr ENV.AddAToBuf bra .2 .8 clc rts *-------------------------------------- * ENV.FindVarP1 * In: * ZPPtr1 -> NAME * Out: * CC: Found * ZPPtr1 -> NAME * ZPPtr3 -> ENV.NAME * CS: Not Found * ZPPtr1 -> NAME * ZPPtr3 -> PTR to Ending 0 *-------------------------------------- ENV.FindVarP1 jsr ENV.InitEnvP3 Store ENV .1 lda (ZPPtr3) beq .9 end of ENV ldy #$ff .2 iny lda (ZPPtr1),y cmp (ZPPtr3),y bne .3 ora #0 bne .2 .8 clc rts .3 jsr ENV.NextEnvP3x2 Skip NAME & VALUE bra .1 .9 sec rts *-------------------------------------- * ENV.DelVarP3 * In: * ZPPtr3 -> ENV.NAME to Discard *-------------------------------------- ENV.DelVarP3 >LDYA ZPPtr3 save actual Ptr >STYA ZPPtr4 jsr ENV.NextEnvP3x2 Skip NAME & VALUE .1 ldy #$ff .2 iny lda (ZPPtr3),y Move back CSTRs... sta (ZPPtr4),y bne .2 tya beq .8 we moved back ending \0 jsr ENV.NextEnvP3Y jsr ENV.NextEnvP4Y bra .1 .8 rts *-------------------------------------- ENV.InitEnvP3 ldy #S.PS.hENV lda (pPs),y jsr K.GetMemPtr >STYA ZPPtr3 Store ENV rts *-------------------------------------- ENV.NextEnvP3x2 jsr ENV.NextEnvP3 *-------------------------------------- ENV.NextEnvP3 jsr ENV.GetP3LenY *-------------------------------------- ENV.NextEnvP3Y tya sec adc ZPPtr3 sta ZPPtr3 bcc .8 inc ZPPtr3+1 .8 rts *-------------------------------------- ENV.GetP3LenY ldy #$ff .1 iny lda (ZPPtr3),y bne .1 rts *-------------------------------------- ENV.NextEnvP4Y tya sec adc ZPPtr4 sta ZPPtr4 bcc .8 inc ZPPtr4+1 .8 rts *-------------------------------------- ENV.AddAToBuf30 ora #$30 ENV.AddAToBuf ldx ENV.BufLen sta K.Buf256,x inc ENV.BufLen rts *-------------------------------------- * ENV.Dup * In: * A = ENV hMem To Duplicate * Out: * A = hMem to new ENV * X = Page Count *-------------------------------------- ENV.Dup ldy #S.PS.ENVPAGECNT lda (pPs),y ENV.Dup.A sta .8+1 Store target page Count ldy #0 jsr K.GetMem bcs .9 >STYA .2+1 Target Buffer phx save hMem jsr PS.SetMemOwner Set Ownership ldy #S.PS.hENV lda (pPs),y jsr K.GetMemPtr >STYA .1+1 ldy #S.PS.ENVPAGECNT get SOURCE page count lda (pPs),y tax ldy #0 .1 lda $ffff,y SELF MODIFIED .2 sta $ffff,y SELF MODIFIED iny bne .1 inc .1+2 inc .2+2 dex bne .1 .8 ldx #$ff SELF MODIFIED Target Page Count pla hMem clc .9 rts *-------------------------------------- ENV.VARS .DA .1 .DA .2 .DA .3 .1 .AZ "LIB" .2 .AZ "DRV" .3 .AZ "PATH" *-------------------------------------- MAN SAVE USR/SRC/SYS/KERNEL.S.ENV LOAD USR/SRC/SYS/KERNEL.S ASM