[心得] FC中文化經驗談(三)—找到目標—
【前言】
要修改自然得找到想修改的目標,
例如要製作生命不減的ROM至少得知道儲放生命值的記憶體在哪,
故找到目標便是首要作業;
仔細想想,這講完好像就沒了 XD
【正文】
我們要找到的目標大致有兩個,一個是字庫,一個是文本,
這兩個在畫面顯示時,肯定都在PPU裡,
其中字庫在顯示當下會放在PPU的0x0000~0x1FFF
(不只字庫,包含背景、人物圖像都會在此),
而文本則會放在PPU的0x2000~0x3FFF
(不只文本,包含背景、人物組成以及調色盤都會在此)。
一、字庫
說是字庫,其實也就是圖形長得像文字,和其他包括背景或人物圖形沒什麼差別;
由於畫面上所有東西肯定都在PPU裡,使用PPUViewer(或檢視PPU Memory)可以找到;
不過大部分的案例直接開啟tlp工具通常就找的到。
1. 透過tlp或YYCHR之類的工具找
由於紅白機的ROM,通常未壓縮,或者說未編碼過,
所以使用工具直接開啟ROM檔,即可直接看到圖形部分。
圖為光神話,紅框的數字即是圖形在檔案中的起始位置
https://meee.com.tw/b2tmFpR
2. 透過PPU Viewer找到
開啟Mesen的PPU Viewer,切到CHR Viewer頁籤,
此頁籤顯示的即是PPU的0x0000~0x1FFF的內容,
很直觀可以看到0~9、A~z等等文字,
我們可以在0上面按右鍵→Edit in Memory Viewer,
這樣模擬器會自動幫我們開啟Memory Tools,並且定位到0這個字的位置,
其中位於0x1000~0x100F這16Bytes
(38 4C C6 C6 C6 64 38 00 00 00 00 00 00 00 00 00)便是0的pixel data,
此時使用任意16進位編輯器(UltraEdit之類的軟體)開啟ROM,
並且搜尋38 4C C6 C6 C6 64 38 00 00 00 00 00 00 00 00 00
高機率可以找到0在ROM裡的位置,
實際搜尋可以發現位置在ROM的0x1010,和第1點的方式顯示的位置一致。
(圖為PPU Viewer)
https://meee.com.tw/Hf5aWZq
(圖為PPU Viewer的右鍵選單,選擇使用Edit in Memory Viewer)
https://meee.com.tw/mqTGueL
(圖為Memory Tools for PPU,已定位到字庫位置)
https://meee.com.tw/yCiZlc4
(圖為搜尋到字庫在ROM檔裡的位置)
https://meee.com.tw/wIMO6I7
3. 如果以上方法找不到,那代表圖形有壓縮或是編碼過,在紅白機很少見,
這代表圖像肯定是1 byte 1byte寫進PPU的,得要追蹤程式。
4. 找到後就可以建立所謂的碼表,
其實就是每一單位(紅白機叫做Tile,一Tile為8x8像素,實際占用16bytes)
的圖片編號表,依前面找到的可以建立出這樣的編號表
00 = 0
01 = 1
…
0F = -
…
2F = Z
…
==========================================================================
二、文字
1. 文字的找尋方式大致可參考前述第一項第2點,
一樣是開啟PPU Viewer,透過PPU Viewer快速跳到Memory Tools,
就可以看到顯示在畫面上的文字實際的的編碼
圖為指標選中PUSH START的P時的資訊,
其中可以看到P的編碼是0x31,位置(PPU Addr)在0x21E7
https://meee.com.tw/NiYS6hx
圖為Memory Tools顯示PPU,
https://meee.com.tw/rJduFxz
其中
0x31 = P
0x5D = U
0xC0 = S
0x64 = H
....
2. 找到文字的編碼後,一樣可以在ROM檔裡搜尋到
https://meee.com.tw/vP2uH0q
==========================================================================
三、如果前面方法找不到,如何分析
0. 首先稍微說明一下CPU如何讀寫PPU
CPU是透過兩個Port來讀寫PPU,
0x2006: 決定要寫入的PPU位置
0x2007: 要寫入的值
也就是如果CPU想要將0x31寫到PPU的0x21E7這個位置時,
首先得先透過0x2006將欲讀寫的位置指定成0x21E7,
然後再往0x2007這個位置寫入0x31即可;
實際程式碼會是,
LDA #$21
STA $2006
LDA #$E7
STA $2006
LDA #$31
STA $2007
可以看到2006被寫兩次,肇因於紅白機能讀寫的數值是1byte,
但PPU位置是2Bytes,
所以紅白機分兩次寫入(先寫高byte再寫低byte)來達到目的。
1. 首先使用debugger針對PPU做寫入偵測的中斷點
圖為如何設定中斷點
https://meee.com.tw/C3scTqY
2. 讓程式回到文字顯示之前重跑
此處案例為開頭畫面,故只要reset即可,
其他時候會在顯示文字前先即時存檔來方便重跑,
如果中斷點設定正確,程式會在對應的位置中斷;
圖為程式中斷
https://meee.com.tw/bjWV8u6
此處案例可以看到如下程式碼,
寫入值是0x31也符合我們已知道的文字P的編碼,故可確認此找到的程式正確
…..
LDA ($43),Y @ $A2E8 = $31
STA PpuData 2007 = $00
INY
…..
並且會停在在STA PpuData 2007這行,這就是前面說的CPU正透過$2007寫入PPU,
寫入值是0x31也符合我們已知道的文字P的編碼,故可確認此找到的程式正確
3. 檢視記憶體
前面找到的程式碼,
其中LDA ($43),Y @ $A2E8 = $31是資料來源,
意思是讀取0xA2E8位置的值放進暫存器A,
所以P(0x31)來自0xA2E8這個位置,
此時可以打開Memory Tools,並跳到0xA2E8這個位置
圖為0xA2E8的記憶體內容
https://meee.com.tw/XPmLRuF
4. 依樣畫葫蘆便能在ROM中找到位置
圖為在ROM中搜尋31 5D C0 64 12 C0 C3 A7,並確實找到
https://meee.com.tw/r7pHSGY
以上,字庫跟文本都找到了,只要異動這兩個地方,
就可以達到在畫面上顯示自己要的東西,當然也包括中文字。
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.192.217.145 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/Emulator/M.1733198181.A.7C1.html
推
12/03 11:59,
1天前
, 1F
12/03 11:59, 1F
推
12/03 13:17,
1天前
, 2F
12/03 13:17, 2F
推
12/03 13:40,
1天前
, 3F
12/03 13:40, 3F
推
12/03 16:23,
23小時前
, 4F
12/03 16:23, 4F
推
12/03 16:52,
23小時前
, 5F
12/03 16:52, 5F
推
12/03 19:21,
20小時前
, 6F
12/03 19:21, 6F
推
12/04 08:48,
7小時前
, 7F
12/04 08:48, 7F
推
12/04 11:41,
4小時前
, 8F
12/04 11:41, 8F
推
12/04 12:27,
3小時前
, 9F
12/04 12:27, 9F
Emulator 近期熱門文章
PTT遊戲區 即時熱門文章