executeInstruction 関数の処理
Visual Studio で補完されたプログラムと ChatGPT で作ってもらったプログラムを元に改造しました。まだ動くようにはなっていません。
executeInstruction 関数の move 系命令の処理は以下のようになります。『X68000ベスト・プログラミング入門』に 68000 の命令セットが載っているのでこれを参考にしています。
move, movea, moveq
「move src, dst」は src の値を取得して dst に設定します。moveq も同様です。movea は動作が異なるようですが、説明がよくわからないので今のところ同じ動作になっています。
フラグは N と Z は値によって変化し、V と C は 0、X は不明です。
if (instruction.is_move_instruction()) { // MOVE命令の処理 if (operands.size() != 2) { cerr << "Invalid MOVE instruction: " << line << endl; return; } int32_t value = operands[0].get_value(instruction.data_size()); operands[1].set_value(value, instruction.data_size()); if (instruction.modifies_flags()) { cpu.set_value_status(value, instruction.data_size()); } }
movem
「move src, dst」は
それ以外の場合もあるようですが詳細は不明です(対応していません)。
フラグは変化しません。
レジスタリストの指定は
- 「%dk-%dl/%am-%an」のようなパターンか、
- 「#数値」(即値)で表されるビットマスク
となります。詳細は不明です。ここでは
- プッシュのときは a7, ... , a0, d7, ... , d0 の順
- ポップのときは d0, ... , d7, a0, ... , a7 の順
とします。ビットマスクは
- プッシュのときは上位から a7, ... , a0, d7, ... , d0 の順
- ポップのときは上位から d0, ... , d7, a0, ... , a7 の順
とします。
else if (instruction.is_movem_instruction()) { // MOVEM命令の処理 if (operands.size() != 2) { cerr << "Invalid MOVEM instruction: " << line << endl; return; } Operand& src = operands[0]; Operand& dst = operands[1]; vector<string> regs = src.get_src_reglist(); if(regs.size() >= 2) { // src がレジスタリストの場合 for (auto it = regs.rbegin(); it != regs.rend(); ++it) { dst.set_value(cpu.getRegisterValue(*it), instruction.data_size()); } } else { // dst がレジスタリストの場合 vector<string> regs = dst.get_dst_reglist(); for (const string& reg : regs) { int32_t value = src.get_value(instruction.data_size()); cpu.setRegisterValue(reg, value); } } }


