로우섹터 디스크 코드 찾기
MSX 게임 디스크는 FAT 가 아닌 커스텀 포맷인 경우가 많다. 디렉터리가 없으니 「어느 섹터가 코드인가」부터 직접 밝혀야 한다.
스킬 이름
msx-disk-codemap
역어셈블
z80-disasm 을 쓴다
실전 사례
룬워스 (T&E Soft, 1990)
결론을 한 장으로 내지 마라
가장 크게 헛디디는 지점이다. 게임이 여러 장이면 장마다 다른 프로그램이 들어 있다. 룬워스는 Disk1(스타트)과 Disk2/3(게임)의 코드가 한 바이트도 겹치지 않았다.
「이 게임은 매퍼를 안 쓴다」를 한 장만 보고 판정하면 틀린다. 반드시 전 디스크에 같은 검사를 돌리고 장별로 결과를 따로 적는다.
부트 체인을 끝까지 따라간다
가장 확실한 코드 진입점이다. 디스크 ROM 은 섹터 0 을 0xC000 에 읽고 0xC01E 를 호출한다. 여기서부터는 추측이 아니라 추적이다.
룬워스 Disk1 실제 경로
섹터0 → 0xC000 로드
0xC02E LD HL,C03Bh / LD DE,8000h / LD BC,0083h / LDIR ; 자기 일부를 옮긴다
0xC036 JP 805Eh
0x805E LD SP,F51Fh
LD HL,807Ch / CALL 8000h ; 섹터 읽기
JP C000h
0x807C DW C000h, 0010h, 0003h ; 버퍼 / 섹터16 / 3섹터 ← 진짜 로더
JP·CALL 직후의 6바이트가 파라미터 블록인 게 흔한 관용이다. 항상 의심할 것.
로드 주소 알아내기
부트 코드가 LDIR 로 자기를 옮기면 옮긴 원본 오프셋 ↔ 목적지 주소가 그대로 매핑표다. 위 예에서 오프셋 0x3B ↔ 주소 0x8000. 이걸로 진입점 0x805E → 오프셋 0x99 를 검산해 LD SP,F51Fh 가 나오면 매핑이 맞다.
바이트 스캔은 아무것도 증명하지 못한다
밀집도 증거가 아니다
룬워스 Disk2 섹터 160~163 에 OUT (FDh),A 6개와 IN A,(FDh) 5개가 밀집해 있었다. 밀집이면 코드일 거라 생각했지만 뜯어보니 벡터 애니메이션 데이터였다. D3 FD 는 그중 인접한 두 토큰이었을 뿐이다.
토큰 기반 데이터는 원래 특정 바이트가 몰려 나온다.
대신 쓸 것 ① — 3바이트 절대주소 참조
오탐이 훨씬 적다. 3A/32/21 뒤에 BIOS 작업영역 주소가 오는 경우만 본다.
주소 이름 뜻
FCC1h EXPTBL 슬롯 확장표 — 슬롯 순회의 시작점
FCC5h SLTTBL 서브슬롯 섀도 — ENASLT 복제본이 반드시 건드린다
F341~44h RAMAD0~3 페이지별 RAM 슬롯 — 디스크 ROM 호출 후 복구용
대신 쓸 것 ② — 지문 대조
정체를 밝힌 루틴의 선두 40~48바이트를 지문으로 삼아 전 디스크를 훑는다. 복제본이 어디에 몇 벌 있는지 한 번에 나온다.
대신 쓸 것 ③ — 교차 검증
코드 청크 범위를 확정한 뒤 의심 바이트가 그 안에 몇 개인지 센다. 룬워스 최종 결과는 매퍼 포트 바이트가 디스크별로 30·85·73개였지만 코드 청크 안에 든 것은 0개였다. 이게 결론을 낼 수 있는 형태의 증거다.
슬롯을 뒤진다고 다 RAM 탐색이 아니다
LD HL,FCC1h + ENASLT 루프를 보면 놀라기 쉽지만 대개는 음원 탐색이다. 근처 ASCII 가 답을 준다 — APRLOPLL(ROM 4018h)이면 MSX-MUSIC/FM-PAC 찾기다.
ROM 시그니처를 읽기만 하면 RAM 탐색이 아니다. 안전하다.
진짜 RAM 탐색은 이 모양뿐이다
슬롯을 바꿔가며 → 메모리에 값을 쓰고 → 다시 읽어 → 같은지 비교
(ENASLT / LD (HL),A / LD A,(HL) / CP / 반복)
쓰고 되읽어 비교하는 루프가 없으면 RAM 탐색이 아니다. 왜 중요한가 — 자체 RAM 탐색을 하는 로더는 확장 RAM 카트리지를 꽂으면 오작동한다. 탐색이 없으면 BIOS 가 잡아 준 구성을 그대로 쓰므로 램카트가 그냥 메인 RAM 으로 보인다.
순서
전 디스크에 똑같이 돌리고 장별로 결과를 적는다.
섹터 0 부터 부트 체인을 따라가 로더 섹터와 로드 주소를 확정한다. 매핑은 진입점으로 검산한다.
3바이트 BIOS 작업영역 참조로 후보를 뽑는다. 2바이트 옵코드 스캔은 후보조차 못 된다.
후보를 역어셈블해 정체를 밝힌다.
밝힌 루틴을 지문으로 삼아 복제본을 찾는다.
코드 청크 범위가 확정되면 「청크 안 N개」 형태로 결론을 적는다.
가능하면 워치포인트로 실행 중 0회까지 확인한다. 정적 0 + 동적 0 이라야 안심할 수 있다.
댓글
0첫 댓글을 남겨주세요.