PR#3 PREFIX /A2OSX.BUILD NEW INC 1 AUTO 6 .LIST OFF *-------------------------------------- CMD.Init >LDYAI CmdLine.MAX+1 >SYSCALL GetMem.YA bcs .9 txa >STA.G hCmdBuf .9 rts *-------------------------------------- * ZPCMDBuf : Remove extra SPACE & comment *-------------------------------------- Cmd.Parse >LDYA ZPCMDBuf >STYA ZPPtr1 ldy #0 lda (ZPCMDBuf) empty line...quit beq .9 .1 jsr Cmd.Parse.NextC beq .8 no more char, exit cmp #' ' skip leading spaces beq .1 cmp #'#' Comment ? beq .8 ignore remaining chars .3 sta (ZPCMDBuf),y add char to buffer iny jsr Cmd.Parse.NextC beq .8 cmp #' ' bne .3 sta (ZPCMDBuf),y add One SPACE to buffer iny .5 jsr Cmd.Parse.NextC beq .8 cmp #' ' beq .5 skip additional spaces bne .3 no more space, add next word... .8 lda #0 sta (ZPCMDBuf),y .9 tya >STA.G CmdBuflen rts Cmd.Parse.NextC lda (ZPPtr1) beq .8 inc ZPPtr1 bne .8 inc ZPPtr1+1 never Z .8 rts *-------------------------------------- * ZPCMDBuf-> Command line (formatted & not empty) *-------------------------------------- Cmd.Exec lda #0 >STA.G CMD.bStartProc >STA.G CMD.hFullpath >LDYA ZPCMDBuf >SYSCALL ExpandStr.YA >STYA ZPPtr1 Ptr to CMD ARGS txa >STA.G CMD.hCmdLine >LDYA L.INTCMDS >STYA ZPPtr2 ldx #0 .3 lda (ZPPtr2) beq Cmd.Exec.EXT Array Ending 0, must be an external Cmd.... ldy #$ff .4 iny lda (ZPPtr2),y bne .41 End of string in array lda (ZPPtr1),y Get CMD char... beq .8 both end with 0, found! cmp #' ' beq .8 we reached space between CMD & ARGS.... .41 lda (ZPPtr1),y Get CMD char... beq .61 end of CMD.....too short... cmp #' ' beq .61 we reached space between CMD & ARGS.... cmp #'a' To Uppercase bcc .5 cmp #'z'+1 bcs .5 eor #$20 .5 cmp (ZPPtr2),y beq .4 .61 iny lda (ZPPtr2),y bne .61 .7 inx inx tya sec adc ZPPtr2 sta ZPPtr2 bcc .3 inc ZPPtr2+1 bra .3 .8 jsr Cmd.Exec.Split X unmodified jmp (J.INTCMDS,x) Found an internal Cmd... *-------------------------------------- Cmd.Exec.Done php pha >LDA.G CMD.hCmdLine >SYSCALL FreeMem.A >LDA.G CMD.hFullpath beq .1 >SYSCALL FreeMem.A .1 pla plp rts *-------------------------------------- Cmd.Exec.EXT jsr Cmd.Exec.Split lda (ZPPtr1) cmp #'/' Command line is already full path, no search bne .1 >LEA.G CMD.Stat >PUSHYA >PUSHW ZPPtr1 >SYSCALL STAT bcs Cmd.Exec.Done >LDYA ZPPtr1 bra .4 .1 >LDYA L.ENV.PATH push ENVNAME=PATH for search >SYSCALL GetEnv.YA get value for ENV=PATH bcs .2 No PATH, try in CD jsr Cmd.Exec.EXT.Search bcc .3 .2 ldy #S.PS.hPREFIX not found, try in CD lda (pPs),y >SYSCALL GetMemPtr.A jsr Cmd.Exec.EXT.Search bcs .99 .3 >LDYA ZPCMDBuf .4 >SYSCALL NewStr.YA bcs .99 txa >STA.G CMD.hFullpath ldy #CMD.Stat+S.STAT.P.TYPE lda (pData),y cmp #$04 TXT File ? beq Cmd.Exec.EXT.TXT cmp #$06 BIN File ? beq Cmd.Exec.EXT.BIN cmp #$ff SYS File ? bne .9 bra * .9 lda #SYSMGR.ERRSYN sec .99 jmp Cmd.Exec.Done *-------------------------------------- * TXT : Launch "/PATH/SHELL /PATH/CMD ARGS" *-------------------------------------- Cmd.Exec.EXT.TXT lda #0 Get arg[0] = /PATH/SHELL >SYSCALL GetArg.A >PUSHYA >PUSHW ZPCMDBuf >SYSCALL StrCpy jsr Cmd.Exec.EXT.SEP Add a space.... >LDA.G CMD.hFullpath >SYSCALL GetMemPtr.A >PUSHYA >PUSHW ZPCMDBuf >SYSCALL StrCat *-------------------------------------- * BIN : Launch "/PATH/CMD ARGS" *-------------------------------------- Cmd.Exec.EXT.BIN jsr Cmd.Exec.EXT.SEP Add a space.... >PUSHW ZPPTR2 >PUSHW ZPCMDBuf >SYSCALL StrCat .1 >LDA.G CMD.bStartProc asl >LDYA ZPCMDBuf bcs .2 startproc >SYSCALL ExecProcessNewEnvYA jmp Cmd.Exec.Done .2 >SYSCALL CreateProcessYA jmp Cmd.Exec.Done *-------------------------------------- Cmd.Exec.EXT.Search >PUSHYA push search list >PUSHW ZPPtr1 push CMD >PUSHW ZPCMDBuf push dest full path >LEA.G CMD.Stat >PUSHYA >SYSCALL FileSearch rts *-------------------------------------- Cmd.Exec.EXT.SEP ldy #$ff .1 iny lda (ZPCMDBuf),y bne .1 lda #' ' sta (ZPCMDBuf),y iny lda #0 sta (ZPCMDBuf),y rts *-------------------------------------- * Internal Commands *-------------------------------------- Cmd.Exec.CD lda (ZPPTR2) bne Cmd.Exec.CD1 Cmd.Exec.PWD ldy #S.PS.hPREFIX lda (pPs),y >SYSCALL GetMemPtr.A >SYSCALL PrintF.YA jmp Cmd.Exec.Done Cmd.Exec.CD1 lda #0 sta (ZPCMDBuf) cmp #'/' Full Path? beq .1 ldy #S.PS.hPREFIX no, init target prefix with actual prefix lda (pPs),y >SYSCALL GetMemPtr.A >PUSHYA >PUSHW ZPCMDBuf >SYSCALL StrCpy .1 >PUSHW ZPPTR2 Append ARG to buffer >PUSHW ZPCMDBuf >SYSCALL StrCat ldy #$ff ldx #'/' .10 tax iny lda (ZPCMDBuf),y bne .10 cpx #'/' beq .2 lda #'/' sta (ZPCMDBuf),y iny lda #0 sta (ZPCMDBuf),y .2 ldy #$ff path is something like : /dir1/../dir2/ .3 ldx #0 reset char counter .4 iny lda (ZPCMDBuf),y beq .8 cmp #'/' bne .4 .5 txa any char count? bne .51 no, start counting... inx bra .4 .51 inx cpx #2 do we have /xx/? bne .3 no, skip this token dey lda (ZPCMDBuf),y /yy/x./ ? dey cmp (ZPCMDBuf),y /yy/../ ? bne .3 cpy #3 /../ ? beq Cmd.Exec.ERRSYN illegal txa tay save end of /../ sec sbc #3 remove ../ tax .6 dex lda UsrBuf256,x Found beginning of dir before /../ cmp #'/' bne .6 .7 lda UsrBuf256,y strip dir/../ sta UsrBuf256,x cpy UsrBuf256 beq .71 iny inx bra .7 .71 stx UsrBuf256 bra .2 Start over... .8 cpx #1 beq .80 we have '/' go change prefix >LEA.G CMD.Stat >PUSHYA >PUSHWI UsrBuf256 >SYSCALL STAT bcs .9 ldy #CMD.Stat+S.STAT.P.TYPE lda (pData),y cmp #$0F Directory ? bne Cmd.Exec.ERRSYN .80 >LDYAI UsrBuf256 >SYSCALL NewStr.YA bcs .9 phx ldy #S.PS.hPREFIX lda (pPs),y >SYSCALL FreeMem.A pla ldy #S.PS.hPREFIX sta (pPs),y jsr SetPWD clc .9 jmp Cmd.Exec.Done *-------------------------------------- Cmd.Exec.ERRSYN lda #SYSMGR.ERRSYN sec jmp Cmd.Exec.Done *-------------------------------------- Cmd.Exec.STARTPROC lda (ZPPTR2) beq Cmd.Exec.ERRSYN lda #$ff >STA.G CMD.bStartProc >LDYA ZPPTR2 >STYA ZPPTR1 jmp Cmd.Exec.EXT *-------------------------------------- Cmd.Exec.SET lda (ZPPTR2) bne Cmd.Exec.SETVAR * No arg, print all ENV ldy #S.PS.hENV lda (pPs),y >SYSCALL GetMemPtr.A >STYA ZPPTR1 .1 lda (ZPPTR1) beq .8 Ending 0 ? ldy #$ff .2 iny lda (ZPPTR1),y bne .2 tya sec adc ZPPTR1 sta ZPPTR2 lda #0 adc ZPPTR1+1 sta ZPPTR2+1 >PUSHW ZPPTR2 Push value >PUSHW ZPPTR1 Push name >LDYA L.MSG.PRINTENV >SYSCALL PrintF.YA bcs .9 ldy #$ff .3 iny lda (ZPPTR2),y bne .3 tya sec adc ZPPTR2 sta ZPPTR1 lda #0 adc ZPPTR2+1 sta ZPPTR1+1 bra .1 .8 clc .9 jmp Cmd.Exec.Done Cmd.Exec.SETVAR ldy #0 lda (ZPPTR2),y iny cmp #'=' string is '=value' ? beq .99 syntax error .1 lda (ZPPTR2),y iny beq .3 no =, GetEnv cmp #'=' ARGS contains =, PutEnv bne .1 lda (ZPPTR2),y beq .2 "VAR=" go UnsetEnv >LDYA ZPPTR2 String is VAR=VALUE... >SYSCALL PutEnv.YA jmp Cmd.Exec.Done .2 dey String is "VAR=", Remove endig '=' sta (ZPPTR2),y >LDYA ZPPTR2 String is "VAR"... >SYSCALL UnsetEnv.YA jmp Cmd.Exec.Done * Print requested VAR .3 >LDYA ZPPTR2 >SYSCALL GetEnv.YA bcs .8 >PUSHYA push value >PUSHW ZPPTR2 push name >LDYA L.MSG.PRINTENV >SYSCALL PrintF.YA .8 clc .9 jmp Cmd.Exec.Done .99 jmp Cmd.Exec.ERRSYN *-------------------------------------- Cmd.Exec.DATE sec .HS 90 bcc Cmd.Exec.TIME clc php >LEA.G CMD.Time >SYSCALL TimeYA >PUSHWI ZPCMDBuf plp bcc .1 >PUSHW L.FMT.DATE bra .2 .1 >PUSHW L.FMT.TIME .2 >LEA.G CMD.Time >PUSHYA >SYSCALL StrFTime >LDYAI ZPCMDBuf >SYSCALL PrintF.YA bcs Cmd.Exec.ECHO.END bra Cmd.Exec.ECHO.CR *-------------------------------------- Cmd.Exec.ECHO lda (ZPPtr2) beq Cmd.Exec.ECHO.CR >LDYA ZPPtr2 >SYSCALL PrintF.YA Cmd.Exec.ECHO.CR lda #13 >SYSCALL PutChar.A bcs Cmd.Exec.ECHO.END lda #10 >SYSCALL PutChar.A Cmd.Exec.ECHO.END jmp Cmd.Exec.Done *-------------------------------------- Cmd.Exec.READ lda (ZPPtr2) beq .9 lda #0 >STA.G bSecureRead lda pData clc adc #CMD.VarName sta ZPPTR1 lda pData+1 adc #0 sta ZPPTR1+1 ldy #0 .1 lda (ZPPtr2),y beq .8 iny cmp #' ' beq .1 cmp #'-' bne .7 lda (ZPPtr2),y beq .9 iny cmp #'S' bne .2 lda #$80 >STA.G bSecureRead bra .1 .2 cmp #'P' bne .9 lda (ZPPtr2),y beq .9 iny cmp #' ' bne .9 lda (ZPPtr2),y beq .9 iny cmp #'"' bne .9 .3 lda (ZPPtr2),y beq .9 iny cmp #'"' beq .1 phy >SYSCALL PutChar.A ply bcs .99 bra .3 .9 jmp Cmd.Exec.ERRSYN .70 lda (ZPPtr2),y cmp #' ' beq .1 .7 lda (ZPPTR1) cmp #VarLen.MAX beq .9 inc sta (ZPPTR1) tay lda (ZPPtr2),y sta (ZPPTR1),y bne .70 .8 lda (ZPPTR1) No var name ? SYNERR beq .9 clc .99 jmp Cmd.Exec.Done *-------------------------------------- Cmd.Exec.SLEEP lda (ZPPtr2) beq .9 lda #Sleep clc adc pData tay lda /Sleep adc pData+1 >PUSHYA >PUSHW ZPPtr2 >SYSCALL AToI.YA bcs .9 jmp Cmd.Exec.Done .9 jmp Cmd.Exec.ERRSYN *-------------------------------------- Cmd.Exec.PAUSE lda #$FF >STA.G bPause clc jmp Cmd.Exec.Done *-------------------------------------- Cmd.Exec.EXIT lda #$FF >STA.G bExit clc jmp Cmd.Exec.Done *-------------------------------------- Cmd.Exec.Split ldy #$ff CMD Len .1 iny lda (ZPPtr1),y Get CMD char... beq .2 cmp #' ' we reached blank between CMD ARGS bne .1 lda #0 sta (ZPPtr1),y Cut CMD with the ending 0 iny .2 tya Y=CMD len+0, if ARGS="" Y= clc adc ZPPtr1 sta ZPPtr2 lda ZPPtr1+1 adc #0 sta ZPPtr2+1 ZPPtr2->ARGS or CMD ending 0 if empty rts *-------------------------------------- MAN SAVE /A2OSX.SRC/SBIN/SHELL.S.CMD LOAD /A2OSX.SRC/SBIN/SHELL.S ASM