版を指定して表示しています。
理由が無い限り、最新版の閲覧をお願いします。

ランダムアクセス

目次

概要

Z80 基本

6502基本

速度判定


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 クロック版にします(笑))


速度判定

6502 は 2128 クロック。周波数を考慮して倍にすると、MSX での 4256 クロック相当の実時間になります。


Z80 は 8248 クロックなので、ファミコンの倍も遅いです。


…まだ試作した程度なので、僕の作り方も悪いかもしれない。

でも、こういうメモリアクセスの多いプログラムは、Z80 の苦手なところなんです。


そして、ゲームを作るならメモリアクセスは避けられない。

いくら Z80 がレジスタをたくさん持っていると言っても、動き回る多数の敵キャラクターを全て記憶できるほどではないのだから。



前ページ 1 2

(ページ作成 2014-08-07)
第1版 …他の版 最新版

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

-- share --

3000

-- follow --




- Reverse Link -