aboutsummaryrefslogtreecommitdiffstats
path: root/src/programs.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/programs.asm')
-rw-r--r--src/programs.asm181
1 files changed, 41 insertions, 140 deletions
diff --git a/src/programs.asm b/src/programs.asm
index 161ee2f..1a7092e 100644
--- a/src/programs.asm
+++ b/src/programs.asm
@@ -90,149 +90,13 @@ ProgRm:
INCBIN "c/rm.bin"
; -----------------------------------------------------------------------------
-; PROG_SH (bank 3) - a tiny shell.
-; prompt -> read a line (with echo) -> match a command -> fork+exec+wait.
+; PROG_SH (bank 3) - the shell, now written in C (c/sh.c): parses >/</| and
+; drives fork+exec+wait with I/O redirection. Command lookup + StrEqual/SkipName
+; live in the kernel now (sys_lookup + NameTable + shell_lib).
; -----------------------------------------------------------------------------
SECTION "prog_sh", ROMX[$4000], BANK[3]
ProgSh:
-.prompt
- ld de, .ps1
- ld b, 2
- ld c, SYS_WRITE
- rst $30
-
- ; read a line into SH_LINEBUF, echoing as we go
- ld hl, SH_LINEBUF
-.rd
- push hl ; syscalls clobber HL (trap uses it to dispatch)
- ld c, SYS_READ
- rst $30 ; A = input byte
- pop hl
- cp $04
- jr z, .eof ; Ctrl-D / EOF: exit the shell
- cp $0D
- jr z, .eol
- cp $0A
- jr z, .eol
- ld [hl], a ; store in the line buffer (A preserved)
- inc hl
- ld [$FF01], a ; echo the char straight to serial
- ld a, $81
- ld [$FF02], a
- ld a, l
- cp LOW(SH_LINEBUF) + SH_MAXLINE - 1
- jr c, .rd ; keep reading unless the buffer is full
-
-.eof
- ld b, 0
- ld c, SYS_EXIT ; exit init/shell -> system idle
- rst $30
-
-.eol
- ld [hl], 0 ; NUL-terminate
- ld de, .crlf
- ld b, 2
- ld c, SYS_WRITE
- rst $30
- ld a, [SH_LINEBUF]
- or a
- jp z, .prompt ; empty line
-
- ; split off the first word: replace the first space with a NUL so command
- ; matching sees just the command, and the args survive at SH_LINEBUF+n
- ; (inherited by the child through fork, read back via main(char *args)).
- ld hl, SH_LINEBUF
-.split
- ld a, [hl]
- or a
- jr z, .lookup ; no space -> no args
- cp $20
- jr z, .cut
- inc hl
- jr .split
-.cut
- ld [hl], 0 ; isolate the command word
-
-.lookup
- ; look the command up in the table
- ld de, .cmdtab
-.scan
- ld a, [de]
- or a
- jr z, .unknown ; empty name = end of table
- push de
- ld hl, SH_LINEBUF
- call StrEqual ; Z set if equal
- pop de
- jr z, .match
- call SkipName ; DE -> NUL after this name
- inc de ; -> program id
- inc de ; -> next entry
- jr .scan
-
-.match
- call SkipName
- inc de ; DE -> program id
- ld a, [de]
- ld [SH_PROGID], a
- ld c, SYS_FORK
- rst $30
- or a
- jr z, .exec
- ld c, SYS_WAIT ; parent: reap the command
- rst $30
- jp .prompt
-.exec
- ld a, [SH_PROGID]
- ld b, a
- ld c, SYS_EXEC
- rst $30 ; child becomes the command
-
-.unknown
- ld de, .huh
- ld b, 3
- ld c, SYS_WRITE
- rst $30
- jp .prompt
-
-.ps1
- db "$ "
-.crlf
- db $0D, $0A
-.huh
- db "?", $0D, $0A
-.cmdtab
- db "worker", 0
- db PROG_WORKER
- db "hello", 0
- db PROG_HELLO
- db "chello", 0
- db PROG_CHELLO
- db "echo", 0
- db PROG_ECHO
- db "true", 0
- db PROG_TRUE
- db "false", 0
- db PROG_FALSE
- db "uname", 0
- db PROG_UNAME
- db "pid", 0
- db PROG_PID
- db "cat", 0
- db PROG_CAT
- db "wc", 0
- db PROG_WC
- db "head", 0
- db PROG_HEAD
- db "args", 0
- db PROG_ARGS
- db "ls", 0
- db PROG_LS
- db "save", 0
- db PROG_SAVE
- db "rm", 0
- db PROG_RM
- db 0 ; terminator
+ INCBIN "c/sh.bin"
; -----------------------------------------------------------------------------
; Shell string helpers (ROM0, always mapped).
@@ -298,3 +162,40 @@ ProgramTable::
dw ProgSave
db LOW(BANK(ProgRm)), HIGH(BANK(ProgRm))
dw ProgRm
+
+; -----------------------------------------------------------------------------
+; NameTable (ROM0) - command name -> program id, searched by sys_lookup.
+; -----------------------------------------------------------------------------
+SECTION "nametab", ROM0
+NameTable::
+ db "worker", 0
+ db PROG_WORKER
+ db "hello", 0
+ db PROG_HELLO
+ db "chello", 0
+ db PROG_CHELLO
+ db "echo", 0
+ db PROG_ECHO
+ db "true", 0
+ db PROG_TRUE
+ db "false", 0
+ db PROG_FALSE
+ db "uname", 0
+ db PROG_UNAME
+ db "pid", 0
+ db PROG_PID
+ db "cat", 0
+ db PROG_CAT
+ db "wc", 0
+ db PROG_WC
+ db "head", 0
+ db PROG_HEAD
+ db "args", 0
+ db PROG_ARGS
+ db "ls", 0
+ db PROG_LS
+ db "save", 0
+ db PROG_SAVE
+ db "rm", 0
+ db PROG_RM
+ db 0