NEW PREFIX /A2OSX.BUILD AUTO 4,1 .LIST OFF *-------------------------------------- CMD.Init >LDYAI 256 >SYSCALL GetMem bcs .9 >STYA ZPCMDBuf txa >STA.G hCmdBuf .9 rts *-------------------------------------- CMD.Quit >LDA.G hCmdBuf beq .9 >SYSCALL FreeMem .9 rts *-------------------------------------- * in: * ZPCMDBuf : CString command line * out: * ZPArgVBuf : * /path/excmd\0 arg1\0 arg2\0 ... \0 * - or - * intcmd\0 arg1\0 arg2\0 ... \0 *-------------------------------------- Cmd.Parse >STZ.G CMD.bCmd lda #S.PS.F.HOLD+S.PS.F.DUPENV >STA.G CMD.PSFlags >LDYA ZPCMDBuf >SYSCALL ExpandStr bcs .9 phx save expanded string pha >PUSHW ZPCMDBuf pla Y,A = expanded string >SYSCALL Args2ArgV pla Get Back expanded string >SYSCALL FreeMem >LDYAI 256 >SYSCALL GetMem bcs .9 >STYA ZPArgVBuf txa >STA.G CMD.hArgVBuf lda #0 sta (ZPArgVBuf) lda (ZPCMDBuf) beq .8 .1 >LDA.G CMD.bCmd bne .6 we already have Cmd, go check args ldy #2 lda (ZPCMDBuf),y only one char ? bne .2 dey lda (ZPCMDBuf),y cmp #'.' leading dot ? bne .2 >lda.G CMD.PSFlags yes, child process will run in same ENV and #S.PS.F.DUPENV sta (pData),y bra .7 and skip this token .2 jsr CMD.CheckCmd bcc .7 success, skip token, already added by CheckCmd rts .6 jsr CMD.AddTokenToArgV bcs .9 .7 jsr CMD.NextCmdBufToken lda (ZPCMDBuf) bne .1 .8 clc .9 rts *-------------------------------------- * ZPCMDBuf-> argv[] (formatted & not empty) *-------------------------------------- Cmd.CheckCmd ldy #$ff .1 iny lda (ZPCMDBuf),y beq .2 cmp #'/' bne .1 >LDYA ZPCMDBuf found /, some path specified, External, no search >SYSCALL realpath bcs .9 txa >STA.G CMD.hCmdLine bra .6 go check type... .2 >LDYA L.CMD.INT jsr CMD.SearchInt no / found, search internal... bcs .4 not internal, search PATH jsr CMD.AddYAToArgV X unmodified bcs .9 txa >STA.G CMD.bCmd clc .9 rts .4 >LDYAI 256 Get a buffer for found path >SYSCALL GetMem bcs .9 txa >STA.G CMD.hCmdLine >LDYA L.ENV.PATH push ENVNAME=PATH for search >SYSCALL GetEnv get value for ENV=PATH bcs .5 no PATH, try workdir jsr Cmd.SearchExt bcc .6 found in PATH, go check Type .5 ldy #S.PS.hPREFIX not found, try in CD lda (pPs),y >SYSCALL GetMemPtr jsr Cmd.SearchExt bcs Cmd.CheckCmd.90 .6 >PUSHEA.G CMD.Stat >LDA.G CMD.hCmdLine >SYSCALL GetMemPtr >SYSCALL STAT bcs Cmd.CheckCmd.90 ldy #CMD.Stat+S.STAT.P.TYPE lda (pData),y cmp #S.FI.T.TXT beq Cmd.CheckCmd.TXT cmp #S.FI.T.BIN beq Cmd.CheckCmd.BIN cmp #S.FI.T.SYS beq Cmd.CheckCmd.SYS lda #E.SYN sec Cmd.CheckCmd.90 php pha >LDA.G CMD.hCmdLine >SYSCALL FreeMem pla plp Cmd.CheckCmd.RTS rts *-------------------------------------- * TXT : add "/PATH/SHELL" "/PATH/CMD" *-------------------------------------- Cmd.CheckCmd.TXT lda #0 >SYSCALL ArgV jsr CMD.AddYAToArgV bcs Cmd.CheckCmd.90 *-------------------------------------- * BIN : add "/PATH/CMD" *-------------------------------------- Cmd.CheckCmd.BIN >LDA.G CMD.hCmdLine >SYSCALL GetMemPtr jsr CMD.AddYAToArgV bcs Cmd.CheckCmd.90 lda #$ff >STA.G CMD.bCmd bra Cmd.CheckCmd.90 *-------------------------------------- Cmd.CheckCmd.SYS *-------------------------------------- bra * *-------------------------------------- Cmd.SearchExt pha phy >PUSHEA.G CMD.Stat >LDA.G CMD.hCmdLine >SYSCALL GetMemPtr >PUSHYA push dest full path ply pla >PUSHYA push search list >LDYA ZPCMDBuf push CMD >SYSCALL FileSearch rts *-------------------------------------- Cmd.Exec lda (ZPArgVBuf) cmp #'/' beq .1 >LDA.G CMD.bCmd tax jmp (J.CMD.INT,x) .1 >PUSHB.G CMD.PSFlags >LDYA ZPArgVBuf >SYSCALL exec rts *-------------------------------------- * STARTPROC : intcmd = 0 *-------------------------------------- Cmd.INT.STARTPROC >LDA.G CMD.PSFlags and #$ff^S.PS.F.HOLD sta (pData),y clc rts *-------------------------------------- Cmd.INT.PWD ldy #S.PS.hPREFIX lda (pPs),y >SYSCALL GetMemPtr >SYSCALL puts rts *-------------------------------------- Cmd.INT.CD ldx #1 jsr Cmd.GetArgX bcc .1 >LDYA L.ENV.HOME >SYSCALL GetEnv bcs Cmd.INT.PWD >SYSCALL ExpandStr bcs .9 bra .4 .1 >SYSCALL RealPath bcs .9 .4 >STYA ZPCMDBuf txa >STA.G CMD.hCmdLine **** MEMORY LEAK : CMD.hCmdLine not released ldy #1 lda (ZPCMDBuf),y beq .8 we have '/' >PUSHEA.G CMD.Stat >LDYA ZPCMDBuf >SYSCALL STAT bcs .9 >LDA.G CMD.Stat+S.STAT.P.TYPE cmp #S.FI.T.DIR bne Cmd.Exec.ERRSYN .8 >LDYA ZPCMDBuf >SYSCALL NewStr bcs .9 phx ldy #S.PS.hPREFIX lda (pPs),y >SYSCALL FreeMem pla ldy #S.PS.hPREFIX sta (pPs),y jmp SetPWD .9 rts *-------------------------------------- Cmd.Exec.ERRSYN lda #E.SYN sec rts *-------------------------------------- Cmd.INT.SET ldx #1 jsr Cmd.GetArgX bcc Cmd.INT.SETVAR * No arg, print all ENV ldy #S.PS.hENV lda (pPs),y >SYSCALL GetMemPtr >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 jsr Cmd.INT.SET.PRINT 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 rts *-------------------------------------- Cmd.INT.SETVAR >STYA ZPPTR1 >SYSCALL puts lda (ZPPTR1) cmp #'=' string is '=value' ? beq .99 syntax error ldy #0 .1 iny lda (ZPPTR1),y beq .3 no =, GetEnv cmp #'=' ARGS contains =, PutEnv bne .1 iny lda (ZPPTR1),y beq .2 "VAR=" go UnsetEnv >LDYA ZPPTR1 String is VAR=VALUE... >SYSCALL PutEnv rts .2 dey String is "VAR=", Remove ending '=' lda #0 sta (ZPPTR1),y >LDYA ZPPTR1 String is "VAR"... >SYSCALL UnsetEnv rts * Print requested VAR .3 >LDYA ZPPTR1 >SYSCALL GetEnv bcs .8 >PUSHYA push value >PUSHW ZPPTR1 push name jsr Cmd.INT.SET.PRINT .8 clc .9 rts .99 jmp Cmd.Exec.ERRSYN *-------------------------------------- Cmd.INT.SET.PRINT >PUSHBI 4 >LDYA L.MSG.PRINTENV >SYSCALL printf rts *-------------------------------------- Cmd.INT.DATE sec .HS 90 bcc Cmd.INT.TIME clc php >LEA.G CMD.Time >SYSCALL Time >PUSHEA.G CMD.Time plp bcc .1 >PUSHW L.FMT.DATE bra .2 .1 >PUSHW L.FMT.TIME .2 >LDYA ZPCMDBuf >SYSCALL StrFTime >LDYA ZPCMDBuf >SYSCALL puts rts *-------------------------------------- Cmd.INT.ECHO ldx #1 jsr Cmd.GetArgX bcs .71 >PUSHYA ldy #S.PS.hStdOut lda (pPs),y >SYSCALL fputs bcs .9 ldx #2 .1 phx jsr Cmd.GetArgX bcs .7 >PUSHYA lda #C.SPACE >SYSCALL putchar ldy #S.PS.hStdOut lda (pPs),y >SYSCALL fputs plx inx bcc .1 clc rts .7 plx .71 >LDA.G bECHO.N bmi .8 * >PUSHBI 0 * >LDYA L.MSG.ECHOCRLF * >SYSCALL printf * rts .8 clc .9 rts *-------------------------------------- Cmd.INT.READ lda (ZPCMDBuf) beq .9 lda #0 >STA.G bSecureRead >STA.G CMD.VarName.LEN lda pData clc adc #CMD.VarName sta ZPPTR1 lda pData+1 adc #0 sta ZPPTR1+1 .1 lda (ZPPtr2) beq .8 cmp #' ' bne .11 jsr Cmd.NextCharPtr2 bra .1 .11 cmp #'-' bne .7 jsr Cmd.NextCharPtr2 beq .9 cmp #'S' bne .2 lda #$80 >STA.G bSecureRead jsr Cmd.NextCharPtr2 beq .8 cmp #' ' bne .9 bra .1 .2 cmp #'P' bne .9 jsr Cmd.NextCharPtr2 beq .9 cmp #' ' bne .9 jsr Cmd.NextCharPtr2 beq .9 cmp #'"' bne .9 .3 jsr Cmd.NextCharPtr2 beq .9 cmp #'"' beq .1 >SYSCALL PutChar bcs .99 bra .3 .9 jmp Cmd.Exec.ERRSYN .7 >LDA.G CMD.VarName.LEN cmp #VarLen.MAX beq .9 pha inc sta (pData),y ply lda (ZPPtr2) sta (ZPPTR1),y iny lda #0 sta (ZPPTR1),y jsr Cmd.NextCharPtr2 beq .1 cmp #' ' beq .1 bra .7 .8 >LDA.G CMD.VarName.LEN No var name ? SYNERR beq .9 lda #$ff >STA.G bReadMode clc .99 rts *-------------------------------------- Cmd.INT.SLEEP lda (ZPCMDBuf) beq .9 >LDYA ZPCMDBuf >SYSCALL AToL bcs .9 >PULLL.G Sleep clc rts .9 jmp Cmd.Exec.ERRSYN *-------------------------------------- Cmd.INT.PAUSE lda #$FF >STA.G bPause clc rts *-------------------------------------- Cmd.INT.EXIT lda #$FF >STA.G bExit clc rts *-------------------------------------- Cmd.INT.IF >STZ.G CMD.IFNOT lda (ZPCMDBuf) beq .9 cmp #'!' bne .1 lda #$ff sta (pData),y Y = #CMD.IFNOT jsr Cmd.NextCharPtr2NB beq .9 cmp #'(' bne .9 jsr Cmd.NextCharPtr2NB beq .9 cmp #'-' -d -e -f bne .1 jsr Cmd.NextCharPtr2NB beq .9 .1 >DEBUG >LDYA ZPCMDBuf >SYSCALL puts rts .9 jmp Cmd.Exec.ERRSYN *-------------------------------------- CMD.NextCmdBufToken lda (ZPCMDBuf) inc ZPCMDBuf bne .1 inc ZPCMDBuf+1 .1 tax bne CMD.NextCmdBufToken rts *-------------------------------------- CMD.AddTokenToArgV >LDYA ZPCmdBuf CMD.AddYAToArgV >STYA ZPPtr1 >LDYA ZPArgVBuf >STYA ZPPtr2 .1 lda (ZPPtr2) scan to end of argV beq .6 .2 inc ZPPtr2 bne .3 inc ZPPtr2+1 .3 lda (ZPPtr2) bne .2 inc ZPPtr2 bne .4 inc ZPPtr2+1 .4 lda (ZPPtr2) bne .2 .6 ldy #$ff .7 iny * beq .9 lda (ZPPtr1),y sta (ZPPtr2),y bne .7 including str ending \0 iny * beq .9 sta (ZPPtr2),y arg[] ending \0 clc rts .9 lda #E.BUF sec rts *-------------------------------------- CMD.SearchInt >STYA ZPPtr2 ldx #0 .1 phx >PUSHW ZPPtr2 >LDYA ZPCMDBuf >SYSCALL StrCaseCmp bcs .2 plx >LDYA ZPPtr2 clc Found an internal Cmd... rts .2 inc ZPPtr2 bne .3 inc ZPPtr2+1 .3 lda (ZPPtr2) bne .2 inc ZPPtr2 bne .4 inc ZPPtr2+1 .4 plx inx inx lda (ZPPtr2) Array Ending 0, must be an external Cmd.... bne .1 sec rts *-------------------------------------- Cmd.GetArgX >LDYA ZPArgVBuf dex bmi .8 >STYA ZPPtr1 .1 jsr Cmd.NextArgPtr1 bcs .9 dex bpl .1 >LDYA ZPPtr1 .8 clc .9 rts *-------------------------------------- Cmd.NextArgPtr1 lda (ZPPtr1) beq .9 .1 inc ZPPtr1 bne .2 inc ZPPtr1+1 .2 lda (ZPPtr1) bne .1 inc ZPPtr1 bne .3 inc ZPPtr1+1 .3 lda (ZPPtr1) beq .9 .8 clc rts .9 sec rts *-------------------------------------- Cmd.NextCharPtr2NB .1 jsr Cmd.NextCharPtr2 beq .9 cmp #C.SPACE beq .1 .9 rts *-------------------------------------- Cmd.NextCharPtr2 inc ZPPtr2 bne .1 inc ZPPtr2+1 .1 lda (ZPPtr2) rts *-------------------------------------- MAN SAVE /A2OSX.SRC/SBIN/SHELL.S.CMD LOAD /A2OSX.SRC/SBIN/SHELL.S ASM