From 64f99d83a40455b64b406f0410b0e7aa697b8eeb Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 1 Apr 2019 21:21:26 -0400 Subject: [PATCH] Takes a stab at offering ADD, ADDA, SUB and SUBA operations. Not yet decoded. --- .../Implementation/68000Implementation.hpp | 83 +++++++++++++++++++ .../68000/Implementation/68000Storage.hpp | 6 +- 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 56654050d..8e6621634 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -92,6 +92,48 @@ template void Processor: active_program_->destination->halves.low.halves.low = uint8_t(result); } break; + // ADD and ADDA add two quantities, the latter sign extending and without setting any flags. + case Operation::ADDb: { + const uint8_t source = active_program_->source->halves.low.halves.low; + const uint8_t destination = active_program_->destination->halves.low.halves.low; + const int result = destination + source; + + 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; + } break; + + case Operation::ADDw: { + const uint16_t source = active_program_->source->halves.low.full; + const uint16_t destination = active_program_->destination->halves.low.full; + const int result = destination + source; + + 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; + } break; + + case Operation::ADDl: { + const uint32_t source = active_program_->source->full; + const uint32_t destination = active_program_->destination->full; + const uint64_t result = destination + source; + + 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; + } break; + + case Operation::ADDAw: + active_program_->destination->full += int16_t(active_program_->source->halves.low.full); + break; + + case Operation::ADDAl: + active_program_->destination->full += active_program_->source->full; + break; + // BRA: alters the program counter, exclusively via the prefetch queue. case Operation::BRA: { const int8_t byte_offset = int8_t(prefetch_queue_.halves.high.halves.low); @@ -290,6 +332,47 @@ template void Processor: active_program_->destination->halves.low.halves.low = uint8_t(result); } break; + case Operation::SUBb: { + const uint8_t source = active_program_->source->halves.low.halves.low; + const uint8_t destination = active_program_->destination->halves.low.halves.low; + const int result = destination - source; + + 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; + } break; + + case Operation::SUBw: { + const uint16_t source = active_program_->source->halves.low.full; + const uint16_t destination = active_program_->destination->halves.low.full; + const int result = destination - source; + + 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; + } break; + + case Operation::SUBl: { + const uint32_t source = active_program_->source->full; + const uint32_t destination = active_program_->destination->full; + const uint64_t result = destination - source; + + 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; + } break; + + case Operation::SUBAw: + active_program_->destination->full -= int16_t(active_program_->source->halves.low.full); + break; + + case Operation::SUBAl: + active_program_->destination->full -= active_program_->source->full; + break; + /* Development period debugging. */ diff --git a/Processors/68000/Implementation/68000Storage.hpp b/Processors/68000/Implementation/68000Storage.hpp index 67c642a86..d41fd73a0 100644 --- a/Processors/68000/Implementation/68000Storage.hpp +++ b/Processors/68000/Implementation/68000Storage.hpp @@ -45,7 +45,11 @@ class ProcessorStorage { enum class Operation { None, ABCD, SBCD, - ADD, AND, EOR, OR, SUB, + + ADDb, ADDw, ADDl, + SUBb, SUBw, SUBl, + ADDAw, ADDAl, + SUBAw, SUBAl, MOVEb, MOVEw, MOVEl, MOVEq, MOVEAw, MOVEAl,