aboutsummaryrefslogtreecommitdiffstats
path: root/docs/internals.md
diff options
context:
space:
mode:
authoruser <user@clank>2026-09-24 12:48:37 +0200
committeruser <user@clank>2026-09-24 12:48:37 +0200
commitdc9dffb9069e32a1a0cf14883176544b234fc3e5 (patch)
tree4877daa5f01e98ac5d7e64d98c4144c94fa94a91 /docs/internals.md
parentterm: write the palette attribute for every re-rendered tile, not just the cu... (diff)
downloadgbos-dc9dffb9069e32a1a0cf14883176544b234fc3e5.tar.gz
gbos-dc9dffb9069e32a1a0cf14883176544b234fc3e5.tar.xz
gbos-dc9dffb9069e32a1a0cf14883176544b234fc3e5.zip
kernel: stat/fsstat/isatty syscalls, and O_APPEND
Four things userland had no way to ask for: - SYS_STAT: type, link count, size and inode for a path. The trap needs HL for its dispatch table, so a call taking both a path and an output buffer passes a request block - the shape SYS_NET already established. usr/stat.h wraps it, header-only like sock.h, because the block must live in the caller's RAM. - SYS_FSSTAT: blocks/inodes, total and free. The bitmaps are already cached write-through in fs_bmbuf, so this is the popcount boot_fs already prints. - SYS_ISATTY: is this process's stdin the console? The shell needs it to tell an interactive session from a script. - O_APPEND: open a file positioned at EOF. There is no seek syscall, so this is the only way to add to a file - without it nothing running ON the Game Boy can build a multi-line file, shell scripts included. Together these back ls -l, df, and `>>`.
Diffstat (limited to 'docs/internals.md')
-rw-r--r--docs/internals.md13
1 files changed, 13 insertions, 0 deletions
diff --git a/docs/internals.md b/docs/internals.md
index 3e27bd2..f9c5899 100644
--- a/docs/internals.md
+++ b/docs/internals.md
@@ -234,6 +234,13 @@ blocks 4.. data blocks
the damage once something else touched the neighbouring inode.
- **One-block data cache.** Two files open at once thrash it: `cp` of a 3 KiB
file alternates read/write blocks per byte and takes ~25s. Correct, slow.
+- **Open modes** are read / write / append. There is no seek syscall, so
+ `O_APPEND` (open at EOF) is the only way to add to a file - which is what
+ makes `>>`, and therefore building a multi-line script on the device,
+ possible at all.
+- **`sys_stat` / `sys_fsstat`** back `ls -l` and `df`. The syscall trap needs
+ HL for its dispatch table, so a call taking both a path and an output
+ buffer passes a request block, the shape SYS_NET already uses.
- **Paths + per-process cwd.** `open`/`mkdir`/`chdir`/`remove`/`ls` take paths
(absolute `/a/b` or relative `a/b`); each process has a cwd inode (`PROC_CWD`,
inherited on fork). Shell builtins: `cd`, and a cwd-aware prompt.
@@ -271,6 +278,12 @@ gbos programs are written in **C**, compiled with **SDCC** (the `sm83` port):
Arguments: the shell leaves `"cmd\0args\0"` at `$A000`; the child inherits it
through `fork`, `getargs()` returns the raw string, `argv_parse()` tokenizes.
+**Scripts.** `sh` is the same program interactively and as a script runner: it
+asks `isatty()` (SYS_ISATTY: is stdin the console?) and, when stdin is a file,
+drops the prompt and the echo. EOF ends that shell - only pid 1 on the console
+treats EOF as "power the machine off", which is why a script used to shut the
+Game Boy down when it reached the end. init runs `/rc` at boot if it exists.
+
**Toolchain gotchas found the hard way:** SDCC's `--asm=rgbds` mode mis-orders
instructions (emits `ld [hl],a` before the `ld hl,sp+0` that sets the pointer)
— so we use the native asxxxx path and INCBIN the blob instead. String