diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 3de94d69c..434abca28 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -482,7 +482,7 @@ template void Proces break; /* - Status word moves. + Status word moves and manipulations. */ case Operation::MOVEtoSR: @@ -497,6 +497,35 @@ template void Proces set_ccr(active_program_->source->full); break; +#define and_op(a, b) a &= b +#define or_op(a, b) a |= b +#define eor_op(a, b) a ^= b + +#define apply(op, func) {\ + auto status = get_status(); \ + op(status, prefetch_queue_.halves.high.full); \ + func(status); \ + program_counter_.full -= 2; \ +} + +#define apply_sr(op) apply(op, set_status) +#define apply_ccr(op) apply(op, set_ccr) + + case Operation::ANDItoSR: apply_sr(and_op); break; + case Operation::EORItoSR: apply_sr(eor_op); break; + case Operation::ORItoSR: apply_sr(or_op); break; + + case Operation::ANDItoCCR: apply_ccr(and_op); break; + case Operation::EORItoCCR: apply_ccr(eor_op); break; + case Operation::ORItoCCR: apply_ccr(or_op); break; + +#undef apply_ccr +#undef apply_sr +#undef apply +#undef eor_op +#undef or_op +#undef and_op + /* Multiplications. */ diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp index 73f2f7d2f..7937de7c9 100644 --- a/Processors/68000/Implementation/68000Storage.cpp +++ b/Processors/68000/Implementation/68000Storage.cpp @@ -416,6 +416,8 @@ struct ProcessorStorageConstructor { EXG, // Maps source and destination registers and an operation mode to an EXG. SWAP, // Maps a source register to a SWAP. + + EORI_ORI_ANDI_SR, // Maps to an EORI, ORI or ANDI to SR/CCR. }; using Operation = ProcessorStorage::Operation; @@ -616,6 +618,13 @@ struct ProcessorStorageConstructor { {0xf1f8, 0xc188, Operation::EXG, Decoder::EXG}, // 4-105 (p209) {0xfff8, 0x4840, Operation::SWAP, Decoder::SWAP}, // 4-185 (p289) + + {0xffff, 0x027c, Operation::ANDItoSR, Decoder::EORI_ORI_ANDI_SR}, + {0xffff, 0x023c, Operation::ANDItoCCR, Decoder::EORI_ORI_ANDI_SR}, + {0xffff, 0x0a7c, Operation::EORItoSR, Decoder::EORI_ORI_ANDI_SR}, + {0xffff, 0x0a3c, Operation::EORItoCCR, Decoder::EORI_ORI_ANDI_SR}, + {0xffff, 0x007c, Operation::ORItoSR, Decoder::EORI_ORI_ANDI_SR}, + {0xffff, 0x003c, Operation::ORItoCCR, Decoder::EORI_ORI_ANDI_SR}, }; std::vector micro_op_pointers(65536, std::numeric_limits::max()); @@ -661,6 +670,13 @@ struct ProcessorStorageConstructor { #define inc(n) increment_action(is_long_word_access, is_byte_access, n) switch(mapping.decoder) { + case Decoder::EORI_ORI_ANDI_SR: { + // The source used here is always the high word of the prefetch queue. + storage_.instructions[instruction].requires_supervisor = !(instruction & 0x40); + op(Action::None, seq("np nn nn")); + op(Action::PerformOperation, seq("np np")); + } break; + case Decoder::SWAP: { storage_.instructions[instruction].set_destination(storage_, Dn, ea_register); op(Action::PerformOperation, seq("np")); diff --git a/Processors/68000/Implementation/68000Storage.hpp b/Processors/68000/Implementation/68000Storage.hpp index b0ed03061..fd24480ad 100644 --- a/Processors/68000/Implementation/68000Storage.hpp +++ b/Processors/68000/Implementation/68000Storage.hpp @@ -62,6 +62,10 @@ class ProcessorStorage { MOVEtoSR, MOVEfromSR, MOVEtoCCR, + ORItoSR, ORItoCCR, + ANDItoSR, ANDItoCCR, + EORItoSR, EORItoCCR, + BTSTb, BTSTl, BCLRl, BCLRb, CMPb, CMPw, CMPl,