1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-07 23:25:00 +00:00

Attempts to clean up my JMP/JSR mess.

Also takes a step forwards in decimal SBC, but it's not right yet.
This commit is contained in:
Thomas Harte
2020-10-08 16:48:46 -04:00
parent b578240993
commit 907c3374c3
3 changed files with 37 additions and 35 deletions

View File

@@ -448,19 +448,23 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
[[fallthrough]]; [[fallthrough]];
case JMP: case JMP:
pc_ = instruction_buffer_.value & 0xffff; pc_ = uint16_t(instruction_buffer_.value);
break;
case JMPind:
pc_ = data_buffer_.value;
break; break;
case JSL: case JSL:
program_bank_ = instruction_buffer_.value & 0xff0000; program_bank_ = instruction_buffer_.value & 0xff0000;
instruction_buffer_.size = 2;
[[fallthrough]]; [[fallthrough]];
case JSR: { case JSR:
const uint16_t old_pc = pc_; data_buffer_.value = pc_;
data_buffer_.size = 2;
pc_ = instruction_buffer_.value; pc_ = instruction_buffer_.value;
instruction_buffer_.value = old_pc; break;
} break;
// //
// Block moves. // Block moves.
@@ -639,35 +643,32 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
#undef cp #undef cp
case SBC: case SBC:
if(flags_.decimal) { data_buffer_.value = ~data_buffer_.value & m_masks_[1];
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;
[[fallthrough]]; [[fallthrough]];
case ADC: { case ADC: {
int result; int result;
const uint16_t a = a_.full & m_masks_[1];
if(flags_.decimal) { if(flags_.decimal) {
result = flags_.carry; result = flags_.carry;
const int nibble_adjustment = (active_instruction_->operation == SBC) ? 0xa : 0x6;
#define nibble(mask, limit, addition, carry) \ // TODO: this still isn't quite correct for SBC as the limit test is wrong, I think.
result += (a_.full & mask) + (data_buffer_.value & mask); \
if(result >= limit) result = ((result + addition) & (carry - 1)) + carry;
nibble(0x000f, 0x000a, 0x0006, 0x00010); #define nibble(mask, limit, addition, carry) \
nibble(0x00f0, 0x00a0, 0x0060, 0x00100); result += (a & mask) + (data_buffer_.value & mask); \
nibble(0x0f00, 0x0a00, 0x0600, 0x01000); if(result >= limit) result = ((result + (addition)) & (carry - 1)) + carry;
nibble(0xf000, 0xa000, 0x6000, 0x10000);
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 #undef nibble
} else { } 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; flags_.overflow = (( (result ^ a_.full) & (result ^ data_buffer_.value) ) >> (1 + m_shift_))&0x40;

View File

@@ -178,7 +178,6 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
static void absolute_jmp(AccessType, bool, const std::function<void(MicroOp)> &target) { static void absolute_jmp(AccessType, bool, const std::function<void(MicroOp)> &target) {
target(CycleFetchIncrementPC); // New PCL. target(CycleFetchIncrementPC); // New PCL.
target(CycleFetchPC); // New PCH. target(CycleFetchPC); // New PCH.
target(OperationConstructAbsolute); // Calculate data address.
target(OperationPerform); // [JMP] target(OperationPerform); // [JMP]
} }
@@ -187,7 +186,6 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
target(CycleFetchIncrementPC); // New PCL. target(CycleFetchIncrementPC); // New PCL.
target(CycleFetchPC); // New PCH. target(CycleFetchPC); // New PCH.
target(CycleFetchPCThrowaway); // IO target(CycleFetchPCThrowaway); // IO
target(OperationConstructAbsolute); // Calculate data address.
target(OperationPerform); // [JSR] target(OperationPerform); // [JSR]
target(CyclePush); // PCH target(CyclePush); // PCH
target(CyclePush); // PCL target(CyclePush); // PCL
@@ -227,7 +225,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
target(OperationConstructAbsoluteIndexedIndirect); // Calculate data address. target(OperationConstructAbsoluteIndexedIndirect); // Calculate data address.
target(CycleFetchIncrementData); // New PCL target(CycleFetchIncrementData); // New PCL
target(CycleFetchData); // New PCH. target(CycleFetchData); // New PCH.
target(OperationPerform); // ['JSR' (actually: JMP will do)] target(OperationPerform); // ['JSR' (actually: JMPind will do)]
} }
// 3a. Absolute Indirect; (a), JML. // 3a. Absolute Indirect; (a), JML.
@@ -814,7 +812,7 @@ ProcessorStorage::ProcessorStorage() {
/* 0x5e LSR a, x */ op(absolute_x_rmw, LSR); /* 0x5e LSR a, x */ op(absolute_x_rmw, LSR);
/* 0x5f EOR al, x */ op(absolute_long_x, EOR); /* 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); /* 0x61 ADC (d, x) */ op(direct_indexed_indirect, ADC);
/* 0x62 PER s */ op(stack_per, NOP); /* 0x62 PER s */ op(stack_per, NOP);
/* 0x63 ADC d, s */ op(stack_relative, ADC); /* 0x63 ADC d, s */ op(stack_relative, ADC);
@@ -826,7 +824,7 @@ ProcessorStorage::ProcessorStorage() {
/* 0x69 ADC # */ op(immediate, ADC); /* 0x69 ADC # */ op(immediate, ADC);
/* 0x6a ROR A */ op(accumulator, ROR); /* 0x6a ROR A */ op(accumulator, ROR);
/* 0x6b RTL s */ op(stack_rtl, JML); /* 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); /* 0x6d ADC a */ op(absolute, ADC);
/* 0x6e ROR a */ op(absolute_rmw, ROR); /* 0x6e ROR a */ op(absolute_rmw, ROR);
/* 0x6f ADC al */ op(absolute_long, ADC); /* 0x6f ADC al */ op(absolute_long, ADC);
@@ -843,7 +841,7 @@ ProcessorStorage::ProcessorStorage() {
/* 0x79 ADC a, y */ op(absolute_y, ADC); /* 0x79 ADC a, y */ op(absolute_y, ADC);
/* 0x7a PLY s */ op(stack_pull, LDY); /* 0x7a PLY s */ op(stack_pull, LDY);
/* 0x7b TDC i */ op(implied, TDC); /* 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); /* 0x7d ADC a, x */ op(absolute_x, ADC);
/* 0x7e ROR a, x */ op(absolute_x_rmw, ROR); /* 0x7e ROR a, x */ op(absolute_x_rmw, ROR);
/* 0x7f ADC al, x */ op(absolute_long_x, ADC); /* 0x7f ADC al, x */ op(absolute_long_x, ADC);
@@ -979,7 +977,7 @@ ProcessorStorage::ProcessorStorage() {
/* 0xf9 SBC a, y */ op(absolute_y, SBC); /* 0xf9 SBC a, y */ op(absolute_y, SBC);
/* 0xfa PLX s */ op(stack_pull, LDX); /* 0xfa PLX s */ op(stack_pull, LDX);
/* 0xfb XCE i */ op(implied, XCE); /* 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); /* 0xfd SBC a, x */ op(absolute_x, SBC);
/* 0xfe INC a, x */ op(absolute_x_rmw, INC); /* 0xfe INC a, x */ op(absolute_x_rmw, INC);
/* 0xff SBC al, x */ op(absolute_long_x, SBC); /* 0xff SBC al, x */ op(absolute_long_x, SBC);

View File

@@ -174,18 +174,21 @@ enum Operation: uint8_t {
// from the stack. // from the stack.
RTI, RTL, 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, 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, JML,
/// Loads the PC with the operand from the data buffer, replacing /// Loads the PC with the operand from the instruction buffer, placing
/// it with the old PC. /// the current PC into the data buffer.
JSR, JSR,
/// Loads the PC and the PBR with the operand from the data buffer, /// Loads the PC and the PBR with the operand from the instruction buffer,
/// replacing it with the old PC (and only the PC; PBR not included). /// placing the old PC into the data buffer (and only the PC; PBR not included).
JSL, JSL,
/// i.e. jump to vector. TODO: is this really distinct from JMP? I'm assuming so for now, /// i.e. jump to vector. TODO: is this really distinct from JMP? I'm assuming so for now,