aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-16 07:53:19 +0200
committeruser <user@clank>2026-07-16 07:53:19 +0200
commit7b5c532625a864a3fbaf76f44df6aa99b0d6861e (patch)
tree6a6d67644993ccaea4b71bdc0881798887a6d1aa /README.md
parentlibc: option parsing (hasflag/optval); wc -l/-w/-c, head -n N (diff)
downloadgbos-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 '')
-rw-r--r--README.md45
1 files changed, 41 insertions, 4 deletions
diff --git a/README.md b/README.md
index 84c5c72..85a01d2 100644
--- a/README.md
+++ b/README.md
@@ -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)