ブロック転送

(前のページより続く)

目次

概要

Z80基本

ループ展開

6502基本

ループ展開さらに展開無駄の削除

速度比較


さらに展開

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午前追記

ループ途中へ飛び込%