QuickSave F6/F9 в roomtest; bank_load_file/bank_save_file/gfx_w0_page_prepare; sprinter-cc: авто n_banks

roomtest:
- QuickSave/QuickLoad (F6/F9): снапшот 'POPQ' v3 в POP.SAV/POP.BAK на HDD,
  транзакционная запись (POP.NEW -> rename, откат при ошибке), XOR-контрольная
  сумма payload'а; сериализация всех игровых переменных через W0-примитивы
  pop_qs_*; pop_qsave_process() на границе кадра вне Char-окон
- pop_qsave_restore_room(): полная перезагрузка комнаты после загрузки
  (карта/края/швы, сброс bake-кэша, перерисовка обеих страниц, инвалидация
  кэшей спрайтов и HP)
- сериализаторы в pop_map/pop_loose_mob/pop_trob/pop_guard_ai
  (+ восстановление инвариантов: mobs_live, trob_drawn, redraw)
- immortal-чит 2 уровня: уровень 2 поглощает только малый урон Kid'а

libc/libbgi:
- bank_load_file()/bank_save_file() — резидентное файловое I/O в банк,
  без правила W3 (путь читается до переключения страницы)
- gfx_w0_page_prepare(page) — подготовка W0-окна (IRQ/NMI-стабы) одной
  функцией; atlas_load.c и roomtest переведены на новые примитивы;
  ручные ISR-стабы удалены

sprinter-cc / сборка:
- --bank N=FILE.c: автогенерация n_banks (_n_banks_auto.c), ручные
  const n_banks удалены из тестов
- roomtest/app.mk: ресурсы через stamp-файлы (.resource-stamps/) — один
  запуск упаковщика на группу вместо N под -B; HDD_PACK_ARGS
This commit is contained in:
2026-08-22 11:53:10 +03:00
parent b6699b3aef
commit f4b4852d51
57 changed files with 1610 additions and 301 deletions
+37 -10
View File
@@ -163,6 +163,34 @@ done
[[ -z "$OUT" ]] && { echo "sprinter-cc: -o NAME is required" >&2; exit 1; }
[[ ${#SOURCES[@]} -eq 0 ]] && { echo "sprinter-cc: no input files" >&2; exit 1; }
# ------- Validate bank layout and derive n_banks ----------------------------
# crt0_banked loads 16 KB images consecutively and fills _bank_pages[1..N],
# therefore N is the highest bank number and the numbering must have no gaps.
# Several source modules may share one bank, so counting --bank options would
# be incorrect.
BANK_MAX=0
BANK_SEEN=()
for spec in "${BANK_SPECS[@]}"; do
if [[ ! "$spec" =~ ^([0-9]+)=(.+)$ ]]; then
echo "sprinter-cc: bad --bank specification: '$spec' (expected N=FILE.c)" >&2
exit 1
fi
bank_n="${BASH_REMATCH[1]}"
bank_n=$((10#$bank_n))
if (( bank_n < 1 || bank_n > 15 )); then
echo "sprinter-cc: bank number must be in range 1..15: '$spec'" >&2
exit 1
fi
BANK_SEEN[$bank_n]=1
(( bank_n > BANK_MAX )) && BANK_MAX=$bank_n
done
for ((bank_n = 1; bank_n <= BANK_MAX; bank_n++)); do
if [[ -z "${BANK_SEEN[$bank_n]:-}" ]]; then
echo "sprinter-cc: bank $bank_n is missing; banks must be consecutive from 1 to $BANK_MAX" >&2
exit 1
fi
done
# ------- --w3: резидентный код окна W3 (подход A) ----------------------------
# W3-модули едут в область W3CODE @0xC000 и вызываются напрямую (без
# трамплинов). Работает поверх small-лейаута: main-код с 0x4100 (W1/W2),
@@ -399,8 +427,8 @@ fi
# 3. bank infrastructure — required whenever crt0_banked is in play.
# Always assemble bank.s for _bank_pages + the bcall/bjump trampolines.
# If the user did not pass any --bank, generate a tiny stub providing
# n_banks = 0 (crt0_banked.s imports this symbol unconditionally).
# Generate n_banks from the validated --bank layout. crt0_banked.s imports
# this symbol unconditionally, including banked memory modes with zero banks.
# In BIG mode banks live in W1 at low16 = 0x4000; in HUGE / default
# mode they live in W3 at low16 = 0xC000.
BANK_RELS=()
@@ -416,14 +444,13 @@ if [[ "$CRT0_TYPE" == "banked" ]]; then
asm_runtime "$RUNTIME/bank.s" "$BANK_TRAMP_REL"
BANK_RELS+=("$BANK_TRAMP_REL")
if [[ ${#BANK_SPECS[@]} -eq 0 ]]; then
# User has no banks — supply n_banks=0 so crt0_banked links.
STUB_C="$WORK/_n_banks_stub.c"
STUB_REL="$WORK/_n_banks_stub.rel"
echo "const unsigned char n_banks = 0;" > "$STUB_C"
run "$SDCC" "${CC_FLAGS[@]}" -c -o "$STUB_REL" "$STUB_C"
BANK_RELS+=("$STUB_REL")
else
BANK_COUNT_C="$WORK/_n_banks_auto.c"
BANK_COUNT_REL="$WORK/_n_banks_auto.rel"
echo "const unsigned char n_banks = $BANK_MAX;" > "$BANK_COUNT_C"
run "$SDCC" "${CC_FLAGS[@]}" -c -o "$BANK_COUNT_REL" "$BANK_COUNT_C"
BANK_RELS+=("$BANK_COUNT_REL")
if [[ ${#BANK_SPECS[@]} -gt 0 ]]; then
for spec in "${BANK_SPECS[@]}"; do
bank_n="${spec%%=*}"
bank_src="${spec#*=}"