yasuokaの日記: Z80における「手抜き」回転行列
ネットサーフィンしていたところ、このtweetで35年ほど前の悪行がバラされてしまっていたので、当時の記憶を辿りつつ、ざっと書いてみようと思う。
┌ cosθ -sinθ ┐ ┌ x ┐
└ sinθ cosθ ┘ └ y ┘
画面中心を(0,0)とするxy座標系において、適当な微小角度θで回転をおこないたい。θの値は、まあ何でも良くて、とにかく見た目が「回って」いる雰囲気を出したい。ただ、対象とするCPUがZ80なので、乗算は自分で実装するしかなく、そのあたりの「手抜き」を考える。
微小角度θにおいてcosθは1に近い値なので、ここの実装を簡単にすべく、とりあえずcosθ=1-2-kとしてみる。そうすると、sin2θ=2(1-k)-2-2kとなるので、小さい方の項を捨てれば、だいたいsinθ≒2(1-k)/2。つまり、kが奇数なら実装が簡単となり、たとえばk=7なら、cosθ=127/128, sinθ≒1/8となる。
HLレジスタのHレジスタに符号付整数、Lレジスタに256を分母とする分数が入っているとすると、1/8の乗算は単純に
7D LD A,L
CB 2C SRA H
1F RRA
CB 2C SRA H
1F RRA
CB 2C SRA H
1F RRA
6F LD L,A
で済む。一方、127/128の乗算は、私(安岡孝一)の記憶が正しければ
7C LD A,H
2F CPL
07 RLCA
5F LD E,A
9F SBC A,A
57 LD D,A
19 ADD HL,DE
と手を抜いた覚えがある。RLCAのところは、本来はLレジスタのトップビットを反転して持ってくるべきなのだが、それをAレジスタの符号ビットのコピーで誤魔化していて、少しだけ127/128からズレているわけだ。さて、今なら、どう書くかなぁ…。
Z80における「手抜き」回転行列 More ログイン