PoP roomtest: pop_bg и pop_map в банки; --dataseg BANKn стал опцией
Резидента --w3 больше нет: отрисовка (pop_bg + pop_gdraw) уехала в БАНК 2, физика/коллизия (pop_map) — в БАНК 3. Куча W1/W2 1294 -> 6750 Б. Что это разблокировало. Резидент был тупиком: из банка он недостижим ни прямо, ни транзитивно, поэтому pop_map (самый крупный модуль, 5.8 КБ) в банк было не увести — он зовёт mob-отрисовку. Проверено, что банк->банк РАБОТАЕТ: ___sdcc_bcall_ehl читает страницу окна портом 0xE2 и кладёт её на СТЕК своего кадра (runtime/bank.s), поэтому вложенность корректна по построению. Подтверждено в MAME цепочкой W1 -> банк1 -> банк2 -> банк1: nested=124 after=8, ровно ожидаемое. Значит развязка mob'а (самое рисковое место, loose-полы) НЕ понадобилась — pop_map зовёт pop_bg трамплином. Правила вызовов проверены на сгенерированном asm и записаны в memory sdcc_banked_call_rules: трамплин выбирает ОБЪЯВЛЕНИЕ (__banked), а не раскладка — даже внутри одного .c между __banked функциями он есть. Внутрибанковые функции оставлены непомеченными и зовутся напрямую, в т.ч. через границу файла (pop_gdraw -> pop_fore_over_char). sprinter-cc: --dataseg BANKn БОЛЬШЕ НЕ ставится по умолчанию. Раньше вся писучая память банкового модуля уезжала в страницу банка и снаружи не читалась (проверено на .map: глобал лёг по 0x0001C000) — грабли на каждом переносе. Теперь данные банков по умолчанию в общем _DATA (W1/W2, замаплен всегда), а прежнее поведение — по явному --bank-data. Замеры (комната 3, Kid + страж; кадр Sprinter в турбо = 430 000 тактов): до переноса 338 508 (0.79 кадра) + pop_bg в банк 2 347 100 (+2.5 %) + pop_map в банк 3 371 100 (+9.6 % к исходному, 0.86 кадра) Плата — трамплины (~654 такта на вызов, ~30 вызовов за кадр). При пейсинге в 3 кадра это 29 % логического кадра, но запас до ОДНОГО кадра всего ~59 000 тактов — под звук его надо возвращать (следующий шаг: батчить кроссбанковые вызовы, начиная с pop_redraw_needed). Профилирование бордюром включено по умолчанию (make PROF=0 выключает) и переведено на реально работающие биты: бит 0 (красный) у бордюра Sprinter ИГНОРИРУЕТСЯ, поэтому различимых состояний четыре и значения обязаны быть чётными — 0 чёрный (ждём vsync), 2 синий (логика), 4 зелёный (фон), 6 циан (спрайты). Раньше нечётные номера сливались и полосы не читались. Проверено в MAME: комнаты 1/3 рисуются как прежде, бег и коллизия работают, в комнате 12 плиты проваливаются со щебнем — то есть цепочка loose банк3 -> банк2 живая. Полосы бордюра в комнате 3: логика 73 строки, фон 64, спрайты 128, свободно 23. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+17
-1
@@ -33,6 +33,9 @@
|
||||
# --data-loc 0xN override SDCC --data-loc (default: derived from --memory)
|
||||
# -Wl FLAG extra linker flag (repeatable)
|
||||
# --bank N=FILE.c compile FILE.c as bank N; repeatable; pulls crt0_banked
|
||||
# --bank-data put bank modules' writable data INTO the bank page
|
||||
# (default: it goes to the shared _DATA in W1/W2, which
|
||||
# stays mapped and is visible from everywhere)
|
||||
# automatically and adds -Wl-b_BANKN=0x{N}C000
|
||||
# --w3 FILE.c place FILE.c resident in window 3 (0xC000), called
|
||||
# DIRECTLY (no trampoline). Repeatable. Defaults to
|
||||
@@ -108,6 +111,7 @@ MKEXE_EXTRA=()
|
||||
BANK_SPECS=() # entries like "1=engine.c"
|
||||
W3_SPECS=() # entries like "mod.c" — резидентные модули окна W3 (--w3)
|
||||
USER_DEFS=() # -DFOO / -DFOO=bar — пробрасываются в sdcc как есть
|
||||
BANK_LOCAL_DATA=0 # 1 (--bank-data): писучие данные банков — В СТРАНИЦУ банка
|
||||
W3_RELS=() # заполняется при компиляции W3-модулей
|
||||
W3_LD_FLAGS=() # -Wl-b_W3CODE=0xC000, если есть --w3
|
||||
USER_SET_MEMORY="" # непусто, если --memory задан явно (для --w3 авто-small)
|
||||
@@ -143,6 +147,7 @@ while [[ $# -gt 0 ]]; do
|
||||
-Wl) LD_EXTRA+=("$2"); shift 2;;
|
||||
-D*) USER_DEFS+=("$1"); shift;;
|
||||
--bank) BANK_SPECS+=("$2"); shift 2;;
|
||||
--bank-data) BANK_LOCAL_DATA=1; shift;;
|
||||
--mkexe) MKEXE_EXTRA+=("$2"); shift 2;;
|
||||
--max-allocs) MAX_ALLOCS="$2"; shift 2;;
|
||||
--gfx) GFX_MODE="$2"; shift 2;;
|
||||
@@ -423,8 +428,19 @@ if [[ "$CRT0_TYPE" == "banked" ]]; then
|
||||
bank_n="${spec%%=*}"
|
||||
bank_src="${spec#*=}"
|
||||
rel="$WORK/bank${bank_n}_$(basename "$bank_src" .c).rel"
|
||||
# По умолчанию --dataseg НЕ задаём: писучие данные банкового
|
||||
# модуля (глобалы, file-static, статики функций) остаются в
|
||||
# общем _DATA, то есть в W1/W2 — они замаплены всегда и видны
|
||||
# и банку, и остальному коду. С --dataseg BANKn они уезжают в
|
||||
# СТРАНИЦУ БАНКА и снаружи не читаются (проверено на .map:
|
||||
# глобал банкового модуля лёг по 0x0001C000): это экономит
|
||||
# W1/W2, но требует ручного контроля видимости, поэтому
|
||||
# включается явно через --bank-data.
|
||||
bank_data_flags=()
|
||||
[[ $BANK_LOCAL_DATA -eq 1 ]] && bank_data_flags=(--dataseg "BANK${bank_n}")
|
||||
run "$SDCC" "${CC_FLAGS[@]}" \
|
||||
--codeseg "BANK${bank_n}" --constseg "BANK${bank_n}" --dataseg "BANK${bank_n}" \
|
||||
--codeseg "BANK${bank_n}" --constseg "BANK${bank_n}" \
|
||||
"${bank_data_flags[@]}" \
|
||||
-c -o "$rel" "$bank_src"
|
||||
BANK_RELS+=("$rel")
|
||||
# Virtual address: bank_n in upper byte, BANK_LOW16 in low half.
|
||||
|
||||
Reference in New Issue
Block a user