mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-19 23:29:05 +00:00
Merge pull request #350 from TomHarte/MinorMSXOptimisations
Introduces modest MSX optimisations
This commit is contained in:
commit
a4dc9c0403
@ -38,6 +38,7 @@
|
|||||||
#include "../../Outputs/Speaker/Implementation/SampleSource.hpp"
|
#include "../../Outputs/Speaker/Implementation/SampleSource.hpp"
|
||||||
|
|
||||||
#include "../../Configurable/StandardOptions.hpp"
|
#include "../../Configurable/StandardOptions.hpp"
|
||||||
|
#include "../../ClockReceiver/ForceInline.hpp"
|
||||||
|
|
||||||
namespace MSX {
|
namespace MSX {
|
||||||
|
|
||||||
@ -116,7 +117,8 @@ class ConcreteMachine:
|
|||||||
public ConfigurationTarget::Machine,
|
public ConfigurationTarget::Machine,
|
||||||
public KeyboardMachine::Machine,
|
public KeyboardMachine::Machine,
|
||||||
public Configurable::Device,
|
public Configurable::Device,
|
||||||
public MemoryMap {
|
public MemoryMap,
|
||||||
|
public Sleeper::SleepObserver {
|
||||||
public:
|
public:
|
||||||
ConcreteMachine():
|
ConcreteMachine():
|
||||||
z80_(*this),
|
z80_(*this),
|
||||||
@ -135,6 +137,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
ay_.set_port_handler(&ay_port_handler_);
|
ay_.set_port_handler(&ay_port_handler_);
|
||||||
speaker_.set_input_rate(3579545.0f / 2.0f);
|
speaker_.set_input_rate(3579545.0f / 2.0f);
|
||||||
|
tape_player_.set_sleep_observer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_output(float aspect_ratio) override {
|
void setup_output(float aspect_ratio) override {
|
||||||
@ -278,7 +281,7 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Z80::BusHandler
|
// MARK: Z80::BusHandler
|
||||||
HalfCycles perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
|
forceinline HalfCycles perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
|
||||||
if(time_until_interrupt_ > 0) {
|
if(time_until_interrupt_ > 0) {
|
||||||
time_until_interrupt_ -= cycle.length;
|
time_until_interrupt_ -= cycle.length;
|
||||||
if(time_until_interrupt_ <= HalfCycles(0)) {
|
if(time_until_interrupt_ <= HalfCycles(0)) {
|
||||||
@ -460,8 +463,8 @@ class ConcreteMachine:
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the tape. (TODO: allow for sleeping)
|
if(!tape_player_is_sleeping_)
|
||||||
tape_player_.run_for(cycle.length.as_int());
|
tape_player_.run_for(cycle.length.as_int());
|
||||||
|
|
||||||
// Per the best information I currently have, the MSX inserts an extra cycle into each opcode read,
|
// Per the best information I currently have, the MSX inserts an extra cycle into each opcode read,
|
||||||
// but otherwise runs without pause.
|
// but otherwise runs without pause.
|
||||||
@ -568,6 +571,12 @@ class ConcreteMachine:
|
|||||||
return selection_set;
|
return selection_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Sleeper
|
||||||
|
void set_component_is_sleeping(void *component, bool is_sleeping) override {
|
||||||
|
tape_player_is_sleeping_ = tape_player_.is_sleeping();
|
||||||
|
set_use_fast_tape();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update_audio() {
|
void update_audio() {
|
||||||
speaker_.run_for(audio_queue_, time_since_ay_update_.divide_cycles(Cycles(2)));
|
speaker_.run_for(audio_queue_, time_since_ay_update_.divide_cycles(Cycles(2)));
|
||||||
@ -628,10 +637,11 @@ class ConcreteMachine:
|
|||||||
Outputs::Speaker::LowpassSpeaker<Outputs::Speaker::CompoundSource<GI::AY38910::AY38910, AudioToggle, Konami::SCC>> speaker_;
|
Outputs::Speaker::LowpassSpeaker<Outputs::Speaker::CompoundSource<GI::AY38910::AY38910, AudioToggle, Konami::SCC>> speaker_;
|
||||||
|
|
||||||
Storage::Tape::BinaryTapePlayer tape_player_;
|
Storage::Tape::BinaryTapePlayer tape_player_;
|
||||||
|
bool tape_player_is_sleeping_ = false;
|
||||||
bool allow_fast_tape_ = false;
|
bool allow_fast_tape_ = false;
|
||||||
bool use_fast_tape_ = false;
|
bool use_fast_tape_ = false;
|
||||||
void set_use_fast_tape() {
|
void set_use_fast_tape() {
|
||||||
use_fast_tape_ = allow_fast_tape_ && tape_player_.has_tape();
|
use_fast_tape_ = !tape_player_is_sleeping_ && allow_fast_tape_ && tape_player_.has_tape();
|
||||||
}
|
}
|
||||||
|
|
||||||
i8255PortHandler i8255_port_handler_;
|
i8255PortHandler i8255_port_handler_;
|
||||||
|
@ -158,13 +158,15 @@ class MachineDocument:
|
|||||||
func runForNumberOfCycles(_ numberOfCycles: Int32) {
|
func runForNumberOfCycles(_ numberOfCycles: Int32) {
|
||||||
bestEffortLock.lock()
|
bestEffortLock.lock()
|
||||||
if let bestEffortUpdater = bestEffortUpdater {
|
if let bestEffortUpdater = bestEffortUpdater {
|
||||||
|
bestEffortLock.unlock()
|
||||||
let cyclesToRunFor = min(numberOfCycles, Int32(bestEffortUpdater.clockRate / 10))
|
let cyclesToRunFor = min(numberOfCycles, Int32(bestEffortUpdater.clockRate / 10))
|
||||||
if actionLock.try() {
|
if actionLock.try() {
|
||||||
self.machine.runForNumber(ofCycles: cyclesToRunFor)
|
self.machine.runForNumber(ofCycles: cyclesToRunFor)
|
||||||
actionLock.unlock()
|
actionLock.unlock()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
bestEffortLock.unlock()
|
||||||
}
|
}
|
||||||
bestEffortLock.unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: CSAudioQueueDelegate
|
// MARK: CSAudioQueueDelegate
|
||||||
@ -178,13 +180,15 @@ class MachineDocument:
|
|||||||
final func openGLView(_ view: CSOpenGLView, drawViewOnlyIfDirty onlyIfDirty: Bool) {
|
final func openGLView(_ view: CSOpenGLView, drawViewOnlyIfDirty onlyIfDirty: Bool) {
|
||||||
bestEffortLock.lock()
|
bestEffortLock.lock()
|
||||||
if let bestEffortUpdater = bestEffortUpdater {
|
if let bestEffortUpdater = bestEffortUpdater {
|
||||||
|
bestEffortLock.unlock()
|
||||||
bestEffortUpdater.update()
|
bestEffortUpdater.update()
|
||||||
if drawLock.try() {
|
if drawLock.try() {
|
||||||
self.machine.drawView(forPixelSize: view.backingSize, onlyIfDirty: onlyIfDirty)
|
self.machine.drawView(forPixelSize: view.backingSize, onlyIfDirty: onlyIfDirty)
|
||||||
drawLock.unlock()
|
drawLock.unlock()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
bestEffortLock.unlock()
|
||||||
}
|
}
|
||||||
bestEffortLock.unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final func openGLView(_ view: CSOpenGLView, didReceiveFileAt URL: URL) {
|
final func openGLView(_ view: CSOpenGLView, didReceiveFileAt URL: URL) {
|
||||||
|
@ -39,9 +39,9 @@ struct UpdaterDelegate: public Concurrency::BestEffortUpdater::Delegate {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
//- (void)dealloc {
|
||||||
_updater.flush();
|
// _updater.flush();
|
||||||
}
|
//}
|
||||||
|
|
||||||
- (void)update {
|
- (void)update {
|
||||||
_updater.update();
|
_updater.update();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user