LDA 命令 (Load Accumulator from Memory)
アキュムレータに対し8ビットないし16ビットの値をロードします。
LDAオーバーロード
| オペコード | 構文 | アドレッシングモード | バイト数 | 命令サイクル | 注 |
|---|---|---|---|---|---|
| A9 | LDA #const | Imm. | 2/ 3 | 2 | 1, 4 |
| A5 | LDA dp | DP. | 2 | 3 | 1, 2 |
| B2 | LDA (dp) | DP. Ind | 2 | 5 | 1, 2 |
| A7 | LDA [dp] | DP. Ind long | 2 | 6 | 1, 2 |
| B5 | LDA dp, X | DP. Idx X | 2 | 4 | 1, 2 |
| A1 | LDA (dp, X) | DP. Idx Ind X | 2 | 6 | 1, 2 |
| B1 | LDA (dp), Y | DP. Ind Idx Y | 2 | 5 | 1, 2, 3 |
| B7 | LDA [dp], Y | DP. Ind long Idx Y | 2 | 6 | 1, 2 |
| AD | LDA abs | Abs. | 3 | 4 | 1 |
| BD | LDA abs, X | Abs. Idx X | 3 | 4 | 1, 3 |
| B9 | LDA abs, Y | Abs. Idx Y | 3 | 4 | 1, 3 |
| AF | LDA long | Abs. long | 4 | 5 | 1 |
| BF | LDA long, X | Abs. long Idx X | 4 | 5 | 1 |
| A3 | LDA sp, S | SR. | 2 | 4 | 1 |
| B3 | LDA (sp, S), Y | SR. Ind Idx Y | 2 | 7 | 1 |
注
- メモリモードフラグクリア時は1サイクル追加
- ダイレクトページの開始アドレスがページ境界になっていない場合1サイクル追加
- インデクス加算時にページ境界を超える場合、またはインデクスレジスタが16ビット長の場合は1サイクル追加
- メモリモードフラグクリア時は3バイト。メモリモードフラグセット時は2バイト。
フラグ変化
n-----z-
n: 読み込んだ値のMSBが格納される。
z: 読み込んだ値が0の場合にセットされ、それ以外の場合はクリアされる。
解説
LDA命令はオペコードによって指定されたアドレッシングモードに従ってアキュムレータに値をロードします。
ステータスレジスタのメモリモードフラグがクリアされている場合は16ビット長のデータをロードし、メモリモードフラグがセットされている場合は8ビット長のデータをロードします。
データの読み込みはリトル・エンディアン方式で行われます。すなわち、バイナリコードでは常に下位バイトが先に配置されます。
使用例
8ビットと16ビットの読み込み
SEP #$20
LDA $10 ; $10の1バイトを読み込む
REP #$20
LDA $10 ; $10を下位、$11を上位として2バイトを読み込む
テーブルからの読み込み
インデクスレジスタを使うと、表の中のn番目の値を読み込めます。テーブルが別のバンクにある場合は、ロングアドレスを使います。
; Xの値の2乗を読み込む(Aは8ビット、Xは16ビット)
SEP #$20
REP #$10
LDX $10
LDA.l Squares,X
...
Squares:
db $00,$01,$04,$09,$10,$19,$24,$31
16ビットの値のテーブルを引く場合は、インデクスを2倍してから使います。
同じ番地へのいろいろなアクセス
65C816では、同じ番地を何通りものアドレッシングモードで読むことができます。次はすべて、WRAMの$7E:0010を読む例です。どれを使えるかは、そのときのダイレクトページレジスタ(D)・データバンクレジスタ(DB)・インデクスレジスタの値によって決まります。
LDA $10 ; ダイレクトページ: D=$0000 のとき $00:0010
; (バンク$00の$0000~$1FFFはWRAM $7E:0000~$1FFF の写し)
LDA $0010 ; 絶対: DB=$00・$80・$7E のいずれでも $7E:0010 の内容が読める
LDA.l $7E0010 ; ロング: DB に関係なく $7E:0010
LDA $00,X ; ダイレクトページ + X: D=$0000、X=$0010 のとき
LDA.l $7E0000,X ; ロング + X: X=$0010 のとき
LDA ($20) ; 間接: D+$20 にある16ビット値 $0010 をアドレスとし、バンクは DB
LDA [$20] ; ロング間接: D+$20 にある24ビット値 $7E0010 をアドレスとする
バイト数とサイクル数はアドレッシングモードごとに異なります。ダイレクトページは2バイトで最も速く、ロングは4バイトで遅くなります。よく使う変数をダイレクトページに置くのはこのためです。
インデクスとバンクの境界
ネイティブモードでは、アドレッシングモードによって、インデクスを足したアドレスがバンクの境界を越えるかどうかが異なります。思わぬ番地を読み書きする原因になりやすいので注意してください。
| アドレッシングモード | 実際のアドレス | バンク内のアドレスが$FFFFを越えた場合 |
|---|---|---|
| dp、dp,X、dp,Y | D + dp (+ インデクス) | バンク$00の中で$0000に戻る |
| abs,X、abs,Y | DB:abs + インデクス | 次のバンクへ繰り上がる |
| long,X | long + X | 次のバンクへ繰り上がる |
| (dp),Y | DB:(ポインタ) + Y | 次のバンクへ繰り上がる |
| [dp],Y | (24ビットポインタ) + Y | 次のバンクへ繰り上がる |
; DB=$7E、X=$0020 のとき
LDA $FFF0,X ; $7E:FFF0 + $20 = $7F:0010 を読む(バンクが繰り上がる)
; D=$0000、X=$0020 のとき
LDA $F0,X ; $00:0110 を読む
; ネイティブモードでは、ダイレクトページ + インデクスは256バイトの範囲に収まらない
; Aが16ビット、DB=$7E のとき
LDA $FFFF ; 下位バイトは $7E:FFFF、上位バイトは $7F:0000 から読む
一方、プログラムカウンタはバンクの境界を越えません。$xx:FFFFの次の命令は、同じバンクの$xx:0000から読まれます。