From adf6723bf69e0834e272e88231d10b6a9a6f2502 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 14 Dec 2019 15:09:06 -0500 Subject: [PATCH] Ensures state is evaluated directly at opcode end. --- .../68000ComparativeTests.mm | 110 ++++++++++-------- 1 file changed, 60 insertions(+), 50 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm index eabcebe8c..a8f65ac4d 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm @@ -12,6 +12,7 @@ #include #include +#include @interface M68000ComparativeTests : XCTestCase @end @@ -50,12 +51,14 @@ struct Test68000: public CPU::MC68000::BusHandler { std::array ram; CPU::MC68000::Processor processor; + std::function comparitor; Test68000() : processor(*this) { } void will_perform(uint32_t address, uint16_t opcode) { --instructions_remaining_; + if(!instructions_remaining_) comparitor(); } HalfCycles perform_bus_operation(const CPU::MC68000::Microcycle &cycle, int is_supervisor) { @@ -66,8 +69,9 @@ return HalfCycles(0); } - void run_for_instructions(int instructions) { + void run_for_instructions(int instructions, const std::function &compare) { instructions_remaining_ = instructions + 1; // i.e. run up to the will_perform of the instruction after. + comparitor = std::move(compare); while(instructions_remaining_) { processor.run_for(HalfCycles(2)); } @@ -76,64 +80,70 @@ private: int instructions_remaining_; }; - auto test68000 = std::make_unique(); + auto uniqueTest68000 = std::make_unique(); + auto test68000 = uniqueTest68000.get(); + memset(test68000->ram.data(), 0xce, test68000->ram.size()); - // Apply initial memory state. - NSArray *const initialMemory = test[@"initial memory"]; - NSEnumerator *enumerator = [initialMemory objectEnumerator]; - while(true) { - NSNumber *const address = [enumerator nextObject]; - NSNumber *const value = [enumerator nextObject]; + { + // Apply initial memory state. + NSArray *const initialMemory = test[@"initial memory"]; + NSEnumerator *enumerator = [initialMemory objectEnumerator]; + while(true) { + NSNumber *const address = [enumerator nextObject]; + NSNumber *const value = [enumerator nextObject]; - if(!address || !value) break; - test68000->ram[address.integerValue ^ 1] = value.integerValue; // Effect a short-resolution endianness swap. + if(!address || !value) break; + test68000->ram[address.integerValue ^ 1] = value.integerValue; // Effect a short-resolution endianness swap. + } + + // Apply initial processor state. + NSDictionary *const initialState = test[@"initial state"]; + auto state = test68000->processor.get_state(); + for(int c = 0; c < 8; ++c) { + const NSString *dX = [@"d" stringByAppendingFormat:@"%d", c]; + const NSString *aX = [@"a" stringByAppendingFormat:@"%d", c]; + + state.data[c] = uint32_t([initialState[dX] integerValue]); + if(c < 7) + state.address[c] = uint32_t([initialState[aX] integerValue]); + } + state.supervisor_stack_pointer = uint32_t([initialState[@"a7"] integerValue]); + state.user_stack_pointer = uint32_t([initialState[@"usp"] integerValue]); + state.status = [initialState[@"sr"] integerValue]; + test68000->processor.set_state(state); } - // Apply initial processor state. - NSDictionary *const initialState = test[@"initial state"]; - auto state = test68000->processor.get_state(); - for(int c = 0; c < 8; ++c) { - const NSString *dX = [@"d" stringByAppendingFormat:@"%d", c]; - const NSString *aX = [@"a" stringByAppendingFormat:@"%d", c]; - - state.data[c] = [initialState[dX] integerValue]; - if(c < 7) - state.address[c] = [initialState[aX] integerValue]; - } - state.supervisor_stack_pointer = [initialState[@"a7"] integerValue]; - state.user_stack_pointer = [initialState[@"usp"] integerValue]; - state.status = [initialState[@"sr"] integerValue]; - test68000->processor.set_state(state); - // Run the thing. - test68000->run_for_instructions(1); + const auto comparitor = [=] { + // Test the end state. + NSDictionary *const finalState = test[@"final state"]; + const auto state = test68000->processor.get_state(); + for(int c = 0; c < 8; ++c) { + const NSString *dX = [@"d" stringByAppendingFormat:@"%d", c]; + const NSString *aX = [@"a" stringByAppendingFormat:@"%d", c]; - // Test the end state. - NSDictionary *const finalState = test[@"final state"]; - state = test68000->processor.get_state(); - for(int c = 0; c < 8; ++c) { - const NSString *dX = [@"d" stringByAppendingFormat:@"%d", c]; - const NSString *aX = [@"a" stringByAppendingFormat:@"%d", c]; - - XCTAssertEqual(state.data[c], [finalState[dX] integerValue], @"%@: D%d inconsistent", name, c); - if(c < 7) { - XCTAssertEqual(state.address[c], [finalState[aX] integerValue], @"%@: A%d inconsistent", name, c); + XCTAssertEqual(state.data[c], [finalState[dX] integerValue], @"%@: D%d inconsistent", name, c); + if(c < 7) { + XCTAssertEqual(state.address[c], [finalState[aX] integerValue], @"%@: A%d inconsistent", name, c); + } } - } - XCTAssertEqual(state.supervisor_stack_pointer, [finalState[@"a7"] integerValue], @"%@: A7 inconsistent", name); - XCTAssertEqual(state.user_stack_pointer, [finalState[@"usp"] integerValue], @"%@: USP inconsistent", name); - XCTAssertEqual(state.status, [finalState[@"sr"] integerValue], @"%@: Status inconsistent", name); + XCTAssertEqual(state.supervisor_stack_pointer, [finalState[@"a7"] integerValue], @"%@: A7 inconsistent", name); + XCTAssertEqual(state.user_stack_pointer, [finalState[@"usp"] integerValue], @"%@: USP inconsistent", name); + XCTAssertEqual(state.status, [finalState[@"sr"] integerValue], @"%@: Status inconsistent", name); - // Test final memory state. - NSArray *const finalMemory = test[@"final memory"]; - enumerator = [finalMemory objectEnumerator]; - while(true) { - NSNumber *const address = [enumerator nextObject]; - NSNumber *const value = [enumerator nextObject]; + // Test final memory state. + NSArray *const finalMemory = test[@"final memory"]; + NSEnumerator *enumerator = [finalMemory objectEnumerator]; + while(true) { + NSNumber *const address = [enumerator nextObject]; + NSNumber *const value = [enumerator nextObject]; - if(!address || !value) break; - XCTAssertEqual(test68000->ram[address.integerValue ^ 1], value.integerValue, @"%@: Memory at location %@ inconsistent", name, address); - } + if(!address || !value) break; + XCTAssertEqual(test68000->ram[address.integerValue ^ 1], value.integerValue, @"%@: Memory at location %@ inconsistent", name, address); + } + }; + + test68000->run_for_instructions(1, comparitor); } @end