こんにちは、めのんです!
前回のビット単位のAND演算に続いて、今回はビット単位のOR演算を実装します。
OR命令の実装
まずはOR命令からです。
ビット単位のORについてはとくに説明は必要ないと思います。
それではいつものように「AVR®命令一式手引書」から命令の説明を引用します。
ほとんどOR命令といっしょですね。
コードを見ていきますね。
static void or(atmega328_t *cpu, uint16_t op)
{
int d = (op >> 4) & 0x1f;
int r = (op & 0xf) | (op >> 5) & 0x10;
int value = cpu->r[d] | cpu->r[r];
cpu->r[d] = value;
int sr = cpu->sr & ~(flag_S | flag_V | flag_N | flag_Z);
if (value & 0x80)
sr |= flag_N | flag_S;
if (value == 0)
sr |= flag_Z;
cpu->sr = sr;
++cpu->clock;
}
こちらもand関数とほとんど同じです。
andと同じように、「or」も<iso646.h>で定義されるマクロと同名です。
<iso646.h>をインクルードしていると使えません。
ORI命令の実装
次はORI命令を実装します。
こちらも「AVR®命令一式手引書」から命令の説明を引用します。
ほとんどANDI命令といっしょですね。
では、コードを見ていきます。
static void ori(atmega328_t *cpu, uint16_t op)
{
int d = 16 + ((op >> 4) & 0xf);
int K = (op & 0xf) | (op >> 4) & 0xf0;
int value = cpu->r[d] | K;
cpu->r[d] = value;
int sr = cpu->sr & ~(flag_S | flag_V | flag_N | flag_Z);
if (value & 0x80)
sr |= flag_N | flag_S;
if (value == 0)
sr |= flag_Z;
cpu->sr = sr;
++cpu->clock;
}
とくに説明は必要ないでしょう。
op_tableへの登録
次に、いつものようにop_tableに登録します。
opcode.phpに次のコードを追加して実行してあげればOKです。
for ($i = 0; $i < 1024; ++$i)
{
$opcode_table[0b0010_1000_0000_0000 | $i] = 'or';
}
for ($i = 0; $i < 4096; ++$i)
{
$opcode_table[0b0110_0000_0000_0000 | $i] = 'ori';
}
前回同様、今回も65,536命令のうち 1,024 + 4,096 = 5,120 個が埋まりました。
それでは次回またお会いしましょう!