[心得] FC中文化經驗談(二)—擴充ROM容量—

看板Emulator (模擬器)作者時間1月前 (2024/11/18 23:49), 編輯推噓14(1403)
留言17則, 17人參與, 4周前最新討論串1/1
【前言】 即便是文字不多的動作遊戲,也很常會遇到刻好的中文字無法全部塞進去的窘境, 這時就得將遊戲占用容量擴大,並且遊戲程式碼還要認識擴大後的區域, 這就是擴容。 【正文】 本篇以光神話歐美版為例來說明如何擴充容量 ========================================================================== 一、查詢ROM的規格 最主要是要知道ROM的Mapper和PRG、CHR的大小, 我們不可能記住Header每個byte的定義,所以使用工具查看才是正確方式 圖中可知光神話是Mapper1,PRG-ROM有128KB,沒有CHR-ROM https://meee.com.tw/sirFyzT ========================================================================== 二、查詢該規格的規格書 推薦到下列網站查詢 https://www.nesdev.org/wiki/Mapper https://problemkaputt.de/everynes.htm#cartridgesandmappers 光神話使用MMC1這個晶片做輔助, 之所以叫Mapper1是做出nes格式的模擬器作者所做的編號, 他將MMC1編號成1號,其他常見的還有MMC3(Mapper4) https://meee.com.tw/f6hFWvT 圖中為nesdev查到的Mapper1規格,PRG-ROM最大到512KB, 這代表只使用128KB的光神話還可以擴容, 如果遇到原遊戲已經使用到該Mapper的上限, 要嘛看看程式中是否有空白區段, 要嘛看有沒有其他可以相容的Mapper, 要嘛放棄 XD ========================================================================== 三、擴大ROM前的注意事項 1.區塊編號 每一區塊的PRG或CHR都會有編號,依序由前到後從編號0開始遞增 2.預設映射的PRG區塊 每個ROM在執行前就會有固定某一段PRG由卡帶中被映射到主機裡, 依照每個Mapper規範,會預設的區塊不一定是哪一塊, 但我看到的基本上都是最後一個PRG會被預映射。 3.編號不可異動 增大檔案後,除預映射(最後的區塊)外不可導致原本區塊編號有所更動, 也就是區塊順序須不變 4.異動後的PRG/CHR總大小各自都得是2的某次方KB 例如原ROM是PRG(32KB)+CHR(16KB),兩種區塊都想增大, 那最後ROM得要是PRG(64KB)+CHR(32KB), 即使中文化的需要量沒那麼多也得擴充這麼大, PRG沒照這規則應該會不能跑, CHR沒照這規則可能會影響實機或部分模擬器不能跑。 ========================================================================== 四、實作 以光神話所屬的Mapper1來說,PRG一個區塊16KB, 光神話PRG有128KB,故光神話共有編號0~7共8個區塊的PRG, 又Mapper1固定是最後一個區塊(編號7)在開機時會被映射到0xC000~0xFFFF, 依照規則, 原編號0~6須保持在0~6不可變, 原編號7也須保持是最後一個區塊, 所以我們要安插的地方就落在6、7之間, 這樣可以保持0~6還在原位且原本的7還是最後一塊; 要插入的大小則須是128KB(總大小256KB,是2的8次方), 這樣一來就多了編號7~14(0xE)的區塊可用了。 喔,對了, 之前有提到模擬器要辨識ROM size是透過Header, 所以要記得修改Header中size的定義, 否則會發現此時ROM無法執行, Mesen有提供Header Edit,很方便; 該功能位於Debug -> Edit iNES Header https://meee.com.tw/dWW9ExP 改成256KB後,模擬器就能正常執行了 ========================================================================== 五、程式中如何使用擴充的區段(需6502組合語言) 要使用新增的區塊,就得將其映射進CPU, 這牽涉到各Mapper的定義,依照Mapper1的定義, 是將要切換的編號寫入到$E000~$FFFF(這區段任意挑一個即可), 圖為nesdev查到的Mapper1切RPG ROM的位置定義 https://meee.com.tw/BnBjvXW 圖為Mapper1切換的程式碼範例 https://meee.com.tw/1WVdppw 可以看到寫入的方法不是很直覺,需連續寫五次,且每次寫完後需做bit shift, 感覺很麻煩,但照抄即可 XD 舉例說明,如果要將編號12映射到CPU RAM,程式碼如下 LDA #$C (0xC(16進位) = 12(10進位)) STA $E123 LSR STA $E123 LSR STA $E123 LSR STA $E123 LSR STA $E123 ------------(語法說明,看看就好,有用到再查)------------- LDA(Load to A) 是將數值放入累加器(或者說是A暫存器) STA(Store from A) 是將累加器裡的數值寫到某位置(例如$E123) LSR(Logical Shift Right)是將累加器裡的數值往右做一次bit shift ========================================================================== 六、擴充CHR 剛好舉的案例是無CHR-ROM的,所以沒提到, 基本上擴充CHR沒有預設映射問題, 故只要在檔案最尾巴依照2的次方大小增加並修改Header即可, 切換則是透過$A000-$BFFF & $C000-$DFFF這兩組位置, 方法和上一節一樣。 舉例:將編號4的CHR映射到PPU RAM的$1000~$1FFF LDA #$4 STA $D321 LSR STA $D321 LSR STA $D321 LSR STA $D321 LSR STA $D321 值得注意的是,原本沒有CHR-ROM代表所使用的圖形是1byte 1byte寫進PPU的, 我們加上CHR-ROM後,在Mapper1會導致原本寫入PPU的程式失效, 故還需將原程式由寫PPU的模式改為切換映射的模式; 似乎是有Mapper是同時支援CHR-RAM與CHR-ROM的,我不是很確定 XD 以上。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.192.217.145 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Emulator/M.1731944999.A.615.html

11/19 00:34, 1月前 , 1F
11/19 00:34, 1F

11/19 01:55, 1月前 , 2F
太專業了 純推看不懂...
11/19 01:55, 2F

11/19 07:56, 1月前 , 3F
11/19 07:56, 3F

11/19 08:26, 1月前 , 4F
推推
11/19 08:26, 4F

11/19 09:27, 1月前 , 5F
頂個
11/19 09:27, 5F

11/19 15:55, 1月前 , 6F
推,謝謝
11/19 15:55, 6F

11/20 00:37, 1月前 , 7F
11/20 00:37, 7F

11/20 01:53, 1月前 , 8F
必須推
11/20 01:53, 8F

11/20 15:54, 1月前 , 9F
推推~
11/20 15:54, 9F

11/20 22:22, 1月前 , 10F
11/20 22:22, 10F

11/21 09:38, 1月前 , 11F
大推
11/21 09:38, 11F

11/21 09:40, 1月前 , 12F
推好文,感謝分享
11/21 09:40, 12F

11/21 20:49, 1月前 , 13F
好強
11/21 20:49, 13F

11/22 11:48, 4周前 , 14F
看不懂,但還是要大推
11/22 11:48, 14F

11/23 16:03, 4周前 , 15F
不明覺厲
11/23 16:03, 15F

11/24 00:37, 4周前 , 16F
推 這些都是計算機的硬功夫 組合語言
11/24 00:37, 16F

11/24 08:16, 4周前 , 17F
11/24 08:16, 17F
文章代碼(AID): #1dEs8dOL (Emulator)
文章代碼(AID): #1dEs8dOL (Emulator)