From 1ab831f5713aa4a465521ac48448316ccec2d536 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 13:17:01 -0400 Subject: [PATCH 01/17] Add the option to log a list of all untested instructions. --- .../68000ComparativeTests.mm | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm index 6e2bec4b2..94c6cddce 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm @@ -18,6 +18,7 @@ //#define USE_EXECUTOR //#define MAKE_SUGGESTIONS +//#define LOG_UNTESTED namespace { @@ -127,6 +128,7 @@ struct TestProcessor: public CPU::MC68000Mk2::BusHandler { NSMutableSet *_failures; NSMutableArray *_failingOpcodes; NSMutableDictionary *> *_suggestedCorrections; + NSMutableSet *_testedOpcodes; InstructionSet::M68k::Predecoder _decoder; @@ -150,6 +152,10 @@ struct TestProcessor: public CPU::MC68000Mk2::BusHandler { _failures = [[NSMutableSet alloc] init]; _failingOpcodes = [[NSMutableArray alloc] init]; + // This will simply accumulate a list of all tested opcodes, in order to report + // on those that are missing. + _testedOpcodes = [[NSMutableSet alloc] init]; + #ifdef MAKE_SUGGESTIONS _suggestedCorrections = [[NSMutableDictionary alloc] init]; #endif @@ -190,6 +196,25 @@ struct TestProcessor: public CPU::MC68000Mk2::BusHandler { } } } + +#ifdef LOG_UNTESTED + // Output a list of untested opcodes. + NSMutableArray *untested = [[NSMutableArray alloc] init]; + for(int opcode = 0; opcode < 65536; opcode++) { + const auto instruction = _decoder.decode(uint16_t(opcode)); + + if(instruction.operation == InstructionSet::M68k::Operation::Undefined) { + continue; + } + if([_testedOpcodes containsObject:@(opcode)]) { + continue; + } + + [untested addObject:[NSString stringWithFormat:@"%04x %s", opcode, instruction.to_string(uint16_t(opcode)).c_str()]]; + } + + NSLog(@"Untested: %@", untested); +#endif } - (void)testJSONAtURL:(NSURL *)url { @@ -213,6 +238,20 @@ struct TestProcessor: public CPU::MC68000Mk2::BusHandler { // Compare against a test set if one has been supplied. if(_testSet && ![_testSet containsObject:name]) continue; + // Pull out the opcode and record it. + NSArray *const initialMemory = test[@"initial memory"]; + uint16_t opcode = 0; + NSEnumerator *enumerator = [initialMemory objectEnumerator]; + while(true) { + NSNumber *const address = [enumerator nextObject]; + NSNumber *const value = [enumerator nextObject]; + + if(!address || !value) break; + if(address.integerValue == 0x100) opcode |= value.integerValue << 8; + if(address.integerValue == 0x101) opcode |= value.integerValue; + } + [_testedOpcodes addObject:@(opcode)]; + #ifdef USE_EXECUTOR [self testOperationExecutor:test name:name]; #else From 0bedf608c04c7ed50f3a8c8075a5a9f7c5fa6ef8 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 15:36:27 -0400 Subject: [PATCH 02/17] Add details on gaps in coverage. --- .../68000 Comparative Tests/readme.md | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md b/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md index 1bb9ed03d..4a1690621 100644 --- a/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md +++ b/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md @@ -40,6 +40,25 @@ All initial register contents are random except that the lowest bit is never set So the output is very scattergun approach, with a lot of redundancy. +## Known Issues + +Errors in generation mean that: +1. MOVE is mostly untested; MOVEq is well-tested and other MOVEs appear within the test set as per the approximate generation algorithm above but due to an error in the generation of move.json, all of its opcodes are $2000 less than they should be, causing them to hit various instructions other than MOVE; +2. there is sparse coverage of the rotates and shifts: LS[L/R], AS[L/R], RO[L/R] and ROX[L/R]; and +3. there are similarly few tests of MULU. + +Issues with comparing results between multiple emulators in the case of unusual instructions mean that no tests have been generated for: +1. MOVE [to or from] SR; +2. TRAP; +3. TRAPV; +4. MOVE [to or from] USP; +5. STOP; +6. RTE; +7. Bcc where the offset is an odd number; or +8. BSR where the offset is an odd number. + +For both Bcc and BSR, there is good coverage of even-quantity offsets. + ## Questionable Results -Values for the undocumented flags of DIVU and DIVS have not yet been verified, due to a lack of documentation. \ No newline at end of file +Values for the undocumented flags of DIVU and DIVS have not yet been verified, due to a lack of documentation. From 4961e39fb66c0625a1450fb28b426db54cf9b8c5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 15:39:00 -0400 Subject: [PATCH 03/17] Mention DIVU/DIVS flags. --- .../Mac/Clock SignalTests/68000 Comparative Tests/readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md b/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md index 4a1690621..c50378092 100644 --- a/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md +++ b/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md @@ -59,6 +59,8 @@ Issues with comparing results between multiple emulators in the case of unusual For both Bcc and BSR, there is good coverage of even-quantity offsets. +Lack of good documentation for the meaning of N and Z flags for DIVU and DIVS in the case of overflow means that the results here may or may not be correct; there was no consensus between emulators and I have been unable to find information on what the proper answers should be. + ## Questionable Results Values for the undocumented flags of DIVU and DIVS have not yet been verified, due to a lack of documentation. From ee58301a46ed00642cc46bf75b4219067254d484 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 15:45:09 -0400 Subject: [PATCH 04/17] Add `RaiseException` macro. --- .../Implementation/68000Mk2Implementation.hpp | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index 4db2a457e..fb4b8bf80 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -317,6 +317,12 @@ void Processor Date: Wed, 25 May 2022 16:05:28 -0400 Subject: [PATCH 05/17] Fix for the actual number of cycles in a standard reset. --- OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp index 414da9395..650d79641 100644 --- a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp +++ b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp @@ -76,8 +76,8 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { // cycles to finish the reset program, and set the stored state. if(!has_run_) { has_run_ = true; - m68000_.run_for(HalfCycles(76)); - duration_ -= HalfCycles(76); + m68000_.run_for(HalfCycles(80)); + duration_ -= HalfCycles(80); } } @@ -140,7 +140,7 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { } private: - CPU::MC68000Mk2::Processor m68000_; + CPU::MC68000Mk2::Processor m68000_; std::array ram_{}; int instructions_remaining_; HalfCycles duration_; From 4ad0e04c235a47a7209514a1bb0989474cb87226 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 16:05:45 -0400 Subject: [PATCH 06/17] Fix macro for `n` being an expression. --- Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index fb4b8bf80..0877055f4 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -244,7 +244,7 @@ void Processor Date: Wed, 25 May 2022 16:20:26 -0400 Subject: [PATCH 07/17] Fix ANDI/ORI/EORI to CCR/SR timing. --- Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index 0877055f4..91fb48f81 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -2018,6 +2018,8 @@ void Processor Date: Wed, 25 May 2022 16:32:02 -0400 Subject: [PATCH 08/17] Eliminate false prefetch for BSR. --- .../Implementation/68000Mk2Implementation.hpp | 23 ++++++++----------- .../Implementation/68000Mk2Storage.hpp | 2 +- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index 91fb48f81..e6903141d 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -135,7 +135,8 @@ enum ExecutionState: int { Bccb_branch_not_taken, Bccw_branch_not_taken, - BSR, + BSRb, + BSRw, JSRJMPAddressRegisterIndirect, JSRJMPAddressRegisterIndirectWithDisplacement, @@ -814,8 +815,8 @@ void Processor void ProcessorBase::complete_bcc(bool take_branch, IntT Bccb_branch_not_taken : Bccw_branch_not_taken; } -void ProcessorBase::bsr(uint32_t offset) { - program_counter_.l = instruction_address_.l + offset + 2; -} - void ProcessorBase::did_bit_op(int bit_position) { dynamic_instruction_length_ = int(bit_position > 15); } diff --git a/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp b/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp index be3bb8c8c..c0ea0a942 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp @@ -155,7 +155,6 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController { inline void did_update_status(); template void complete_bcc(bool, IntT); inline void complete_dbcc(bool, bool, int16_t); - inline void bsr(uint32_t); inline void move_to_usp(uint32_t); inline void move_from_usp(uint32_t &); inline void tas(Preinstruction, uint32_t); @@ -167,6 +166,7 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController { template void movem_toM(Preinstruction, uint32_t, uint32_t) {} template void movem_toR(Preinstruction, uint32_t, uint32_t) {} void jsr(uint32_t) {} + void bsr(uint32_t) {} void jmp(uint32_t) {} inline void pea(uint32_t) {} inline void link(Preinstruction, uint32_t) {} From 22714b8c7f33e7d38b92563247993663694270d8 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 16:32:26 -0400 Subject: [PATCH 09/17] Capture state at instruction end, for potential inspection. --- OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp index 650d79641..dc1e1eede 100644 --- a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp +++ b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp @@ -55,6 +55,9 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { void will_perform(uint32_t, uint16_t) { --instructions_remaining_; + if(!instructions_remaining_) { + captured_state_ = m68000_.get_state(); + } } void run_for_instructions(int count) { @@ -120,7 +123,7 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { } CPU::MC68000Mk2::State get_processor_state() { - return m68000_.get_state(); + return captured_state_; } void set_processor_state(const CPU::MC68000Mk2::State &state) { @@ -145,6 +148,7 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { int instructions_remaining_; HalfCycles duration_; bool has_run_ = false; + CPU::MC68000Mk2::State captured_state_; }; #endif /* TestRunner68000_h */ From 06f3c716f5d85bed78d016497b62d36f6dd3589d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 16:47:41 -0400 Subject: [PATCH 10/17] Make better effort to establish initial state. --- OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp index dc1e1eede..12990751d 100644 --- a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp +++ b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp @@ -54,6 +54,10 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { } void will_perform(uint32_t, uint16_t) { + if(!has_run_) { + m68000_.set_state(initial_state_); + } + --instructions_remaining_; if(!instructions_remaining_) { captured_state_ = m68000_.get_state(); @@ -78,9 +82,9 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { // If the 68000 hasn't run yet, build in the necessary // cycles to finish the reset program, and set the stored state. if(!has_run_) { - has_run_ = true; m68000_.run_for(HalfCycles(80)); duration_ -= HalfCycles(80); + has_run_ = true; } } @@ -127,6 +131,7 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { } void set_processor_state(const CPU::MC68000Mk2::State &state) { + initial_state_ = captured_state_ = state; m68000_.set_state(state); } @@ -148,7 +153,7 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { int instructions_remaining_; HalfCycles duration_; bool has_run_ = false; - CPU::MC68000Mk2::State captured_state_; + CPU::MC68000Mk2::State captured_state_, initial_state_; }; #endif /* TestRunner68000_h */ From 68b184885f05f5292ab5c048bb54c11b6ce2f4ae Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 16:54:25 -0400 Subject: [PATCH 11/17] Reapply only the status. --- OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp index 12990751d..66a00e4be 100644 --- a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp +++ b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp @@ -55,7 +55,11 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { void will_perform(uint32_t, uint16_t) { if(!has_run_) { - m68000_.set_state(initial_state_); + // Patch back in the status result, since reset will + // have affected that. + auto state = m68000_.get_state(); + state.registers.status = initial_state_.registers.status; + m68000_.set_state(state); } --instructions_remaining_; From 64491525b4b3f6fb74a7b4b9d6b34e7ebaaa2278 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 17:01:18 -0400 Subject: [PATCH 12/17] Work further to guess at caller's intention for set_state. Probably I should just eliminate the initial reset, somehow. --- OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp index 66a00e4be..7ddf28d62 100644 --- a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp +++ b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp @@ -55,11 +55,13 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { void will_perform(uint32_t, uint16_t) { if(!has_run_) { - // Patch back in the status result, since reset will - // have affected that. - auto state = m68000_.get_state(); - state.registers.status = initial_state_.registers.status; - m68000_.set_state(state); + // Reapply all of initial state except the program counter and stack pointers. + // Also copy the supervisor stack pointer to the user. + const auto state = m68000_.get_state(); + initial_state_.registers.program_counter = state.registers.program_counter; + initial_state_.registers.user_stack_pointer = state.registers.supervisor_stack_pointer; + initial_state_.registers.supervisor_stack_pointer = state.registers.supervisor_stack_pointer; + m68000_.set_state(initial_state_); } --instructions_remaining_; From 367ad8079ae3b78e73e71423c3a0ed403fc6474d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 20:22:05 -0400 Subject: [PATCH 13/17] Add a call to set register state with population of the prefetch. --- Processors/68000Mk2/68000Mk2.hpp | 9 ++++++++ .../Implementation/68000Mk2Implementation.hpp | 23 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/Processors/68000Mk2/68000Mk2.hpp b/Processors/68000Mk2/68000Mk2.hpp index 0df184870..f58777494 100644 --- a/Processors/68000Mk2/68000Mk2.hpp +++ b/Processors/68000Mk2/68000Mk2.hpp @@ -397,9 +397,18 @@ class Processor: private ProcessorBase { void run_for(HalfCycles duration); + /// @returns The current processor state. CPU::MC68000Mk2::State get_state(); + + /// Sets the current processor state. void set_state(const CPU::MC68000Mk2::State &); + /// Sets all registers to the values provided, fills the prefetch queue and ensures the + /// next action the processor will take is to decode whatever is in the queue. + /// + /// The queue is filled synchronously, during this call, causing calls to the bus handler. + void decode_from_state(const InstructionSet::M68k::RegisterSet &); + // TODO: bus ack/grant, halt, /// Sets the DTack line — @c true for active, @c false for inactive. diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index e6903141d..4f319391c 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -2615,6 +2615,29 @@ void Processor +void Processor::decode_from_state(const InstructionSet::M68k::RegisterSet ®isters) { + // Populate registers. + CPU::MC68000Mk2::State state; + state.registers = registers; + set_state(state); + + // Ensure the state machine will resume at decode. + state_ = Decode; + + // Fill the prefetch queue. + captured_interrupt_level_ = bus_interrupt_level_; + + read_program.value = &prefetch_.high; + bus_handler_.perform_bus_operation(read_program_announce, is_supervisor_); + bus_handler_.perform_bus_operation(read_program, is_supervisor_); + program_counter_.l += 2; + + read_program.value = &prefetch_.low; + bus_handler_.perform_bus_operation(read_program_announce, is_supervisor_); + bus_handler_.perform_bus_operation(read_program, is_supervisor_); + program_counter_.l += 2; +} } } From 866787c5d38240079c0c32f1586d513ca1efdba5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 May 2022 20:22:38 -0400 Subject: [PATCH 14/17] Make an effort to withdraw from the high-circuitous stuff of working around the reset sequence. --- .../Clock SignalTests/68000ArithmeticTests.mm | 16 ++-- .../Clock SignalTests/68000BitwiseTests.mm | 12 +-- .../68000ControlFlowTests.mm | 24 ++---- .../Mac/Clock SignalTests/68000MoveTests.mm | 30 +++----- .../Mac/Clock SignalTests/68000Tests.mm | 3 +- .../Mac/Clock SignalTests/TestRunner68000.hpp | 76 ++++++------------- 6 files changed, 55 insertions(+), 106 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm b/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm index d6ebc8d67..68e367051 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm @@ -741,10 +741,10 @@ @end @implementation M68000DIVSTests -- (void)performDIVS:(uint16_t)divisor d1:(uint32_t)d1 { +- (void)performDIVS:(uint16_t)divisor d1:(uint32_t)d1 sp:(uint32_t)sp { self.machine->set_program({ 0x83fc, divisor // DIVS #divisor, D1 - }); + }, sp); auto state = self.machine->get_processor_state(); state.registers.data[1] = d1; state.registers.status |= ConditionCode::AllConditions; @@ -753,6 +753,10 @@ self.machine->run_for_instructions(1); } +- (void)performDIVS:(uint16_t)divisor d1:(uint32_t)d1 { + [self performDIVS:divisor d1:d1]; +} + - (void)performDIVSOverflowTestDivisor:(uint16_t)divisor { [self performDIVS:divisor d1:0x4768f231]; @@ -871,7 +875,7 @@ - (void)testDIVS_12 { // DIVS.W #$af32, D1 - [self performDIVS:0xaf32 d1:0xe1d44]; + [self performDIVS:0xaf32 d1:0xe1d44 sp:0]; const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x39dcffd4); @@ -882,8 +886,7 @@ - (void)testDIVSException { // DIVS.W #0, D1 const uint32_t initial_sp = 0x5000; - self.machine->set_initial_stack_pointer(initial_sp); - [self performDIVS:0x0 d1:0x1fffffff]; + [self performDIVS:0x0 d1:0x1fffffff sp:initial_sp]; // Check register state.registers. const auto state = self.machine->get_processor_state(); @@ -1440,8 +1443,7 @@ - (void)testSUBb_PreDec { self.machine->set_program({ 0x9427 // SUB.b -(A7), D2 - }); - self.machine->set_initial_stack_pointer(0x2002); + }, 0x2002); auto state = self.machine->get_processor_state(); state.registers.data[2] = 0x9c40; *self.machine->ram_at(0x2000) = 0x2710; diff --git a/OSBindings/Mac/Clock SignalTests/68000BitwiseTests.mm b/OSBindings/Mac/Clock SignalTests/68000BitwiseTests.mm index a3dcd8420..0a9e85691 100644 --- a/OSBindings/Mac/Clock SignalTests/68000BitwiseTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000BitwiseTests.mm @@ -155,8 +155,7 @@ - (void)testANDb_PostInc_A7 { _machine->set_program({ 0xc61f // AND.B (A7)+, D3 - }); - _machine->set_initial_stack_pointer(0x3000); + }, 0x3000); auto state = _machine->get_processor_state(); state.registers.data[3] = 0x54fff856; *_machine->ram_at(0x3000) = 0x0053; @@ -1088,8 +1087,7 @@ - (void)testANDISR_supervisor { _machine->set_program({ 0x027c, 0x0700 // ANDI.W #$700, SR - }); - _machine->set_initial_stack_pointer(300); + }, 300); _machine->run_for_instructions(1); @@ -1214,8 +1212,7 @@ - (void)testEORISR_supervisor { _machine->set_program({ 0x0a7c, 0x0700 // EORI.W #$700, SR - }); - _machine->set_initial_stack_pointer(300); + }, 300); _machine->run_for_instructions(1); @@ -1432,8 +1429,7 @@ - (void)testORISR_supervisor { _machine->set_program({ 0x007c, 0x0700 // ORI.W #$700, SR - }); - _machine->set_initial_stack_pointer(300); + }, 300); _machine->run_for_instructions(1); diff --git a/OSBindings/Mac/Clock SignalTests/68000ControlFlowTests.mm b/OSBindings/Mac/Clock SignalTests/68000ControlFlowTests.mm index 5e9559171..f59d7a423 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ControlFlowTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ControlFlowTests.mm @@ -108,8 +108,7 @@ - (void)testBSRw { _machine->set_program({ 0x6100, 0x0006 // BSR.w $1008 - }); - _machine->set_initial_stack_pointer(0x3000); + }, 0x3000); _machine->run_for_instructions(1); @@ -126,8 +125,7 @@ - (void)testBSRb { _machine->set_program({ 0x6106 // BSR.b $1008 - }); - _machine->set_initial_stack_pointer(0x3000); + }, 0x3000); _machine->run_for_instructions(1); @@ -146,13 +144,12 @@ - (void)performCHKd1:(uint32_t)d1 d2:(uint32_t)d2 { _machine->set_program({ 0x4581 // CHK D1, D2 - }); + }, 0); auto state = _machine->get_processor_state(); state.registers.data[1] = d1; state.registers.data[2] = d2; state.registers.status |= ConditionCode::AllConditions; - _machine->set_initial_stack_pointer(0); _machine->set_processor_state(state); _machine->run_for_instructions(1); @@ -414,8 +411,7 @@ - (void)testJSR_PC { _machine->set_program({ 0x4eba, 0x000a // JSR (+a)PC ; JSR to $100c - }); - _machine->set_initial_stack_pointer(0x2000); + }, 0x2000); _machine->run_for_instructions(1); @@ -430,8 +426,7 @@ - (void)testJSR_XXXl { _machine->set_program({ 0x4eb9, 0x0000, 0x1008 // JSR ($1008).l - }); - _machine->set_initial_stack_pointer(0x2000); + }, 0x2000); _machine->run_for_instructions(1); @@ -458,8 +453,7 @@ - (void)testRTR { _machine->set_program({ 0x4e77 // RTR - }); - _machine->set_initial_stack_pointer(0x2000); + }, 0x2000); *_machine->ram_at(0x2000) = 0x7fff; *_machine->ram_at(0x2002) = 0; *_machine->ram_at(0x2004) = 0xc; @@ -478,8 +472,7 @@ - (void)testRTS { _machine->set_program({ 0x4e75 // RTS - }); - _machine->set_initial_stack_pointer(0x2000); + }, 0x2000); *_machine->ram_at(0x2000) = 0x0000; *_machine->ram_at(0x2002) = 0x000c; @@ -521,8 +514,7 @@ - (void)testTRAPV_taken { _machine->set_program({ 0x4e76 // TRAPV - }); - _machine->set_initial_stack_pointer(0x206); + }, 0x206); auto state = _machine->get_processor_state(); state.registers.status = 0x702; diff --git a/OSBindings/Mac/Clock SignalTests/68000MoveTests.mm b/OSBindings/Mac/Clock SignalTests/68000MoveTests.mm index 6704fd4ec..e0371b75d 100644 --- a/OSBindings/Mac/Clock SignalTests/68000MoveTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000MoveTests.mm @@ -292,10 +292,9 @@ - (void)testLINKA1_5 { _machine->set_program({ 0x4e51, 0x0005 // LINK a1, #5 - }); + }, 0x22222222); auto state = _machine->get_processor_state(); state.registers.address[1] = 0x11111111; - _machine->set_initial_stack_pointer(0x22222222); _machine->set_processor_state(state); _machine->run_for_instructions(1); @@ -311,8 +310,7 @@ - (void)testLINKA7_5 { _machine->set_program({ 0x4e57, 0x0005 // LINK a7, #5 - }); - _machine->set_initial_stack_pointer(0x22222222); + }, 0x22222222); _machine->run_for_instructions(1); @@ -326,10 +324,9 @@ - (void)testLINKA1_8000 { _machine->set_program({ 0x4e51, 0x8000 // LINK a1, #$8000 - }); + }, 0x22222222); auto state = _machine->get_processor_state(); state.registers.address[1] = 0x11111111; - _machine->set_initial_stack_pointer(0x22222222); _machine->set_processor_state(state); _machine->run_for_instructions(1); @@ -395,14 +392,13 @@ - (void)testMOVEMl_fromEverything { _machine->set_program({ 0x48e4, 0xffff // MOVEM.L D0-D7/A0-A7, -(A4) - }); + }, 0xffffffff); auto state = _machine->get_processor_state(); for(int c = 0; c < 8; ++c) state.registers.data[c] = (c+1) * 0x11111111; for(int c = 0; c < 7; ++c) state.registers.address[c] = ((c < 4) ? (c + 9) : (c + 8)) * 0x11111111; state.registers.address[4] = 0x4000; - _machine->set_initial_stack_pointer(0xffffffff); _machine->set_processor_state(state); _machine->run_for_instructions(1); @@ -995,10 +991,9 @@ - (void)testPEA_A1 { _machine->set_program({ 0x4851 // PEA (A1) - }); + }, 0x1996); auto state = _machine->get_processor_state(); state.registers.address[1] = 0x3000ffff; - _machine->set_initial_stack_pointer(0x1996); _machine->set_processor_state(state); _machine->run_for_instructions(1); @@ -1014,8 +1009,7 @@ - (void)testPEA_A7 { _machine->set_program({ 0x4857 // PEA (A7) - }); - _machine->set_initial_stack_pointer(0x1012); + }, 0x1012); _machine->run_for_instructions(1); @@ -1029,8 +1023,7 @@ - (void)testPEA_4A7 { _machine->set_program({ 0x486f, 0x0004 // PEA 4(A7) - }); - _machine->set_initial_stack_pointer(0x1012); + }, 0x1012); _machine->run_for_instructions(1); @@ -1044,8 +1037,7 @@ - (void)testPEA_XXXw { _machine->set_program({ 0x4878, 0x3000 // PEA ($3000).w - }); - _machine->set_initial_stack_pointer(0x1996); + }, 0x1996); _machine->run_for_instructions(1); @@ -1059,8 +1051,7 @@ - (void)testPEA_XXXl { _machine->set_program({ 0x4879, 0x1234, 0x5678 // PEA ($12345678) - }); - _machine->set_initial_stack_pointer(0x1996); + }, 0x1996); _machine->run_for_instructions(1); @@ -1235,8 +1226,7 @@ - (void)testUNLINK_A7 { _machine->set_program({ 0x4e5f // UNLNK A7 - }); - _machine->set_initial_stack_pointer(0x3000); + }, 0x3000); *_machine->ram_at(0x3000) = 0x0000; *_machine->ram_at(0x3002) = 0x4000; diff --git a/OSBindings/Mac/Clock SignalTests/68000Tests.mm b/OSBindings/Mac/Clock SignalTests/68000Tests.mm index 18cbe8e51..565b3e85e 100644 --- a/OSBindings/Mac/Clock SignalTests/68000Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000Tests.mm @@ -148,8 +148,7 @@ class CPU::MC68000::ProcessorStorageTests { 0x82C0, // DIVU; location 0x404 /* Next instruction would be at 0x406 */ - }); - _machine->set_initial_stack_pointer(0x1000); + }, 0x1000); _machine->run_for_instructions(4); diff --git a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp index 7ddf28d62..633e00366 100644 --- a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp +++ b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp @@ -23,77 +23,48 @@ using namespace InstructionSet::M68k; */ class RAM68000: public CPU::MC68000Mk2::BusHandler { public: - RAM68000() : m68000_(*this) { - // Setup the /RESET vector. - ram_[0] = 0; - ram_[1] = 0x206; // Supervisor stack pointer. - ram_[2] = 0; - ram_[3] = 0x1000; // Initial PC. - - // Ensure the condition codes start unset. - auto state = get_processor_state(); - state.registers.status &= ~ConditionCode::AllConditions; - set_processor_state(state); - } + RAM68000() : m68000_(*this) {} uint32_t initial_pc() const { return 0x1000; } - void set_program(const std::vector &program) { + void set_program( + const std::vector &program, + uint32_t stack_pointer = 0x206) { memcpy(&ram_[0x1000 >> 1], program.data(), program.size() * sizeof(uint16_t)); - // Add a NOP suffix, to avoid corrupting flags should the attempt to - // run for a certain number of instructions overrun. - ram_[(0x1000 >> 1) + program.size()] = 0x4e71; - } - - void set_initial_stack_pointer(uint32_t sp) { - ram_[0] = sp >> 16; - ram_[1] = sp & 0xffff; + // Ensure the condition codes start unset and set the initial program counter + // and supervisor stack pointer. + auto state = get_processor_state(); + state.registers.status &= ~ConditionCode::AllConditions; + state.registers.program_counter = initial_pc(); + state.registers.supervisor_stack_pointer = stack_pointer; + set_processor_state(state); } void will_perform(uint32_t, uint16_t) { - if(!has_run_) { - // Reapply all of initial state except the program counter and stack pointers. - // Also copy the supervisor stack pointer to the user. - const auto state = m68000_.get_state(); - initial_state_.registers.program_counter = state.registers.program_counter; - initial_state_.registers.user_stack_pointer = state.registers.supervisor_stack_pointer; - initial_state_.registers.supervisor_stack_pointer = state.registers.supervisor_stack_pointer; - m68000_.set_state(initial_state_); - } - --instructions_remaining_; if(!instructions_remaining_) { - captured_state_ = m68000_.get_state(); + throw StopException(); } } void run_for_instructions(int count) { - instructions_remaining_ = count + (has_run_ ? 0 : 1); - finish_reset_if_needed(); + instructions_remaining_ = count; + if(!instructions_remaining_) return; - while(instructions_remaining_) { - run_for(HalfCycles(2)); - } + try { + while(true) { + run_for(HalfCycles(2000)); + } + } catch (const StopException &) {} } void run_for(HalfCycles cycles) { - finish_reset_if_needed(); m68000_.run_for(cycles); } - void finish_reset_if_needed() { - // If the 68000 hasn't run yet, build in the necessary - // cycles to finish the reset program, and set the stored state. - if(!has_run_) { - m68000_.run_for(HalfCycles(80)); - duration_ -= HalfCycles(80); - has_run_ = true; - } - } - uint16_t *ram_at(uint32_t address) { return &ram_[(address >> 1) % ram_.size()]; } @@ -133,12 +104,11 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { } CPU::MC68000Mk2::State get_processor_state() { - return captured_state_; + return m68000_.get_state(); } void set_processor_state(const CPU::MC68000Mk2::State &state) { - initial_state_ = captured_state_ = state; - m68000_.set_state(state); + m68000_.decode_from_state(state.registers); } auto &processor() { @@ -154,12 +124,12 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { } private: + struct StopException {}; + CPU::MC68000Mk2::Processor m68000_; std::array ram_{}; int instructions_remaining_; HalfCycles duration_; - bool has_run_ = false; - CPU::MC68000Mk2::State captured_state_, initial_state_; }; #endif /* TestRunner68000_h */ From f3c0c62c79cd1508630f5279065231c376914de8 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 26 May 2022 07:52:14 -0400 Subject: [PATCH 15/17] Switch register-setting interface. --- .../Clock SignalTests/68000ArithmeticTests.mm | 600 ++++++++---------- .../Mac/Clock SignalTests/68000BCDTests.mm | 117 ++-- .../Clock SignalTests/68000BitwiseTests.mm | 540 +++++++--------- .../68000ControlFlowTests.mm | 56 +- .../Mac/Clock SignalTests/68000MoveTests.mm | 550 ++++++++-------- .../Clock SignalTests/68000RollShiftTests.mm | 489 +++++++------- .../Mac/Clock SignalTests/68000Tests.mm | 10 +- .../Mac/Clock SignalTests/TestRunner68000.hpp | 27 +- 8 files changed, 1096 insertions(+), 1293 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm b/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm index 68e367051..ec2e70d0f 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm @@ -42,12 +42,12 @@ self.machine->set_program({ 0x0602, 0xff // ADD.B #$ff, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = 0x9ae; - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0x9ae; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Carry | ConditionCode::Negative | ConditionCode::Extend); XCTAssertEqual(state.registers.data[2], 0x9ad); XCTAssertEqual(8, self.machine->get_cycle_count()); @@ -57,12 +57,12 @@ self.machine->set_program({ 0xd43c, 0x82 // ADD.B #$82, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = 0x82; - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0x82; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Overflow | ConditionCode::Carry | ConditionCode::Extend); XCTAssertEqual(state.registers.data[2], 0x04); XCTAssertEqual(8, self.machine->get_cycle_count()); @@ -72,13 +72,13 @@ self.machine->set_program({ 0xd538, 0x3000 // ADD.B D2, ($3000).W }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = 0x82; + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0x82; + }); *self.machine->ram_at(0x3000) = 0x8200; - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Overflow | ConditionCode::Carry | ConditionCode::Extend); XCTAssertEqual(state.registers.data[2], 0x82); XCTAssertEqual(*self.machine->ram_at(0x3000), 0x0400); @@ -89,12 +89,12 @@ self.machine->set_program({ 0xd442 // ADD.W D2, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = 0x3e8; - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0x3e8; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[2], 0x7D0); XCTAssertEqual(4, self.machine->get_cycle_count()); } @@ -103,16 +103,15 @@ self.machine->set_program({ 0xd59a // ADD.L D2, (A2)+ }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = 0xb2d05e00; - state.registers.address[2] = 0x2000; + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0xb2d05e00; + registers.address[2] = 0x2000; + }); *self.machine->ram_at(0x2000) = 0x7735; *self.machine->ram_at(0x2002) = 0x9400; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[2], 0xb2d05e00); XCTAssertEqual(*self.machine->ram_at(0x2000), 0x2a05); XCTAssertEqual(*self.machine->ram_at(0x2002), 0xf200); @@ -124,16 +123,15 @@ self.machine->set_program({ 0xd462 // ADD.W -(A2), D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = 0xFFFF0000; - state.registers.address[2] = 0x2002; + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0xFFFF0000; + registers.address[2] = 0x2002; + }); *self.machine->ram_at(0x2000) = 0; *self.machine->ram_at(0x2002) = 0xffff; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[2], 0xFFFF0000); XCTAssertEqual(state.registers.address[2], 0x2000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero); @@ -149,14 +147,13 @@ self.machine->set_program({ 0xd481 // ADD.l D1, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0xfe35aab0; - state.registers.data[2] = 0x012557ac; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xfe35aab0; + registers.data[2] = 0x012557ac; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xfe35aab0); XCTAssertEqual(state.registers.data[2], 0xff5b025c); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); @@ -175,14 +172,13 @@ self.machine->set_program({ 0xd5fc, 0x1234, 0x5678 // ADDA.L #$12345678, A2 }); - auto state = self.machine->get_processor_state(); - state.registers.address[2] = 0xae43ab1d; - state.registers.status = ConditionCode::AllConditions; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xae43ab1d; + registers.status = ConditionCode::AllConditions; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0xc0780195); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::AllConditions); } @@ -191,14 +187,13 @@ self.machine->set_program({ 0xd4fc, 0x5678 // ADDA.W #$5678, A2 }); - auto state = self.machine->get_processor_state(); - state.registers.address[2] = 0xae43ab1d; - state.registers.status = ConditionCode::AllConditions; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xae43ab1d; + registers.status = ConditionCode::AllConditions; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0xae440195); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::AllConditions); } @@ -207,14 +202,13 @@ self.machine->set_program({ 0xd4fc, 0xf678 // ADDA.W #$f678, A2 }); - auto state = self.machine->get_processor_state(); - state.registers.address[2] = 0xae43ab1d; - state.registers.status = ConditionCode::AllConditions; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xae43ab1d; + registers.status = ConditionCode::AllConditions; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0xae43a195); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::AllConditions); } @@ -223,14 +217,13 @@ self.machine->set_program({ 0xd4fc, 0xf000 // ADDA.W #$f000, A2 }); - auto state = self.machine->get_processor_state(); - state.registers.status = ConditionCode::AllConditions; - state.registers.address[2] = 0; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.status = ConditionCode::AllConditions; + registers.address[2] = 0; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0xfffff000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::AllConditions); } @@ -239,16 +232,15 @@ self.machine->set_program({ 0xd5e2 // ADDA.L -(A2), A2 }); - auto state = self.machine->get_processor_state(); - state.registers.status = ConditionCode::AllConditions; - state.registers.address[2] = 0x2004; + self.machine->set_registers([=](auto ®isters) { + registers.status = ConditionCode::AllConditions; + registers.address[2] = 0x2004; + }); *self.machine->ram_at(0x2000) = 0x7002; *self.machine->ram_at(0x2002) = 0; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0x70022000); XCTAssertEqual(*self.machine->ram_at(0x2000), 0x7002); XCTAssertEqual(*self.machine->ram_at(0x2002), 0x0000); @@ -267,15 +259,14 @@ self.machine->set_program({ 0xd581 // ADDX.l D1, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x12345678; - state.registers.data[2] = 0x12345678; - state.registers.status |= ConditionCode::AllConditions; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x12345678; + registers.data[2] = 0x12345678; + registers.status |= ConditionCode::AllConditions; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x12345678); XCTAssertEqual(state.registers.data[2], 0x2468acf1); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -286,14 +277,13 @@ self.machine->set_program({ 0xd501 // ADDX.b D1, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x80; - state.registers.data[2] = 0x8080; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x80; + registers.data[2] = 0x8080; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x80); XCTAssertEqual(state.registers.data[2], 0x8000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Carry | ConditionCode::Overflow | ConditionCode::Extend); @@ -304,15 +294,14 @@ self.machine->set_program({ 0xd541 // ADDX.w D1, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x1ffff; - state.registers.data[2] = 0x18080; - state.registers.status |= ConditionCode::AllConditions; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x1ffff; + registers.data[2] = 0x18080; + registers.status |= ConditionCode::AllConditions; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x1ffff); XCTAssertEqual(state.registers.data[2], 0x18080); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Carry | ConditionCode::Negative | ConditionCode::Extend); @@ -323,18 +312,17 @@ self.machine->set_program({ 0xd389 // ADDX.l -(A1), -(A1) }); - auto state = self.machine->get_processor_state(); - state.registers.address[1] = 0x3000; - state.registers.status |= ConditionCode::AllConditions; + self.machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x3000; + registers.status |= ConditionCode::AllConditions; + }); *self.machine->ram_at(0x2ff8) = 0x1000; *self.machine->ram_at(0x2ffa) = 0x0000; *self.machine->ram_at(0x2ffc) = 0x7000; *self.machine->ram_at(0x2ffe) = 0x1ff1; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x2ff8); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Overflow); XCTAssertEqual(*self.machine->ram_at(0x2ff8), 0x8000); @@ -356,13 +344,12 @@ self.machine->set_program({ 0x0681, 0x1111, 0x1111 // ADDI.l #$11111111, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x300021b3; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x300021b3; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x411132C4); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(16, self.machine->get_cycle_count()); @@ -394,13 +381,12 @@ self.machine->set_program({ 0x5e81 // ADDQ.l #$7, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0xffffffff; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xffffffff; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x6); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry); XCTAssertEqual(8, self.machine->get_cycle_count()); @@ -410,13 +396,12 @@ self.machine->set_program({ 0x5641 // ADDQ.W #$3, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0xfffffffe; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xfffffffe; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xffff0001); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry); XCTAssertEqual(4, self.machine->get_cycle_count()); @@ -426,13 +411,12 @@ self.machine->set_program({ 0x5649 // ADDQ.W #$3, A1 }); - auto state = self.machine->get_processor_state(); - state.registers.address[1] = 0xfffffffe; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.address[1] = 0xfffffffe; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 1); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(8, self.machine->get_cycle_count()); @@ -464,14 +448,13 @@ self.machine->set_program({ opcode }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x1234567f; - state.registers.data[2] = 0x12345680; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x1234567f; + registers.data[2] = 0x12345680; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x1234567f); XCTAssertEqual(state.registers.data[2], 0x12345680); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, flags); @@ -490,14 +473,13 @@ self.machine->set_program({ 0xb242 // CMP.W D2, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = d1; - state.registers.data[2] = d2; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = d1; + registers.data[2] = d2; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); XCTAssertEqual(state.registers.data[2], d2); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, flags); @@ -516,14 +498,13 @@ self.machine->set_program({ 0xb282 // CMP.l D2, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x12347002; - state.registers.data[2] = 0x12348004; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x12347002; + registers.data[2] = 0x12348004; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x12347002); XCTAssertEqual(state.registers.data[2], 0x12348004); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Carry); @@ -542,14 +523,13 @@ self.machine->set_program({ 0xb5c1 // CMPA.l D1, A2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = d1; - state.registers.address[2] = a2; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = d1; + registers.address[2] = a2; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); XCTAssertEqual(state.registers.address[2], a2); XCTAssertEqual(6, self.machine->get_cycle_count()); @@ -580,14 +560,13 @@ self.machine->set_program({ 0xb4c1 // CMPA.w D1, A2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = d1; - state.registers.address[2] = a2; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = d1; + registers.address[2] = a2; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); XCTAssertEqual(state.registers.address[2], a2); XCTAssertEqual(6, self.machine->get_cycle_count()); @@ -619,13 +598,12 @@ self.machine->set_program({ 0x0c41, 0xffff // CMPI.W #$ffff, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0xfff2ffff; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xfff2ffff; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xfff2ffff); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero); XCTAssertEqual(8, self.machine->get_cycle_count()); @@ -635,13 +613,12 @@ self.machine->set_program({ 0x0c81, 0x8000, 0x0000 // CMPI.L #$80000000, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x7fffffff; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x7fffffff; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x7fffffff); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Carry); XCTAssertEqual(14, self.machine->get_cycle_count()); @@ -651,13 +628,12 @@ self.machine->set_program({ 0x0c01, 0x0090 // CMPI.B #$90, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x8f; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x8f; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x8f); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Carry); XCTAssertEqual(8, self.machine->get_cycle_count()); @@ -675,18 +651,17 @@ self.machine->set_program({ 0xb389 // CMPM.L (A1)+, (A1)+ }); - auto state = self.machine->get_processor_state(); - state.registers.address[1] = 0x3000; - state.registers.status |= ConditionCode::AllConditions; + self.machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x3000; + registers.status |= ConditionCode::AllConditions; + }); *self.machine->ram_at(0x3000) = 0x7000; *self.machine->ram_at(0x3002) = 0x1ff1; *self.machine->ram_at(0x3004) = 0x1000; *self.machine->ram_at(0x3006) = 0x0000; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x3008); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Extend | ConditionCode::Carry); XCTAssertEqual(20, self.machine->get_cycle_count()); @@ -696,17 +671,16 @@ self.machine->set_program({ 0xb549 // CMPM.w (A1)+, (A2)+ }); - auto state = self.machine->get_processor_state(); - state.registers.address[1] = 0x3000; - state.registers.address[2] = 0x3002; - state.registers.status |= ConditionCode::AllConditions; + self.machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x3000; + registers.address[2] = 0x3002; + registers.status |= ConditionCode::AllConditions; + }); *self.machine->ram_at(0x3000) = 0; *self.machine->ram_at(0x3002) = 0; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x3002); XCTAssertEqual(state.registers.address[2], 0x3004); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero | ConditionCode::Extend); @@ -717,16 +691,15 @@ self.machine->set_program({ 0xb509 // CMPM.b (A1)+, (A2)+ }); - auto state = self.machine->get_processor_state(); - state.registers.address[1] = 0x3000; - state.registers.address[2] = 0x3001; - state.registers.status |= ConditionCode::AllConditions; + self.machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x3000; + registers.address[2] = 0x3001; + registers.status |= ConditionCode::AllConditions; + }); *self.machine->ram_at(0x3000) = 0x807f; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x3001); XCTAssertEqual(state.registers.address[2], 0x3002); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow); @@ -745,11 +718,10 @@ self.machine->set_program({ 0x83fc, divisor // DIVS #divisor, D1 }, sp); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = d1; - state.registers.status |= ConditionCode::AllConditions; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = d1; + registers.status |= ConditionCode::AllConditions; + }); self.machine->run_for_instructions(1); } @@ -919,11 +891,10 @@ self.machine->set_program({ 0x82fc, divisor // DIVU #$eef0, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = d1; - state.registers.status |= ConditionCode::AllConditions; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = d1; + registers.status |= ConditionCode::AllConditions; + }); self.machine->run_for_instructions(1); } @@ -978,11 +949,10 @@ 0x4883 // EXT.W D3 }); - auto state = self.machine->get_processor_state(); - state.registers.data[3] = d3; - state.registers.status = 0x13; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[3] = d3; + registers.status = 0x13; + }); self.machine->run_for_instructions(1); XCTAssertEqual(4, self.machine->get_cycle_count()); @@ -1017,16 +987,15 @@ 0x48c3 // EXT.L D3 }); - auto state = self.machine->get_processor_state(); - state.registers.data[3] = 0x1234f6f0; - state.registers.status = 0x13; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[3] = 0x1234f6f0; + registers.status = 0x13; + }); self.machine->run_for_instructions(1); XCTAssertEqual(4, self.machine->get_cycle_count()); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0xfffff6f0); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Negative); } @@ -1043,12 +1012,11 @@ self.machine->set_program({ 0xc5c1 // MULS D1, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = d1; - state.registers.data[2] = d2; - state.registers.status = ccr; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = d1; + registers.data[2] = d2; + registers.status = ccr; + }); self.machine->run_for_instructions(1); } @@ -1056,11 +1024,10 @@ self.machine->set_program({ 0xc5fc, constant // MULS #constant, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = d2; - state.registers.status = ConditionCode::Carry | ConditionCode::Extend | ConditionCode::Overflow; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = d2; + registers.status = ConditionCode::Carry | ConditionCode::Extend | ConditionCode::Overflow; + }); self.machine->run_for_instructions(1); } @@ -1124,12 +1091,11 @@ self.machine->set_program({ 0xc4c1 // MULU D1, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = d1; - state.registers.data[2] = d2; - state.registers.status |= ccr; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = d1; + registers.data[2] = d2; + registers.status |= ccr; + }); self.machine->run_for_instructions(1); } @@ -1156,14 +1122,13 @@ self.machine->set_program({ 0xc4fc, 0xffff // MULU.W #$ffff, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = 0xffff; - state.registers.status |= ConditionCode::Extend | ConditionCode::Overflow | ConditionCode::Carry; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0xffff; + registers.status |= ConditionCode::Extend | ConditionCode::Overflow | ConditionCode::Carry; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(state.registers.data[2], 0xfffe0001); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Negative); XCTAssertEqual(74, self.machine->get_cycle_count()); @@ -1181,10 +1146,9 @@ self.machine->set_program({ 0x4400 // NEG.b D0 }); - auto state = self.machine->get_processor_state(); - state.registers.data[0] = value; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[0] = value; + }); self.machine->run_for_instructions(1); XCTAssertEqual(4, self.machine->get_cycle_count()); @@ -1218,13 +1182,12 @@ self.machine->set_program({ 0x4440 // NEG.w D0 }); - auto state = self.machine->get_processor_state(); - state.registers.data[0] = 0x12348000; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[0] = 0x12348000; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(4, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.data[0], 0x12348000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Extend | ConditionCode::Carry); @@ -1234,10 +1197,9 @@ self.machine->set_program({ 0x4480 // NEG.l D0 }); - auto state = self.machine->get_processor_state(); - state.registers.data[0] = value; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[0] = value; + }); self.machine->run_for_instructions(1); XCTAssertEqual(6, self.machine->get_cycle_count()); @@ -1287,11 +1249,10 @@ self.machine->set_program({ 0x4000 // NEGX.b D0 }); - auto state = self.machine->get_processor_state(); - state.registers.data[0] = value; - state.registers.status |= ConditionCode::Extend; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[0] = value; + registers.status |= ConditionCode::Extend; + }); self.machine->run_for_instructions(1); XCTAssertEqual(4, self.machine->get_cycle_count()); @@ -1325,14 +1286,13 @@ self.machine->set_program({ 0x4040 // NEGX.w D0 }); - auto state = self.machine->get_processor_state(); - state.registers.data[0] = 0x12348000; - state.registers.status |= ConditionCode::Extend; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[0] = 0x12348000; + registers.status |= ConditionCode::Extend; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(4, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.data[0], 0x12347fff); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry); @@ -1342,11 +1302,10 @@ self.machine->set_program({ 0x4080 // NEGX.l D0 }); - auto state = self.machine->get_processor_state(); - state.registers.data[0] = value; - state.registers.status |= ConditionCode::Extend; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[0] = value; + registers.status |= ConditionCode::Extend; + }); self.machine->run_for_instructions(1); XCTAssertEqual(6, self.machine->get_cycle_count()); @@ -1372,15 +1331,14 @@ self.machine->set_program({ 0x40b9, 0x0000, 0x3000 // NEGX.L ($3000).L }); + self.machine->set_registers([=](auto ®isters) { + registers.status |= ConditionCode::Extend; + }); *self.machine->ram_at(0x3000) = 0xf001; *self.machine->ram_at(0x3002) = 0x2311; - auto state = self.machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(28, self.machine->get_cycle_count()); XCTAssertEqual(*self.machine->ram_at(0x3000), 0x0ffe); XCTAssertEqual(*self.machine->ram_at(0x3002), 0xdcee); @@ -1399,10 +1357,9 @@ self.machine->set_program({ 0x0402, value // SUB.b #value, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = d2; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = d2; + }); self.machine->run_for_instructions(1); XCTAssertEqual(8, self.machine->get_cycle_count()); @@ -1444,14 +1401,13 @@ self.machine->set_program({ 0x9427 // SUB.b -(A7), D2 }, 0x2002); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = 0x9c40; + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0x9c40; + }); *self.machine->ram_at(0x2000) = 0x2710; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(10, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.data[2], 0x9c19); XCTAssertEqual(state.registers.stack_pointer(), 0x2000); @@ -1463,14 +1419,13 @@ self.machine->set_program({ 0x9578, 0x3000 // SUB.w D2, ($3000).w }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = 0x2711; + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0x2711; + }); *self.machine->ram_at(0x3000) = 0x759f; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(16, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.data[2], 0x2711); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -1481,16 +1436,15 @@ self.machine->set_program({ 0x95ab, 0x0004 // SUB.l D2, 4(A3) }); - auto state = self.machine->get_processor_state(); - state.registers.data[2] = 0x45fd5ab4; - state.registers.address[3] = 0x3000; + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0x45fd5ab4; + registers.address[3] = 0x3000; + }); *self.machine->ram_at(0x3004) = 0x327a; *self.machine->ram_at(0x3006) = 0x4ef3; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(24, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.data[2], 0x45fd5ab4); XCTAssertEqual(state.registers.address[3], 0x3000); @@ -1511,14 +1465,13 @@ self.machine->set_program({ 0x95fc, 0x1234, 0x5678 // SUBA.l #$12345678, A2 }); - auto state = self.machine->get_processor_state(); - state.registers.address[2] = 0xae43ab1d; - state.registers.status |= ConditionCode::AllConditions; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xae43ab1d; + registers.status |= ConditionCode::AllConditions; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(16, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.address[2], 0x9c0f54a5); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::AllConditions); @@ -1528,13 +1481,12 @@ self.machine->set_program({ 0x94fc, 0x5678 // SUBA.w #$5678, A2 }); - auto state = self.machine->get_processor_state(); - state.registers.address[2] = 0xae43ab1d; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xae43ab1d; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(12, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.address[2], 0xae4354a5); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -1544,13 +1496,12 @@ self.machine->set_program({ 0x94fc, 0xf678 // SUBA.w #$5678, A2 }); - auto state = self.machine->get_processor_state(); - state.registers.address[2] = 0xae43ab1d; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xae43ab1d; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(12, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.address[2], 0xae43b4a5); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -1560,15 +1511,14 @@ self.machine->set_program({ 0x95e2 // SUBA.l -(A2), A2 }); - auto state = self.machine->get_processor_state(); - state.registers.address[2] = 0x2004; + self.machine->set_registers([=](auto ®isters) { + registers.address[2] = 0x2004; + }); *self.machine->ram_at(0x2000) = 0x7002; *self.machine->ram_at(0x2002) = 0x0000; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(16, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.address[2], 0x8ffe2000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -1586,13 +1536,12 @@ self.machine->set_program({ 0x0481, 0xf111, 0x1111 // SUBI.L #$f1111111, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x300021b3; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x300021b3; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(16, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.data[1], 0x3eef10a2); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Carry | ConditionCode::Extend); @@ -1612,13 +1561,12 @@ self.machine->set_program({ 0x5f81 // SUBQ.L #$7, D1 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0xffffffff; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xffffffff; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(8, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.data[1], 0xfffffff8); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); @@ -1628,13 +1576,12 @@ self.machine->set_program({ 0x5f49 // SUBQ.W #$7, A1 }); - auto state = self.machine->get_processor_state(); - state.registers.address[1] = 0xffff0001; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.address[1] = 0xffff0001; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(8, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.address[1], 0xfffefffa); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -1666,15 +1613,14 @@ self.machine->set_program({ 0x9581 // SUBX.l D1, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x12345678; - state.registers.data[2] = 0x12345678; - state.registers.status |= ConditionCode::AllConditions; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x12345678; + registers.data[2] = 0x12345678; + registers.status |= ConditionCode::AllConditions; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(8, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.data[1], 0x12345678); XCTAssertEqual(state.registers.data[2], 0xffffffff); @@ -1685,14 +1631,13 @@ self.machine->set_program({ 0x9501 // SUBX.b D1, D2 }); - auto state = self.machine->get_processor_state(); - state.registers.data[1] = 0x80; - state.registers.data[2] = 0x01; - - self.machine->set_processor_state(state); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x80; + registers.data[2] = 0x01; + }); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(4, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.data[1], 0x80); XCTAssertEqual(state.registers.data[2], 0x81); @@ -1703,18 +1648,17 @@ self.machine->set_program({ 0x9389 // SUBX.l -(A1), -(A1) }); - auto state = self.machine->get_processor_state(); - state.registers.address[1] = 0x3000; + self.machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x3000; + registers.status |= ConditionCode::AllConditions; + }); *self.machine->ram_at(0x2ff8) = 0x1000; *self.machine->ram_at(0x2ffa) = 0x0000; *self.machine->ram_at(0x2ffc) = 0x7000; *self.machine->ram_at(0x2ffe) = 0x1ff1; - state.registers.status |= ConditionCode::AllConditions; - - self.machine->set_processor_state(state); self.machine->run_for_instructions(1); - state = self.machine->get_processor_state(); + const auto state = self.machine->get_processor_state(); XCTAssertEqual(30, self.machine->get_cycle_count()); XCTAssertEqual(state.registers.address[1], 0x2ff8); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Negative ); diff --git a/OSBindings/Mac/Clock SignalTests/68000BCDTests.mm b/OSBindings/Mac/Clock SignalTests/68000BCDTests.mm index 84cff91bc..6396cc318 100644 --- a/OSBindings/Mac/Clock SignalTests/68000BCDTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000BCDTests.mm @@ -32,13 +32,13 @@ _machine->set_program({ 0xc302, // ABCD D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x1234567a; - state.registers.data[2] = 0xf745ff78; - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[1] = 0x1234567a; + registers.data[2] = 0xf745ff78; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssert(state.registers.status & ConditionCode::Carry); XCTAssertEqual(state.registers.data[1], 0x12345658); XCTAssertEqual(state.registers.data[2], 0xf745ff78); @@ -48,14 +48,14 @@ _machine->set_program({ 0xc302, // ABCD D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x12345600; - state.registers.data[2] = 0x12345600; - state.registers.status = ConditionCode::Zero; - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[1] = 0x12345600; + registers.data[2] = 0x12345600; + registers.status = ConditionCode::Zero; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssert(state.registers.status & ConditionCode::Zero); XCTAssertEqual(state.registers.data[1], 0x12345600); XCTAssertEqual(state.registers.data[2], 0x12345600); @@ -65,14 +65,14 @@ _machine->set_program({ 0xc302, // ABCD D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x12345645; - state.registers.data[2] = 0x12345654; - state.registers.status = ConditionCode::Zero; - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[1] = 0x12345645; + registers.data[2] = 0x12345654; + registers.status = ConditionCode::Zero; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssert(state.registers.status & ConditionCode::Negative); XCTAssertEqual(state.registers.data[1], 0x12345699); XCTAssertEqual(state.registers.data[2], 0x12345654); @@ -82,14 +82,14 @@ _machine->set_program({ 0xc302, // ABCD D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x12345645; - state.registers.data[2] = 0x12345654; - state.registers.status = ConditionCode::Extend; - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[1] = 0x12345645; + registers.data[2] = 0x12345654; + registers.status = ConditionCode::Extend; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssert(state.registers.status & ConditionCode::Carry); XCTAssertEqual(state.registers.data[1], 0x12345600); XCTAssertEqual(state.registers.data[2], 0x12345654); @@ -99,14 +99,14 @@ _machine->set_program({ 0xc302, // ABCD D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x1234563e; - state.registers.data[2] = 0x1234563e; - state.registers.status = ConditionCode::Extend; - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[1] = 0x1234563e; + registers.data[2] = 0x1234563e; + registers.status = ConditionCode::Extend; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssert(state.registers.status & ConditionCode::Overflow); XCTAssertEqual(state.registers.data[1], 0x12345683); XCTAssertEqual(state.registers.data[2], 0x1234563e); @@ -116,17 +116,16 @@ _machine->set_program({ 0xc30a, // ABCD -(A2), -(A1) }); + _machine->set_registers([=](auto ®isters){ + registers.address[1] = 0x3001; + registers.address[2] = 0x4001; + registers.status = ConditionCode::Extend; + }); *_machine->ram_at(0x3000) = 0xa200; *_machine->ram_at(0x4000) = 0x1900; - - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x3001; - state.registers.address[2] = 0x4001; - state.registers.status = ConditionCode::Extend; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssert(state.registers.status & ConditionCode::Carry); XCTAssert(state.registers.status & ConditionCode::Extend); XCTAssertEqual(state.registers.address[1], 0x3000); @@ -139,15 +138,14 @@ _machine->set_program({ 0xc309, // ABCD -(A1), -(A1) }); + _machine->set_registers([=](auto ®isters){ + registers.address[1] = 0x3002; + registers.status = ConditionCode::Extend; + }); *_machine->ram_at(0x3000) = 0x19a2; - - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x3002; - state.registers.status = ConditionCode::Extend; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssert(state.registers.status & ConditionCode::Carry); XCTAssert(state.registers.status & ConditionCode::Extend); XCTAssertEqual(state.registers.address[1], 0x3000); @@ -160,11 +158,10 @@ _machine->set_program({ 0x4801 // NBCD D1 }); - auto state = _machine->get_processor_state(); - state.registers.status |= ccr; - state.registers.data[1] = d1; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.status |= ccr; + registers.data[1] = d1; + }); _machine->run_for_instructions(1); XCTAssertEqual(6, _machine->get_cycle_count()); @@ -222,15 +219,14 @@ _machine->set_program({ 0x8302 // SBCD D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.status |= ccr; - state.registers.data[1] = d1; - state.registers.data[2] = d2; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.status |= ccr; + registers.data[1] = d1; + registers.data[2] = d2; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(6, _machine->get_cycle_count()); XCTAssertEqual(state.registers.data[2], d2); } @@ -273,15 +269,14 @@ }); *_machine->ram_at(0x3000) = 0xa200; *_machine->ram_at(0x4000) = 0x1900; - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x3001; - state.registers.address[2] = 0x4001; - state.registers.status |= ConditionCode::Extend; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.address[1] = 0x3001; + registers.address[2] = 0x4001; + registers.status |= ConditionCode::Extend; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(18, _machine->get_cycle_count()); XCTAssertEqual(*_machine->ram_at(0x3000), 0x8200); XCTAssertEqual(*_machine->ram_at(0x4000), 0x1900); diff --git a/OSBindings/Mac/Clock SignalTests/68000BitwiseTests.mm b/OSBindings/Mac/Clock SignalTests/68000BitwiseTests.mm index 0a9e85691..b4a328994 100644 --- a/OSBindings/Mac/Clock SignalTests/68000BitwiseTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000BitwiseTests.mm @@ -32,14 +32,13 @@ _machine->set_program({ 0xc604 // AND.b D4, D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54ff7856; - state.registers.data[4] = 0x9853abcd; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54ff7856; + registers.data[4] = 0x9853abcd; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54ff7844); XCTAssertEqual(state.registers.data[4], 0x9853abcd); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -50,14 +49,14 @@ _machine->set_program({ 0xc644 // AND.w D4, D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.data[4] = 0x9853fbcd; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.data[4] = 0x9853fbcd; + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54fff844); XCTAssertEqual(state.registers.data[4], 0x9853fbcd); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); @@ -68,14 +67,13 @@ _machine->set_program({ 0xc684 // AND.l D4, D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.data[4] = 0x9853fbcd; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.data[4] = 0x9853fbcd; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x1053f844); XCTAssertEqual(state.registers.data[4], 0x9853fbcd); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -86,16 +84,15 @@ _machine->set_program({ opcode }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3000; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3000; + }); *_machine->ram_at(0x3000) = 0x0053; *_machine->ram_at(0x3002) = 0xfb00; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3000), 0x0053); XCTAssertEqual(*_machine->ram_at(0x3002), 0xfb00); XCTAssertEqual(state.registers.address[4], 0x3000); @@ -132,13 +129,13 @@ _machine->set_program({ opcode // AND.B (A4)+, D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3000; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3000; + }); *_machine->ram_at(0x3000) = 0x0053; *_machine->ram_at(0x3002) = 0xfb00; - _machine->set_processor_state(state); _machine->run_for_instructions(1); } @@ -156,15 +153,14 @@ _machine->set_program({ 0xc61f // AND.B (A7)+, D3 }, 0x3000); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + }); *_machine->ram_at(0x3000) = 0x0053; *_machine->ram_at(0x3002) = 0xfb00; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54fff800); XCTAssertEqual(state.registers.stack_pointer(), 0x3002); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero); @@ -197,16 +193,15 @@ _machine->set_program({ 0xc6a4 // AND.l -(A4), D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3004; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3004; + }); *_machine->ram_at(0x3000) = 0x0053; *_machine->ram_at(0x3002) = 0xfb00; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3000), 0x0053); XCTAssertEqual(*_machine->ram_at(0x3002), 0xfb00); XCTAssertEqual(state.registers.address[4], 0x3000); @@ -219,16 +214,15 @@ _machine->set_program({ 0xc6ac, 0xfffa // AND.l -6(A4), D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3006; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3006; + }); *_machine->ram_at(0x3000) = 0x1253; *_machine->ram_at(0x3002) = 0xfb34; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3000), 0x1253); XCTAssertEqual(*_machine->ram_at(0x3002), 0xfb34); XCTAssertEqual(state.registers.address[4], 0x3006); @@ -241,17 +235,16 @@ _machine->set_program({ 0xc6b4, 0x6006 // AND.l 6(A4, D6.W), D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.data[6] = 0xfffffffd; - state.registers.address[4] = 0x2ffd; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.data[6] = 0xfffffffd; + registers.address[4] = 0x2ffd; + }); *_machine->ram_at(0x3000) = 0x1253; *_machine->ram_at(0x3002) = 0xfb34; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3000), 0x1253); XCTAssertEqual(*_machine->ram_at(0x3002), 0xfb34); XCTAssertEqual(state.registers.address[4], 0x2ffd); @@ -265,17 +258,16 @@ _machine->set_program({ 0xc6b4, 0x60fe // AND.l -2(A4, D6.W), D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.data[6] = 0xf001fffd; - state.registers.address[4] = 0x3005; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.data[6] = 0xf001fffd; + registers.address[4] = 0x3005; + }); *_machine->ram_at(0x3000) = 0x1253; *_machine->ram_at(0x3002) = 0xfb34; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3000), 0x1253); XCTAssertEqual(*_machine->ram_at(0x3002), 0xfb34); XCTAssertEqual(state.registers.address[4], 0x3005); @@ -289,17 +281,16 @@ _machine->set_program({ 0xc6b4, 0x6801 // AND.l 6(A4, D6.W), D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.data[6] = 0xffffffff; - state.registers.address[4] = 0x3000; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.data[6] = 0xffffffff; + registers.address[4] = 0x3000; + }); *_machine->ram_at(0x3000) = 0x1253; *_machine->ram_at(0x3002) = 0xfb34; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3000), 0x1253); XCTAssertEqual(*_machine->ram_at(0x3002), 0xfb34); XCTAssertEqual(state.registers.address[4], 0x3000); @@ -313,15 +304,14 @@ _machine->set_program({ 0xc6b8, 0x3000 // AND.l $3000.w, D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + }); *_machine->ram_at(0x3000) = 0x1253; *_machine->ram_at(0x3002) = 0xfb34; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3000), 0x1253); XCTAssertEqual(*_machine->ram_at(0x3002), 0xfb34); XCTAssertEqual(state.registers.data[3], 0x1053f814); @@ -333,15 +323,14 @@ _machine->set_program({ 0xc6b9, 0x0001, 0x1170 // AND.L $11170.l, D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + }); *_machine->ram_at(0x11170) = 0x1253; *_machine->ram_at(0x11172) = 0xfb34; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x11170), 0x1253); XCTAssertEqual(*_machine->ram_at(0x11172), 0xfb34); XCTAssertEqual(state.registers.data[3], 0x1053f814); @@ -353,15 +342,14 @@ _machine->set_program({ 0xc6ba, 0xfffa // AND.l -6(PC), D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + }); *_machine->ram_at(0xffc) = 0x383c; *_machine->ram_at(0xffe) = 0x1234; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0xffc), 0x383c); XCTAssertEqual(*_machine->ram_at(0xffe), 0x1234); XCTAssertEqual(state.registers.data[3], 0x103c1014); @@ -373,16 +361,15 @@ _machine->set_program({ 0xc6bb, 0x10f6 // and.l -10(PC), D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.data[1] = 4; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.data[1] = 4; + }); *_machine->ram_at(0xffc) = 0x383c; *_machine->ram_at(0xffe) = 0x1234; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0xffc), 0x383c); XCTAssertEqual(*_machine->ram_at(0xffe), 0x1234); XCTAssertEqual(state.registers.data[3], 0x103c1014); @@ -394,13 +381,12 @@ _machine->set_program({ 0xc63c, 0x0034 // AND.b #$34, D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54fff814); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(8, _machine->get_cycle_count()); @@ -410,13 +396,12 @@ _machine->set_program({ 0xc67c, 0x1234 // AND.w #$1234, D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54ff1014); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(8, _machine->get_cycle_count()); @@ -426,13 +411,12 @@ _machine->set_program({ 0xc6bc, 0x3456, 0x1234 // AND.l #$34561234, D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x14561014); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(16, _machine->get_cycle_count()); @@ -442,16 +426,15 @@ _machine->set_program({ 0xc794 // AND.l D3, (A4) }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3000; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3000; + }); *_machine->ram_at(0x3000) = 0x1253; *_machine->ram_at(0x3002) = 0xfb03; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54fff856); XCTAssertEqual(state.registers.address[4], 0x3000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -464,16 +447,15 @@ _machine->set_program({ 0xc79c // AND.l D3, (A4)+ }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3000; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3000; + }); *_machine->ram_at(0x3000) = 0x1253; *_machine->ram_at(0x3002) = 0xfb03; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54fff856); XCTAssertEqual(state.registers.address[4], 0x3004); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -486,16 +468,17 @@ _machine->set_program({ 0xc7a4 // AND.l D3, -(A4) }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3000; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3000; + }); *_machine->ram_at(0x2ffc) = 0x1253; *_machine->ram_at(0x2ffe) = 0xfb03; - _machine->set_processor_state(state); + _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54fff856); XCTAssertEqual(state.registers.address[4], 0x2ffc); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -508,16 +491,15 @@ _machine->set_program({ 0xc7ac, 0x0002 // AND.l D3, 2(A4) }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3000; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3000; + }); *_machine->ram_at(0x3002) = 0x1253; *_machine->ram_at(0x3004) = 0xfb03; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54fff856); XCTAssertEqual(state.registers.address[4], 0x3000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -530,16 +512,15 @@ _machine->set_program({ 0xc7b8, 0x3000 // AND.l D3, ($3000).w }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3000; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3000; + }); *_machine->ram_at(0x3000) = 0x1253; *_machine->ram_at(0x3002) = 0xfb03; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54fff856); XCTAssertEqual(state.registers.address[4], 0x3000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -554,14 +535,13 @@ _machine->set_program({ 0x0340 // BCHG D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - state.registers.data[1] = d1; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0x12345678; + registers.data[1] = d1; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); } @@ -596,15 +576,14 @@ _machine->set_program({ 0x0350 // BCHG D1, (A0) }); - auto state = _machine->get_processor_state(); - state.registers.address[0] = 0x3000; - state.registers.data[1] = d1; + _machine->set_registers([=](auto ®isters){ + registers.address[0] = 0x3000; + registers.data[1] = d1; + }); *_machine->ram_at(0x3000) = 0x7800; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); XCTAssertEqual(state.registers.address[0], 0x3000); XCTAssertEqual(_machine->get_cycle_count(), 12); @@ -630,10 +609,9 @@ _machine->set_program({ 0x0840, immediate // BCHG #, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0x12345678; + }); _machine->run_for_instructions(1); } @@ -675,14 +653,13 @@ _machine->set_program({ 0x0380 // BCLR D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - state.registers.data[1] = d1; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0x12345678; + registers.data[1] = d1; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); } @@ -717,15 +694,14 @@ _machine->set_program({ 0x0390 // BCLR D1, (A0) }); - auto state = _machine->get_processor_state(); - state.registers.address[0] = 0x3000; - state.registers.data[1] = d1; + _machine->set_registers([=](auto ®isters){ + registers.address[0] = 0x3000; + registers.data[1] = d1; + }); *_machine->ram_at(0x3000) = 0x7800; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); XCTAssertEqual(state.registers.address[0], 0x3000); XCTAssertEqual(_machine->get_cycle_count(), 12); @@ -751,13 +727,12 @@ _machine->set_program({ 0x0880, immediate // BCLR #, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0x12345678; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); } @@ -797,14 +772,13 @@ _machine->set_program({ 0x03c0 // BSET D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - state.registers.data[1] = d1; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0x12345678; + registers.data[1] = d1; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); } @@ -839,15 +813,14 @@ _machine->set_program({ 0x03d0 // BSET D1, (A0) }); - auto state = _machine->get_processor_state(); - state.registers.address[0] = 0x3000; - state.registers.data[1] = d1; + _machine->set_registers([=](auto ®isters){ + registers.address[0] = 0x3000; + registers.data[1] = d1; + }); *_machine->ram_at(0x3000) = 0x7800; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); XCTAssertEqual(state.registers.address[0], 0x3000); XCTAssertEqual(_machine->get_cycle_count(), 12); @@ -873,10 +846,9 @@ _machine->set_program({ 0x08c0, immediate // BSET #, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0x12345678; + }); _machine->run_for_instructions(1); } @@ -918,14 +890,13 @@ _machine->set_program({ 0x0300 // BTST D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - state.registers.data[1] = d1; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0x12345678; + registers.data[1] = d1; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x12345678); XCTAssertEqual(state.registers.data[1], d1); XCTAssertEqual(6, _machine->get_cycle_count()); @@ -956,15 +927,14 @@ _machine->set_program({ 0x0310 // BTST D1, (A0) }); - auto state = _machine->get_processor_state(); - state.registers.address[0] = 0x3000; - state.registers.data[1] = d1; + _machine->set_registers([=](auto ®isters){ + registers.address[0] = 0x3000; + registers.data[1] = d1; + }); *_machine->ram_at(0x3000) = 0x7800; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); XCTAssertEqual(state.registers.address[0], 0x3000); XCTAssertEqual(8, _machine->get_cycle_count()); @@ -989,13 +959,12 @@ _machine->set_program({ 0x0800, immediate // BTST #, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0x12345678; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x12345678); XCTAssertEqual(10, _machine->get_cycle_count()); } @@ -1035,14 +1004,12 @@ _machine->set_program({ 0x0201, 0x0012 // ANDI.B #$12, D1 }); - - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[1] = 0x12345678; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x12345610); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(8, _machine->get_cycle_count()); @@ -1071,13 +1038,12 @@ _machine->set_program({ 0x023c, 0x001b // ANDI.b #$1b, CCR }); - auto state = _machine->get_processor_state(); - state.registers.status |= 0xc; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.status |= 0xc; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0xc & 0x1b); XCTAssertEqual(20, _machine->get_cycle_count()); } @@ -1115,16 +1081,14 @@ _machine->set_program({ 0xb744 // EOR.w D3, D4 }); - - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; - state.registers.data[3] = 0x54ff0056; - state.registers.data[4] = 0x9853abcd; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; + registers.data[3] = 0x54ff0056; + registers.data[4] = 0x9853abcd; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54ff0056); XCTAssertEqual(state.registers.data[4], 0x9853ab9b); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -1134,17 +1098,15 @@ _machine->set_program({ 0xb792 // EOR.l D3, (A2) }); - - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0x3000; - state.registers.data[3] = 0x54ff0056; + _machine->set_registers([=](auto ®isters){ + registers.address[2] = 0x3000; + registers.data[3] = 0x54ff0056; + }); *_machine->ram_at(0x3000) = 0x0f0f; *_machine->ram_at(0x3002) = 0x0f11; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54ff0056); XCTAssertEqual(state.registers.address[2], 0x3000); XCTAssertEqual(*_machine->ram_at(0x3000), 0x5bf0); @@ -1159,14 +1121,12 @@ _machine->set_program({ 0x0a01, 0x0012 // EORI.B #$12, D1 }); - - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[1] = 0x12345678; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x1234566a); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(8, _machine->get_cycle_count()); @@ -1196,13 +1156,12 @@ 0x0a3c, 0x001b // EORI.b #$1b, CCR }); - auto state = _machine->get_processor_state(); - state.registers.status |= 0xc; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.status |= 0xc; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0xc ^ 0x1b); XCTAssertEqual(20, _machine->get_cycle_count()); } @@ -1240,13 +1199,12 @@ _machine->set_program({ 0x4600 // NOT.B D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0x12345678; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x12345687); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -1256,14 +1214,13 @@ _machine->set_program({ 0x4640 // NOT.w D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12340000; - state.registers.status |= ConditionCode::AllConditions; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0x12340000; + registers.status |= ConditionCode::AllConditions; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x1234ffff); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Extend); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -1273,14 +1230,13 @@ _machine->set_program({ 0x4680 // NOT.l D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xffffff00; - state.registers.status |= ConditionCode::AllConditions; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = 0xffffff00; + registers.status |= ConditionCode::AllConditions; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x000000ff); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend); XCTAssertEqual(6, _machine->get_cycle_count()); @@ -1290,15 +1246,14 @@ _machine->set_program({ 0x46b9, 0x0000, 0x3000 // NOT.L ($3000).L }); + _machine->set_registers([=](auto ®isters){ + registers.status |= ConditionCode::Extend; + }); *_machine->ram_at(0x3000) = 0xf001; *_machine->ram_at(0x3002) = 0x2311; - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3000), 0x0ffe); XCTAssertEqual(*_machine->ram_at(0x3002), 0xdcee); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend); @@ -1311,15 +1266,14 @@ _machine->set_program({ 0x8604 // OR.b D4, D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54ff0056; - state.registers.data[4] = 0x9853abcd; - state.registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54ff0056; + registers.data[4] = 0x9853abcd; + registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54ff00df); XCTAssertEqual(state.registers.data[4], 0x9853abcd); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Negative); @@ -1330,16 +1284,15 @@ _machine->set_program({ 0x86ac, 0xfffa // OR.l -6(A4), D3 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3006; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3006; + }); *_machine->ram_at(0x3000) = 0x1253; *_machine->ram_at(0x3002) = 0xfb34; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x56fffb76); XCTAssertEqual(state.registers.address[4], 0x3006); XCTAssertEqual(*_machine->ram_at(0x3000), 0x1253); @@ -1352,16 +1305,15 @@ _machine->set_program({ 0x87ac, 0xfffa // OR.l D3, -6(A4) }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x54fff856; - state.registers.address[4] = 0x3006; + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; + registers.address[4] = 0x3006; + }); *_machine->ram_at(0x3000) = 0x1253; *_machine->ram_at(0x3002) = 0xfb34; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[3], 0x54fff856); XCTAssertEqual(state.registers.address[4], 0x3006); XCTAssertEqual(*_machine->ram_at(0x3000), 0x56ff); @@ -1376,14 +1328,12 @@ _machine->set_program({ 0x0001, 0x0012 // ORI.B #$12, D1 }); - - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[1] = 0x12345678; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x1234567a); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(8, _machine->get_cycle_count()); @@ -1412,14 +1362,12 @@ _machine->set_program({ 0x003c, 0x001b // ORI.b #$1b, CCR }); - - auto state = _machine->get_processor_state(); - state.registers.status |= 0xc; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.status |= 0xc; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0xc | 0x1b); XCTAssertEqual(20, _machine->get_cycle_count()); } @@ -1457,14 +1405,12 @@ _machine->set_program({ 0x4ac0 // TAS D0 }); - - auto state = _machine->get_processor_state(); - state.registers.data[0] = d0; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters){ + registers.data[0] = d0; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ccr); XCTAssertEqual(4, _machine->get_cycle_count()); } @@ -1481,15 +1427,13 @@ _machine->set_program({ 0x4af9, 0x0000, 0x3000 // TAS ($3000).l }); + _machine->set_registers([=](auto ®isters){ + registers.status |= ConditionCode::AllConditions; + }); *_machine->ram_at(0x3000) = 0x1100; - - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::AllConditions; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend); XCTAssertEqual(*_machine->ram_at(0x3000), 0x9100); XCTAssertEqual(22, _machine->get_cycle_count()); diff --git a/OSBindings/Mac/Clock SignalTests/68000ControlFlowTests.mm b/OSBindings/Mac/Clock SignalTests/68000ControlFlowTests.mm index f59d7a423..88ccae157 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ControlFlowTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ControlFlowTests.mm @@ -145,15 +145,14 @@ _machine->set_program({ 0x4581 // CHK D1, D2 }, 0); - auto state = _machine->get_processor_state(); - state.registers.data[1] = d1; - state.registers.data[2] = d2; - state.registers.status |= ConditionCode::AllConditions; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = d1; + registers.data[2] = d2; + registers.status |= ConditionCode::AllConditions; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); XCTAssertEqual(state.registers.data[2], d2); } @@ -201,14 +200,13 @@ _machine->set_program({ opcode, 0x0008 // DBcc D2, +8 }); - auto state = _machine->get_processor_state(); - state.registers.status = status; - state.registers.data[2] = 1; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.status = status; + registers.data[2] = 1; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[2], d2Output); XCTAssertEqual(state.registers.status, status); } @@ -382,13 +380,12 @@ 0x4ed1 // JMP (A1) }); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x3000; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x3000; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x3000); XCTAssertEqual(state.registers.program_counter, 0x3000 + 4); XCTAssertEqual(8, _machine->get_cycle_count()); @@ -490,17 +487,16 @@ _machine->set_program({ 0x4e41 // TRAP #1 }); - auto state = _machine->get_processor_state(); - state.registers.status = 0x700; - state.registers.user_stack_pointer = 0x200; - state.registers.supervisor_stack_pointer = 0x206; + _machine->set_registers([=](auto ®isters) { + registers.status = 0x700; + registers.user_stack_pointer = 0x200; + registers.supervisor_stack_pointer = 0x206; + }); *_machine->ram_at(0x84) = 0xfffe; *_machine->ram_at(0xfffe) = 0x4e71; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status, 0x2700); XCTAssertEqual(*_machine->ram_at(0x200), 0x700); XCTAssertEqual(*_machine->ram_at(0x202), 0x0000); @@ -516,16 +512,16 @@ 0x4e76 // TRAPV }, 0x206); - auto state = _machine->get_processor_state(); - state.registers.status = 0x702; - state.registers.supervisor_stack_pointer = 0x206; + _machine->set_registers([=](auto ®isters) { + registers.status = 0x702; + registers.supervisor_stack_pointer = 0x206; + }); *_machine->ram_at(0x1e) = 0xfffe; *_machine->ram_at(0xfffe) = 0x4e71; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status, 0x2702); XCTAssertEqual(state.registers.stack_pointer(), 0x200); XCTAssertEqual(*_machine->ram_at(0x202), 0x0000); diff --git a/OSBindings/Mac/Clock SignalTests/68000MoveTests.mm b/OSBindings/Mac/Clock SignalTests/68000MoveTests.mm index e0371b75d..f23ffbf24 100644 --- a/OSBindings/Mac/Clock SignalTests/68000MoveTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000MoveTests.mm @@ -32,14 +32,13 @@ _machine->set_program({ 0x4244 // CLR.w D4 }); - auto state = _machine->get_processor_state(); - state.registers.data[4] = 0x9853abcd; - state.registers.status |= ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Carry; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[4] = 0x9853abcd; + registers.status |= ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Carry; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[4], 0x98530000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Zero); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -49,14 +48,13 @@ _machine->set_program({ 0x4284 // CLR.l D4 }); - auto state = _machine->get_processor_state(); - state.registers.data[4] = 0x9853abcd; - state.registers.status |= ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Carry; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[4] = 0x9853abcd; + registers.status |= ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Carry; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[4], 0x0); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Zero); XCTAssertEqual(6, _machine->get_cycle_count()); @@ -68,13 +66,12 @@ }); *_machine->ram_at(0x186a0) = 0x9853; *_machine->ram_at(0x186a2) = 0xabcd; - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Carry; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.status |= ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Carry; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x186a0), 0x0); XCTAssertEqual(*_machine->ram_at(0x186a2), 0x0); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Zero); @@ -87,13 +84,12 @@ }); *_machine->ram_at(0x186a0) = 0x9853; *_machine->ram_at(0x186a2) = 0xabcd; - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Carry; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.status |= ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Carry; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x186a0), 0x0053); XCTAssertEqual(*_machine->ram_at(0x186a2), 0xabcd); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Zero); @@ -107,14 +103,13 @@ 0xc342 // EXG D1, D2 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x11111111; - state.registers.data[2] = 0x22222222; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x11111111; + registers.data[2] = 0x22222222; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x22222222); XCTAssertEqual(state.registers.data[2], 0x11111111); XCTAssertEqual(6, _machine->get_cycle_count()); @@ -125,14 +120,13 @@ 0xc34a // EXG A1, A2 }); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x11111111; - state.registers.address[2] = 0x22222222; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x11111111; + registers.address[2] = 0x22222222; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x22222222); XCTAssertEqual(state.registers.address[2], 0x11111111); XCTAssertEqual(6, _machine->get_cycle_count()); @@ -143,14 +137,13 @@ 0xc389 // EXG A1, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x11111111; - state.registers.address[1] = 0x22222222; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x11111111; + registers.address[1] = 0x22222222; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x22222222); XCTAssertEqual(state.registers.address[1], 0x11111111); XCTAssertEqual(6, _machine->get_cycle_count()); @@ -187,13 +180,12 @@ 0x43d2, // LEA (A2), A1 }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0xc000d; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xc000d; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0xc000d); XCTAssertEqual(state.registers.address[2], 0xc000d); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -204,13 +196,12 @@ 0x43ea, 0xffff // LEA (-1,A2), A1 }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0xc000d; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xc000d; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0xc000c); XCTAssertEqual(state.registers.address[2], 0xc000d); XCTAssertEqual(8, _machine->get_cycle_count()); @@ -221,14 +212,13 @@ 0x43f2, 0x7002 // LEA (2,A2,D7.W), A1 }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0xc000d; - state.registers.data[7] = 0x10000022; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xc000d; + registers.data[7] = 0x10000022; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0xc0031); XCTAssertEqual(state.registers.address[2], 0xc000d); XCTAssertEqual(state.registers.data[7], 0x10000022); @@ -240,14 +230,14 @@ 0x43f2, 0x7802 // LEA (2,A2,D7.l), A1 }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0xc000d; - state.registers.data[7] = 0x10000022; + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xc000d; + registers.data[7] = 0x10000022; + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x100c0031); XCTAssertEqual(state.registers.address[2], 0xc000d); XCTAssertEqual(state.registers.data[7], 0x10000022); @@ -259,13 +249,12 @@ 0x43fa, 0xeff8 // LEA (-6,PC), A1 }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0xc000d; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xc000d; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0xFFFFFFFA); XCTAssertEqual(8, _machine->get_cycle_count()); } @@ -275,13 +264,12 @@ 0x43fb, 0x30fe // LEA (-6,PC,D3), A1 }); - auto state = _machine->get_processor_state(); - state.registers.data[3] = 0x2; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[3] = 0x2; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x1002); XCTAssertEqual(state.registers.data[3], 0x2); XCTAssertEqual(12, _machine->get_cycle_count()); @@ -293,13 +281,12 @@ _machine->set_program({ 0x4e51, 0x0005 // LINK a1, #5 }, 0x22222222); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x11111111; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x11111111; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x2222221e); XCTAssertEqual(state.registers.supervisor_stack_pointer, 0x22222223); XCTAssertEqual(*_machine->ram_at(0x2222221e), 0x1111); @@ -325,13 +312,12 @@ _machine->set_program({ 0x4e51, 0x8000 // LINK a1, #$8000 }, 0x22222222); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x11111111; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x11111111; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x2222221e); XCTAssertEqual(state.registers.supervisor_stack_pointer, 0x2221a21e); XCTAssertEqual(*_machine->ram_at(0x2222221e), 0x1111); @@ -345,15 +331,14 @@ _machine->set_program({ 0x48e1, 0xc000 // MOVEM.L D0-D1, -(A1) }); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x3000; - state.registers.data[0] = 0x12345678; - state.registers.data[1] = 0x87654321; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x3000; + registers.data[0] = 0x12345678; + registers.data[1] = 0x87654321; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x2ff8); XCTAssertEqual(state.registers.data[0], 0x12345678); XCTAssertEqual(state.registers.data[1], 0x87654321); @@ -368,15 +353,14 @@ _machine->set_program({ 0x48e1, 0xc040 // MOVEM.L D0-D1/A1, -(A1) }); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x3000; - state.registers.data[0] = 0x12345678; - state.registers.data[1] = 0x87654321; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x3000; + registers.data[0] = 0x12345678; + registers.data[1] = 0x87654321; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x2ff4); XCTAssertEqual(state.registers.data[0], 0x12345678); XCTAssertEqual(state.registers.data[1], 0x87654321); @@ -393,17 +377,16 @@ _machine->set_program({ 0x48e4, 0xffff // MOVEM.L D0-D7/A0-A7, -(A4) }, 0xffffffff); - auto state = _machine->get_processor_state(); - for(int c = 0; c < 8; ++c) - state.registers.data[c] = (c+1) * 0x11111111; - for(int c = 0; c < 7; ++c) - state.registers.address[c] = ((c < 4) ? (c + 9) : (c + 8)) * 0x11111111; - state.registers.address[4] = 0x4000; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + for(int c = 0; c < 8; ++c) + registers.data[c] = (c+1) * 0x11111111; + for(int c = 0; c < 7; ++c) + registers.address[c] = ((c < 4) ? (c + 9) : (c + 8)) * 0x11111111; + registers.address[4] = 0x4000; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[4], 0x3fc0); const uint32_t expected_values[] = { @@ -426,15 +409,14 @@ _machine->set_program({ 0x48a4, 0x0800 // MOVEM.W D4, -(A4) }); - auto state = _machine->get_processor_state(); - state.registers.address[4] = 0x4000; - state.registers.data[4] = 0x111a1111; - state.registers.data[0] = 0xffffffff; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[4] = 0x4000; + registers.data[4] = 0x111a1111; + registers.data[0] = 0xffffffff; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[4], 0x3ffe); XCTAssertEqual(state.registers.data[0], 0xffffffff); @@ -452,8 +434,9 @@ _machine->set_program({ 0x4cd9, 0x0606 // MOVEM.l (A1)+, D1-D2/A1-A2 }); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x4000; + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x4000; + }); *_machine->ram_at(0x4000) = 0x1111; *_machine->ram_at(0x4002) = 0x1111; *_machine->ram_at(0x4004) = 0x2222; @@ -461,10 +444,9 @@ *_machine->ram_at(0x400c) = 0x3333; *_machine->ram_at(0x400e) = 0x3333; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x11111111); XCTAssertEqual(state.registers.data[2], 0x22222222); @@ -478,14 +460,14 @@ _machine->set_program({ 0x4c99, 0x0002 // MOVEM.w (A1)+, D1 }); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x4000; + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x4000; + }); *_machine->ram_at(0x4000) = 0x8000; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xffff8000); XCTAssertEqual(state.registers.address[1], 0x4002); @@ -497,17 +479,17 @@ _machine->set_program({ 0x4c91, 0x0206 // MOVEM.w (A1), A1/D1-D2 }); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x4000; - state.registers.data[2] = 0xffffffff; + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x4000; + registers.data[2] = 0xffffffff; + }); *_machine->ram_at(0x4000) = 0x8000; *_machine->ram_at(0x4002) = 0x2222; *_machine->ram_at(0x4004) = 0x3333; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xffff8000); XCTAssertEqual(state.registers.data[2], 0x00002222); @@ -520,15 +502,14 @@ _machine->set_program({ 0x4891, 0x0206 // MOVEM.w A1/D1-D2, (A1) }); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x4000; - state.registers.data[1] = 0x11111111; - state.registers.data[2] = 0x22222222; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x4000; + registers.data[1] = 0x11111111; + registers.data[2] = 0x22222222; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x4000), 0x1111); XCTAssertEqual(*_machine->ram_at(0x4002), 0x2222); @@ -544,13 +525,13 @@ _machine->set_program({ 0x1401 // MOVE.b D1, D2 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x12345678; + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x12345678; + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x12345678); XCTAssertEqual(state.registers.data[2], 0x00000078); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -574,14 +555,14 @@ _machine->set_program({ 0x34bc, 0x0000 // MOVE #$0, (A2) }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0x3000; + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0x3000; + }); *_machine->ram_at(0x3000) = 0x1234; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0x3000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero); XCTAssertEqual(*_machine->ram_at(0x3000), 0); @@ -592,16 +573,16 @@ _machine->set_program({ 0x24da // MOVE.l (A2)+, (A2)+ }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0x3000; - state.registers.status = ConditionCode::Negative; + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0x3000; + registers.status = ConditionCode::Negative; + }); *_machine->ram_at(0x3000) = 0xaaaa; *_machine->ram_at(0x3002) = 0xbbbb; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0x3008); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); XCTAssertEqual(*_machine->ram_at(0x3000), 0xaaaa); @@ -615,16 +596,16 @@ _machine->set_program({ 0x251a // MOVE.l (A2)+, -(A2) }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0x3000; - state.registers.status = ConditionCode::Negative; + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0x3000; + registers.status = ConditionCode::Negative; + }); *_machine->ram_at(0x3000) = 0xaaaa; *_machine->ram_at(0x3002) = 0xbbbb; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0x3000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); XCTAssertEqual(*_machine->ram_at(0x3000), 0xaaaa); @@ -638,17 +619,17 @@ _machine->set_program({ 0x25a2, 0x1004 // MOVE.L -(A2), 4(A2,D1) }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0x3004; - state.registers.data[1] = 0; - state.registers.status = ConditionCode::Negative; + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0x3004; + registers.data[1] = 0; + registers.status = ConditionCode::Negative; + }); *_machine->ram_at(0x3000) = 0xaaaa; *_machine->ram_at(0x3002) = 0xbbbb; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0x3000); XCTAssertEqual(state.registers.data[1], 0); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); @@ -663,13 +644,13 @@ _machine->set_program({ 0x33c1, 0x0000, 0x3000 // MOVE.W D1, ($3000).L }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x5678; + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x5678; + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x5678); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(*_machine->ram_at(0x3000), 0x5678); @@ -698,13 +679,13 @@ _machine->set_program({ 0x244a // MOVEA.l A2, A2 }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0xffffffff; + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xffffffff; + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0xffffffff); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -714,14 +695,13 @@ _machine->set_program({ 0x3442 // MOVEA.w D2, A2 }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0xffffffff; - state.registers.data[2] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xffffffff; + registers.data[2] = 0x12345678; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0x00005678); XCTAssertEqual(state.registers.data[2], 0x12345678); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -732,14 +712,13 @@ _machine->set_program({ 0x3442 // MOVEA.w D2, A2 }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0xffffffff; - state.registers.data[2] = 0x12348756; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xffffffff; + registers.data[2] = 0x12348756; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 0xffff8756); XCTAssertEqual(state.registers.data[2], 0x12348756); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -750,13 +729,12 @@ _machine->set_program({ 0x247c, 0x0000, 0x0001 // MOVEA.L #$1, A2 }); - auto state = _machine->get_processor_state(); - state.registers.address[2] = 0xffffffff; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[2] = 0xffffffff; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[2], 1); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(12, _machine->get_cycle_count()); @@ -768,15 +746,14 @@ _machine->set_program({ 0x030e, 0x0004 // MOVEP.w 4(A6), D1 }); - auto state = _machine->get_processor_state(); - state.registers.address[6] = 0x3000; + _machine->set_registers([=](auto ®isters) { + registers.address[6] = 0x3000; + }); *_machine->ram_at(0x3004) = 0x1200; *_machine->ram_at(0x3006) = 0x3400; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[6], 0x3000); XCTAssertEqual(state.registers.data[1], 0x1234); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -787,17 +764,17 @@ _machine->set_program({ 0x034e, 0x0002 // MOVEP.l 2(A6), D1 }); - auto state = _machine->get_processor_state(); - state.registers.address[6] = 0x3000; + _machine->set_registers([=](auto ®isters) { + registers.address[6] = 0x3000; + }); *_machine->ram_at(0x3002) = 0x1200; *_machine->ram_at(0x3004) = 0x3400; *_machine->ram_at(0x3006) = 0x5600; *_machine->ram_at(0x3008) = 0x7800; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[6], 0x3000); XCTAssertEqual(state.registers.data[1], 0x12345678); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); @@ -808,14 +785,13 @@ _machine->set_program({ 0x038e, 0x0002 // MOVEP.w D1, 2(A6) }); - auto state = _machine->get_processor_state(); - state.registers.address[6] = 0x3000; - state.registers.data[1] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[6] = 0x3000; + registers.data[1] = 0x12345678; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[6], 0x3000); XCTAssertEqual(*_machine->ram_at(0x3002), 0x5600); XCTAssertEqual(*_machine->ram_at(0x3004), 0x7800); @@ -828,14 +804,14 @@ _machine->set_program({ 0x03ce, 0x0002 // MOVEP.l D1, 2(A6) }); - auto state = _machine->get_processor_state(); - state.registers.address[6] = 0x3000; - state.registers.data[1] = 0x12345678; + _machine->set_registers([=](auto ®isters) { + registers.address[6] = 0x3000; + registers.data[1] = 0x12345678; + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[6], 0x3000); XCTAssertEqual(*_machine->ram_at(0x3002), 0x1200); @@ -853,13 +829,12 @@ _machine->set_program({ 0x7201 // MOVEQ #1, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xffffffff; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xffffffff; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x1); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -869,14 +844,13 @@ _machine->set_program({ 0x72ff // MOVEQ #-1, D1 }); - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xffffffff); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Negative); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -886,14 +860,14 @@ _machine->set_program({ 0x7280 // MOVEQ #$80, D1 }); - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; - state.registers.data[1] = 0x12345678; + _machine->set_registers([=](auto ®isters) { + registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; + registers.data[1] = 0x12345678; + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xffffff80); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Negative); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -903,14 +877,13 @@ _machine->set_program({ 0x7200 // MOVEQ #00, D1 }); - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; - state.registers.data[1] = 0x12345678; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; + registers.data[1] = 0x12345678; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Zero); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -922,13 +895,12 @@ _machine->set_program({ 0x40c1 // MOVE SR, D1 }); - auto state = _machine->get_processor_state(); - state.registers.status = 0x271f; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.status = 0x271f; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x271f); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::AllConditions); XCTAssertEqual(6, _machine->get_cycle_count()); @@ -940,13 +912,13 @@ _machine->set_program({ 0x44fc, 0x001f // MOVE #$1f, CCR }); - auto state = _machine->get_processor_state(); - state.registers.status = 0; // i.e. not even supervisor. + _machine->set_registers([=](auto ®isters) { + registers.status = 0; // i.e. not supervisor. + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0x1f); XCTAssertEqual(16, _machine->get_cycle_count()); } @@ -957,14 +929,13 @@ _machine->set_program({ 0x46fc, 0x0700 // MOVE #$700, SR }); - auto state = _machine->get_processor_state(); - state.registers.supervisor_stack_pointer = 0x3000; - state.registers.user_stack_pointer = 0; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.supervisor_stack_pointer = 0x3000; + registers.user_stack_pointer = 0; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.stack_pointer(), 0); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(16, _machine->get_cycle_count()); @@ -976,13 +947,13 @@ _machine->set_program({ 0x4e69 // MOVE USP, A1 }); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x12348756; + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x12348756; + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0); } @@ -992,13 +963,12 @@ _machine->set_program({ 0x4851 // PEA (A1) }, 0x1996); - auto state = _machine->get_processor_state(); - state.registers.address[1] = 0x3000ffff; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x3000ffff; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[1], 0x3000ffff); XCTAssertEqual(state.registers.stack_pointer(), 0x1992); XCTAssertEqual(*_machine->ram_at(0x1992), 0x3000); @@ -1068,14 +1038,13 @@ _machine->set_program({ 0x51c0 // SF D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - state.registers.status = ConditionCode::Extend; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0x12345678; + registers.status = ConditionCode::Extend; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x12345600); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend); } @@ -1084,14 +1053,13 @@ _machine->set_program({ 0x50c0 // ST D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - state.registers.status = ConditionCode::Extend; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0x12345678; + registers.status = ConditionCode::Extend; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x123456ff); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend); } @@ -1100,14 +1068,13 @@ _machine->set_program({ 0x53c0 // SLS D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0x12345678; - state.registers.status = ConditionCode::AllConditions; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0x12345678; + registers.status = ConditionCode::AllConditions; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x123456ff); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::AllConditions); } @@ -1116,15 +1083,15 @@ _machine->set_program({ 0x5ee8, 0x0002 // SGT 2(a0) }); - auto state = _machine->get_processor_state(); - state.registers.address[0] = 0x3000; + _machine->set_registers([=](auto ®isters) { + registers.address[0] = 0x3000; + registers.status = ConditionCode::Extend; + }); *_machine->ram_at(0x3002) = 0x8800; - state.registers.status = ConditionCode::Extend; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3002), 0xff00); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend); } @@ -1133,15 +1100,15 @@ _machine->set_program({ 0x5ee8, 0x0002 // SGT 2(a0) }); - auto state = _machine->get_processor_state(); - state.registers.address[0] = 0x3000; + _machine->set_registers([=](auto ®isters) { + registers.address[0] = 0x3000; + registers.status = ConditionCode::AllConditions; + }); *_machine->ram_at(0x3002) = 0x8800; - state.registers.status = ConditionCode::AllConditions; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3002), 0x0000); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::AllConditions); } @@ -1153,13 +1120,12 @@ _machine->set_program({ 0x4841 // SWAP D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0x12348756; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0x12348756; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x87561234); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); } @@ -1170,14 +1136,14 @@ _machine->set_program({ 0x4a44 // TST.w D4 }); - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; - state.registers.data[4] = 0xfff1; + _machine->set_registers([=](auto ®isters) { + registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; + registers.data[4] = 0xfff1; + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Extend); XCTAssertEqual(state.registers.data[4], 0xfff1); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -1187,14 +1153,14 @@ _machine->set_program({ 0x4a84 // TST.l D4 }); - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; - state.registers.data[4] = 0; + _machine->set_registers([=](auto ®isters) { + registers.status |= ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Overflow; + registers.data[4] = 0; + }); - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero | ConditionCode::Extend); XCTAssertEqual(state.registers.data[4], 0); XCTAssertEqual(4, _machine->get_cycle_count()); @@ -1209,15 +1175,15 @@ 0x4e5e // UNLNK A6 }); - auto state = _machine->get_processor_state(); - state.registers.address[6] = 0x3000; + _machine->set_registers([=](auto ®isters) { + registers.address[6] = 0x3000; + }); *_machine->ram_at(0x3000) = 0x0000; *_machine->ram_at(0x3002) = 0x4000; - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[6], 0x4000); XCTAssertEqual(state.registers.supervisor_stack_pointer, 0x3004); XCTAssertEqual(12, _machine->get_cycle_count()); diff --git a/OSBindings/Mac/Clock SignalTests/68000RollShiftTests.mm b/OSBindings/Mac/Clock SignalTests/68000RollShiftTests.mm index 9e0b9c609..587c41e80 100644 --- a/OSBindings/Mac/Clock SignalTests/68000RollShiftTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000RollShiftTests.mm @@ -33,14 +33,13 @@ _machine->set_program({ 0xe521 // ASL.B D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 2; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 2; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd59c); XCTAssertEqual(state.registers.data[2], 2); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Overflow | ConditionCode::Carry); @@ -51,14 +50,13 @@ _machine->set_program({ 0xe521 // ASL.B D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 105; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 105; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd500); XCTAssertEqual(state.registers.data[2], 105); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Overflow | ConditionCode::Zero); @@ -69,14 +67,13 @@ _machine->set_program({ 0xe561 // ASL.w D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd567); XCTAssertEqual(state.registers.data[2], 0); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); @@ -87,14 +84,13 @@ _machine->set_program({ 0xe561 // ASL.w D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0xb; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0xb; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3d3800); XCTAssertEqual(state.registers.data[2], 0xb); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Overflow | ConditionCode::Carry); @@ -105,14 +101,13 @@ _machine->set_program({ 0xe5a1 // ASL.l D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0x20; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0x20; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0); XCTAssertEqual(state.registers.data[2], 0x20); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Overflow | ConditionCode::Carry | ConditionCode::Zero); @@ -123,14 +118,13 @@ _machine->set_program({ 0xe181 // ASL.l #8, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0x20; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0x20; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x3dd56700); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Overflow); XCTAssertEqual(24, _machine->get_cycle_count()); @@ -172,14 +166,13 @@ _machine->set_program({ 0xe421 // ASR.B D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 2; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 2; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd519); XCTAssertEqual(state.registers.data[2], 2); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry); @@ -190,14 +183,13 @@ _machine->set_program({ 0xe421 // ASR.B D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 105; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 105; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd500); XCTAssertEqual(state.registers.data[2], 105); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero); @@ -208,14 +200,13 @@ _machine->set_program({ 0xe461 // ASR.w D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd567); XCTAssertEqual(state.registers.data[2], 0); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); @@ -226,14 +217,13 @@ _machine->set_program({ 0xe461 // ASR.w D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0xb; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0xb; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dfffa); XCTAssertEqual(state.registers.data[2], 0xb); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Carry); @@ -244,14 +234,13 @@ _machine->set_program({ 0xe4a1 // ASR.l D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0x20; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0x20; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xffffffff); XCTAssertEqual(state.registers.data[2], 0x20); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Carry); @@ -262,14 +251,13 @@ _machine->set_program({ 0xe081 // ASR.l #8, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0x20; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0x20; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xffce3dd5); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); XCTAssertEqual(24, _machine->get_cycle_count()); @@ -311,14 +299,13 @@ _machine->set_program({ 0xe529 // LSL.b D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 2; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 2; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd59c); XCTAssertEqual(state.registers.data[2], 2); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Negative | ConditionCode::Carry); @@ -329,14 +316,13 @@ _machine->set_program({ 0xe529 // LSL.b D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0x69; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0x69; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd500); XCTAssertEqual(state.registers.data[2], 0x69); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero); @@ -347,14 +333,13 @@ _machine->set_program({ 0xe569 // LSL.w D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd567); XCTAssertEqual(state.registers.data[2], 0); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); @@ -365,14 +350,13 @@ _machine->set_program({ 0xe569 // LSL.w D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0xb; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0xb; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3d3800); XCTAssertEqual(state.registers.data[2], 0xb); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry); @@ -383,14 +367,13 @@ _machine->set_program({ 0xe5a9 // LSL.l D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0x20; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0x20; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0); XCTAssertEqual(state.registers.data[2], 0x20); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Zero); @@ -401,13 +384,12 @@ _machine->set_program({ 0xe189 // LSL.l #8, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0x3dd56700); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(24, _machine->get_cycle_count()); @@ -433,14 +415,13 @@ _machine->set_program({ 0xe429 // LSR.b D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 2; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 2; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd519); XCTAssertEqual(state.registers.data[2], 2); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry); @@ -451,14 +432,13 @@ _machine->set_program({ 0xe429 // LSR.b D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0x69; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0x69; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd500); XCTAssertEqual(state.registers.data[2], 0x69); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Zero); @@ -469,14 +449,13 @@ _machine->set_program({ 0xe469 // LSR.w D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd567); XCTAssertEqual(state.registers.data[2], 0); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); @@ -487,14 +466,13 @@ _machine->set_program({ 0xe469 // LSR.w D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0xb; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0xb; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3d001a); XCTAssertEqual(state.registers.data[2], 0xb); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry); @@ -505,14 +483,13 @@ _machine->set_program({ 0xe4a9 // LSR.l D2, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - state.registers.data[2] = 0x20; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + registers.data[2] = 0x20; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0); XCTAssertEqual(state.registers.data[2], 0x20); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry | ConditionCode::Zero); @@ -523,13 +500,12 @@ _machine->set_program({ 0xe089 // LSR.L #8, D1 }); - auto state = _machine->get_processor_state(); - state.registers.data[1] = 0xce3dd567; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = 0xce3dd567; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], 0xce3dd5); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(24, _machine->get_cycle_count()); @@ -555,13 +531,12 @@ _machine->set_program({ 0xe118 // ROL.B #8, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0xce3dd567); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Carry); XCTAssertEqual(22, _machine->get_cycle_count()); @@ -571,13 +546,12 @@ _machine->set_program({ 0xe318 // ROL.B #1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0xce3dd5ce); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative); XCTAssertEqual(8, _machine->get_cycle_count()); @@ -587,14 +561,13 @@ _machine->set_program({ 0xe518 // ROL.B #2, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.status = ConditionCode::AllConditions; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.status = ConditionCode::AllConditions; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0xce3dd59d); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Extend | ConditionCode::Carry); XCTAssertEqual(10, _machine->get_cycle_count()); @@ -604,14 +577,13 @@ _machine->set_program({ 0xef18 // ROL.B #7, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.status = ConditionCode::AllConditions; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.status = ConditionCode::AllConditions; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0xce3dd5b3); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Extend | ConditionCode::Carry); XCTAssertEqual(20, _machine->get_cycle_count()); @@ -621,14 +593,13 @@ _machine->set_program({ 0xe158 // ROL.w #7, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.status = ConditionCode::AllConditions; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.status = ConditionCode::AllConditions; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0xce3d67d5); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry); XCTAssertEqual(22, _machine->get_cycle_count()); @@ -638,14 +609,13 @@ _machine->set_program({ 0xe798 // ROL.l #3, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.status = ConditionCode::AllConditions; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.status = ConditionCode::AllConditions; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x71eeab3e); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend); XCTAssertEqual(14, _machine->get_cycle_count()); @@ -655,12 +625,11 @@ _machine->set_program({ 0xe378 // ROL.l D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.data[1] = d1; - state.registers.status = ConditionCode::AllConditions; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.data[1] = d1; + registers.status = ConditionCode::AllConditions; + }); _machine->run_for_instructions(1); } @@ -695,15 +664,14 @@ _machine->set_program({ 0xe3b8 // ROL.l D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.data[1] = 200; - state.registers.status = ConditionCode::AllConditions; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.data[1] = 200; + registers.status = ConditionCode::AllConditions; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x3dd567ce); XCTAssertEqual(state.registers.data[1], 200); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend); @@ -744,10 +712,9 @@ _machine->set_program({ uint16_t(0xe018 | (immediate << 9)) // ROR.b #, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd599; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd599; + }); _machine->run_for_instructions(1); } @@ -791,13 +758,12 @@ _machine->set_program({ 0xec58 // ROR.w #6, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd599; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd599; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0xce3d6756); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(18, _machine->get_cycle_count()); @@ -807,13 +773,12 @@ _machine->set_program({ 0xea98 // ROR.l #5, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd599; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd599; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0xce71eeac); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Carry | ConditionCode::Negative); XCTAssertEqual(18, _machine->get_cycle_count()); @@ -823,14 +788,13 @@ _machine->set_program({ 0xe238 // ROR.b D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd599; - state.registers.data[1] = 20; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd599; + registers.data[1] = 20; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0xce3dd599); XCTAssertEqual(state.registers.data[1], 20); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Carry | ConditionCode::Negative); @@ -841,14 +805,13 @@ _machine->set_program({ 0xe2b8 // ROR.l D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd599; - state.registers.data[1] = 26; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd599; + registers.data[1] = 26; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x8f756673); XCTAssertEqual(state.registers.data[1], 26); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Carry | ConditionCode::Negative); @@ -888,15 +851,14 @@ _machine->set_program({ 0xe330 // ROXL.b D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.data[1] = 9; - state.registers.status |= ccr; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.data[1] = 9; + registers.status |= ccr; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(24, _machine->get_cycle_count()); XCTAssertEqual(state.registers.data[0], 0xce3dd567); XCTAssertEqual(state.registers.data[1], 9); @@ -920,15 +882,14 @@ _machine->set_program({ 0xe370 // ROXL.w D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.data[1] = d1; - state.registers.status |= ccr; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.data[1] = d1; + registers.status |= ccr; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); } @@ -963,15 +924,14 @@ _machine->set_program({ 0xe3b0 // ROXL.l D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.data[1] = 33; - state.registers.status |= ConditionCode::Extend; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.data[1] = 33; + registers.status |= ConditionCode::Extend; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0xce3dd567); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Negative | ConditionCode::Carry | ConditionCode::Extend); XCTAssertEqual(74, _machine->get_cycle_count()); @@ -981,14 +941,13 @@ _machine->set_program({ 0xe950 // ROXL.w #4, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3d3600; - state.registers.status |= ConditionCode::Extend; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3d3600; + registers.status |= ConditionCode::Extend; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0xce3d6009); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Extend | ConditionCode::Carry); XCTAssertEqual(14, _machine->get_cycle_count()); @@ -1014,15 +973,14 @@ _machine->set_program({ 0xe230 // ROXR.b D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.data[1] = 9; - state.registers.status |= ccr; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.data[1] = 9; + registers.status |= ccr; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(24, _machine->get_cycle_count()); XCTAssertEqual(state.registers.data[0], 0xce3dd567); XCTAssertEqual(state.registers.data[1], 9); @@ -1046,15 +1004,14 @@ _machine->set_program({ 0xe270 // ROXR.w D1, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3dd567; - state.registers.data[1] = d1; - state.registers.status |= ccr; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3dd567; + registers.data[1] = d1; + registers.status |= ccr; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); } @@ -1089,14 +1046,13 @@ _machine->set_program({ 0xe890 // ROXR.L #4, D0 }); - auto state = _machine->get_processor_state(); - state.registers.data[0] = 0xce3d3600; - state.registers.status |= ConditionCode::Extend; - - _machine->set_processor_state(state); + _machine->set_registers([=](auto ®isters) { + registers.data[0] = 0xce3d3600; + registers.status |= ConditionCode::Extend; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[0], 0x1ce3d360); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, 0); XCTAssertEqual(16, _machine->get_cycle_count()); @@ -1106,14 +1062,13 @@ _machine->set_program({ 0xe4f8, 0x3000 // ROXR.W ($3000).W }); + _machine->set_registers([=](auto ®isters) { + registers.status |= ConditionCode::Extend; + }); *_machine->ram_at(0x3000) = 0xd567; - auto state = _machine->get_processor_state(); - state.registers.status |= ConditionCode::Extend; - - _machine->set_processor_state(state); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(*_machine->ram_at(0x3000), 0xeab3); XCTAssertEqual(state.registers.status & ConditionCode::AllConditions, ConditionCode::Carry | ConditionCode::Extend | ConditionCode::Negative); XCTAssertEqual(16, _machine->get_cycle_count()); diff --git a/OSBindings/Mac/Clock SignalTests/68000Tests.mm b/OSBindings/Mac/Clock SignalTests/68000Tests.mm index 565b3e85e..41ed261de 100644 --- a/OSBindings/Mac/Clock SignalTests/68000Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000Tests.mm @@ -125,15 +125,13 @@ class CPU::MC68000::ProcessorStorageTests { _machine->set_program({ 0xc100 // ABCD D0, D0 }); - - auto state = _machine->get_processor_state(); const uint8_t bcd_d = ((d / 10) * 16) + (d % 10); - state.registers.data[0] = bcd_d; - _machine->set_processor_state(state); - + _machine->set_registers([=](auto ®isters){ + registers.data[0] = bcd_d; + }); _machine->run_for_instructions(1); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); const uint8_t double_d = (d * 2) % 100; const uint8_t bcd_double_d = ((double_d / 10) * 16) + (double_d % 10); XCTAssert(state.registers.data[0] == bcd_double_d, "%02x + %02x = %02x; should equal %02x", bcd_d, bcd_d, state.registers.data[0], bcd_double_d); diff --git a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp index 633e00366..3ce70440f 100644 --- a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp +++ b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp @@ -10,6 +10,7 @@ #define TestRunner68000_h #include +#include #include #include "../../../Processors/68000Mk2/68000Mk2.hpp" @@ -31,16 +32,24 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { void set_program( const std::vector &program, - uint32_t stack_pointer = 0x206) { + uint32_t stack_pointer = 0x206 + ) { memcpy(&ram_[0x1000 >> 1], program.data(), program.size() * sizeof(uint16_t)); // Ensure the condition codes start unset and set the initial program counter - // and supervisor stack pointer. - auto state = get_processor_state(); - state.registers.status &= ~ConditionCode::AllConditions; - state.registers.program_counter = initial_pc(); - state.registers.supervisor_stack_pointer = stack_pointer; - set_processor_state(state); + // and supervisor stack pointer, as well as starting in supervisor mode. + set_registers([=](InstructionSet::M68k::RegisterSet ®isters){ + registers.status &= ~ConditionCode::AllConditions; + registers.status |= 0x2700; + registers.program_counter = initial_pc(); + registers.supervisor_stack_pointer = stack_pointer; + }); + } + + void set_registers(std::function func) { + auto state = m68000_.get_state(); + func(state.registers); + m68000_.set_state(state); } void will_perform(uint32_t, uint16_t) { @@ -107,10 +116,6 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { return m68000_.get_state(); } - void set_processor_state(const CPU::MC68000Mk2::State &state) { - m68000_.decode_from_state(state.registers); - } - auto &processor() { return m68000_; } From 88e33353a1a84c112f18859f87d0645aa6183e2e Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 26 May 2022 09:17:37 -0400 Subject: [PATCH 16/17] Fix instruction and time counting, and initial state. --- .../Mac/Clock SignalTests/TestRunner68000.hpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp index 3ce70440f..949ac7e1b 100644 --- a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp +++ b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp @@ -38,12 +38,12 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { // Ensure the condition codes start unset and set the initial program counter // and supervisor stack pointer, as well as starting in supervisor mode. - set_registers([=](InstructionSet::M68k::RegisterSet ®isters){ - registers.status &= ~ConditionCode::AllConditions; - registers.status |= 0x2700; - registers.program_counter = initial_pc(); - registers.supervisor_stack_pointer = stack_pointer; - }); + auto registers = m68000_.get_state().registers; + registers.status &= ~ConditionCode::AllConditions; + registers.status |= 0x2700; + registers.program_counter = initial_pc(); + registers.supervisor_stack_pointer = stack_pointer; + m68000_.decode_from_state(registers); } void set_registers(std::function func) { @@ -54,12 +54,13 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { void will_perform(uint32_t, uint16_t) { --instructions_remaining_; - if(!instructions_remaining_) { + if(instructions_remaining_ < 0) { throw StopException(); } } void run_for_instructions(int count) { + duration_ = HalfCycles(0); instructions_remaining_ = count; if(!instructions_remaining_) return; @@ -80,7 +81,7 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { HalfCycles perform_bus_operation(const CPU::MC68000Mk2::Microcycle &cycle, int) { const uint32_t word_address = cycle.word_address(); - if(instructions_remaining_) duration_ += cycle.length; + duration_ += cycle.length; using Microcycle = CPU::MC68000Mk2::Microcycle; if(cycle.data_select_active()) { From 5f030edea417b758ae0d3c2635e16af20435afb7 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 26 May 2022 19:37:30 -0400 Subject: [PATCH 17/17] Simplify transaction. --- OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp index 949ac7e1b..71ab51199 100644 --- a/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp +++ b/OSBindings/Mac/Clock SignalTests/TestRunner68000.hpp @@ -39,8 +39,7 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { // Ensure the condition codes start unset and set the initial program counter // and supervisor stack pointer, as well as starting in supervisor mode. auto registers = m68000_.get_state().registers; - registers.status &= ~ConditionCode::AllConditions; - registers.status |= 0x2700; + registers.status = 0x2700; registers.program_counter = initial_pc(); registers.supervisor_stack_pointer = stack_pointer; m68000_.decode_from_state(registers);