私が作成した Newシティヒーローというゲームでは、消費メモリを削減するために様々なテクニックを駆使したのですが、その中でリアルタイムビット左右反転というのがあります。
Newシティヒーロー
通常、ビット反転を行うためには8回のローテートが必要で、軽い処理ではありません。これをゲーム実行中にリアルタイムで反転しても、実用に足る速度を出すためのテクニックとなります。


  • 普通のビット反転
通常、ビット反転を行うには以下の処理を必要とします。

ld b, 8 .loop rrca rl c djnz .loop
ld a, c ret
Acc を反転するだけなのに、8回ループが必要ですし、BCは壊すため有用ではありません。やってる事は、Acc の値を右に CF として取り出して、C レジスタに左から順次入れているだけです。結果、右側のビットが左側に移動しますので、反転した結果が得られます。


  • 高速化の考え方
Z80 で最も簡単な高速化手法はやはりテーブル化です。また、Z80 アライメントによる高速化でも説明しましたが、桁上がりや桁下がりが発生するような 16bit 計算は遅くなります。この問題を解決しつつ、テーブル化できれば高速化は容易いと考えます。

8ビットレジスタが扱える数値は 0x00 から 0xFF の256種類しかありません。そのため、256種類の反転済みテーブルを用意して参照するだけで、いとも簡単に結果が取り出せます。また、256個のデータならば、全てのデータを 256境界内に収める事が出来ます。そのため、ALIGN 256 とすれば、参照は下位8ビットだけ操作すれば可能という事になります。

方向性が見えたので、実装します。
※ これを使っています。モノはエルゴトロンみたいで、お辞儀する事も無く堅牢で気に入っています。なにより机が広く使えますからね!


  • テーブルを生成する
データとして256個のデータをエクセルか何かで生成してソースに保持しても良いのですが、単純な計算で結果は得られますので、今回は256テーブルをプログラムで生成してしまいます。

; ; 反転テーブルを作成する ; InitRevTbl: xor a ld hl, RevTbl ld e, 8 .next ld b, e .loop rrca rl d djnz .loop ld (hl), d inc l inc a jr nz, .next ret
0 から 255 までの反転テーブルを作ります。開始は 0、終了は 0xFF ですので、その元となる値は Acc で用意します。同時に、テーブルに結果を収めていきますので、テーブルトップアドレスを HL に入れます。8回ループは DJNZ のため Bレジスタを使うのが良いですが、LD b,8 を 256回実行すると、それなりに遅いので、初期化用のレジスタ E に 8 を入れておき、B の初期化は E からのレジスタ間代入としてしまいます。これで最速の4サイクルでループします。

RRCA で右側からビット情報を CF に取り出します。すかさず RL D で D レジスタに左方向に CF 情報を入れます。これを 8回ループする事で Acc は元の値に戻り、D には反転した結果が残ります。この D の値を HL が示す場所に代入して、HL を次のアドレスに、Acc を次の数値に変更します。ALIGN 256 テーブルなので、桁上がりは起きない前提ですから、INC HL ではなく INC L で済ませています。INC A の結果が ZF=1 なら全ての出力が完了したので終了します。

テーブルを格納するアドレス RevTbl は例えば以下のように定義します

RevTbl equ $FF00 ; 反転テーブル

アドレス定義ですが、tools80 なら以下のように記述したいところです。

org $FF00
RevTbl: ds 256 ; 反転テーブル


  • ビット反転する
ここまで出来てしまえば後は簡単です。Acc の値をビット反転するには以下の処理を行います。

ld l, a ld h, RevTbl / 256 ld a, (hl)
どう考えても最速ですよね😁
ビット反転データの取り出しがあまりにも短いので、サブルーチンにしてしまうとオーバーヘッドがもったいないです。そのため、下記のようにマクロにして、処理に埋め込んでしまった方が得策です。

; ; Acc を反転する ; REVACC() MACRO ld l, a ld h, RevTbl / 256 ld a, (hl) ENDM
これで Acc を反転したいタイミングで、REVACC() と記述するだけで簡単に反転します。Newシティヒーローではパターン反転に加えて、キャラ位置反転とPCG再定義処理が必要ですが、やってる事はこの記事内と全く同様です。

※ Amazonブランドはちょっと…という場合はちょっとだけ高くなりますが、元メーカーの純正品を。モノは全く変わらないっぽいです。