“遊戲機模擬器” 注重的是 “嚴格模擬硬體”,要精確,可以對照 MAME程式碼,所有問題都能在裡面找到對應答案:
1. 模擬 CPU:
MAME裡實現了各種 68000, z80,mips, sparc, arm,pic16c5x,nec, alpha,等 100 多款你見過的或者沒見過的主從協處理器的模擬,雖然都是 switch case opcode,但是不像 lua虛擬機器。MAME的 CPU模擬重點在 “精確實現硬體”,除了指令集實現外,還有各種軟硬終端/trap/異常處理/IO實現。舉個簡單例子,一個遊戲主機需要 4MHz 的 z80晶片,你就得給我真的按照 4Mhz來跑,每條指令計算週期,不能多也不能少,你要把 4Mhz跑成 8Mhz,遊戲玩起來節奏就不一樣了。比如以前老遊戲機上敵人一多,就會慢下來,你實現模擬器,也得把這種慢下來給實現了。另外很多街機是雙處理器,比如一塊 68000 + z80,你不能復原老主機的執行速度,一些寫的粗糙的遊戲 ROM可能會出錯。
模擬 CPU重點是 “精細”,比如浮點數誤差最好一致,比如中斷優先順序你得模擬出來,模擬器由於按照 interval 來執行,更容易產生同時多個硬體中斷被觸發,比如 “手柄按鍵” ,多核通訊之類各種東西加在一起,某個核滿負荷執行的情況下,優先順序低的可能永遠得不到處理,弄錯了可能遊戲就沒法玩了。
2. 模擬匯流排:
匯流排也有好多規格需要實現,不同基板的匯流排連結不同cpu 和外設的方式都不一樣,還是需要 “精確模擬”,比如 ROM /RAM / IO 地址對映,一些大容量遊戲需要 ROM 的 BANK 切換,還有一些遊戲會在卡帶上帶有擴充套件記憶體,除此之外還要正確模擬各種異常,比如某些 RAM,讀寫奇數地址會出錯,要給對應 CPU傳送異常訊號,某些老點的 RAM只能讀寫 16bit的 WORD,不能讀寫 DWORD或者 BYTE,否則都無效。這些你都得模擬到位了,有些有 BUG的遊戲,錯誤的寫了記憶體,在真實主機上,寫操作直接被硬體忽略掉了,沒有損傷,但軟體模擬不注意執行了那條指令結果就不一致了。
3. 外設模擬:
音訊晶片,I/O,圖形加速晶片,隨機數發生器,音影片輸出,搖桿,時鐘等。有些外設是有bug的,你也要把這些歷史上的硬體bug給模擬進去,不然遊戲可能行為不一致。
4. 除錯系統:
提供終端和介面可以記憶體 DUMP,反彙編,修改指令和資料,儲存現場之類的。
有史以來出現過的遊戲機硬體數不勝數,但是他們用到的晶片或者硬體是有限的,比如z80和 68000這類流行的晶片,具體每臺主機其實就是一份配置檔案,包含使用那種匯流排,哪些cpu,分別按照什麼速度來執行,記憶體I/O佈局,關聯哪些外設,BIOS和啟動載入等資訊。
總之是個辛苦活,你需要一本硬體手冊,然後邊查邊弄。
如果你嫌 MAME太複雜龐大,再推薦一個 gens 的程式碼,只針對世嘉16位機的 Windows實現,條理很清晰,很多比世嘉簡單的 FC模擬器寫的都沒有 gens那麼結構清晰,簡單易讀。它就不像MAME那麼大而全,很多步驟實現的很直接不需要配置那麼多,程式碼量也不大。
現在新進的模擬器很多,沒機會逐一檢視他們的實現細節,只記得有幾款比較新的模擬器都是直接裁剪 MAME的部分程式碼來弄的,因為 MAME裡面幾乎實現了所有遊戲能用的晶片了,拿出來改改引數加點指令集就可以用,比如 MAME裡面模擬了 mips,我們裁剪出來實現 PSP模擬器,個別指令有些區別需要改一下,然後我們著重自己實現 PSP裡面 MAME沒有的硬體部分。
--
“遊戲機模擬器” 注重的是 “嚴格模擬硬體”,要精確,可以對照 MAME程式碼,所有問題都能在裡面找到對應答案:
1. 模擬 CPU:
MAME裡實現了各種 68000, z80,mips, sparc, arm,pic16c5x,nec, alpha,等 100 多款你見過的或者沒見過的主從協處理器的模擬,雖然都是 switch case opcode,但是不像 lua虛擬機器。MAME的 CPU模擬重點在 “精確實現硬體”,除了指令集實現外,還有各種軟硬終端/trap/異常處理/IO實現。舉個簡單例子,一個遊戲主機需要 4MHz 的 z80晶片,你就得給我真的按照 4Mhz來跑,每條指令計算週期,不能多也不能少,你要把 4Mhz跑成 8Mhz,遊戲玩起來節奏就不一樣了。比如以前老遊戲機上敵人一多,就會慢下來,你實現模擬器,也得把這種慢下來給實現了。另外很多街機是雙處理器,比如一塊 68000 + z80,你不能復原老主機的執行速度,一些寫的粗糙的遊戲 ROM可能會出錯。
模擬 CPU重點是 “精細”,比如浮點數誤差最好一致,比如中斷優先順序你得模擬出來,模擬器由於按照 interval 來執行,更容易產生同時多個硬體中斷被觸發,比如 “手柄按鍵” ,多核通訊之類各種東西加在一起,某個核滿負荷執行的情況下,優先順序低的可能永遠得不到處理,弄錯了可能遊戲就沒法玩了。
2. 模擬匯流排:
匯流排也有好多規格需要實現,不同基板的匯流排連結不同cpu 和外設的方式都不一樣,還是需要 “精確模擬”,比如 ROM /RAM / IO 地址對映,一些大容量遊戲需要 ROM 的 BANK 切換,還有一些遊戲會在卡帶上帶有擴充套件記憶體,除此之外還要正確模擬各種異常,比如某些 RAM,讀寫奇數地址會出錯,要給對應 CPU傳送異常訊號,某些老點的 RAM只能讀寫 16bit的 WORD,不能讀寫 DWORD或者 BYTE,否則都無效。這些你都得模擬到位了,有些有 BUG的遊戲,錯誤的寫了記憶體,在真實主機上,寫操作直接被硬體忽略掉了,沒有損傷,但軟體模擬不注意執行了那條指令結果就不一致了。
3. 外設模擬:
音訊晶片,I/O,圖形加速晶片,隨機數發生器,音影片輸出,搖桿,時鐘等。有些外設是有bug的,你也要把這些歷史上的硬體bug給模擬進去,不然遊戲可能行為不一致。
4. 除錯系統:
提供終端和介面可以記憶體 DUMP,反彙編,修改指令和資料,儲存現場之類的。
有史以來出現過的遊戲機硬體數不勝數,但是他們用到的晶片或者硬體是有限的,比如z80和 68000這類流行的晶片,具體每臺主機其實就是一份配置檔案,包含使用那種匯流排,哪些cpu,分別按照什麼速度來執行,記憶體I/O佈局,關聯哪些外設,BIOS和啟動載入等資訊。
總之是個辛苦活,你需要一本硬體手冊,然後邊查邊弄。
如果你嫌 MAME太複雜龐大,再推薦一個 gens 的程式碼,只針對世嘉16位機的 Windows實現,條理很清晰,很多比世嘉簡單的 FC模擬器寫的都沒有 gens那麼結構清晰,簡單易讀。它就不像MAME那麼大而全,很多步驟實現的很直接不需要配置那麼多,程式碼量也不大。
現在新進的模擬器很多,沒機會逐一檢視他們的實現細節,只記得有幾款比較新的模擬器都是直接裁剪 MAME的部分程式碼來弄的,因為 MAME裡面幾乎實現了所有遊戲能用的晶片了,拿出來改改引數加點指令集就可以用,比如 MAME裡面模擬了 mips,我們裁剪出來實現 PSP模擬器,個別指令有些區別需要改一下,然後我們著重自己實現 PSP裡面 MAME沒有的硬體部分。
--