Files
Sprinter-SDCC/tests/banklocl/banklocl.c
T
snark13 f4b4852d51 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
2026-08-22 11:53:10 +03:00

83 lines
2.6 KiB
C

/*
* bank_local_data — demonstrates that a banked function can own its own
* static (BSS) array and a const lookup table without burning HOME
* memory. When the function executes, BANK1 is mapped into window 3
* and both code and data are directly addressable.
*
* No bank_read / bank_write needed — the trampoline maps the bank for
* us and the C code touches the arrays normally.
*/
#include <stdio.h>
#include <stdint.h>
extern void bank1_fill (int seed) __banked;
extern uint16_t bank1_sumtab (void) __banked;
extern uint8_t bank1_peek (int idx) __banked;
extern void bank1_map_print(void) __banked;
extern uint8_t *bank1_alloc_and_fill(int n, uint8_t pattern) __banked;
extern void bank1_free (void *p) __banked;
uint8_t local0_buf[16];
int main(int argc, char **argv)
{
puts("bank_local_data: testing static data in BANK1");
bank1_map_print();
/* Verify crt0_banked parsed argv correctly. */
printf("argc=%d, argv[0]=\"%s\"\n", argc, argv[0]);
printf("local0_buf = %p\n", local0_buf);
for (int i = 1; i < argc; i++)
printf(" argv[%d]=\"%s\"\n", i, argv[i]);
/* Seed the BSS array in BANK1. */
bank1_fill(0x10);
/* Read it back through another banked function — verifies the data
* survived after the trampoline returned to HOME and re-entered. */
int ok = 1;
for (int i = 0; i < 8; i++) {
uint8_t v = bank1_peek(i);
uint8_t expected = (uint8_t)(0x10 + i);
if (v != expected) {
printf(" bank1_buf[%d] = 0x%02X, expected 0x%02X\n",
i, v, expected);
ok = 0;
}
}
if (ok)
puts(" buf[0..7] OK");
/* Use the const lookup table that lives in BANK1. */
uint16_t sum = bank1_sumtab();
printf(" bank1_sumtab() = %u (expected 1500)\n", sum);
/* malloc from a banked function — the heap lives in W2 (HOME),
* which stays mapped across W3 page swaps. Returned pointer
* should be usable both inside the bank AND from HOME afterwards. */
uint8_t *heap_p = bank1_alloc_and_fill(32, 0xA0);
if (heap_p == NULL) {
puts(" malloc from bank FAILED");
} else {
printf(" caller sees pointer = %p\n", heap_p);
int ok = 1;
for (int i = 0; i < 32; i++) {
uint8_t expected = (uint8_t)(0xA0 + i);
if (heap_p[i] != expected) {
printf(" heap_p[%d] = 0x%02X, expected 0x%02X\n",
i, heap_p[i], expected);
ok = 0;
}
}
if (ok) puts(" bank-allocated heap [0..31] OK from HOME");
bank1_free(heap_p);
}
puts("done");
return 0;
}