ブロック転送
(前のページより続く)
目次
さらに展開
2014.8.6午前追記
改良版が投稿されました。40バイトの制限の中で、もう一段ループを展開し、ループ内の転送を5回にしたものです。
転送量 512 バイトは、5 では割り切れません。そこで、3バイト重複転送することにすれば、515 / 3 = 103 で、103回ループで転送できることになります。
LDX #$66 ; 2
LOOP:
LDA $400,X ; 4
STA $600,X ; 5
LDA $467,X ; 4
STA $667,X ; 5
LDA $4CB,X ; 4 / 5
STA $6CB,X ; 5
LDA $532,X ; 4
STA $732,X ; 5
LDA $599,X ; 4
STA $799,X ; 5
DEX ; 2
BPL LOOP ; 3 / 2
冒頭で LDX #$66 としていますが、16進数の 66 は 10進数で 102 。0の時も含め、103回ループです。
さて、重複する転送個所は、LDA $4CB,X となっているところ。CB / CC / CD の3か所が重複します。
そして、この命令の実行クロック数は、4 / 5 となっています。6502 のインデックスレジスタ相対アドレッシングでは、アドレスの上位バイトに繰上りが生じた時、1クロック遅くなることがあるのです。(STA はもともと遅い代わり、この遅延は発生しません)
繰上りが問題なので、ここに重複を持ってくることで、繰り上がりにくい「前の方の」アドレスを指定しています。
さて、ループ内は、遅延が無いものとして 50クロック。103 回ループなので 5150 クロックですが、最後はループ冒頭へのジャンプが発生しないので1クロック速くなり、5149クロック。
100(hex)-cb(hex) = 53(dec) なので、53 回は遅延が発生しません。ということは、50回の遅延が発生し、50クロック遅くなります。
さらに、前処理の 2 クロックを足すと、総計は 5201 クロックです。
実は、4回のループ展開版を作成した際に、一部が重複しても良い、という考えで「6回展開」は作ろうとしました。ただ、これは41バイトになってしまうので、今回のルールでは規定違反です。
6回だと、512/6 を 256/3 2つに分けられるため、遅延の発生を抑えられます。プログラムは示しませんが、この方法だとクロック数は 5075 クロックになります。(それでも MSX には負けています)
無駄の削除
2014.8.10午前追記
ループ途中へ飛び込%