#!/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: usr/build.sh (run from the repo root) set -e SRC="$1"; OUT="$2"; B=build/usr/obj LIBDIR=/usr/share/sdcc/lib/sm83 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. # TRAP: only _CODE/_DATA have pinned bases. sm83.lib modules (long div/mod/ # shift helpers) link into their own areas, which sdldgb places after _DATA - # i.e. code in the $A000 RAM window ("buffer too small" from makebin, or # garbage at runtime). Don't use long division/shifts in programs; see # usr/uptime.c for the inlined-arithmetic workaround. sdldgb -n -m -w -j -i "$B/prog.ihx" \ -b _CODE=0x4000 -b _DATA=0xa000 \ -k "$LIBDIR" -l sm83 \ "$B/crt0.rel" "$B/libc.rel" "$B/libc_c.rel" "$B/prog.rel" makebin -Z -p "$B/prog.ihx" "$B/prog.bin" dd if="$B/prog.bin" of="$OUT" bs=1024 skip=16 count=16 2>/dev/null echo "wrote $OUT ($(wc -c < "$OUT") bytes); entry:" grep -iE ' _start| _main' "$B/prog.map" | head -2