diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 41 |
1 files changed, 40 insertions, 1 deletions
@@ -169,13 +169,52 @@ A real gbos would render to VRAM; serial is the zero-VRAM debug channel. jump table, clobbering the `write()` buffer pointer passed in `DE`. Dispatch now indexes via `A`/`HL` only, preserving `DE`/`B` for the handler. +## Writing programs in C + +gbos programs can be written in **C**, compiled with **SDCC** (the `sm83` port). +This makes porting tiny Unix CLI tools realistic. The toolchain (`c/`): + +- `c/gbos.h` — the userland API (`writes`, `readc`, `nl`, `getpid`, `sexit`). +- `c/libc.s` — syscall wrappers (asxxxx asm). Each saves + `BC/DE/HL` around `rst $30`, since the trap clobbers them but SDCC expects + them preserved. +- `c/crt0.s` — entry: `call main`; then `exit(0)`. Linked first so `_start` is + the `$4000` entry. +- `c/build.sh` — compiles a `.c` with SDCC's **native** toolchain + (`sdasgb` + `sdldgb`), links code at `$4000`, and extracts the ROM-bank blob. + The Makefile INCBINs it and registers it as a program. + +```c +#include "gbos.h" +void main(void) { + writes("hello from C on gbos!", 21); nl(); + writes("my pid is ", 10); + { char d = getpid() + '0'; writes(&d, 1); } nl(); +} +``` + +``` +$ chello +hello from C on gbos! +my pid is 2 +``` + +**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 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()`. + ## Roadmap - [x] `fork`: copy parent's 8 KiB RAM bank → free bank, child returns 0 - [x] `exec`: point `PROC_ROMB` at a program in a ROM bank, reset stack, enter - [x] `exit` / `wait` / zombie reaping + cart-RAM bank recycling (free list) - [ ] `exec` refinement: copy `.data` from ROM + zero `.bss` for RW globals -- [ ] a real shell program: `fork`+`exec`+`wait` driven from the serial console +- [x] a real shell program: `fork`+`exec`+`wait` driven from the serial console +- [x] C toolchain: SDCC (sm83) + libc shim, C programs run as gbos processes +- [ ] grow libc (strings, a `main(argc,argv)`, more syscalls) + port real tools +- [ ] Makefile-drive multiple C programs (a `CPROGS` list) - [ ] 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) |
