mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-26 09:29:45 +00:00
Merge pull request #349 from TomHarte/CheaperTapeChecks
Reduces cost of checking for fast-tape usage
This commit is contained in:
commit
832ac173ae
@ -312,9 +312,6 @@ class ConcreteMachine:
|
|||||||
delete[] rom_;
|
delete[] rom_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_rom(ROMSlot slot, const std::vector<uint8_t> &data) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtains the system ROMs.
|
// Obtains the system ROMs.
|
||||||
bool set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &roms_with_names) override {
|
bool set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &roms_with_names) override {
|
||||||
auto roms = roms_with_names(
|
auto roms = roms_with_names(
|
||||||
@ -396,6 +393,8 @@ class ConcreteMachine:
|
|||||||
write_to_map(processor_read_memory_map_, rom_, rom_address_, 0x2000);
|
write_to_map(processor_read_memory_map_, rom_, rom_address_, 0x2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_use_fast_tape();
|
||||||
|
|
||||||
return !media.tapes.empty() || (!media.disks.empty() && c1540_ != nullptr) || !media.cartridges.empty();
|
return !media.tapes.empty() || (!media.disks.empty() && c1540_ != nullptr) || !media.cartridges.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,10 +515,6 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_use_fast_tape_hack(bool activate) {
|
|
||||||
use_fast_tape_hack_ = activate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// to satisfy CPU::MOS6502::Processor
|
// to satisfy CPU::MOS6502::Processor
|
||||||
forceinline Cycles perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) {
|
forceinline Cycles perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) {
|
||||||
// run the phase-1 part of this cycle, in which the VIC accesses memory
|
// run the phase-1 part of this cycle, in which the VIC accesses memory
|
||||||
@ -539,7 +534,7 @@ class ConcreteMachine:
|
|||||||
// PC hits the start of the loop that just waits for an interesting tape interrupt to have
|
// PC hits the start of the loop that just waits for an interesting tape interrupt to have
|
||||||
// occurred then skip both 6522s and the tape ahead to the next interrupt without any further
|
// occurred then skip both 6522s and the tape ahead to the next interrupt without any further
|
||||||
// CPU or 6560 costs.
|
// CPU or 6560 costs.
|
||||||
if(use_fast_tape_hack_ && tape_->has_tape() && operation == CPU::MOS6502::BusOperation::ReadOpcode) {
|
if(use_fast_tape_hack_ && operation == CPU::MOS6502::BusOperation::ReadOpcode) {
|
||||||
if(address == 0xf7b2) {
|
if(address == 0xf7b2) {
|
||||||
// Address 0xf7b2 contains a JSR to 0xf8c0 that will fill the tape buffer with the next header.
|
// Address 0xf7b2 contains a JSR to 0xf8c0 that will fill the tape buffer with the next header.
|
||||||
// So cancel that via a double NOP and fill in the next header programmatically.
|
// So cancel that via a double NOP and fill in the next header programmatically.
|
||||||
@ -674,7 +669,8 @@ class ConcreteMachine:
|
|||||||
void set_selections(const Configurable::SelectionSet &selections_by_option) override {
|
void set_selections(const Configurable::SelectionSet &selections_by_option) override {
|
||||||
bool quickload;
|
bool quickload;
|
||||||
if(Configurable::get_quick_load_tape(selections_by_option, quickload)) {
|
if(Configurable::get_quick_load_tape(selections_by_option, quickload)) {
|
||||||
set_use_fast_tape_hack(quickload);
|
allow_fast_tape_hack_ = quickload;
|
||||||
|
set_use_fast_tape();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,8 +735,12 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
// Tape
|
// Tape
|
||||||
std::shared_ptr<Storage::Tape::BinaryTapePlayer> tape_;
|
std::shared_ptr<Storage::Tape::BinaryTapePlayer> tape_;
|
||||||
bool use_fast_tape_hack_;
|
bool use_fast_tape_hack_ = false;
|
||||||
|
bool allow_fast_tape_hack_ = false;
|
||||||
bool is_running_at_zero_cost_ = false;
|
bool is_running_at_zero_cost_ = false;
|
||||||
|
void set_use_fast_tape() {
|
||||||
|
use_fast_tape_hack_ = allow_fast_tape_hack_ && tape_->has_tape();
|
||||||
|
}
|
||||||
|
|
||||||
// Disk
|
// Disk
|
||||||
std::shared_ptr<::Commodore::C1540::Machine> c1540_;
|
std::shared_ptr<::Commodore::C1540::Machine> c1540_;
|
||||||
|
@ -115,10 +115,6 @@ class ConcreteMachine:
|
|||||||
if(is_holding_shift_) set_key_state(KeyShift, true);
|
if(is_holding_shift_) set_key_state(KeyShift, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_use_fast_tape_hack(bool activate) {
|
|
||||||
use_fast_tape_hack_ = activate;
|
|
||||||
}
|
|
||||||
|
|
||||||
void configure_as_target(const Analyser::Static::Target &target) override final {
|
void configure_as_target(const Analyser::Static::Target &target) override final {
|
||||||
if(target.loading_command.length()) {
|
if(target.loading_command.length()) {
|
||||||
type_string(target.loading_command);
|
type_string(target.loading_command);
|
||||||
@ -158,6 +154,7 @@ class ConcreteMachine:
|
|||||||
slot = static_cast<ROMSlot>((static_cast<int>(slot) + 1)&15);
|
slot = static_cast<ROMSlot>((static_cast<int>(slot) + 1)&15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_use_fast_tape_hack();
|
||||||
return !media.tapes.empty() || !media.disks.empty() || !media.cartridges.empty();
|
return !media.tapes.empty() || !media.disks.empty() || !media.cartridges.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +280,6 @@ class ConcreteMachine:
|
|||||||
if(isReadOperation(operation)) {
|
if(isReadOperation(operation)) {
|
||||||
if(
|
if(
|
||||||
use_fast_tape_hack_ &&
|
use_fast_tape_hack_ &&
|
||||||
tape_.has_tape() &&
|
|
||||||
(operation == CPU::MOS6502::BusOperation::ReadOpcode) &&
|
(operation == CPU::MOS6502::BusOperation::ReadOpcode) &&
|
||||||
(
|
(
|
||||||
(address == 0xf4e5) || (address == 0xf4e6) || // double NOPs at 0xf4e5, 0xf6de, 0xf6fa and 0xfa51
|
(address == 0xf4e5) || (address == 0xf4e6) || // double NOPs at 0xf4e5, 0xf6de, 0xf6fa and 0xfa51
|
||||||
@ -437,7 +433,8 @@ class ConcreteMachine:
|
|||||||
void set_selections(const Configurable::SelectionSet &selections_by_option) override {
|
void set_selections(const Configurable::SelectionSet &selections_by_option) override {
|
||||||
bool quickload;
|
bool quickload;
|
||||||
if(Configurable::get_quick_load_tape(selections_by_option, quickload)) {
|
if(Configurable::get_quick_load_tape(selections_by_option, quickload)) {
|
||||||
set_use_fast_tape_hack(quickload);
|
allow_fast_tape_hack_ = quickload;
|
||||||
|
set_use_fast_tape_hack();
|
||||||
}
|
}
|
||||||
|
|
||||||
Configurable::Display display;
|
Configurable::Display display;
|
||||||
@ -526,6 +523,10 @@ class ConcreteMachine:
|
|||||||
// Tape
|
// Tape
|
||||||
Tape tape_;
|
Tape tape_;
|
||||||
bool use_fast_tape_hack_ = false;
|
bool use_fast_tape_hack_ = false;
|
||||||
|
bool allow_fast_tape_hack_ = false;
|
||||||
|
void set_use_fast_tape_hack() {
|
||||||
|
use_fast_tape_hack_ = allow_fast_tape_hack_ && tape_.has_tape();
|
||||||
|
}
|
||||||
bool fast_load_is_in_data_ = false;
|
bool fast_load_is_in_data_ = false;
|
||||||
|
|
||||||
// Disk
|
// Disk
|
||||||
|
@ -228,6 +228,8 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_use_fast_tape();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +289,7 @@ class ConcreteMachine:
|
|||||||
uint16_t address = cycle.address ? *cycle.address : 0x0000;
|
uint16_t address = cycle.address ? *cycle.address : 0x0000;
|
||||||
switch(cycle.operation) {
|
switch(cycle.operation) {
|
||||||
case CPU::Z80::PartialMachineCycle::ReadOpcode:
|
case CPU::Z80::PartialMachineCycle::ReadOpcode:
|
||||||
if(use_fast_tape_ && tape_player_.has_tape()) {
|
if(use_fast_tape_) {
|
||||||
if(address == 0x1a63) {
|
if(address == 0x1a63) {
|
||||||
// TAPION
|
// TAPION
|
||||||
|
|
||||||
@ -542,7 +544,8 @@ class ConcreteMachine:
|
|||||||
void set_selections(const Configurable::SelectionSet &selections_by_option) override {
|
void set_selections(const Configurable::SelectionSet &selections_by_option) override {
|
||||||
bool quickload;
|
bool quickload;
|
||||||
if(Configurable::get_quick_load_tape(selections_by_option, quickload)) {
|
if(Configurable::get_quick_load_tape(selections_by_option, quickload)) {
|
||||||
use_fast_tape_ = quickload;
|
allow_fast_tape_ = quickload;
|
||||||
|
set_use_fast_tape();
|
||||||
}
|
}
|
||||||
|
|
||||||
Configurable::Display display;
|
Configurable::Display display;
|
||||||
@ -625,7 +628,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 allow_fast_tape_ = false;
|
||||||
bool use_fast_tape_ = false;
|
bool use_fast_tape_ = false;
|
||||||
|
void set_use_fast_tape() {
|
||||||
|
use_fast_tape_ = allow_fast_tape_ && tape_player_.has_tape();
|
||||||
|
}
|
||||||
|
|
||||||
i8255PortHandler i8255_port_handler_;
|
i8255PortHandler i8255_port_handler_;
|
||||||
AYPortHandler ay_port_handler_;
|
AYPortHandler ay_port_handler_;
|
||||||
|
@ -158,7 +158,7 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
|
|
||||||
case CPU::Z80::PartialMachineCycle::ReadOpcode:
|
case CPU::Z80::PartialMachineCycle::ReadOpcode:
|
||||||
// Check for use of the fast tape hack.
|
// Check for use of the fast tape hack.
|
||||||
if(use_fast_tape_hack_ && address == tape_trap_address_ && tape_player_.has_tape()) {
|
if(use_fast_tape_hack_ && address == tape_trap_address_) {
|
||||||
uint64_t prior_offset = tape_player_.get_tape()->get_offset();
|
uint64_t prior_offset = tape_player_.get_tape()->get_offset();
|
||||||
int next_byte = parser_.get_next_byte(tape_player_.get_tape());
|
int next_byte = parser_.get_next_byte(tape_player_.get_tape());
|
||||||
if(next_byte != -1) {
|
if(next_byte != -1) {
|
||||||
@ -290,6 +290,7 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
tape_player_.set_tape(media.tapes.front());
|
tape_player_.set_tape(media.tapes.front());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_use_fast_tape();
|
||||||
return !media.tapes.empty();
|
return !media.tapes.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,9 +332,6 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Tape control
|
// MARK: - Tape control
|
||||||
void set_use_fast_tape_hack(bool activate) {
|
|
||||||
use_fast_tape_hack_ = activate;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_use_automatic_tape_motor_control(bool enabled) {
|
void set_use_automatic_tape_motor_control(bool enabled) {
|
||||||
use_automatic_tape_motor_control_ = enabled;
|
use_automatic_tape_motor_control_ = enabled;
|
||||||
@ -366,7 +364,8 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
void set_selections(const Configurable::SelectionSet &selections_by_option) override {
|
void set_selections(const Configurable::SelectionSet &selections_by_option) override {
|
||||||
bool quickload;
|
bool quickload;
|
||||||
if(Configurable::get_quick_load_tape(selections_by_option, quickload)) {
|
if(Configurable::get_quick_load_tape(selections_by_option, quickload)) {
|
||||||
set_use_fast_tape_hack(quickload);
|
allow_fast_tape_hack_ = quickload;
|
||||||
|
set_use_fast_tape();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool autotapemotor;
|
bool autotapemotor;
|
||||||
@ -423,6 +422,10 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
bool has_latched_video_byte_ = false;
|
bool has_latched_video_byte_ = false;
|
||||||
|
|
||||||
bool use_fast_tape_hack_ = false;
|
bool use_fast_tape_hack_ = false;
|
||||||
|
bool allow_fast_tape_hack_ = false;
|
||||||
|
void set_use_fast_tape() {
|
||||||
|
use_fast_tape_hack_ = allow_fast_tape_hack_ && tape_player_.has_tape();
|
||||||
|
}
|
||||||
bool use_automatic_tape_motor_control_;
|
bool use_automatic_tape_motor_control_;
|
||||||
HalfCycles tape_advance_delay_ = 0;
|
HalfCycles tape_advance_delay_ = 0;
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
#import "CSAudioQueue.h"
|
#import "CSAudioQueue.h"
|
||||||
|
#import "CSFastLoading.h"
|
||||||
#import "CSOpenGLView.h"
|
#import "CSOpenGLView.h"
|
||||||
#import "CSStaticAnalyser.h"
|
#import "CSStaticAnalyser.h"
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#import "NSBundle+DataResource.h"
|
#import "NSBundle+DataResource.h"
|
||||||
#import "NSData+StdVector.h"
|
#import "NSData+StdVector.h"
|
||||||
|
|
||||||
@interface CSMachine()
|
@interface CSMachine() <CSFastLoading>
|
||||||
- (void)speaker:(Outputs::Speaker::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
|
- (void)speaker:(Outputs::Speaker::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
|
||||||
- (void)machineDidChangeClockRate;
|
- (void)machineDidChangeClockRate;
|
||||||
- (void)machineDidChangeClockIsUnlimited;
|
- (void)machineDidChangeClockIsUnlimited;
|
||||||
|
@ -16,8 +16,10 @@ struct UpdaterDelegate: public Concurrency::BestEffortUpdater::Delegate {
|
|||||||
|
|
||||||
void update(Concurrency::BestEffortUpdater *updater, int cycles, bool did_skip_previous_update) {
|
void update(Concurrency::BestEffortUpdater *updater, int cycles, bool did_skip_previous_update) {
|
||||||
[delegateLock lock];
|
[delegateLock lock];
|
||||||
[delegate bestEffortUpdater:nil runForCycles:(NSUInteger)cycles didSkipPreviousUpdate:did_skip_previous_update];
|
__weak id<CSBestEffortUpdaterDelegate> delegateCopy = delegate;
|
||||||
[delegateLock unlock];
|
[delegateLock unlock];
|
||||||
|
|
||||||
|
[delegateCopy bestEffortUpdater:nil runForCycles:(NSUInteger)cycles didSkipPreviousUpdate:did_skip_previous_update];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user