diff options
| author | user <user@clank> | 2026-07-18 00:38:38 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-07-18 00:38:38 +0200 |
| commit | ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c (patch) | |
| tree | e01e6c7c710a661defe2515ff9657f08cddcb283 | |
| parent | tools: gbtype prints hub errors to stderr and exits 1 (diff) | |
| download | gbos-ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c.tar.gz gbos-ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c.tar.xz gbos-ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c.zip | |
refactor: c/ -> usr/, compiled program blobs out of the source tree
Userland sources live in usr/ (fits the Unix theme better than 'c').
SDCC output .bin blobs land in build/usr/ with the other build artifacts
instead of littering the source dir; programs.asm INCBINs them from there.
Byte-identical ROM.
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 16 | ||||
| -rw-r--r-- | README.md | 20 | ||||
| -rw-r--r-- | src/programs.asm | 62 | ||||
| -rw-r--r-- | usr/args.c (renamed from c/args.c) | 0 | ||||
| -rw-r--r-- | usr/blk.c (renamed from c/blk.c) | 0 | ||||
| -rwxr-xr-x | usr/build.sh (renamed from c/build.sh) | 14 | ||||
| -rw-r--r-- | usr/cat.c (renamed from c/cat.c) | 0 | ||||
| -rw-r--r-- | usr/chat.c (renamed from c/chat.c) | 0 | ||||
| -rw-r--r-- | usr/chello.c (renamed from c/chello.c) | 0 | ||||
| -rw-r--r-- | usr/count.c (renamed from c/count.c) | 0 | ||||
| -rw-r--r-- | usr/crt0.s (renamed from c/crt0.s) | 0 | ||||
| -rw-r--r-- | usr/dhcp.c (renamed from c/dhcp.c) | 0 | ||||
| -rw-r--r-- | usr/echo.c (renamed from c/echo.c) | 0 | ||||
| -rw-r--r-- | usr/false.c (renamed from c/false.c) | 0 | ||||
| -rw-r--r-- | usr/gbos.h (renamed from c/gbos.h) | 0 | ||||
| -rw-r--r-- | usr/head.c (renamed from c/head.c) | 0 | ||||
| -rw-r--r-- | usr/irc.c (renamed from c/irc.c) | 0 | ||||
| -rw-r--r-- | usr/kill.c (renamed from c/kill.c) | 0 | ||||
| -rw-r--r-- | usr/libc.c (renamed from c/libc.c) | 0 | ||||
| -rw-r--r-- | usr/libc.s (renamed from c/libc.s) | 0 | ||||
| -rw-r--r-- | usr/ls.c (renamed from c/ls.c) | 0 | ||||
| -rw-r--r-- | usr/mkdir.c (renamed from c/mkdir.c) | 0 | ||||
| -rw-r--r-- | usr/necho.c (renamed from c/necho.c) | 0 | ||||
| -rw-r--r-- | usr/netd.c (renamed from c/netd.c) | 0 | ||||
| -rw-r--r-- | usr/netlib.h (renamed from c/netlib.h) | 0 | ||||
| -rw-r--r-- | usr/nslookup.c (renamed from c/nslookup.c) | 0 | ||||
| -rw-r--r-- | usr/pid.c (renamed from c/pid.c) | 0 | ||||
| -rw-r--r-- | usr/ping.c (renamed from c/ping.c) | 0 | ||||
| -rw-r--r-- | usr/ps.c (renamed from c/ps.c) | 0 | ||||
| -rw-r--r-- | usr/ptest.c (renamed from c/ptest.c) | 0 | ||||
| -rw-r--r-- | usr/resolve.h (renamed from c/resolve.h) | 0 | ||||
| -rw-r--r-- | usr/rm.c (renamed from c/rm.c) | 0 | ||||
| -rw-r--r-- | usr/save.c (renamed from c/save.c) | 0 | ||||
| -rw-r--r-- | usr/sh.c (renamed from c/sh.c) | 0 | ||||
| -rw-r--r-- | usr/sock.h (renamed from c/sock.h) | 0 | ||||
| -rw-r--r-- | usr/spin.c (renamed from c/spin.c) | 0 | ||||
| -rw-r--r-- | usr/true.c (renamed from c/true.c) | 0 | ||||
| -rw-r--r-- | usr/uname.c (renamed from c/uname.c) | 0 | ||||
| -rw-r--r-- | usr/wc.c (renamed from c/wc.c) | 0 | ||||
| -rw-r--r-- | usr/wget.c (renamed from c/wget.c) | 0 |
41 files changed, 57 insertions, 56 deletions
@@ -1,4 +1,3 @@ build/ *.gb *.sav -c/*.bin @@ -17,17 +17,19 @@ all: $(ROM) $(BUILD)/%.o: src/%.asm | $(BUILD) rgbasm $(ASFLAGS) -o $@ $< -# C programs: compiled with SDCC into ROM-bank blobs and INCBIN'd by programs.asm -CBLOBS := c/chello.bin c/echo.bin c/true.bin c/false.bin c/uname.bin \ - c/pid.bin c/cat.bin c/wc.bin c/head.bin c/args.bin \ - c/ls.bin c/save.bin c/rm.bin c/sh.bin c/ps.bin c/kill.bin c/spin.bin c/blk.bin c/mkdir.bin c/count.bin c/ptest.bin c/necho.bin c/wget.bin c/chat.bin c/netd.bin c/ping.bin c/nslookup.bin c/dhcp.bin c/irc.bin +# Userland C programs (usr/): compiled with SDCC into ROM-bank blobs under +# $(BUILD)/usr and INCBIN'd by programs.asm +PROGS := chello echo true false uname pid cat wc head args \ + ls save rm sh ps kill spin blk mkdir count ptest necho \ + wget chat netd ping nslookup dhcp irc +CBLOBS := $(patsubst %,$(BUILD)/usr/%.bin,$(PROGS)) $(BUILD)/programs.o: $(CBLOBS) # C programs also depend on the shared libc sources -$(CBLOBS): c/libc.c c/gbos.h +$(CBLOBS): usr/libc.c usr/gbos.h -c/%.bin: c/%.c c/crt0.s c/libc.s c/build.sh - sh c/build.sh $< $@ +$(BUILD)/usr/%.bin: usr/%.c usr/crt0.s usr/libc.s usr/build.sh + sh usr/build.sh $< $@ $(ROM): $(OBJS) rgblink -m $(BUILD)/gbos.map -n $(BUILD)/gbos.sym -o $@ $(OBJS) @@ -58,7 +58,7 @@ across a syscall (`push hl` / `pop hl`). Libc syscall stubs handle this for C. | 2 | read | ✅ blocking console input (1 byte) via external-clock serial | | 4,5,9,10 | open/close/kill/brk | ⛔ `ENOSYS` | -### The shell (`c/sh.c`) +### The shell (`usr/sh.c`) init `exec`s the shell (written in C). It reads a line, tokenizes it, and runs commands with **I/O redirection and pipes**: @@ -183,15 +183,15 @@ A real gbos would render to VRAM; serial is the zero-VRAM debug channel. ## 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/`): +This makes porting tiny Unix CLI tools realistic. The toolchain (`usr/`): -- `c/gbos.h` — the userland API (`writes`, `readc`, `nl`, `getpid`, `sexit`). -- `c/libc.s` — syscall wrappers (asxxxx asm). Each saves +- `usr/gbos.h` — the userland API (`writes`, `readc`, `nl`, `getpid`, `sexit`). +- `usr/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 +- `usr/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 +- `usr/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. @@ -206,9 +206,9 @@ void main(void) { ### libc -Syscall wrappers (`c/libc.s`): `writes`, `putc`, `puts`, `nl`, `strlen`, `readc` +Syscall wrappers (`usr/libc.s`): `writes`, `putc`, `puts`, `nl`, `strlen`, `readc` (returns `EOF`=4 at end of input), `getargs` (this program's argument string), -`getpid`, `sexit`. C helpers (`c/libc.c`, linked into every program): `putu` +`getpid`, `sexit`. C helpers (`usr/libc.c`, linked into every program): `putu` (print decimal), `atou` (parse decimal), `argv_parse` (tokenize into argc/argv). Arguments: the shell splits the command line at the first space and leaves @@ -220,7 +220,7 @@ char *argv[8]; unsigned char argc = argv_parse(argv, 8); /* args one two -> argc=3 */ ``` -### CLI tools (in `c/`) +### CLI tools (in `usr/`) | tool | what it does | |------|--------------| @@ -254,7 +254,7 @@ alpha beta ``` -Each tool is a separate `c/<name>.c`, built to a ROM-bank blob, INCBIN'd, and +Each tool is a separate `usr/<name>.c`, built to a ROM-bank blob, INCBIN'd, and registered in the program table + shell command table (`src/programs.asm`). **Toolchain gotchas found the hard way:** SDCC's `--asm=rgbds` mode mis-orders diff --git a/src/programs.asm b/src/programs.asm index 36f9d02..92c736b 100644 --- a/src/programs.asm +++ b/src/programs.asm @@ -47,101 +47,101 @@ ProgHello: ; ----------------------------------------------------------------------------- ; PROG_CHELLO (bank 5) - a program written in C, compiled with SDCC to a ; self-contained ROM-bank image (crt0 + libc + code) and included verbatim. -; Rebuild with: sh c/build.sh c/chello.c c/chello.bin +; Rebuild with: make (or: sh usr/build.sh usr/chello.c build/usr/chello.bin) ; ----------------------------------------------------------------------------- SECTION "prog_chello", ROMX[$4000], BANK[5] ProgChello: - INCBIN "c/chello.bin" + INCBIN "build/usr/chello.bin" SECTION "prog_echo", ROMX[$4000], BANK[6] ProgEcho: - INCBIN "c/echo.bin" + INCBIN "build/usr/echo.bin" SECTION "prog_true", ROMX[$4000], BANK[7] ProgTrue: - INCBIN "c/true.bin" + INCBIN "build/usr/true.bin" SECTION "prog_false", ROMX[$4000], BANK[8] ProgFalse: - INCBIN "c/false.bin" + INCBIN "build/usr/false.bin" SECTION "prog_uname", ROMX[$4000], BANK[9] ProgUname: - INCBIN "c/uname.bin" + INCBIN "build/usr/uname.bin" SECTION "prog_pid", ROMX[$4000], BANK[10] ProgPid: - INCBIN "c/pid.bin" + INCBIN "build/usr/pid.bin" SECTION "prog_cat", ROMX[$4000], BANK[11] ProgCat: - INCBIN "c/cat.bin" + INCBIN "build/usr/cat.bin" SECTION "prog_wc", ROMX[$4000], BANK[12] ProgWc: - INCBIN "c/wc.bin" + INCBIN "build/usr/wc.bin" SECTION "prog_head", ROMX[$4000], BANK[13] ProgHead: - INCBIN "c/head.bin" + INCBIN "build/usr/head.bin" SECTION "prog_args", ROMX[$4000], BANK[14] ProgArgs: - INCBIN "c/args.bin" + INCBIN "build/usr/args.bin" SECTION "prog_ls", ROMX[$4000], BANK[15] ProgLs: - INCBIN "c/ls.bin" + INCBIN "build/usr/ls.bin" SECTION "prog_save", ROMX[$4000], BANK[16] ProgSave: - INCBIN "c/save.bin" + INCBIN "build/usr/save.bin" SECTION "prog_rm", ROMX[$4000], BANK[17] ProgRm: - INCBIN "c/rm.bin" + INCBIN "build/usr/rm.bin" SECTION "prog_ps", ROMX[$4000], BANK[18] ProgPs: - INCBIN "c/ps.bin" + INCBIN "build/usr/ps.bin" SECTION "prog_kill", ROMX[$4000], BANK[19] ProgKill: - INCBIN "c/kill.bin" + INCBIN "build/usr/kill.bin" SECTION "prog_spin", ROMX[$4000], BANK[20] ProgSpin: - INCBIN "c/spin.bin" + INCBIN "build/usr/spin.bin" SECTION "prog_blk", ROMX[$4000], BANK[21] ProgBlk: - INCBIN "c/blk.bin" + INCBIN "build/usr/blk.bin" SECTION "prog_mkdir", ROMX[$4000], BANK[22] ProgMkdir: - INCBIN "c/mkdir.bin" + INCBIN "build/usr/mkdir.bin" SECTION "prog_count", ROMX[$4000], BANK[23] ProgCount: - INCBIN "c/count.bin" + INCBIN "build/usr/count.bin" SECTION "prog_ptest", ROMX[$4000], BANK[24] ProgPtest: - INCBIN "c/ptest.bin" + INCBIN "build/usr/ptest.bin" SECTION "prog_necho", ROMX[$4000], BANK[25] ProgNecho: - INCBIN "c/necho.bin" + INCBIN "build/usr/necho.bin" SECTION "prog_wget", ROMX[$4000], BANK[26] ProgWget: - INCBIN "c/wget.bin" + INCBIN "build/usr/wget.bin" SECTION "prog_chat", ROMX[$4000], BANK[27] ProgChat: - INCBIN "c/chat.bin" + INCBIN "build/usr/chat.bin" SECTION "prog_netd", ROMX[$4000], BANK[28] ProgNetd: - INCBIN "c/netd.bin" + INCBIN "build/usr/netd.bin" SECTION "prog_ping", ROMX[$4000], BANK[29] ProgPing: - INCBIN "c/ping.bin" + INCBIN "build/usr/ping.bin" SECTION "prog_nslookup", ROMX[$4000], BANK[30] ProgNslookup: - INCBIN "c/nslookup.bin" + INCBIN "build/usr/nslookup.bin" SECTION "prog_dhcp", ROMX[$4000], BANK[31] ProgDhcp: - INCBIN "c/dhcp.bin" + INCBIN "build/usr/dhcp.bin" SECTION "prog_irc", ROMX[$4000], BANK[32] ProgIrc: - INCBIN "c/irc.bin" + INCBIN "build/usr/irc.bin" ; ----------------------------------------------------------------------------- -; PROG_SH (bank 3) - the shell, now written in C (c/sh.c): parses >/</| and +; PROG_SH (bank 3) - the shell, now written in C (usr/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: - INCBIN "c/sh.bin" + INCBIN "build/usr/sh.bin" ; ----------------------------------------------------------------------------- ; Shell string helpers (ROM0, always mapped). diff --git a/c/build.sh b/usr/build.sh index 8034d87..93815d2 100755 --- a/c/build.sh +++ b/usr/build.sh @@ -1,15 +1,15 @@ #!/bin/sh # Build a gbos C program into a self-contained 16 KiB ROM-bank image. # SDCC native toolchain; crt0 linked FIRST so _start is the $4000 entry. -# usage: c/build.sh <prog.c> <out.bin> +# usage: usr/build.sh <prog.c> <out.bin> (run from the repo root) set -e -SRC="$1"; OUT="$2"; B=build/c +SRC="$1"; OUT="$2"; B=build/usr/obj LIBDIR=/usr/share/sdcc/lib/sm83 -mkdir -p "$B" -sdasgb -o "$B/crt0.rel" c/crt0.s -sdasgb -o "$B/libc.rel" c/libc.s -sdcc -msm83 -c -Ic c/libc.c -o "$B/libc_c.rel" -sdcc -msm83 -c -Ic "$SRC" -o "$B/prog.rel" +mkdir -p "$B" "$(dirname "$OUT")" +sdasgb -o "$B/crt0.rel" usr/crt0.s +sdasgb -o "$B/libc.rel" usr/libc.s +sdcc -msm83 -c -Iusr usr/libc.c -o "$B/libc_c.rel" +sdcc -msm83 -c -Iusr "$SRC" -o "$B/prog.rel" # link: crt0 first (=> _start at 0x4000), then libc, program, and sm83 lib sdldgb -n -m -w -j -i "$B/prog.ihx" \ -b _CODE=0x4000 -b _DATA=0xa000 \ diff --git a/c/chello.c b/usr/chello.c index f570b61..f570b61 100644 --- a/c/chello.c +++ b/usr/chello.c diff --git a/c/netlib.h b/usr/netlib.h index ec98eac..ec98eac 100644 --- a/c/netlib.h +++ b/usr/netlib.h diff --git a/c/nslookup.c b/usr/nslookup.c index 6a531b8..6a531b8 100644 --- a/c/nslookup.c +++ b/usr/nslookup.c diff --git a/c/resolve.h b/usr/resolve.h index 9aaccc1..9aaccc1 100644 --- a/c/resolve.h +++ b/usr/resolve.h |
