アドレッシングモード
65C816プロセッサで利用可能なアドレッシングモードについて説明します。

アドレッシングモードの概要
命令の実行には、通常、操作する対象が何であるのか、また、操作する対象がメモリ上のどこに存在しているのかといった情報が必要になります。
また、用途によって、同一のメモリに対して複数のアクセス方法があるほうがコーディングのロスを抑え、柔軟なプログラミングを可能にできます。
命令の実行に必要なデータの種類、およびそのデータへのアクセス方法を規定したものをアドレッシングモードと言います。また、前述の目的を達成するため、65C816には多数のアドレッシングモードが用意されています。

暗黙 (Implied)
とくにアドレッシングモードを指定する必要のない命令に対して使用されます。オペランドは取りません。
主としてスタック退避命令やレジスタ操作命令が対象となります。このドキュメントでは Imp. と略します。

アキュムレータ (Accumulator)
オペランドとしてアキュムレータを指定します。ソースコード上では A をオペランドに指定します。
このドキュメントでは Acc. と略します。

例: LSR A ;アキュムレータを1ビット左シフト

即値 (Immediate)
オペランドとして定数リテラルを指定します。アドレスと区別するためにソースコード上では # プレフィックスを付けます。
このドキュメントでは Imm. と略します。

例: LDA #$1234 ;定数0x1234をアキュムレータにロード

ダイレクトページ (Direct Page)
オペランドとしてダイレクトページ内のアドレスを指定します。実際にアクセスされる番地は、オペランドに指定した8ビット値にダイレクトページレジスタの値を足したアドレスとなります。バンクは0固定です。
このドキュメントでは DP と略します。

例: LDX $64 ;D+0x64にある8ないし16ビット値をインデクスレジスタXにロード

ダイレクトページインデクス (Direct Page Indexed, X)
オペランドとしてダイレクトページ内の基底アドレス、およびXレジスタを指定します。
このドキュメントでは DP Idx と略します。

例: LDA $12, X ;D+0x12+Xにある8ないし16ビット値をアキュムレータにロード

ダイレクトページ間接 (Direct Page Indirect)
オペランドとしてダイレクトページ内のポインタアドレスを指定します。
実際にアクセスされるデータはオペランドとして指定されたアドレスにある16ビットアドレスから取得されます。バンクバイトはデータバンクレジスタの値が使用されます。
このドキュメントでは DP Ind と略します。

例: LDA ($64) ;D+0x64から16ビットのアドレスを取得し、バンクバイトをDBとしたアドレスから8ないし16ビット値をアキュムレータにロード

ダイレクトページ間接ロング (Direct Page Indirect Long)
オペランドとしてダイレクトページ内のポインタアドレスを指定します。
基本的な考え方はダイレクトページ間接と同じですが、こちらは24ビットのアドレスをダイレクトページから取得します。
このアドレッシングモードを使用する命令は、命令の実行中はデータバンクレジスタを一時的に変更しますが、命令の完了後は元の値に戻されます。
このドキュメントでは DP Ind long と略します。

例: STA [$32] ;D+0x32から24ビットのアドレスを取得し、そのアドレスにアキュムレータの値をストア

ダイレクトページインデクス間接 (Direct Page Indexed Indirect, X)
オペランドとしてダイレクトページ内のポインタアドレスとXレジスタを指定します。
ダイレクトページ内のアドレス指定がインデクス付きになる以外はダイレクトページ間接モードと同じ働きをします。
このドキュメントでは DP Idx Ind X  と略します。

例: STA ($12, X) ;D+0x12+Xから16ビットのアドレスを取得し、バンクバイトをDBとしたアドレスにアキュムレータの値をストア

ダイレクトページ間接インデクス (Direct Page Indirect Indexed, Y)
オペランドとしてダイレクトページ内のポインタアドレスとYレジスタを指定します。
このアドレッシングモードでは、まずダイレクトページ間接によってアドレスを取得します。
次に、取得したアドレスにインデクスとしてYの値を加算したアドレスにアクセスします。
このドキュメントでは DP Ind Idx Y  と略します。

例: STA ($12), Y ;D+0x12から16ビットのアドレスを取得し、バンクバイトをDBとしたアドレスにYインデクスを加算したアドレスにアキュムレータの値をストア

ダイレクトページ間接ロングインデクス (Direct Page Indirect Long Indexed, Y)
オペランドとしてダイレクトページ内のポインタアドレスとYレジスタを指定します。
このアドレッシングモードでは、まずダイレクトページ間接ロングによって24ビットのアドレスを取得します。
次に、取得したアドレスにインデクスとしてYの値を加算したアドレスにアクセスします。
このドキュメントでは DP Ind long Idx Y  と略します。

例: STA [$12], Y ;D+0x12から24ビットのアドレスを取得し、Yインデクスを加算したアドレスにアキュムレータの値をストア

