header
ds $150 - @, 0
を0でうめたのは、ゲームボーイのROMでは必ずヘッダーが必要で、rgbfix でそのヘッダー情報を埋めている。必ず作法として必要なんですね。
そして最後
Done:
jp Done
で永久ループしています。
Operations & flags
なんとゲームボーイのCPUは掛け算ありません(笑)高級言語しかさわったことのない自分にとっては驚きです。
inc, dec が インクリメント、デクリメント add と sub が足して代入、引いて代入ですね。
add a, 5
は a += 5; です。
cp 144
jp c, WaitVBlank
cp はa - 144 の結果がフラグに反映される(値は変化しない)。ここでは a が144より小さければCのフラグ(オーバーフロー、アンダーフロー)がたち WaitVBlankにもどる。ということで、144になるまで待つという処理になる。
つまり if (c < 144) goto WaitVBlank; ってことですね!
等しいことを検証したい場合は z,nz フラグを使うと。
Jumps
条件付きジャンプです。今実行中のアドレスがPC(プログラムカウンタ)に入っており、これが変更される。
call(サブルーチン)があるらしい。あとで調べる。
; Copy the tile data
ld de, Tiles
ld hl, $9000
ld bc, TilesEnd - Tiles
CopyTiles:
ld a, [de]
ld [hli], a
inc de
dec bc
ld a, b
or a, c
jp nz, CopyTiles
de に Tilesのアドレスを格納、hlには定数$9000を格納して、bcには
TilesEnd - Tiles (これはアセンブラが計算してくれる?)はデータの長さになり、これをbcに格納する。
CopyTilesは deにあるデータをaに格納、このaをhlのアドレスに格納たあとhlをインクリメント([hli]でインクリメントできる)de (コピー中のアドレス)をインクリメント、bc (コピーすべき残りの長さ)をデクリメント、a に bcの上位ビットをいれて c と or をとることによってどちらかが0でないと、nzがたつので CopyTiles に戻って繰り返す。
if (bc != 0) goto CopyTiles; ですね。orをつかってbcが0であるか判定しています。
ゲームボーイの画面は8x8のタイルを定義して、それをタイルマップで配置します。こちらはタイルのデータをVRAM($9000から)にコピーしています。
CopyTilemap:
ld a, [de]
ld [hli], a
inc de
dec bc
ld a, b
or a, c
jp nz, CopyTilemap
こちらはタイルマップの場合($9800からはじまる)で同様ですね。
ループが難しい!慣れるとイディオムのように使えるのかもしれません。
次回
いよいよデバッガつかってトレースです。たのしみ!