Резидент: pop_redraw + холодная половина pop_level в банки (902 -> 3525 Б кучи)

MEM-COLD3, шаг 1-2 из плана разгрузки резидента:

* pop_redraw.c целиком -> банк 7 (к pop_room.c: он и есть единственный
  потребитель разбора пометок).  Два модуля в одном банке линкуются в один
  сегмент — проверено на .map (BANK7 7928 -> 8556).
* pop_level.c расколот по частоте вызова: горячая половина (чтение тайлов,
  связи, дверные таблицы, живые стражи — зовут все банки, местами на каждый
  тайл) осталась в резиденте, холодная (чтение файла уровня, разбор комнаты,
  рестарт, потабличные различия) уехала в pop_level_cold.c -> банк 8.
  Общее состояние объявлено в _pop_level.h: данные банковых модулей всё
  равно линкуются в общий _DATA, в банк уехал только КОД.

Побочно найден баг кодогена SDCC: `return 1;` из ветки не кладёт 1 в A —
до __banked он маскировался случайным ненулевым остатком в A.  Репро и
разбор — docs/bugs/sdcc-z80-ret-const-lost/, стаб t_char починен одним
выходом через переменную.  Аудит всех .asm roomtest: других мест нет.

_CODE 25628 -> 23005, куча 902 -> 3525 Б.  tests-host 6/6.
This commit is contained in:
2026-08-12 21:53:08 +03:00
parent f541c0aad9
commit 5d31ed086f
13 changed files with 884 additions and 426 deletions
+4 -4
View File
@@ -19,7 +19,7 @@ static uint8_t rda_kind[NCOLS], rda_cnt[NCOLS];
* КАЖДЫЙ кадр впустую (замер 2026-07-27 на прежнем rest-цикле: ~12 % кадра). */
static uint8_t rd_pending;
void pop_redraw_reset(void)
void pop_redraw_reset(void) __banked
{
uint8_t i;
for (i = 0; i < NTILES; i++) { rd_kind[i] = 0; rd_cnt[i] = 0; }
@@ -27,7 +27,7 @@ void pop_redraw_reset(void)
rd_pending = 0;
}
void pop_set_redraw(uint8_t tilepos, uint8_t kind, uint8_t pages)
void pop_set_redraw(uint8_t tilepos, uint8_t kind, uint8_t pages) __banked
{
if (tilepos >= NTILES) return;
if (!rd_cnt[tilepos]) rd_pending++;
@@ -35,7 +35,7 @@ void pop_set_redraw(uint8_t tilepos, uint8_t kind, uint8_t pages)
if (pages > rd_cnt[tilepos]) rd_cnt[tilepos] = pages;
}
void pop_set_redraw_above(uint8_t col, uint8_t kind, uint8_t pages)
void pop_set_redraw_above(uint8_t col, uint8_t kind, uint8_t pages) __banked
{
if (col >= NCOLS) return;
if (!rda_cnt[col]) rd_pending++;
@@ -47,7 +47,7 @@ void pop_set_redraw_above(uint8_t col, uint8_t kind, uint8_t pages)
* бегущими счётчиками, а не через i/10 и i%10 — у Z80 нет деления, и SDCC
* выносит __divuchar/__moduchar в вершину цикла как общее подвыражение
* аргументов (30*2 делений за кадр даже когда рисовать нечего). */
void pop_redraw_needed(void)
void pop_redraw_needed(void) __banked
{
uint8_t i, row = 0, col = 0, left = 0;
if (!rd_pending) return;