# 2020q3 專題: Game Boy 模擬器
## 目標
* 改進[給定的 Game Boy 模擬器](https://github.com/sysprog21/gameboy-emu),提升其執行效率、程式碼重構 (refactor),及其相容性
* 透過 [GBIT](https://github.com/koenk/gbit) 確保程式碼實作的相容性和正確性
* 量化分析直譯器效率,並尋求效能改進的方案
* 善用 [perf](http://www.brendangregg.com/perf.html) 和 GNU Toolchain
* 實作 CPU 除錯器,允許單步執行和分析特定記憶體內容
## 準備工作
* 研讀 [Gameboy Overview](https://thomas.spurden.name/gameboy/),理解 Game Boy 硬體和相關模擬器的撰寫
* 研讀 [Z80 Emu Evolution](https://floooh.github.io/2017/12/10/z80-emu-evolution.html) 以理解模擬器設計考量。注意: Game Boy CPU 使用 Z80 的客製化版本,和原本的 Z80 不相容
* 研讀 [Game Boy 遊戲軟體發展](http://140.134.131.145/upload/paper_uni/912pdf/910211.pdf),理解 Game Boy 產品、硬體資訊、記憶體映射,及 GBDK 流程
## Game Boy 硬體資訊
> [Game Boy 的硬體設計與運作原理](https://hackmd.io/@RinHizakura/BJ6HoW29v)
## 現有的 Game Boy 模擬器
* [binjgb](https://github.com/binji/binjgb)
* 可[在網頁瀏覽器中啟動](https://binji.github.io/binjgb/)
* Convenient Python test harness using hashes to validate
* Debugger with various visualizations
* [jgbc](https://github.com/jamie-mh/jgbc)
* 實作完整
* 內建測試
* [SameBoy](https://github.com/LIJI32/SameBoy)
* Supports Game Boy (DMG) and Game Boy Color (CGB) emulation
* High quality 96KHz audio
* Battery save support
* Save states
* Advanced text-based debugger with an expression evaluator, disassembler, conditional breakpoints, conditional watchpoints, backtracing and other features
* Several [scaling algorithms](https://sameboy.github.io/scaling/) (Including exclusive algorithms like OmniScale and Anti-aliased Scale2x; Requires OpenGL 3.2 or later or Metal)
* [PlutoBoy](https://github.com/RossMeikleham/PlutoBoy)
* 非常完整
* [GBC](https://github.com/koenk/gbc)
* When the emulator detects unexpected behavior (e.g., accessing an unknown memory region), it will drop into a built-in debugger.
* [Worldwide](https://github.com/pokemium/Worldwide): GameBoyColor emulator written in Go
* 具備 hq2x
* 非常完整
* [dmg](https://github.com/majestic53/dmg)
* 程式碼架構清晰
* 內建 test suite
* [mgba/src/sm83](https://github.com/mgba-emu/mgba/tree/master/src/sm83): mGBA 是 Game Boy Advance 模擬器,儘管主要針對 ARMv4T,但裡頭的 sm83 則是針對 GBZ80,這部分程式碼相當簡潔並附有指令層級除錯器
## [給定的 Game Boy 模擬器](https://github.com/sysprog21/gameboy-emu)
1. 取得原始程式碼:
```shell
$ git clone https://github.com/sysprog21/gameboy-emu
```
2. 安裝 SDL2 套件
3. 編譯
```shell
$ cd gameboy-emu
$ make
```
4. 下載 Game Boy ROM 並測試
```shell
$ make download_rom
$ build/emu roms/HungryBirds.gb
```
預期會見到以下執行畫面:
![HungryBirds for Game Boy](https://i.imgur.com/DhRRdnf.png)
## Computed Goto
* [Computed goto for efficient dispatch tables](https://eli.thegreenplace.net/2012/07/12/computed-goto-for-efficient-dispatch-tables)
* 使用案例: [q3vm](https://github.com/jnz/q3vm)
| Interpreter | Time |
| ----------- | ---- |
| Default | 3.063 s |
| w/ computed gotos | 1.771 s |
- commit [speed up computed gotos with the right GCC flags](https://github.com/jnz/q3vm/commit/bb4848c25b2b95c08b9aa03bb6ac46ef4948d900)
- `USE_COMPUTED_GOTOS` : [src/vm/vm.c](https://github.com/jnz/q3vm/blob/master/src/vm/vm.c)
## Opcode Generator / Instruction Tester
* 參照 [emu-gameboy](https://github.com/geaz/emu-gameboy),允許由表格來產生 opcode 及其實作程式碼
* 預期產出
* 讀取 [Gameboy CPU (LR35902) instruction set](https://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html) 表格和現有的實作,產生對應的 C 程式碼
* 將 CPU 指令分類,提供個別實作,例如 [src/instructions](https://github.com/SakiiR/Emulator/tree/master/src/instructions)
* [GBIT](https://github.com/koenk/gbit): Game Boy Instruction Tester
* Tests all instructions of a Game Boy CPU against a known-good implementation to detect implementation bugs.
* Useful for testing and debugging, especially early on in Game Boy emulator development where test ROMs do not run yet.
## 研究進度
[gameboy-emu](https://hackmd.io/@Rsysz/gameboy)
## 參考資訊
* [Nintendo Learning Environment](http://olab.is.s.u-tokyo.ac.jp/~kamil.rocki/nintendo/): AI-oriented, high-performance and minimal Nintendo Gameboy emulator