libbgi: скролл-примитивы + --w3 + отчёт раскладки памяти

Скролл региона video->video (неактивная страница -> активная, банк 0x50:
копия = скролл + heal цели):
- gfx_scroll_h / _bgi_scroll_rows_raw — горизонтальный, построчно без
  страйдов (~54Т/строку), DI/EI бандами по 16 строк, h=0=>256;
- gfx_scroll_v / _bgi_scroll_cols_raw — верт. И/ИЛИ гориз. за один проход
  без буфера (колонка = accel-burst LD A,A, STOP между read/write делает
  промежуточный OUT Port_Y безопасным), банды по 16 колонок;
- _gfx_addr_shadow_base (адрес неактивной страницы) + gfx_rect_t.
Пример examples/scroll.

check_banks.py + sprinter-cc: отчёт раскладки памяти для ЛЮБОЙ модели
(W1/W2 код/данные, остаток кучи/стека, W3 при --w3, банки при --bank),
не только при --bank.  Док docs/memory-management.md §10.

--w3 (резидентный код окна W3) + сопутствующее: crt0_banked W3_RESIDENT,
mkexe -W, tests/w3probe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 19:38:00 +03:00
parent d1bc97c589
commit 95c22be9bd
46 changed files with 4125 additions and 133 deletions
+13 -5
View File
@@ -277,11 +277,14 @@ int main(int argc, char **argv) {
uint32_t pad_byte = 0xFF;
uint32_t bank_base = DEFAULT_BANK_BASE;
int verbose = 0;
int allow_w3_home = 0; /* -W: HOME может тянуться в W3 при W3-банках
(резидентный код --w3 в HUGE делит окно) */
for (int i = 1; i < argc; i++) {
const char *a = argv[i];
if (!strcmp(a, "-h") || !strcmp(a, "--help")) { usage(stdout); return 0; }
if (!strcmp(a, "-v")) { verbose = 1; continue; }
if (!strcmp(a, "-W")) { allow_w3_home = 1; continue; }
if (!strcmp(a, "-o") && i + 1 < argc) { out_path = argv[++i]; continue; }
if (!strcmp(a, "-L") && i + 1 < argc) {
if (parse_addr(argv[++i], &load_addr) < 0) { fprintf(stderr, "mkexe: bad -L\n"); return 1; }
@@ -386,12 +389,17 @@ int main(int argc, char **argv) {
}
}
/* HOME must not extend past 0xBFFF (W3 = bank territory in HUGE,
free in BIG but still off-limits to HOME). */
if (home->hi >= 0xC000u) {
/* HOME может тянуться в W3 (0xC000..0xFFFF) — это резидентный код
окна W3 (--w3, подход A): DSS грузит непрерывный образ и маппит
W1/W2/W3. Запрещаем ТОЛЬКО когда W3 реально занят трамплин-банками
(HUGE: bank_base=0xC000, max_bank>0) — тогда HOME и банки
столкнулись бы в одном окне. */
if (home->hi >= 0xC000u && max_bank > 0 && bank_base == DEFAULT_BANK_BASE
&& !allow_w3_home) {
fprintf(stderr,
"mkexe: HOME image extends to 0x%04X, past window 2 end (0xBFFF).\n"
" Code grew too big for HOME — move some .c files into a bank.\n",
"mkexe: HOME image extends to 0x%04X, into W3 (0xC000+) which\n"
" holds trampoline banks in HUGE mode — collision.\n"
" Move some .c files into a bank, or pass -W for --w3 residents.\n",
home->hi);
return 2;
}