- удалён глобальный скретч акселератора (_gfx_acc256.c); fill-сегменты (_gfx_hfill256/_gfx_vfill256) принимают аргументы в регистрах HL/C/B/E, вызываются только из asm raw-примитивов - новый _gfx_rectfill256: заливка прямоугольника через Horizontal_Size - raw-примитивы (plot/read/hspan/vspan/clear) переписаны под новый ABI - graphics.h: typedef color_t (uint8_t) для всех public color-функций - sprinter-cc: флаг --safe (линковка *_safe.lib при наличии) - CLAUDE.md/mame_interactive: авто-прогон тестов в MAME - gfx_demo: демонстрация rectfill Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.7 KiB
Sprinter C-Compiler — правила проекта
Target-слой SDCC 4.5 (z80) для компьютера Sprinter Sp2000: crt0, линковка, libc, mkexe. Общение и комментарии — на русском.
Сборка и проверка
make # tools + lib + libbgi + все тесты (45) + examples
make -C libc # только libc → lib/sprinter.lib
make -C libbgi # только BGI → lib/bgi256.lib (и bgi16.lib в Фазе 2)
make floppy # упаковать все .exe в mame/v306/IMG/mc.img
make size-check # размерный регресс: _CODE vs docs/size_baseline.tsv
make size-baseline # принять текущие размеры эталоном
Графика (BGI) — отдельная библиотека libbgi/ (см. ниже). Программа,
использующая graphics.h, собирается с --gfx 256 (или --gfx 16 в
Фазе 2): sprinter-cc подлинкует lib/bgi256.lib и добавит -I libbgi/include.
Одиночный тест: cd tests/<имя> && make run (пакует exe + EXTRA_DATA на
дискету и запускает MAME автоматически через toolchain/mame_interactive.py,
снимает скриншоты, выводит пути). Для сложных сценариев (диалог, несколько
шагов ввода) — прямой вызов:
python3 toolchain/mame_interactive.py tests/<имя>/<имя>.exe --snap T1,T2 --timeout T.
Скриншоты лежат в mame/v306/snap_auto/sprinter/ (читаются инструментом Read).
Подробности: docs/mame-autotest.md.
После правок libc/libbgi: пересборка от чистого листа (make -C libc clean
/ make -C libbgi clean) не обязательна — stale .rel чистятся
автоматически; make size-check обязателен (рост _CODE без причины —
регрессия).
Правила libc
- 1 публичная функция = 1 .c-модуль (линкер тянет .rel целиком —
гранулярность файлов = гранулярность DCE). Никакой группировки
«используются вместе». Internal-хелперы — тоже по одному на модуль
(
_-префикс); общие статики — в отдельные data-модули (_xxx_state.c); internal-заголовки (_file.h,_gfx.h, …) — рядом с исходниками, НЕ в libc/include. - Имя файла = имя функции. libc/Makefile собирает wildcard'ом — ничего регистрировать не надо.
- Комментарии — на русском; шапка модуля объясняет что/зачем + ABI.
- File-scope переменные НЕ инициализировать
= 0(crt0 зануляет _DATA; см. memory/sdcc_static_storage_gotcha). - asm-связки между модулями:
call/jp _global— ок;jr/djnzчерез границу и fall-through — НЕЛЬЗЯ (docs/libc-split-asm-cases.md). - Заголовки: сначала пробовать include_next-паттерн; полная замена SDCC-заголовка обязана дублировать его контракт (docs/libc-headers.md).
- Справочник API — docs/libc-reference.md (обновлять при добавлении функций).
ABI и платформа (кратко; детали в memory/)
- SDCC
__sdcccall(1): arg1 → HL (8-бит → A), arg2 → DE, остальные на стеке (callee-pops в __naked); возврат int/ptr в DE, uint8 в A. IX callee-saved (в __naked с IX — push/pop обязательны). - ESTEX (rst #0x10): CF=1 — ошибка, код в A →
call __errno_set; все регистры клобберятся (IX сохранять); стек обязан быть в W2. - BIOS (rst #0x08): строки/буферы в #4000-#BFFF.
- Квирки: ESTEX WRITE возвращает DE=0 на успехе (судить по CF/A); лимит 8 файловых манипуляторов, 9-й OPEN ВЕШАЕТ DSS (_fd_guard); ENV $46: A=0 = NOT FOUND.
- Перед обвинением компилятора/железа — подтвердить артефактом (сгенерированный .asm в libc/build/ или libbgi/build/, дамп, репро) — см. memory/defer_unexplained_quirks.
Структура
libc/<area>/*.c— модули libc (ядро, БЕЗ графики);libc/include/— публичные заголовки libclibbgi/— графика BGI (отдельная библиотека):common/— mode-agnostic (один исходник, .rel в обеих driver-библиотеках),bgi256/+bgi16/— mode-specific leaf'ы (реальные реализации, без обёрток);include/— graphics.h + gfx.h;_bgi.h— внутренний заголовок. Собираетlib/bgi256.lib(иbgi16.libв Фазе 2). Выбор режима линковкой:--gfx 256/--gfx 16.runtime/— crt0-семейство, heap, bank (bank.s собирается per-build)bin/sprinter-cc— обёртка компилятора;toolchain/mkexe— упаковщикtests/— по одному API/фиче;examples/— реальные приложенияdocs/— дизайн-доки;docs/TODO.md— roadmapthird_party/solid-c/— нативный Sprinter C (референс, CP866; их ABI несовместим — только как образец)