論理演算命令

ORA (OR Accumulator with memory)

アキュムレータとメモリの値で論理和を取ります。2つの値を比較してどちらか一方でも1が立っているビットを1に、両方が0のビットを0にします。
この命令で変更されうるフラグはネガティブフラグとゼロフラグとなります。

OC 文法 アドレッシングモード バイト数 サイクル
09 ORA #$??
ORA #$????
Immediate 2
3
2
3
 
0D ORA $???? Absolute 3 4  
0F ORA $?????? Absolute Long 4 5  
05 ORA $?? Direct Page 2 3 1
12 ORA ($??) Direct Page Indirect 2 5 1
07 ORA [$??] Direct Page Indirect Long 2 6 1
1D ORA $????,x Absolute Indexed, X 3 4 2
1F ORA $??????,x Absolute Long Indexed, X 4 5  
19 ORA $????,y Absolute Indexed, Y 3 4 2
15 ORA $??,x Direct Page Indexed, X 2 4 1
01 ORA ($??,x) Direct Page Indexed Indirect, X 2 6 1
11 ORA ($??),y Direct Page Indirect Indexed, Y 2 5 1,2
17 ORA [$??],y Direct Page Indirect Long Indexed, Y 2 6 1
03 ORA $??,S Stack Relative 2 4  
13 ORA ($??,S),Y Stack Relative Indirect Indexed, Y 2 7  


アキュムレータが16bit幅の場合、1サイクル追加
1:ダイレクトページレジスタの下位バイトが0で無い場合は1サイクル追加
2:インデックスの追加時にページ境界をまたぐ場合は1サイクル追加

コード例
 
ORA #$1234        A:$5678
アキュムレータの値(この場合0x5678)と定数0x1234の論理和を取ります。
    $5678=%0101011001111000
OR  $1234=%0001001000110100
    $567C=%0101011001111100


AND (AND Accumulator with memory)

アキュムレータとメモリの値で論理積を取ります。2つの値を比較してどちらか一方でも0が立っているビットを0に、両方が1のビットを1にします。
この命令で変更されうるフラグはネガティブフラグとゼロフラグとなります。

OC 文法 アドレッシングモード バイト数 サイクル
29 AND #$??
AND #$????
Immediate 2
3
2
3
 
2D AND $???? Absolute 3 4  
2F AND $?????? Absolute Long 4 5  
25 AND $?? Direct Page 2 3 1
32 AND ($??) Direct Page Indirect 2 5 1
27 AND [$??] Direct Page Indirect Long 2 6 1
3D AND $????,x Absolute Indexed, X 3 4 2
3F AND $??????,x Absolute Long Indexed, X 4 5  
39 AND $????,y Absolute Indexed, Y 3 4 2
35 AND $??,x Direct Page Indexed, X 2 4 1
21 AND ($??,x) Direct Page Indexed Indirect, X 2 6 1
31 AND ($??),y Direct Page Indirect Indexed, Y 2 5 1,2
37 AND [$??],y Direct Page Indirect Long Indexed, Y 2 6 1
23 AND $??,S Stack Relative 2 4  
33 AND ($??,S),Y Stack Relative Indirect Indexed, Y 2 7  


アキュムレータが16bit幅の場合、1サイクル追加
1:ダイレクトページレジスタの下位バイトが0で無い場合は1サイクル追加
2:インデックスの追加時にページ境界をまたぐ場合は1サイクル追加

コード例
 
AND #$1234        A:$5678
アキュムレータの値(この場合0x5678)と定数0x1234の論理積を取ります。
    $5678=%0101011001111000
AND $1234=%0001001000110100
    $1230=%0001001000110000

コラム:数フレームに1度実行する処理を作る


AND演算と条件分岐を組み合わせれば、数フレーム間隔で実行する命令を作ることが出来ます。
RAMには電源投入からの経過フレーム数を記録しているフレームカウンタが存在します。たとえばSDK2の場合は$2Aや$2Cがフレームカウンタです。
Aレジスタにフレームカウンタの内容を取得し、さらにAND演算を組み合わせて条件分岐を用いると、その分岐先は数フレームに1度実行される処理となります。
以下のコードは奇数フレーム時に処理A、偶数フレーム時に処理Bを行います。
LDA $2A
AND #$0001
BEQ B            ;Branch to B if Z=1
処理Aの内容
RTS

B:
処理Bの内容
RTS
このコードの原理は次のようになります。
・電源投入からの経過フレームを取得します。
・定数#$0001とANDします。このとき、経過フレームが偶数なら最下位ビットは0なので結果が0になります。奇数の場合は1です。
・偶数フレームの場合、AND演算によってゼロフラグが立ちます。BEQ命令により、ゼロフラグが立っていた場合にだけBに分岐します。
・奇数フレームの場合はBEQによる分岐は発生せず、直後にある処理Aだけが実行されます。

