From 907c3374c3c8b16bdcd663ecf49331ac61edeb3e Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 8 Oct 2020 16:48:46 -0400 Subject: [PATCH] Attempts to clean up my JMP/JSR mess. Also takes a step forwards in decimal SBC, but it's not right yet. --- .../Implementation/65816Implementation.hpp | 45 ++++++++++--------- .../65816/Implementation/65816Storage.cpp | 12 +++-- .../65816/Implementation/65816Storage.hpp | 15 ++++--- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/Processors/65816/Implementation/65816Implementation.hpp b/Processors/65816/Implementation/65816Implementation.hpp index 8fe4a34cb..5c316b280 100644 --- a/Processors/65816/Implementation/65816Implementation.hpp +++ b/Processors/65816/Implementation/65816Implementation.hpp @@ -448,19 +448,23 @@ template void Processor::run_for(const Cycles [[fallthrough]]; case JMP: - pc_ = instruction_buffer_.value & 0xffff; + pc_ = uint16_t(instruction_buffer_.value); + break; + + case JMPind: + pc_ = data_buffer_.value; break; case JSL: program_bank_ = instruction_buffer_.value & 0xff0000; - instruction_buffer_.size = 2; [[fallthrough]]; - case JSR: { - const uint16_t old_pc = pc_; + case JSR: + data_buffer_.value = pc_; + data_buffer_.size = 2; + pc_ = instruction_buffer_.value; - instruction_buffer_.value = old_pc; - } break; + break; // // Block moves. @@ -639,35 +643,32 @@ template void Processor::run_for(const Cycles #undef cp case SBC: - if(flags_.decimal) { - assert(false); - break; - } - - // Implement non-decimal SBC by falling through to ADC; - // TODO: what do I need to invert to be able to fall through in both cases? And does it matter? - data_buffer_.value = ~data_buffer_.value; + data_buffer_.value = ~data_buffer_.value & m_masks_[1]; [[fallthrough]]; case ADC: { int result; + const uint16_t a = a_.full & m_masks_[1]; if(flags_.decimal) { result = flags_.carry; + const int nibble_adjustment = (active_instruction_->operation == SBC) ? 0xa : 0x6; -#define nibble(mask, limit, addition, carry) \ - result += (a_.full & mask) + (data_buffer_.value & mask); \ - if(result >= limit) result = ((result + addition) & (carry - 1)) + carry; + // TODO: this still isn't quite correct for SBC as the limit test is wrong, I think. - nibble(0x000f, 0x000a, 0x0006, 0x00010); - nibble(0x00f0, 0x00a0, 0x0060, 0x00100); - nibble(0x0f00, 0x0a00, 0x0600, 0x01000); - nibble(0xf000, 0xa000, 0x6000, 0x10000); +#define nibble(mask, limit, addition, carry) \ + result += (a & mask) + (data_buffer_.value & mask); \ + if(result >= limit) result = ((result + (addition)) & (carry - 1)) + carry; + + nibble(0x000f, 0x000a, nibble_adjustment << 0, 0x00010); + nibble(0x00f0, 0x00a0, nibble_adjustment << 8, 0x00100); + nibble(0x0f00, 0x0a00, nibble_adjustment << 16, 0x01000); + nibble(0xf000, 0xa000, nibble_adjustment << 24, 0x10000); #undef nibble } else { - result = a_.full + data_buffer_.value + flags_.carry; + result = a + data_buffer_.value + flags_.carry; } flags_.overflow = (( (result ^ a_.full) & (result ^ data_buffer_.value) ) >> (1 + m_shift_))&0x40; diff --git a/Processors/65816/Implementation/65816Storage.cpp b/Processors/65816/Implementation/65816Storage.cpp index 5c0483872..ac554f5e2 100644 --- a/Processors/65816/Implementation/65816Storage.cpp +++ b/Processors/65816/Implementation/65816Storage.cpp @@ -178,7 +178,6 @@ struct CPU::WDC65816::ProcessorStorageConstructor { static void absolute_jmp(AccessType, bool, const std::function &target) { target(CycleFetchIncrementPC); // New PCL. target(CycleFetchPC); // New PCH. - target(OperationConstructAbsolute); // Calculate data address. target(OperationPerform); // [JMP] } @@ -187,7 +186,6 @@ struct CPU::WDC65816::ProcessorStorageConstructor { target(CycleFetchIncrementPC); // New PCL. target(CycleFetchPC); // New PCH. target(CycleFetchPCThrowaway); // IO - target(OperationConstructAbsolute); // Calculate data address. target(OperationPerform); // [JSR] target(CyclePush); // PCH target(CyclePush); // PCL @@ -227,7 +225,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor { target(OperationConstructAbsoluteIndexedIndirect); // Calculate data address. target(CycleFetchIncrementData); // New PCL target(CycleFetchData); // New PCH. - target(OperationPerform); // ['JSR' (actually: JMP will do)] + target(OperationPerform); // ['JSR' (actually: JMPind will do)] } // 3a. Absolute Indirect; (a), JML. @@ -814,7 +812,7 @@ ProcessorStorage::ProcessorStorage() { /* 0x5e LSR a, x */ op(absolute_x_rmw, LSR); /* 0x5f EOR al, x */ op(absolute_long_x, EOR); - /* 0x60 RTS s */ op(stack_rts, JMP); // [sic]; loads the PC from data as per an RTS. + /* 0x60 RTS s */ op(stack_rts, JMPind); // [sic]; loads the PC from data as per an RTS. /* 0x61 ADC (d, x) */ op(direct_indexed_indirect, ADC); /* 0x62 PER s */ op(stack_per, NOP); /* 0x63 ADC d, s */ op(stack_relative, ADC); @@ -826,7 +824,7 @@ ProcessorStorage::ProcessorStorage() { /* 0x69 ADC # */ op(immediate, ADC); /* 0x6a ROR A */ op(accumulator, ROR); /* 0x6b RTL s */ op(stack_rtl, JML); - /* 0x6c JMP (a) */ op(absolute_indirect_jmp, JMP); + /* 0x6c JMP (a) */ op(absolute_indirect_jmp, JMPind); /* 0x6d ADC a */ op(absolute, ADC); /* 0x6e ROR a */ op(absolute_rmw, ROR); /* 0x6f ADC al */ op(absolute_long, ADC); @@ -843,7 +841,7 @@ ProcessorStorage::ProcessorStorage() { /* 0x79 ADC a, y */ op(absolute_y, ADC); /* 0x7a PLY s */ op(stack_pull, LDY); /* 0x7b TDC i */ op(implied, TDC); - /* 0x7c JMP (a, x) */ op(absolute_indexed_indirect_jmp, JMP); + /* 0x7c JMP (a, x) */ op(absolute_indexed_indirect_jmp, JMPind); /* 0x7d ADC a, x */ op(absolute_x, ADC); /* 0x7e ROR a, x */ op(absolute_x_rmw, ROR); /* 0x7f ADC al, x */ op(absolute_long_x, ADC); @@ -979,7 +977,7 @@ ProcessorStorage::ProcessorStorage() { /* 0xf9 SBC a, y */ op(absolute_y, SBC); /* 0xfa PLX s */ op(stack_pull, LDX); /* 0xfb XCE i */ op(implied, XCE); - /* 0xfc JSR (a, x) */ op(absolute_indexed_indirect_jsr, JMP); // [sic] + /* 0xfc JSR (a, x) */ op(absolute_indexed_indirect_jsr, JMPind); // [sic] /* 0xfd SBC a, x */ op(absolute_x, SBC); /* 0xfe INC a, x */ op(absolute_x_rmw, INC); /* 0xff SBC al, x */ op(absolute_long_x, SBC); diff --git a/Processors/65816/Implementation/65816Storage.hpp b/Processors/65816/Implementation/65816Storage.hpp index 71423b830..f16d36bb6 100644 --- a/Processors/65816/Implementation/65816Storage.hpp +++ b/Processors/65816/Implementation/65816Storage.hpp @@ -174,18 +174,21 @@ enum Operation: uint8_t { // from the stack. RTI, RTL, - /// Loads the PC with the operand from the data buffer. + /// Loads the PC with the contents of the data buffer. + JMPind, + + /// Loads the PC with the contents of the instruction bufer. JMP, - /// Loads the PC and PBR with the operand from the data buffer. + /// Loads the PC and PBR with the operand from the instruction buffer. JML, - /// Loads the PC with the operand from the data buffer, replacing - /// it with the old PC. + /// Loads the PC with the operand from the instruction buffer, placing + /// the current PC into the data buffer. JSR, - /// Loads the PC and the PBR with the operand from the data buffer, - /// replacing it with the old PC (and only the PC; PBR not included). + /// Loads the PC and the PBR with the operand from the instruction buffer, + /// placing the old PC into the data buffer (and only the PC; PBR not included). JSL, /// i.e. jump to vector. TODO: is this really distinct from JMP? I'm assuming so for now,