またゲームボーイエミュレータ触ってる

一年位放置してたゲームボーイエミュレータをここ一週間位気になりだして触ってる。前回まではコントローラーの実装が良くなくてオープニングムービーは流れるけど、そこから操作できず進めないというところで詰んでた。そのへんを考え直して実装し直した。

ジョイパッド操作を読むとき、JOYPに書き込みが発生する。アクションか矢印のどちらとしてキーマトリックスを認識するかフラグを立てる。フラグが立ったタイミングでJOYPにジョイパッド入力を書き込む。それだけのことなんだけど。GUIのキーイベントのタイミングでJOYPを更新してたので、CPUのタイミングとマッチしていなくて認識されなかった。キーマトリックス操作のレジスタの性質上、JOYPは一回リセットが入るので、CPUのJOYPのWrite/Readのタイミングで実際のキー入力を別で保存しておいたデータからJOYPを生成する必要があった。ソフト側からキーマトリックスを操作する感じを理解できていなかったのが敗因。

ディスプレイも、スプライトの位置やウィンドウの位置が合わなかったりしてたけど、これも解決した。バックグランドマップ上でのOAM[0,1]、WX、WYかと思ってたけど違って、144x160の実際の液晶ディスプレイ上での位置だった。BGマップはSCX,SCYでくり抜かれる用のバッファーだった。グローバルなバッファーがあってそこに全部書き込まれてて、スクロールで抜き出す認識だったけど全然違った。PPUはだいたいこれで良くなったが、まだ表示されないスプライトがあったり、なぜか肝心のプレイヤー、リンクが表示されなかったりしてる。スプライトのYかXが0であった場合、そのスプライトは表示されない。リンクのOAMもなぜかYが0になっていて表示されない。MBCにlogを噛ませてみると、どうも正しい座標を書き込んではいるが、すぐリセットもされていて、ディスプレイのレンダリングのタイミングではリセットされてるので表示されないっぽい。PPUのフラグ管理かクロックの同期が悪いのか、てかなんでプレイヤーの座標のリセット入るんだよ。またしばらく詰みかなぁ...タイマー、割り込み系が怪しいかとおもったけど、LCDC以外割り込み発生してないっぽいし...わからんな...

PPUしっかり実装できても、APU(音)まったく触ってないのでまだやることたくさんありそうで良い。MBCもMBC3RTCとかやらんと、ポケモン動かないからな。長いな。