From e46b12e359cadc7d58a34fca62fd45cbbc2a25cc Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 16 Jun 2024 14:27:48 -0400 Subject: [PATCH 01/19] Start parsing CSL. --- .../Clock Signal.xcodeproj/project.pbxproj | 18 +++ Storage/Automation/CSL.cpp | 134 ++++++++++++++++++ Storage/Automation/CSL.hpp | 72 ++++++++++ 3 files changed, 224 insertions(+) create mode 100644 Storage/Automation/CSL.cpp create mode 100644 Storage/Automation/CSL.hpp diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 341d4dbbf..805fa9c2c 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -180,6 +180,9 @@ 4B0F1C242605996900B85C66 /* ZXSpectrumTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1C212605996900B85C66 /* ZXSpectrumTAP.cpp */; }; 4B0F94FE208C1A1600FE41D9 /* NIB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F94FC208C1A1600FE41D9 /* NIB.cpp */; }; 4B0F94FF208C1A1600FE41D9 /* NIB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F94FC208C1A1600FE41D9 /* NIB.cpp */; }; + 4B1082C32C1A87CA00B07C5D /* CSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1082C02C1A87CA00B07C5D /* CSL.cpp */; }; + 4B1082C42C1F5E7D00B07C5D /* CSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1082C02C1A87CA00B07C5D /* CSL.cpp */; }; + 4B1082C52C1F60A900B07C5D /* CSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1082C02C1A87CA00B07C5D /* CSL.cpp */; }; 4B121F9B1E06293F00BFDA12 /* PCMSegmentEventSourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B121F9A1E06293F00BFDA12 /* PCMSegmentEventSourceTests.mm */; }; 4B12C0ED1FCFA98D005BFD93 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B12C0EB1FCFA98D005BFD93 /* Keyboard.cpp */; }; 4B12C0EE1FCFAD1A005BFD93 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B12C0EB1FCFA98D005BFD93 /* Keyboard.cpp */; }; @@ -1305,6 +1308,8 @@ 4B0F94FC208C1A1600FE41D9 /* NIB.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NIB.cpp; sourceTree = ""; }; 4B0F94FD208C1A1600FE41D9 /* NIB.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = NIB.hpp; sourceTree = ""; }; 4B0F9500208C42A300FE41D9 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = Target.hpp; path = AppleII/Target.hpp; sourceTree = ""; }; + 4B1082C02C1A87CA00B07C5D /* CSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSL.cpp; sourceTree = ""; }; + 4B1082C12C1A87CA00B07C5D /* CSL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CSL.hpp; sourceTree = ""; }; 4B121F9A1E06293F00BFDA12 /* PCMSegmentEventSourceTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PCMSegmentEventSourceTests.mm; sourceTree = ""; }; 4B12C0EB1FCFA98D005BFD93 /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = ""; }; 4B12C0EC1FCFA98D005BFD93 /* Keyboard.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Keyboard.hpp; sourceTree = ""; }; @@ -2688,6 +2693,15 @@ path = Keyboard; sourceTree = ""; }; + 4B1082C22C1A87CA00B07C5D /* Automation */ = { + isa = PBXGroup; + children = ( + 4B1082C02C1A87CA00B07C5D /* CSL.cpp */, + 4B1082C12C1A87CA00B07C5D /* CSL.hpp */, + ); + path = Automation; + sourceTree = ""; + }; 4B1414561B58879D00E04248 /* 6502 */ = { isa = PBXGroup; children = ( @@ -3326,6 +3340,7 @@ 4BAB62AE1D32730D00DF5BA0 /* Storage.hpp */, 4BF4A2D91F534DB300B171F4 /* TargetPlatforms.hpp */, 4BB697CA1D4B6D3E00248BDF /* TimedEventLoop.hpp */, + 4B1082C22C1A87CA00B07C5D /* Automation */, 4BEE0A691D72496600532C7B /* Cartridge */, 4B8805F81DCFF6CD003085B1 /* Data */, 4BAB62AA1D3272D200DF5BA0 /* Disk */, @@ -5918,6 +5933,7 @@ 4B055AAC1FAE85FD0060FFFF /* PCMSegment.cpp in Sources */, 4BB307BC235001C300457D33 /* 6850.cpp in Sources */, 4B055AB31FAE860F0060FFFF /* CSW.cpp in Sources */, + 4B1082C52C1F60A900B07C5D /* CSL.cpp in Sources */, 4B89451D201967B4007DE474 /* Disk.cpp in Sources */, 4BFEA2F02682A7B900EBF94C /* Dave.cpp in Sources */, 4B4C81C628B3C5CD00F84AE9 /* SCSICard.cpp in Sources */, @@ -6084,6 +6100,7 @@ 4BAF2B4E2004580C00480230 /* DMK.cpp in Sources */, 4BB697CE1D4BA44400248BDF /* CommodoreGCR.cpp in Sources */, 4B5B37312777C7FC0047F238 /* IPF.cpp in Sources */, + 4B1082C42C1F5E7D00B07C5D /* CSL.cpp in Sources */, 4B0ACC3023775819008902D0 /* TIASound.cpp in Sources */, 4B7136861F78724F008B8ED9 /* Encoder.cpp in Sources */, 4B0E04EA1FC9E5DA00F43484 /* CAS.cpp in Sources */, @@ -6372,6 +6389,7 @@ 4B778F4A23A5F1FB0000D260 /* StaticAnalyser.cpp in Sources */, 4B7752AB28217E560073E2C5 /* SZX.cpp in Sources */, 4BD91D772401C2B8007BDC91 /* PatrikRakTests.swift in Sources */, + 4B1082C32C1A87CA00B07C5D /* CSL.cpp in Sources */, 4B680CE223A5553100451D43 /* 68000ComparativeTests.mm in Sources */, 4B778F3723A5F11C0000D260 /* Parser.cpp in Sources */, 4B778F4523A5F1CD0000D260 /* SegmentParser.cpp in Sources */, diff --git a/Storage/Automation/CSL.cpp b/Storage/Automation/CSL.cpp new file mode 100644 index 000000000..67033e722 --- /dev/null +++ b/Storage/Automation/CSL.cpp @@ -0,0 +1,134 @@ +// +// CSL.cpp +// Clock Signal +// +// Created by Thomas Harte on 12/06/2024. +// Copyright © 2024 Thomas Harte. All rights reserved. +// + +#include "CSL.hpp" + +#include +#include +#include +#include + +using namespace Storage::Automation; + + +struct CSLTest { + CSLTest() { + CSL c("/Users/thomasharte/Downloads/Shaker_CSL/MODULE A/SHAKE26A-4.CSL"); + } + +}; +CSLTest test; + +CSL::CSL(const std::string &file_name) { + // Parse the entire file ahead of time; this isn't necessary but introduces + // little significant overhead and greatly simplifies my debugging. + + std::ifstream file; + file.open(file_name); + + using Type = Instruction::Type; + static const std::unordered_map keywords = { + {"csl_version", Type::Version}, + {"reset", Type::Reset}, + {"crtc_select", Type::CRTCSelect}, + {"disk_insert", Type::DiskInsert}, + {"disk_dir", Type::SetDiskDir}, + {"tape_insert", Type::TapeInsert}, + {"tape_dir", Type::SetTapeDir}, + {"tape_play", Type::TapeInsert}, + {"tape_stop", Type::TapeStop}, + {"tape_rewind", Type::TapeRewind}, + {"snapshot_load", Type::SnapshotLoad}, + {"snapshot_dir", Type::SetSnapshotDir}, + {"key_delay", Type::KeyDelay}, + {"key_output", Type::KeyOutput}, + {"key_from_file", Type::KeyFromFile}, + {"wait", Type::Wait}, + {"wait_driveonoff", Type::WaitDriveOnOff}, + {"wait_ssm0000", Type::WaitSSM0000}, + {"screenshot_name", Type::SetScreenshotName}, + {"screenshot_dir", Type::SetScreenshotDir}, + {"screenshot", Type::Screenshot}, + {"snapshot_name", Type::SetSnapshotDir}, + {"csl_load", Type::LoadCSL}, + }; + + for(std::string line; std::getline(file, line); ) { + // Ignore comments. + if(line[0] == ';') { + continue; + } + + std::istringstream stream(line); + std::string keyword; + stream >> keyword; + + const auto key_pair = keywords.find(keyword); + if(key_pair == keywords.end()) { + throw InvalidKeyword; + } + + Instruction instruction; + instruction.type = key_pair->second; + + const auto require = [&](auto &&target) { + stream >> target; + if(!stream.good()) { + throw InvalidArgument; + } + }; + + switch(instruction.type) { + // Keywords with a single string mandatory argument. + case Type::Version: { + std::string argument; + require(argument); + instruction.argument = argument; + } break; + + // Keywords with a single number mandatory argument. + case Type::Wait: { + uint64_t argument; + require(argument); + instruction.argument = argument; + } break; + + // Miscellaneous: + case Type::Reset: { + std::string type; + stream >> type; + if(stream.good()) { + if(type != "soft" && type != "hard") { + throw InvalidArgument; + } + instruction.argument = (type == "soft") ? ResetType::Soft : ResetType::Hard; + } + } break; + + case Type::CRTCSelect: { + std::string type; + require(type); + + static const std::set allowed_types = { + "0", "1", "1A", "1B", "2", "3", "4", + }; + if(allowed_types.find(type) == allowed_types.end()) { + throw InvalidArgument; + } + + instruction.argument = static_cast(std::stoi(type)); + } break; + + default: + printf(""); + break; + } + + instructions.push_back(std::move(instruction)); + } +} diff --git a/Storage/Automation/CSL.hpp b/Storage/Automation/CSL.hpp new file mode 100644 index 000000000..cf9fc962a --- /dev/null +++ b/Storage/Automation/CSL.hpp @@ -0,0 +1,72 @@ +// +// CSL.hpp +// Clock Signal +// +// Created by Thomas Harte on 12/06/2024. +// Copyright © 2024 Thomas Harte. All rights reserved. +// + +#pragma once + +#include +#include +#include + +namespace Storage::Automation { + +struct CSL { + CSL(const std::string &file_name); + + enum Errors { + InvalidKeyword, + InvalidArgument, + }; + + private: + enum ResetType { + Hard, Soft + }; + + struct Instruction { + enum class Type { + Version, + Reset, + CRTCSelect, + LoadCSL, + + DiskInsert, + SetDiskDir, + + TapeInsert, + SetTapeDir, + TapePlay, + TapeStop, + TapeRewind, + + SetSnapshotDir, + SnapshotLoad, + SetSnapshotName, + Snapshot, + + KeyDelay, + KeyOutput, + KeyFromFile, + + Wait, + WaitDriveOnOff, + WaitVsyncOnOff, + WaitSSM0000, + + SetScreenshotName, + SetScreenshotDir, + Screenshot, + } type; + + std::variant argument; + }; + + std::vector instructions; + std::optional next(); +}; + +} From 09e8d4ba0a97f24e93877891cbd0ea87f2e065df Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 18 Jun 2024 22:16:23 -0400 Subject: [PATCH 02/19] Do enough to parse sample files. --- Storage/Automation/CSL.cpp | 235 ++++++++++++++++++++++++++++++++++--- Storage/Automation/CSL.hpp | 128 +++++++++++--------- 2 files changed, 293 insertions(+), 70 deletions(-) diff --git a/Storage/Automation/CSL.cpp b/Storage/Automation/CSL.cpp index 67033e722..fc8845566 100644 --- a/Storage/Automation/CSL.cpp +++ b/Storage/Automation/CSL.cpp @@ -8,26 +8,26 @@ #include "CSL.hpp" +#include #include #include #include #include -using namespace Storage::Automation; +#include "../../Machines/AmstradCPC/Keyboard.hpp" +using namespace Storage::Automation; struct CSLTest { CSLTest() { - CSL c("/Users/thomasharte/Downloads/Shaker_CSL/MODULE A/SHAKE26A-4.CSL"); + CSL::parse("/Users/thomasharte/Downloads/Shaker_CSL/MODULE A/SHAKE26A-4.CSL"); } }; CSLTest test; -CSL::CSL(const std::string &file_name) { - // Parse the entire file ahead of time; this isn't necessary but introduces - // little significant overhead and greatly simplifies my debugging. - +std::vector CSL::parse(const std::string &file_name) { + std::vector instructions; std::ifstream file; file.open(file_name); @@ -43,7 +43,7 @@ CSL::CSL(const std::string &file_name) { {"tape_play", Type::TapeInsert}, {"tape_stop", Type::TapeStop}, {"tape_rewind", Type::TapeRewind}, - {"snapshot_load", Type::SnapshotLoad}, + {"snapshot_load", Type::LoadSnapshot}, {"snapshot_dir", Type::SetSnapshotDir}, {"key_delay", Type::KeyDelay}, {"key_output", Type::KeyOutput}, @@ -59,8 +59,8 @@ CSL::CSL(const std::string &file_name) { }; for(std::string line; std::getline(file, line); ) { - // Ignore comments. - if(line[0] == ';') { + // Ignore comments and empty lines. + if(line.empty() || line[0] == ';') { continue; } @@ -68,6 +68,11 @@ CSL::CSL(const std::string &file_name) { std::string keyword; stream >> keyword; + // Second way for a line to be empty: purely whitespace. + if(keyword.empty()) { + continue; + } + const auto key_pair = keywords.find(keyword); if(key_pair == keywords.end()) { throw InvalidKeyword; @@ -76,22 +81,77 @@ CSL::CSL(const std::string &file_name) { Instruction instruction; instruction.type = key_pair->second; + // TODO: strings are encoded specially in order to capture whitespace. + // They're surrounded in single quotes with some special keys escaped. const auto require = [&](auto &&target) { stream >> target; - if(!stream.good()) { + if(stream.fail()) { throw InvalidArgument; } }; switch(instruction.type) { - // Keywords with a single string mandatory argument. + // Keywords with no argument. + case Type::TapePlay: + case Type::TapeStop: + case Type::TapeRewind: + case Type::WaitVsyncOnOff: + case Type::WaitSSM0000: + break; + + // Keywords with a single string mandatory argument + // that can be directly captured as a string. case Type::Version: { std::string argument; require(argument); instruction.argument = argument; } break; + // Keywords with a single string mandatory argument + // that is within quotes but otherwise directly usable + // as a string. + case Type::LoadCSL: + case Type::SetScreenshotDir: + case Type::SetScreenshotName: + case Type::SetSnapshotDir: + case Type::SetSnapshotName: + case Type::LoadSnapshot: + case Type::SetTapeDir: + case Type::TapeInsert: + case Type::SetDiskDir: + case Type::KeyFromFile: { + std::string argument; + + char next; + stream >> next; + if(next != '\'') { + throw InvalidArgument; + } + + while(true) { + next = stream.get(); + + // Take a bit of a random guess about what's escaped + // in regular string arguments. + if(next == '\\' && stream.peek() == '(') { + stream.get(); + if(stream.peek() != '\'') { + argument.push_back('\\'); + argument.push_back('('); + continue; + } + } + + if(next == '\'') { + break; + } + argument.push_back(next); + } + instruction.argument = argument; + } break; + // Keywords with a single number mandatory argument. + case Type::WaitDriveOnOff: case Type::Wait: { uint64_t argument; require(argument); @@ -99,14 +159,28 @@ CSL::CSL(const std::string &file_name) { } break; // Miscellaneous: + case Type::Snapshot: + case Type::Screenshot: { + std::string vsync; + stream >> vsync; + if(stream.fail()) { + instruction.argument = ScreenshotOrSnapshot::Now; + break; + } + if(vsync != "vsync") { + throw InvalidArgument; + } + instruction.argument = ScreenshotOrSnapshot::WaitForVSync; + } break; + case Type::Reset: { std::string type; stream >> type; - if(stream.good()) { + if(!stream.fail()) { if(type != "soft" && type != "hard") { throw InvalidArgument; } - instruction.argument = (type == "soft") ? ResetType::Soft : ResetType::Hard; + instruction.argument = (type == "soft") ? Reset::Soft : Reset::Hard; } } break; @@ -124,11 +198,140 @@ CSL::CSL(const std::string &file_name) { instruction.argument = static_cast(std::stoi(type)); } break; - default: - printf(""); - break; + case Type::DiskInsert: { + std::string name; + require(name); + + DiskInsert argument; + if(name.size() == 1) { + argument.drive = toupper(name[0]) - 'A'; + require(name); + } + + argument.file = name; + instruction.argument = argument; + } break; + + case Type::KeyOutput: { + std::vector argument; + + char next; + stream >> next; + if(next != '\'') { + throw InvalidArgument; + } + + const auto press = [&](uint16_t key) { + KeyEvent event; + event.key = key; + event.down = true; + argument.push_back(event); + event.down = false; + argument.push_back(event); + }; + const auto shift = [&](uint16_t key) { + KeyEvent event; + event.key = AmstradCPC::Key::KeyShift; + event.down = true; + argument.push_back(event); + press(key); + event.down = false; + argument.push_back(event); + }; + + bool done = false; + while(!done) { + next = stream.get(); + + switch(next) { + default: throw InvalidArgument; + case '\'': + done = true; + break; + + case 'A': press(AmstradCPC::Key::KeyA); break; + case 'B': press(AmstradCPC::Key::KeyB); break; + case 'C': press(AmstradCPC::Key::KeyC); break; + case 'D': press(AmstradCPC::Key::KeyD); break; + case 'E': press(AmstradCPC::Key::KeyE); break; + case 'F': press(AmstradCPC::Key::KeyF); break; + case 'G': press(AmstradCPC::Key::KeyG); break; + case 'H': press(AmstradCPC::Key::KeyH); break; + case 'I': press(AmstradCPC::Key::KeyI); break; + case 'J': press(AmstradCPC::Key::KeyJ); break; + case 'K': press(AmstradCPC::Key::KeyK); break; + case 'L': press(AmstradCPC::Key::KeyL); break; + case 'M': press(AmstradCPC::Key::KeyM); break; + case 'N': press(AmstradCPC::Key::KeyN); break; + case 'O': press(AmstradCPC::Key::KeyO); break; + case 'P': press(AmstradCPC::Key::KeyP); break; + case 'Q': press(AmstradCPC::Key::KeyQ); break; + case 'R': press(AmstradCPC::Key::KeyR); break; + case 'S': press(AmstradCPC::Key::KeyS); break; + case 'T': press(AmstradCPC::Key::KeyT); break; + case 'U': press(AmstradCPC::Key::KeyU); break; + case 'V': press(AmstradCPC::Key::KeyV); break; + case 'W': press(AmstradCPC::Key::KeyW); break; + case 'X': press(AmstradCPC::Key::KeyX); break; + case 'Y': press(AmstradCPC::Key::KeyY); break; + case 'Z': press(AmstradCPC::Key::KeyZ); break; + case ' ': press(AmstradCPC::Key::KeySpace); break; + case '0': press(AmstradCPC::Key::Key0); break; + case '1': press(AmstradCPC::Key::Key1); break; + case '2': press(AmstradCPC::Key::Key2); break; + case '3': press(AmstradCPC::Key::Key3); break; + case '4': press(AmstradCPC::Key::Key4); break; + case '5': press(AmstradCPC::Key::Key5); break; + case '6': press(AmstradCPC::Key::Key6); break; + case '7': press(AmstradCPC::Key::Key7); break; + case '8': press(AmstradCPC::Key::Key8); break; + case '9': press(AmstradCPC::Key::Key9); break; + + case '"': shift(AmstradCPC::Key::Key2); break; + + case '\\': { + if(stream.peek() != '(') { + press(AmstradCPC::Key::KeyBackSlash); + break; + } + stream.get(); + + std::string name; + while(stream.peek() != ')') { + name.push_back(char(stream.get())); + } + stream.get(); + + if(name == "ESC") { + press(AmstradCPC::Key::KeyEscape); + } else if(name == "TAB") { + press(AmstradCPC::Key::KeyTab); + } else if(name == "RET") { + press(AmstradCPC::Key::KeyEnter); + } + + } break; + } + } + instruction.argument = argument; + } break; + + case Type::KeyDelay: { + KeyDelay argument; + require(argument.press_delay); + require(argument.interpress_delay); + + uint64_t carriage_return_delay; + stream >> carriage_return_delay; + if(!stream.fail()) { + argument.carriage_return_delay = carriage_return_delay; + } + instruction.argument = argument; + } break; } instructions.push_back(std::move(instruction)); } + + return instructions; } diff --git a/Storage/Automation/CSL.hpp b/Storage/Automation/CSL.hpp index cf9fc962a..032238402 100644 --- a/Storage/Automation/CSL.hpp +++ b/Storage/Automation/CSL.hpp @@ -8,65 +8,85 @@ #pragma once +#include #include #include #include -namespace Storage::Automation { +namespace Storage::Automation::CSL { -struct CSL { - CSL(const std::string &file_name); - - enum Errors { - InvalidKeyword, - InvalidArgument, - }; - - private: - enum ResetType { - Hard, Soft - }; - - struct Instruction { - enum class Type { - Version, - Reset, - CRTCSelect, - LoadCSL, - - DiskInsert, - SetDiskDir, - - TapeInsert, - SetTapeDir, - TapePlay, - TapeStop, - TapeRewind, - - SetSnapshotDir, - SnapshotLoad, - SetSnapshotName, - Snapshot, - - KeyDelay, - KeyOutput, - KeyFromFile, - - Wait, - WaitDriveOnOff, - WaitVsyncOnOff, - WaitSSM0000, - - SetScreenshotName, - SetScreenshotDir, - Screenshot, - } type; - - std::variant argument; - }; - - std::vector instructions; - std::optional next(); +enum Reset { + Hard, Soft +}; +struct DiskInsert { + int drive = 0; + std::string file; +}; +enum ScreenshotOrSnapshot { + WaitForVSync, Now, +}; +struct KeyDelay { + uint64_t press_delay; + uint64_t interpress_delay; + std::optional carriage_return_delay; +}; +struct KeyEvent { + bool down; + uint16_t key; }; +struct Instruction { + enum class Type { + Version, + Reset, + CRTCSelect, + LoadCSL, + + DiskInsert, + SetDiskDir, + + TapeInsert, + SetTapeDir, + TapePlay, + TapeStop, + TapeRewind, + + SetSnapshotDir, + LoadSnapshot, + SetSnapshotName, + Snapshot, + + KeyDelay, + KeyOutput, + KeyFromFile, + + Wait, + WaitDriveOnOff, + WaitVsyncOnOff, + WaitSSM0000, + + SetScreenshotName, + SetScreenshotDir, + Screenshot, + } type; + + std::variant< + std::monostate, + DiskInsert, + Reset, + ScreenshotOrSnapshot, + KeyDelay, + std::string, + std::vector, + uint64_t + > argument; +}; + + +enum Errors { + InvalidKeyword, + InvalidArgument, +}; +std::vector parse(const std::string &file_name); + } From 63737c09aa8ec2e30457ffe12e40369d116dd6f6 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 20 Jun 2024 22:13:19 -0400 Subject: [PATCH 03/19] Improve handling of compound sequences. --- Storage/Automation/CSL.cpp | 228 ++++++++++++++++++++++--------------- 1 file changed, 136 insertions(+), 92 deletions(-) diff --git a/Storage/Automation/CSL.cpp b/Storage/Automation/CSL.cpp index fc8845566..52a4e9666 100644 --- a/Storage/Automation/CSL.cpp +++ b/Storage/Automation/CSL.cpp @@ -18,6 +18,8 @@ using namespace Storage::Automation; +namespace { + struct CSLTest { CSLTest() { CSL::parse("/Users/thomasharte/Downloads/Shaker_CSL/MODULE A/SHAKE26A-4.CSL"); @@ -26,6 +28,131 @@ struct CSLTest { }; CSLTest test; +bool append_typed(std::vector &down, std::vector &up, std::istringstream &stream) { + const auto press = [&](uint16_t key) { + CSL::KeyEvent event; + event.key = key; + event.down = true; + down.push_back(event); + event.down = false; + up.push_back(event); + }; + + const auto shift = [&](uint16_t key) { + CSL::KeyEvent event; + event.key = AmstradCPC::Key::KeyShift; + event.down = true; + down.push_back(event); + press(key); + event.down = false; + up.push_back(event); + }; + + const auto next = stream.get(); + if(stream.eof()) return false; + + switch(next) { + default: throw CSL::InvalidArgument; + case '\'': return false; + case '}': return false; + + case 'A': press(AmstradCPC::Key::KeyA); break; + case 'B': press(AmstradCPC::Key::KeyB); break; + case 'C': press(AmstradCPC::Key::KeyC); break; + case 'D': press(AmstradCPC::Key::KeyD); break; + case 'E': press(AmstradCPC::Key::KeyE); break; + case 'F': press(AmstradCPC::Key::KeyF); break; + case 'G': press(AmstradCPC::Key::KeyG); break; + case 'H': press(AmstradCPC::Key::KeyH); break; + case 'I': press(AmstradCPC::Key::KeyI); break; + case 'J': press(AmstradCPC::Key::KeyJ); break; + case 'K': press(AmstradCPC::Key::KeyK); break; + case 'L': press(AmstradCPC::Key::KeyL); break; + case 'M': press(AmstradCPC::Key::KeyM); break; + case 'N': press(AmstradCPC::Key::KeyN); break; + case 'O': press(AmstradCPC::Key::KeyO); break; + case 'P': press(AmstradCPC::Key::KeyP); break; + case 'Q': press(AmstradCPC::Key::KeyQ); break; + case 'R': press(AmstradCPC::Key::KeyR); break; + case 'S': press(AmstradCPC::Key::KeyS); break; + case 'T': press(AmstradCPC::Key::KeyT); break; + case 'U': press(AmstradCPC::Key::KeyU); break; + case 'V': press(AmstradCPC::Key::KeyV); break; + case 'W': press(AmstradCPC::Key::KeyW); break; + case 'X': press(AmstradCPC::Key::KeyX); break; + case 'Y': press(AmstradCPC::Key::KeyY); break; + case 'Z': press(AmstradCPC::Key::KeyZ); break; + case ' ': press(AmstradCPC::Key::KeySpace); break; + case '0': press(AmstradCPC::Key::Key0); break; + case '1': press(AmstradCPC::Key::Key1); break; + case '2': press(AmstradCPC::Key::Key2); break; + case '3': press(AmstradCPC::Key::Key3); break; + case '4': press(AmstradCPC::Key::Key4); break; + case '5': press(AmstradCPC::Key::Key5); break; + case '6': press(AmstradCPC::Key::Key6); break; + case '7': press(AmstradCPC::Key::Key7); break; + case '8': press(AmstradCPC::Key::Key8); break; + case '9': press(AmstradCPC::Key::Key9); break; + + case '"': shift(AmstradCPC::Key::Key2); break; + + case '\\': { + if(stream.peek() != '(') { + press(AmstradCPC::Key::KeyBackSlash); + break; + } + stream.get(); + + std::string name; + while(stream.peek() != ')') { + name.push_back(char(stream.get())); + } + stream.get(); + + static const std::unordered_map names = { + {"ESC", AmstradCPC::Key::KeyEscape}, + {"TAB", AmstradCPC::Key::KeyTab}, + {"CAP", AmstradCPC::Key::KeyCapsLock}, + {"SHI", AmstradCPC::Key::KeyShift}, + {"CTR", AmstradCPC::Key::KeyControl}, + {"COP", AmstradCPC::Key::KeyCopy}, + {"CLR", AmstradCPC::Key::KeyClear}, + {"DEL", AmstradCPC::Key::KeyDelete}, + {"RET", AmstradCPC::Key::KeyReturn}, + {"ENT", AmstradCPC::Key::KeyEnter}, + {"ARL", AmstradCPC::Key::KeyLeft}, + {"ARR", AmstradCPC::Key::KeyRight}, + {"ARU", AmstradCPC::Key::KeyUp}, + {"ARD", AmstradCPC::Key::KeyDown}, + {"FN0", AmstradCPC::Key::KeyF0}, + {"FN1", AmstradCPC::Key::KeyF1}, + {"FN2", AmstradCPC::Key::KeyF2}, + {"FN3", AmstradCPC::Key::KeyF3}, + {"FN4", AmstradCPC::Key::KeyF4}, + {"FN5", AmstradCPC::Key::KeyF5}, + {"FN6", AmstradCPC::Key::KeyF6}, + {"FN7", AmstradCPC::Key::KeyF7}, + {"FN8", AmstradCPC::Key::KeyF8}, + {"FN9", AmstradCPC::Key::KeyF9}, + //TODO: { } \ ' KOF + }; + const auto name_pair = names.find(name); + if(name_pair == names.end()) { + throw CSL::InvalidArgument; + } + press(name_pair->second); + } break; + + case '{': + while(append_typed(down, up, stream)); + break; + } + + return true; +} + +} + std::vector CSL::parse(const std::string &file_name) { std::vector instructions; std::ifstream file; @@ -129,7 +256,8 @@ std::vector CSL::parse(const std::string &file_name) { } while(true) { - next = stream.get(); + next = static_cast(stream.get()); + if(stream.eof()) break; // Take a bit of a random guess about what's escaped // in regular string arguments. @@ -221,97 +349,13 @@ std::vector CSL::parse(const std::string &file_name) { throw InvalidArgument; } - const auto press = [&](uint16_t key) { - KeyEvent event; - event.key = key; - event.down = true; - argument.push_back(event); - event.down = false; - argument.push_back(event); - }; - const auto shift = [&](uint16_t key) { - KeyEvent event; - event.key = AmstradCPC::Key::KeyShift; - event.down = true; - argument.push_back(event); - press(key); - event.down = false; - argument.push_back(event); - }; - - bool done = false; - while(!done) { - next = stream.get(); - - switch(next) { - default: throw InvalidArgument; - case '\'': - done = true; - break; - - case 'A': press(AmstradCPC::Key::KeyA); break; - case 'B': press(AmstradCPC::Key::KeyB); break; - case 'C': press(AmstradCPC::Key::KeyC); break; - case 'D': press(AmstradCPC::Key::KeyD); break; - case 'E': press(AmstradCPC::Key::KeyE); break; - case 'F': press(AmstradCPC::Key::KeyF); break; - case 'G': press(AmstradCPC::Key::KeyG); break; - case 'H': press(AmstradCPC::Key::KeyH); break; - case 'I': press(AmstradCPC::Key::KeyI); break; - case 'J': press(AmstradCPC::Key::KeyJ); break; - case 'K': press(AmstradCPC::Key::KeyK); break; - case 'L': press(AmstradCPC::Key::KeyL); break; - case 'M': press(AmstradCPC::Key::KeyM); break; - case 'N': press(AmstradCPC::Key::KeyN); break; - case 'O': press(AmstradCPC::Key::KeyO); break; - case 'P': press(AmstradCPC::Key::KeyP); break; - case 'Q': press(AmstradCPC::Key::KeyQ); break; - case 'R': press(AmstradCPC::Key::KeyR); break; - case 'S': press(AmstradCPC::Key::KeyS); break; - case 'T': press(AmstradCPC::Key::KeyT); break; - case 'U': press(AmstradCPC::Key::KeyU); break; - case 'V': press(AmstradCPC::Key::KeyV); break; - case 'W': press(AmstradCPC::Key::KeyW); break; - case 'X': press(AmstradCPC::Key::KeyX); break; - case 'Y': press(AmstradCPC::Key::KeyY); break; - case 'Z': press(AmstradCPC::Key::KeyZ); break; - case ' ': press(AmstradCPC::Key::KeySpace); break; - case '0': press(AmstradCPC::Key::Key0); break; - case '1': press(AmstradCPC::Key::Key1); break; - case '2': press(AmstradCPC::Key::Key2); break; - case '3': press(AmstradCPC::Key::Key3); break; - case '4': press(AmstradCPC::Key::Key4); break; - case '5': press(AmstradCPC::Key::Key5); break; - case '6': press(AmstradCPC::Key::Key6); break; - case '7': press(AmstradCPC::Key::Key7); break; - case '8': press(AmstradCPC::Key::Key8); break; - case '9': press(AmstradCPC::Key::Key9); break; - - case '"': shift(AmstradCPC::Key::Key2); break; - - case '\\': { - if(stream.peek() != '(') { - press(AmstradCPC::Key::KeyBackSlash); - break; - } - stream.get(); - - std::string name; - while(stream.peek() != ')') { - name.push_back(char(stream.get())); - } - stream.get(); - - if(name == "ESC") { - press(AmstradCPC::Key::KeyEscape); - } else if(name == "TAB") { - press(AmstradCPC::Key::KeyTab); - } else if(name == "RET") { - press(AmstradCPC::Key::KeyEnter); - } - - } break; - } + std::vector down; + std::vector up; + while(append_typed(down, up, stream)) { + std::copy(down.begin(), down.end(), std::back_inserter(argument)); + std::copy(up.begin(), up.end(), std::back_inserter(argument)); + down.clear(); + up.clear(); } instruction.argument = argument; } break; From f7422661778acca5777141aaf0f14ad7407e6d03 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 26 Jun 2024 21:53:11 -0400 Subject: [PATCH 04/19] Add SSM code capture to CPC. --- Analyser/Static/AmstradCPC/Target.hpp | 3 ++ Machines/AmstradCPC/AmstradCPC.cpp | 43 ++++++++++++++++++++++++--- Machines/AmstradCPC/AmstradCPC.hpp | 10 ++++++- Storage/Automation/CSL.cpp | 8 ----- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/Analyser/Static/AmstradCPC/Target.hpp b/Analyser/Static/AmstradCPC/Target.hpp index 9bffa3358..6a4e74e4f 100644 --- a/Analyser/Static/AmstradCPC/Target.hpp +++ b/Analyser/Static/AmstradCPC/Target.hpp @@ -20,6 +20,9 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl class ConcreteMachine: +template +class ConcreteMachine: public MachineTypes::ScanProducer, public MachineTypes::AudioProducer, public MachineTypes::TimedMachine, @@ -942,6 +943,19 @@ template class ConcreteMachine: *cycle.value = 0xc9; break; } + + if constexpr (catches_ssm) { + ssm_code_ = (ssm_code_ << 8) | read_pointers_[address >> 14][address & 16383]; + if((ssm_code_ & 0xff00ff00) == 0xed00ed00) { + if(ssm_delegate_) { + ssm_delegate_->perform( + uint16_t( + (ssm_code_ & 0xff) | ((ssm_code_ >> 8) & 0xff00) + )); + } + ssm_code_ = 0; + } + } [[fallthrough]]; case CPU::Z80::PartialMachineCycle::Read: @@ -1115,6 +1129,10 @@ template class ConcreteMachine: tape_player_is_sleeping_ = tape_player_.preferred_clocking() == ClockingHint::Preference::None; } + void set_ssm_delegate(SSMDelegate *delegate) final { + ssm_delegate_ = delegate; + } + // MARK: - Keyboard void type_string(const std::string &string) final { Utility::TypeRecipient::add_typer(string); @@ -1276,6 +1294,9 @@ template class ConcreteMachine: KeyboardState key_state_; AmstradCPC::KeyboardMapper keyboard_mapper_; + SSMDelegate *ssm_delegate_ = nullptr; + uint32_t ssm_code_ = 0; + bool has_run_ = false; uint8_t ram_[128 * 1024]; }; @@ -1284,12 +1305,26 @@ template class ConcreteMachine: using namespace AmstradCPC; +namespace { + +template +std::unique_ptr machine(const Analyser::Static::AmstradCPC::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) { + using Model = Analyser::Static::AmstradCPC::Target::Model; + switch(target.model) { + default: return std::make_unique>(target, rom_fetcher); + case Model::CPC464: return std::make_unique>(target, rom_fetcher); + } +} + +} + // See header; constructs and returns an instance of the Amstrad CPC. std::unique_ptr Machine::AmstradCPC(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) { using Target = Analyser::Static::AmstradCPC::Target; const Target *const cpc_target = dynamic_cast(target); - switch(cpc_target->model) { - default: return std::make_unique>(*cpc_target, rom_fetcher); - case Target::Model::CPC464: return std::make_unique>(*cpc_target, rom_fetcher); + if(cpc_target->catch_ssm_codes) { + return machine(*cpc_target, rom_fetcher); + } else { + return machine(*cpc_target, rom_fetcher); } } diff --git a/Machines/AmstradCPC/AmstradCPC.hpp b/Machines/AmstradCPC/AmstradCPC.hpp index 33304eeb0..e29b46285 100644 --- a/Machines/AmstradCPC/AmstradCPC.hpp +++ b/Machines/AmstradCPC/AmstradCPC.hpp @@ -25,7 +25,10 @@ class Machine { virtual ~Machine() = default; /// Creates and returns an Amstrad CPC. - static std::unique_ptr AmstradCPC(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher); + static std::unique_ptr AmstradCPC( + const Analyser::Static::Target *target, + const ROMMachine::ROMFetcher &rom_fetcher + ); /// Defines the runtime options available for an Amstrad CPC. class Options: @@ -47,6 +50,11 @@ class Machine { } } }; + + struct SSMDelegate { + virtual void perform(uint16_t) = 0; + }; + virtual void set_ssm_delegate(SSMDelegate *) = 0; }; } diff --git a/Storage/Automation/CSL.cpp b/Storage/Automation/CSL.cpp index 52a4e9666..2982fccd1 100644 --- a/Storage/Automation/CSL.cpp +++ b/Storage/Automation/CSL.cpp @@ -20,14 +20,6 @@ using namespace Storage::Automation; namespace { -struct CSLTest { - CSLTest() { - CSL::parse("/Users/thomasharte/Downloads/Shaker_CSL/MODULE A/SHAKE26A-4.CSL"); - } - -}; -CSLTest test; - bool append_typed(std::vector &down, std::vector &up, std::istringstream &stream) { const auto press = [&](uint16_t key) { CSL::KeyEvent event; From 7a145d72f93e20cadd59e767b09b51835480caa6 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 28 Jun 2024 21:52:04 -0400 Subject: [PATCH 05/19] Start Shaker test case. --- .../Clock Signal.xcodeproj/project.pbxproj | 10 +- .../Mac/Clock SignalTests/CPCShakerTests.mm | 42 ++ .../Shaker/MODULE A/SHAKE26A-0.CSL | 297 +++++++++++++ .../Shaker/MODULE A/SHAKE26A-1.CSL | 297 +++++++++++++ .../Shaker/MODULE A/SHAKE26A-2.CSL | 267 ++++++++++++ .../Shaker/MODULE A/SHAKE26A-3.CSL | 296 +++++++++++++ .../Shaker/MODULE A/SHAKE26A-4.CSL | 297 +++++++++++++ .../Shaker/MODULE B/SHAKE26B-0.CSL | 390 ++++++++++++++++++ .../Shaker/MODULE B/SHAKE26B-1.CSL | 278 +++++++++++++ .../Shaker/MODULE B/SHAKE26B-2.CSL | 306 ++++++++++++++ .../Shaker/MODULE B/SHAKE26B-3.CSL | 242 +++++++++++ .../Shaker/MODULE B/SHAKE26B-4.CSL | 241 +++++++++++ .../Shaker/MODULE C/SHAKE26C-0.CSL | 96 +++++ .../Shaker/MODULE C/SHAKE26C-1.CSL | 187 +++++++++ .../Shaker/MODULE C/SHAKE26C-2.CSL | 154 +++++++ .../Shaker/MODULE C/SHAKE26C-3.CSL | 94 +++++ .../Shaker/MODULE C/SHAKE26C-4.CSL | 94 +++++ .../Shaker/MODULE D/SHAKE26D-0.CSL | 201 +++++++++ .../Shaker/MODULE D/SHAKE26D-1.CSL | 238 +++++++++++ .../Shaker/MODULE D/SHAKE26D-2.CSL | 199 +++++++++ .../Shaker/MODULE D/SHAKE26D-3.CSL | 285 +++++++++++++ .../Shaker/MODULE D/SHAKE26D-4.CSL | 286 +++++++++++++ .../Shaker/MODULE E/SHAKE26E-0.CSL | 37 ++ .../Shaker/MODULE E/SHAKE26E-1.CSL | 38 ++ .../Shaker/MODULE E/SHAKE26E-2.CSL | 28 ++ .../Shaker/MODULE E/SHAKE26E-3.CSL | 27 ++ .../Shaker/MODULE E/SHAKE26E-4.CSL | 28 ++ .../Mac/Clock SignalTests/Shaker/shaker26.dsk | Bin 0 -> 194816 bytes 28 files changed, 4954 insertions(+), 1 deletion(-) create mode 100644 OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-0.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-1.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-2.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-3.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-4.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-0.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-1.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-2.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-3.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-4.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-0.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-1.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-2.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-3.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-4.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-0.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-1.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-2.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-3.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-4.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-0.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-1.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-2.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-3.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-4.CSL create mode 100644 OSBindings/Mac/Clock SignalTests/Shaker/shaker26.dsk diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 805fa9c2c..345b5d4fd 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -540,6 +540,8 @@ 4B8805F41DCFD22A003085B1 /* Commodore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F21DCFD22A003085B1 /* Commodore.cpp */; }; 4B8805F71DCFF6C9003085B1 /* Commodore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F51DCFF6C9003085B1 /* Commodore.cpp */; }; 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 */; }; 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 */; }; @@ -1649,6 +1651,8 @@ 4B8805F61DCFF6C9003085B1 /* Commodore.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Commodore.hpp; sourceTree = ""; }; 4B8805F91DCFF807003085B1 /* Oric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Oric.cpp; path = Parsers/Oric.cpp; sourceTree = ""; }; 4B8805FA1DCFF807003085B1 /* Oric.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Oric.hpp; path = Parsers/Oric.hpp; sourceTree = ""; }; + 4B882F582C2F9C6900D84031 /* CPCShakerTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CPCShakerTests.mm; sourceTree = ""; }; + 4B882F5A2C2F9C7700D84031 /* Shaker */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Shaker; sourceTree = ""; }; 4B89449220194A47007DE474 /* CSStaticAnalyser+TargetVector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "CSStaticAnalyser+TargetVector.h"; path = "StaticAnalyser/CSStaticAnalyser+TargetVector.h"; sourceTree = ""; }; 4B8944E4201967B4007DE474 /* ConfidenceSummary.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ConfidenceSummary.hpp; sourceTree = ""; }; 4B8944E5201967B4007DE474 /* ConfidenceSource.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ConfidenceSource.hpp; sourceTree = ""; }; @@ -2716,7 +2720,6 @@ 4B1414631B588A1100E04248 /* Test Binaries */ = { isa = PBXGroup; children = ( - 4BB505882B9C0E6F0031C43C /* Messy ARM */, 4B680CE323A555CA00451D43 /* 68000 Comparative Tests */, 4B75F97A280D7C7700121055 /* 68000 Decoding */, 4B683B002727BE6F0043E541 /* Amiga Blitter Tests */, @@ -2725,7 +2728,9 @@ 4BB0CAB127E51D2A00672A88 /* dingusdev PowerPC tests */, 4B7C7A06282C3DED002D6C0B /* flamewing 68000 BCD tests */, 4BBB77DC2867EBB300D335A1 /* IIgs Memory Map */, + 4BB505882B9C0E6F0031C43C /* Messy ARM */, 4B98A1CD1FFADEC400ADF63B /* MSX ROMs */, + 4B882F5A2C2F9C7700D84031 /* Shaker */, 4B018B88211930DE002A3937 /* 65C02_extended_opcodes_test.bin */, 4BE211DD253E4E4800435408 /* 65C02_no_Rockwell_test.bin */, 4B44EBF61DC9883B00A7820C /* 6502_functional_test.bin */, @@ -4569,6 +4574,7 @@ 4B2005422B804D6400420C5C /* ARMDecoderTests.mm */, 4B924E981E74D22700B76AF1 /* AtariStaticAnalyserTests.mm */, 4BE34437238389E10058E78F /* AtariSTVideoTests.mm */, + 4B882F582C2F9C6900D84031 /* CPCShakerTests.mm */, 4BB2A9AE1E13367E001A5C23 /* CRCTests.mm */, 4BB0CAA627E51B6300672A88 /* DingusdevPowerPCTests.mm */, 428168392A37AFB4008ECD27 /* DispatcherTests.mm */, @@ -5512,6 +5518,7 @@ 4BB298FE1B587D8400A49093 /* anday in Resources */, 4BB299141B587D8400A49093 /* axsz in Resources */, 4BB2991D1B587D8400A49093 /* bplr in Resources */, + 4B882F5B2C2F9C7700D84031 /* Shaker in Resources */, 4BB298FB1B587D8400A49093 /* ancb in Resources */, 4BB299431B587D8400A49093 /* dcma in Resources */, 4BB298FD1B587D8400A49093 /* andax in Resources */, @@ -6517,6 +6524,7 @@ 4B7752B828217F110073E2C5 /* Amiga.cpp in Sources */, 4B3BA0C31D318AEC005DD7A7 /* C1540Tests.swift in Sources */, 4BDA8235261E8E000021AA19 /* Z80ContentionTests.mm in Sources */, + 4B882F592C2F9C6A00D84031 /* CPCShakerTests.mm in Sources */, 4B7752C328217F720073E2C5 /* Z80.cpp in Sources */, 4B778F1A23A5ED320000D260 /* Video.cpp in Sources */, 4B778F3B23A5F1650000D260 /* KeyboardMachine.cpp in Sources */, diff --git a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm new file mode 100644 index 000000000..7530e75cf --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm @@ -0,0 +1,42 @@ +// +// CPCShakerTests.m +// Clock SignalTests +// +// Created by Thomas Harte on 28/06/2024. +// Copyright © 2024 Thomas Harte. All rights reserved. +// + +#import + +#include +#include + +#include "CSL.hpp" + +@interface CPCShakerTests : XCTestCase +@end + +@implementation CPCShakerTests { +} + +- (void)testCSLPath:(NSString *)path name:(NSString *)name { + using namespace Storage::Automation; + const auto steps = CSL::parse([[path stringByAppendingPathComponent:name] UTF8String]); + NSLog(@"%@ / %@", path, name); +} + +- (void)testModulePath:(NSString *)path name:(NSString *)name { + NSString *basePath = + [[NSBundle bundleForClass:[self class]] + pathForResource:@"Shaker" + ofType:nil]; + [self testCSLPath:[basePath stringByAppendingPathComponent:path] name:name]; +} + +- (void)testModuleA { [self testModulePath:@"MODULE A" name:@"SHAKE26A-0.CSL"]; } +- (void)testModuleB { [self testModulePath:@"MODULE B" name:@"SHAKE26B-0.CSL"]; } +- (void)testModuleC { [self testModulePath:@"MODULE C" name:@"SHAKE26C-0.CSL"]; } +- (void)testModuleD { [self testModulePath:@"MODULE D" name:@"SHAKE26D-0.CSL"]; } +- (void)testModuleE { [self testModulePath:@"MODULE E" name:@"SHAKE26E-0.CSL"]; } + +@end diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-0.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-0.CSL new file mode 100644 index 000000000..4e80e428c --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-0.CSL @@ -0,0 +1,297 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26A du DSK SHAKER26.DSK en CRTC 0 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 0 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26A"\(RET)' +wait 10000000 +; +; test 1 +key_output '1' +wait 800000 ; fin affichage 1er ecran & ssm 595215 +key_output ' ' +wait 800000 ; fin affichage 2nd ecran & ssm 659451 +key_output ' ' +wait 800000 ; fin affichage 3eme ecran & ssm 627963 +key_output ' ' +wait 800000 ; fin affichage 4eme ecran & ssm 698883 +key_output ' ' +wait 800000 ; fin affichage 5eme ecran & ssm 551415 +key_output ' ' +wait 1000000 ; retour menu +; +; test 2 +key_output '2' +wait 800000 ; 519961 crt 0 1 ecran +key_output ' ' +wait 800000 ; 2 ecrans +wait 800000 ; +key_output ' ' +wait 800000 ; 723923 +key_output ' ' +wait 800000 ; 599040 +key_output ' ' +wait 1000000 ; retour menu +; +; test 3 +key_output '3' +wait 800000 ; 596058 +wait 1500000 ; 1337856 +key_output ' ' +wait 800000 ; 730624 +wait 1500000 ; 1337856 +key_output ' ' +wait 800000 ; 750685 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 710656 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 726016 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 726952 +wait 800000 ; 698880 +key_output ' ' +wait 1000000 ; 845824 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 666112 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 666112 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 706048 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 730624 +wait 800000 ; 698880 +key_output ' ' +wait 900000 ; 745984 +wait 800000 ; 698880 +key_output ' ' +wait 900000 ; 805888 +wait 800000 ; 698880 +key_output ' ' +wait 1000000 ; 865792 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 686080 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 686080 +wait 800000 ; 698880 +key_output ' ' +wait 10000000 +; +key_output '4' +wait 9000000 ; 6743019 +key_output ' ' +wait 1000000 +; +key_output '5' +wait 800000 ; 434016 +key_output ' ' +wait 800000 ; 547328 +key_output ' ' +wait 800000 ; 567296 +key_output ' ' +wait 800000 ; 587264 +key_output ' ' +wait 800000 ; 607232 +key_output ' ' +wait 1000000 +; +key_output '6' +wait 800000 ; 473960 +key_output ' ' +wait 800000 ; 607232 +key_output ' ' +wait 800000 ; 627200 +key_output ' ' +wait 800000 ; 647168 +key_output ' ' +wait 800000 ; 667136 +key_output ' ' +wait 1000000 +; +key_output '7' +wait 800000 ; 473957 +key_output ' ' +wait 800000 ; 667072 +key_output ' ' +wait 800000 ; 527296 +key_output ' ' +wait 800000 ; 547264 +key_output ' ' +wait 800000 ; 567232 +key_output ' ' +wait 1000000 +; +key_output '8' +wait 800000 ; 431083 +key_output ' ' +wait 1000000 +; +key_output '9' +wait 800000 ; 474048 +key_output ' ' +wait 800000 ; 559104 +key_output ' ' +wait 800000 ; 598363 +key_output ' ' +wait 1000000 +; +key_output 'E' +wait 800000 ; 514468 +key_output ' ' +wait 1000000 +; +key_output 'R' +wait 800000 ; 592695 +wait 1200000 ; 998400 +key_output ' ' +wait 800000 ; 599040 +wait 1200000 ; 998400 +key_output ' ' +wait 800000 ; 658944 +wait 1200000 ; 998400 +key_output ' ' +wait 1000000 +; +key_output 'T' +wait 800000 ; 531832 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 638976 +key_output ' ' +wait 1000000 +; +key_output 'Y' +wait 800000 ; 511931 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; ??? +key_output ' ' +wait 1000000 +; +key_output 'U' +wait 14000000 ; 11803953+1007210 +key_output ' ' +wait 1000000 +; +key_output 'I' +wait 2200000 ; 2013010 +key_output ' ' +wait 2200000 ; 2315008 +key_output ' ' +wait 5000000 ; 4233216 +key_output ' ' +wait 35000000 ; 31301630 +key_output ' ' +wait 2000000 ; 1557507 +key_output ' ' +wait 1000000 +; +key_output 'O' +wait 800000 ; 576098 +key_output ' ' +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 599040 +key_output ' ' +wait 800000 ; 497671 +key_output ' ' +wait 800000 ; 469504 +key_output ' ' +wait 800000 ; 522696 +key_output ' ' +wait 800000 ; 547978 +key_output ' ' +wait 800000 ; 579072 +; crtc 1 +;key_output ' ' +;wait 800000 ; 482251 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 519680 +key_output ' ' +wait 1000000 +; +key_output 'P' +wait 450000 ; 427222 +wait 5200000 ; 5111808 +key_output ' ' +wait 800000 ; 529408 +key_output ' ' +wait 800000 ; 489472 +key_output ' ' +wait 800000 ; 449536 +key_output ' ' +wait 800000 ; 509440 +key_output ' ' +wait 800000 ; 587307 +key_output ' ' +wait 800000 ; 479104 +key_output ' ' +wait 800000 ; 479360 +key_output ' ' +wait 800000 ; 490944 +key_output ' ' +wait 800000 ; 638464 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 1000000 +; +csl_load 'SHAKE26A-1' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-1.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-1.CSL new file mode 100644 index 000000000..3e0bddd6b --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-1.CSL @@ -0,0 +1,297 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26A du DSK SHAKER26.DSK en CRTC 1 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 1 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26A"\(RET)' +wait 10000000 +; +; test 1 +key_output '1' +wait 800000 ; fin affichage 1er ecran & ssm 595215 +key_output ' ' +wait 800000 ; fin affichage 2nd ecran & ssm 659451 +key_output ' ' +wait 800000 ; fin affichage 3eme ecran & ssm 627963 +key_output ' ' +wait 800000 ; fin affichage 4eme ecran & ssm 698883 +key_output ' ' +wait 800000 ; fin affichage 5eme ecran & ssm 551415 +key_output ' ' +wait 1000000 ; retour menu +; +; test 2 +key_output '2' +wait 800000 ; 519961 crt 0 1 ecran +wait 800000 ; 2 ecrans +key_output ' ' +wait 800000 ; +key_output ' ' +wait 800000 ; 723923 +key_output ' ' +wait 800000 ; 599040 +key_output ' ' +wait 1000000 ; retour menu +; +; test 3 +key_output '3' +wait 800000 ; 596058 +wait 1500000 ; 1337856 +key_output ' ' +wait 800000 ; 730624 +wait 1500000 ; 1337856 +key_output ' ' +wait 800000 ; 750685 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 710656 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 726016 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 726952 +wait 800000 ; 698880 +key_output ' ' +wait 1000000 ; 845824 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 666112 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 666112 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 706048 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 730624 +wait 800000 ; 698880 +key_output ' ' +wait 900000 ; 745984 +wait 800000 ; 698880 +key_output ' ' +wait 900000 ; 805888 +wait 800000 ; 698880 +key_output ' ' +wait 1000000 ; 865792 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 686080 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 686080 +wait 800000 ; 698880 +key_output ' ' +wait 10000000 +; +key_output '4' +wait 8000000 ; 6743019 +key_output ' ' +wait 1000000 +; +key_output '5' +wait 800000 ; 434016 +key_output ' ' +wait 800000 ; 547328 +key_output ' ' +wait 800000 ; 567296 +key_output ' ' +wait 800000 ; 587264 +key_output ' ' +wait 800000 ; 607232 +key_output ' ' +wait 1000000 +; +key_output '6' +wait 800000 ; 473960 +key_output ' ' +wait 800000 ; 607232 +key_output ' ' +wait 800000 ; 627200 +key_output ' ' +wait 800000 ; 647168 +key_output ' ' +wait 800000 ; 667136 +key_output ' ' +wait 1000000 +; +key_output '7' +wait 800000 ; 473957 +key_output ' ' +wait 800000 ; 667072 +key_output ' ' +wait 800000 ; 527296 +key_output ' ' +wait 800000 ; 547264 +key_output ' ' +wait 800000 ; 567232 +key_output ' ' +wait 1000000 +; +key_output '8' +wait 800000 ; 431083 +key_output ' ' +wait 1000000 +; +key_output '9' +wait 800000 ; 474048 +key_output ' ' +wait 800000 ; 559104 +key_output ' ' +wait 800000 ; 598363 +key_output ' ' +wait 1000000 +; +key_output 'E' +wait 800000 ; 514468 +key_output ' ' +wait 1000000 +; +key_output 'R' +wait 800000 ; 592695 +wait 1200000 ; 998400 +key_output ' ' +wait 800000 ; 599040 +wait 1200000 ; 998400 +key_output ' ' +wait 800000 ; 658944 +wait 1200000 ; 998400 +key_output ' ' +wait 1000000 +; +key_output 'T' +wait 800000 ; 531832 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 638976 +key_output ' ' +wait 1000000 +; +key_output 'Y' +wait 800000 ; 511931 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; ??? +key_output ' ' +wait 1000000 +; +key_output 'U' +wait 14000000 ; 11803953+1007210 +key_output ' ' +wait 1000000 +; +key_output 'I' +wait 2200000 ; 2013010 +key_output ' ' +wait 2200000 ; 2315008 +key_output ' ' +wait 5000000 ; 4233216 +key_output ' ' +wait 35000000 ; 31301630 +key_output ' ' +wait 2000000 ; 1557507 +key_output ' ' +wait 1000000 +; +key_output 'O' +wait 800000 ; 576098 +key_output ' ' +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 599040 +key_output ' ' +wait 800000 ; 497671 +key_output ' ' +wait 800000 ; 469504 +key_output ' ' +wait 800000 ; 522696 +key_output ' ' +wait 800000 ; 547978 +key_output ' ' +wait 800000 ; 579072 +; crtc 1 +;key_output ' ' +;wait 800000 ; 482251 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 519680 +key_output ' ' +wait 1000000 +; +key_output 'P' +wait 450000 ; 427222 +wait 5200000 ; 5111808 +key_output ' ' +wait 800000 ; 529408 +key_output ' ' +wait 800000 ; 489472 +key_output ' ' +wait 800000 ; 449536 +key_output ' ' +wait 800000 ; 509440 +key_output ' ' +wait 800000 ; 587307 +key_output ' ' +wait 800000 ; 479104 +key_output ' ' +wait 800000 ; 479360 +key_output ' ' +wait 800000 ; 490944 +key_output ' ' +wait 800000 ; 638464 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 1000000 + +csl_load 'SHAKE26A-2' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-2.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-2.CSL new file mode 100644 index 000000000..182d3719a --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-2.CSL @@ -0,0 +1,267 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26A du DSK SHAKER26.DSK en CRTC 2 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 2 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26A"\(RET)' +wait 10000000 +; +; test 1 +key_output '1' +wait 800000 ; fin affichage 1er ecran & ssm 595215 +key_output ' ' +wait 800000 ; fin affichage 2nd ecran & ssm 659451 +key_output ' ' +wait 800000 ; fin affichage 3eme ecran & ssm 627963 +key_output ' ' +wait 800000 ; fin affichage 4eme ecran & ssm 698883 +key_output ' ' +wait 800000 ; fin affichage 5eme ecran & ssm 551415 +key_output ' ' +wait 1000000 ; retour menu +; +; test 2 +key_output '2' +wait 800000 ; 519961 crt 0 1 ecran +key_output ' ' +wait 800000 ; 2 ecrans +wait 800000 ; +key_output ' ' +wait 800000 ; 723923 +key_output ' ' +wait 800000 ; 599040 +key_output ' ' +wait 1000000 ; retour menu +; +; test 3 +key_output '3' +wait 800000 ; 596058 +wait 1500000 ; 1337856 +key_output ' ' +wait 800000 ; 730624 +wait 1500000 ; 1337856 +key_output ' ' +wait 800000 ; 750685 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 710656 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 726016 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 726952 +wait 800000 ; 698880 +key_output ' ' +wait 1000000 ; 845824 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 666112 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 666112 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 706048 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 730624 +wait 800000 ; 698880 +key_output ' ' +wait 900000 ; 745984 +wait 800000 ; 698880 +key_output ' ' +wait 900000 ; 805888 +wait 800000 ; 698880 +key_output ' ' +wait 1000000 ; 865792 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 686080 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 686080 +wait 800000 ; 698880 +key_output ' ' +wait 10000000 +; +key_output '4' +wait 8000000 ; 6743019 +key_output ' ' +wait 1000000 +; +key_output '8' +wait 800000 ; 431083 +key_output ' ' +wait 1000000 +; +key_output '9' +wait 800000 ; 474048 +key_output ' ' +wait 800000 ; 559104 +key_output ' ' +wait 800000 ; 598363 +key_output ' ' +wait 1000000 +; +key_output 'E' +wait 800000 ; 514468 +key_output ' ' +wait 1000000 +; +key_output 'R' +wait 800000 ; 592695 +wait 1200000 ; 998400 +key_output ' ' +wait 800000 ; 599040 +wait 1200000 ; 998400 +key_output ' ' +wait 800000 ; 658944 +wait 1200000 ; 998400 +key_output ' ' +wait 1000000 +; +key_output 'T' +wait 800000 ; 531832 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 638976 +key_output ' ' +wait 1000000 +; +key_output 'Y' +wait 800000 ; 511931 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; ??? +key_output ' ' +wait 1000000 +; +key_output 'U' +wait 14000000 ; 11803953+1007210 +key_output ' ' +wait 1000000 +; +key_output 'I' +wait 2200000 ; 2013010 +key_output ' ' +wait 2200000 ; 2315008 +key_output ' ' +wait 5000000 ; 4233216 +key_output ' ' +wait 35000000 ; 31301630 +key_output ' ' +wait 2000000 ; 1557507 +key_output ' ' +wait 1000000 +; +key_output 'O' +wait 800000 ; 576098 +key_output ' ' +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 599040 +key_output ' ' +wait 800000 ; 497671 +key_output ' ' +wait 800000 ; 469504 +key_output ' ' +wait 800000 ; 522696 +key_output ' ' +wait 800000 ; 547978 +key_output ' ' +wait 800000 ; 579072 +; crtc 1 +;key_output ' ' +;wait 800000 ; 482251 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 519680 +key_output ' ' +wait 1000000 +; +key_output 'P' +wait 450000 ; 427222 +wait 5200000 ; 5111808 +key_output ' ' +wait 800000 ; 529408 +key_output ' ' +wait 800000 ; 489472 +key_output ' ' +wait 800000 ; 449536 +key_output ' ' +wait 800000 ; 509440 +key_output ' ' +wait 800000 ; 587307 +key_output ' ' +wait 800000 ; 479104 +key_output ' ' +wait 800000 ; 479360 +key_output ' ' +wait 800000 ; 490944 +key_output ' ' +wait 800000 ; 638464 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 1000000 +; +; crtc 2 +; +key_output '\(COP)' +wait 8500000 ; 8313240 +wait 500000 ; 319488 +key_output ' ' +wait 1000000 +; +; +csl_load 'SHAKE26A-4' diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-3.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-3.CSL new file mode 100644 index 000000000..f6c3c95a3 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-3.CSL @@ -0,0 +1,296 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26A du DSK SHAKER26.DSK en CRTC 3 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 3 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26A"\(RET)' +wait 10000000 +; +; test 1 +key_output '1' +wait 800000 ; fin affichage 1er ecran & ssm 595215 +key_output ' ' +wait 800000 ; fin affichage 2nd ecran & ssm 659451 +key_output ' ' +wait 800000 ; fin affichage 3eme ecran & ssm 627963 +key_output ' ' +wait 800000 ; fin affichage 4eme ecran & ssm 698883 +key_output ' ' +wait 800000 ; fin affichage 5eme ecran & ssm 551415 +key_output ' ' +wait 1000000 ; retour menu +; +; test 2 +key_output '2' +wait 800000 ; 519961 crt 0 1 ecran +key_output ' ' +wait 800000 ; 2 ecrans +wait 800000 ; +key_output ' ' +wait 800000 ; 723923 +key_output ' ' +wait 800000 ; 599040 +key_output ' ' +wait 1000000 ; retour menu +; +; test 3 +key_output '3' +wait 800000 ; 596058 +wait 1500000 ; 1337856 +key_output ' ' +wait 800000 ; 730624 +wait 1500000 ; 1337856 +key_output ' ' +wait 800000 ; 750685 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 710656 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 726016 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 726952 +wait 800000 ; 698880 +key_output ' ' +wait 1000000 ; 845824 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 666112 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 666112 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 706048 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 730624 +wait 800000 ; 698880 +key_output ' ' +wait 900000 ; 745984 +wait 800000 ; 698880 +key_output ' ' +wait 900000 ; 805888 +wait 800000 ; 698880 +key_output ' ' +wait 1000000 ; 865792 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 686080 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 686080 +wait 800000 ; 698880 +key_output ' ' +wait 10000000 +; +key_output '4' +wait 8000000 ; 6743019 +key_output ' ' +wait 1000000 +; +key_output '5' +wait 800000 ; 434016 +key_output ' ' +wait 800000 ; 547328 +key_output ' ' +wait 800000 ; 567296 +key_output ' ' +wait 800000 ; 587264 +key_output ' ' +wait 800000 ; 607232 +key_output ' ' +wait 1000000 +; +key_output '6' +wait 800000 ; 473960 +key_output ' ' +wait 800000 ; 607232 +key_output ' ' +wait 800000 ; 627200 +key_output ' ' +wait 800000 ; 647168 +key_output ' ' +wait 800000 ; 667136 +key_output ' ' +wait 1000000 +; +key_output '7' +wait 800000 ; 473957 +key_output ' ' +wait 800000 ; 667072 +key_output ' ' +wait 800000 ; 527296 +key_output ' ' +wait 800000 ; 547264 +key_output ' ' +wait 800000 ; 567232 +key_output ' ' +wait 1000000 +; +key_output '8' +wait 800000 ; 431083 +key_output ' ' +wait 1000000 +; +key_output '9' +wait 800000 ; 474048 +key_output ' ' +wait 800000 ; 559104 +key_output ' ' +wait 800000 ; 598363 +key_output ' ' +wait 1000000 +; +key_output 'E' +wait 800000 ; 514468 +key_output ' ' +wait 1000000 +; +key_output 'R' +wait 800000 ; 592695 +wait 1200000 ; 998400 +key_output ' ' +wait 800000 ; 599040 +wait 1200000 ; 998400 +key_output ' ' +wait 800000 ; 658944 +wait 1200000 ; 998400 +key_output ' ' +wait 1000000 +; +key_output 'T' +wait 800000 ; 531832 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 638976 +key_output ' ' +wait 1000000 +; +key_output 'Y' +wait 800000 ; 511931 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; ??? +key_output ' ' +wait 1000000 +; +key_output 'U' +wait 14000000 ; 11803953+1007210 +key_output ' ' +wait 1000000 +; +key_output 'I' +wait 2200000 ; 2013010 +key_output ' ' +wait 2200000 ; 2315008 +key_output ' ' +wait 5000000 ; 4233216 +key_output ' ' +wait 35000000 ; 31301630 +key_output ' ' +wait 2000000 ; 1557507 +key_output ' ' +wait 1000000 +; +key_output 'O' +wait 800000 ; 576098 +key_output ' ' +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 599040 +key_output ' ' +wait 800000 ; 497671 +key_output ' ' +wait 800000 ; 469504 +key_output ' ' +wait 800000 ; 522696 +key_output ' ' +wait 800000 ; 547978 +key_output ' ' +wait 800000 ; 579072 +; crtc 1 +;key_output ' ' +;wait 800000 ; 482251 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 519680 +key_output ' ' +wait 1000000 +; +key_output 'P' +wait 450000 ; 427222 +wait 5200000 ; 5111808 +key_output ' ' +wait 800000 ; 529408 +key_output ' ' +wait 800000 ; 489472 +key_output ' ' +wait 800000 ; 449536 +key_output ' ' +wait 800000 ; 509440 +key_output ' ' +wait 800000 ; 587307 +key_output ' ' +wait 800000 ; 479104 +key_output ' ' +wait 800000 ; 479360 +key_output ' ' +wait 800000 ; 490944 +key_output ' ' +wait 800000 ; 638464 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 1000000 +reset \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-4.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-4.CSL new file mode 100644 index 000000000..019e34612 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE A/SHAKE26A-4.CSL @@ -0,0 +1,297 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26A du DSK SHAKER26.DSK en CRTC 4 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 4 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26A"\(RET)' +wait 10000000 +; +; test 1 +key_output '1' +wait 800000 ; fin affichage 1er ecran & ssm 595215 +key_output ' ' +wait 800000 ; fin affichage 2nd ecran & ssm 659451 +key_output ' ' +wait 800000 ; fin affichage 3eme ecran & ssm 627963 +key_output ' ' +wait 800000 ; fin affichage 4eme ecran & ssm 698883 +key_output ' ' +wait 800000 ; fin affichage 5eme ecran & ssm 551415 +key_output ' ' +wait 1000000 ; retour menu +; +; test 2 +key_output '2' +wait 800000 ; 519961 crt 0 1 ecran +key_output ' ' +wait 800000 ; 2 ecrans +wait 800000 ; +key_output ' ' +wait 800000 ; 723923 +key_output ' ' +wait 800000 ; 599040 +key_output ' ' +wait 1000000 ; retour menu +; +; test 3 +key_output '3' +wait 800000 ; 596058 +wait 1500000 ; 1337856 +key_output ' ' +wait 800000 ; 730624 +wait 1500000 ; 1337856 +key_output ' ' +wait 800000 ; 750685 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 750592 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 710656 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 726016 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 726952 +wait 800000 ; 698880 +key_output ' ' +wait 1000000 ; 845824 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 666112 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 666112 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 706048 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 610816 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 730624 +wait 800000 ; 698880 +key_output ' ' +wait 900000 ; 745984 +wait 800000 ; 698880 +key_output ' ' +wait 900000 ; 805888 +wait 800000 ; 698880 +key_output ' ' +wait 1000000 ; 865792 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 686080 +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 686080 +wait 800000 ; 698880 +key_output ' ' +wait 10000000 +; +key_output '4' +wait 12000000 ; 6743019 +key_output ' ' +wait 1000000 +; +key_output '5' +wait 800000 ; 434016 +key_output ' ' +wait 800000 ; 547328 +key_output ' ' +wait 800000 ; 567296 +key_output ' ' +wait 800000 ; 587264 +key_output ' ' +wait 800000 ; 607232 +key_output ' ' +wait 1000000 +; +key_output '6' +wait 800000 ; 473960 +key_output ' ' +wait 800000 ; 607232 +key_output ' ' +wait 800000 ; 627200 +key_output ' ' +wait 800000 ; 647168 +key_output ' ' +wait 800000 ; 667136 +key_output ' ' +wait 1000000 +; +key_output '7' +wait 800000 ; 473957 +key_output ' ' +wait 800000 ; 667072 +key_output ' ' +wait 800000 ; 527296 +key_output ' ' +wait 800000 ; 547264 +key_output ' ' +wait 800000 ; 567232 +key_output ' ' +wait 1000000 +; +key_output '8' +wait 800000 ; 431083 +key_output ' ' +wait 1000000 +; +key_output '9' +wait 800000 ; 474048 +key_output ' ' +wait 800000 ; 559104 +key_output ' ' +wait 800000 ; 598363 +key_output ' ' +wait 1000000 +; +key_output 'E' +wait 800000 ; 514468 +key_output ' ' +wait 1000000 +; +key_output 'R' +wait 800000 ; 592695 +wait 1200000 ; 998400 +key_output ' ' +wait 800000 ; 599040 +wait 1200000 ; 998400 +key_output ' ' +wait 800000 ; 658944 +wait 1200000 ; 998400 +key_output ' ' +wait 1000000 +; +key_output 'T' +wait 800000 ; 531832 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 579072 +key_output ' ' +wait 800000 ; 638976 +key_output ' ' +wait 1000000 +; +key_output 'Y' +wait 800000 ; 511931 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 800000 ; ??? +key_output ' ' +wait 1000000 +; +key_output 'U' +wait 14000000 ; 11803953+1007210 +key_output ' ' +wait 1000000 +; +key_output 'I' +wait 2200000 ; 2013010 +key_output ' ' +wait 2200000 ; 2315008 +key_output ' ' +wait 5000000 ; 4233216 +key_output ' ' +wait 35000000 ; 31301630 +key_output ' ' +wait 2000000 ; 1557507 +key_output ' ' +wait 1000000 +; +key_output 'O' +wait 800000 ; 576098 +key_output ' ' +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 698880 +key_output ' ' +wait 800000 ; 599040 +key_output ' ' +wait 800000 ; 497671 +key_output ' ' +wait 800000 ; 469504 +key_output ' ' +wait 800000 ; 522696 +key_output ' ' +wait 800000 ; 547978 +key_output ' ' +wait 800000 ; 579072 +; crtc 1 +;key_output ' ' +;wait 800000 ; 482251 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 599552 +;key_output ' ' +;wait 800000 ; 519680 +key_output ' ' +wait 1000000 +; +key_output 'P' +wait 450000 ; 427222 +wait 5200000 ; 5111808 +key_output ' ' +wait 800000 ; 529408 +key_output ' ' +wait 800000 ; 489472 +key_output ' ' +wait 800000 ; 449536 +key_output ' ' +wait 800000 ; 509440 +key_output ' ' +wait 800000 ; 587307 +key_output ' ' +wait 800000 ; 479104 +key_output ' ' +wait 800000 ; 479360 +key_output ' ' +wait 800000 ; 490944 +key_output ' ' +wait 800000 ; 638464 +key_output ' ' +wait 800000 ; 619008 +key_output ' ' +wait 1000000 + +csl_load 'SHAKE26A-3' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-0.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-0.CSL new file mode 100644 index 000000000..1c7731399 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-0.CSL @@ -0,0 +1,390 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26B du DSK SHAKER26.DSK en CRTC 0 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 0 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26B"\(RET)' +wait 10000000 +; +; test 1 interlace c4/c9 counters R9 base=07 Parity Odd +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +key_output 'Y' ; bascule sur parity Even (R9 Base=7) +wait 300000 +; +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +key_output 'Z' ; Passe sur R9 BASE=6 (parity Even) +wait 300000 +; +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +; +key_output 'Y' ; bascule sur parity Odd (R9 base=6) +wait 300000 +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +; +; test 9 (garder la foi tu dois, mecreant) +key_output '9' ; En Odd +wait 20000000 ; +key_output ' ' +wait 20000000 +key_output ' ' +wait 1000000 +; +key_output 'Y' ; Repasser en Even +wait 100000 +key_output '9' ; En even +wait 20000000 ; +key_output ' ' +wait 20000000 +key_output ' ' +wait 1000000 +; +key_output '0' ; vertical sub pixel scroll +wait 1000000 ; 816677 1/8 +key_output ' ' +wait 1000000 ; 890842 1/16 +key_output ' ' +wait 1000000 ; 830950 1/32 +key_output ' ' +wait 1000000 ; 870899 1/64 +key_output ' ' +wait 1000000 ; 830965 1/128 +key_output ' ' +wait 1000000 ; menu +; +; +key_output '4' ; +wait 2000000 ; 1913669 +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 1000000 ; +key_output ' ' +wait 1000000 ; menu +; +key_output '5' ; rlal crtc 2 (tous crtc) +wait 900000 +key_output ' ' +wait 2000000 +key_output ' ' ; Menu +wait 1000000 +; +; +key_output '\(RET)' +wait 800000 ; 632429 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 800000 ; 647344 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 800000 ; 667312 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 1000000 +; +;Test Bounga +key_output '\(FN0)' +wait 30000000 ; ??? +key_output ' ' +wait 1000000 +; +; Test RVNI LTD +; +key_output '\(CAP)' +wait 6000000 ; 753563 +key_output ' ' +wait 6000000 ; 727728 +key_output ' ' +wait 6000000 ; 728880 +key_output ' ' +wait 6000000 +; +; Shaker Killer Don't be afraid +; +key_output 'R' +wait 5000000 ; 2615301 z80aintb +key_output ' ' +wait 6000000 ; 4692484 r52Reset +key_output ' ' +wait 9000000 ; 7867387 Inter Test IM1 +key_output ' ' +wait 9000000 ; 6888966 Inter Test IM2 +key_output ' ' +wait 3000000 ; 1711766 R52 Incr +key_output ' ' +wait 900000 ; 486262 Otir Zone +key_output ' ' +wait 1000000 ; menu +; +; R3 JIT +key_output 'I' +wait 1000000 ; 474622 +key_output ' ' +wait 1000000 ; 519168 +key_output ' ' +wait 1000000 ; 519168 +key_output ' ' +wait 1000000 ; 499200 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 599040 +key_output ' ' +wait 1000000 ; Menu +; +; test crtc 0,1 only +; +key_output '\(COP)' +wait 1000000 ; 787700 +key_output ' ' +wait 1000000 ; 778752 +key_output ' ' +wait 2000000 ; 702326+19968 +key_output ' ' +wait 2000000 ; 835656 +key_output ' ' +wait 2000000 ; 924826 +key_output ' ' +wait 4000000 +; +; +; test crtc 1 , ouvert aux autres CRTCs +; +key_output '6' +wait 10000000 ; 1676617 +key_output ' ' +wait 1000000 +; +; test crtc 0 only +; +key_output '7' ; resultat a verifier +wait 800000 ; 613742 +wait 600000 ; 511808 +wait 2000000 ; 1277952 +wait 5000000 ; 3833856 +wait 2000000 ; 1277952 +wait 5000000 ; 3833856 +wait 2000000 ; 1277952 +key_output ' ' +wait 800000 ; 533680 +wait 6000000 ; 5111808 +wait 2000000 ; 1277952 +wait 6000000 ; 3833856 +wait 2000000 ; 1277952 +wait 6000000 ; 3833856 +wait 2000000 ; 1277952 +key_output ' ' +wait 800000 ; 565936 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 2000000 ; 1277952 +wait 6000000 ; 3833856 +wait 2000000 ; 1277952 +key_output ' ' +key_output ' ' +wait 800000 ; 565936 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 2000000 ; 1277952 +wait 6000000 ; 3833856 +wait 2000000 ; 1277952 +key_output ' ' +wait 1000000 ; menu +; +; test crtc 0 only +; +key_output 'U' +wait 1200000 ; +key_output ' ' ; A +wait 1200000 ; +key_output ' ' ; B +wait 1200000 ; +key_output ' ' ; C +wait 1200000 ; +key_output ' ' ; D +wait 1200000 ; +key_output ' ' ; E +wait 1200000 ; +key_output ' ' ; F +wait 1200000 ; +key_output ' ' ; G +wait 1200000 ; +key_output ' ' ; H +wait 1200000 ; +key_output ' ' ; I +wait 1200000 ; +key_output ' ' ; J +wait 1200000 ; +key_output ' ' ; K +wait 1200000 ; +key_output ' ' ; L +wait 1200000 ; +key_output ' ' ; M +wait 1200000 ; +key_output ' ' ; N +wait 1200000 ; +key_output ' ' ; O +wait 1200000 ; +key_output ' ' ; P +wait 1200000 ; +key_output ' ' ; Q +wait 1200000 ; +key_output ' ' ; R +wait 1200000 ; +key_output ' ' ; S +wait 1200000 ; +; +; Test Analyzer des premieres heures +; +key_output 'P' +wait 100000000 ; 12828735+638976 +key_output ' ' +wait 100000000 ; 5440000+638976 +key_output ' ' +wait 100000000 ; 11637760+638976 +key_output ' ' +wait 100000000 ; 13560624+638976 +key_output ' ' +wait 1000000 + +csl_load 'SHAKE26B-1' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-1.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-1.CSL new file mode 100644 index 000000000..320858e85 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-1.CSL @@ -0,0 +1,278 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26B du DSK SHAKER26.DSK en CRTC 1 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 1A +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26B"\(RET)' +wait 10000000 +; +; test 1 interlace c4/c9 counters R9 base=07 +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +; +key_output 'Z' ; Passe sur R9 BASE=6 +wait 300000 +; +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +; +; test 9 (garder la foi tu dois, mecreant) +key_output '9' +wait 20000000 ; +key_output ' ' +wait 20000000 +key_output ' ' +wait 1000000 +; +key_output '0' ; vertical sub pixel scroll +wait 1000000 ; 816677 1/8 +key_output ' ' +wait 1000000 ; 890842 1/16 +key_output ' ' +wait 1000000 ; 830950 1/32 +key_output ' ' +wait 1000000 ; 870899 1/64 +key_output ' ' +wait 1000000 ; 830965 1/128 +key_output ' ' +wait 1000000 ; menu +; +key_output '4' ; +wait 2000000 ; 1913669 +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 1000000 ; +key_output ' ' +wait 1000000 ; menu +; +key_output '5' ; rlal crtc 2 (tous crtc) +wait 900000 +key_output ' ' +wait 2000000 +key_output ' ' ; Menu +wait 1000000 +; +; +key_output '\(RET)' +wait 800000 ; 632429 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 800000 ; 647344 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 800000 ; 667312 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 1000000 +; +;Test Bounga +key_output '\(FN0)' +wait 30000000 ; ??? +key_output ' ' +wait 1000000 +; +; Test RVNI LTD +; +key_output '\(CAP)' +wait 6000000 ; 753563 +key_output ' ' +wait 6000000 ; 727728 +key_output ' ' +wait 6000000 ; 728880 +key_output ' ' +wait 6000000 +; +; Shaker Killer Don't be afraid +; +key_output 'R' +wait 5000000 ; 2615301 z80aintb +key_output ' ' +wait 6000000 ; 4692484 r52Reset +key_output ' ' +wait 9000000 ; 7867387 Inter Test IM1 +key_output ' ' +wait 9000000 ; 6888966 Inter Test IM2 +key_output ' ' +wait 3000000 ; 1711766 R52 Incr +key_output ' ' +wait 900000 ; 486262 Otir Zone +key_output ' ' +wait 1000000 ; menu +; +; R3 JIT +key_output 'I' +wait 1000000 ; 474622 +key_output ' ' +wait 1000000 ; 519168 +key_output ' ' +wait 1000000 ; 519168 +key_output ' ' +wait 1000000 ; 499200 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 599040 +key_output ' ' +wait 1000000 ; Menu +; +; test crtc 0,1 only +; +key_output '\(COP)' +wait 1000000 ; 787700 +key_output ' ' +wait 1000000 ; 778752 +key_output ' ' +wait 2000000 ; 702326+19968 +key_output ' ' +wait 2000000 ; 835656 +key_output ' ' +wait 2000000 ; 924826 +key_output ' ' +wait 4000000 +; +; +; test crtc 1 , ouvert aux autres CRTCs +; +key_output '6' +wait 10000000 ; 1676617 +key_output ' ' +wait 1000000 +; +; test crtc 1 only : identification crtc 1A/1B +; pour le 1A +key_output 'O' +wait 500000 ; 336980 +key_output ' ' +wait 1000000 +; +; +; test crtc 1 only : BE00 check +; +key_output 'S' +wait 5000000 ; 1976392 +key_output ' ' +wait 1000000 +; +; +; Test Analyzer des premieres heures +; +key_output 'P' +wait 100000000 ; 12828735+638976 +key_output ' ' +wait 100000000 ; 5440000+638976 +key_output ' ' +wait 100000000 ; 11637760+638976 +key_output ' ' +wait 100000000 ; 13560624+638976 +key_output ' ' +wait 1000000 +; +; Test RFD +; +key_output '\(CTR)' +wait 10000000 +; +; Si la selection de crtc en cours de route pose prb sortir ce test +; +crtc_select 1B +; +; test crtc 1 only : identification crtc 1A/1B +; pour le 1B +key_output 'E' +wait 500000 ; 336980 +key_output ' ' +wait 1000000 +; +csl_load 'SHAKE26B-2' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-2.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-2.CSL new file mode 100644 index 000000000..ef806a1de --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-2.CSL @@ -0,0 +1,306 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26B du DSK SHAKER26.DSK en CRTC 2 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 2 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26B"\(RET)' +wait 10000000 +; +; test 1 interlace c4/c9 counters R9 base=07 Parity Odd +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +key_output 'Y' ; bascule sur parity Even (R9 Base=7) +wait 300000 +; +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +key_output 'Z' ; Passe sur R9 BASE=6 (parity Even) +wait 300000 +; +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +; +key_output 'Y' ; bascule sur parity Odd (R9 base=6) +wait 300000 +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +; +; test 9 (garder la foi tu dois, mecreant) +key_output '9' ; En Odd +wait 20000000 ; +key_output ' ' +wait 20000000 +key_output ' ' +wait 1000000 +; +key_output 'Y' ; Repasser en Even +wait 100000 +key_output '9' ; En even +wait 20000000 ; +key_output ' ' +wait 20000000 +key_output ' ' +wait 1000000 +; +key_output '0' ; vertical sub pixel scroll +wait 1000000 ; 816677 1/8 +key_output ' ' +wait 1000000 ; 890842 1/16 +key_output ' ' +wait 1000000 ; 830950 1/32 +key_output ' ' +wait 1000000 ; 870899 1/64 +key_output ' ' +wait 1000000 ; 830965 1/128 +key_output ' ' +wait 1000000 ; menu +; +; ** crtc 2 only Even mode 1 ecran +key_output '2' ; +wait 3000000 ; 1245718 +key_output ' ' ; +wait 1000000 ; menu +key_output 'Y' ; repasser en Odd +key_output '2' +wait 3000000 ; 1245718 +key_output ' ' ; +wait 3000000 ; 1245718 2 ecrans +; +key_output '4' ; +wait 2000000 ; 1913669 +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 1000000 ; +key_output ' ' +wait 1000000 ; menu +; +key_output '5' ; rlal crtc 2 (tous crtc) +wait 900000 +key_output ' ' +wait 2000000 +key_output ' ' ; Menu +wait 1000000 +; +; +key_output '\(RET)' +wait 800000 ; 632429 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 800000 ; 647344 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 800000 ; 667312 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 1000000 +; +;Test Bounga +key_output '\(FN0)' +wait 30000000 ; ??? +key_output ' ' +wait 1000000 +; +; Test RVNI LTD +; +key_output '\(CAP)' +wait 6000000 ; 753563 +key_output ' ' +wait 6000000 ; 727728 +key_output ' ' +wait 6000000 ; 728880 +key_output ' ' +wait 6000000 +; +; Shaker Killer Don't be afraid +; +key_output 'R' +wait 5000000 ; 2615301 z80aintb +key_output ' ' +wait 6000000 ; 4692484 r52Reset +key_output ' ' +wait 9000000 ; 7867387 Inter Test IM1 +key_output ' ' +wait 9000000 ; 6888966 Inter Test IM2 +key_output ' ' +wait 3000000 ; 1711766 R52 Incr +key_output ' ' +wait 900000 ; 486262 Otir Zone +key_output ' ' +wait 1000000 ; menu +; +; R3 JIT +key_output 'I' +wait 1000000 ; 474622 +key_output ' ' +wait 1000000 ; 519168 +key_output ' ' +wait 1000000 ; 519168 +key_output ' ' +wait 1000000 ; 499200 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 599040 +key_output ' ' +wait 1000000 ; Menu +; +; test crtc 1 , ouvert aux autres CRTCs +; +key_output '6' +wait 20000000 ; 1676617 +key_output ' ' +wait 1000000 +; +; +; Test Analyzer des premieres heures +; +key_output 'P' +wait 100000000 ; 12828735+638976 +key_output ' ' +wait 100000000 ; 5440000+638976 +key_output ' ' +wait 100000000 ; 11637760+638976 +key_output ' ' +wait 100000000 ; 13560624+638976 +key_output ' ' +wait 1000000 + +csl_load 'SHAKE26B-4' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-3.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-3.CSL new file mode 100644 index 000000000..c536aff21 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-3.CSL @@ -0,0 +1,242 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26B du DSK SHAKER26.DSK en CRTC 3 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 3 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26B"\(RET)' +wait 10000000 +; +; test 1 interlace c4/c9 counters R9 base=07 +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +; +key_output 'Z' ; Passe sur R9 BASE=6 +wait 300000 +; +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +; +; test 9 (garder la foi tu dois, mecreant) +key_output '9' +wait 20000000 ; +key_output ' ' +wait 20000000 +key_output ' ' +wait 1000000 +; +key_output 'Y' ; Repasser en Even +wait 100000 +key_output '9' ; En even +wait 20000000 ; +key_output ' ' +wait 20000000 +key_output ' ' +wait 1000000 +; +key_output '0' ; vertical sub pixel scroll +wait 1000000 ; 816677 1/8 +key_output ' ' +wait 1000000 ; 890842 1/16 +key_output ' ' +wait 1000000 ; 830950 1/32 +key_output ' ' +wait 1000000 ; 870899 1/64 +key_output ' ' +wait 1000000 ; 830965 1/128 +key_output ' ' +wait 1000000 ; menu +; +key_output '4' ; +wait 2000000 ; 1913669 +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 1000000 ; +key_output ' ' +wait 1000000 ; menu +; +key_output '5' ; rlal crtc 2 (tous crtc) +wait 900000 +key_output ' ' +wait 2000000 +key_output ' ' ; Menu +wait 1000000 +; +; +key_output '\(RET)' +wait 800000 ; 632429 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 800000 ; 647344 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 800000 ; 667312 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 1000000 +; +;Test Bounga +key_output '\(FN0)' +wait 30000000 ; ??? +key_output ' ' +wait 1000000 +; +; Test RVNI LTD +; +key_output '\(CAP)' +wait 6000000 ; 753563 +key_output ' ' +wait 6000000 ; 727728 +key_output ' ' +wait 6000000 ; 728880 +key_output ' ' +wait 6000000 +; +; Shaker Killer Don't be afraid +; +key_output 'R' +wait 5000000 ; 2615301 z80aintb +key_output ' ' +wait 6000000 ; 4692484 r52Reset +key_output ' ' +wait 9000000 ; 7867387 Inter Test IM1 +key_output ' ' +wait 9000000 ; 6888966 Inter Test IM2 +key_output ' ' +wait 3000000 ; 1711766 R52 Incr +key_output ' ' +wait 900000 ; 486262 Otir Zone +key_output ' ' +wait 1000000 ; menu +; +; R3 JIT +key_output 'I' +wait 1000000 ; 474622 +key_output ' ' +wait 1000000 ; 519168 +key_output ' ' +wait 1000000 ; 519168 +key_output ' ' +wait 1000000 ; 499200 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 599040 +key_output ' ' +wait 1000000 ; Menu +; +; +; test crtc 1 , ouvert aux autres CRTCs +; +key_output '6' +wait 2000000 ; 1676617 +key_output ' ' +wait 1000000 + +; +; Test Analyzer des premieres heures +; +key_output 'P' +wait 100000000 ; 12828735+638976 +key_output ' ' +wait 100000000 ; 5440000+638976 +key_output ' ' +wait 100000000 ; 11637760+638976 +key_output ' ' +wait 100000000 ; 13560624+638976 +key_output ' ' +wait 1000000 +; +reset +; \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-4.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-4.CSL new file mode 100644 index 000000000..f54c20e28 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE B/SHAKE26B-4.CSL @@ -0,0 +1,241 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26B du DSK SHAKER26.DSK en CRTC 4 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 4 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26B"\(RET)' +wait 10000000 +; +; test 1 interlace c4/c9 counters R9 base=06 +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +; +key_output 'X' ; Passe sur R9 BASE=7 +wait 300000 +; +key_output '1' +wait 5000000 ; Ecran settings, ecran intermediaire +wait 7000000 ; 1er ecran +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; 5251584 +key_output ' ' +wait 7000000 ; menu +; +; test 9 (garder la foi tu dois, mecreant) +key_output '9' +wait 20000000 ; +key_output ' ' +wait 20000000 +key_output ' ' +wait 1000000 +; +key_output 'Y' ; Repasser en Even +wait 100000 +key_output '9' ; En even +wait 20000000 ; +key_output ' ' +wait 20000000 +key_output ' ' +wait 1000000 +; +key_output '0' ; vertical sub pixel scroll +wait 1000000 ; 816677 1/8 +key_output ' ' +wait 1000000 ; 890842 1/16 +key_output ' ' +wait 1000000 ; 830950 1/32 +key_output ' ' +wait 1000000 ; 870899 1/64 +key_output ' ' +wait 1000000 ; 830965 1/128 +key_output ' ' +wait 1000000 ; menu +; +key_output '4' ; +wait 2000000 ; 1913669 +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 900000 ; 730624 +key_output ' ' +wait 1000000 ; +key_output ' ' +wait 1000000 ; menu +; +key_output '5' ; rlal crtc 2 (tous crtc) +wait 900000 +key_output ' ' +wait 2000000 +key_output ' ' ; Menu +wait 1000000 +; +; +key_output '\(RET)' +wait 800000 ; 632429 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 800000 ; 647344 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 800000 ; 667312 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +wait 6000000 ; 5111808 +key_output ' ' +wait 1000000 +; +;Test Bounga +key_output '\(FN0)' +wait 50000000 ; ??? +key_output ' ' +wait 1000000 +; +; Test RVNI LTD +; +key_output '\(CAP)' +wait 6000000 ; 753563 +key_output ' ' +wait 6000000 ; 727728 +key_output ' ' +wait 6000000 ; 728880 +key_output ' ' +wait 6000000 +; +; Shaker Killer Don't be afraid +; +key_output 'R' +wait 5000000 ; 2615301 z80aintb +key_output ' ' +wait 6000000 ; 4692484 r52Reset +key_output ' ' +wait 9000000 ; 7867387 Inter Test IM1 +key_output ' ' +wait 9000000 ; 6888966 Inter Test IM2 +key_output ' ' +wait 3000000 ; 1711766 R52 Incr +key_output ' ' +wait 900000 ; 486262 Otir Zone +key_output ' ' +wait 1000000 ; menu +; +; R3 JIT +key_output 'I' +wait 1000000 ; 474622 +key_output ' ' +wait 1000000 ; 519168 +key_output ' ' +wait 1000000 ; 519168 +key_output ' ' +wait 1000000 ; 499200 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 619008 +key_output ' ' +wait 1000000 ; 599040 +key_output ' ' +wait 1000000 ; Menu +; +; +; test crtc 1 , ouvert aux autres CRTCs +; +key_output '6' +wait 12000000 ; 1676617 +key_output ' ' +wait 1000000 + +; +; Test Analyzer des premieres heures +; +key_output 'P' +wait 100000000 ; 12828735+638976 +key_output ' ' +wait 100000000 ; 5440000+638976 +key_output ' ' +wait 100000000 ; 11637760+638976 +key_output ' ' +wait 100000000 ; 13560624+638976 +key_output ' ' +wait 1000000 +; +csl_load 'SHAKE26B-3' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-0.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-0.CSL new file mode 100644 index 000000000..ed724fffb --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-0.CSL @@ -0,0 +1,96 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26C du DSK SHAKER26.DSK en CRTC 0 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 0 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26C"\(RET)' +wait 10000000 +; +; test 5 Parity Check Select CRTC 0, 2 +key_output '5' +wait 10000000 +key_output ' ' +wait 1000000 ; menu + +; test prevu pour CRTC 2 mais disp autre crc Last Line cond +key_output '7' +wait 64000000 +key_output ' ' +wait 1000000 ; menu + +; test crtc 2 vma' sur R1=0 +key_output 'T' +wait 1100000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1000000 ; menu + +; crtc 2 ghost vsync vs Last Line (others crtc welcome) +key_output '\(RET)' +wait 5000000 +key_output ' ' +wait 2000000 +key_output ' ' +wait 1000000 ; menu + +; Add Line R5 on last line +key_output 'E' +wait 10000000 +key_output ' ' +wait 5000000 +key_output ' ' +wait 1000000 ; menu + +; Add line R8 +key_output 'P' +wait 12000000 +key_output ' ' +wait 1000000 ; menu + +; r5 additional line in interlace mode +key_output 'S' +wait 2000000 +key_output ' ' +wait 1000000 ; menu + +; CRTC 0,3,4 Interlace vsync nightmare (2 1er test uniqu CRTC1) +key_output 'O' +wait 4000000 +key_output ' ' +wait 6000000 +key_output ' ' +wait 1000000 +wait 8000000 +key_output ' ' +wait 9000000 +key_output ' ' +wait 9000000 +key_output ' ' +wait 10000000 +key_output ' ' +wait 9000000 +key_output ' ' +wait 10000000 +key_output ' ' +wait 10000000 +key_output ' ' +wait 1000000 ; menu + +; R9/R4 UPD LAST LIMIT +key_output 'R' +wait 5000000 +key_output ' ' +wait 10000000 ; menu + +csl_load 'SHAKE26C-1' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-1.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-1.CSL new file mode 100644 index 000000000..2c41dc58b --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-1.CSL @@ -0,0 +1,187 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26C du DSK SHAKER26.DSK en CRTC 1 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 1 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26C"\(RET)' +wait 10000000 +; +; R8 IVM ODD C9 +key_output '2' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 ; menu + +; Parity Switch Status +key_output '3' +wait 5000000 +key_output ' ' +wait 1000000 ; menu + +; Ivm On/Off +key_output '4' +wait 800000 ; 23D +key_output ' ' +wait 1000000 ; 23E +key_output ' ' +wait 1000000 ; 23F +key_output ' ' +wait 1000000 ; 27F +key_output ' ' +wait 1000000 ; 280 +key_output ' ' +wait 1000000 ; 281 +key_output ' ' +wait 1000000 ; 282 +key_output ' ' +wait 1000000 ; 283 +key_output ' ' +wait 1000000 ; 284 +key_output ' ' +wait 1000000 ; 285, 286 +key_output ' ' +wait 1000000 ; 287, 288 +key_output ' ' +wait 1000000 ; 289 +key_output ' ' +wait 1000000 ; 28A +key_output ' ' +wait 1000000 ; 28B +key_output ' ' +wait 1000000 ; 28c +key_output ' ' +wait 1000000 ; 28d +key_output ' ' +wait 1000000 ; 28e +key_output ' ' +wait 1000000 ; 28f +key_output ' ' +wait 1000000 ; 290 +key_output ' ' +wait 1000000 ; 291 +key_output ' ' +wait 1000000 ; 292 +key_output ' ' +wait 1000000 ; 293 +key_output ' ' +wait 1000000 ; 294 +key_output ' ' +wait 1000000 ; 295 +key_output ' ' +wait 1000000 ; 296, 297 +key_output ' ' +wait 1000000 ; 298, 299 +key_output ' ' +wait 1000000 ; 29a +key_output ' ' +wait 1000000 ; 29b +key_output ' ' +wait 1000000 ; 29c +key_output ' ' +wait 1000000 ; 29d +key_output ' ' + +; test prevu pour CRTC 2 mais disp autre crc Last Line cond +key_output '7' +wait 64000000 +key_output ' ' +wait 1000000 ; menu + +; test crtc 2 vma' sur R1=0 +key_output 'T' +wait 1100000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1000000 ; menu + +; crtc 2 ghost vsync vs Last Line (others crtc welcome) +key_output '\(RET)' +wait 5000000 +key_output ' ' +wait 2000000 +key_output ' ' +wait 1000000 ; menu + +; Add Line R5 on last line +key_output 'E' +wait 20000000 +key_output ' ' +wait 10000000 +key_output ' ' +wait 1000000 ; menu + +; Add line R8 +key_output 'P' +wait 20000000 +key_output ' ' +wait 1000000 ; menu + +; r5 additional line in interlace mode +key_output 'S' +wait 4000000 +key_output ' ' +wait 1000000 ; menu + +; CRTC 1 Interlace vsync nightmare (2 1er test uniqu CRTC1) +key_output 'O' +wait 12000000 ; cvsct1_a +key_output ' ' +wait 6000000 ; cvsct1_b +key_output ' ' +wait 3500000 ; cvstot +key_output ' ' +wait 2000000 ; parity00 +wait 8000000 +key_output ' ' +wait 6000000 ; cvms_a +key_output ' ' +wait 6000000 ; cvms_b +key_output ' ' +wait 6000000 ; cvms_b +key_output ' ' +wait 6000000 ; cvms_c +key_output ' ' +wait 6000000 ; cvms_c +key_output ' ' +wait 3000000 ; parity01a +key_output ' ' +wait 3000000 ; parity01b +key_output ' ' +wait 3000000 ; parity01c +key_output ' ' +wait 3000000 ; parity01d +key_output ' ' +wait 3000000 ; parity01e +key_output ' ' +wait 3000000 ; parity01f +key_output ' ' +wait 1000000 + +csl_load 'SHAKE26C-2' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-2.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-2.CSL new file mode 100644 index 000000000..fcd59ee97 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-2.CSL @@ -0,0 +1,154 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26C du DSK SHAKER26.DSK en CRTC 2 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 2 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26C"\(RET)' +wait 10000000 +; +; test 5 Parity Check Select CRTC 0, 2 +key_output '5' +wait 10000000 +key_output ' ' +wait 1000000 ; menu + +; C9 IVM Switch +key_output '6' +wait 1200000 ; 29f +key_output ' ' +wait 1200000 ; 2a4 +key_output ' ' +wait 1200000 ; 2a5 +key_output ' ' +wait 1200000 ; 2a6 +key_output ' ' +wait 1200000 ; 2a7 +key_output ' ' +wait 1200000 ; 2ac +key_output ' ' +wait 1200000 ; 2ad +key_output ' ' +wait 1200000 ; 2ae +key_output ' ' +wait 1200000 ; 2af +key_output ' ' +wait 1200000 ; 2b4 +key_output ' ' +wait 1200000 ; 2b5 +key_output ' ' +wait 1200000 ; 2b6 +key_output ' ' +wait 1200000 ; 2b7 +key_output ' ' +wait 1200000 ; 2bc +key_output ' ' +wait 1200000 ; 2bd +key_output ' ' +wait 1200000 ; 2be +key_output ' ' +wait 1000000 ; menu + + +; test prevu pour CRTC 2 mais disp autre crc Last Line cond +key_output '7' +wait 64000000 +key_output ' ' +wait 1000000 ; menu +; +; add line on parity bug +key_output '8' +wait 2000000 ; 2c0 +key_output ' ' +wait 2000000 ; 2c1 +key_output ' ' +wait 2000000 ; 2c2 +key_output ' ' +wait 2000000 ; 2c3 +key_output ' ' +wait 2000000 ; 2c4 +key_output ' ' +wait 2000000 ; 2c5 +key_output ' ' +wait 2000000 ; 2c6 +key_output ' ' +wait 1000000 ; menu + +; add line rq & trigger +key_output '9' +wait 2000000 ; 2c7 +key_output ' ' +wait 300000000 +key_output ' ' + +; test crtc 2 vma' sur R1=0 +key_output 'T' +wait 1100000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1000000 ; menu + +; crtc 2 ghost vsync vs Last Line (others crtc welcome) +key_output '\(RET)' +wait 5000000 +key_output ' ' +wait 2000000 +key_output ' ' +wait 1000000 ; menu + +; Add Line R5 on last line +key_output 'E' +wait 20000000 +key_output ' ' +wait 10000000 +key_output ' ' +wait 1000000 ; menu + +; Add line R8 +key_output 'P' +wait 20000000 +key_output ' ' +wait 1000000 ; menu + +; r5 additional line in interlace mode +key_output 'S' +wait 2000000 +key_output ' ' +wait 1000000 ; menu + +; CRTC 2 Interlace vsync nightmare (2 1er test uniqu CRTC1) +key_output 'O' +wait 6000000 ; cvstot +key_output ' ' +wait 2000000 ; parity00 2d8 +wait 8000000 ; 2d9 +key_output ' ' +wait 10000000 ; cvms_a ; 2da +key_output ' ' +wait 10000000 ; cvms_b ; 2db +key_output ' ' +wait 10000000 ; cvms_b ; 2dc +key_output ' ' +wait 10000000 ; cvms_c ; 2dd +key_output ' ' +wait 10000000 ; cvms_c ; 2de +key_output ' ' +wait 10000000 ; menu + +; R9/R4 UPD LAST LIMIT +key_output 'R' +wait 5000000 ; 3ad +key_output ' ' +wait 10000000 ; menu + +cls_load 'SHAKE26C-4' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-3.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-3.CSL new file mode 100644 index 000000000..ccd58e9b6 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-3.CSL @@ -0,0 +1,94 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26C du DSK SHAKER26.DSK en CRTC 3 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 3 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26C"\(RET)' +wait 10000000 + +; test prevu pour CRTC 2 mais disp autre crc Last Line cond +key_output '7' +wait 64000000 +key_output ' ' +wait 1000000 ; menu +; +; test crtc 2 vma' sur R1=0 +key_output 'T' +wait 1100000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1000000 ; menu + +; crtc 2 ghost vsync vs Last Line (others crtc welcome) +key_output '\(RET)' +wait 5000000 ; 2cd +key_output ' ' +wait 2000000 ; 2ce +key_output ' ' +wait 1000000 ; menu + +; Add Line R5 on last line +key_output 'E' +wait 10000000 ; 2c9 +key_output ' ' +wait 5000000 ; 2ca +key_output ' ' +wait 1000000 ; menu + +; r5 additional line in interlace mode +key_output 'S' +wait 2000000 ; 2d3 +key_output ' ' +wait 1000000 ; menu + +; CRTC 2 Interlace vsync nightmare (2 1er test uniqu CRTC1) +key_output 'O' +wait 6000000 ; cvstot 2d6 +key_output ' ' +wait 3500000 ; cvstot 2d7 +key_output ' ' +wait 2000000 ; parity00 +wait 8000000 +key_output ' ' +wait 10000000 ; cvms_a 2d8 +key_output ' ' +wait 10000000 ; cvms_b +key_output ' ' +wait 10000000 ; cvms_b +key_output ' ' +wait 10000000 ; cvms_c +key_output ' ' +wait 10000000 ; cvms_c +key_output ' ' +wait 10000000 ; menu + +; Y crtc 3/4 parity +key_output 'Y' +wait 4500000 ; 2df +key_output ' ' +wait 1000000 ; 2e0 +key_output ' ' +wait 1000000 ; 2e1 +key_output ' ' +wait 1000000 ; 2e2 +key_output ' ' +wait 10000000 ; menu + +; R9/R4 UPD LAST LIMIT +key_output 'R' +wait 5000000 +key_output ' ' +wait 10000000 ; menu + +reset \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-4.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-4.CSL new file mode 100644 index 000000000..efd2f791b --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-4.CSL @@ -0,0 +1,94 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26C du DSK SHAKER26.DSK en CRTC 4 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 4 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26C"\(RET)' +wait 10000000 + +; test prevu pour CRTC 2 mais disp autre crc Last Line cond +key_output '7' +wait 64000000 +key_output ' ' +wait 1000000 ; menu +; +; test crtc 2 vma' sur R1=0 +key_output 'T' +wait 1100000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1200000 +key_output ' ' +wait 1000000 ; menu + +; crtc 2 ghost vsync vs Last Line (others crtc welcome) +key_output '\(RET)' +wait 5000000 ; 2cd +key_output ' ' +wait 2000000 ; 2ce +key_output ' ' +wait 1000000 ; menu + +; Add Line R5 on last line +key_output 'E' +wait 10000000 ; 2c9 +key_output ' ' +wait 5000000 ; 2ca +key_output ' ' +wait 1000000 ; menu + +; r5 additional line in interlace mode +key_output 'S' +wait 2000000 ; 2d3 +key_output ' ' +wait 1000000 ; menu + +; CRTC 2 Interlace vsync nightmare (2 1er test uniqu CRTC1) +key_output 'O' +wait 6000000 ; cvstot 2d6 +key_output ' ' +wait 3500000 ; cvstot 2d7 +key_output ' ' +wait 2000000 ; parity00 +wait 8000000 +key_output ' ' +wait 10000000 ; cvms_a 2d8 +key_output ' ' +wait 10000000 ; cvms_b +key_output ' ' +wait 10000000 ; cvms_b +key_output ' ' +wait 10000000 ; cvms_c +key_output ' ' +wait 10000000 ; cvms_c +key_output ' ' +wait 10000000 ; menu + +; Y crtc 3/4 parity +key_output 'Y' +wait 4500000 ; 2df +key_output ' ' +wait 1000000 ; 2e0 +key_output ' ' +wait 1000000 ; 2e1 +key_output ' ' +wait 1000000 ; 2e2 +key_output ' ' +wait 10000000 ; menu + +; R9/R4 UPD LAST LIMIT +key_output 'R' +wait 5000000 +key_output ' ' +wait 10000000 ; menu + +csl_load 'SHAKE26C-3' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-0.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-0.CSL new file mode 100644 index 000000000..50bef1179 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-0.CSL @@ -0,0 +1,201 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26D du DSK SHAKER26.DSK en CRTC 0 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 0 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26D"\(RET)' +wait 10000000 +; +; SHAKER KILLER 2 +key_output 'I' +wait 2000000 ; 2e3 ecran bleu +key_output ' ' +wait 2000000 ; 2e4 +key_output ' ' +wait 2000000 ; 2e5 +key_output ' ' +wait 2000000 ; 2e6 +key_output ' ' +wait 2000000 ; 2e7 +key_output ' ' +wait 2000000 ; 2e8 +key_output ' ' +wait 2000000 ; 2e9 +key_output ' ' +wait 1000000 ; menu + +; VSYNC TORTURE (LOCK MECHANISM) +; Eventuellement ajouter des SS sur les 3 tests desync crtc 0 +key_output 'R' +wait 22000000 ; 2ea +key_output ' ' +wait 1000000 ; menu + +; VSYNC/CSYNC GATE ARRAY +key_output 'T' +wait 800000 ; 2eb +key_output ' ' +wait 2000000 ; 2ec +key_output ' ' +wait 2000000 ; 2ed +key_output ' ' +wait 2000000 ; 2ee +key_output ' ' +wait 2000000 ; 2ef +key_output ' ' +wait 2000000 ; 2ef +key_output ' ' +wait 2000000 ; 2f0 +key_output ' ' +wait 2000000 ; 2f1 +key_output ' ' +wait 2000000 ; 2f2 +key_output ' ' +wait 2000000 ; 2f3 +key_output ' ' +wait 2000000 ; 2f4 +key_output ' ' +wait 2000000 ; 2f5 +key_output ' ' +wait 2000000 ; 2fb +key_output ' ' +wait 8000000 ; 2fc 2fd +key_output ' ' +wait 4000000 ; 2fe +key_output ' ' +wait 4000000 ; 2ff +key_output ' ' +wait 4000000 ; 300 +key_output ' ' +wait 4000000 ; 301 +key_output ' ' +wait 1000000 +key_delay 90000 +key_output ' ' +key_output ' ' +wait 1000000 ; menu + + +; HSYNC CSYNC GATE ARRAY +key_output 'H' +wait 1000000 ; 306 +key_output ' ' +wait 1200000 ; 307 +key_output ' ' +wait 1200000 ; 308 +key_output ' ' +wait 1200000 ; 309 +key_output ' ' +wait 1200000 ; 30A +key_output ' ' +wait 1200000 ; 30B +key_output ' ' +wait 1200000 ; 30C +key_output ' ' +wait 1200000 ; 30D +key_output ' ' +wait 1200000 ; 30E +key_output ' ' +wait 1200000 ; 30F +key_output ' ' +wait 1000000 ; menu + +; CSYNC4 VS 2XCSYNC2 +; +key_output '1' +wait 4600000 ; 310 +wait 4000000 ; 311 +wait 8000000 +key_output ' ' +wait 1000000 ; menu + +; R2JIT >> NO CSYNC UPD +; +key_output '2' +wait 4500000 ; 312 +wait 4000000 ; 313 +wait 4000000 +key_output ' ' +wait 10000000 +key_output ' ' +wait 1000000 + +; 2 CSYNC RELATIVE; +key_output '3' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 + +; CSYNC MULTIPLES +key_output '4' +wait 1000000 ; 37f +key_output ' ' +wait 3000000 ; 380 +key_output ' ' +wait 1000000 + +; Hardware scroll 1 pixel mode 1/0 (no buffering) +key_output '6' +wait 10000000 ; 381 +key_output ' ' +wait 10000000 ; 382 +key_output ' ' +wait 1000000 + +; +; R2 oscillation story; +key_output '7' +wait 10000000 ; 383 +key_output ' ' +wait 4000000 ; 384 +key_output ' ' +wait 4000000 ; 385 +key_output ' ' +wait 4000000 ; 386 +key_output ' ' +wait 4000000 ; 387 +key_output ' ' +wait 4000000 ; 388 +key_output ' ' +wait 4000000 ; 389 +key_output ' ' +wait 4000000 ; 38a +key_output ' ' +wait 4000000 ; 38b +key_output ' ' +wait 4000000 ; 38c +key_output ' ' +wait 1000000 ; menu +; +; no hsync for xx line +key_output '8' +wait 3000000 ; 38d +key_output ' ' +wait 3000000 ; 38e +key_output ' ' +wait 3000000 ; 38f +key_output ' ' +wait 3000000 ; 390 +key_output ' ' +wait 3000000 ; 391 +key_output ' ' +wait 3000000 ; 392 +key_output ' ' +wait 1000000 ; menu + + +csl_load 'SHAKE26D-1' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-1.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-1.CSL new file mode 100644 index 000000000..b7c4fd486 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-1.CSL @@ -0,0 +1,238 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26D du DSK SHAKER26.DSK en CRTC 1 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 1 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26D"\(RET)' +wait 10000000 +; +; SHAKER KILLER 2 +key_output 'I' +wait 2000000 ; 2e3 ecran bleu +key_output ' ' +wait 2000000 ; 2e4 +key_output ' ' +wait 2000000 ; 2e5 +key_output ' ' +wait 2000000 ; 2e6 +key_output ' ' +wait 2000000 ; 2e7 +key_output ' ' +wait 2000000 ; 2e8 +key_output ' ' +wait 2000000 ; 2e9 +key_output ' ' +wait 1000000 ; menu + +; VSYNC TORTURE (LOCK MECHANISM) +; Eventuellement ajouter des SS sur les 3 tests desync crtc 0 +key_output 'R' +wait 22000000 ; 2ea +key_output ' ' +wait 1000000 ; menu + +; VSYNC/CSYNC GATE ARRAY +key_output 'T' +wait 800000 ; 2eb +key_output ' ' +wait 2000000 ; 2ec +key_output ' ' +wait 2000000 ; 2ed +key_output ' ' +wait 2000000 ; 2ee +key_output ' ' +wait 2000000 ; 2ef +key_output ' ' +wait 2000000 ; 2ef +key_output ' ' +wait 2000000 ; 2f0 +key_output ' ' +wait 2000000 ; 2f1 +key_output ' ' +wait 2000000 ; 2f2 +key_output ' ' +wait 2000000 ; 2f3 +key_output ' ' +wait 2000000 ; 2f4 +key_output ' ' +wait 2000000 ; 2f5 +key_output ' ' +wait 2000000 ; 2fb +key_output ' ' +wait 8000000 ; 2fc 2fd +key_output ' ' +wait 4000000 ; 2fe +key_output ' ' +wait 4000000 ; 2ff +key_output ' ' +wait 4000000 ; 300 +key_output ' ' +wait 4000000 ; 301 +key_output ' ' +wait 1000000 +key_delay 90000 +key_output ' ' +key_output ' ' +wait 1000000 ; menu + +; HSYNC CSYNC GATE ARRAY +key_output 'H' +wait 1000000 ; 306 +key_output ' ' +wait 1200000 ; 307 +key_output ' ' +wait 1200000 ; 308 +key_output ' ' +wait 1200000 ; 309 +key_output ' ' +wait 1200000 ; 30A +key_output ' ' +wait 1200000 ; 30B +key_output ' ' +wait 1200000 ; 30C +key_output ' ' +wait 1200000 ; 30D +key_output ' ' +wait 1200000 ; 30E +key_output ' ' +wait 1200000 ; 30F +key_output ' ' +wait 1000000 ; menu + +; CSYNC4 VS 2XCSYNC2 +; +key_output '1' +wait 4600000 ; 310 +wait 4000000 ; 311 +wait 8000000 +key_output ' ' +wait 1000000 ; menu + +; R2JIT >> NO CSYNC UPD +; +key_output '2' +wait 4500000 ; 312 +wait 4000000 ; 313 +wait 4000000 +key_output ' ' +wait 10000000 +key_output ' ' +wait 1000000 + +; 2 CSYNC RELATIVE; +key_output '3' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 + +; CSYNC MULTIPLES +key_output '4' +wait 1000000 ; 37f +key_output ' ' +wait 3000000 ; 380 +key_output ' ' +wait 1000000 + +; Hardware scroll 1 pixel mode 1/0 (no buffering) +key_output '6' +wait 10000000 ; 381 +key_output ' ' +wait 10000000 ; 382 +key_output ' ' +wait 1000000 + +; +; R2 oscillation story; +key_output '7' +wait 10000000 ; 383 +key_output ' ' +wait 4000000 ; 384 +key_output ' ' +wait 4000000 ; 385 +key_output ' ' +wait 4000000 ; 386 +key_output ' ' +wait 4000000 ; 387 +key_output ' ' +wait 4000000 ; 388 +key_output ' ' +wait 4000000 ; 389 +key_output ' ' +wait 4000000 ; 38a +key_output ' ' +wait 4000000 ; 38b +key_output ' ' +wait 4000000 ; 38c +key_output ' ' +wait 1000000 ; menu +; +; no hsync for xx line +key_output '8' +wait 3000000 ; 38d +key_output ' ' +wait 3000000 ; 38e +key_output ' ' +wait 3000000 ; 38f +key_output ' ' +wait 3000000 ; 390 +key_output ' ' +wait 3000000 ; 391 +key_output ' ' +wait 3000000 ; 392 +key_output ' ' + +; rfd round 2 +; +key_output '9' +wait 2000000 ; 393, 3f7 +key_output ' ' +wait 2000000 ; 394, 3f8 +key_output ' ' +wait 2000000 ; 395, 3f9 +key_output ' ' +wait 2000000 ; 396 +key_output ' ' +wait 2000000 ; 397 +key_output ' ' +wait 2000000 ; 398 +key_output ' ' +wait 2000000 ; 399 +key_output ' ' +wait 2000000 ; 39a +key_output ' ' +wait 2000000 ; 39b +key_output ' ' +wait 1000000 ; menu + +; ofs upd in add managment +; +key_output 'E' +wait 1000000 ; 3ae +key_output ' ' +wait 1000000 ; 3af +key_output ' ' +wait 1000000 ; 3b4 +key_output ' ' +wait 1000000 ; 3b5 +key_output ' ' +wait 1000000 ; 3b6 +key_output ' ' +wait 1000000 ; 3b7 +key_output ' ' +wait 1000000 ; menu + +csl_load 'SHAKE26D-2' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-2.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-2.CSL new file mode 100644 index 000000000..609458da0 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-2.CSL @@ -0,0 +1,199 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26D du DSK SHAKER26.DSK en CRTC 2 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 2 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26D"\(RET)' +wait 10000000 +; +; SHAKER KILLER 2 +key_output 'I' +wait 2000000 ; 2e3 ecran bleu +key_output ' ' +wait 2000000 ; 2e4 +key_output ' ' +wait 2000000 ; 2e5 +key_output ' ' +wait 2000000 ; 2e6 +key_output ' ' +wait 2000000 ; 2e7 +key_output ' ' +wait 2000000 ; 2e8 +key_output ' ' +wait 2000000 ; 2e9 +key_output ' ' +wait 1000000 ; menu + +; VSYNC TORTURE (LOCK MECHANISM) +; Eventuellement ajouter des SS sur les 3 tests desync crtc 0 +key_output 'R' +wait 22000000 ; 2ea +key_output ' ' +wait 1000000 ; menu + +; VSYNC/CSYNC GATE ARRAY +key_output 'T' +wait 800000 ; 2eb +key_output ' ' +wait 2000000 ; 2ec +key_output ' ' +wait 2000000 ; 2ed +key_output ' ' +wait 2000000 ; 2ee +key_output ' ' +wait 2000000 ; 2ef +key_output ' ' +wait 2000000 ; 2ef +key_output ' ' +wait 2000000 ; 2f0 +key_output ' ' +wait 2000000 ; 2f1 +key_output ' ' +wait 2000000 ; 2f2 +key_output ' ' +wait 2000000 ; 2f3 +key_output ' ' +wait 2000000 ; 2f4 +key_output ' ' +wait 2000000 ; 2f5 +key_output ' ' +wait 2000000 ; 2fb +key_output ' ' +wait 8000000 ; 2fc 2fd +key_output ' ' +wait 4000000 ; 2fe +key_output ' ' +wait 4000000 ; 2ff +key_output ' ' +wait 4000000 ; 300 +key_output ' ' +wait 4000000 ; 301 +key_output ' ' +wait 1000000 +key_delay 90000 +key_output ' ' +key_output ' ' +wait 1000000 ; menu + +; HSYNC CSYNC GATE ARRAY +key_output 'H' +wait 1000000 ; 306 +key_output ' ' +wait 1200000 ; 307 +key_output ' ' +wait 1200000 ; 308 +key_output ' ' +wait 1200000 ; 309 +key_output ' ' +wait 1200000 ; 30A +key_output ' ' +wait 1200000 ; 30B +key_output ' ' +wait 1200000 ; 30C +key_output ' ' +wait 1200000 ; 30D +key_output ' ' +wait 1200000 ; 30E +key_output ' ' +wait 1200000 ; 30F +key_output ' ' +wait 1000000 ; menu + +; CSYNC4 VS 2XCSYNC2 +; +key_output '1' +wait 4600000 ; 310 +wait 4000000 ; 311 +wait 8000000 +key_output ' ' +wait 1000000 ; menu + +; R2JIT >> NO CSYNC UPD +; +key_output '2' +wait 4500000 ; 312 +wait 4000000 ; 313 +wait 4000000 +key_output ' ' +wait 10000000 +key_output ' ' +wait 1000000 + +; 2 CSYNC RELATIVE; +key_output '3' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 + +; CSYNC MULTIPLES +key_output '4' +wait 1000000 ; 37f +key_output ' ' +wait 3000000 ; 380 +key_output ' ' +wait 1000000 + +; Hardware scroll 1 pixel mode 1/0 (no buffering) +key_output '6' +wait 10000000 ; 381 +key_output ' ' +wait 10000000 ; 382 +key_output ' ' +wait 1000000 +; +; R2 oscillation story; +key_output '7' +wait 10000000 ; 383 +key_output ' ' +wait 4000000 ; 384 +key_output ' ' +wait 4000000 ; 385 +key_output ' ' +wait 4000000 ; 386 +key_output ' ' +wait 4000000 ; 387 +key_output ' ' +wait 4000000 ; 388 +key_output ' ' +wait 4000000 ; 389 +key_output ' ' +wait 4000000 ; 38a +key_output ' ' +wait 4000000 ; 38b +key_output ' ' +wait 4000000 ; 38c +key_output ' ' +wait 1000000 ; menu +; +; no hsync for xx line +key_output '8' +wait 3000000 ; 38d +key_output ' ' +wait 3000000 ; 38e +key_output ' ' +wait 3000000 ; 38f +key_output ' ' +wait 3000000 ; 390 +key_output ' ' +wait 3000000 ; 391 +key_output ' ' +wait 3000000 ; 392 +key_output ' ' +wait 1000000 ; menu + + +csl_load 'SHAKE26D-4' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-3.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-3.CSL new file mode 100644 index 000000000..41bcd1693 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-3.CSL @@ -0,0 +1,285 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26D du DSK SHAKER26.DSK en CRTC 4 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 3 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26D"\(RET)' +wait 10000000 +; +; SHAKER KILLER 2 +key_output 'I' +wait 2000000 ; 2e3 ecran bleu +key_output ' ' +wait 2000000 ; 2e4 +key_output ' ' +wait 2000000 ; 2e5 +key_output ' ' +wait 2000000 ; 2e6 +key_output ' ' +wait 2000000 ; 2e7 +key_output ' ' +wait 2000000 ; 2e8 +key_output ' ' +wait 2000000 ; 2e9 +key_output ' ' +wait 1000000 ; menu + +; VSYNC TORTURE (LOCK MECHANISM) +; Eventuellement ajouter des SS sur les 3 tests desync crtc 0 +key_output 'R' +wait 22000000 ; 2ea +key_output ' ' +wait 1000000 ; menu + +; VSYNC/CSYNC GATE ARRAY +key_output 'T' +wait 800000 ; 2eb +key_output ' ' +wait 2000000 ; 2ec +key_output ' ' +wait 2000000 ; 2ed +key_output ' ' +wait 2000000 ; 2ee +key_output ' ' +wait 2000000 ; 2ef +key_output ' ' +wait 2000000 ; 2ef +key_output ' ' +wait 2000000 ; 2f0 +key_output ' ' +wait 2000000 ; 2f1 +key_output ' ' +wait 2000000 ; 2f2 +key_output ' ' +wait 2000000 ; 2f3 +key_output ' ' +wait 2000000 ; 2f4 +key_output ' ' +wait 2000000 ; 2f5 +key_output ' ' +wait 2000000 ; 2fb +key_output ' ' +wait 8000000 ; 2fc 2fd +key_output ' ' +wait 4000000 ; 2fe +key_output ' ' +wait 4000000 ; 2ff +key_output ' ' +wait 4000000 ; 300 +key_output ' ' +wait 4000000 ; 301 +key_output ' ' +wait 1000000 +key_delay 90000 +key_output ' ' +key_output ' ' +wait 1000000 ; menu + +; HSYNC CSYNC GATE ARRAY +key_output 'H' +wait 1000000 ; 306 +key_output ' ' +wait 1200000 ; 307 +key_output ' ' +wait 1200000 ; 308 +key_output ' ' +wait 1200000 ; 309 +key_output ' ' +wait 1200000 ; 30A +key_output ' ' +wait 1200000 ; 30B +key_output ' ' +wait 1200000 ; 30C +key_output ' ' +wait 1200000 ; 30D +key_output ' ' +wait 1200000 ; 30E +key_output ' ' +wait 1200000 ; 30F +key_output ' ' +wait 1000000 ; menu + +; CSYNC4 VS 2XCSYNC2 +; +key_output '1' +wait 4600000 ; 310 +wait 4000000 ; 311 +wait 8000000 +key_output ' ' +wait 1000000 ; menu + +; R2JIT >> NO CSYNC UPD +; +key_output '2' +wait 4500000 ; 312 +wait 4000000 ; 313 +wait 4000000 +key_output ' ' +wait 10000000 +key_output ' ' +wait 1000000 + +; 2 CSYNC RELATIVE; +key_output '3' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 + +; CSYNC MULTIPLES +key_output '4' +wait 1000000 ; 37f +key_output ' ' +wait 3000000 ; 380 +key_output ' ' +wait 1000000 + +; Hardware scroll 1 pixel mode 1/0 (no buffering) +key_output '6' +wait 10000000 ; 381 +key_output ' ' +wait 10000000 ; 382 +key_output ' ' +wait 1000000 + +; +; R2 oscillation story; +key_output '7' +wait 10000000 ; 383 +key_output ' ' +wait 4000000 ; 384 +key_output ' ' +wait 4000000 ; 385 +key_output ' ' +wait 4000000 ; 386 +key_output ' ' +wait 4000000 ; 387 +key_output ' ' +wait 4000000 ; 388 +key_output ' ' +wait 4000000 ; 389 +key_output ' ' +wait 4000000 ; 38a +key_output ' ' +wait 4000000 ; 38b +key_output ' ' +wait 4000000 ; 38c +key_output ' ' +wait 1000000 ; menu +; +; no hsync for xx line +key_output '8' +wait 3000000 ; 38d +key_output ' ' +wait 3000000 ; 38e +key_output ' ' +wait 3000000 ; 38f +key_output ' ' +wait 3000000 ; 390 +key_output ' ' +wait 3000000 ; 391 +key_output ' ' +wait 3000000 ; 392 +key_output ' ' +wait 1000000 ; menu + +; +; CRTC 3/4 STATUS +key_output 'U' +wait 10000000 ; 3bc +key_output ' ' +wait 10000000 ; 3bd +key_output ' ' +wait 10000000 ; 3be +key_output ' ' +wait 15000000 ; 3bf +key_output ' ' +wait 45000000 ; 3c0 +key_output ' ' +wait 10000000 ; 3c1 +key_output ' ' +wait 4000000 ; 3c2 +key_output ' ' +wait 4000000 ; 3c3 +key_output ' ' +wait 4000000 ; 3c4 +key_output ' ' +wait 4000000 ; 3c5 +key_output ' ' +wait 4000000 ; 3c6 +key_output ' ' +wait 4000000 ; 3c7 +key_output ' ' +wait 4000000 ; 3c8 +key_output ' ' +wait 4000000 ; 3c9 +key_output ' ' +wait 4000000 ; 3ca +key_output ' ' +wait 4000000 ; 3cb +key_output ' ' +wait 4000000 ; 3cc +key_output ' ' +wait 4000000 ; 3cd +key_output ' ' +wait 4000000 ; 3ce +key_output ' ' +wait 4000000 ; 3cf +key_output ' ' +wait 4000000 ; 3d0 +key_output ' ' +wait 4000000 ; 3d1 +key_output ' ' +wait 4000000 ; 3d2 +key_output ' ' +wait 4000000 ; 3d3 +key_output ' ' +wait 4000000 ; 3d4 +key_output ' ' +wait 4000000 ; 3d5 +key_output ' ' +wait 4000000 ; 3d6 +key_output ' ' +wait 4000000 ; 3d7 +key_output ' ' +wait 4000000 ; 3d8 +key_output ' ' +wait 4000000 ; 3d9 +key_output ' ' +wait 4000000 ; 3da +key_output ' ' +wait 4000000 ; 3db +key_output ' ' +wait 4000000 ; 3dc +key_output ' ' +wait 4000000 ; 3dd +key_output ' ' +wait 4000000 ; 3de +key_output ' ' +wait 4000000 ; 3df +key_output ' ' +wait 4000000 ; 3e0 +key_output ' ' +wait 4000000 ; 3e1 +key_output ' ' +wait 4000000 ; 3e2 +key_output ' ' +wait 4000000 ; 3e3 +key_output ' ' +wait 4000000 ; 3e4 +key_output ' ' +wait 4000000 ; menu +reset diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-4.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-4.CSL new file mode 100644 index 000000000..dc2efadd9 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE D/SHAKE26D-4.CSL @@ -0,0 +1,286 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26D du DSK SHAKER26.DSK en CRTC 4 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 4 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26D"\(RET)' +wait 10000000 +; +; SHAKER KILLER 2 +key_output 'I' +wait 2000000 ; 2e3 ecran bleu +key_output ' ' +wait 2000000 ; 2e4 +key_output ' ' +wait 2000000 ; 2e5 +key_output ' ' +wait 2000000 ; 2e6 +key_output ' ' +wait 2000000 ; 2e7 +key_output ' ' +wait 2000000 ; 2e8 +key_output ' ' +wait 2000000 ; 2e9 +key_output ' ' +wait 1000000 ; menu + +; VSYNC TORTURE (LOCK MECHANISM) +; Eventuellement ajouter des SS sur les 3 tests desync crtc 0 +key_output 'R' +wait 22000000 ; 2ea +key_output ' ' +wait 1000000 ; menu + +; VSYNC/CSYNC GATE ARRAY +key_output 'T' +wait 800000 ; 2eb +key_output ' ' +wait 2000000 ; 2ec +key_output ' ' +wait 2000000 ; 2ed +key_output ' ' +wait 2000000 ; 2ee +key_output ' ' +wait 2000000 ; 2ef +key_output ' ' +wait 2000000 ; 2ef +key_output ' ' +wait 2000000 ; 2f0 +key_output ' ' +wait 2000000 ; 2f1 +key_output ' ' +wait 2000000 ; 2f2 +key_output ' ' +wait 2000000 ; 2f3 +key_output ' ' +wait 2000000 ; 2f4 +key_output ' ' +wait 2000000 ; 2f5 +key_output ' ' +wait 2000000 ; 2fb +key_output ' ' +wait 8000000 ; 2fc 2fd +key_output ' ' +wait 4000000 ; 2fe +key_output ' ' +wait 4000000 ; 2ff +key_output ' ' +wait 4000000 ; 300 +key_output ' ' +wait 4000000 ; 301 +key_output ' ' +wait 1000000 +key_delay 90000 +key_output ' ' +key_output ' ' +wait 1000000 ; menu + +; HSYNC CSYNC GATE ARRAY +key_output 'H' +wait 1000000 ; 306 +key_output ' ' +wait 1200000 ; 307 +key_output ' ' +wait 1200000 ; 308 +key_output ' ' +wait 1200000 ; 309 +key_output ' ' +wait 1200000 ; 30A +key_output ' ' +wait 1200000 ; 30B +key_output ' ' +wait 1200000 ; 30C +key_output ' ' +wait 1200000 ; 30D +key_output ' ' +wait 1200000 ; 30E +key_output ' ' +wait 1200000 ; 30F +key_output ' ' +wait 1000000 ; menu + +; CSYNC4 VS 2XCSYNC2 +; +key_output '1' +wait 4600000 ; 310 +wait 4000000 ; 311 +wait 8000000 +key_output ' ' +wait 1000000 ; menu + +; R2JIT >> NO CSYNC UPD +; +key_output '2' +wait 4500000 ; 312 +wait 4000000 ; 313 +wait 4000000 +key_output ' ' +wait 10000000 +key_output ' ' +wait 1000000 + +; 2 CSYNC RELATIVE; +key_output '3' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 +key_output ' ' +wait 1000000 + +; CSYNC MULTIPLES +key_output '4' +wait 1000000 ; 37f +key_output ' ' +wait 3000000 ; 380 +key_output ' ' +wait 1000000 + +; Hardware scroll 1 pixel mode 1/0 (no buffering) +key_output '6' +wait 10000000 ; 381 +key_output ' ' +wait 10000000 ; 382 +key_output ' ' +wait 1000000 + +; +; R2 oscillation story; +key_output '7' +wait 10000000 ; 383 +key_output ' ' +wait 4000000 ; 384 +key_output ' ' +wait 4000000 ; 385 +key_output ' ' +wait 4000000 ; 386 +key_output ' ' +wait 4000000 ; 387 +key_output ' ' +wait 4000000 ; 388 +key_output ' ' +wait 4000000 ; 389 +key_output ' ' +wait 4000000 ; 38a +key_output ' ' +wait 4000000 ; 38b +key_output ' ' +wait 4000000 ; 38c +key_output ' ' +wait 1000000 ; menu +; +; no hsync for xx line +key_output '8' +wait 3000000 ; 38d +key_output ' ' +wait 3000000 ; 38e +key_output ' ' +wait 3000000 ; 38f +key_output ' ' +wait 3000000 ; 390 +key_output ' ' +wait 3000000 ; 391 +key_output ' ' +wait 3000000 ; 392 +key_output ' ' +wait 1000000 ; menu + +; +; CRTC 3/4 STATUS +key_output 'U' +wait 10000000 ; 3bc +key_output ' ' +wait 10000000 ; 3bd +key_output ' ' +wait 10000000 ; 3be +key_output ' ' +wait 15000000 ; 3bf +key_output ' ' +wait 45000000 ; 3c0 +key_output ' ' +wait 10000000 ; 3c1 +key_output ' ' +wait 4000000 ; 3c2 +key_output ' ' +wait 4000000 ; 3c3 +key_output ' ' +wait 4000000 ; 3c4 +key_output ' ' +wait 4000000 ; 3c5 +key_output ' ' +wait 4000000 ; 3c6 +key_output ' ' +wait 4000000 ; 3c7 +key_output ' ' +wait 4000000 ; 3c8 +key_output ' ' +wait 4000000 ; 3c9 +key_output ' ' +wait 4000000 ; 3ca +key_output ' ' +wait 4000000 ; 3cb +key_output ' ' +wait 4000000 ; 3cc +key_output ' ' +wait 4000000 ; 3cd +key_output ' ' +wait 4000000 ; 3ce +key_output ' ' +wait 4000000 ; 3cf +key_output ' ' +wait 4000000 ; 3d0 +key_output ' ' +wait 4000000 ; 3d1 +key_output ' ' +wait 4000000 ; 3d2 +key_output ' ' +wait 4000000 ; 3d3 +key_output ' ' +wait 4000000 ; 3d4 +key_output ' ' +wait 4000000 ; 3d5 +key_output ' ' +wait 4000000 ; 3d6 +key_output ' ' +wait 4000000 ; 3d7 +key_output ' ' +wait 4000000 ; 3d8 +key_output ' ' +wait 4000000 ; 3d9 +key_output ' ' +wait 4000000 ; 3da +key_output ' ' +wait 4000000 ; 3db +key_output ' ' +wait 4000000 ; 3dc +key_output ' ' +wait 4000000 ; 3dd +key_output ' ' +wait 4000000 ; 3de +key_output ' ' +wait 4000000 ; 3df +key_output ' ' +wait 4000000 ; 3e0 +key_output ' ' +wait 4000000 ; 3e1 +key_output ' ' +wait 4000000 ; 3e2 +key_output ' ' +wait 4000000 ; 3e3 +key_output ' ' +wait 4000000 ; 3e4 +key_output ' ' +wait 4000000 ; menu + +csl_load 'SHAKE26D-3' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-0.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-0.CSL new file mode 100644 index 000000000..05abdace4 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-0.CSL @@ -0,0 +1,37 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26E du DSK SHAKER26.DSK en CRTC 0 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 0 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26E"\(RET)' +wait 10000000 +; +; R5 STORIES 2ND ROUND +key_output '1' +wait 2000000 ; 3fa +key_output ' ' +wait 2000000 ; 3fb +key_output ' ' +wait 2000000 ; 3fc +key_output ' ' +wait 2000000 ; 3fd +key_output ' ' +; +; +; CRTC 0 : C4/C9 COUNTER LOGIC +key_output '3' +wait 2000000 ; 403 +key_output ' ' +wait 2000000 ; 404 +key_output ' ' +wait 2000000 ; 405 +key_output ' ' +; +; +csl_load 'SHAKE26E-1' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-1.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-1.CSL new file mode 100644 index 000000000..66f04deb0 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-1.CSL @@ -0,0 +1,38 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26E du DSK SHAKER26.DSK en CRTC 1 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 1 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26E"\(RET)' +wait 10000000 +; +; R5 STORIES 2ND ROUND +key_output '1' +wait 2000000 ; 3fa +key_output ' ' +wait 2000000 ; 3fb +key_output ' ' +wait 2000000 ; 3fc +key_output ' ' +wait 2000000 ; 3fd +key_output ' ' +; +; +; CRTC 1 : VMA TRT C4=R4=0 ON ADJ LINE +; +key_output '2' +wait 2000000 ; 400 +key_output ' ' +wait 2000000 ; 401 +key_output ' ' +wait 2000000 ; 402 +key_output ' ' +; +; +csl_load 'SHAKE26E-2' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-2.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-2.CSL new file mode 100644 index 000000000..9ff24d678 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-2.CSL @@ -0,0 +1,28 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26E du DSK SHAKER26.DSK en CRTC 2 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 2 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26E"\(RET)' +wait 10000000 +; +; R5 STORIES 2ND ROUND +key_output '1' +wait 2000000 ; 3fa +key_output ' ' +wait 2000000 ; 3fb +key_output ' ' +wait 2000000 ; 3fc +key_output ' ' +wait 2000000 ; 3fd +key_output ' ' +; +; +; +csl_load 'SHAKE26E-4' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-3.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-3.CSL new file mode 100644 index 000000000..e25fa783c --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-3.CSL @@ -0,0 +1,27 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26E du DSK SHAKER26.DSK en CRTC 3 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 3 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26E"\(RET)' +wait 10000000 +; +; R5 STORIES 2ND ROUND +key_output '1' +wait 2000000 ; 3fa +key_output ' ' +wait 2000000 ; 3fb +key_output ' ' +wait 2000000 ; 3fc +key_output ' ' +wait 2000000 ; 3fd +key_output ' ' +; +; +; \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-4.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-4.CSL new file mode 100644 index 000000000..27684887e --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE E/SHAKE26E-4.CSL @@ -0,0 +1,28 @@ +; +; Fichier de script CSL +; Execution du module SHAKE26E du DSK SHAKER26.DSK en CRTC 4 +; Le module genere des instructions au format SSM +; +csl_version 1.0 +crtc_select 4 +reset +wait 3000000 +disk_insert 'shaker26.dsk' +key_delay 70000 70000 400000 +key_output 'RUN"SHAKE26E"\(RET)' +wait 10000000 +; +; R5 STORIES 2ND ROUND +key_output '1' +wait 2000000 ; 3fa +key_output ' ' +wait 2000000 ; 3fb +key_output ' ' +wait 2000000 ; 3fc +key_output ' ' +wait 2000000 ; 3fd +key_output ' ' +; +; +; +csl_load 'SHAKE26E-3' \ No newline at end of file diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/shaker26.dsk b/OSBindings/Mac/Clock SignalTests/Shaker/shaker26.dsk new file mode 100644 index 0000000000000000000000000000000000000000..8965d5175f02f4c3ef77d09e12d38f7bac379b60 GIT binary patch literal 194816 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 Date: Fri, 28 Jun 2024 21:53:18 -0400 Subject: [PATCH 06/19] Add URL credit. --- OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm index 7530e75cf..8da32bbbd 100644 --- a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm +++ b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm @@ -13,6 +13,9 @@ #include "CSL.hpp" +// +// Runs a local capture of the test cases found at https://shaker.logonsystem.eu +// @interface CPCShakerTests : XCTestCase @end From 0e30e2d8658415142a6e736603e16d1f3ec588ef Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 30 Jun 2024 20:19:02 -0400 Subject: [PATCH 07/19] Add CSL side of execution. --- Analyser/Static/AmstradCPC/Target.hpp | 5 + .../Clock Signal.xcodeproj/project.pbxproj | 4 + .../Mac/Clock SignalTests/CPCShakerTests.mm | 117 +++++++++++++++++- Storage/Automation/CSL.cpp | 4 + 4 files changed, 129 insertions(+), 1 deletion(-) diff --git a/Analyser/Static/AmstradCPC/Target.hpp b/Analyser/Static/AmstradCPC/Target.hpp index 6a4e74e4f..6db95805c 100644 --- a/Analyser/Static/AmstradCPC/Target.hpp +++ b/Analyser/Static/AmstradCPC/Target.hpp @@ -20,13 +20,18 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl #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 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(step.argument) != "1.0") { + XCTAssert(false, "Unrecognised file version"); + } + break; + + case Type::CRTCSelect: { + switch(std::get(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(step.argument)); + break; + + case Type::DiskInsert: { + const auto &disk = std::get(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(step.argument); + break; + + case Type::KeyOutput: { + auto &key_target = *machine().keyboard_machine(); + + const auto &events = std::get>(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(step.argument) + ".csl").c_str() + ]]; + break; + + default: + XCTAssert(false, "Unrecognised command: %d", step.type); + break; + } + } } - (void)testModulePath:(NSString *)path name:(NSString *)name { diff --git a/Storage/Automation/CSL.cpp b/Storage/Automation/CSL.cpp index 2982fccd1..08368ee50 100644 --- a/Storage/Automation/CSL.cpp +++ b/Storage/Automation/CSL.cpp @@ -322,6 +322,10 @@ std::vector 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'; From dbc0ecde311bb491bc0fede3ebb669063cb42d78 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 30 Jun 2024 21:26:16 -0400 Subject: [PATCH 08/19] Catch SSM events. --- Machines/AmstradCPC/AmstradCPC.cpp | 29 ++++++++++++++----- .../Mac/Clock SignalTests/CPCShakerTests.mm | 15 ++++++---- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index a7a046d3b..ff547d481 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -946,14 +946,29 @@ class ConcreteMachine: if constexpr (catches_ssm) { ssm_code_ = (ssm_code_ << 8) | read_pointers_[address >> 14][address & 16383]; - if((ssm_code_ & 0xff00ff00) == 0xed00ed00) { - if(ssm_delegate_) { - ssm_delegate_->perform( - uint16_t( - (ssm_code_ & 0xff) | ((ssm_code_ >> 8) & 0xff00) - )); + if(ssm_delegate_) { + if((ssm_code_ & 0xff00ff00) == 0xed00ed00) { + const auto code = uint16_t( + (ssm_code_ & 0xff) | ((ssm_code_ >> 8) & 0xff00) + ); + ssm_code_ = 0; + + if( + (code <= 0x3f3f) || + (code >= 0x7f7f && code <= 0x9f9f) || + (code >= 0xa4a4 && code <= 0xa7a7) || + (code >= 0xacac && code <= 0xafaf) || + (code >= 0xb4b4 && code <= 0xb7b7) || + (code >= 0xbcbc && code <= 0xbfbf) || + (code >= 0xc0c0 && code <= 0xfdfd) + ) { + ssm_delegate_->perform(code); + } } - ssm_code_ = 0; + } else if((ssm_code_ & 0xffff) == 0xedfe) { + ssm_delegate_->perform(0xfffe); + } else if((ssm_code_ & 0xffff) == 0xedff) { + ssm_delegate_->perform(0xffff); } } [[fallthrough]]; diff --git a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm index 9fc81a247..7ffc35ef4 100644 --- a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm +++ b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm @@ -21,8 +21,10 @@ #include "KeyboardMachine.hpp" #include "MachineForTarget.hpp" -struct CSLPerformer { - +struct SSMDelegate: public AmstradCPC::Machine::SSMDelegate { + void perform(uint16_t code) { + NSLog(@"SSM %04x", code); + } }; // @@ -31,23 +33,27 @@ struct CSLPerformer { @interface CPCShakerTests : XCTestCase @end -@implementation CPCShakerTests { -} +@implementation CPCShakerTests {} - (void)testCSLPath:(NSString *)path name:(NSString *)name { using namespace Storage::Automation; const auto steps = CSL::parse([[path stringByAppendingPathComponent:name] UTF8String]); + SSMDelegate ssm_delegate; + std::unique_ptr lazy_machine; CSL::KeyDelay key_delay; using Target = Analyser::Static::AmstradCPC::Target; Target target; target.catch_ssm_codes = true; + target.model = Target::Model::CPC6128; const auto machine = [&]() -> Machine::DynamicMachine& { if(!lazy_machine) { Machine::Error error; lazy_machine = Machine::MachineForTarget(&target, CSROMFetcher(), error); + reinterpret_cast(lazy_machine->raw_pointer()) + ->set_ssm_delegate(&ssm_delegate); } return *lazy_machine; }; @@ -56,7 +62,6 @@ struct CSLPerformer { }; using Type = CSL::Instruction::Type; - int c = 0; for(const auto &step: steps) { switch(step.type) { case Type::Version: From 00b3007b9ff8722dd66b527974ef58e214b0af21 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 2 Jul 2024 21:51:00 -0400 Subject: [PATCH 09/19] Switch byte order. --- Machines/AmstradCPC/AmstradCPC.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index ff547d481..67e3f0686 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -949,7 +949,7 @@ class ConcreteMachine: if(ssm_delegate_) { if((ssm_code_ & 0xff00ff00) == 0xed00ed00) { const auto code = uint16_t( - (ssm_code_ & 0xff) | ((ssm_code_ >> 8) & 0xff00) + ((ssm_code_ << 8) & 0xff00) | ((ssm_code_ >> 16) & 0x00ff) ); ssm_code_ = 0; From 9e8801d867c9b2456527e9e02683757e3f422d86 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 8 Jul 2024 00:17:39 +0200 Subject: [PATCH 10/19] Add header for std::variant. --- .../xcshareddata/xcschemes/Clock Signal.xcscheme | 2 +- Storage/Automation/CSL.hpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme index 474fa352e..3534e9926 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme +++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme @@ -1,7 +1,7 @@ + version = "1.3"> diff --git a/Storage/Automation/CSL.hpp b/Storage/Automation/CSL.hpp index 032238402..9e84ee100 100644 --- a/Storage/Automation/CSL.hpp +++ b/Storage/Automation/CSL.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace Storage::Automation::CSL { From 1e84a735e6c05169287c6b9743460363c18c7bf2 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 8 Jul 2024 00:18:53 +0200 Subject: [PATCH 11/19] Add header for std::vector. --- OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm index 86540c0ac..5885f30f6 100644 --- a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm +++ b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm @@ -15,6 +15,7 @@ #include #include +#include using namespace InstructionSet::ARM; From 78b2a89554cffc2f6dc5535e38f8722102f845ca Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 8 Jul 2024 00:18:53 +0200 Subject: [PATCH 12/19] Add header for std::vector. --- OSBindings/Mac/Clock SignalTests/8088Tests.mm | 1 + OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm | 1 + 2 files changed, 2 insertions(+) diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index 2aa017fc0..26c651890 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -16,6 +16,7 @@ #include #include #include +#include #include "NSData+dataWithContentsOfGZippedFile.h" diff --git a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm index 86540c0ac..5885f30f6 100644 --- a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm +++ b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm @@ -15,6 +15,7 @@ #include #include +#include using namespace InstructionSet::ARM; From 1977675a73621affb900faef4257908a5f3b35b4 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 5 Aug 2024 21:48:40 -0400 Subject: [PATCH 13/19] Add some measure of graphics output. --- .../Mac/Clock SignalTests/CPCShakerTests.mm | 100 +++++++++++++++++- 1 file changed, 96 insertions(+), 4 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm index 7ffc35ef4..60944292c 100644 --- a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm +++ b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm @@ -15,16 +15,106 @@ #include "AmstradCPC.hpp" #include "../../../Analyser/Static/AmstradCPC/Target.hpp" #include "../../../Machines/AmstradCPC/Keyboard.hpp" +#include "../../../Outputs/ScanTarget.hpp" #include "CSROMFetcher.hpp" #include "TimedMachine.hpp" #include "MediaTarget.hpp" #include "KeyboardMachine.hpp" #include "MachineForTarget.hpp" -struct SSMDelegate: public AmstradCPC::Machine::SSMDelegate { - void perform(uint16_t code) { - NSLog(@"SSM %04x", code); +struct ScanTarget: public Outputs::Display::ScanTarget { + void set_modals(Modals modals) override { + modals_ = modals; } + Scan *begin_scan() override { + return &scan_; + } + uint8_t *begin_data(size_t, size_t) override { + return data_.data(); + } + + + void end_scan() override { + // Empirical, CPC-specific observation: x positions end up + // being multiplied by 61 compared to a 1:1 pixel sampling at + // the CPC's highest resolution. + const int WidthDivider = 61; + + const int src_pixels = scan_.end_points[1].data_offset - scan_.end_points[0].data_offset; + const int dst_pixels = (scan_.end_points[1].x - scan_.end_points[0].x) / WidthDivider; + + const int step = (src_pixels << 16) / dst_pixels; + int position = 0; + + for(int x = scan_.end_points[0].x / WidthDivider; x < scan_.end_points[1].x / WidthDivider; x++) { + raw_image_[line_ * ImageWidth + x] = data_[position >> 16]; + position += step; + } + } + void announce(Event event, bool, const Scan::EndPoint &, uint8_t) override { + switch(event) { + case Event::EndHorizontalRetrace: ++line_; break; + case Event::EndVerticalRetrace: line_ = 0; break; + default: break; + } + } + + NSBitmapImageRep *image_representation() { + NSBitmapImageRep *const result = + [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL + pixelsWide:ImageWidth + pixelsHigh:ImageHeight + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:4 * ImageWidth + bitsPerPixel:0]; + uint8_t *const data = result.bitmapData; + + for(int c = 0; c < ImageWidth * ImageHeight; c++) { + data[c * 4 + 0] = ((raw_image_[c] >> 4) & 3) * 127; + data[c * 4 + 1] = ((raw_image_[c] >> 2) & 3) * 127; + data[c * 4 + 2] = ((raw_image_[c] >> 0) & 3) * 127; + data[c * 4 + 3] = 0xff; + } + + return result; + } + + +private: + Modals modals_; + Scan scan_; + std::array data_; + int line_ = 0; + + static constexpr int ImageWidth = 914; + static constexpr int ImageHeight = 312; + std::array raw_image_; +}; + +struct SSMDelegate: public AmstradCPC::Machine::SSMDelegate { + SSMDelegate(ScanTarget &scan_target) : scan_target_(scan_target) { + temp_dir_ = NSTemporaryDirectory(); + NSLog(@"Outputting to %@", temp_dir_); + } + + void perform(uint16_t code) { + NSData *const data = + [scan_target_.image_representation() representationUsingType:NSPNGFileType properties:@{}]; + NSString *const name = [temp_dir_ stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png", code]]; + [data + writeToFile:name + atomically:NO]; + NSLog(@"Wrote %@", name); + } + +private: + ScanTarget &scan_target_; + NSString *temp_dir_; }; // @@ -39,7 +129,8 @@ struct SSMDelegate: public AmstradCPC::Machine::SSMDelegate { using namespace Storage::Automation; const auto steps = CSL::parse([[path stringByAppendingPathComponent:name] UTF8String]); - SSMDelegate ssm_delegate; + ScanTarget scan_target; + SSMDelegate ssm_delegate(scan_target); std::unique_ptr lazy_machine; CSL::KeyDelay key_delay; @@ -54,6 +145,7 @@ struct SSMDelegate: public AmstradCPC::Machine::SSMDelegate { lazy_machine = Machine::MachineForTarget(&target, CSROMFetcher(), error); reinterpret_cast(lazy_machine->raw_pointer()) ->set_ssm_delegate(&ssm_delegate); + lazy_machine->scan_producer()->set_scan_target(&scan_target); } return *lazy_machine; }; From 05f0a122f4222a978afbbece87b15eb018510330 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 5 Aug 2024 22:06:23 -0400 Subject: [PATCH 14/19] Blank out border. --- .../Mac/Clock SignalTests/CPCShakerTests.mm | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm index 60944292c..bf7a2b229 100644 --- a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm +++ b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm @@ -46,15 +46,37 @@ struct ScanTarget: public Outputs::Display::ScanTarget { const int step = (src_pixels << 16) / dst_pixels; int position = 0; - for(int x = scan_.end_points[0].x / WidthDivider; x < scan_.end_points[1].x / WidthDivider; x++) { - raw_image_[line_ * ImageWidth + x] = data_[position >> 16]; + const auto x1 = scan_.end_points[0].x / WidthDivider; + const auto x2 = scan_.end_points[1].x / WidthDivider; + + uint8_t *const line = &raw_image_[line_ * ImageWidth]; + if(x_ < x1) { + std::fill(&line[x_], &line[x1], 0); + } + for(int x = x1; x < x2; x++) { + line[x] = data_[position >> 16]; position += step; } + x_ = x2; } void announce(Event event, bool, const Scan::EndPoint &, uint8_t) override { switch(event) { - case Event::EndHorizontalRetrace: ++line_; break; - case Event::EndVerticalRetrace: line_ = 0; break; + case Event::EndHorizontalRetrace: { + if(line_ == ImageHeight - 1) break; + + if(x_ < ImageWidth) { + uint8_t *const line = &raw_image_[line_ * ImageWidth]; + std::fill(&line[x_], &line[ImageWidth], 0); + } + + ++line_; + x_ = 0; + } break; + case Event::EndVerticalRetrace: + std::fill(&raw_image_[line_ * ImageWidth], &raw_image_[ImageHeight * ImageWidth], 0); + line_ = 0; + x_ = 0; + break; default: break; } } @@ -90,6 +112,7 @@ private: Scan scan_; std::array data_; int line_ = 0; + int x_ = 0; static constexpr int ImageWidth = 914; static constexpr int ImageHeight = 312; From 2d049f5fdc38d59e8da98fc9011daa469a20e694 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 7 Aug 2024 22:00:24 -0400 Subject: [PATCH 15/19] Implement reset, correct file names. --- .../Mac/Clock SignalTests/CPCShakerTests.mm | 78 +++++++++++++++---- 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm index bf7a2b229..2d1e66065 100644 --- a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm +++ b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm @@ -125,10 +125,20 @@ struct SSMDelegate: public AmstradCPC::Machine::SSMDelegate { NSLog(@"Outputting to %@", temp_dir_); } + void set_crtc(int number) { + crtc_ = number; + } + void perform(uint16_t code) { + if(!code) { + // A code of 0000 is supposed to end a wait0000 command; at present + // there seem to be no wait0000 commands to unblock. + return; + } + NSData *const data = [scan_target_.image_representation() representationUsingType:NSPNGFileType properties:@{}]; - NSString *const name = [temp_dir_ stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png", code]]; + NSString *const name = [temp_dir_ stringByAppendingPathComponent:[NSString stringWithFormat:@"CLK_%d_%04x.png", crtc_, code]]; [data writeToFile:name atomically:NO]; @@ -138,6 +148,7 @@ struct SSMDelegate: public AmstradCPC::Machine::SSMDelegate { private: ScanTarget &scan_target_; NSString *temp_dir_; + int crtc_ = 0; }; // @@ -162,6 +173,7 @@ private: target.catch_ssm_codes = true; target.model = Target::Model::CPC6128; + NSString *diskPath; const auto machine = [&]() -> Machine::DynamicMachine& { if(!lazy_machine) { Machine::Error error; @@ -169,6 +181,11 @@ private: reinterpret_cast(lazy_machine->raw_pointer()) ->set_ssm_delegate(&ssm_delegate); lazy_machine->scan_producer()->set_scan_target(&scan_target); + + if(diskPath) { + const auto media = Analyser::Static::GetMedia(diskPath.UTF8String); + lazy_machine->media_target()->insert_media(media); + } } return *lazy_machine; }; @@ -186,17 +203,21 @@ private: break; case Type::CRTCSelect: { - switch(std::get(step.argument)) { - default: break; + const auto argument = static_cast(std::get(step.argument)); + switch(argument) { + default: + NSLog(@"Unrecognised CRTC type %d", argument); + 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; } + ssm_delegate.set_crtc(argument); } break; case Type::Reset: - // Temporarily a no-op. + lazy_machine.reset(); break; case Type::Wait: @@ -208,14 +229,15 @@ private: XCTAssertEqual(disk.drive, 0); // Only drive 0 is supported for now. NSString *diskName = [NSString stringWithUTF8String:disk.file.c_str()]; - NSString *const diskPath = + 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); + if(lazy_machine) { + const auto media = Analyser::Static::GetMedia(diskPath.UTF8String); + machine().media_target()->insert_media(media); + } } break; case Type::KeyDelay: @@ -271,10 +293,40 @@ private: [self testCSLPath:[basePath stringByAppendingPathComponent:path] name:name]; } -- (void)testModuleA { [self testModulePath:@"MODULE A" name:@"SHAKE26A-0.CSL"]; } -- (void)testModuleB { [self testModulePath:@"MODULE B" name:@"SHAKE26B-0.CSL"]; } -- (void)testModuleC { [self testModulePath:@"MODULE C" name:@"SHAKE26C-0.CSL"]; } -- (void)testModuleD { [self testModulePath:@"MODULE D" name:@"SHAKE26D-0.CSL"]; } -- (void)testModuleE { [self testModulePath:@"MODULE E" name:@"SHAKE26E-0.CSL"]; } +- (void)testModuleA { + [self testModulePath:@"MODULE A" name:@"SHAKE26A-0.CSL"]; + [self testModulePath:@"MODULE A" name:@"SHAKE26A-1.CSL"]; + [self testModulePath:@"MODULE A" name:@"SHAKE26A-2.CSL"]; + [self testModulePath:@"MODULE A" name:@"SHAKE26A-3.CSL"]; + [self testModulePath:@"MODULE A" name:@"SHAKE26A-4.CSL"]; +} +- (void)testModuleB { + [self testModulePath:@"MODULE B" name:@"SHAKE26B-0.CSL"]; + [self testModulePath:@"MODULE B" name:@"SHAKE26B-1.CSL"]; + [self testModulePath:@"MODULE B" name:@"SHAKE26B-2.CSL"]; + [self testModulePath:@"MODULE B" name:@"SHAKE26B-3.CSL"]; + [self testModulePath:@"MODULE B" name:@"SHAKE26B-4.CSL"]; +} +- (void)testModuleC { + [self testModulePath:@"MODULE C" name:@"SHAKE26C-0.CSL"]; + [self testModulePath:@"MODULE C" name:@"SHAKE26C-1.CSL"]; + [self testModulePath:@"MODULE C" name:@"SHAKE26C-2.CSL"]; + [self testModulePath:@"MODULE C" name:@"SHAKE26C-3.CSL"]; + [self testModulePath:@"MODULE C" name:@"SHAKE26C-4.CSL"]; +} +- (void)testModuleD { + [self testModulePath:@"MODULE D" name:@"SHAKE26D-0.CSL"]; + [self testModulePath:@"MODULE D" name:@"SHAKE26D-1.CSL"]; + [self testModulePath:@"MODULE D" name:@"SHAKE26D-2.CSL"]; + [self testModulePath:@"MODULE D" name:@"SHAKE26D-3.CSL"]; + [self testModulePath:@"MODULE D" name:@"SHAKE26D-4.CSL"]; +} +- (void)testModuleE { + [self testModulePath:@"MODULE E" name:@"SHAKE26E-0.CSL"]; + [self testModulePath:@"MODULE E" name:@"SHAKE26E-1.CSL"]; + [self testModulePath:@"MODULE E" name:@"SHAKE26E-2.CSL"]; + [self testModulePath:@"MODULE E" name:@"SHAKE26E-3.CSL"]; + [self testModulePath:@"MODULE E" name:@"SHAKE26E-4.CSL"]; +} @end From ef11262721983d2d889b3a43106702e31e748569 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 7 Aug 2024 22:15:43 -0400 Subject: [PATCH 16/19] Expand test membership. --- .../Clock Signal.xcodeproj/project.pbxproj | 154 ++++++++++++++++++ .../xcschemes/Clock SignalTests.xcscheme | 2 +- 2 files changed, 155 insertions(+), 1 deletion(-) diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index cf8e5264d..7cd0b9f30 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -139,6 +139,83 @@ 4B055AEE1FAE9BBF0060FFFF /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B86E2591F8C628F006FAA45 /* Keyboard.cpp */; }; 4B055AEF1FAE9BF00060FFFF /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A471F9B8FA70062DABF /* Typer.cpp */; }; 4B055AF21FAE9C1C0060FFFF /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B055AF01FAE9C080060FFFF /* OpenGL.framework */; }; + 4B06AACB2C645ED00034D014 /* AY38910.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */; }; + 4B06AACC2C645EDF0034D014 /* Archimedes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB505842B9634F30031C43C /* Archimedes.cpp */; }; + 4B06AACD2C645EE50034D014 /* Enterprise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B051CA12676F52200CA44E8 /* Enterprise.cpp */; }; + 4B06AACE2C645EEC0034D014 /* PCCompatible.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425739372B051EA800B7D1E4 /* PCCompatible.cpp */; }; + 4B06AACF2C645EF40034D014 /* i8272.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC951C1F368D83008F4C34 /* i8272.cpp */; }; + 4B06AAD02C645F0A0034D014 /* EXDos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B051CB42680158600CA44E8 /* EXDos.cpp */; }; + 4B06AAD12C645F130034D014 /* 1770.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD468F51D8DF41D0084958B /* 1770.cpp */; }; + 4B06AAD22C645F190034D014 /* I2C.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A1CD92BA775C5004496CE /* I2C.cpp */; }; + 4B06AAD32C645F1F0034D014 /* MSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B79A4FF1FC913C900EEDAD5 /* MSX.cpp */; }; + 4B06AAD42C645F250034D014 /* Oric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */; }; + 4B06AAD52C645F290034D014 /* AppleII.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCE0050227CE8CA000CA200 /* AppleII.cpp */; }; + 4B06AAD62C645F2D0034D014 /* AtariST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0ACC0623775819008902D0 /* AtariST.cpp */; }; + 4B06AAD72C645F330034D014 /* AppleIIgs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE21214253FCE9C00435408 /* AppleIIgs.cpp */; }; + 4B06AAD82C645F370034D014 /* MasterSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7F188C2154825D00388727 /* MasterSystem.cpp */; }; + 4B06AAD92C645F5D0034D014 /* SN76489.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB0A6592044FD3000FB3688 /* SN76489.cpp */; }; + 4B06AADA2C645F650034D014 /* MemorySlotHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0BC67297108D100CCA2B5 /* MemorySlotHandler.cpp */; }; + 4B06AADB2C645F6D0034D014 /* DiskROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4F2002DB30000708CC /* DiskROM.cpp */; }; + 4B06AADC2C645F720034D014 /* BD500.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7BA03523CEB86000B98D9E /* BD500.cpp */; }; + 4B06AADD2C645F790034D014 /* Microdisc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */; }; + 4B06AADE2C645F7E0034D014 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DF4F7254E36AD00F3433C /* Video.cpp */; }; + 4B06AADF2C645F830034D014 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5056F2B962DDF0031C43C /* Video.cpp */; }; + 4B06AAE02C645F870034D014 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCE004D227CE8CA000CA200 /* Video.cpp */; }; + 4B06AAE12C645F8B0034D014 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2BFDB01DAEF5FF001A68B8 /* Video.cpp */; }; + 4B06AAE22C645F970034D014 /* PCBooter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 423820422B1A90BE00964EFE /* PCBooter.cpp */; }; + 4B06AAE32C645F9E0034D014 /* StringSerialiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B17B58920A8A9D9007CCA8F /* StringSerialiser.cpp */; }; + 4B06AAE42C645FA50034D014 /* DiskIICard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCE004E227CE8CA000CA200 /* DiskIICard.cpp */; }; + 4B06AAE52C645FAA0034D014 /* SCSICard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4C81C328B3C5CD00F84AE9 /* SCSICard.cpp */; }; + 4B06AAE62C645FB10034D014 /* ADB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DF503254E3C9D00F3433C /* ADB.cpp */; }; + 4B06AAE72C645FBC0034D014 /* DMAController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0ACC0723775819008902D0 /* DMAController.cpp */; }; + 4B06AAE82C645FCD0034D014 /* RP5C01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0BC6F2973318E00CCA2B5 /* RP5C01.cpp */; }; + 4B06AAE92C645FD30034D014 /* Jasmin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7BA02E23C2B19B00B98D9E /* Jasmin.cpp */; }; + 4B06AAEA2C645FDD0034D014 /* Bus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCE1DEF25D4C3FA00AE7A2B /* Bus.cpp */; }; + 4B06AAEB2C645FE80034D014 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C11F8D91CD0050900F /* Keyboard.cpp */; }; + 4B06AAEC2C645FF50034D014 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E86CD25D8D8C70024F1E9 /* Keyboard.cpp */; }; + 4B06AAED2C6460040034D014 /* Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1EC714255398B000A1F44B /* Sound.cpp */; }; + 4B06AAEE2C64600C0034D014 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; + 4B06AAEF2C6460180034D014 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B051CAE267C1CA200CA44E8 /* Keyboard.cpp */; }; + 4B06AAF02C6460240034D014 /* ReactiveDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E86B525D7490E0024F1E9 /* ReactiveDevice.cpp */; }; + 4B06AAF12C64602D0034D014 /* 6850.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB307BA235001C300457D33 /* 6850.cpp */; }; + 4B06AAF22C6460320034D014 /* MFP68901.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B92E268234AE35000CD6D1B /* MFP68901.cpp */; }; + 4B06AAF32C64603D0034D014 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C41F8D91D90050900F /* Keyboard.cpp */; }; + 4B06AAF42C6460430034D014 /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1BCC2602F17B00B85C66 /* ZX8081.cpp */; }; + 4B06AAF52C6460600034D014 /* Mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E86BC25D74F160024F1E9 /* Mouse.cpp */; }; + 4B06AAF62C6460670034D014 /* DiskIIDrive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80CD6D2568A82600176FCC /* DiskIIDrive.cpp */; }; + 4B06AAF72C64606E0034D014 /* DiskII.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B302183208A550100773308 /* DiskII.cpp */; }; + 4B06AAF82C6460760034D014 /* IntelligentKeyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0ACC0923775819008902D0 /* IntelligentKeyboard.cpp */; }; + 4B06AAF92C64607C0034D014 /* AudioToggle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B595FAC2086DFBA0083CAA8 /* AudioToggle.cpp */; }; + 4B06AAFA2C6460800034D014 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; }; + 4B06AAFB2C6460920034D014 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BD1F8D8F450050900F /* Keyboard.cpp */; }; + 4B06AAFC2C6460970034D014 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B12C0EB1FCFA98D005BFD93 /* Keyboard.cpp */; }; + 4B06AAFD2C64609D0034D014 /* IMD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42EB81262B23AAC300429AF4 /* IMD.cpp */; }; + 4B06AAFE2C6460A40034D014 /* ConfidenceSummary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8944E8201967B4007DE474 /* ConfidenceSummary.cpp */; }; + 4B06AAFF2C6460A80034D014 /* ConfidenceCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8944E6201967B4007DE474 /* ConfidenceCounter.cpp */; }; + 4B06AB002C6460B70034D014 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1C1B2604EA1000B85C66 /* Keyboard.cpp */; }; + 4B06AB012C6460C30034D014 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1BCD2602F17B00B85C66 /* Video.cpp */; }; + 4B06AB022C6460CB0034D014 /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A471F9B8FA70062DABF /* Typer.cpp */; }; + 4B06AB032C6460D00034D014 /* OPLL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC23A2B2467600E001A6030 /* OPLL.cpp */; }; + 4B06AB042C6460D60034D014 /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; }; + 4B06AB052C6460EC0034D014 /* ZXSpectrum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1BFA260300D900B85C66 /* ZXSpectrum.cpp */; }; + 4B06AB062C6460F40034D014 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0ACC2223775819008902D0 /* Atari2600.cpp */; }; + 4B06AB072C6461160034D014 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 429B135F2B1F7BDA006BB4CB /* StaticAnalyser.cpp */; }; + 4B06AB082C64611F0034D014 /* ColecoVision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7A90E42041097C008514A2 /* ColecoVision.cpp */; }; + 4B06AB092C64612C0034D014 /* TIA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0ACC1D23775819008902D0 /* TIA.cpp */; }; + 4B06AB0A2C6461350034D014 /* TIASound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0ACC2123775819008902D0 /* TIASound.cpp */; }; + 4B06AB0B2C64614B0034D014 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5056E2B962DDF0031C43C /* Electron.cpp */; }; + 4B06AB0C2C6461590034D014 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 423820102B17CBC800964EFE /* StaticAnalyser.cpp */; }; + 4B06AB0D2C6461610034D014 /* MultiMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3FCC3F201EC24200960631 /* MultiMachine.cpp */; }; + 4B06AB0E2C6461700034D014 /* MultiMediaTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB70A3202011C2002FE009 /* MultiMediaTarget.cpp */; }; + 4B06AB0F2C6461780034D014 /* MultiProducer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB70A6202014E2002FE009 /* MultiProducer.cpp */; }; + 4B06AB102C6461810034D014 /* SoundGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5056B2B962DDF0031C43C /* SoundGenerator.cpp */; }; + 4B06AB112C64618B0034D014 /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB505732B962DDF0031C43C /* Tape.cpp */; }; + 4B06AB122C6461910034D014 /* Plus3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB505752B962DDF0031C43C /* Plus3.cpp */; }; + 4B06AB132C6461970034D014 /* MultiConfigurable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B88BE202E3DB200B67DFF /* MultiConfigurable.cpp */; }; + 4B06AB142C64619E0034D014 /* MultiJoystickMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B88C6202E469300B67DFF /* MultiJoystickMachine.cpp */; }; + 4B06AB152C6461A20034D014 /* MultiKeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B88B9202E2EC100B67DFF /* MultiKeyboardMachine.cpp */; }; + 4B06AB162C6461AB0034D014 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB505762B962DDF0031C43C /* Keyboard.cpp */; }; + 4B06AB172C6461B30034D014 /* MultiSpeaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9BE3FE203A0C0600FFAE60 /* MultiSpeaker.cpp */; }; 4B08A2751EE35D56008B7065 /* Z80InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */; }; 4B08A2781EE39306008B7065 /* TestMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2771EE39306008B7065 /* TestMachine.mm */; }; 4B08A56920D72BEF0016CE5A /* Activity.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B08A56720D72BEF0016CE5A /* Activity.xib */; }; @@ -6366,6 +6443,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4B06AAEA2C645FDD0034D014 /* Bus.cpp in Sources */, 4B778EF623A5EB600000D260 /* WOZ.cpp in Sources */, 42EB812F2B4700B800429AF4 /* MemoryMap.cpp in Sources */, 4B778F1423A5EC960000D260 /* Z80Storage.cpp in Sources */, @@ -6373,12 +6451,16 @@ 4B778F1523A5EC980000D260 /* PartialMachineCycle.cpp in Sources */, 4BEDA43125B3C700000C2DBD /* Executor.cpp in Sources */, 4B778F6123A5F3560000D260 /* Disk.cpp in Sources */, + 4B06AAF82C6460760034D014 /* IntelligentKeyboard.cpp in Sources */, 4B7752B628217EE70073E2C5 /* DSK.cpp in Sources */, + 4B06AAD12C645F130034D014 /* 1770.cpp in Sources */, 4B778F2523A5EDF40000D260 /* Encoder.cpp in Sources */, 4B778F4223A5F1A70000D260 /* MemoryFuzzer.cpp in Sources */, 4B778F0123A5EBA00000D260 /* MacintoshIMG.cpp in Sources */, 4B7752AD28217E770073E2C5 /* AmigaADF.cpp in Sources */, + 4B06AAEB2C645FE80034D014 /* Keyboard.cpp in Sources */, 4BFF1D3D2235C3C100838EA1 /* EmuTOSTests.mm in Sources */, + 4B06AB052C6460EC0034D014 /* ZXSpectrum.cpp in Sources */, 4B3F76B925A1635300178AEC /* PowerPCDecoderTests.mm in Sources */, 4B778F0A23A5EC150000D260 /* TapePRG.cpp in Sources */, 4B778F0823A5EC150000D260 /* CSW.cpp in Sources */, @@ -6388,6 +6470,7 @@ 4B7752BA28217F160073E2C5 /* Bitplanes.cpp in Sources */, 4BDDBA991EF3451200347E61 /* Z80MachineCycleTests.swift in Sources */, 4B778F4E23A5F2160000D260 /* StaticAnalyser.cpp in Sources */, + 4B06AAFF2C6460A80034D014 /* ConfidenceCounter.cpp in Sources */, 4B778F5523A5F2A70000D260 /* Keyboard.cpp in Sources */, 4B778F5D23A5F3230000D260 /* Commodore.cpp in Sources */, 4B98A05F1FFAD62400ADF63B /* CSROMFetcher.mm in Sources */, @@ -6398,21 +6481,29 @@ 4B778F4A23A5F1FB0000D260 /* StaticAnalyser.cpp in Sources */, 4B7752AB28217E560073E2C5 /* SZX.cpp in Sources */, 4BD91D772401C2B8007BDC91 /* PatrikRakTests.swift in Sources */, + 4B06AAE22C645F970034D014 /* PCBooter.cpp in Sources */, 4B1082C32C1A87CA00B07C5D /* CSL.cpp in Sources */, 4B680CE223A5553100451D43 /* 68000ComparativeTests.mm in Sources */, 4B778F3723A5F11C0000D260 /* Parser.cpp in Sources */, + 4B06AAE32C645F9E0034D014 /* StringSerialiser.cpp in Sources */, + 4B06AADB2C645F6D0034D014 /* DiskROM.cpp in Sources */, 4B778F4523A5F1CD0000D260 /* SegmentParser.cpp in Sources */, 4B90467422C6FADD000E2074 /* 68000BitwiseTests.mm in Sources */, + 4B06AAD42C645F250034D014 /* Oric.cpp in Sources */, 4B7962A12819681F008130F9 /* Decoder.cpp in Sources */, 4B7752BB28217F1A0073E2C5 /* Copper.cpp in Sources */, 4B778F1D23A5ED470000D260 /* DiskController.cpp in Sources */, 4B778F0023A5EB990000D260 /* G64.cpp in Sources */, 4B778F4B23A5F2030000D260 /* StaticAnalyser.cpp in Sources */, 4B778F5023A5F2230000D260 /* StaticAnalyser.cpp in Sources */, + 4B06AACB2C645ED00034D014 /* AY38910.cpp in Sources */, + 4B06AB172C6461B30034D014 /* MultiSpeaker.cpp in Sources */, + 4B06AADE2C645F7E0034D014 /* Video.cpp in Sources */, 4B924E991E74D22700B76AF1 /* AtariStaticAnalyserTests.mm in Sources */, 4B90467622C6FD6E000E2074 /* 68000ArithmeticTests.mm in Sources */, 4B778F3423A5F1040000D260 /* DirectAccessDevice.cpp in Sources */, 4B7BC7F51F58F27800D1B1B4 /* 6502AllRAM.cpp in Sources */, + 4B06AAD82C645F370034D014 /* MasterSystem.cpp in Sources */, 4BC5C3E022C994CD00795658 /* 68000MoveTests.mm in Sources */, 4B778F5923A5F2D00000D260 /* Z80.cpp in Sources */, 4BD971392BFC3D9D00C907AA /* ArchimedesStaticAnalyserTests.mm in Sources */, @@ -6420,49 +6511,66 @@ 4B778F0E23A5EC4F0000D260 /* Tape.cpp in Sources */, 4B778F2D23A5EF190000D260 /* MFMDiskController.cpp in Sources */, 4B7752C228217F5C0073E2C5 /* Spectrum.cpp in Sources */, + 4B06AAD92C645F5D0034D014 /* SN76489.cpp in Sources */, 423BDC4A2AB24699008E37B6 /* 8088Tests.mm in Sources */, 4B778F2723A5EEF60000D260 /* BinaryDump.cpp in Sources */, 4BFCA1241ECBDCB400AC40C1 /* AllRAMProcessor.cpp in Sources */, + 4B06AB042C6460D60034D014 /* 6560.cpp in Sources */, + 4B06AB002C6460B70034D014 /* Keyboard.cpp in Sources */, 4B778F5223A5F22F0000D260 /* StaticAnalyser.cpp in Sources */, 4B778F4923A5F1F40000D260 /* StaticAnalyser.cpp in Sources */, 4BBF49AF1ED2880200AB3669 /* FUSETests.swift in Sources */, 4B778F4D23A5F20F0000D260 /* StaticAnalyser.cpp in Sources */, + 4B06AAD72C645F330034D014 /* AppleIIgs.cpp in Sources */, + 4B06AB082C64611F0034D014 /* ColecoVision.cpp in Sources */, 4B778F0423A5EBB00000D260 /* OricMFMDSK.cpp in Sources */, 4B7752BE28217F220073E2C5 /* MouseJoystick.cpp in Sources */, 4B8DF4D825465B7500F3433C /* IIgsMemoryMapTests.mm in Sources */, 4B3BA0CE1D318B44005DD7A7 /* C1540Bridge.mm in Sources */, 4B4F477C253530B7004245B8 /* Jeek816Tests.swift in Sources */, + 4B06AB062C6460F40034D014 /* Atari2600.cpp in Sources */, 4B7752B928217F140073E2C5 /* Audio.cpp in Sources */, 4B778F0F23A5EC560000D260 /* PCMTrack.cpp in Sources */, 4B778F1123A5EC650000D260 /* FileHolder.cpp in Sources */, 4B778EFC23A5EB8B0000D260 /* AcornADF.cpp in Sources */, + 4B06AB122C6461910034D014 /* Plus3.cpp in Sources */, 4B778F2023A5EDCE0000D260 /* HFV.cpp in Sources */, 4B778F3323A5F0FB0000D260 /* MassStorageDevice.cpp in Sources */, 4B75F979280D7C5100121055 /* 68000DecoderTests.mm in Sources */, 4B778F2C23A5EF0F0000D260 /* ZX8081.cpp in Sources */, 4B778F3023A5F0C50000D260 /* Macintosh.cpp in Sources */, 4B882F5C2C32199400D84031 /* MachineForTarget.cpp in Sources */, + 4B06AAD32C645F1F0034D014 /* MSX.cpp in Sources */, + 4B06AAD02C645F0A0034D014 /* EXDos.cpp in Sources */, 4B3BA0D11D318B44005DD7A7 /* TestMachine6502.mm in Sources */, 4B778F4623A5F1D80000D260 /* StaticAnalyser.cpp in Sources */, 4B778F1323A5EC890000D260 /* Z80Base.cpp in Sources */, 4B778F2923A5EF030000D260 /* CommodoreROM.cpp in Sources */, + 4B06AADC2C645F720034D014 /* BD500.cpp in Sources */, 4B778F4823A5F1E70000D260 /* StaticAnalyser.cpp in Sources */, 4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */, 4B778F2823A5EEF80000D260 /* Cartridge.cpp in Sources */, + 4B06AAED2C6460040034D014 /* Sound.cpp in Sources */, + 4B06AAF12C64602D0034D014 /* 6850.cpp in Sources */, + 4B06AAF22C6460320034D014 /* MFP68901.cpp in Sources */, 4B7752B528217ED30073E2C5 /* SNA.cpp in Sources */, 4BEDA3C025B25563000C2DBD /* Decoder.cpp in Sources */, 4B2005432B804D6400420C5C /* ARMDecoderTests.mm in Sources */, 4B778F4C23A5F2090000D260 /* StaticAnalyser.cpp in Sources */, 4B778F2623A5EE350000D260 /* Acorn.cpp in Sources */, 4B7752C128217F490073E2C5 /* FAT.cpp in Sources */, + 4B06AAFE2C6460A40034D014 /* ConfidenceSummary.cpp in Sources */, 4B778F5B23A5F2DE0000D260 /* Tape.cpp in Sources */, 4BB73EB71B587A5100552FC2 /* AllSuiteATests.swift in Sources */, 4B7752B228217EAE0073E2C5 /* StaticAnalyser.cpp in Sources */, 4B7752BC28217F1D0073E2C5 /* Disk.cpp in Sources */, + 4B06AAE42C645FA50034D014 /* DiskIICard.cpp in Sources */, 4B04C899285E3DC800AA8FD6 /* 65816ComparativeTests.mm in Sources */, + 4B06AAF92C64607C0034D014 /* AudioToggle.cpp in Sources */, 4B01A6881F22F0DB001FD6E3 /* Z80MemptrTests.swift in Sources */, 4B778EFA23A5EB790000D260 /* DMK.cpp in Sources */, 4BEE1EC122B5E2FD000A26A6 /* Encoder.cpp in Sources */, + 4B06AACD2C645EE50034D014 /* Enterprise.cpp in Sources */, 4B7752AF28217E890073E2C5 /* DAT.cpp in Sources */, 4B121F9B1E06293F00BFDA12 /* PCMSegmentEventSourceTests.mm in Sources */, 4B778EFF23A5EB940000D260 /* D64.cpp in Sources */, @@ -6470,79 +6578,111 @@ 4B778F2423A5EDEE0000D260 /* PRG.cpp in Sources */, 4B778F5A23A5F2D50000D260 /* 6502.cpp in Sources */, 4B778F6223A5F35F0000D260 /* File.cpp in Sources */, + 4B06AB0F2C6461780034D014 /* MultiProducer.cpp in Sources */, 4B778F3523A5F1040000D260 /* SCSI.cpp in Sources */, 4BD388882239E198002D14B5 /* 68000Tests.mm in Sources */, 4B8DF5142550D62A00F3433C /* 65816kromTests.swift in Sources */, + 4B06AB022C6460CB0034D014 /* Typer.cpp in Sources */, 4BA91E1D216D85BA00F79557 /* MasterSystemVDPTests.mm in Sources */, 4B98A0611FFADCDE00ADF63B /* MSXStaticAnalyserTests.mm in Sources */, 4BE34438238389E10058E78F /* AtariSTVideoTests.mm in Sources */, 4BEF6AAC1D35D1C400E73575 /* DPLLTests.swift in Sources */, 4BE76CF922641ED400ACD6FA /* QLTests.mm in Sources */, + 4B06AB0C2C6461590034D014 /* StaticAnalyser.cpp in Sources */, 4B43983A29620FC8006B0BFC /* 9918.cpp in Sources */, 4B778F0923A5EC150000D260 /* OricTAP.cpp in Sources */, 4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */, 4B778F6023A5F3460000D260 /* Disk.cpp in Sources */, + 4B06AB142C64619E0034D014 /* MultiJoystickMachine.cpp in Sources */, 4B778F5C23A5F3070000D260 /* MSX.cpp in Sources */, 4B7752AA28217E370073E2C5 /* ROMCatalogue.cpp in Sources */, 4B778F0323A5EBB00000D260 /* FAT12.cpp in Sources */, 4B778F4023A5F1910000D260 /* z8530.cpp in Sources */, 4B778EFD23A5EB8E0000D260 /* AppleDSK.cpp in Sources */, 4B7752B728217EF40073E2C5 /* Chipset.cpp in Sources */, + 4B06AAF72C64606E0034D014 /* DiskII.cpp in Sources */, 4B778EFB23A5EB7E0000D260 /* HFE.cpp in Sources */, 4BC751B21D157E61006C31D9 /* 6522Tests.swift in Sources */, 4B0DA67D282DCDF300C12F17 /* Instruction.cpp in Sources */, + 4B06AAE12C645F8B0034D014 /* Video.cpp in Sources */, 4BFCA12B1ECBE7C400AC40C1 /* ZexallTests.swift in Sources */, + 4B06AAD62C645F2D0034D014 /* AtariST.cpp in Sources */, + 4B06AB132C6461970034D014 /* MultiConfigurable.cpp in Sources */, 4B778F2223A5EDDD0000D260 /* PulseQueuedTape.cpp in Sources */, + 4B06AB112C64618B0034D014 /* Tape.cpp in Sources */, 4B051CB3267D3FF800CA44E8 /* EnterpriseNickTests.mm in Sources */, 4B9D0C4D22C7DA1A00DE1AD3 /* 68000ControlFlowTests.mm in Sources */, 4BB2A9AF1E13367E001A5C23 /* CRCTests.mm in Sources */, + 4B06AAEE2C64600C0034D014 /* Vic20.cpp in Sources */, + 4B06AB0A2C6461350034D014 /* TIASound.cpp in Sources */, 4BB0CAA727E51B6300672A88 /* DingusdevPowerPCTests.mm in Sources */, + 4B06AACC2C645EDF0034D014 /* Archimedes.cpp in Sources */, 4B778F5623A5F2AF0000D260 /* CPM.cpp in Sources */, 4B778F1C23A5ED3F0000D260 /* TimedEventLoop.cpp in Sources */, + 4B06AAFA2C6460800034D014 /* KonamiSCC.cpp in Sources */, 4B47770D26900685005C2340 /* EnterpriseDaveTests.mm in Sources */, 4B3BA0D01D318B44005DD7A7 /* MOS6532Bridge.mm in Sources */, 4B778F3823A5F11C0000D260 /* SegmentParser.cpp in Sources */, 4B778F0723A5EC150000D260 /* CommodoreTAP.cpp in Sources */, 4281683A2A37AFB4008ECD27 /* DispatcherTests.mm in Sources */, + 4B06AAE52C645FAA0034D014 /* SCSICard.cpp in Sources */, 4B778F4123A5F19A0000D260 /* MemoryPacker.cpp in Sources */, + 4B06AAE02C645F870034D014 /* Video.cpp in Sources */, 4B778F4423A5F1BE0000D260 /* CommodoreGCR.cpp in Sources */, 4B778EF923A5EB740000D260 /* MSA.cpp in Sources */, 4B4DEC07252BFA56004583AC /* 65816Base.cpp in Sources */, 4B7752A628217DF80073E2C5 /* Dave.cpp in Sources */, 4B778F2323A5EDE40000D260 /* Tape.cpp in Sources */, 4B7752A728217E060073E2C5 /* Blitter.cpp in Sources */, + 4B06AAD22C645F190034D014 /* I2C.cpp in Sources */, 4B778F4F23A5F21C0000D260 /* StaticAnalyser.cpp in Sources */, + 4B06AAE72C645FBC0034D014 /* DMAController.cpp in Sources */, 4B8DD3682633B2D400B3C866 /* SpectrumVideoContentionTests.mm in Sources */, + 4B06AB162C6461AB0034D014 /* Keyboard.cpp in Sources */, 4B7752A928217E200073E2C5 /* 65816Storage.cpp in Sources */, + 4B06AAFB2C6460920034D014 /* Keyboard.cpp in Sources */, 4BC62FF228A149300036AE59 /* NSData+dataWithContentsOfGZippedFile.m in Sources */, + 4B06AB152C6461A20034D014 /* MultiKeyboardMachine.cpp in Sources */, 4B7752AC28217E6E0073E2C5 /* StaticAnalyser.cpp in Sources */, 4B778F1223A5EC720000D260 /* CRT.cpp in Sources */, 4B778EF423A5DB3A0000D260 /* C1540.cpp in Sources */, 4B778F3C23A5F16F0000D260 /* FIRFilter.cpp in Sources */, + 4B06AB092C64612C0034D014 /* TIA.cpp in Sources */, 4B778F5423A5F2600000D260 /* UnformattedTrack.cpp in Sources */, 4B7752B028217E9A0073E2C5 /* StaticAnalyser.cpp in Sources */, + 4B06AADA2C645F650034D014 /* MemorySlotHandler.cpp in Sources */, 4B778EF823A5EB6E0000D260 /* NIB.cpp in Sources */, 4B9D0C4B22C7D70A00DE1AD3 /* 68000BCDTests.mm in Sources */, 4B778F5E23A5F3230000D260 /* Oric.cpp in Sources */, 4B7752B828217F110073E2C5 /* Amiga.cpp in Sources */, + 4B06AAEF2C6460180034D014 /* Keyboard.cpp in Sources */, 4B3BA0C31D318AEC005DD7A7 /* C1540Tests.swift in Sources */, 4BDA8235261E8E000021AA19 /* Z80ContentionTests.mm in Sources */, 4B882F592C2F9C6A00D84031 /* CPCShakerTests.mm in Sources */, 4B7752C328217F720073E2C5 /* Z80.cpp in Sources */, + 4B06AACE2C645EEC0034D014 /* PCCompatible.cpp in Sources */, + 4B06AB072C6461160034D014 /* StaticAnalyser.cpp in Sources */, 4B778F1A23A5ED320000D260 /* Video.cpp in Sources */, 4B778F3B23A5F1650000D260 /* KeyboardMachine.cpp in Sources */, 4B5D497C28513F870076E2F9 /* IPF.cpp in Sources */, + 4B06AAF32C64603D0034D014 /* Keyboard.cpp in Sources */, 4B778F2E23A5F09E0000D260 /* IRQDelegatePortHandler.cpp in Sources */, 4B778EF323A5DB230000D260 /* PCMSegment.cpp in Sources */, + 4B06AB0D2C6461610034D014 /* MultiMachine.cpp in Sources */, + 4B06AAD52C645F290034D014 /* AppleII.cpp in Sources */, + 4B06AAFC2C6460970034D014 /* Keyboard.cpp in Sources */, 4B778F0D23A5EC150000D260 /* ZX80O81P.cpp in Sources */, 4B1414621B58888700E04248 /* KlausDormannTests.swift in Sources */, 4B778EFE23A5EB910000D260 /* CPCDSK.cpp in Sources */, 4B778F5823A5F2C60000D260 /* Tape.cpp in Sources */, 4B7752B328217EB90073E2C5 /* State.cpp in Sources */, + 4B06AB032C6460D00034D014 /* OPLL.cpp in Sources */, + 4B06AAFD2C64609D0034D014 /* IMD.cpp in Sources */, 4B1414601B58885000E04248 /* WolfgangLorenzTests.swift in Sources */, 4BD4A8D01E077FD20020D856 /* PCMTrackTests.mm in Sources */, 4B778F2123A5EDD50000D260 /* TrackSerialiser.cpp in Sources */, 4B049CDD1DA3C82F00322067 /* BCDTest.swift in Sources */, + 4B06AADF2C645F830034D014 /* Video.cpp in Sources */, 4BC6237226F94BCB00F83DFE /* MintermTests.mm in Sources */, 4B7752BF28217F250073E2C5 /* Sprites.cpp in Sources */, 4B778F3923A5F11C0000D260 /* Shifter.cpp in Sources */, @@ -6550,10 +6690,14 @@ 4B778F3623A5F1040000D260 /* Target.cpp in Sources */, 4B1D08061E0F7A1100763741 /* TimeTests.mm in Sources */, 4B75EBFE28FF9CA20088AB22 /* MacintoshVolume.cpp in Sources */, + 4B06AB0B2C64614B0034D014 /* Electron.cpp in Sources */, + 4B06AAF52C6460600034D014 /* Mouse.cpp in Sources */, 4B778F3D23A5F1750000D260 /* ncr5380.cpp in Sources */, 4BF701A026FFD32300996424 /* AmigaBlitterTests.mm in Sources */, 4B7752B428217ECB0073E2C5 /* ZXSpectrumTAP.cpp in Sources */, 4B778F6323A5F3630000D260 /* Tape.cpp in Sources */, + 4B06AB012C6460C30034D014 /* Video.cpp in Sources */, + 4B06AADD2C645F790034D014 /* Microdisc.cpp in Sources */, 4B778EF523A5DB440000D260 /* StaticAnalyser.cpp in Sources */, 4BEE1EC022B5E236000A26A6 /* MacGCRTests.mm in Sources */, 4B778F0623A5EC150000D260 /* CAS.cpp in Sources */, @@ -6561,9 +6705,11 @@ 4B778F3F23A5F1890000D260 /* MacintoshDoubleDensityDrive.cpp in Sources */, 4B778F1623A5ECA00000D260 /* Z80AllRAM.cpp in Sources */, 4BEDA40D25B2844B000C2DBD /* Decoder.cpp in Sources */, + 4B06AAE62C645FB10034D014 /* ADB.cpp in Sources */, 4B778EF723A5EB670000D260 /* SSD.cpp in Sources */, 4BDA7F8329C4EA28007A10A5 /* 6809OperationMapperTests.mm in Sources */, 4B778F5723A5F2BB0000D260 /* ZX8081.cpp in Sources */, + 4B06AACF2C645EF40034D014 /* i8272.cpp in Sources */, 4B778F2F23A5F0B10000D260 /* ScanTarget.cpp in Sources */, 4B882F5D2C3219A400D84031 /* AmstradCPC.cpp in Sources */, 4B69DEB72AB79E4F0055B217 /* Instruction.cpp in Sources */, @@ -6573,16 +6719,23 @@ 4B778F0C23A5EC150000D260 /* TZX.cpp in Sources */, 4B778F1B23A5ED380000D260 /* Video.cpp in Sources */, 4B778F4723A5F1DD0000D260 /* StaticAnalyser.cpp in Sources */, + 4B06AAF62C6460670034D014 /* DiskIIDrive.cpp in Sources */, 4B778F1923A5ED1B0000D260 /* 6502Storage.cpp in Sources */, 4B7752A828217E110073E2C5 /* Nick.cpp in Sources */, 42A5E80C2ABBE04600A0DD5D /* NeskellTests.swift in Sources */, + 4B06AAE92C645FD30034D014 /* Jasmin.cpp in Sources */, 4B7752AE28217E830073E2C5 /* 2MG.cpp in Sources */, + 4B06AB102C6461810034D014 /* SoundGenerator.cpp in Sources */, 4B08A2781EE39306008B7065 /* TestMachine.mm in Sources */, 4B778F1E23A5EDC00000D260 /* DriveSpeedAccumulator.cpp in Sources */, 4B778F4323A5F1B00000D260 /* ImplicitSectors.cpp in Sources */, 4B7752B128217EA30073E2C5 /* StaticAnalyser.cpp in Sources */, 4B778F5123A5F2290000D260 /* StaticAnalyser.cpp in Sources */, + 4B06AB0E2C6461700034D014 /* MultiMediaTarget.cpp in Sources */, 42437B332AC70833006DFED1 /* HDV.cpp in Sources */, + 4B06AAE82C645FCD0034D014 /* RP5C01.cpp in Sources */, + 4B06AAEC2C645FF50034D014 /* Keyboard.cpp in Sources */, + 4B06AAF02C6460240034D014 /* ReactiveDevice.cpp in Sources */, 4B7752C028217F3D0073E2C5 /* Line.cpp in Sources */, 4B7C7A00282C3BCA002D6C0B /* 68000flamewingTests.mm in Sources */, 4B778F0223A5EBA40000D260 /* MFMSectorDump.cpp in Sources */, @@ -6591,6 +6744,7 @@ 4B778F3E23A5F17C0000D260 /* IWM.cpp in Sources */, 4BD91D732401960C007BDC91 /* STX.cpp in Sources */, 4B778F1023A5EC5D0000D260 /* Drive.cpp in Sources */, + 4B06AAF42C6460430034D014 /* ZX8081.cpp in Sources */, 4B9D0C4F22C7E0CF00DE1AD3 /* 68000RollShiftTests.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock SignalTests.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock SignalTests.xcscheme index ab4951d39..1e460a993 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock SignalTests.xcscheme +++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock SignalTests.xcscheme @@ -7,7 +7,7 @@ buildImplicitDependencies = "YES"> From 30b1b36e6371991687b9a47d879e17815adf9b0d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 7 Aug 2024 22:44:48 -0400 Subject: [PATCH 17/19] Test digits individually; CSLs autolink. --- Machines/AmstradCPC/AmstradCPC.cpp | 21 ++++++---- .../Mac/Clock SignalTests/CPCShakerTests.mm | 42 +++++++++---------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index 67e3f0686..db780a0ab 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -951,18 +951,23 @@ class ConcreteMachine: const auto code = uint16_t( ((ssm_code_ << 8) & 0xff00) | ((ssm_code_ >> 16) & 0x00ff) ); - ssm_code_ = 0; + + const auto is_valid = [](uint8_t digit) { + return + (digit <= 0x3f) || + (digit >= 0x7f && digit <= 0x9f) || + (digit >= 0xa4 && digit <= 0xa7) || + (digit >= 0xac && digit <= 0xaf) || + (digit >= 0xb4 && digit <= 0xb7) || + (digit >= 0xbc && digit <= 0xbf) || + (digit >= 0xc0 && digit <= 0xfd); + }; if( - (code <= 0x3f3f) || - (code >= 0x7f7f && code <= 0x9f9f) || - (code >= 0xa4a4 && code <= 0xa7a7) || - (code >= 0xacac && code <= 0xafaf) || - (code >= 0xb4b4 && code <= 0xb7b7) || - (code >= 0xbcbc && code <= 0xbfbf) || - (code >= 0xc0c0 && code <= 0xfdfd) + is_valid(static_cast(code)) && is_valid(static_cast(code >> 8)) ) { ssm_delegate_->perform(code); + ssm_code_ = 0; } } } else if((ssm_code_ & 0xffff) == 0xedfe) { diff --git a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm index 2d1e66065..4173d0ee3 100644 --- a/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm +++ b/OSBindings/Mac/Clock SignalTests/CPCShakerTests.mm @@ -178,7 +178,7 @@ private: if(!lazy_machine) { Machine::Error error; lazy_machine = Machine::MachineForTarget(&target, CSROMFetcher(), error); - reinterpret_cast(lazy_machine->raw_pointer()) + static_cast(lazy_machine->raw_pointer()) ->set_ssm_delegate(&ssm_delegate); lazy_machine->scan_producer()->set_scan_target(&scan_target); @@ -295,38 +295,38 @@ private: - (void)testModuleA { [self testModulePath:@"MODULE A" name:@"SHAKE26A-0.CSL"]; - [self testModulePath:@"MODULE A" name:@"SHAKE26A-1.CSL"]; - [self testModulePath:@"MODULE A" name:@"SHAKE26A-2.CSL"]; - [self testModulePath:@"MODULE A" name:@"SHAKE26A-3.CSL"]; - [self testModulePath:@"MODULE A" name:@"SHAKE26A-4.CSL"]; +// [self testModulePath:@"MODULE A" name:@"SHAKE26A-1.CSL"]; +// [self testModulePath:@"MODULE A" name:@"SHAKE26A-2.CSL"]; +// [self testModulePath:@"MODULE A" name:@"SHAKE26A-3.CSL"]; +// [self testModulePath:@"MODULE A" name:@"SHAKE26A-4.CSL"]; } - (void)testModuleB { [self testModulePath:@"MODULE B" name:@"SHAKE26B-0.CSL"]; - [self testModulePath:@"MODULE B" name:@"SHAKE26B-1.CSL"]; - [self testModulePath:@"MODULE B" name:@"SHAKE26B-2.CSL"]; - [self testModulePath:@"MODULE B" name:@"SHAKE26B-3.CSL"]; - [self testModulePath:@"MODULE B" name:@"SHAKE26B-4.CSL"]; +// [self testModulePath:@"MODULE B" name:@"SHAKE26B-1.CSL"]; +// [self testModulePath:@"MODULE B" name:@"SHAKE26B-2.CSL"]; +// [self testModulePath:@"MODULE B" name:@"SHAKE26B-3.CSL"]; +// [self testModulePath:@"MODULE B" name:@"SHAKE26B-4.CSL"]; } - (void)testModuleC { [self testModulePath:@"MODULE C" name:@"SHAKE26C-0.CSL"]; - [self testModulePath:@"MODULE C" name:@"SHAKE26C-1.CSL"]; - [self testModulePath:@"MODULE C" name:@"SHAKE26C-2.CSL"]; - [self testModulePath:@"MODULE C" name:@"SHAKE26C-3.CSL"]; - [self testModulePath:@"MODULE C" name:@"SHAKE26C-4.CSL"]; +// [self testModulePath:@"MODULE C" name:@"SHAKE26C-1.CSL"]; +// [self testModulePath:@"MODULE C" name:@"SHAKE26C-2.CSL"]; +// [self testModulePath:@"MODULE C" name:@"SHAKE26C-3.CSL"]; +// [self testModulePath:@"MODULE C" name:@"SHAKE26C-4.CSL"]; } - (void)testModuleD { [self testModulePath:@"MODULE D" name:@"SHAKE26D-0.CSL"]; - [self testModulePath:@"MODULE D" name:@"SHAKE26D-1.CSL"]; - [self testModulePath:@"MODULE D" name:@"SHAKE26D-2.CSL"]; - [self testModulePath:@"MODULE D" name:@"SHAKE26D-3.CSL"]; - [self testModulePath:@"MODULE D" name:@"SHAKE26D-4.CSL"]; +// [self testModulePath:@"MODULE D" name:@"SHAKE26D-1.CSL"]; +// [self testModulePath:@"MODULE D" name:@"SHAKE26D-2.CSL"]; +// [self testModulePath:@"MODULE D" name:@"SHAKE26D-3.CSL"]; +// [self testModulePath:@"MODULE D" name:@"SHAKE26D-4.CSL"]; } - (void)testModuleE { [self testModulePath:@"MODULE E" name:@"SHAKE26E-0.CSL"]; - [self testModulePath:@"MODULE E" name:@"SHAKE26E-1.CSL"]; - [self testModulePath:@"MODULE E" name:@"SHAKE26E-2.CSL"]; - [self testModulePath:@"MODULE E" name:@"SHAKE26E-3.CSL"]; - [self testModulePath:@"MODULE E" name:@"SHAKE26E-4.CSL"]; +// [self testModulePath:@"MODULE E" name:@"SHAKE26E-1.CSL"]; +// [self testModulePath:@"MODULE E" name:@"SHAKE26E-2.CSL"]; +// [self testModulePath:@"MODULE E" name:@"SHAKE26E-3.CSL"]; +// [self testModulePath:@"MODULE E" name:@"SHAKE26E-4.CSL"]; } @end From 43887b42b11296ad3e1114c0b47998fd22971417 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 7 Aug 2024 23:05:26 -0400 Subject: [PATCH 18/19] Allow vsync on line 0. --- Components/6845/CRTC6845.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Components/6845/CRTC6845.hpp b/Components/6845/CRTC6845.hpp index 8f910a696..14ac74c22 100644 --- a/Components/6845/CRTC6845.hpp +++ b/Components/6845/CRTC6845.hpp @@ -301,17 +301,17 @@ template cl } } else { line_counter_ = (line_counter_ + 1) & 0x7f; + } - // Check for start of vertical sync. - if(line_counter_ == layout_.vertical.start_sync) { - bus_state_.vsync = true; - vsync_counter_ = 0; - } + // Check for start of vertical sync. + if(line_counter_ == layout_.vertical.start_sync) { + bus_state_.vsync = true; + vsync_counter_ = 0; + } - // Check for end of visible lines. - if(line_counter_ == layout_.vertical.displayed) { - line_is_visible_ = false; - } + // Check for end of visible lines. + if(line_counter_ == layout_.vertical.displayed) { + line_is_visible_ = false; } } else { bus_state_.row_address = (bus_state_.row_address + 1) & 0x1f; From a9c8ef642ce7a1a5122f40c2cd25416da850054b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 14 Aug 2024 18:55:35 -0400 Subject: [PATCH 19/19] Correct original author's typo. --- OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-2.CSL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-2.CSL b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-2.CSL index fcd59ee97..761966518 100644 --- a/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-2.CSL +++ b/OSBindings/Mac/Clock SignalTests/Shaker/MODULE C/SHAKE26C-2.CSL @@ -151,4 +151,4 @@ wait 5000000 ; 3ad key_output ' ' wait 10000000 ; menu -cls_load 'SHAKE26C-4' \ No newline at end of file +csl_load 'SHAKE26C-4' ; corrected from cls_load \ No newline at end of file