#!/usr/bin/env python3 """ gen_kid_blob.py — kid_data.bin как C-массив для тестов под ucsim. Зачем. Таблицы кадров и seqtbl живут в EMM-странице, замапленной в W0, и pop_kid ходит по ним АБСОЛЮТНЫМИ адресами от KD_DATA_OFF (0x100). В ucsim никакого W0 нет, зато есть ровная 64-КБ память, поэтому тест просто кладёт файл по 0x100 и глушит gfx_w0_map. Единственное следствие для сборки — код набора линкуется с --code-loc выше конца блоба (см. Makefile). Файл берётся ровно тот, что уходит на устройство, — pop_extract_kid_data.py делает его из оригинального PRINCE.EXE, так что тест проверяет порт против НАСТОЯЩИХ данных игры, а не против переписанной от руки таблицы. """ import sys from pathlib import Path src, dst = Path(sys.argv[1]), Path(sys.argv[2]) data = src.read_bytes() out = [ "/* Сгенерировано gen_kid_blob.py — не править руками. */", '#include "kidblob.h"', "", f"const unsigned char kid_blob[{len(data)}] = {{", ] for i in range(0, len(data), 16): out.append(" " + ",".join(str(b) for b in data[i:i + 16]) + ",") out += [ "};", "", f"const unsigned int kid_blob_size = {len(data)};", "", "/* Разложить блоб по KD_DATA_OFF. Без memcpy: тестовый бинарь не", " * линкуется с libc, а тянуть ради этого z80-рантайм незачем. */", "void kid_blob_install(void)", "{", " unsigned char *d = (unsigned char *)KID_BLOB_ADDR;", " const unsigned char *s = kid_blob;", f" unsigned int n = {len(data)};", " while (n--) *d++ = *s++;", "}", "", ] dst.write_text("\n".join(out)) print(f"gen_kid_blob: {src.name} -> {dst.name} ({len(data)} Б)")