1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Introduces failing test of 68000 opcode coverage.

This commit is contained in:
Thomas Harte 2019-04-25 22:06:05 -04:00
parent 7cbd5e0ef6
commit 3983f8303f
3 changed files with 94 additions and 0 deletions

View File

@ -308,6 +308,7 @@
4B9BE401203A0C0600FFAE60 /* MultiSpeaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9BE3FE203A0C0600FFAE60 /* MultiSpeaker.cpp */; };
4B9F11C92272375400701480 /* qltrace.txt.gz in Resources */ = {isa = PBXBuildFile; fileRef = 4B9F11C82272375400701480 /* qltrace.txt.gz */; };
4B9F11CA2272433900701480 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; };
4B9F11CC22729B3600701480 /* OPCLOGR2.BIN in Resources */ = {isa = PBXBuildFile; fileRef = 4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */; };
4BA0F68E1EEA0E8400E9489E /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA0F68C1EEA0E8400E9489E /* ZX8081.cpp */; };
4BA61EB01D91515900B3C876 /* NSData+StdVector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA61EAF1D91515900B3C876 /* NSData+StdVector.mm */; };
4BA91E1D216D85BA00F79557 /* MasterSystemVDPTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA91E1C216D85BA00F79557 /* MasterSystemVDPTests.mm */; };
@ -1040,6 +1041,7 @@
4B9BE3FE203A0C0600FFAE60 /* MultiSpeaker.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MultiSpeaker.cpp; sourceTree = "<group>"; };
4B9BE3FF203A0C0600FFAE60 /* MultiSpeaker.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MultiSpeaker.hpp; sourceTree = "<group>"; };
4B9F11C82272375400701480 /* qltrace.txt.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = qltrace.txt.gz; sourceTree = "<group>"; };
4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = OPCLOGR2.BIN; path = "68000 Coverage/OPCLOGR2.BIN"; sourceTree = "<group>"; };
4BA0F68C1EEA0E8400E9489E /* ZX8081.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ZX8081.cpp; path = Data/ZX8081.cpp; sourceTree = "<group>"; };
4BA0F68D1EEA0E8400E9489E /* ZX8081.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ZX8081.hpp; path = Data/ZX8081.hpp; sourceTree = "<group>"; };
4BA141C12073100800A31EC9 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
@ -1570,6 +1572,7 @@
4B018B88211930DE002A3937 /* 65C02_extended_opcodes_test.bin */,
4B44EBF61DC9883B00A7820C /* 6502_functional_test.bin */,
4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */,
4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */,
4BBF49B41ED2881600AB3669 /* FUSE */,
4B9F11C72272375400701480 /* QL Startup */,
4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */,
@ -3528,6 +3531,7 @@
4BB2997D1B587D8400A49093 /* ldxay in Resources */,
4BB299D71B587D8400A49093 /* staax in Resources */,
4B98A1CE1FFADEC500ADF63B /* MSX ROMs in Resources */,
4B9F11CC22729B3600701480 /* OPCLOGR2.BIN in Resources */,
4BB2990C1B587D8400A49093 /* asoax in Resources */,
4BB299191B587D8400A49093 /* bita in Resources */,
4BB2992A1B587D8400A49093 /* cia2ta in Resources */,

View File

@ -10,6 +10,7 @@
#include <array>
#include <cassert>
#include <set>
#include "68000.hpp"
@ -72,11 +73,88 @@ class RAM68000: public CPU::MC68000::BusHandler {
m68000_.set_state(state);
}
const CPU::MC68000::Processor<RAM68000, true> &processor() {
return m68000_;
}
private:
CPU::MC68000::Processor<RAM68000, true> m68000_;
std::vector<uint16_t> ram_;
};
class CPU::MC68000::ProcessorStorageTests {
public:
ProcessorStorageTests(const CPU::MC68000::ProcessorStorage &storage, const char *coverage_file_name) {
FILE *source = fopen(coverage_file_name, "rb");
// The file format here is [2 bytes opcode][2 ASCII characters:VA for valid, IN for invalid]...
// The file terminates with four additional bytes that begin with two zero bytes.
//
// The version of the file I grabbed seems to cover all opcodes, making their enumeration
// arguably redundant; the code below nevertheless uses the codes from the file.
//
// Similarly, I'm testing for exactly the strings VA or IN to ensure no further
// types creep into any updated version of the table that I then deal with incorrectly.
uint16_t last_observed = 0;
while(true) {
// Fetch opcode number.
uint16_t next_opcode = fgetc(source) << 8;
next_opcode |= fgetc(source);
if(next_opcode < last_observed) break;
last_observed = next_opcode;
// Determine whether it's meant to be valid.
char type[3];
type[0] = fgetc(source);
type[1] = fgetc(source);
type[2] = '\0';
if(!strcmp(type, "VA")) {
// Test for validity.
if(!storage.instructions[next_opcode].micro_operations) {
false_invalids_.insert(next_opcode);
}
continue;
}
if(!strcmp(type, "IN")) {
// Test for invalidity.
if(!storage.instructions[next_opcode].micro_operations) {
false_valids_.insert(next_opcode);
}
continue;
}
assert(false);
}
fclose(source);
}
NSString *false_valids() const {
return contents_of(false_valids_);
}
NSString *false_invalids() const {
return contents_of(false_invalids_);
}
private:
std::set<uint16_t> false_invalids_;
std::set<uint16_t> false_valids_;
static NSString *contents_of(const std::set<uint16_t> &set) {
NSMutableString *result = [[NSMutableString alloc] init];
for(auto value: set) {
[result appendFormat:@"%04x ", value];
}
return result;
}
};
@interface M68000Tests : XCTestCase
@end
@ -164,4 +242,15 @@ class RAM68000: public CPU::MC68000::BusHandler {
XCTAssert(state.data[2] == 0x303cfb2e, "D2 was %08x instead of 0x303cfb2e", state.data[2]);
}
- (void)testOpcodeCoverage {
// Perform an audit of implemented instructions.
CPU::MC68000::ProcessorStorageTests storage_tests(
_machine->processor(),
[[NSBundle bundleForClass:[self class]] pathForResource:@"OPCLOGR2" ofType:@"BIN"].UTF8String
);
XCTAssert(!storage_tests.false_valids().length, "Opcodes should be invalid but aren't: %@", storage_tests.false_valids());
XCTAssert(!storage_tests.false_invalids().length, "Opcodes should be valid but aren't: %@", storage_tests.false_invalids());
}
@end

View File

@ -387,6 +387,7 @@ class ProcessorStorage {
private:
friend class ProcessorStorageConstructor;
friend class ProcessorStorageTests;
};
#endif /* MC68000Storage_h */