テーブルが実際に複数の 8 バイト レコードである場合、効率的にインデックスを作成できる 8 つの 1 バイト レコード テーブルとして格納します。
つまり、構造体の配列ではなく、配列の構造体
これには、レジスタ オフセットだけで 256 レコードのインデックスを作成できるという利点があり、アドレス計算を変更せずに異なるサイズのレコードを使用することもできます (したがって、5 バイトのレコードが必要な場合は、計算を変更するのではなく、使用する配列を減らすだけです)。 )。
LDA ELEMENT1,Y ; This is an array of the first bytes of our record
STA $1000
LDA ELEMENT2,Y ; This is the second bytes...
STA $1001
...etc...
INY ; Just need to inc Y to access next record
INX
/は 2 サイクルの命令であるためINY
、インデックスの更新に勝るものはありません。
データの再フォーマットを意味しますが、これは高速で簡単なので、私の主な推奨事項です。
これがオプションでない場合は、データをそのように動的に再フォーマットすることができます(コストに見合うだけの十分なアクセスがあり、そのためのスペースがあると仮定します)。実際にデータにアクセスする方法やパフォーマンスの重要性に応じて、さまざまな手法を使用できます。
インクリメントするだけでなく、任意の量をインデックスに追加する必要がある場合は、単純な方法で次のようにします。
TYA (2)
CLC (2)
ADC #amt (2)
TAY (2)
ただし、その単純なバージョンには 8 サイクルかかります。クリアキャリーを省略した場合、6 サイクルで実行できます。これは、既にクリアされていることがわかっている場合に実行できます (たとえば、ループ内にあることがキャリーが実行されていないことを意味する他のループ計算に従う場合)。生成されています)。そのため、フラグを設定しないようにコードを調整する価値があります。4 ずつインクリメントするよりも小さいことは、複数回インクリメントするだけで実行できます。
キャリーがクリアされることを保証できないが、ルックアップ テーブル用にメモリ内のページを確保できる場合は、そのページのバイトに 0 -> 255 を格納して、次のようにします。
LDA table + amt, Y (4)
TAY (2)
それによってキャリーフラグは設定されませんが、ゼロフラグは設定されるため、テーブルがゼロにラップアラウンドする場合は、それを確認できます。
アドレスをインデックス化する必要がある場合は、次のようにすることができます。
LDA (zeropagevector), Y
の上位バイトをインクリメントしますzeropagevector
。ただし、読み取りには 5 サイクルかかります。単一の命令でレコードから読み取るだけの場合は、通常の絶対アドレス指定を使用して、命令自体のアドレスを変更し、サイクルを節約できます。
基本的に、6502 でこの種のものを最適化する方法はたくさんありますが、実際には、データが何であり、どのようにアクセスしたいかによって異なります。