ゲームボーイを作るその16。今回はジャンプの挙動について、どう扱うべきかについて迷ったのでメモ書き程度にまとめておく。
ジャンプ命令(JPNN/JPHL)
ジャンプは他にもフラグを使った条件付きのジャンプや、相対アドレスでジャンプするものなどがあるのだが、ひとまずJPNN
/JPHL
の2つについてをまとめておく。
JPNN
/JPHL
は共に、自分が実装時に命令にふったニーモニックで、アセンブラではそれぞれ次の命令になる。(つなげて大文字にしただけ、NN
は8bitの16進数整数 x 2を表す)
jp $(1000) ; JPNN jp hl ; JPHL
この2つは無条件ジャンプなので処理自体は単純だ。JPNN
はメモリから読んできた2byteが示すアドレスに、JPHL
はHL
レジスタの示すアドレスにジャンプする。
で個人的に引っかかったのが処理サイクルとジャンプするタイミングの扱いだ。それぞれの命令が要するサイクルだがJPNN
は4サイクル、JPHL
は1サイクルで実行となっている。
Game Boy: Complete Technical Referenceには、命令の疑似コードとタイミングが記載されているのだが、それぞれの命令の疑似コードは次のようになっている。
- JPNN
opcode = read(PC++) if opcode == 0xC3: nn = unsigned_16(lsb=read(PC++), msb=read(PC++)) PC = nn
- JPHL
opcode = read(PC++) if opcode == 0xE9: PC = HL
要はOPコードがJPNN
/JPHL
ならPC
レジスタにジャンプ先のアドレスを格納するという動作になる。自分が気になったのは、メモリアドレスにジャンプ先のアドレスを入れるのは、どのサイクルになるのかという点だ。今の自分の設計だと、フェッチとそれ以降の処理という2段のパイプラインになっており、この状態で"Game Boy: Complete Technical Reference"の図を元にジャンプ命令のタイミング図を書くと、次のような感じになる。?
とついてるのは、どのタイミングで扱うのか、、に迷っている所。画像書いてて思ったけど、これパイプラインになってていいのかな。。。この図のとおりに作るなら、PC
にアドレスをライトして次のサイクルでジャンプにすると、JPNN
は1cycle余るという。なのでM4
でジャンプ??するのかという考えもよぎったり。そうするとJPHL
の方でもアドレスを、PC
にライトバックするサイクルで、アドレスバスに出さないとだし。。。
- JPNN
- JPHL
とりあえず色々迷っているが、Mサイクルを遵守する形で動くように作っていこうと思う。blargg-gb-testsの方で何か引っかかったらその時に考えよう。。。