Files
Sprinter-SDCC/docs/solid_c_compatibility.md
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

Solid-C compatibility — gap analysis

Goal: if a function exists in Solid-C, it must exist in our libc (with the same name). If we deliberately use a different name, document the difference here.

Solid-C source (third_party/solid-c/INCLUDE/*.H) provides these functions. SDCC's z80.lib auto-includes most of the standard C library. This document tracks the remaining gaps.

Already covered (no work needed)

From our libc directly: atexit, chdir, clearerr, close, clrscr, cprintf, cputs, creat, ctime, asctime, exit, exit, fclose, feof, ferror, fflush, fgetc, fgets, ffirst, fnext, fopen, fputc, fputs, fread, fseek, fstat, ftell, fwrite, getch, getchar, getche, getcwd, getenv, gotoxy, kbhit, longjmp, lseek, mkdir, open, perror, printf, putch, putchar, putenv, puts, read, rewind, rmdir, setjmp, sleep, sprintf, stat, textattr, textbackground, textcolor, unlink, vprintf, vsprintf, write, wherex, wherey, set_videomode, get_videomode, mouse{init,show,hide,read,goto,bounds_x,bounds_y,refresh,text_cursor, load_cursor,get_cursor,get_sensitivity_x,get_sensitivity_y,set_sensitivity, video_mode_changed}.

Free from SDCC's z80.lib (auto-linked): abs, atof, atoi, atol, bsearch, calloc, free, isalpha, isdigit, islower, isupper, isspace, iscntrl, isgraph, isprint, ispunct, isalnum, isxdigit, malloc, memchr, memcmp, memcpy, memmove, memset, qsort, rand, realloc, srand, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, strstr, strtok, strtol, strtoul, tolower, toupper.

REAL gaps — to implement

Category A: trivial (one-liner aliases or small wrappers)

Solid-C Status Notes
getc(fd) macro alias #define getc(fp) fgetc(fp)
putc(c, fp) macro alias #define putc(c,fp) fputc(c,fp)
remove(name) alias #define remove(n) unlink(n) (POSIX semantic match)
seek(fd, off) alias int seek(fd, off) { return lseek(fd, off, SEEK_SET); }
tell(fd) alias int tell(fd) { return lseek(fd, 0, SEEK_CUR); }
ltell(fd, &lpos) wrapper wrap our lseek (32-bit)
home() macro alias #define home() gotoxy(0,0)
_setargv() crt0 does this provide stub or doc that crt0 covers it
_ffirst() alias already have ffirst with same semantic — alias macro
setmem(p, n, b) alias #define setmem(p,n,b) memset(p,b,n)
movmem(s, d, n) alias #define movmem(s,d,n) memcpy(d,s,n) (note arg order!)
min(a,b), max(a,b) macros #define min(a,b) ((a)<(b)?(a):(b)) etc.
isascii(c) macro #define isascii(c) ((unsigned)(c) < 128)
abort() wrapper void abort(void) { _exit(0xFF); }
strerr(n) alias rename existing strerror or alias
sysenv() wrapper already have env API, just alias

Category B: small new implementations

Solid-C Notes
dec8/dec16/dec32 print uint8/16/32 as decimal — use sprintf("%u") internally
hex8/hex16/hex32 print uint8/16/32 as hex — we have print_hex, just add hex16 and hex32
strlwr(s) in-place lowercase the string (returns s)
strupr(s) in-place uppercase the string
div(num, den) returns div_t { quot, rem } — trivial wrapper over / and %
getc/putc/ungetc one-byte putback for streams; ungetc needs 1-char buffer in FILE*
gets(buf) dangerous-but-Solid-C-has-it, simple fgets-wrapper
cgets(buf) line input via conio (no echo control — wrap getche loop)
inp(port) / outp(port,val) direct port I/O — Z80 IN/OUT, can be __sfr or inline asm wrappers
enable() / disable() __asm ei __endasm / __asm di __endasm
getdisk() / setdisk(d) ESTEX $02 CURDISK / $01 CHDISK

Category C: requires research / non-trivial work

Solid-C Notes
fdopen(fd, mode) / freopen needs FILE* expansion — currently we have unbuffered FILE; mid-effort
fclosall() iterate over all open FILE*'s and close them — depends on FILE table refactor
fgetpos(fp, &pos) / fsetpos wrappers over ftell/fseek with fpos_t type
bdos(a, hl) / bdosh(...) / intdos(&regs) Solid-C exposes raw ESTEX call interface. Our convention is typed wrappers — we may document the difference and skip these.
absread(disk, n, sect, buf) / abswrite absolute disk sector I/O — need ESTEX READ_SECT / WRITE_SECT (need to find function numbers)
_ffirst raw vs ffirst cooked Solid-C has two — raw "FilenameExt" format and cooked. Investigate if we want both.
ioctl(fd, ...) terminal control — Solid-C scope unclear, may skip
isatty(fd) trivial (always returns 0 — we have no tty handle), but check our FD numbers
brk(addr) / sbrk(n) classical Unix heap pointer manipulation; our heap is managed by SDCC _sbrk already? Investigate alias.
scanf / sscanf / fscanf parser — SDCC may have it in stdlib if requested. Check or add stub.
getdate / gettime / setdate / settime we have getdatetime/setdatetime; Solid-C splits into date/time structs. Build wrappers.

Category D: Mouse aliases — Solid-C ms_* names

Solid-C uses short names: ms_init/show/hide/stat/spos/ybnd/xbnd/scur/tcur/gcur/gsen/ssen/hard/vmod/ref + msgstat/mssgpos. All have the same semantics as our mouse_* functions.

Plan: add aliases via header macros so both names work:

#define ms_init    mouse_init
#define ms_show    mouse_show
/* ... etc */

Also Solid-C wraps state into MSSTAT (8-bit coords) and MSGSTAT (16-bit coords) structs. Our mouse_state_t already matches MSGSTAT semantics — add a typedef alias.

Documented differences (will NOT match Solid-C exactly)

These will be in docs/solid_c_diff.md:

  • bdos / bdosh / intdos — we don't expose raw ESTEX call interface; use typed wrappers
  • FILE* model — ours is unbuffered (currently); Solid-C may use buffered streams
  • Error code constants — Solid-C's EZERO/EINVFNC/etc. vs our errno table. Will provide compat aliases in errno.h.

Implementation plan

Phase 1 — trivial aliases/macros (~1 hour):

  • conio.h additions: home, inp, outp, enable, disable
  • stdio.h: getc, putc, remove, gets
  • string.h: setmem, movmem, strlwr, strupr, strerr
  • stdlib.h: min, max, div, abort, sysenv, dec8/16/32, hex8/16/32
  • ctype.h: isascii
  • io.h: seek, tell, ltell, _setargv stub
  • dir.h: _ffirst
  • mouse.h: ms_* aliases + MSSTAT/MSGSTAT typedefs
  • types.h: provide compat BOOL/uint/WORD/f_point types

Phase 2 — new impls (~2-3 hours):

  • ungetc, gets, cgets
  • getdisk/setdisk
  • getdate/gettime/setdate/settime (split datetime struct)

Phase 3 — investigate / decide (research first):

  • absread/abswrite (sector I/O)
  • scanf family (SDCC has it?)
  • brk/sbrk vs SDCC heap

Compatibility header

To make porting easier, add a single <sprinter_solid.h> that includes all the standard headers (stdio.h, string.h, conio.h, etc.) — Solid-C programs can #include <sprinter_solid.h> and have most functions available.

History

  • 2026-06-01 — initial gap analysis vs Solid-C v2004