diff options
Diffstat (limited to 'src/programs.asm')
| -rw-r--r-- | src/programs.asm | 181 |
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 |
