yasuokaの日記: Z80におけるPaethの回転行列 1
一昨日・昨日の日記を読み返しながら、イキオイ余ってPaethの回転行列を、Z80で汎用的に実装してしまった。IXレジスタにx座標の256倍を、IYレジスタにy座標の256倍を、HLレジスタに-tan(θ/2)の16384倍を、DEレジスタにsinθの16384倍を、それぞれ符号付整数で入れて呼び出すと、θだけ回転(ただし-2π/3≦θ≦2π/3)した結果がIX,IYレジスタに返ってくる。
06 03 LD B,3
DD E5 PUSH IX
FD E5 PUSH IY
E5 PUSH HL
CB 40 BIT 0,B
D9 EXX
C1 POP BC
D1 POP DE
E1 POP HL
20 01 JR NZ,+3
EB EX DE,HL
CB 21 SLA C
CB 10 RL B
30 0C JR NC,+14
AF XOR A
93 SUB E
5F LD E,A
9F SBC A
92 SUB D
57 LD D,A
AF XOR A
91 SUB C
4F LD C,A
9F SBC A
90 SUB B
47 LD B,A
CB 21 SLA C
CB 10 RL B
30 01 JR NC,+3
19 ADD HL,DE
CB 2A SRA D
CB 1B RR E
78 LD A,B
B1 OR C
20 F1 JR NZ,-13
E5 PUSH HL
D9 EXX
CB 40 BIT 0,B
20 03 JR NZ,+5
FD E1 POP IY
C2 DD E1 JP NZ,E1DDH
EB EX DE,HL
10 C3 DJNZ -59
EB EX DE,HL
C9 RET
θ=2π/48に対し、いくつかの-tan(θ/2)とsinθを試したところ、普通にHL=FBCEH, DE=085AHすなわち-tan(θ/2)=-1074/16384, sinθ=2138/16384とするのが、いちばん精度が良かった。この値だと、(100,0)すなわちIX=6400H, IY=0000Hから、48回まわしたところで、IX=640AH, IY=0000Hとなる。文句なしの精度だ。ただ、このプログラム、絶対にジャンプしない「JP NZ,E1DDH」とか、かなりアヤシイ部分もあるので、もし万が一どこかで使う場合には注意されたい。
┌ 1 -1074/16384 ┐┌ 1 0 ┐┌ 1 -1074/16384 ┐
└ 0 1 ┘└ 2138/16384 1 ┘└ 0 1 ┘
ずらし読み…… (スコア:1)
なんだろうと思ったら、POP IX (DD E1) をスキップするためだったのですね。
私はこういう場合、LD BC,E1DDH を使っていたのですが、今回はBCレジスタを破壊できないのですね。
#なんだか懐かしい……