diff --git a/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md b/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md index 1bb9ed03d..c50378092 100644 --- a/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md +++ b/OSBindings/Mac/Clock SignalTests/68000 Comparative Tests/readme.md @@ -40,6 +40,27 @@ 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. + +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. \ 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. diff --git a/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm b/OSBindings/Mac/Clock SignalTests/68000ArithmeticTests.mm index d6ebc8d67..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); @@ -741,18 +714,21 @@ @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); + self.machine->set_registers([=](auto ®isters) { + registers.data[1] = d1; + registers.status |= ConditionCode::AllConditions; }); - 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->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 +847,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 +858,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(); @@ -916,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); } @@ -975,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()); @@ -1014,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); } @@ -1040,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); } @@ -1053,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); } @@ -1121,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); } @@ -1153,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()); @@ -1178,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()); @@ -1215,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); @@ -1231,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()); @@ -1284,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()); @@ -1322,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); @@ -1339,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()); @@ -1369,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); @@ -1396,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()); @@ -1440,16 +1400,14 @@ - (void)testSUBb_PreDec { self.machine->set_program({ 0x9427 // SUB.b -(A7), D2 + }, 0x2002); + self.machine->set_registers([=](auto ®isters) { + registers.data[2] = 0x9c40; }); - self.machine->set_initial_stack_pointer(0x2002); - auto state = self.machine->get_processor_state(); - state.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); @@ -1461,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); @@ -1479,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); @@ -1509,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); @@ -1526,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); @@ -1542,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); @@ -1558,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); @@ -1584,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); @@ -1610,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); @@ -1626,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); @@ -1664,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); @@ -1683,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); @@ -1701,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 a3dcd8420..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); } @@ -155,17 +152,15 @@ - (void)testANDb_PostInc_A7 { _machine->set_program({ 0xc61f // AND.B (A7)+, D3 + }, 0x3000); + _machine->set_registers([=](auto ®isters){ + registers.data[3] = 0x54fff856; }); - _machine->set_initial_stack_pointer(0x3000); - auto state = _machine->get_processor_state(); - state.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); @@ -198,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); @@ -220,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); @@ -242,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); @@ -266,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); @@ -290,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); @@ -314,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); @@ -334,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); @@ -354,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); @@ -374,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); @@ -395,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()); @@ -411,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()); @@ -427,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()); @@ -443,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); @@ -465,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); @@ -487,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); @@ -509,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); @@ -531,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); @@ -555,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); } @@ -597,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); @@ -631,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); } @@ -676,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); } @@ -718,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); @@ -752,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); } @@ -798,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); } @@ -840,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); @@ -874,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); } @@ -919,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()); @@ -957,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()); @@ -990,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()); } @@ -1036,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()); @@ -1072,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()); } @@ -1088,8 +1053,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); @@ -1117,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()); @@ -1136,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); @@ -1161,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()); @@ -1198,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()); } @@ -1214,8 +1171,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); @@ -1243,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()); @@ -1259,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()); @@ -1276,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()); @@ -1293,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); @@ -1314,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); @@ -1333,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); @@ -1355,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); @@ -1379,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()); @@ -1415,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()); } @@ -1432,8 +1377,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); @@ -1461,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()); } @@ -1485,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/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 diff --git a/OSBindings/Mac/Clock SignalTests/68000ControlFlowTests.mm b/OSBindings/Mac/Clock SignalTests/68000ControlFlowTests.mm index 5e9559171..88ccae157 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,17 +144,15 @@ - (void)performCHKd1:(uint32_t)d1 d2:(uint32_t)d2 { _machine->set_program({ 0x4581 // CHK D1, D2 + }, 0); + _machine->set_registers([=](auto ®isters) { + registers.data[1] = d1; + registers.data[2] = d2; + registers.status |= ConditionCode::AllConditions; }); - 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); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.data[1], d1); XCTAssertEqual(state.registers.data[2], d2); } @@ -204,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); } @@ -385,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()); @@ -414,8 +408,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 +423,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 +450,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 +469,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; @@ -497,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); @@ -521,19 +510,18 @@ - (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; - 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 6704fd4ec..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()); @@ -292,15 +280,13 @@ - (void)testLINKA1_5 { _machine->set_program({ 0x4e51, 0x0005 // LINK a1, #5 + }, 0x22222222); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x11111111; }); - 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); - 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); @@ -311,8 +297,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,15 +311,13 @@ - (void)testLINKA1_8000 { _machine->set_program({ 0x4e51, 0x8000 // LINK a1, #$8000 + }, 0x22222222); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x11111111; }); - 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); - 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); @@ -348,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); @@ -371,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); @@ -395,19 +376,17 @@ - (void)testMOVEMl_fromEverything { _machine->set_program({ 0x48e4, 0xffff // MOVEM.L D0-D7/A0-A7, -(A4) + }, 0xffffffff); + _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; }); - 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); - state = _machine->get_processor_state(); + const auto state = _machine->get_processor_state(); XCTAssertEqual(state.registers.address[4], 0x3fc0); const uint32_t expected_values[] = { @@ -430,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); @@ -456,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; @@ -465,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); @@ -482,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); @@ -501,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); @@ -524,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); @@ -548,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); @@ -578,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); @@ -596,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); @@ -619,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); @@ -642,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); @@ -667,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); @@ -702,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()); @@ -718,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); @@ -736,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); @@ -754,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()); @@ -772,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); @@ -791,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); @@ -812,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); @@ -832,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); @@ -857,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()); @@ -873,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()); @@ -890,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()); @@ -907,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()); @@ -926,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()); @@ -944,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()); } @@ -961,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()); @@ -980,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); } @@ -995,15 +962,13 @@ - (void)testPEA_A1 { _machine->set_program({ 0x4851 // PEA (A1) + }, 0x1996); + _machine->set_registers([=](auto ®isters) { + registers.address[1] = 0x3000ffff; }); - 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); - 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); @@ -1014,8 +979,7 @@ - (void)testPEA_A7 { _machine->set_program({ 0x4857 // PEA (A7) - }); - _machine->set_initial_stack_pointer(0x1012); + }, 0x1012); _machine->run_for_instructions(1); @@ -1029,8 +993,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 +1007,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 +1021,7 @@ - (void)testPEA_XXXl { _machine->set_program({ 0x4879, 0x1234, 0x5678 // PEA ($12345678) - }); - _machine->set_initial_stack_pointer(0x1996); + }, 0x1996); _machine->run_for_instructions(1); @@ -1077,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); } @@ -1093,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); } @@ -1109,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); } @@ -1125,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); } @@ -1142,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); } @@ -1162,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); } @@ -1179,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()); @@ -1196,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()); @@ -1218,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()); @@ -1235,8 +1192,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/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 18cbe8e51..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); @@ -148,8 +146,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 414da9395..71ab51199 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" @@ -23,71 +24,63 @@ 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; + // 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 = 0x2700; + registers.program_counter = initial_pc(); + registers.supervisor_stack_pointer = stack_pointer; + m68000_.decode_from_state(registers); } - void set_initial_stack_pointer(uint32_t sp) { - ram_[0] = sp >> 16; - ram_[1] = sp & 0xffff; + 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) { --instructions_remaining_; + if(instructions_remaining_ < 0) { + throw StopException(); + } } void run_for_instructions(int count) { - instructions_remaining_ = count + (has_run_ ? 0 : 1); - finish_reset_if_needed(); + duration_ = HalfCycles(0); + 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_) { - has_run_ = true; - m68000_.run_for(HalfCycles(76)); - duration_ -= HalfCycles(76); - } - } - uint16_t *ram_at(uint32_t address) { return &ram_[(address >> 1) % ram_.size()]; } 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()) { @@ -123,10 +116,6 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { return m68000_.get_state(); } - void set_processor_state(const CPU::MC68000Mk2::State &state) { - m68000_.set_state(state); - } - auto &processor() { return m68000_; } @@ -140,11 +129,12 @@ class RAM68000: public CPU::MC68000Mk2::BusHandler { } private: - CPU::MC68000Mk2::Processor m68000_; + struct StopException {}; + + CPU::MC68000Mk2::Processor m68000_; std::array ram_{}; int instructions_remaining_; HalfCycles duration_; - bool has_run_ = false; }; #endif /* TestRunner68000_h */ 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 3519b7050..dd6ecd5cd 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, @@ -244,7 +245,7 @@ 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); } @@ -2612,6 +2613,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; +} } } 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) {}