diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index 9fc8a8c54..2c6e7bd8a 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -224,7 +224,7 @@ enum class Operation: uint8_t { /// current EFLAGS DF flag. INS, /// Outputs a byte, word or double word from ES:[e]DI to the port specified by DX, - /// incrementing or decrementing [e]DI as per the current EFLAGS DF flag.] + /// incrementing or decrementing [e]DI as per the current EFLAGS DF flag. OUTS, /// Pushes all general purpose registers to the stack, in the order: diff --git a/OSBindings/Mac/Clock SignalTests/65816ComparativeTests.mm b/OSBindings/Mac/Clock SignalTests/65816ComparativeTests.mm index c342889a6..6017f35ac 100644 --- a/OSBindings/Mac/Clock SignalTests/65816ComparativeTests.mm +++ b/OSBindings/Mac/Clock SignalTests/65816ComparativeTests.mm @@ -155,14 +155,14 @@ void print_ram(FILE *file, const std::unordered_map &data) { - (void)generate { BusHandler handler; - // Make tests repeatable, at least for any given instance of - // the runtime. - srand(65816); - NSString *const tempDir = NSTemporaryDirectory(); NSLog(@"Outputting to %@", tempDir); for(int operation = 0; operation < 512; operation++) { + // Make tests repeatable, at least for any given instance of + // the runtime. + srand(65816 + operation); + const bool is_emulated = operation & 256; const uint8_t opcode = operation & 255; diff --git a/Processors/65816/Implementation/65816Base.cpp b/Processors/65816/Implementation/65816Base.cpp index 83bb01701..3eaf614cd 100644 --- a/Processors/65816/Implementation/65816Base.cpp +++ b/Processors/65816/Implementation/65816Base.cpp @@ -14,10 +14,7 @@ uint16_t ProcessorBase::value_of(Register r) const { switch (r) { case Register::ProgramCounter: return registers_.pc; case Register::LastOperationAddress: return last_operation_pc_; - case Register::StackPointer: - return - (registers_.s.full & (registers_.emulation_flag ? 0xff : 0xffff)) | - (registers_.emulation_flag ? 0x100 : 0x000); + case Register::StackPointer: return registers_.s.full; case Register::Flags: return get_flags(); case Register::A: return registers_.a.full; case Register::X: return registers_.x.full; diff --git a/Processors/65816/Implementation/65816Implementation.hpp b/Processors/65816/Implementation/65816Implementation.hpp index bbb9dcedc..9bd0b8902 100644 --- a/Processors/65816/Implementation/65816Implementation.hpp +++ b/Processors/65816/Implementation/65816Implementation.hpp @@ -191,6 +191,13 @@ template void Processor void Processor void Processor void Processor &target) { target(CycleFetchPCThrowaway); // IO. target(CycleFetchPCThrowaway); // IO. @@ -667,7 +667,18 @@ struct CPU::WDC65816::ProcessorStorageConstructor { 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 &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 &target) { target(CycleFetchPCThrowaway); // IO. @@ -677,6 +688,16 @@ struct CPU::WDC65816::ProcessorStorageConstructor { target(CyclePush); // REG [low]. } + // 22c(i). Stack; s, PHx, ignoring emulation mode. I.e. PHD. + static void stack_phd(AccessType, bool, const std::function &target) { + target(CycleFetchPCThrowaway); // IO. + + target(OperationPerform); + + target(CyclePushNotEmulation); // REG high. + target(CyclePushNotEmulation); // REG [low]. + } + // 22d. Stack; s, PEA. static void stack_pea(AccessType, bool, const std::function &target) { target(CycleFetchIncrementPC); // AAL. @@ -684,8 +705,8 @@ struct CPU::WDC65816::ProcessorStorageConstructor { target(OperationCopyInstructionToData); - target(CyclePush); // AAH. - target(CyclePush); // AAL. + target(CyclePushNotEmulation); // AAH. + target(CyclePushNotEmulation); // AAL. } // 22e. Stack; s, PEI. @@ -697,8 +718,8 @@ struct CPU::WDC65816::ProcessorStorageConstructor { target(CycleFetchIncrementData); // AAL. target(CycleFetchData); // AAH. - target(CyclePush); // AAH. - target(CyclePush); // AAL. + target(CyclePushNotEmulation); // AAH. + target(CyclePushNotEmulation); // AAL. } // 22f. Stack; s, PER. @@ -709,8 +730,8 @@ struct CPU::WDC65816::ProcessorStorageConstructor { target(OperationConstructPER); - target(CyclePush); // AAH. - target(CyclePush); // AAL. + target(CyclePushNotEmulation); // AAH. + target(CyclePushNotEmulation); // AAL. } // 22g. Stack; s, RTI. @@ -743,9 +764,9 @@ struct CPU::WDC65816::ProcessorStorageConstructor { target(CycleFetchPCThrowaway); // IO. target(CycleFetchPCThrowaway); // IO. - target(CyclePull); // New PCL. - target(CyclePull); // New PCH. - target(CyclePull); // New PBR. + target(CyclePullNotEmulation); // New PCL. + target(CyclePullNotEmulation); // New PCH. + target(CyclePullNotEmulation); // New PBR. target(OperationPerform); // [RTL] } @@ -818,7 +839,7 @@ ProcessorStorage::ProcessorStorage() { /* 0x08 PHP s */ op(stack_push, PHP, AccessMode::Always8Bit); /* 0x09 ORA # */ op(immediate, ORA); /* 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); /* 0x0d ORA a */ op(absolute, ORA); /* 0x0e ASL a */ op(absolute_rmw, ASL); @@ -852,7 +873,7 @@ ProcessorStorage::ProcessorStorage() { /* 0x28 PLP s */ op(stack_pull, PLP, AccessMode::Always8Bit); /* 0x29 AND # */ op(immediate, AND); /* 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); /* 0x2d AND a */ op(absolute, AND); /* 0x2e ROL a */ op(absolute_rmw, ROL); diff --git a/Processors/65816/Implementation/65816Storage.hpp b/Processors/65816/Implementation/65816Storage.hpp index 35d4570b6..d227dd899 100644 --- a/Processors/65816/Implementation/65816Storage.hpp +++ b/Processors/65816/Implementation/65816Storage.hpp @@ -58,6 +58,11 @@ enum MicroOp: uint8_t { /// Performs as CyclePull if the 65816 is not in emulation mode; otherwise skips itself. 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 /// STP or WAI condition is satisfied. CycleRepeatingNone,