Files
snark13 c71e249a4e Add full compiler toolchain, libc, examples and reference docs
First substantive commit: the entire Sprinter C compiler tree on top of
the bare README+gitignore initial commit.

What's in here:
  bin/sprinter-cc        — driver script invoking SDCC + linker + mkexe
  libc/                  — Sprinter-specific libc layer over ESTEX/BIOS
                           (conio, gfx, io, mem, stdio + headers)
  runtime/               — crt0 variants (default/small/banked/minimal)
                           + heap + bank trampolines
  toolchain/             — mkexe (SprintEXE packer, C + tests)
  examples/              — 30 demo programs (gfx, file I/O, env, time, …)
  lib/Makefile           — builds the libc archive (sprinter.lib)
  docs/                  — converted Sprinter manuals + asm reference samples
  third_party/           — solid-c reference compiler dump + sdcc setup script
  release_docs/          — packaging / release notes

gitignore overhaul:
  • Drop dangerous blanket patterns: *.asm (would hide docs/samples/*.asm)
    and *.exe (case-insensitive match was hiding third_party/solid-c/*.EXE
    on macOS APFS).  Replaced with examples/*/*.{asm,exe,…} and lib/*.lib.
  • Restore tracking of toolchain/mkexe/tests/{one,big}.bin — those are
    INPUT fixtures, not build outputs.
  • Collapse the duplicated SDCC/C/Sdcc sections into one section per
    concern (build outputs / vendored / OS-junk).
  • Add .sprinter-cc-*/, build/ (catches lib/build/ too), .claude/.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 16:13:21 +03:00

7.1 KiB
Raw Permalink Blame History

Sprinter C Compiler — Release Notes

v1.0 (2026-06-01)

First public release. Production-ready toolchain for writing C programs that target Sprinter / ESTEX DSS. Built on top of vendored SDCC 4.5; this repository adds everything Sprinter-specific.

Highlights

  • One-line builds: sprinter-cc -o foo.exe foo.c — pulls in crt0, libsprinter, packs the resulting .ihx into a SprintEXE.
  • 27 working examples covering every API surface — used as regression tests while the toolchain was developed.
  • Five memory modes (tiny / small / big / huge / manual) handle programs from a few KB up to 32 KB of code + arbitrarily many 16 KB banks.
  • Full Sprinter API coverage: console, files & directories, environment, date/time, mouse, graphics (both 320×256×256 and 640×256×16 modes including the hardware accelerator), bitmap-font text, banking, paging.

Component versions

  • SDCC: 4.5.0 (vendored binary)
  • SprintEXE format: as documented in docs/converted/ProgrammerManual.txt
  • MAME: 0.283 with sprinter driver (vendored at mame/v306/mame.arm)
  • DSS / ESTEX: 1.71.57 (matches mame/v306/IMG/dss171u.img)

What's included

Toolchain:

  • bin/sprinter-cc — Bash driver
  • toolchain/mkexe/mkexe — host C utility, packs .ihx.exe
  • toolchain/check_banks.py — post-link bank size enforcement

Runtime (runtime/):

  • crt0.s — default startup for tiny / big modes, parses argv
  • crt0_minimal.s — opt-out for very small programs (no argv)
  • crt0_small.s — for small / huge modes, allocates W2 via ESTEX $3A
  • crt0_banked.s — parameterised: handles W3 banks (huge) or W1 banks (big) via assemble-time BANK_W1 flag
  • bank.s___sdcc_bcall_ehl trampoline (banking-aware, preserves uint8_t return value in A)
  • heap.s + heap_top.s — 32 KB W2-resident heap, configurable upper bound via sprinter-cc --stack-size

Libraries (libc/):

  • libsprinter.lib archives: io (open/read/lseek/close/unlink/stat/atexit/setjmp/ errno/sleep/time/env/conio/fsdir/dir/mouse), stdio (putchar/puts/getchar/print_hex/ file/cprintf/solid_helpers), mem (mem_alloc/bank_io), gfx (gfx_core/gfx_lines/ gfx_16/gfx_text)

Headers (libc/include/):

  • Standard: stdio.h, unistd.h, fcntl.h, errno.h, time.h, sys/stat.h
  • Sprinter-specific: conio.h, gfx.h, mouse.h, dir.h, sprinter.h, sprinter_exit.h, sprinter_mem.h
  • Compatibility: sprinter_compat.h — Solid-C aliases and types

Examples (27 in examples/):

  • I/O: hello, argv, cat, seek, ls, filetest, stattest, errno
  • Memory & banking: mem_test, malloc, banked, bankedbg, banklocl
  • Mouse: mouse, gfx_mous
  • Graphics: gfx_demo, gfx_d16, gfx_text
  • Misc: timedir, ptime, openenv, conio, attrprob, strtest, stdlib, assrtest, rt_test

Documentation (docs/):

  • TODO.md — roadmap, v2 plans
  • solid_c_compatibility.md — Solid-C compatibility gap analysis
  • im2_isr_design.md — interrupt design (v2)
  • converted/ — searchable plain-text copies of original Russian documentation

Notable design decisions

  • DSS allocates pages by program size< 16 KB programs get only one 16 KB page. Memory modes encode the four possible layouts.
  • One libsprinter.lib for all modes — SDCC's linker drops unused .rel members, so a tiny hello program only pulls in what it needs (~700 bytes overhead).
  • Banking trampoline ABI: 1-byte saved page + 2-byte bjump return between the bcall ret and the callee's stack arguments. pop bc; out (c), b on the way back preserves A (a previous version clobbered A and silently lost uint8_t return values).
  • Text I/O is Turbo-C-style split: puts/printf/putchar (fast, via PCHARS) ignore text attribute; cputs/cprintf/putch apply g_text_attr. Same convention as Borland C 2.x — programs port over with minimal changes.
  • Graphics accelerator: the LD D,D / LD C,C / LD E,E / LD B,B instruction trick is wrapped in self-modifying-code primitives in gfx_lines.c (the block length byte must literally follow LD A,#imm; we patch it at runtime).
  • Mouse cursor format (verified empirically): 1 byte per pixel, 0xFF = transparent; the driver stores the bitmap in a dedicated video bank.
  • Video mode bitmaps: BIOS font is interleavedbyte[r*256 + c], not byte[c*8 + r] as the obvious reading suggests.

Limitations / known issues

  • No interrupt handlers in v1 — scheduled for v2. examples/rt_test uses busy-wait sleep via ESTEX $30 instead.
  • MAME's mouse driver stubs $0E GET_SENSITIVE — returns 0 instead of the current value. Workaround: always call mouse_set_sensitivity(h, v) with known values at startup; don't trust mouse_get_sensitivity_*() reads.
  • MAME's mouse driver $0B RETURN_CURSOR — writes the bitmap to the IX buffer but does not update the H/L/D/E result registers, so mouse_get_cursor() returns width/height/hot_x/hot_y as 0.
  • Several Solid-C functions not yet ported — see docs/solid_c_compatibility.md for the categorised list.
  • No fprintf / scanf family — workaround: sprintf(buf, ...) + fputs(buf, fp).
  • No double-buffering wrapper — Sprinter hardware supports it (port 0xC9), the user-facing wrapper is part of the v2 BGI-style API.

Migration notes from pre-1.0 trees

If you were tracking the project during development:

  • All example directories were renamed to satisfy 8.3 filenames on the floppy: banked_big → bankedbg, seek_demo → seek, malloc_test → malloc, time_dir_test → timedir, bank_local_data → banklocl, gfx_demo16 → gfx_d16, gfx_text_demo → gfx_text, gfx_mouse_test → gfx_mous, etc.
  • puts / putchar no longer apply g_text_attr (switched to fast PCHARS). Programs that depended on coloured stdio must use cputs / cprintf / putch instead, or call textattr(...) followed by clrscr.
  • runtime/bank.s is no longer bundled in sprinter.lib — it's assembled per-build by sprinter-cc with the right BANK_W1 flag for the chosen memory mode.

Acknowledgements

  • Peters Plus team (Иван Мак, Дмитрий Паринов) for designing Sprinter and publishing the architecture / BIOS / DSS documentation that made this toolchain possible.
  • Dmitry M. for the z88dk +pps Sprinter target — first proof-of-concept for cross-compiling C to SprintEXE; several conventions were borrowed.
  • The SDCC team for the Z80 backend that does the heavy lifting.
  • The MAME team for emulating the Sprinter Sp2000 well enough for full toolchain regression testing without hardware.

v2.0 (planned)

Scope:

  1. IM2 interrupt handlers (irq_install / irq_remove) — design in docs/im2_isr_design.md
  2. Turbo-C-style BGI graphics API (initgraph / setcolor / circle / getimage / putimage / setviewport / setlinestyle / ...)
  3. Audio API (AY-3-8910 + COVOX, requires IM2)
  4. ISA-8 slot drivers (sound, network — requires IM2)
  5. Remaining Solid-C compatibility (Phase 2/3 in docs/solid_c_compatibility.md): ungetc, getdate/gettime/setdate/settime, absread/abswrite, scanf family, fdopen / freopen / fclosall