From 6d0e41b7608e9d9a7e66eae6db5ef0d2238746aa Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 19 Sep 2019 19:41:43 -0400 Subject: [PATCH 1/4] Adds "quick boot" as a standard option. I assume I'm going to reuse this. --- Configurable/StandardOptions.cpp | 9 +++++++++ Configurable/StandardOptions.hpp | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Configurable/StandardOptions.cpp b/Configurable/StandardOptions.cpp index 2aae5b393..4b57ce6ae 100644 --- a/Configurable/StandardOptions.cpp +++ b/Configurable/StandardOptions.cpp @@ -42,6 +42,7 @@ std::vector> Configurable::standard_option options.emplace_back(new Configurable::ListOption("Display", "display", display_options)); } if(mask & AutomaticTapeMotorControl) options.emplace_back(new Configurable::BooleanOption("Automatic Tape Motor Control", "autotapemotor")); + if(mask & QuickBoot) options.emplace_back(new Configurable::BooleanOption("Boot Quickly", "quickboot")); return options; } @@ -66,6 +67,10 @@ void Configurable::append_display_selection(Configurable::SelectionSet &selectio selection_set["display"] = std::unique_ptr(new Configurable::ListSelection(string_selection)); } +void Configurable::append_quick_boot_selection(Configurable::SelectionSet &selection_set, bool selection) { + append_bool(selection_set, "quickboot", selection); +} + // MARK: - Selection parsers bool Configurable::get_quick_load_tape(const Configurable::SelectionSet &selections_by_option, bool &result) { return get_bool(selections_by_option, "quickload", result); @@ -97,3 +102,7 @@ bool Configurable::get_display(const Configurable::SelectionSet &selections_by_o } return false; } + +bool Configurable::get_quick_boot(const Configurable::SelectionSet &selections_by_option, bool &result) { + return get_bool(selections_by_option, "quickboot", result); +} diff --git a/Configurable/StandardOptions.hpp b/Configurable/StandardOptions.hpp index a6a4a915d..fa042ee65 100644 --- a/Configurable/StandardOptions.hpp +++ b/Configurable/StandardOptions.hpp @@ -19,7 +19,8 @@ enum StandardOptions { DisplayCompositeColour = (1 << 2), DisplayCompositeMonochrome = (1 << 3), QuickLoadTape = (1 << 4), - AutomaticTapeMotorControl = (1 << 5) + AutomaticTapeMotorControl = (1 << 5), + QuickBoot = (1 << 6), }; enum class Display { @@ -49,6 +50,11 @@ void append_automatic_tape_motor_control_selection(SelectionSet &selection_set, */ void append_display_selection(SelectionSet &selection_set, Display selection); +/*! + Appends to @c selection_set a selection of @c selection for QuickBoot. +*/ +void append_quick_boot_selection(SelectionSet &selection_set, bool selection); + /*! Attempts to discern a QuickLoadTape selection from @c selections_by_option. @@ -76,6 +82,15 @@ bool get_automatic_tape_motor_control_selection(const SelectionSet &selections_b */ bool get_display(const SelectionSet &selections_by_option, Display &result); +/*! + Attempts to QuickBoot a QuickLoadTape selection from @c selections_by_option. + + @param selections_by_option The user selections. + @param result The location to which the selection will be stored if found. + @returns @c true if a selection is found; @c false otherwise. +*/ +bool get_quick_boot(const SelectionSet &selections_by_option, bool &result); + } #endif /* StandardOptions_hpp */ From e46601872b04a3656478c4421cbac1db145ac75e Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 19 Sep 2019 21:50:39 -0400 Subject: [PATCH 2/4] Establishes that the Macintosh offers the quick-boot option. --- Machines/Apple/Macintosh/Macintosh.cpp | 31 ++++++++++++++++++++++++++ Machines/Apple/Macintosh/Macintosh.hpp | 3 +++ Machines/Utility/MachineForTarget.cpp | 1 + 3 files changed, 35 insertions(+) diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index 4db65ca4e..20ef4ae80 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -27,6 +27,7 @@ #include "../../../ClockReceiver/JustInTime.hpp" #include "../../../ClockReceiver/ClockingHintSource.hpp" +#include "../../../Configurable/StandardOptions.hpp" //#define LOG_TRACE @@ -55,6 +56,12 @@ const int CLOCK_RATE = 7833600; namespace Apple { namespace Macintosh { +std::vector> get_options() { + return Configurable::standard_options( + static_cast(Configurable::QuickBoot) + ); +} + template class ConcreteMachine: public Machine, public CRTMachine::Machine, @@ -64,6 +71,7 @@ template class ConcreteMachin public KeyboardMachine::MappedMachine, public Zilog::SCC::z8530::Delegate, public Activity::Source, + public Configurable::Device, public DriveSpeedAccumulator::Delegate, public ClockingHint::Observer { public: @@ -506,6 +514,29 @@ template class ConcreteMachin } } + // MARK: - Configuration options. + std::vector> get_options() override { + return Apple::Macintosh::get_options(); + } + + void set_selections(const Configurable::SelectionSet &selections_by_option) override { + bool quick_boot; + if(Configurable::get_quick_boot(selections_by_option, quick_boot)) { + } + } + + Configurable::SelectionSet get_accurate_selections() override { + Configurable::SelectionSet selection_set; + Configurable::append_quick_boot_selection(selection_set, false); + return selection_set; + } + + Configurable::SelectionSet get_user_friendly_selections() override { + Configurable::SelectionSet selection_set; + Configurable::append_quick_boot_selection(selection_set, true); + return selection_set; + } + private: void set_component_prefers_clocking(ClockingHint::Source *component, ClockingHint::Preference clocking) override { scsi_bus_is_clocked_ = scsi_bus_.preferred_clocking() != ClockingHint::Preference::None; diff --git a/Machines/Apple/Macintosh/Macintosh.hpp b/Machines/Apple/Macintosh/Macintosh.hpp index e39462f01..58623ea7c 100644 --- a/Machines/Apple/Macintosh/Macintosh.hpp +++ b/Machines/Apple/Macintosh/Macintosh.hpp @@ -9,12 +9,15 @@ #ifndef Macintosh_hpp #define Macintosh_hpp +#include "../../../Configurable/Configurable.hpp" #include "../../../Analyser/Static/StaticAnalyser.hpp" #include "../../ROMMachine.hpp" namespace Apple { namespace Macintosh { +std::vector> get_options(); + class Machine { public: virtual ~Machine(); diff --git a/Machines/Utility/MachineForTarget.cpp b/Machines/Utility/MachineForTarget.cpp index e5b4ee453..631cb3c7f 100644 --- a/Machines/Utility/MachineForTarget.cpp +++ b/Machines/Utility/MachineForTarget.cpp @@ -139,6 +139,7 @@ std::map>> Machin options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::AppleII), Apple::II::get_options())); options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::ColecoVision), Coleco::Vision::get_options())); options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::Electron), Electron::get_options())); + options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::Macintosh), Apple::Macintosh::get_options())); options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::MSX), MSX::get_options())); options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::Oric), Oric::get_options())); options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::Vic20), Commodore::Vic20::get_options())); From 2e24da461446b0ca91a1e76bdaa3526eb9bcef30 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 19 Sep 2019 22:32:12 -0400 Subject: [PATCH 3/4] Implements quick booting, and edges towards exposing it on the Mac. It should already work in kiosk mode. --- Configurable/StandardOptions.cpp | 6 +-- Machines/Apple/Macintosh/Macintosh.cpp | 6 +++ .../Clock Signal.xcodeproj/project.pbxproj | 16 +++++- .../Base.lproj/MacintoshOptions.xib | 49 +++++++++++++++++++ .../Clock Signal/Documents/MachinePanel.swift | 17 +++++++ .../Mac/Clock Signal/Machine/CSMachine.h | 1 + .../Mac/Clock Signal/Machine/CSMachine.mm | 13 +++++ .../StaticAnalyser/CSStaticAnalyser.mm | 1 + 8 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 OSBindings/Mac/Clock Signal/Base.lproj/MacintoshOptions.xib diff --git a/Configurable/StandardOptions.cpp b/Configurable/StandardOptions.cpp index 4b57ce6ae..7f140557f 100644 --- a/Configurable/StandardOptions.cpp +++ b/Configurable/StandardOptions.cpp @@ -21,9 +21,9 @@ void append_bool(Configurable::SelectionSet &selection_set, const std::string &n Enquires for a Boolean selection for option @c name from @c selections_by_option, storing it to @c result if found. */ bool get_bool(const Configurable::SelectionSet &selections_by_option, const std::string &name, bool &result) { - auto quickload = Configurable::selection(selections_by_option, "quickload"); - if(!quickload) return false; - result = quickload->value; + auto selection = Configurable::selection(selections_by_option, name); + if(!selection) return false; + result = selection->value; return true; } diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index 20ef4ae80..0915abed9 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -522,6 +522,12 @@ template class ConcreteMachin void set_selections(const Configurable::SelectionSet &selections_by_option) override { bool quick_boot; if(Configurable::get_quick_boot(selections_by_option, quick_boot)) { + if(quick_boot) { + // Cf. Big Mess o' Wires' disassembly of the Mac Plus ROM, and the + // test at $E00. TODO: adapt as(/if?) necessary for other Macs. + ram_[0x02ae >> 1] = 0x40; + ram_[0x02b0 >> 1] = 0x00; + } } } diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 2e10c1604..7103f99c8 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -186,6 +186,7 @@ 4B4518A31F75FD1C00926311 /* HFE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518951F75FD1B00926311 /* HFE.cpp */; }; 4B4518A41F75FD1C00926311 /* OricMFMDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */; }; 4B4518A51F75FD1C00926311 /* SSD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518991F75FD1B00926311 /* SSD.cpp */; }; + 4B49F0A923346F7A0045E6A6 /* MacintoshOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B49F0A723346F7A0045E6A6 /* MacintoshOptions.xib */; }; 4B4A76301DB1A3FA007AAE2E /* AY38910.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */; }; 4B4B1A3C200198CA00A0F866 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; }; 4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; }; @@ -912,6 +913,7 @@ 4B45189A1F75FD1B00926311 /* SSD.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SSD.hpp; sourceTree = ""; }; 4B4518A71F76004200926311 /* TapeParser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = TapeParser.hpp; path = Parsers/TapeParser.hpp; sourceTree = ""; }; 4B4518A81F76022000926311 /* DiskImageImplementation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DiskImageImplementation.hpp; sourceTree = ""; }; + 4B49F0A823346F7A0045E6A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/MacintoshOptions.xib"; sourceTree = SOURCE_ROOT; }; 4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AY38910.cpp; path = AY38910/AY38910.cpp; sourceTree = ""; }; 4B4A762F1DB1A3FA007AAE2E /* AY38910.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AY38910.hpp; path = AY38910/AY38910.hpp; sourceTree = ""; }; 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KonamiSCC.cpp; sourceTree = ""; }; @@ -2134,6 +2136,7 @@ 4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */, 4BEEE6BB20DC72EA003723BF /* CompositeOptions.xib */, 4B8FE2151DA19D5F0090D3CE /* MachineDocument.xib */, + 4B49F0A723346F7A0045E6A6 /* MacintoshOptions.xib */, 4B2A332B1DB86821002876E3 /* OricOptions.xib */, 4B8FE2171DA19D5F0090D3CE /* QuickLoadCompositeOptions.xib */, 4BD61662206B2AC700236112 /* QuickLoadOptions.xib */, @@ -2266,12 +2269,12 @@ 4B6AAEA1230E3E1D0078E864 /* MassStorage */ = { isa = PBXGroup; children = ( + 4B74CF83231370BC00500CE8 /* MacintoshVolume.cpp */, 4B6AAEA2230E3E1D0078E864 /* MassStorageDevice.cpp */, + 4B74CF84231370BC00500CE8 /* MacintoshVolume.hpp */, 4B6AAEA3230E3E1D0078E864 /* MassStorageDevice.hpp */, 4B74CF7E2312FA9C00500CE8 /* Formats */, 4B6AAEA5230E40250078E864 /* SCSI */, - 4B74CF83231370BC00500CE8 /* MacintoshVolume.cpp */, - 4B74CF84231370BC00500CE8 /* MacintoshVolume.hpp */, ); path = MassStorage; sourceTree = ""; @@ -3651,6 +3654,7 @@ 4B79E4441E3AF38600141F11 /* cassette.png in Resources */, 4BB73EAC1B587A5100552FC2 /* MainMenu.xib in Resources */, 4B8FE21D1DA19D5F0090D3CE /* QuickLoadCompositeOptions.xib in Resources */, + 4B49F0A923346F7A0045E6A6 /* MacintoshOptions.xib in Resources */, 4BA3189422E7A4CA00D18CFA /* ROMImages in Resources */, 4B79E4461E3AF38600141F11 /* floppy525.png in Resources */, 4BEEE6BD20DC72EB003723BF /* CompositeOptions.xib in Resources */, @@ -4426,6 +4430,14 @@ name = OricOptions.xib; sourceTree = ""; }; + 4B49F0A723346F7A0045E6A6 /* MacintoshOptions.xib */ = { + isa = PBXVariantGroup; + children = ( + 4B49F0A823346F7A0045E6A6 /* Base */, + ); + name = MacintoshOptions.xib; + sourceTree = ""; + }; 4B55DD8120DF06680043F2E5 /* MachinePicker.xib */ = { isa = PBXVariantGroup; children = ( diff --git a/OSBindings/Mac/Clock Signal/Base.lproj/MacintoshOptions.xib b/OSBindings/Mac/Clock Signal/Base.lproj/MacintoshOptions.xib new file mode 100644 index 000000000..94d298078 --- /dev/null +++ b/OSBindings/Mac/Clock Signal/Base.lproj/MacintoshOptions.xib @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift b/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift index 19630c625..0b748a9cb 100644 --- a/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift +++ b/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift @@ -16,6 +16,7 @@ class MachinePanel: NSPanel { return "\(self.machine.userDefaultsPrefix).\(key)" } + // MARK: Fast Loading var fastLoadingUserDefaultsKey: String { return prefixedUserDefaultsKey("fastLoading") } @@ -28,6 +29,20 @@ class MachinePanel: NSPanel { } } + // MARK: Quick Boot + var bootQuicklyUserDefaultsKey: String { + return prefixedUserDefaultsKey("bootQuickly") + } + @IBOutlet var fastBootingButton: NSButton? + @IBAction func setFastBooting(_ sender: NSButton!) { +// if let fastLoadingMachine = machine as? CSFastLoading { +// let useFastLoadingHack = sender.state == .on +// fastLoadingMachine.useFastLoadingHack = useFastLoadingHack +// UserDefaults.standard.set(useFastLoadingHack, forKey: fastLoadingUserDefaultsKey) +// } + } + + // MARK: Display-Type Selection fileprivate func signalForTag(tag: Int) -> CSMachineVideoSignal { switch tag { case 1: return .composite @@ -49,6 +64,7 @@ class MachinePanel: NSPanel { } } + // MARK: Restoring user defaults func establishStoredOptions() { let standardUserDefaults = UserDefaults.standard standardUserDefaults.register(defaults: [ @@ -62,6 +78,7 @@ class MachinePanel: NSPanel { self.fastLoadingButton?.state = useFastLoadingHack ? .on : .off } + if let displayTypeButton = self.displayTypeButton { // Enable or disable options as per machine support. var titlesToRemove: [String] = [] diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.h b/OSBindings/Mac/Clock Signal/Machine/CSMachine.h index 7a14bf721..0417e843a 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.h +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.h @@ -86,6 +86,7 @@ typedef NS_ENUM(NSInteger, CSMachineKeyboardInputMode) { @property (nonatomic, assign) BOOL useFastLoadingHack; @property (nonatomic, assign) CSMachineVideoSignal videoSignal; @property (nonatomic, assign) BOOL useAutomaticTapeMotorControl; +@property (nonatomic, assign) BOOL useQuickBootingHack; @property (nonatomic, readonly) BOOL canInsertMedia; diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm index 87ac39456..1b16c4a77 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm @@ -624,6 +624,19 @@ struct ActivityObserver: public Activity::Observer { } } +- (void)setUseQuickBootingHack:(BOOL)useQuickBootingHack { + Configurable::Device *configurable_device = _machine->configurable_device(); + if(!configurable_device) return; + + @synchronized(self) { + _useQuickBootingHack = useQuickBootingHack; + + Configurable::SelectionSet selection_set; + append_quick_boot_selection(selection_set, useQuickBootingHack ? true : false); + configurable_device->set_selections(selection_set); + } +} + - (NSString *)userDefaultsPrefix { // Assumes that the first machine in the targets list is the source of user defaults. std::string name = Machine::ShortNameForTargetMachine(_analyser.targets.front()->machine); diff --git a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm index ee187bfbf..7310ea9e9 100644 --- a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm +++ b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm @@ -219,6 +219,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K case Analyser::Machine::Atari2600: return @"Atari2600Options"; case Analyser::Machine::ColecoVision: return @"CompositeOptions"; case Analyser::Machine::Electron: return @"QuickLoadCompositeOptions"; + case Analyser::Machine::Macintosh: return @"MacintoshOptions"; case Analyser::Machine::MasterSystem: return @"CompositeOptions"; case Analyser::Machine::MSX: return @"QuickLoadCompositeOptions"; case Analyser::Machine::Oric: return @"OricOptions"; From 8ea4c17315b1d61e282d327c266b1e732bec4b42 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 19 Sep 2019 22:37:23 -0400 Subject: [PATCH 4/4] Completes Mac GUI wiring. --- .../Mac/Clock Signal/Documents/MachinePanel.swift | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift b/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift index 0b748a9cb..00cee7a17 100644 --- a/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift +++ b/OSBindings/Mac/Clock Signal/Documents/MachinePanel.swift @@ -35,11 +35,9 @@ class MachinePanel: NSPanel { } @IBOutlet var fastBootingButton: NSButton? @IBAction func setFastBooting(_ sender: NSButton!) { -// if let fastLoadingMachine = machine as? CSFastLoading { -// let useFastLoadingHack = sender.state == .on -// fastLoadingMachine.useFastLoadingHack = useFastLoadingHack -// UserDefaults.standard.set(useFastLoadingHack, forKey: fastLoadingUserDefaultsKey) -// } + let useQuickBootingHack = sender.state == .on + machine.useQuickBootingHack = useQuickBootingHack + UserDefaults.standard.set(useQuickBootingHack, forKey: bootQuicklyUserDefaultsKey) } // MARK: Display-Type Selection @@ -69,6 +67,7 @@ class MachinePanel: NSPanel { let standardUserDefaults = UserDefaults.standard standardUserDefaults.register(defaults: [ fastLoadingUserDefaultsKey: true, + bootQuicklyUserDefaultsKey: true, displayTypeUserDefaultsKey: 0 ]) @@ -78,6 +77,11 @@ class MachinePanel: NSPanel { self.fastLoadingButton?.state = useFastLoadingHack ? .on : .off } + if let fastBootingButton = self.fastBootingButton { + let bootQuickly = standardUserDefaults.bool(forKey: self.bootQuicklyUserDefaultsKey) + machine.useQuickBootingHack = bootQuickly + fastBootingButton.state = bootQuickly ? .on : .off + } if let displayTypeButton = self.displayTypeButton { // Enable or disable options as per machine support.