A retarget of SDCC 4.5.0 (Small Device C Compiler) to the Epson S1C88, the 8-bit core of the
Pokémon Mini. sdcc88 reuses SDCC's C frontend and middle-end unchanged and adds one backend port in
src/s1c88/. It's an overlay on upstream SDCC, built with SDCC's own autotools — build.sh fetches
SDCC, drops in our port, registers it, and builds the whole SDK.
Status: complete and in maintenance. The full SDK builds and a multi-bank Pokémon Mini ROM compiles, links, and runs end-to-end:
sdcc -ms1c88 game.c -o game.ihx && romgen game.ihx game.minCodegen is fully retargeted from its z80 origin to the real S1C88 ISA (the faithful BA+HL register model, IY index args,
__far3-byte banked pointers, nativeDIV/MLT, the MAXIMUM-mode 3-byte CB:PC call model). The differential test suite is clean — no known correctness bugs. The bundled libc coversstring.h,stdlib.h,ctype.h, andprintf/sprintf(<stdio.h>). The numbered backlog is complete; the port is in maintenance.
The port started as a clone of SDCC's z80 backend (the z80 register model fits the S1C88 far better than the earlier stm8 base) and is fully re-pointed to the S1C88 register set, ABI, and instruction encodings.
Prebuilt SDK (Linux x64/arm64/x86, macOS arm64/x64, Windows x64/arm64): grab sdcc88-sdk-<version>-<platform>.tar.gz from the
Releases page (tagged releases; CI also attaches the same
tarballs to every green run as the sdcc88-sdk-<platform> artifacts). It's relocatable — unpack anywhere
and bin/sdcc -ms1c88 works with no environment setup. Built by scripts/package-sdk.sh, which proves
the staged tree self-contained (compile + link + romgen + emulator run from a temp dir under env -i)
before tarring.
# one-time deps (Debian/Ubuntu/WSL)
sudo apt-get install -y build-essential flex bison m4 gawk libboost-dev zlib1g-dev
./build.sh # fetch + overlay + patch + configure + build the whole SDK
build/sdcc-4.5.0/src/sdcc --version # -> "SDCC : s1c88 ... 4.5.0"./build.sh builds the complete SDK under build/sdcc-4.5.0/: the sdcc -ms1c88 driver plus bin/
(sdcpp, sdas88, sdldz80, romgen), the runtime (crt0.rel, s1c88.lib), and the device headers.
sdcc -ms1c88 foo.c preprocesses, compiles, and links for real.
The fast inner loop for codegen work is ./scripts/dev.sh (overlay src/s1c88 + make the compiler +
codegen smoke). In that loop only the compiler is rebuilt, so feed already-preprocessed C via --c1mode:
printf 'int add1(int x){return x+1;}\n' | \
build/sdcc-4.5.0/src/sdcc -ms1c88 --c1mode -o out.asmThe binary handoff is SDCC's own sdas/sdld family, retargeted for the S1C88:
sdas88— the assembler: full practical ISA, every form byte-verified againstdocs/s1c88/instruction-set.md, with same-module branch relaxation. Doubles as the codegen validator (./scripts/validate-s1c88.sh <file.asm>rejects any form the S1C88 can't encode).sdldz80— the linker: assemble→link plus bankedbcall/bjump(the linker resolves and writes the target's code bank), with default-on cross-module branch relaxation.romgen(tools/romgen.c) — packs the linked banks into a flat.minROM, or (with a.minxoutput /--minx) into the MINX debug container: a chunk-tree binary holding the ROM as sparse segments, symbols, a sorted source-line table, function extents, the full type graph + variable locations (registers / IX-relative stack / static), and the embedded source files — everything a debugging emulator needs with no filesystem and no text parsing (docs/s1c88/minx-format.md; validated/dumped byminxdump,tools/minxdump.c).crt0.rel+s1c88.lib+<pm.h>— the production startup, support + libc library, and device header, installed into the driver's lib/include dirs.
make -C examples/hello run # builds a real ROM and runs it on the bundled emulator./scripts/run-tests.sh builds once and runs every suite (TAP): byte-identical codegen (corpus-check),
host-vs-emulator differential (diff-test), on-emulator execution (emu-test), plus the toolchain smokes.
./scripts/opt-test.sh re-runs the execution suites under the user-facing option sets
(--opt-code-size, --opt-code-speed, --max-allocs-per-node, --nolospre --noinduction) — also a CI
job. main is protected — a PR can't merge unless this ci check is green.
Two options are deliberately rejected/unsupported: --fomit-frame-pointer (the allocator already omits
the frame automatically where profitable; forcing it reaches miscompiling stack-addressing paths, so the
port errors out) and --no-peep (the peephole doubles as the instruction legalizer on this port — without
it the asm contains z80-isms like add hl,sp that sdas88 rightly rejects).
src/s1c88/— the SDCC backend port (z80 clone, retargeted). Seesrc/s1c88/README.md.sdas/as88/— the S1C88 assembler backend (overlaid into SDCC'ssdastree).device/— the production runtime:lib/s1c88/crt0.s, the repo-owned libc sources,include/s1c88/pm.h.examples/hello/— a copy-me Pokémon Mini ROM template.build.sh— fetch/overlay/build orchestrator;scripts/— dev, validate, and toolchain build/test scripts.third_party/sdcc/*.patch— register the port + the banked-branch changes to sharedsdas/sdldsources.docs/s1c88/— how the compiler and processor work: distilled Epson references (architecture, ISA, addressing, memory model, toolchain) plus the design docsabi-decision.md(authoritative ABI),building-roms.md(end-user guide),banked-branch.md, andsdas88-retarget.md.
SDCC is GPL-2.0-or-later; as an SDCC derivative, sdcc88 is GPL-compatible.