Z80 vs 6502
目次
さらに展開
2014.8.5 午後追記
一つ上の項目で書きましたが、僕がコード量の計算を間違えるという恥ずかしいミスをしました。
これに気付いた方が、指摘と共に「もっと展開できる」とプログラムを送ってくれました。
ただ、実際送ってもらったものは、端数が「2」の時にチェック漏れで計算回数が狂う、というバグがありました。
このバグを解消するため、前処理部分を大幅に変更しています。
LD BC,100 ; 10 (11)
LD HL,0; 10 (11)
LD A,C ; 4 (5)
AND 3 ; 7 (8)
JR Z,LOOP ; 12 / 7 (13 / 8)
DEC A ; 4 (5)
JR Z,MOD1 ; 12 / 7 (13 / 8)
DEC A ; 4 (5)
JR Z,MOD2 ; 12 / 7 (13 / 8)
JR MOD3; 12 (13)
LOOP:
ADD HL,BC ; 11 (12)
DEC C ; 4 (5)
MOD3:
ADD HL,BC ; 11 (12)
DEC C ; 4 (5)
MOD2:
ADD HL,BC ; 11 (12)
DEC C ; 4 (5)
MOD1:
ADD HL,BC ; 11 (12)
DEC C ; 4 (5)
JP NZ,LOOP ; 10 / 10 (11 / 11)
全部で 30バイトです。今回の例題の「1~100」に最適化するなら、前処理の JR Z,LOOP はJP にしたかったところなのだけど、そうすると1バイト増えるのでできませんでした。
これ、実は「ループ展開条件省略版」として当初僕が作ったたプログラムと、ほぼ同じものです。容量計算間違えなければこちらを出していたかも…と言いたいところですが、実はその時は「6502 の最長プログラムと同じ 28バイトまで」規定で考えていたので、これでも容量オーバーでした。
容量に関しては、6502 の最長を基準としてしまうと 6502 に不利なので、後で規定を変更しました。
前処理が長いですが、100 回の時は 4 で割った端数がないため、最初の条件分岐で LOOP に飛び込んでしまいます。このため、前処理後半は実行されず 48クロック。
ループ内では、17 クロックの処理を4回繰り返しています。最後にループ冒頭に戻るため、10 クロックのジャンプ命令。
ループは 25回繰り返されるので、(17*4+10)*25 = 1950 クロック。
総計で 1998 クロックです。
速度判定
2014.8.5 午後時点での判定。
6502 は 1087 クロック。周波数を考慮するため2倍すると、MSX での 2174クロック相当の実時間になります。
Z80 は 1998 クロックなので、176クロック、9% くらい MSX が速い。
あらら、結構差が付きました。周波数半分だから性能半分、という説は否定するのに十分な速度ですが。
ただ、これは「今回のルールでは」という話です。元々、16bit 計算という題材が Z80 に有利なように考えられたものでしたからね。
次の例題は…掛け算