diff --git a/toolchain/check_bank_calls.py b/toolchain/check_bank_calls.py index cd296a2..006b7dd 100755 --- a/toolchain/check_bank_calls.py +++ b/toolchain/check_bank_calls.py @@ -72,9 +72,15 @@ BANK_ASM_RE = re.compile(r'^bank(\d+)_') IGNORE = {'___sdcc_bcall_ehl', '___sdcc_bcall'} # `ld hl,#_метка` / `ld de,#___str_3` — материализация адреса. +# +# Скобочную форму принимаем обязательно: адрес ПОЛЯ структуры SDCC пишет как +# `ld bc, #(_mstream + 6)`, и без неё проверка молча пропускала целый класс. +# Поймано вживую 2026-09-03 в порту Loom: `mask.c` (банк 5, --bank-data 5) +# отдавал `res_copy` (банк 11) адрес поля своей структуры — маска читалась как +# «всё заполнено», а сборка при этом была «чистой». LOADADDR_RE = re.compile( - r'^\s*ld\s+(hl|de|bc|iy|ix)\s*,\s*#(_{1,3}[A-Za-z_0-9]+)' - r'(?:\s*[+-]\s*\w+)?\s*(?:;.*)?$', re.IGNORECASE) + r'^\s*ld\s+(hl|de|bc|iy|ix)\s*,\s*#\(?\s*(_{1,3}[A-Za-z_0-9]+)' + r'(?:\s*[+-]\s*[\w()+\- ]+?)?\s*\)?\s*(?:;.*)?$', re.IGNORECASE) PUSH_RE = re.compile(r'^\s*push\s+(hl|de|bc|iy|ix)\s*(?:;.*)?$', re.IGNORECASE) # `ld e,#b_foo` перед трамплином называет банк цели.