一見すると何やら不思議なことをしているこの処理ですが、実はコレ、ループを使わずに縦の描画ラインを可変にするテクニックです。ループ展開している途中にジャンプする事で、描画ライン数を調整してたりします。描画の高速化テクニックに有用ですので覚えておくと良いかと思います。
REPT 16 pop de ; 1 ld (hl), e ; 1 set 5, h ; 2 ld (hl), d ; 1 add hl, bc ; 1 = 6 ENDM
この REPT16 は最大で縦16ドットの繰り返しを意味しています。1ループの命令総バイト数は6バイトです。そのため、ジャンプ先を6バイト単位で調整すれば、ループを無視できます。それを分かりやすくするために…
※使い所がかなり難しいけど、うまくセッティングできれば筐体内の熱い空気に触れていない冷えた空気でCPUを冷やせるようになるダクトキットです。厚みが全て異なるスポンジで構成されています。
DrawShot8x16: .unit equ 6 .line8 equ .begin - .unit * 8
このようなラベル定義を行っています。DrawShot8x16を呼び出すと縦16ラインですが、DrawShot8x16.line8を呼び出すと、縦8ラインで描画できるという仕組みです。一見するとどこにもバグがないように見えますが、実はこのラベル定義に問題がありました。それは.beginのアドレスです。起点とするべきアドレスは、最終最後の ADD HL,BC の直後なのですが、.begin のアドレスは $ + 1 となっています。つまり +1 分余分なのです。この1バイトのズレは一番最初の POP DE を無効化してしまいます。結果、不定値が GVRAM に書き込まれることで、画像下部にゴミが入ってしまうのです。
実はよくバグった状態を観察すると、画像も全体的に1ドット上にズレて表示されているのですが、なかなかそれは気が付きにくいです。ということで、コードそのものの問題ではなく定数定義設定ミスでした。正しいコードは以下のようになります。※使い所がかなり難しいけど、うまくセッティングできれば筐体内の熱い空気に触れていない冷えた空気でCPUを冷やせるようになるダクトキットです。厚みが全て異なるスポンジで構成されています。
;----------------------------------------------------------------------- ; ショット画像を描画する ; HL 画像データアドレス ; DE 描画アドレス ; DrawBullet8x8: ld (DrawShot8x16.begin), sp di ld sp, hl ex de, hl ld bc, - VRAM.WIDTH - $2000 jp DrawShot8x16.line8 DrawShot8x16: .unit equ 6 .line8 equ .begin - .unit * 8 - 1 ; !! -1が必要 !! ld (.begin), sp di ld sp, hl ex de, hl ld bc, VRAM.WIDTH - $2000 REPT 16 pop de ; 1 ld (hl), e ; 1 set 5, h ; 2 ld (hl), d ; 1 add hl, bc ; 1 = 6 ENDM .begin equ $ + 1 ld sp, 0 ei ret

コメント