diff options
| author | user <user@clank> | 2026-07-16 07:53:19 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-07-16 07:53:19 +0200 |
| commit | 7b5c532625a864a3fbaf76f44df6aa99b0d6861e (patch) | |
| tree | 6a6d67644993ccaea4b71bdc0881798887a6d1aa /README.md | |
| parent | libc: option parsing (hasflag/optval); wc -l/-w/-c, head -n N (diff) | |
| download | gbos-7b5c532625a864a3fbaf76f44df6aa99b0d6861e.tar.gz gbos-7b5c532625a864a3fbaf76f44df6aa99b0d6861e.tar.xz gbos-7b5c532625a864a3fbaf76f44df6aa99b0d6861e.zip | |
filesystem: a RAM FS (WRAMX) + ls/cat/save/rm; wc/head read files
- fs.asm: 8-slot RAM filesystem in WRAMX ($D000-$DFFF), name[8]+len[2]+data[502];
syscalls open/close/getb/putb/list/remove, seeded with a 'readme' at boot.
- libc: open/close/fgetc/fputc/flist/fremove wrappers + O_READ/O_WRITE/NOFD.
- tools: ls, save (stdin->file, one line), rm; cat/wc/head now take a file arg.
- fix: syscall dispatch clobbers A, so putb takes its byte in E (was reading the
handler's low address byte, 0xDC); ls NUL-terminates 8-char names.
- verified: save/cat/ls/rm cycle; wc readme -> '2 7 38'; head -n 1 readme.
- README: document the filesystem + the A-clobber ABI note.
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 45 |
1 files changed, 41 insertions, 4 deletions
@@ -214,15 +214,20 @@ unsigned char argc = argv_parse(argv, 8); /* args one two -> argc=3 */ | tool | what it does | |------|--------------| | `echo` | print its arguments (`echo hello world`) | -| `cat` | copy stdin to stdout until EOF (Ctrl-D / pipe end) | -| `wc` | count lines / words / chars of stdin | -| `head` | print the first *n* lines of stdin (`head 5`, default 10) | +| `cat` | print a file (`cat readme`) or copy stdin to stdout | +| `wc` | count lines/words/chars of a file or stdin (`wc -l readme`) | +| `head` | first *n* lines of a file or stdin (`head -n 5 readme`) | +| `ls` | list files | +| `save` | read a line from stdin into a file (`save notes`) | +| `rm` | delete a file (`rm notes`) | | `args` | argc/argv demo (`args one two three`) | | `uname`| print the system name | | `pid` | print the process's pid (decimal) | | `true` / `false` | exit 0 / 1 | | `chello` | the C "hello" demo | +Options use `hasflag`/`optval` in libc: `wc -l`/`-w`/`-c`, `head -n N`. + ``` $ echo C tools on a Game Boy C tools on a Game Boy @@ -247,6 +252,35 @@ so we use SDCC's native asxxxx path and INCBIN the blob instead. String literals with embedded control chars are also mangled in rgbds mode; C programs pass explicit lengths and emit newlines via `nl()`. +## Filesystem + +A tiny **RAM filesystem** lives in **WRAMX (`$D000-$DFFF`, 4 KiB)** — always +mapped in DMG mode and simultaneously accessible with a process's `$A000` data +bank, so the kernel copies between file and process memory with no bounce +buffer. 8 fixed slots of 512 bytes: `name[8]` + `len[2]` + `data[502]`. Seeded +with a `readme` at boot. + +Syscalls: `open` (4), `close` (5), `getb` (12), `putb` (13, byte in `E`), +`list` (14), `remove` (15). Libc: `open`/`close`/`fgetc`/`fputc`/`flist`/ +`fremove` (`c/libc.s`). + +``` +$ save notes +gbos has a filesystem now +$ cat notes +gbos has a filesystem now +$ wc notes +1 5 26 +$ ls +readme +notes +$ rm notes +``` + +> **ABI note:** the syscall trap indexes its jump table with `A`, so syscall +> args go in `B`/`DE`/`E` (never `A`) and results come back in `A`. That's why +> `putb` takes its byte in `E`. + ## Roadmap - [x] `fork`: copy parent's 8 KiB RAM bank → free bank, child returns 0 @@ -259,7 +293,10 @@ explicit lengths and emit newlines via `nl()`. - [x] CLI tools in C: `echo`, `cat`, `uname`, `pid`, `true`, `false` - [x] Makefile builds all C programs (a `CBLOBS` list) - [x] `wc`, `head`, and an `argc/argv` demo (`args`) + `argv_parse` in libc -- [ ] more tools (`rev`, `grep`), option parsing (`-n`), a RAM filesystem +- [x] option parsing (`hasflag`/`optval`): `wc -l/-w/-c`, `head -n N` +- [x] a RAM filesystem (WRAMX) + `ls`/`cat`/`save`/`rm`; `wc`/`head` read files +- [ ] more tools (`rev`, `grep`, `tail`), shell redirection (`>`/`|`) +- [ ] battery-backed files (move the FS to cart SRAM), directories - [ ] Preemptive scheduling: real context save in `TimerISR` → `hSwitchTo` - [ ] Use the `$D000-$DFFF` u-area (SVBK) for per-process kernel state / kstack - [ ] `brk`/heap allocator inside the task bank (heap up, stack down, collision = ENOMEM) |
