mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Cleans up and formally introduces a comparative source for QL startup.
This commit is contained in:
parent
c132bda01c
commit
7df85ea695
@ -306,6 +306,8 @@
|
|||||||
4B98A1CE1FFADEC500ADF63B /* MSX ROMs in Resources */ = {isa = PBXBuildFile; fileRef = 4B98A1CD1FFADEC400ADF63B /* MSX ROMs */; };
|
4B98A1CE1FFADEC500ADF63B /* MSX ROMs in Resources */ = {isa = PBXBuildFile; fileRef = 4B98A1CD1FFADEC400ADF63B /* MSX ROMs */; };
|
||||||
4B9BE400203A0C0600FFAE60 /* MultiSpeaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9BE3FE203A0C0600FFAE60 /* MultiSpeaker.cpp */; };
|
4B9BE400203A0C0600FFAE60 /* MultiSpeaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9BE3FE203A0C0600FFAE60 /* MultiSpeaker.cpp */; };
|
||||||
4B9BE401203A0C0600FFAE60 /* MultiSpeaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9BE3FE203A0C0600FFAE60 /* MultiSpeaker.cpp */; };
|
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 */; };
|
||||||
4BA0F68E1EEA0E8400E9489E /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA0F68C1EEA0E8400E9489E /* ZX8081.cpp */; };
|
4BA0F68E1EEA0E8400E9489E /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA0F68C1EEA0E8400E9489E /* ZX8081.cpp */; };
|
||||||
4BA61EB01D91515900B3C876 /* NSData+StdVector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA61EAF1D91515900B3C876 /* NSData+StdVector.mm */; };
|
4BA61EB01D91515900B3C876 /* NSData+StdVector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA61EAF1D91515900B3C876 /* NSData+StdVector.mm */; };
|
||||||
4BA91E1D216D85BA00F79557 /* MasterSystemVDPTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA91E1C216D85BA00F79557 /* MasterSystemVDPTests.mm */; };
|
4BA91E1D216D85BA00F79557 /* MasterSystemVDPTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA91E1C216D85BA00F79557 /* MasterSystemVDPTests.mm */; };
|
||||||
@ -1037,6 +1039,7 @@
|
|||||||
4B98A1CD1FFADEC400ADF63B /* MSX ROMs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "MSX ROMs"; sourceTree = "<group>"; };
|
4B98A1CD1FFADEC400ADF63B /* MSX ROMs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "MSX ROMs"; sourceTree = "<group>"; };
|
||||||
4B9BE3FE203A0C0600FFAE60 /* MultiSpeaker.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MultiSpeaker.cpp; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
||||||
4BA0F68C1EEA0E8400E9489E /* ZX8081.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ZX8081.cpp; path = Data/ZX8081.cpp; 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>"; };
|
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>"; };
|
4BA141C12073100800A31EC9 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
|
||||||
@ -1495,6 +1498,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
4B9F11CA2272433900701480 /* libz.tbd in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -1567,6 +1571,7 @@
|
|||||||
4B44EBF61DC9883B00A7820C /* 6502_functional_test.bin */,
|
4B44EBF61DC9883B00A7820C /* 6502_functional_test.bin */,
|
||||||
4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */,
|
4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */,
|
||||||
4BBF49B41ED2881600AB3669 /* FUSE */,
|
4BBF49B41ED2881600AB3669 /* FUSE */,
|
||||||
|
4B9F11C72272375400701480 /* QL Startup */,
|
||||||
4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */,
|
4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */,
|
||||||
4BE9A6B21EDE294200CBCB47 /* Zexall */,
|
4BE9A6B21EDE294200CBCB47 /* Zexall */,
|
||||||
);
|
);
|
||||||
@ -2444,6 +2449,14 @@
|
|||||||
path = Implementation;
|
path = Implementation;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
4B9F11C72272375400701480 /* QL Startup */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4B9F11C82272375400701480 /* qltrace.txt.gz */,
|
||||||
|
);
|
||||||
|
path = "QL Startup";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
4BAB62AA1D3272D200DF5BA0 /* Disk */ = {
|
4BAB62AA1D3272D200DF5BA0 /* Disk */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -3633,6 +3646,7 @@
|
|||||||
4BB299A41B587D8400A49093 /* oraz in Resources */,
|
4BB299A41B587D8400A49093 /* oraz in Resources */,
|
||||||
4BB299611B587D8400A49093 /* insax in Resources */,
|
4BB299611B587D8400A49093 /* insax in Resources */,
|
||||||
4BB299351B587D8400A49093 /* cmpix in Resources */,
|
4BB299351B587D8400A49093 /* cmpix in Resources */,
|
||||||
|
4B9F11C92272375400701480 /* qltrace.txt.gz in Resources */,
|
||||||
4BB299041B587D8400A49093 /* aneb in Resources */,
|
4BB299041B587D8400A49093 /* aneb in Resources */,
|
||||||
4BB299BB1B587D8400A49093 /* rraa in Resources */,
|
4BB299BB1B587D8400A49093 /* rraa in Resources */,
|
||||||
4BB299091B587D8400A49093 /* aslz in Resources */,
|
4BB299091B587D8400A49093 /* aslz in Resources */,
|
||||||
|
BIN
OSBindings/Mac/Clock SignalTests/QL Startup/qltrace.txt.gz
Normal file
BIN
OSBindings/Mac/Clock SignalTests/QL Startup/qltrace.txt.gz
Normal file
Binary file not shown.
@ -14,24 +14,58 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "68000.hpp"
|
#include "68000.hpp"
|
||||||
#include "CSROMFetcher.hpp"
|
#include "CSROMFetcher.hpp"
|
||||||
|
|
||||||
class QL: public CPU::MC68000::BusHandler {
|
class QL: public CPU::MC68000::BusHandler {
|
||||||
public:
|
public:
|
||||||
QL(const std::vector<uint8_t> &rom) : m68000_(*this) {
|
QL(const std::vector<uint8_t> &rom, const char *trace_name) : m68000_(*this) {
|
||||||
assert(!(rom.size() & 1));
|
assert(!(rom.size() & 1));
|
||||||
rom_.resize(rom.size() / 2);
|
rom_.resize(rom.size() / 2);
|
||||||
|
|
||||||
for(size_t c = 0; c < rom_.size(); ++c) {
|
for(size_t c = 0; c < rom_.size(); ++c) {
|
||||||
rom_[c] = (rom[c << 1] << 8) | rom[(c << 1) + 1];
|
rom_[c] = (rom[c << 1] << 8) | rom[(c << 1) + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace = gzopen(trace_name, "rt");
|
||||||
|
}
|
||||||
|
|
||||||
|
~QL() {
|
||||||
|
gzclose(trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_for(HalfCycles cycles) {
|
void run_for(HalfCycles cycles) {
|
||||||
m68000_.run_for(cycles);
|
m68000_.run_for(cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void will_perform(uint32_t address, uint16_t opcode) {
|
||||||
|
// Obtain the next line from the trace file.
|
||||||
|
char correct_state[300];
|
||||||
|
gzgets(trace, correct_state, sizeof(correct_state));
|
||||||
|
++line_count;
|
||||||
|
|
||||||
|
// Generate state locally.
|
||||||
|
const auto state = m68000_.get_state();
|
||||||
|
char local_state[300];
|
||||||
|
sprintf(local_state, "%04x: %02x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x \n",
|
||||||
|
address,
|
||||||
|
state.status,
|
||||||
|
state.data[0], state.data[1], state.data[2], state.data[3], state.data[4], state.data[5], state.data[6], state.data[7],
|
||||||
|
state.address[0], state.address[1], state.address[2], state.address[3], state.address[4], state.address[5], state.address[6],
|
||||||
|
(state.status & 0x2000) ? state.supervisor_stack_pointer : state.user_stack_pointer
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check that the two coincide.
|
||||||
|
if(strcmp(correct_state, local_state)) {
|
||||||
|
fprintf(stderr, "Diverges at line %d\n", line_count);
|
||||||
|
fprintf(stderr, "Good: %s", correct_state);
|
||||||
|
fprintf(stderr, "Bad: %s", local_state);
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HalfCycles perform_bus_operation(const CPU::MC68000::Microcycle &cycle, int is_supervisor) {
|
HalfCycles perform_bus_operation(const CPU::MC68000::Microcycle &cycle, int is_supervisor) {
|
||||||
const uint32_t address = cycle.word_address();
|
const uint32_t address = cycle.word_address();
|
||||||
uint32_t word_address = address;
|
uint32_t word_address = address;
|
||||||
@ -52,22 +86,6 @@ class QL: public CPU::MC68000::BusHandler {
|
|||||||
using Microcycle = CPU::MC68000::Microcycle;
|
using Microcycle = CPU::MC68000::Microcycle;
|
||||||
if(cycle.data_select_active()) {
|
if(cycle.data_select_active()) {
|
||||||
uint16_t peripheral_result = 0xffff;
|
uint16_t peripheral_result = 0xffff;
|
||||||
/* if(is_peripheral) {
|
|
||||||
switch(address & 0x7ff) {
|
|
||||||
// A hard-coded value for TIMER B.
|
|
||||||
case (0xa21 >> 1):
|
|
||||||
peripheral_result = 0x00000001;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("Peripheral: %c %08x", (cycle.operation & Microcycle::Read) ? 'r' : 'w', *cycle.address);
|
|
||||||
if(!(cycle.operation & Microcycle::Read)) {
|
|
||||||
if(cycle.operation & Microcycle::SelectByte)
|
|
||||||
printf(" %02x", cycle.value->halves.low);
|
|
||||||
else
|
|
||||||
printf(" %04x", cycle.value->full);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
switch(cycle.operation & (Microcycle::SelectWord | Microcycle::SelectByte | Microcycle::Read)) {
|
switch(cycle.operation & (Microcycle::SelectWord | Microcycle::SelectByte | Microcycle::Read)) {
|
||||||
default: break;
|
default: break;
|
||||||
@ -93,10 +111,13 @@ class QL: public CPU::MC68000::BusHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CPU::MC68000::Processor<QL, true> m68000_;
|
CPU::MC68000::Processor<QL, true, true> m68000_;
|
||||||
|
|
||||||
std::vector<uint16_t> rom_;
|
std::vector<uint16_t> rom_;
|
||||||
std::array<uint16_t, 64*1024> ram_;
|
std::array<uint16_t, 64*1024> ram_;
|
||||||
|
|
||||||
|
int line_count = 0;
|
||||||
|
gzFile trace;
|
||||||
};
|
};
|
||||||
|
|
||||||
@interface QLTests : XCTestCase
|
@interface QLTests : XCTestCase
|
||||||
@ -106,18 +127,16 @@ class QL: public CPU::MC68000::BusHandler {
|
|||||||
std::unique_ptr<QL> _machine;
|
std::unique_ptr<QL> _machine;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::streambuf *coutbuf;
|
/*!
|
||||||
|
Tests the progression of Clock Signal's 68000 through the Sinclair QL's ROM against a known-good trace.
|
||||||
- (void)setUp {
|
*/
|
||||||
const auto roms = CSROMFetcher()("SinclairQL", {"js.rom"});
|
|
||||||
_machine.reset(new QL(*roms[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)testStartup {
|
- (void)testStartup {
|
||||||
// This is an example of a functional test case.
|
const auto roms = CSROMFetcher()("SinclairQL", {"js.rom"});
|
||||||
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
NSString *const traceLocation = [[NSBundle bundleForClass:[self class]] pathForResource:@"qltrace" ofType:@".txt.gz"];
|
||||||
_machine->run_for(HalfCycles(40000000));
|
_machine.reset(new QL(*roms[0], traceLocation.UTF8String));
|
||||||
|
|
||||||
|
// This is how many cycles it takes to exhaust the supplied trace file.
|
||||||
|
_machine->run_for(HalfCycles(23923191));
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user