diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index bf4df3819..38289f6f7 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -6,24 +6,32 @@ // Copyright © 2019 Thomas Harte. All rights reserved. // -#define get_status() \ +#define get_ccr() \ ( \ (carry_flag_ ? 0x0001 : 0x0000) | \ (overflow_flag_ ? 0x0002 : 0x0000) | \ (zero_result_ ? 0x0000 : 0x0004) | \ (negative_flag_ ? 0x0008 : 0x0000) | \ - (extend_flag_ ? 0x0010 : 0x0000) | \ + (extend_flag_ ? 0x0010 : 0x0000) \ + ) + +#define get_status() \ + ( \ + get_ccr() | \ (interrupt_level_ << 8) | \ (trace_flag_ ? 0x8000 : 0x0000) | \ (is_supervisor_ << 13) \ ) -#define set_status(x) \ +#define set_ccr(x) \ carry_flag_ = (x) & 0x0001; \ overflow_flag_ = (x) & 0x0002; \ zero_result_ = ((x) & 0x0004) ^ 0x0004; \ negative_flag_ = (x) & 0x0008; \ - extend_flag_ = (x) & 0x0010; \ + extend_flag_ = (x) & 0x0010; + +#define set_status(x) \ + set_ccr(x) \ interrupt_level_ = ((x) >> 8) & 7; \ trace_flag_ = (x) & 0x8000; \ set_is_supervisor(!!(((x) >> 13) & 1)); @@ -58,9 +66,6 @@ template void Processor: active_micro_op_ = active_program_->micro_operations; } -#define sub_overflow() (source ^ destination) & (destination ^ result) -#define add_overflow() ~(source ^ destination) & (destination ^ result) - switch(active_micro_op_->action) { default: std::cerr << "Unhandled 68000 micro op action " << std::hex << active_micro_op_->action << std::endl; @@ -69,6 +74,8 @@ template void Processor: case int(MicroOp::Action::None): break; case int(MicroOp::Action::PerformOperation): +#define sub_overflow() (source ^ destination) & (destination ^ result) +#define add_overflow() ~(source ^ destination) & (destination ^ result) switch(active_program_->operation) { /* ABCD adds the lowest bytes form the source and destination using BCD arithmetic, @@ -332,6 +339,10 @@ template void Processor: active_program_->source->halves.low.full = get_status(); break; + case Operation::MOVEtoCCR: + set_ccr(active_program_->source->full); + break; + /* NEGs: negatives the destination, setting the zero, negative, overflow and carry flags appropriate, and extend. @@ -403,9 +414,9 @@ template void Processor: const int source = 0; const int destination = active_program_->destination->full; int64_t result = source - destination - (extend_flag_ ? 1 : 0); - active_program_->destination->full = result; + active_program_->destination->full = uint32_t(result); - zero_result_ = result; + zero_result_ = uint_fast32_t(result); extend_flag_ = carry_flag_ = result >> 32; negative_flag_ = result & 0x80000000; overflow_flag_ = sub_overflow() & 0x80000000; @@ -456,7 +467,7 @@ template void Processor: zero_result_ |= result & 0xff; extend_flag_ = carry_flag_ = result & ~0xff; negative_flag_ = result & 0x80; - overflow_flag_ = (source ^ destination) & (destination ^ result) & 0x80; + overflow_flag_ = sub_overflow() & 0x80; // Store the result. active_program_->destination->halves.low.halves.low = uint8_t(result); @@ -470,7 +481,7 @@ template void Processor: zero_result_ = active_program_->destination->halves.low.halves.low = uint8_t(result); extend_flag_ = carry_flag_ = result & ~0xff; negative_flag_ = result & 0x80; - overflow_flag_ = (source ^ destination) & (destination ^ result) & 0x80; + overflow_flag_ = sub_overflow() & 0x80; } break; case Operation::SUBw: { @@ -481,7 +492,7 @@ template void Processor: zero_result_ = active_program_->destination->halves.low.full = uint16_t(result); extend_flag_ = carry_flag_ = result & ~0xffff; negative_flag_ = result & 0x8000; - overflow_flag_ = (source ^ destination) & (destination ^ result) & 0x8000; + overflow_flag_ = sub_overflow() & 0x8000; } break; case Operation::SUBl: { @@ -492,7 +503,7 @@ template void Processor: zero_result_ = active_program_->destination->halves.low.full = uint32_t(result); extend_flag_ = carry_flag_ = result >> 32; negative_flag_ = result & 0x80000000; - overflow_flag_ = (source ^ destination) & (destination ^ result) & 0x80000000; + overflow_flag_ = sub_overflow() & 0x80000000; } break; case Operation::SUBAw: @@ -510,6 +521,8 @@ template void Processor: std::cerr << "Should do something with program operation " << int(active_program_->operation) << std::endl; break; } +#undef sub_overflow +#undef add_overflow break; case int(MicroOp::Action::SetMoveFlagsb): @@ -775,3 +788,5 @@ template void Processor: #undef get_status #undef set_status +#undef set_ccr +#undef get_ccr diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp index 38e255ed4..44bf87fd4 100644 --- a/Processors/68000/Implementation/68000Storage.cpp +++ b/Processors/68000/Implementation/68000Storage.cpp @@ -256,7 +256,7 @@ struct ProcessorStorageConstructor { enum class Decoder { Decimal, MOVE, // twelve lowest bits are register, mode, mode, register, for destination and source respectively. - MOVEtoSR, // six lowest bits are [mode, register], decoding to MOVE SR + MOVEtoSRCCR, // six lowest bits are [mode, register], decoding to MOVE SR/CCR CMPI, // eight lowest bits are [size, mode, register], decoding to CMPI BRA, // eight lowest bits are ignored, and an 'n np np' is scheduled Bcc, // twelve lowest bits are ignored, only a PerformAction is scheduled @@ -309,7 +309,8 @@ struct ProcessorStorageConstructor { {0xf000, 0x2000, Operation::MOVEl, Decoder::MOVE}, // 4-116 (p220) {0xf000, 0x3000, Operation::MOVEw, Decoder::MOVE}, // 4-116 (p220) - {0xffc0, 0x46c0, Operation::MOVEtoSR, Decoder::MOVEtoSR}, // 6-19 (p473) + {0xffc0, 0x46c0, Operation::MOVEtoSR, Decoder::MOVEtoSRCCR}, // 6-19 (p473) + {0xffc0, 0x44c0, Operation::MOVEtoCCR, Decoder::MOVEtoSRCCR}, // 4-123 (p227) {0xf1c0, 0xb000, Operation::CMPb, Decoder::CMP}, // 4-75 (p179) {0xf1c0, 0xb040, Operation::CMPw, Decoder::CMP}, // 4-75 (p179) @@ -1245,10 +1246,10 @@ struct ProcessorStorageConstructor { } } break; - case Decoder::MOVEtoSR: { + case Decoder::MOVEtoSRCCR: { if(ea_mode == 1) continue; storage_.instructions[instruction].set_source(storage_, ea_mode, ea_register); - storage_.instructions[instruction].requires_supervisor = true; + storage_.instructions[instruction].requires_supervisor = (operation == Operation::MOVEtoSR); /* DEVIATION FROM YACHT.TXT: it has all of these reading an extra word from the PC; this looks like a mistake so I've padded with nil cycles in the middle. */ diff --git a/Processors/68000/Implementation/68000Storage.hpp b/Processors/68000/Implementation/68000Storage.hpp index e6fed625c..a1621cec6 100644 --- a/Processors/68000/Implementation/68000Storage.hpp +++ b/Processors/68000/Implementation/68000Storage.hpp @@ -55,6 +55,7 @@ class ProcessorStorage { MOVEAw, MOVEAl, MOVEtoSR, MOVEfromSR, + MOVEtoCCR, CMPb, CMPw, CMPl, BTSTb, BTSTl,