mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Tidy up, and reduce for now to a summary report.
This commit is contained in:
parent
6c854e8ecc
commit
6594b38567
@ -99,8 +99,6 @@ struct Test68000 {
|
|||||||
|
|
||||||
- (void)setUp {
|
- (void)setUp {
|
||||||
// To limit tests run to a subset of files and/or of tests, uncomment and fill in below.
|
// To limit tests run to a subset of files and/or of tests, uncomment and fill in below.
|
||||||
// _fileSet = [NSSet setWithArray:@[@"dbcc.json"]];
|
|
||||||
// _testSet = [NSSet setWithArray:@[@"CHK 4190"]];
|
|
||||||
// _fileSet = [NSSet setWithArray:@[@"jmp_jsr.json"]];
|
// _fileSet = [NSSet setWithArray:@[@"jmp_jsr.json"]];
|
||||||
// _testSet = [NSSet setWithArray:@[@"CHK 41a8"]];
|
// _testSet = [NSSet setWithArray:@[@"CHK 41a8"]];
|
||||||
}
|
}
|
||||||
@ -118,20 +116,24 @@ struct Test68000 {
|
|||||||
for(NSURL *url in tests) {
|
for(NSURL *url in tests) {
|
||||||
// Compare against a file set if one has been supplied.
|
// Compare against a file set if one has been supplied.
|
||||||
if(_fileSet && ![_fileSet containsObject:[url lastPathComponent]]) continue;
|
if(_fileSet && ![_fileSet containsObject:[url lastPathComponent]]) continue;
|
||||||
NSLog(@"Testing %@", url);
|
// NSLog(@"Testing %@", url);
|
||||||
[self testJSONAtURL:url];
|
[self testJSONAtURL:url];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a summary of failures.
|
XCTAssert(_failures.count == 0);
|
||||||
NSLog(@"Total: %@", @(_failures.count));
|
|
||||||
NSLog(@"Failures: %@", _failures);
|
|
||||||
NSLog(@"Failing opcodes:");
|
|
||||||
|
|
||||||
InstructionSet::M68k::Predecoder<InstructionSet::M68k::Model::M68000> decoder;
|
// Output a summary of failures, if any.
|
||||||
for(NSNumber *number in _failingOpcodes) {
|
if(_failures.count) {
|
||||||
const auto decoded = decoder.decode(number.intValue);
|
NSLog(@"Total failures: %@", @(_failures.count));
|
||||||
const std::string description = decoded.to_string(number.intValue);
|
NSLog(@"Failures: %@", _failures);
|
||||||
NSLog(@"%04x %s", number.intValue, description.c_str());
|
NSLog(@"Failing opcodes:");
|
||||||
|
|
||||||
|
InstructionSet::M68k::Predecoder<InstructionSet::M68k::Model::M68000> decoder;
|
||||||
|
for(NSNumber *number in _failingOpcodes) {
|
||||||
|
const auto decoded = decoder.decode(number.intValue);
|
||||||
|
const std::string description = decoded.to_string(number.intValue);
|
||||||
|
NSLog(@"%04x %s", number.intValue, description.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,39 +281,44 @@ struct Test68000 {
|
|||||||
test68000->run_for_instructions(1, comparitor);
|
test68000->run_for_instructions(1, comparitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testOperationExecutor:(NSDictionary *)test name:(NSString *)name {
|
- (void)setInitialState:(NSDictionary *)test {
|
||||||
|
// Definitively erase any prior memory contents;
|
||||||
|
// 0xce is arbitrary but hopefully easier to spot
|
||||||
|
// in potential errors than e.g. 0x00 or 0xff.
|
||||||
memset(_test68000.ram.data(), 0xce, _test68000.ram.size());
|
memset(_test68000.ram.data(), 0xce, _test68000.ram.size());
|
||||||
|
|
||||||
{
|
// Apply initial memory state.
|
||||||
// Apply initial memory state.
|
NSArray<NSNumber *> *const initialMemory = test[@"initial memory"];
|
||||||
NSArray<NSNumber *> *const initialMemory = test[@"initial memory"];
|
NSEnumerator<NSNumber *> *enumerator = [initialMemory objectEnumerator];
|
||||||
NSEnumerator<NSNumber *> *enumerator = [initialMemory objectEnumerator];
|
while(true) {
|
||||||
while(true) {
|
NSNumber *const address = [enumerator nextObject];
|
||||||
NSNumber *const address = [enumerator nextObject];
|
NSNumber *const value = [enumerator nextObject];
|
||||||
NSNumber *const value = [enumerator nextObject];
|
|
||||||
|
|
||||||
if(!address || !value) break;
|
if(!address || !value) break;
|
||||||
_test68000.ram[address.integerValue] = value.integerValue;
|
_test68000.ram[address.integerValue] = value.integerValue;
|
||||||
}
|
|
||||||
|
|
||||||
// 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];
|
|
||||||
state.program_counter = uint32_t([initialState[@"pc"] 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] = 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];
|
||||||
|
state.program_counter = uint32_t([initialState[@"pc"] integerValue]);
|
||||||
|
_test68000.processor.set_state(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testOperationExecutor:(NSDictionary *)test name:(NSString *)name {
|
||||||
|
[self setInitialState:test];
|
||||||
|
|
||||||
// Run the thing.
|
// Run the thing.
|
||||||
_test68000.run_for_instructions(1);
|
_test68000.run_for_instructions(1);
|
||||||
|
|
||||||
@ -325,19 +332,19 @@ struct Test68000 {
|
|||||||
if(state.data[c] != [finalState[dX] integerValue]) [_failures addObject:name];
|
if(state.data[c] != [finalState[dX] integerValue]) [_failures addObject:name];
|
||||||
if(c < 7 && state.address[c] != [finalState[aX] integerValue]) [_failures addObject:name];
|
if(c < 7 && state.address[c] != [finalState[aX] integerValue]) [_failures addObject:name];
|
||||||
|
|
||||||
XCTAssertEqual(state.data[c], [finalState[dX] integerValue], @"%@: D%d inconsistent", name, c);
|
// XCTAssertEqual(state.data[c], [finalState[dX] integerValue], @"%@: D%d inconsistent", name, c);
|
||||||
if(c < 7) {
|
// if(c < 7) {
|
||||||
XCTAssertEqual(state.address[c], [finalState[aX] integerValue], @"%@: A%d inconsistent", name, c);
|
// XCTAssertEqual(state.address[c], [finalState[aX] integerValue], @"%@: A%d inconsistent", name, c);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
if(state.supervisor_stack_pointer != [finalState[@"a7"] integerValue]) [_failures addObject:name];
|
if(state.supervisor_stack_pointer != [finalState[@"a7"] integerValue]) [_failures addObject:name];
|
||||||
if(state.user_stack_pointer != [finalState[@"usp"] integerValue]) [_failures addObject:name];
|
if(state.user_stack_pointer != [finalState[@"usp"] integerValue]) [_failures addObject:name];
|
||||||
if(state.status != [finalState[@"sr"] integerValue]) [_failures addObject:name];
|
if(state.status != [finalState[@"sr"] integerValue]) [_failures addObject:name];
|
||||||
|
|
||||||
XCTAssertEqual(state.supervisor_stack_pointer, [finalState[@"a7"] integerValue], @"%@: A7 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.user_stack_pointer, [finalState[@"usp"] integerValue], @"%@: USP inconsistent", name);
|
||||||
XCTAssertEqual(state.status, [finalState[@"sr"] integerValue], @"%@: Status inconsistent", name);
|
// XCTAssertEqual(state.status, [finalState[@"sr"] integerValue], @"%@: Status inconsistent", name);
|
||||||
XCTAssertEqual(state.program_counter, [finalState[@"pc"] integerValue], @"%@: Program counter inconsistent", name);
|
// XCTAssertEqual(state.program_counter, [finalState[@"pc"] integerValue], @"%@: Program counter inconsistent", name);
|
||||||
|
|
||||||
// Test final memory state.
|
// Test final memory state.
|
||||||
NSArray<NSNumber *> *const finalMemory = test[@"final memory"];
|
NSArray<NSNumber *> *const finalMemory = test[@"final memory"];
|
||||||
@ -347,11 +354,12 @@ struct Test68000 {
|
|||||||
NSNumber *const value = [enumerator nextObject];
|
NSNumber *const value = [enumerator nextObject];
|
||||||
|
|
||||||
if(!address || !value) break;
|
if(!address || !value) break;
|
||||||
XCTAssertEqual(_test68000.ram[address.integerValue], value.integerValue, @"%@: Memory at location %@ inconsistent", name, address);
|
// XCTAssertEqual(_test68000.ram[address.integerValue], value.integerValue, @"%@: Memory at location %@ inconsistent", name, address);
|
||||||
if(_test68000.ram[address.integerValue] != value.integerValue) [_failures addObject:name];
|
if(_test68000.ram[address.integerValue] != value.integerValue) [_failures addObject:name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consider collating extra detail.
|
// If this test is now in the failures set, add the corresponding opcode for
|
||||||
|
// later logging.
|
||||||
if([_failures containsObject:name]) {
|
if([_failures containsObject:name]) {
|
||||||
[_failingOpcodes addObject:@(_test68000.read<uint16_t>(0x100, InstructionSet::M68k::FunctionCode()))];
|
[_failingOpcodes addObject:@(_test68000.read<uint16_t>(0x100, InstructionSet::M68k::FunctionCode()))];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user