EOR (Exclusive OR Accumulator with memory)

アキュムレータとメモリの値で排他的論理和を取ります。2つの値を比較して片方に1が立っているビットを1に、両方が0または1のビットを0にします。
この命令で変更されうるフラグはネガティブフラグとゼロフラグとなります。

OC 文法 アドレッシングモード バイト数 サイクル
49 EOR #$??
EOR #$????
Immediate 2
3
2
3
 
4D EOR $???? Absolute 3 4  
4F EOR $?????? Absolute Long 4 5  
45 EOR $?? Direct Page 2 3 1
52 EOR ($??) Direct Page Indirect 2 5 1
47 EOR [$??] Direct Page Indirect Long 2 6 1
5D EOR $????,x Absolute Indexed, X 3 4 2
5F EOR $??????,x Absolute Long Indexed, X 4 5  
59 EOR $????,y Absolute Indexed, Y 3 4 2
55 EOR $??,x Direct Page Indexed, X 2 4 1
41 EOR ($??,x) Direct Page Indexed Indirect, X 2 6 1
51 EOR ($??),y Direct Page Indirect Indexed, Y 2 5 1,2
57 EOR [$??],y Direct Page Indirect Long Indexed, Y 2 6 1
43 EOR $??,S Stack Relative 2 4  
53 EOR ($??,S),Y Stack Relative Indirect Indexed, Y 2 7  


アキュムレータが16bit幅の場合、1サイクル追加
1:ダイレクトページレジスタの下位バイトが0で無い場合は1サイクル追加
2:インデックスの追加時にページ境界をまたぐ場合は1サイクル追加

コード例
 
EOR #$1234        A:$5678
アキュムレータの値(この場合0x5678)と定数0x1234の排他的論理和を取ります。
    $5678=%0101011001111000
XOR $1234=%0001001000110100
    $444C=%0100010001001100

コラム:NOT演算と符号反転


65816には否定演算(NOT)がありません。NOT演算をしたい場合は、8bitの場合は#$FFと、16bitの場合は#$FFFFとXORします。
EOR #$FFFF        A:$5678
アキュムレータ(この場合#$5678)の論理否定が返ります。
    $5678=%0101011001111000
XOR $FFFF=%1111111111111111
    $A987=%1010100110000111


次のコードはエラーとなります。命令"NOT"はありません。(サウンドCPUであるSPC700には実はNOT命令があります)
NOT A             A:$5678

符号反転したい場合はNOTした後に1を足します。正数でも負数でも同じです。
EOR #$FFFF        A:$5678=22136
INC A             A:$A987
***               A:$A988=-22136

BIT (Test Memory Bits against Accumulator)

基本的にANDと同じですが、ステータスフラグの変更だけを行い、アキュムレータの値は変化しません。

この命令で変更されうるフラグはネガティブフラグ・オーバーフローフラグ・ゼロフラグとなります。なお、Immediateのときのみゼロフラグ以外のフラグは変更されません。
この命令はANDした結果の上位2bitをN,Vフラグに返し、ANDした結果が0かどうかをZフラグに返します。

OC 文法 アドレッシングモード バイト数 サイクル
89 BIT #$??
BIT #$????
Immediate 2
3
2
3
 
2C BIT $???? Absolute 3 4  
24 BIT $?? Direct Page 2 3 1
3C BIT $????,x Absolute Indexed, X 3 4 2
34 BIT $??,x Direct Page Indexed, X 2 4 1


アキュムレータが16bit幅の場合、1サイクル追加
1:ダイレクトページレジスタの下位バイトが0で無い場合は1サイクル追加
2:インデックスの追加時にページ境界をまたぐ場合は1サイクル追加

TRB (Test and Reset Memory Bits)

アキュムレータのビット反転値とメモリの値で論理積を取り、メモリに書き戻します。
アキュムレータにメモリと同じビットが立っている場合、それをクリアして不一致ビットと値が0のビットは変更しません。
この命令で変更されうるフラグはゼロフラグです。

OC 文法 アドレッシングモード バイト数 サイクル
1C TRB $???? Absolute 3 6  
14 TRB $?? Direct Page 2 5 1


インデックスレジスタが16bit幅の場合、1サイクル追加
1:ダイレクトページレジスタの下位バイトが0で無い場合は1サイクル追加

TSB (Test and Set Memory Bits)

アキュムレータとメモリの値で論理和を取り、メモリに書き戻します。アキュムレータとメモリともに0のビット以外を立てます。
この命令で変更されうるフラグはゼロフラグです。

OC 文法 アドレッシングモード バイト数 サイクル
0C TSB $???? Absolute 3 6  
04 TSB $?? Direct Page 2 5 1


インデックスレジスタが16bit幅の場合、1サイクル追加
1:ダイレクトページレジスタの下位バイトが0で無い場合は1サイクル追加