ランダムアクセス

目次

概要

Z80 基本

テーブル参照&POPアクセス自己書き換え

6502基本

16bitテーブル小改良

速度判定


6502基本

DATA は、縦座標が 64 個分並んだあと、横座標が 64個、キャラクタ番号が 64 個並びます。

各配列の先頭からの位置が同じものが1組となっています。


	LDX #>DATA ; 2
	LDA #0 ; 2
	STA >0 ; 3
	CLC ; 2

LOOP:
	; 縦位置を考慮して VRAM の上位バイトを計算
	LDY DATA,X ; 4
	BMI END ; 3 / 2
	LDA SHIFT,Y ; 4
	AND #$03 ; 2
	ADC #<VRAM ; 2
	STA >1 ; 3

	; VRAM 下位バイトを計算
	LDA SHIFT,Y ; 4
	AND #$E0 ; 2
	ADC DATA+64,X ;4
	TAY; 2

	; キャラを書き込む
	LDA DATA+128,X ; 4
	STA (0),Y ; 6
	INX ; 2
	BCC LOOP ; 3 / 2
END:


SHIFT:
	DB 00, 20, 40, 60, 80, A0, C0, E0
	DB 01, 21, 41, 61, 81, A1, C1, E1
	DB 02, 22, 42, 62, 82, A2, C2, E2


SHIFT から、24バイトのデータテーブルがあります。

これは、0~24 の数値を、5bit ローテートした値が入っています。

これにより、縦座標の 5bit shift の計算を高速化しています。


ローテートした値の「下位2bit」に VRAM アドレスの上位 8bit を足し、>1 に入れています。

ちなみに、>0 は前処理で 0 を入れた後、常に 0 のままです。


「上位3bit」が、VRAM アドレスの下位バイトに当たります。

こちらはさらに横座標を足して、VRAM アドレスの下位 8bit が完成。


最後に、STA (0),Y でキャラクターの書き込みを行っています。

これは、ゼロページの 0 の値を下位、1 を上位とした 16bit アドレスに、さらに Y を足したアドレスに、A レジスタの値を書き込む命令です。

VRAM の下位アドレス(Yに入れてある)はここで足してしまうため、下位アドレスの >0 は常に 0 にしてあるのです。


ループ内の計算は、一切キャリーを発生しません。

そのため、前処理でキャリーをクリアした後は、足し算前にもキャリーをクリアしていません。

ループ最後の分岐も、「キャリーがクリアなら」を使用していますが、条件分岐ではなく必ずジャンプします。(実行速度は変わらないが、コードが短縮できる)


1キャラクタの書き込みに 44クロック。これを 48回繰り返します。

前処理は 9クロックで、終了時には条件分岐で 7クロック必要です。


44 *48 +9+7 = 2128


総計 2128 クロック。


ちなみに、SHIFT テーブルのサイズを倍増し、48バイトにすると、さらに高速化できます。

詳細は書きませんが総計 1840 クロックになります。

ただ、現時点でも Z80 よりずっと速いので、テーブルを肥大化させるのは自粛しています。

(Z80 に負けそうになった時には 1840 クロック版にします(笑))


16bitテーブル

2014.8.8 午前追記

Z80 に負けそうになったらテーブルを肥大化させる、と書いておいたら、早速その時がやってきました(笑)

いや、自分が作ったヘボプログラムを皆さんが改良してくれるので、非常に楽しいです。


紹介するのも投稿されたもので、単にテーブルを肥大化させただけでなく、さらに高速化されています。


	LDX #>DATA ; 2
	LDA #0 ; 2
	STA >0 ; 3
	CLC ; 2
	LDY DATA,X ; 4
	BMI END ; 3 / 2
LOOP:
	LDA SHIFT_HI,Y; 4
	STA >1 ; 3
	LDA SHIFT_LO,Y; 4
	ADC DATA+64,X; 4
	TAY ; 2
	LDA DATA+128,X; 4
	STA (0),Y ; 6
	INX ; 2
	LDY DATA,X ; 4
	BPL LOOP ; 3 / 2
END:


SHIFT_LO:
	DB 00, 20, 40, 60, 80, A0, C0, E0
	DB 00, 20, 40, 60, 80, A0, C0, E0
	DB 00, 20, 40, 60, 80, A0, C0, E0

SHIFT_HI:
	DB <VRAM  ,<VRAM  ,<VRAM  ,<VRAM  ,<VRAM  ,<VRAM  ,<VRAM  ,<VRAM  
	DB <VRAM+1,<VRAM+1,<VRAM+1,<VRAM+1,<VRAM+1,<VRAM+1,<VRAM+1,<VRAM+1
	DB <VRAM+2,<VRAM+2,<VRAM+2,<VRAM+2,<VRAM+2,<VRAM+2,<VRAM+2,<VRAM+2

ループの位置を2命令だけずらして、条件分岐を高速化しています。

このため、前処理にループの一部だった2命令が増加しています。(ループ内には、末尾にも同等の命令が入っています)


前処理 15クロック。キャラクタ1つの書き込みは 36クロック。

終了判定はループの最後に行われるようになり、終了時は 1クロック減少します。


15 + 36*48 - 1 = 1742


総計で 1742 クロックになっています。


次ページ: 小改良


前ページ 1 2 3 4 次ページ

(ページ作成 2014-08-07)
(最終更新 2014-08-10)
第2版 …他の版 初版

前記事:ブロック転送     戻る     次記事:パッド入力
トップページへ

-- share --

3000

-- follow --




- Reverse Link -