ランダムアクセス
今回記事の元になった日記では、前半で個別命令が 6502 の方が概して高速であることを紹介し、後半で 16bit 演算などは Z80 の方が得意であることを示そうとしました。
その流れで、Z80 に有利な例題を3つほど続けたのですが、その結果 6502 の方が遅いように見えるのも心外です。
ちょっと、6502 の方が有利そうな例題も作ってみたいと思います。
目次
Z80 vs 6502 トップページ(別ページ)
概要
VRAM (画面表示用メモリ)を想定したメモリに対し、別に渡される座標・キャラクタデータを書き込むプログラムを作りたいと思います。
実際には、ファミコンも MSX も、VRAM には自由にアクセスはできません。しかし、ここは例題なので通常のメモリアクセスを考えます。
(なんだったら、表示期間中に裏画面を作っていると考えてください)
VRAM は、VRAM 、とラベルのつけられたアドレスから始まるとします。連続したメモリは、左上から横方向に並んでいて、右端の次は1段下の左端に戻ります。
1段は横方向に 32バイト、縦方向には 24段あることにします。
(MSX の VRAM 構造です。ファミコンなら 30段あるのだけど、小さいほうがプログラムが作りやすいので MSX 基準にします。VRAM は、256バイト単位の切りの良いアドレスから始まるものとします。)
座標やキャラクタのデータは、DATA ラベルから入っていることにします。
横座標 0~31、縦座標 0~23、キャラクタ 0~255 の3つからなりますが、データ構造は自由です。描画終了時に破壊されていても構いません。
縦座標・または横座標の最上位ビットが立っていたら、描画はそこで終了するものとします。
最大 63 個分のデータが入っていることを想定します。
(終了符号をあわせて 64個分。扱いやすいようにダミーデータを含めて4バイト一組にしたとしても、256バイトに収まる。6502 では1ページ内に収まると考えてよい。)
プログラムでは、48個のデータを書き込む時間を計算します。
この時、順序はランダムですが、縦方向には 0~23 が2個づつ含まれるものとします。
(6502 では、縦座標により「ページ境界」を超えてしまい、実行時間に影響を与える可能性があるため)
Z80 基本
DATA は、 縦・横・キャラの繰り返しで入っているものとします。
LD HL,DATA ; 10 (11)
LD B,VRAM/256 ; 7 (8)
LOOP:
; まずは縦座標を計算。 5bit シフト
LD A,(HL) ; 7 (8)
RLA ; 4 (5)
JR C,END ; 12 / 7 (13 / 8)
INC HL ; 6 (7)
EX DE,HL ; 4 (5)
RLA ; 4 (5)
RLA ; 4 (5)
LD L,A ; 4 (5)
LD H,0 ; 7 (8)
ADD HL,HL ; 11 (12)
ADD HL,HL ; 11 (12)
EX DE,HL ; 4 (5)
; 横座標と、VRAMアドレスを足す
LD C,(HL) ; 7 (8)
INC HL ; 6 (7)
EX DE,HL ; 4 (5)
ADD HL,BC ; 11 (12)
EX DE,HL ; 4 (5)
; キャラを書き込む
LD A,(HL) ; 7 (8)
INC HL ; 6 (7)
EX DE,HL ; 4 (5)
LD (HL),A ; 7 (8)
EX DE,HL ; 4 (5)
JMP LOOP ; 10 (11)
END:
VRAM アドレスの計算は、VRAM + 縦座標*32 + 横座標 という単純なものです。
でも、縦座標は 5bit の値で、これを 5bit シフト(*32に相当)すると 8bit からはみ出してしまう。
だから、A レジスタで 3bit だけシフトしてから HL にいれ、HL 同士で2回足し算をしています。
VRAM は 256 バイトごとの区切りの良いアドレスから始まる(つまり、下位 8bit は 00 )という規定なので、VRAM アドレスの上位 8bit を B に入れっぱなしにしてあります。
C に横方向の座標を入れて、HL と BC で足し算をすると、HL にアクセスすべき VRAM アドレスが出来上がります。
ここまでできれば、書き込むべきキャラクタ番号を書き込むだけ。
実際には、VRAM アドレスの計算と、元となるデータ取得用のポインタの両方に HL を使いたいため、EX DE,HL を多用しています。
1キャラクタの書き込みに、166クロック。これを 48回繰り返します。
前処理は 19クロックで、終了時には条件分岐で 26 クロック必要です。
166*48 + 19 + 26 = 8254
総計 8248 クロックです。