1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-21 21:33:54 +00:00

Support FDC overclocking as 'fast loading'.

This commit is contained in:
Thomas Harte 2024-05-26 22:02:40 -04:00
parent f2245b8066
commit eb2b1cb093
8 changed files with 76 additions and 18 deletions

View File

@ -15,6 +15,8 @@
#include "MemoryController.hpp"
#include "Sound.hpp"
#include "../../../Configurable/Configurable.hpp"
#include "../../AudioProducer.hpp"
#include "../../KeyboardMachine.hpp"
#include "../../MediaTarget.hpp"
@ -46,7 +48,8 @@ class ConcreteMachine:
public MachineTypes::MouseMachine,
public MachineTypes::TimedMachine,
public MachineTypes::ScanProducer,
public Activity::Source
public Activity::Source,
public Configurable::Device
{
private:
Log::Logger<Log::Source::Archimedes> logger;
@ -187,6 +190,24 @@ class ConcreteMachine:
const uint32_t swi_code = comment & static_cast<uint32_t>(~(1 << 17));
switch(swi_code) {
//
// Optional high-level reimplementations, for fast loading.
//
case 0x40240: { // ADFS_DiscOp
const uint32_t function = executor_.registers()[1] & 0xf;
switch(function) {
default: break;
case 0x1: // Read sectors.
printf("Read sectors from %d for %d bytes into %08x\n",
executor_.registers()[2],
executor_.registers()[4],
executor_.registers()[3]);
break;
}
} break;
//
// Passive monitoring traps, for automatic loading.
//
@ -367,20 +388,23 @@ class ConcreteMachine:
}
// MARK: - TimedMachine.
int video_divider_ = 1;
void run_for(Cycles cycles) override {
bool use_original_speed() const {
#ifndef NDEBUG
// Debug mode: always run 'slowly' because that's less of a burden, and
// because it allows me to peer at problems with greater leisure.
const bool use_original_speed = true;
return true;
#else
// As a first, blunt implementation: try to model something close
// to original speed if there have been 10 frame rate overages in total.
const bool use_original_speed = executor_.bus.video().frame_rate_overages() > 10;
return executor_.bus.video().frame_rate_overages() > 10;
#endif
}
int video_divider_ = 1;
void run_for(Cycles cycles) override {
const auto run = [&](Cycles cycles) {
if(use_original_speed) run_for<true>(cycles);
if(use_original_speed()) run_for<true>(cycles);
else run_for<false>(cycles);
};
@ -486,7 +510,13 @@ class ConcreteMachine:
void tick_timers() { executor_.bus.tick_timers(); }
void tick_sound() { executor_.bus.sound().tick(); }
void tick_video() { executor_.bus.video().tick(); }
void tick_floppy() { executor_.bus.tick_floppy(); }
bool accelerate_loading_ = true;
void tick_floppy() {
executor_.bus.tick_floppy(
accelerate_loading_ ? (use_original_speed() ? 12 : 18) : 1
);
}
// MARK: - MediaTarget
bool insert_media(const Analyser::Static::Media &media) override {
@ -499,6 +529,18 @@ class ConcreteMachine:
return true;
}
// MARK: - Configuration options.
std::unique_ptr<Reflection::Struct> get_options() final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
options->quickload = accelerate_loading_;
return options;
}
void set_options(const std::unique_ptr<Reflection::Struct> &str) final {
const auto options = dynamic_cast<Options *>(str.get());
accelerate_loading_ = options->quickload;
}
// MARK: - AudioProducer
Outputs::Speaker::Speaker *get_speaker() override {
return executor_.bus.speaker();

View File

@ -8,6 +8,8 @@
#pragma once
#include "../../../Configurable/Configurable.hpp"
#include "../../../Configurable/StandardOptions.hpp"
#include "../../../Analyser/Static/StaticAnalyser.hpp"
#include "../../ROMMachine.hpp"
@ -22,6 +24,17 @@ class Machine {
const Analyser::Static::Target *target,
const ROMMachine::ROMFetcher &rom_fetcher
);
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::QuickloadOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
if(needs_declare()) {
declare_quickload_option();
}
}
};
};
}

View File

@ -130,9 +130,9 @@ struct InputOutputController: public ClockingHint::Observer {
}
}
void tick_floppy() {
void tick_floppy(int clock_multiplier) {
if(floppy_clocking_ != ClockingHint::Preference::None) {
floppy_.run_for(Cycles(1));
floppy_.run_for(Cycles(clock_multiplier));
}
}

View File

@ -214,7 +214,9 @@ struct MemoryController {
// Expose various IOC-owned things.
//
void tick_timers() { ioc_.tick_timers(); }
void tick_floppy() { ioc_.tick_floppy(); }
void tick_floppy(int clock_multiplier) {
ioc_.tick_floppy(clock_multiplier);
}
void set_disk(std::shared_ptr<Storage::Disk::Disk> disk, size_t drive) {
ioc_.set_disk(disk, drive);
}

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18122" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18122"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22690"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>

View File

@ -1,20 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18122" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18122"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22690"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MachineDocument" customModule="Clock_Signal" customModuleProvider="target">
<connections>
<outlet property="optionsController" destination="cWS-AS-crO" id="KeQ-V1-s46"/>
<outlet property="optionsView" destination="e1J-pw-zGw" id="ALr-SV-afm"/>
<outlet property="optionsView" destination="tpZ-0B-QQu" id="Hhq-RT-HTv"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<visualEffectView wantsLayer="YES" appearanceType="vibrantDark" blendingMode="withinWindow" material="HUDWindow" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="tpZ-0B-QQu">
<visualEffectView hidden="YES" wantsLayer="YES" appearanceType="vibrantDark" blendingMode="withinWindow" material="HUDWindow" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="tpZ-0B-QQu">
<rect key="frame" x="0.0" y="0.0" width="200" height="44"/>
<subviews>
<button translatesAutoresizingMaskIntoConstraints="NO" id="e1J-pw-zGw">

View File

@ -191,7 +191,8 @@ class MachineDocument:
// Attach an options panel if one is available.
if let optionsNibName = self.machineDescription?.optionsNibName {
Bundle.main.loadNibNamed(optionsNibName, owner: self, topLevelObjects: nil)
let didLoad = Bundle.main.loadNibNamed(optionsNibName, owner: self, topLevelObjects: nil)
assert(didLoad)
if let optionsController = self.optionsController {
optionsController.machine = machine
optionsController.establishStoredOptions()

View File

@ -380,8 +380,8 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
- (NSString *)optionsNibName {
switch(_targets.front()->machine) {
// case Analyser::Machine::AmstradCPC: return @"QuickLoadCompositeOptions";
case Analyser::Machine::AmstradCPC: return @"CompositeOptions";
case Analyser::Machine::Archimedes: return @"QuickLoadOptions";
case Analyser::Machine::AppleII: return @"AppleIIOptions";
case Analyser::Machine::Atari2600: return @"Atari2600Options";
case Analyser::Machine::AtariST: return @"CompositeOptions";