ハードウェアの気になるあれこれ

技術的に興味のあることを調べて書いてくブログ。主にハードウェアがネタ。

ゲームボーイを作る(6) - 最初のCPUテストコードの作成

スポンサーリンク

ゲームボーイを作るその6。CPUを作るためにcpu_instrsを解析していたが、最初に動かすテストとして使うのは厳しそうということで、まずは自前のテストコードをそれを動かす環境を用意する。

簡単なテストコードを作る

CPUを作るためにcpu_instrsを解析していたが、テスト部分にたどり着くまでに、CPUがだいたい動く状態になってそうな気配を感じた。 そのためcpu_instrsを通すのは、CPUの基本的な動作がある程度動いた状態で、細かい(&把握できてない)部分の仕様を確認する段階で使うのが良いと判断した。 今回は自分で簡単なテストコードを作り、それを動かすためのテスト環境を実装してみることにする。

命令については、次のサイトとかが見やすくまとまっていて非常にありがたかった。

最初はレジスタのロード命令あたりから、ということでただ単にレジスタへのロード命令を並べたコードを用意した。ちなみにcpu_instrsとかのアセンブラ眺めながら、適当に雰囲気で書いてます。せっかくなので、ビルドに失敗したやつとかも含めて載せてます。

  • 最初に書いたコード(ビルド失敗)
.org $100
  ld a, hl

上記はリセット開始直後のアドレスにただ単にld命令を書いただけのもの。これをwla-gbに渡すと、次のような表示が出てビルドに失敗した。(なんかエラーメッセージっぽくないんだけど、オブジェクトファイルが生成されない)

$ wla-gb -o test.o ./01_ld.s
INCLUDE_DIRECTIVES: ROMBANKS/ROMBANKMAP wasn't defined.

どうやらROMバンクとバンクのマップというものを定義しないとダメらしい。ということで、それらしき部分をbuild_rom.sから持ってきて再トライ。

  • ROMBANKS/ROMBANKMAP追加したつもり版(これも失敗)
.romBankSize   $4000
.romBanks      2

.org $100
  ld a, (hl)
$ wla-gb -o test.o ./01_ld.s
MEM_INSERT: The current address ($0100) overflows from SLOT 0.
   ^ ./01_ld.s:7: Writing a byte

今度は先頭のアドレスが、SLOT 0の領域からはみ出ていると言われた。というか、ROMBANKMAP追加版のつもりだったけど、MAP的な要素が確かに入っていなかった。

  • ROMBANKS/ROMBANKMAP追加したつもり版2(成功)
.memoryMap
     defaultSlot 0
     slot 0 $0000 size $4000
     slot 1 $C000 size $4000
.endMe

.romBankSize   $4000
.romBanks      2

.org $100
  ld a, (hl)

上記のコードを再度ビルドしてみた所、ちゃんとオブジェクトファイルが生成され、wlalinkコマンドによりバイナリが生成できた。 ここで使用しているlinkfilecpu_instrs/commonにあるものをそのまま流用している。

$ wla-gb -o test.o ./01_ld.s
$ wlalink linkfile test.gb
$ ls -l
合計 44
-rw-rw-r-- 1 diningyo diningyo   213  7月 17 23:44 01_ld.s
-rw-rw-r-- 1 diningyo diningyo    17  7月 17 23:42 linkfile
-rw-rw-r-- 1 diningyo diningyo 32768  7月 17 23:44 test.gb
-rw-rw-r-- 1 diningyo diningyo   102  7月 17 23:44 test.o

出来上がったバイナリをエミュレータで実行してみると、チェックサムが一致しないとの警告が出ていた。テスト用のバイナリなので、あんまり気にしなくもよいが、一応確認しておく。

f:id:diningyo-kpuku-jougeki:20210718161324j:plain

f:id:diningyo-kpuku-jougeki:20210718161501j:plain

cpu_instrsのデータはちゃんとチェックサムが一致しているのになんで??と思って探してみた所wla-dxのドキュメントがあるのに気づいた。

ちゃんとチェックサム計算のディレクティブ(.computeChecksum/.computeComplementCheck)が準備されてますね。build_rom.sにもしっかり含まれていました。

なんか今のドキュメントによると古い名前のようで、今は.COMPUTEGBCHECKSUM/.COMPUTEGBCOMPLEMENTCHECKになっている模様。 ひとまず、この2つのディレクティブを追加したところ、チェックサムに関する警告はでなくなった。その代わりロゴに関するデータのチェックに失敗するというメッセージが出ているけど。

このメッセージは、build_rom.sに含まれている、次のデータを$104から配置すれば消すことができる。今回のCPUテスト用バイナリデータとしては、必要ではないので、この辺のデータは省く方向で。

.byte $CE,$ED,$66,$66,$CC,$0D,$00,$0B
.byte $03,$73,$00,$83,$00,$0C,$00,$0D
.byte $00,$08,$11,$1F,$88,$89,$00,$0E
.byte $DC,$CC,$6E,$E6,$DD,$DD,$D9,$99
.byte $BB,$BB,$67,$63,$6E,$0E,$EC,$CC
.byte $DD,$DC,$99,$9F,$BB,$B9,$33,$3E

という事で、最終的に作った最初のテストコードは次のような感じ。ただ単に即値ロード命令でaレジスタ0xa5をロードして、それを他のレジスタに伝搬させていくだけ。

 .memoryMap
         defaultSlot 0
         slot 0 $0000 size $4000
         slot 1 $C000 size $4000
    .endMe

    .romBankSize   $4000 ; generates $8000 byte ROM
    .romBanks      2

    .org $100
      ld a, $a5                  ; a = $a5
      ld b, a
      ld c, b
      ld d, c
      ld e, d
      ld l, e
      ld e, l

次はテストベンチ側の実装をしていく。