c71e249a4e
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>
148 lines
7.1 KiB
Markdown
148 lines
7.1 KiB
Markdown
# 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 **interleaved** — `byte[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`
|