mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-17 10:06:21 +00:00
Add CSL side of execution.
This commit is contained in:
parent
ba1879ef78
commit
0e30e2d865
@ -20,13 +20,18 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
Model model = Model::CPC464;
|
||||
std::string loading_command;
|
||||
|
||||
ReflectableEnum(CRTCType, Type0, Type1, Type2, Type3);
|
||||
CRTCType crtc_type = CRTCType::Type2;
|
||||
|
||||
// This is used internally for testing; it therefore isn't exposed reflectively.
|
||||
bool catch_ssm_codes = false;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::AmstradCPC) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(model);
|
||||
DeclareField(crtc_type);
|
||||
AnnounceEnum(Model);
|
||||
AnnounceEnum(CRTCType);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -542,6 +542,8 @@
|
||||
4B8805FB1DCFF807003085B1 /* Oric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F91DCFF807003085B1 /* Oric.cpp */; };
|
||||
4B882F592C2F9C6A00D84031 /* CPCShakerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B882F582C2F9C6900D84031 /* CPCShakerTests.mm */; };
|
||||
4B882F5B2C2F9C7700D84031 /* Shaker in Resources */ = {isa = PBXBuildFile; fileRef = 4B882F5A2C2F9C7700D84031 /* Shaker */; };
|
||||
4B882F5C2C32199400D84031 /* MachineForTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */; };
|
||||
4B882F5D2C3219A400D84031 /* AmstradCPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38F3461F2EC11D00D9235D /* AmstradCPC.cpp */; };
|
||||
4B89449520194CB3007DE474 /* MachineForTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */; };
|
||||
4B894518201967B4007DE474 /* ConfidenceCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8944E6201967B4007DE474 /* ConfidenceCounter.cpp */; };
|
||||
4B894519201967B4007DE474 /* ConfidenceCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8944E6201967B4007DE474 /* ConfidenceCounter.cpp */; };
|
||||
@ -6439,6 +6441,7 @@
|
||||
4B75F979280D7C5100121055 /* 68000DecoderTests.mm in Sources */,
|
||||
4B778F2C23A5EF0F0000D260 /* ZX8081.cpp in Sources */,
|
||||
4B778F3023A5F0C50000D260 /* Macintosh.cpp in Sources */,
|
||||
4B882F5C2C32199400D84031 /* MachineForTarget.cpp in Sources */,
|
||||
4B3BA0D11D318B44005DD7A7 /* TestMachine6502.mm in Sources */,
|
||||
4B778F4623A5F1D80000D260 /* StaticAnalyser.cpp in Sources */,
|
||||
4B778F1323A5EC890000D260 /* Z80Base.cpp in Sources */,
|
||||
@ -6562,6 +6565,7 @@
|
||||
4BDA7F8329C4EA28007A10A5 /* 6809OperationMapperTests.mm in Sources */,
|
||||
4B778F5723A5F2BB0000D260 /* ZX8081.cpp in Sources */,
|
||||
4B778F2F23A5F0B10000D260 /* ScanTarget.cpp in Sources */,
|
||||
4B882F5D2C3219A400D84031 /* AmstradCPC.cpp in Sources */,
|
||||
4B69DEB72AB79E4F0055B217 /* Instruction.cpp in Sources */,
|
||||
4BE90FFD22D5864800FB464D /* MacintoshVideoTests.mm in Sources */,
|
||||
4B4F478A25367EDC004245B8 /* 65816AddressingTests.swift in Sources */,
|
||||
|
@ -12,6 +12,18 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "CSL.hpp"
|
||||
#include "AmstradCPC.hpp"
|
||||
#include "../../../Analyser/Static/AmstradCPC/Target.hpp"
|
||||
#include "../../../Machines/AmstradCPC/Keyboard.hpp"
|
||||
#include "CSROMFetcher.hpp"
|
||||
#include "TimedMachine.hpp"
|
||||
#include "MediaTarget.hpp"
|
||||
#include "KeyboardMachine.hpp"
|
||||
#include "MachineForTarget.hpp"
|
||||
|
||||
struct CSLPerformer {
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Runs a local capture of the test cases found at https://shaker.logonsystem.eu
|
||||
@ -25,7 +37,110 @@
|
||||
- (void)testCSLPath:(NSString *)path name:(NSString *)name {
|
||||
using namespace Storage::Automation;
|
||||
const auto steps = CSL::parse([[path stringByAppendingPathComponent:name] UTF8String]);
|
||||
NSLog(@"%@ / %@", path, name);
|
||||
|
||||
std::unique_ptr<Machine::DynamicMachine> lazy_machine;
|
||||
CSL::KeyDelay key_delay;
|
||||
using Target = Analyser::Static::AmstradCPC::Target;
|
||||
Target target;
|
||||
target.catch_ssm_codes = true;
|
||||
|
||||
const auto machine = [&]() -> Machine::DynamicMachine& {
|
||||
if(!lazy_machine) {
|
||||
Machine::Error error;
|
||||
lazy_machine = Machine::MachineForTarget(&target, CSROMFetcher(), error);
|
||||
}
|
||||
return *lazy_machine;
|
||||
};
|
||||
const auto delay = [&](uint64_t micros) {
|
||||
machine().timed_machine()->run_for((double)micros / 1'000'000.0);
|
||||
};
|
||||
|
||||
using Type = CSL::Instruction::Type;
|
||||
int c = 0;
|
||||
for(const auto &step: steps) {
|
||||
switch(step.type) {
|
||||
case Type::Version:
|
||||
if(std::get<std::string>(step.argument) != "1.0") {
|
||||
XCTAssert(false, "Unrecognised file version");
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::CRTCSelect: {
|
||||
switch(std::get<uint64_t>(step.argument)) {
|
||||
default: break;
|
||||
case 0: target.crtc_type = Target::CRTCType::Type0; break;
|
||||
case 1: target.crtc_type = Target::CRTCType::Type1; break;
|
||||
case 2: target.crtc_type = Target::CRTCType::Type2; break;
|
||||
case 3: target.crtc_type = Target::CRTCType::Type3; break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case Type::Reset:
|
||||
// Temporarily a no-op.
|
||||
break;
|
||||
|
||||
case Type::Wait:
|
||||
delay(std::get<uint64_t>(step.argument));
|
||||
break;
|
||||
|
||||
case Type::DiskInsert: {
|
||||
const auto &disk = std::get<CSL::DiskInsert>(step.argument);
|
||||
XCTAssertEqual(disk.drive, 0); // Only drive 0 is supported for now.
|
||||
|
||||
NSString *diskName = [NSString stringWithUTF8String:disk.file.c_str()];
|
||||
NSString *const diskPath =
|
||||
[[NSBundle bundleForClass:[self class]]
|
||||
pathForResource:diskName ofType:nil inDirectory:@"Shaker"];
|
||||
|
||||
XCTAssertNotNil(diskPath);
|
||||
|
||||
const auto media = Analyser::Static::GetMedia(diskPath.UTF8String);
|
||||
machine().media_target()->insert_media(media);
|
||||
} break;
|
||||
|
||||
case Type::KeyDelay:
|
||||
key_delay = std::get<CSL::KeyDelay>(step.argument);
|
||||
break;
|
||||
|
||||
case Type::KeyOutput: {
|
||||
auto &key_target = *machine().keyboard_machine();
|
||||
|
||||
const auto &events = std::get<std::vector<CSL::KeyEvent>>(step.argument);
|
||||
bool last_down = false;
|
||||
for(const auto &event: events) {
|
||||
// Apply the interpress delay before if this is a second consecutive press;
|
||||
// if this is a release then apply the regular key delay.
|
||||
if(event.down && !last_down) {
|
||||
delay(key_delay.interpress_delay);
|
||||
} else if(!event.down) {
|
||||
delay(key_delay.press_delay);
|
||||
}
|
||||
|
||||
key_target.set_key_state(event.key, event.down);
|
||||
last_down = event.down;
|
||||
|
||||
// If this was the release of a carriage return, wait some more after release.
|
||||
if(key_delay.carriage_return_delay && (event.key == AmstradCPC::Key::KeyEnter || event.key == AmstradCPC::Key::KeyReturn)) {
|
||||
delay(*key_delay.carriage_return_delay);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case Type::LoadCSL:
|
||||
// Quick fix: just recurse.
|
||||
[self
|
||||
testCSLPath:path
|
||||
name:
|
||||
[NSString stringWithUTF8String:
|
||||
(std::get<std::string>(step.argument) + ".csl").c_str()
|
||||
]];
|
||||
break;
|
||||
|
||||
default:
|
||||
XCTAssert(false, "Unrecognised command: %d", step.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testModulePath:(NSString *)path name:(NSString *)name {
|
||||
|
@ -322,6 +322,10 @@ std::vector<CSL::Instruction> CSL::parse(const std::string &file_name) {
|
||||
std::string name;
|
||||
require(name);
|
||||
|
||||
// Crop the assumed opening and closing quotes.
|
||||
name.erase(name.end() - 1);
|
||||
name.erase(name.begin());
|
||||
|
||||
DiskInsert argument;
|
||||
if(name.size() == 1) {
|
||||
argument.drive = toupper(name[0]) - 'A';
|
||||
|
Loading…
Reference in New Issue
Block a user