絶対アドレス (Absolute)
オペランドとしてバンク内の絶対アドレスを指定します。バンクバイトはデータバンクレジスタの値が使用されます。

例: LDX $1234 ;DBバンク内のアドレス0x1234から8ないし16ビットをXレジスタにロード

絶対インデクス (Absolute Indexed (X/Y))
オペランドとしてバンク内の絶対アドレスとインデクスレジスタを指定します。バンクバイトはデータバンクレジスタの値が使用されます。

例: LDX $1234, Y ;DBバンク内のアドレス0x1234にYインデクスを加算したアドレスから8ないし16ビットをXレジスタにロード

絶対アドレス間接 (Absolute Indirect)
オペランドとして現在のプログラムバンク内のポインタアドレスを指定します。
実際にアクセスされるデータは、指定されたアドレスにある16ビット値をアドレス、バンクバイトをPBとしたアドレスです。
このアドレッシングモードはデータアクセス用ではなく、プログラムの実行位置を変えるためのものです。

例: JMP ($1234) ;PBのの0x1234から16ビットアドレスを取得し、バンクをPBとしたアドレスにジャンプ

絶対インデクス間接 (Absolute Indexed Indirect, X)
オペランドとして現在のプログラムバンク内のポインタアドレスおよびXレジスタを指定します。
実際にアクセスされるデータは、指定されたアドレスにXインデクスを追加したアドレスにある16ビット値をアドレス、バンクバイトをPBとしたアドレスです。
このアドレッシングモードはデータアクセス用ではなく、プログラムの実行位置を変えるためのものです。

例: JMP ($1234,X) ;PBの0x1234+Xから16ビットアドレスを取得し、バンクをPBとしたアドレスにジャンプ

絶対アドレス間接ロング (Absolute Indirect long)
オペランドとして現在のプログラムバンク内のポインタアドレスを指定します。
実際にアクセスされるデータは、指定されたアドレスにある24ビット値をアドレスとしたアドレスです。
このアドレッシングモードはデータアクセス用ではなく、プログラムの実行位置を変えるためのものです。

例: JMP [$1234] ;PBの0x1234から取得した24ビットアドレスにジャンプ

絶対ロングアドレス (Absolute long)
オペランドとして24ビットのアドレスを指定します。

例: LDA $123456 ;0x123456から8ないし16ビットの値を取得。

絶対ロングインデクス (Absolute long Indexed, X)
オペランドとして24ビットのアドレスとXレジスタを指定します。

例: LDA $123456, X ;0x123456+Xから8ないし16ビットの値を取得。

スタック相対 (Stack Relative)
オペランドとしてスタックポインタと8ビットのオフセットを指定します。
実際にアクセスするデータは、スタックポインタにオフセットを加算したアドレスにあります。なお、スタックのバンクは0とされます。
スタックポインタは、常にスタック上での次の空き領域を示しています。したがって、オフセットとして1を指定した場合はスタックに最後にプッシュされた値、0を指定した場合は最後にポップされた値を示します。
割込み発生時はスタックの状態が変更されるため注意が必要です。

例: LDA $01, S ;スタックに最後にプッシュされた値をAレジスタに取得 (スタックの状態は変更しない)

スタック相対間接インデクス (Stack Relative Indirect Indexed, Y)
オペランドとしてスタックポインタと8ビットのオフセット、およびYレジスタを指定します。
このアドレッシングモードは2段階でデータにアクセスします。
まず、スタック相対によって16ビットの値を取得します。次に、この16ビットにYインデクスを追加し、バンクバイトをDBとしたアドレスにアクセスします。
このアドレッシングモードは、データベースのベースアドレスを意識することなく、データベースの各要素へのアクセスを可能にするためのものです。

プログラムカウンタ相対 (Program Counter Relative)
オペランドとして8ビットのオフセットを指定します。
現在のプログラムカウンタの値にこのオフセットを加算した位置へプログラムの実行位置を変更します。
プログラムカウンタは、常に次の実行アドレスが格納されていることに注意が必要です。

例: BNE $12 ;ゼロフラグがクリアされている場合に0x12バイト先へ分岐

プログラムカウンタ相対ロング (Program Counter Relative Long)
オペランドとして16ビットのオフセットを指定します。
現在のプログラムカウンタの値にこのオフセットを加算した位置へプログラムの実行位置を変更します。
プログラムカウンタは、常に次の実行アドレスが格納されていることに注意が必要です。

例: BRL $FFF0 ;常に16バイト前へ分岐

ブロック移動 (Block Move)
オペランドとして転送元のバンクおよび転送先のバンクを指定します。
このアドレッシングモードはMVP命令およびMVN命令で使用されるものです。

例: MVN $12, $34 ;バンク0x12のデータをバンク0x34に移動