Это воспроизводимая реконструкция европейского ROM Hang-On размером 32 КиБ. Исполняемая часть представлена Z80-мнемониками с метками, RAM/портами и восстановленными таблицами косвенных переходов. Неисполняемые диапазоны — графика, карты, сжатые блоки, музыка и игровые данные — сохранены отдельными бинарными assets с точными диапазонами адресов.
Сборка не читает исходный ROM и не копирует байты из комментариев. Включённый двухпроходный ассемблер кодирует мнемоники, разрешает метки, подключает assets и затем проверяет итоговый ROM по нескольким контрольным суммам.
Требуется только Python 3.10 или новее.
python build.pyРезультаты появляются в build/:
hangon-europe.sms— собранный ROM;hangon-europe.map— карта символов;hangon-europe.lst— листинг с адресами и реально собранными байтами.
Проверка против собственного файла ROM:
python build.py --compare "Hang-On (Europe).sms"Успешная сборка должна вывести:
size 32768
crc32 071b045e
md5 2864be0d35269c5030a7f297f70e3ac3
sha1 e601257f6477b85eb0b25a5b6d46ebc070d8a05a
sha256 0d35d0e232d64e714fa5d07e45acaf01ea9fb5a8f88fe9ac8018719ac2818d6f
verification passed
Также доступно:
makesrc/hangon_europe.asm основной Z80-исходник
include/hardware.inc порты SMS
include/ram.inc именованные переменные Work RAM
assets/*.bin точные неисполняемые диапазоны ROM
tools/miniz80asm.py автономный двухпроходный Z80-ассемблер
tools/decode_graphics.py декодирование сжатой графики в PNG
tools/rename_assets.py переименование assets по смыслу
build.py сборка и строгая проверка хешей
docs/symbols.csv полный индекс меток
docs/assets.csv диапазоны и имена бинарных assets
docs/ результаты и методика анализа
Бинарные assets в assets/ носят осмысленные имена, отражающие их назначение:
road_tilemap_hud_labels.bin, player_physics_tables.bin,
road_curvature_tables.bin, track86_race_start.bin,
stage_palettes_and_init_state.bin, message_strings.bin и др.
Сопоставление новых имён со старыми диапазонами см. в docs/ASSET_RENAME_PLAN.md.
Статический анализ выделил 4 559 инструкций / 8 823 байта кода в 36 раздельных диапазонах. Для кода нет недокументированных или сырых opcode-вставок: каждая выделенная инструкция собирается из обычной Z80-мнемоники. Восстановлены reset/IRQ/NMI-векторы, основной VBlank-путь, работа с VDP, дорожный renderer, игровые state/object dispatchers и sound engine.
Оставшиеся 23 945 байт не объявлены кодом без доказательств. Это принципиально: графику, карты, таблицы, сжатые данные и музыкальные потоки нельзя честно превращать в фиктивные инструкции только ради 100-процентного дизассемблирования. Известные таблицы функций уже вынесены в .dw; прочие диапазоны сохранены как .incbin и могут разбираться постепенно без нарушения byte exact.
Каждая инструкция в src/hangon_europe.asm снабжена исходным адресом и байтами, например:
InterruptHandler:
push af ; 0038: F5
in a, (VDPControlPort) ; 0039: DB BF
or a ; 003B: B7
jp p, LineInterruptHandlerRAM ; 003C: F2 D0 C4
jp VBlankHandler ; 003F: C3 C8 01Байты после ; служат только для аудита. Ассемблер их игнорирует.
- ROM напрямую занимает
$0000-$7FFF; банкового переключения нет. - Sega header находится в
$7FF0-$7FFF. - Код
$03B3-$03DCкопируется в RAM$C4D0и исполняется как line-interrupt handler. - Восстановлены пять
JP (HL)dispatch points: game state, objects, runtime sound-function pointer, sound triggers и sound-script opcodes. - Таблицы game state (
$1356), objects ($253D), sound triggers ($74AC) и sound commands ($7617) представлены символическими.dw.
Подробности находятся в docs/ANALYSIS.md и docs/MEMORY_MAP.md.