본문으로 건너뛰기
셀리카 공방SELICA WORKSHOP 검색

홈 / 개발기록

개발기록

카트리지 플래시 세이브

디스크 게임을 ROM 으로 구우면 쓰기가 갈 곳이 없다. 커널의 디스크 입출력을 가로채 카트리지 플래시에 직접 굽는다.

세 덩어리로 이루어져 있다
ROM 으로 굽기 — dsk2rom 의 함정, 부팅 실패 진단, 여러 장을 한 롬에
터보R 대응 — R800 으로 떠서 화면·음악이 깨지는 문제
세이브 — 플래시 쓰기 프로토콜, 슬롯·뱅크 전환, 실행용 RAM 자리
터보R 에서만 화면이 찢어진다면
R800 으로 돌고 있는 것이다
ROM 화한 뒤 터보R 에서만 그림에 세로 줄이 가고 한 장면이 통째로 쓰레기가 되고 음악 박자가 틀어졌다. 같은 롬이 다른 기종에서는 완벽했다. 한글 패치와 무관하다 — 무패치 원본을 구운 롬도 똑같이 깨졌다.

디스크로 부팅 S1990 reg6 = 0x60 Z80 모드 → 정상
카트리지로 부팅 S1990 reg6 = 0x00 R800 + DRAM 모드 → 파손
1980~90년대 게임은 VRAM 쓰기와 음악 템포를 고정 루프로 시간을 재므로, CPU 가 몇 배 빨라지면 VDP 가 못 따라와 바이트를 흘린다. 그게 세로 줄무늬의 정체다.

터보R 은 원래 Z80 으로 뜬다. 다만 부팅이 BASIC 쪽으로 흘러가면 그때 R800 으로 바꾼다. 보통 카트리지는 제어를 안 돌려주니 거기까지 안 가는데, dsk2rom 은 디스크롬 행세를 하느라 돌려준다. 그래서 우리만 R800 이 된다.

고치는 법 — H.TIMI 훅
되돌릴 수 있는 창은 0.5초뿐이지만 인터럽트는 16ms 마다 오므로 반드시 그 창에 들어간다. 롬 헤더의 INIT 진입점을 우리 스텁으로 돌리고, 스텁이 타이머 인터럽트 훅에 슬롯 간 호출을 심는다. 커널 코드는 안 건드린다.

나중에 되돌리는 방식은 전부 실패한다. 실패 기록이 남아 있으니 다시 시도하지 말 것.

플래시 쓰기 — 함정 셋
언락 주소는 용량이 아니라 데이터 폭이 정한다
유형 UNLOCK1 UNLOCK2
AMD x8 전용 0x555 0x2AA
AMD x8·x16 겸용 (바이트 모드) 0xAAA 0x555
SST 39SF/39VF 0x5555 0x2AAA
겸용 칩은 바이트 모드에서 주소가 한 칸 밀린다. 작은 칩이 대체로 x8 전용이라 결과적으로 용량과 상관있어 보일 뿐이다. 이걸 「용량 문제」로 적어 뒀다가 한참 헤맸다.

상수로 분기하지 말고 런타임에 칩에 물어보는 게 맞다. SST 계열은 8KB 뱅크 창 하나로 그 주소를 만들 수 없어 이 구조로는 지원 불가.

쓰기 주소를 뱅크 레지스터 창에 두지 마라
에뮬레이터가 가려 주는 실수
세이브 슬롯을 8KB 뱅크에 16개 깔면 일부가 정확히 뱅크 레지스터 창에 걸린다. 실기에서는 플래시가 아니라 뱅크가 바뀐다.

그런데 openMSX 는 그 쓰기를 플래시로 보내 준다 — 폴링까지 통과해 에뮬에서는 완벽히 동작한다. 실기에 꽂았으면 그 슬롯부터 게임 뱅크가 뒤집혔을 것이다.

처방: 뱅크당 8슬롯만 쓴다. 언락·디렉터리·비트맵도 전부 안전한 절반 안에 둔다.

게이트를 연 뒤에는 뱅크를 절대 바꾸지 않는다
게이트의 한 비트가 매퍼(뱅크 전환) 비활성화다. 게이트를 여는 순간 뱅크 전환 쓰기가 조용히 무시된다.

실기에서 저장할 때마다 다운난 원인이 이것이었다. 게이트를 연 뒤에 세이브 뱅크를 걸고 있었는데 그 전환이 안 먹으니, 소거 명령이 그때 걸려 있던 게임 롬 뱅크로 나갔다. 저장할 때마다 게임이 자기 코드를 지운 것이다.

증상 → 원인
ROM 이 아예 안 뜬다
BPB 부터 의심한다. 진단 순서를 따르면 30분 안에 갈린다.
터보R 에서만 깨진다
R800 으로 돌고 있다. H.TIMI 훅으로 되찾는다.
세이브하면 검은 화면으로 멈춘다
쓰기 루틴을 RAM 으로 옮기지 않았다. 정지라 무한루프를 의심하게 되는데, PC 를 40~60개 표본으로 찍으면 5분에 끝난다.
에뮬은 되는데 실기만 다운
뱅크 레지스터 창 또는 게이트 뒤 뱅크 전환.
저장은 되는데 안 읽힌다
읽기 경로의 슬롯 전환을 빠뜨렸다. 쓰기만 보고 넘어가기 쉽다.
검증할 때
롬을 다시 구워도 옛 롬이 도는 일이 있다. 제일 먼저 확인할 것.
디스크 입출력 인자는 범위 검사부터 한다. 부팅 중 쓰레기 인자로 한 번 불린다(실측: 섹터 57870, 개수 0).
게임플레이 없이 쓰기만 재려면 시험용 롬을 따로 굽는다. 시작 코드가 곧바로 세이브 루틴을 부르게 해 두고, 끝나고 세이브 뱅크를 훑어 확인한다.
미사용 RAM 은 한 가지 값이 아닐 수 있다. 처녀 패턴 대조와 여러 상태 겹치기를 같이 쓴다.
세 프로젝트에서 같은 함정에 반복해 걸렸다. 새 게임·새 카트리지로 옮길 때는 체크리스트를 먼저 훑을 것.

← 개발기록 목록

댓글

0
가입 없이 작성할 수 있습니다. 비밀번호로 본인 글을 수정·삭제할 수 있어요.

첫 댓글을 남겨주세요.