1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-05 06:05:27 +00:00

Merge pull request #1148 from TomHarte/NoEmulationStack

Use full 16-bit stack pointer for all 'new' instructions.
This commit is contained in:
Thomas Harte 2023-07-31 20:41:10 -04:00 committed by GitHub
commit cdb86022a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 20 deletions

View File

@ -14,10 +14,7 @@ uint16_t ProcessorBase::value_of(Register r) const {
switch (r) { switch (r) {
case Register::ProgramCounter: return registers_.pc; case Register::ProgramCounter: return registers_.pc;
case Register::LastOperationAddress: return last_operation_pc_; case Register::LastOperationAddress: return last_operation_pc_;
case Register::StackPointer: case Register::StackPointer: return registers_.s.full;
return
(registers_.s.full & (registers_.emulation_flag ? 0xff : 0xffff)) |
(registers_.emulation_flag ? 0x100 : 0x000);
case Register::Flags: return get_flags(); case Register::Flags: return get_flags();
case Register::A: return registers_.a.full; case Register::A: return registers_.a.full;
case Register::X: return registers_.x.full; case Register::X: return registers_.x.full;

View File

@ -191,6 +191,13 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
--registers_.s.full; --registers_.s.full;
break; break;
case CyclePushNotEmulation:
bus_address_ = registers_.s.full;
bus_value_ = data_buffer_.next_output_descending();
bus_operation_ = MOS6502Esque::Write;
--registers_.s.full;
break;
case CyclePullIfNotEmulation: case CyclePullIfNotEmulation:
if(registers_.emulation_flag) { if(registers_.emulation_flag) {
continue; continue;
@ -202,6 +209,13 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
stack_access(data_buffer_.next_input(), MOS6502Esque::Read); stack_access(data_buffer_.next_input(), MOS6502Esque::Read);
break; break;
case CyclePullNotEmulation:
++registers_.s.full;
bus_address_ = registers_.s.full;
bus_value_ = data_buffer_.next_input();
bus_operation_ = MOS6502Esque::Read;
break;
case CycleAccessStack: case CycleAccessStack:
stack_access(&bus_throwaway_, MOS6502Esque::InternalOperationRead); stack_access(&bus_throwaway_, MOS6502Esque::InternalOperationRead);
break; break;

View File

@ -319,7 +319,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
target(CycleFetchIncrementPC); // New PCH. target(CycleFetchIncrementPC); // New PCH.
target(OperationCopyPBRToData); // Copy PBR to the data register. target(OperationCopyPBRToData); // Copy PBR to the data register.
target(CyclePush); // PBR. target(CyclePushNotEmulation); // PBR.
target(CycleFetchPreviousThrowaway); // IO. target(CycleFetchPreviousThrowaway); // IO.
target(CycleFetchPC); // New PBR. target(CycleFetchPC); // New PBR.
@ -327,8 +327,8 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
target(OperationConstructAbsolute); // Calculate data address. target(OperationConstructAbsolute); // Calculate data address.
target(OperationPerform); // [JSL] target(OperationPerform); // [JSL]
target(CyclePush); // PCH. target(CyclePushNotEmulation); // PCH.
target(CyclePush); // PCL. target(CyclePushNotEmulation); // PCL.
} }
// 5. Absolute long, X; al, x. // 5. Absolute long, X; al, x.
@ -656,7 +656,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
stack_exception_impl(type, is8bit, target, CycleAccessStack); stack_exception_impl(type, is8bit, target, CycleAccessStack);
} }
// 22b. Stack; s, PLx. // 22b(i). Stack; s, PLx, respecting emulation mode. E.g. PLP.
static void stack_pull(AccessType, bool is8bit, const std::function<void(MicroOp)> &target) { static void stack_pull(AccessType, bool is8bit, const std::function<void(MicroOp)> &target) {
target(CycleFetchPCThrowaway); // IO. target(CycleFetchPCThrowaway); // IO.
target(CycleFetchPCThrowaway); // IO. target(CycleFetchPCThrowaway); // IO.
@ -667,7 +667,18 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
target(OperationPerform); target(OperationPerform);
} }
// 22c. Stack; s, PHx. // 22b(ii). Stack; s, PLx, ignoring emulation mode. I.e. PLD.
static void stack_pld(AccessType, bool, const std::function<void(MicroOp)> &target) {
target(CycleFetchPCThrowaway); // IO.
target(CycleFetchPCThrowaway); // IO.
target(CyclePullNotEmulation); // REG low.
target(CyclePullNotEmulation); // REG [high].
target(OperationPerform);
}
// 22c(i). Stack; s, PHx, respecting emulation mode. E.g. PHP.
static void stack_push(AccessType, bool is8bit, const std::function<void(MicroOp)> &target) { static void stack_push(AccessType, bool is8bit, const std::function<void(MicroOp)> &target) {
target(CycleFetchPCThrowaway); // IO. target(CycleFetchPCThrowaway); // IO.
@ -677,6 +688,16 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
target(CyclePush); // REG [low]. target(CyclePush); // REG [low].
} }
// 22c(i). Stack; s, PHx, ignoring emulation mode. I.e. PHD.
static void stack_phd(AccessType, bool, const std::function<void(MicroOp)> &target) {
target(CycleFetchPCThrowaway); // IO.
target(OperationPerform);
target(CyclePushNotEmulation); // REG high.
target(CyclePushNotEmulation); // REG [low].
}
// 22d. Stack; s, PEA. // 22d. Stack; s, PEA.
static void stack_pea(AccessType, bool, const std::function<void(MicroOp)> &target) { static void stack_pea(AccessType, bool, const std::function<void(MicroOp)> &target) {
target(CycleFetchIncrementPC); // AAL. target(CycleFetchIncrementPC); // AAL.
@ -684,8 +705,8 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
target(OperationCopyInstructionToData); target(OperationCopyInstructionToData);
target(CyclePush); // AAH. target(CyclePushNotEmulation); // AAH.
target(CyclePush); // AAL. target(CyclePushNotEmulation); // AAL.
} }
// 22e. Stack; s, PEI. // 22e. Stack; s, PEI.
@ -697,8 +718,8 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
target(CycleFetchIncrementData); // AAL. target(CycleFetchIncrementData); // AAL.
target(CycleFetchData); // AAH. target(CycleFetchData); // AAH.
target(CyclePush); // AAH. target(CyclePushNotEmulation); // AAH.
target(CyclePush); // AAL. target(CyclePushNotEmulation); // AAL.
} }
// 22f. Stack; s, PER. // 22f. Stack; s, PER.
@ -709,8 +730,8 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
target(OperationConstructPER); target(OperationConstructPER);
target(CyclePush); // AAH. target(CyclePushNotEmulation); // AAH.
target(CyclePush); // AAL. target(CyclePushNotEmulation); // AAL.
} }
// 22g. Stack; s, RTI. // 22g. Stack; s, RTI.
@ -743,9 +764,9 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
target(CycleFetchPCThrowaway); // IO. target(CycleFetchPCThrowaway); // IO.
target(CycleFetchPCThrowaway); // IO. target(CycleFetchPCThrowaway); // IO.
target(CyclePull); // New PCL. target(CyclePullNotEmulation); // New PCL.
target(CyclePull); // New PCH. target(CyclePullNotEmulation); // New PCH.
target(CyclePull); // New PBR. target(CyclePullNotEmulation); // New PBR.
target(OperationPerform); // [RTL] target(OperationPerform); // [RTL]
} }
@ -818,7 +839,7 @@ ProcessorStorage::ProcessorStorage() {
/* 0x08 PHP s */ op(stack_push, PHP, AccessMode::Always8Bit); /* 0x08 PHP s */ op(stack_push, PHP, AccessMode::Always8Bit);
/* 0x09 ORA # */ op(immediate, ORA); /* 0x09 ORA # */ op(immediate, ORA);
/* 0x0a ASL A */ op(accumulator, ASL); /* 0x0a ASL A */ op(accumulator, ASL);
/* 0x0b PHD s */ op(stack_push, PHD, AccessMode::Always16Bit); /* 0x0b PHD s */ op(stack_phd, PHD);
/* 0x0c TSB a */ op(absolute_rmw, TSB); /* 0x0c TSB a */ op(absolute_rmw, TSB);
/* 0x0d ORA a */ op(absolute, ORA); /* 0x0d ORA a */ op(absolute, ORA);
/* 0x0e ASL a */ op(absolute_rmw, ASL); /* 0x0e ASL a */ op(absolute_rmw, ASL);
@ -852,7 +873,7 @@ ProcessorStorage::ProcessorStorage() {
/* 0x28 PLP s */ op(stack_pull, PLP, AccessMode::Always8Bit); /* 0x28 PLP s */ op(stack_pull, PLP, AccessMode::Always8Bit);
/* 0x29 AND # */ op(immediate, AND); /* 0x29 AND # */ op(immediate, AND);
/* 0x2a ROL A */ op(accumulator, ROL); /* 0x2a ROL A */ op(accumulator, ROL);
/* 0x2b PLD s */ op(stack_pull, PLD, AccessMode::Always16Bit); /* 0x2b PLD s */ op(stack_pld, PLD);
/* 0x2c BIT a */ op(absolute, BIT); /* 0x2c BIT a */ op(absolute, BIT);
/* 0x2d AND a */ op(absolute, AND); /* 0x2d AND a */ op(absolute, AND);
/* 0x2e ROL a */ op(absolute_rmw, ROL); /* 0x2e ROL a */ op(absolute_rmw, ROL);

View File

@ -58,6 +58,11 @@ enum MicroOp: uint8_t {
/// Performs as CyclePull if the 65816 is not in emulation mode; otherwise skips itself. /// Performs as CyclePull if the 65816 is not in emulation mode; otherwise skips itself.
CyclePullIfNotEmulation, CyclePullIfNotEmulation,
/// Pushes a single byte from the data buffer to the stack, always using its full 16-bit address.
CyclePushNotEmulation,
/// Pulls a single byte to the data buffer from the stack, always using its full 16-bit address.
CyclePullNotEmulation,
/// Issues a BusOperation::None and regresses the micro-op counter until an established /// Issues a BusOperation::None and regresses the micro-op counter until an established
/// STP or WAI condition is satisfied. /// STP or WAI condition is satisfied.
CycleRepeatingNone, CycleRepeatingNone,