From ea81096a43073164c19d4502c429990ad4cc8ab9 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 7 Feb 2025 18:09:33 -0500 Subject: [PATCH 1/6] Reinstall debugging temporariness. --- Machines/Commodore/Plus4/Plus4.cpp | 30 ++++++++++++++++++++++++++++-- Numeric/CRC.hpp | 1 - 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Machines/Commodore/Plus4/Plus4.cpp b/Machines/Commodore/Plus4/Plus4.cpp index 35060d5e9..27617a2d5 100644 --- a/Machines/Commodore/Plus4/Plus4.cpp +++ b/Machines/Commodore/Plus4/Plus4.cpp @@ -300,8 +300,31 @@ public: serial_port_.set_output(Serial::Line::Attention, Serial::LineLevel(~output & 0x04)); } } else if(address < 0xfd00 || address >= 0xff40) { - if(use_fast_tape_hack_ && operation == CPU::MOS6502Esque::BusOperation::ReadOpcode && address == 0xe5fd) { - read_dipole(); + constexpr bool use_hle = true; + + if( + use_fast_tape_hack_ && + operation == CPU::MOS6502Esque::BusOperation::ReadOpcode && + ( + (use_hle && address == 0xe5fd) || + address == 0xe68b || + address == 0xe68d + ) + ) { + if(use_hle) { + read_dipole(); + } + ++pulse_num_; + + using Flag = CPU::MOS6502::Flag; + using Register = CPU::MOS6502::Register; + const auto flags = m6502_.value_of(Register::Flags); + printf("Pulse %d: %c%c%c\n", + pulse_num_, + flags & Flag::Sign ? 'n' : '-', + flags & Flag::Overflow ? 'v' : '-', + flags & Flag::Carry ? 'v' : '-' + ); *value = 0x60; } else { if(is_read(operation)) { @@ -728,6 +751,9 @@ private: tape_player_->run_for(length); } + + // TODO: substantially simplify the below; at the minute it's a + // literal transcription of the original as a simple first step. void read_dipole() { using Register = CPU::MOS6502::Register; using Flag = CPU::MOS6502::Flag; diff --git a/Numeric/CRC.hpp b/Numeric/CRC.hpp index 5a0e5f7f2..43f1c2718 100644 --- a/Numeric/CRC.hpp +++ b/Numeric/CRC.hpp @@ -13,7 +13,6 @@ #include #include -#include namespace CRC { From 93eb63d9308bcf99285b0fd85e9c0051fe0be8e5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 11 Feb 2025 21:47:36 -0500 Subject: [PATCH 2/6] Add interrupt register to TED check set. --- Analyser/Static/Commodore/StaticAnalyser.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Analyser/Static/Commodore/StaticAnalyser.cpp b/Analyser/Static/Commodore/StaticAnalyser.cpp index b566d2330..6e38608ae 100644 --- a/Analyser/Static/Commodore/StaticAnalyser.cpp +++ b/Analyser/Static/Commodore/StaticAnalyser.cpp @@ -180,9 +180,8 @@ bool obviously_uses_ted(const File &file) { analysis->machine_code_addresses ); - // If FF3E or FF3F is touched, this is for the +4. - // TODO: probably require a very early touch. - for(const auto address: {0xff3e, 0xff3f}) { + // Check for interrupt status and paging touches. + for(const auto address: {0xff3e, 0xff3f, 0xff09}) { for(const auto &collection: { disassembly.external_loads, disassembly.external_stores, From 947077529290456ca53797b85c0f50eedca0eab5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 11 Feb 2025 21:48:23 -0500 Subject: [PATCH 3/6] Avoid race condition on input/output frequencies. --- Outputs/Speaker/Implementation/LowpassSpeaker.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Outputs/Speaker/Implementation/LowpassSpeaker.hpp b/Outputs/Speaker/Implementation/LowpassSpeaker.hpp index b552ea91e..4f658b7bd 100644 --- a/Outputs/Speaker/Implementation/LowpassSpeaker.hpp +++ b/Outputs/Speaker/Implementation/LowpassSpeaker.hpp @@ -100,8 +100,8 @@ private: std::mutex filter_parameters_mutex_; struct FilterParameters { - float input_cycles_per_second = 0.0f; - float output_cycles_per_second = 0.0f; + float input_cycles_per_second = 1.0f; + float output_cycles_per_second = 1.0f; float high_frequency_cutoff = -1.0; bool parameters_are_dirty = true; From 94b972aaf49ac44ecac5f7cffddb690e209cbaab Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 11 Feb 2025 21:48:56 -0500 Subject: [PATCH 4/6] Improve style. --- SignalProcessing/FIRFilter.cpp | 108 +++++++++++++++++++-------------- SignalProcessing/FIRFilter.hpp | 15 ++--- 2 files changed, 66 insertions(+), 57 deletions(-) diff --git a/SignalProcessing/FIRFilter.cpp b/SignalProcessing/FIRFilter.cpp index 382e11030..ca44febc5 100644 --- a/SignalProcessing/FIRFilter.cpp +++ b/SignalProcessing/FIRFilter.cpp @@ -9,9 +9,11 @@ #include "FIRFilter.hpp" #include +#include #ifndef M_PI static constexpr float M_PI = 3.1415926f; +// TODO: use std::numbers::pi_v when switching to C++20. #endif using namespace SignalProcessing; @@ -36,8 +38,10 @@ using namespace SignalProcessing; "DIGITAL SIGNAL PROCESSING, II", IEEE Press, pages 123-126. */ +namespace { + /*! Evaluates the 0th order Bessel function at @c a. */ -float FIRFilter::ino(float a) { +constexpr float ino(float a) { float d = 0.0f; float ds = 1.0f; float s = 1.0f; @@ -51,73 +55,78 @@ float FIRFilter::ino(float a) { return s; } -void FIRFilter::coefficients_for_idealised_filter_response(short *filter_coefficients, float *A, float attenuation, std::size_t number_of_taps) { - /* calculate alpha, which is the Kaiser-Bessel window shape factor */ - float a; // to take the place of alpha in the normal derivation - - if(attenuation < 21.0f) { - a = 0.0f; - } else { - if(attenuation > 50.0f) - a = 0.1102f * (attenuation - 8.7f); - else - a = 0.5842f * powf(attenuation - 21.0f, 0.4f) + 0.7886f * (attenuation - 21.0f); - } +std::vector coefficients_for_idealised_filter_response( + const std::vector &A, + const float attenuation, + const std::size_t number_of_taps +) { + /* Calculate alpha, the Kaiser-Bessel window shape factor */ + const float a = [&] { + if(attenuation < 21.0f) { + return 0.0f; + } else if(attenuation > 50.0f) { + return 0.1102f * (attenuation - 8.7f); + } else { + return 0.5842f * powf(attenuation - 21.0f, 0.4f) + 0.7886f * (attenuation - 21.0f); + } + } (); std::vector filter_coefficients_float(number_of_taps); - /* work out the right hand side of the filter coefficients */ - std::size_t Np = (number_of_taps - 1) / 2; - float I0 = ino(a); - float Np_squared = float(Np * Np); - for(unsigned int i = 0; i <= Np; ++i) { + /* Work out the right hand side of the filter coefficients. */ + const float I0 = ino(a); + const std::size_t Np = (number_of_taps - 1) / 2; + const float Np_squared = float(Np * Np); + for(std::size_t i = 0; i <= Np; ++i) { filter_coefficients_float[Np + i] = A[i] * ino(a * sqrtf(1.0f - (float(i * i) / Np_squared) )) / I0; } - /* coefficients are symmetrical, so copy from right hand side to left side */ + /* Coefficients are symmetrical, so copy from right hand side to left. */ for(std::size_t i = 0; i < Np; ++i) { filter_coefficients_float[i] = filter_coefficients_float[number_of_taps - 1 - i]; } - /* scale back up so that we retain 100% of input volume */ - float coefficientTotal = 0.0f; - for(std::size_t i = 0; i < number_of_taps; ++i) { - coefficientTotal += filter_coefficients_float[i]; - } + /* Scale back up to retain 100% of input volume. */ + const float coefficientTotal = + std::accumulate(filter_coefficients_float.begin(), filter_coefficients_float.end(), 0.0f); - /* we'll also need integer versions, potentially */ - float coefficientMultiplier = 1.0f / coefficientTotal; + /* Hence produce integer versions. */ + const float coefficientMultiplier = 1.0f / coefficientTotal; + std::vector filter_coefficients; + filter_coefficients.reserve(number_of_taps); for(std::size_t i = 0; i < number_of_taps; ++i) { - filter_coefficients[i] = short(filter_coefficients_float[i] * FixedMultiplier * coefficientMultiplier); + filter_coefficients.push_back(short(filter_coefficients_float[i] * FixedMultiplier * coefficientMultiplier)); } + return filter_coefficients; +} } std::vector FIRFilter::get_coefficients() const { std::vector coefficients; + coefficients.reserve(filter_coefficients_.size()); for(const auto short_coefficient: filter_coefficients_) { coefficients.push_back(float(short_coefficient) / FixedMultiplier); } return coefficients; } -FIRFilter::FIRFilter(std::size_t number_of_taps, float input_sample_rate, float low_frequency, float high_frequency, float attenuation) { - // we must be asked to filter based on an odd number of - // taps, and at least three - if(number_of_taps < 3) number_of_taps = 3; - if(attenuation < 21.0f) attenuation = 21.0f; - - // ensure we have an odd number of taps - number_of_taps |= 1; - - // store instance variables - filter_coefficients_.resize(number_of_taps); +FIRFilter::FIRFilter( + std::size_t number_of_taps, + const float input_sample_rate, + const float low_frequency, + float high_frequency, + float attenuation +) { + // Ensure an odd number of taps greater than or equal to 3, with a minimum attenuation of 21. + number_of_taps = std::max(3, number_of_taps) | 1; + attenuation = std::max(attenuation, 21.0f); /* calculate idealised filter response */ - std::size_t Np = (number_of_taps - 1) / 2; - float two_over_sample_rate = 2.0f / input_sample_rate; + const std::size_t Np = (number_of_taps - 1) / 2; + const float two_over_sample_rate = 2.0f / input_sample_rate; // Clamp the high cutoff frequency. high_frequency = std::min(high_frequency, input_sample_rate * 0.5f); @@ -125,7 +134,7 @@ FIRFilter::FIRFilter(std::size_t number_of_taps, float input_sample_rate, float std::vector A(Np+1); A[0] = 2.0f * (high_frequency - low_frequency) / input_sample_rate; for(unsigned int i = 1; i <= Np; ++i) { - float i_pi = float(i) * float(M_PI); + const float i_pi = float(i) * float(M_PI); A[i] = ( sinf(two_over_sample_rate * i_pi * high_frequency) - @@ -133,20 +142,22 @@ FIRFilter::FIRFilter(std::size_t number_of_taps, float input_sample_rate, float ) / i_pi; } - FIRFilter::coefficients_for_idealised_filter_response(filter_coefficients_.data(), A.data(), attenuation, number_of_taps); + filter_coefficients_ = coefficients_for_idealised_filter_response(A, attenuation, number_of_taps); } FIRFilter::FIRFilter(const std::vector &coefficients) { + filter_coefficients_.reserve(coefficients.size()); for(const auto coefficient: coefficients) { filter_coefficients_.push_back(short(coefficient * FixedMultiplier)); } } FIRFilter FIRFilter::operator+(const FIRFilter &rhs) const { - std::vector coefficients = get_coefficients(); - std::vector rhs_coefficients = rhs.get_coefficients(); + const auto coefficients = get_coefficients(); + const auto rhs_coefficients = rhs.get_coefficients(); std::vector sum; + sum.reserve(coefficients.size()); for(std::size_t i = 0; i < coefficients.size(); ++i) { sum.push_back((coefficients[i] + rhs_coefficients[i]) / 2.0f); } @@ -155,9 +166,11 @@ FIRFilter FIRFilter::operator+(const FIRFilter &rhs) const { } FIRFilter FIRFilter::operator-() const { + const auto coefficients = get_coefficients(); std::vector negative_coefficients; - for(const auto coefficient: get_coefficients()) { + negative_coefficients.reserve(coefficients.size()); + for(const auto coefficient: coefficients) { negative_coefficients.push_back(1.0f - coefficient); } @@ -165,10 +178,11 @@ FIRFilter FIRFilter::operator-() const { } FIRFilter FIRFilter::operator*(const FIRFilter &rhs) const { - std::vector coefficients = get_coefficients(); - std::vector rhs_coefficients = rhs.get_coefficients(); + const std::vector coefficients = get_coefficients(); + const std::vector rhs_coefficients = rhs.get_coefficients(); std::vector sum; + sum.reserve(coefficients.size()); for(std::size_t i = 0; i < coefficients.size(); ++i) { sum.push_back(coefficients[i] * rhs_coefficients[i]); } diff --git a/SignalProcessing/FIRFilter.hpp b/SignalProcessing/FIRFilter.hpp index cf40a5aad..d5826d447 100644 --- a/SignalProcessing/FIRFilter.hpp +++ b/SignalProcessing/FIRFilter.hpp @@ -20,6 +20,8 @@ #include namespace SignalProcessing { +constexpr float FixedMultiplier = 32767.0f; +constexpr int FixedShift = 15; /*! The FIR filter takes a 1d PCM signal with a given sample rate and applies a band-pass filter to it. @@ -28,13 +30,10 @@ namespace SignalProcessing { smaller numbers permit a filter that operates more quickly and with less lag but less effectively. */ class FIRFilter { -private: - static constexpr float FixedMultiplier = 32767.0f; - static constexpr int FixedShift = 15; - public: /*! A suggested default attenuation value. */ - constexpr static float DefaultAttenuation = 60.0f; + static constexpr float DefaultAttenuation = 60.0f; + /*! Creates an instance of @c FIRFilter. @@ -59,7 +58,7 @@ public: @param src The source buffer to apply the filter to. @returns The result of applying the filter. */ - inline short apply(const short *src, size_t stride = 1) const { + inline short apply(const short *const src, const size_t stride = 1) const { #ifdef USE_ACCELERATE short result; vDSP_dotpr_s1_15( @@ -105,10 +104,6 @@ public: private: std::vector filter_coefficients_; - - static void coefficients_for_idealised_filter_response( - short *filterCoefficients, float *A, float attenuation, std::size_t numberOfTaps); - static float ino(float a); }; } From 7f480e8e5616c3ddb21cfc25b1ce38a21c4bcd31 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 11 Feb 2025 21:49:58 -0500 Subject: [PATCH 5/6] Swing desperately at fast tape loading. --- Machines/Commodore/Plus4/Plus4.cpp | 166 ++++++++++++++++++----------- 1 file changed, 104 insertions(+), 62 deletions(-) diff --git a/Machines/Commodore/Plus4/Plus4.cpp b/Machines/Commodore/Plus4/Plus4.cpp index 27617a2d5..4ce4163e5 100644 --- a/Machines/Commodore/Plus4/Plus4.cpp +++ b/Machines/Commodore/Plus4/Plus4.cpp @@ -242,6 +242,7 @@ public: // HACK. NOCOMMIT. int pulse_num_ = 0; + bool superspeed_ = false; Cycles perform_bus_operation( const CPU::MOS6502::BusOperation operation, @@ -254,15 +255,18 @@ public: // Update other subsystems. advance_timers_and_tape(length); - video_.run_for(length); + if(!superspeed_) { + video_.run_for(length); - if(c1541_) { - c1541_cycles_ += length * Cycles(1'000'000); - c1541_->run_for(c1541_cycles_.divide(media_divider_)); + if(c1541_) { + c1541_cycles_ += length * Cycles(1'000'000); + c1541_->run_for(c1541_cycles_.divide(media_divider_)); + } + + + time_since_audio_update_ += length; } - time_since_audio_update_ += length; - if(operation == CPU::MOS6502::BusOperation::Ready) { return length; } @@ -300,7 +304,30 @@ public: serial_port_.set_output(Serial::Line::Attention, Serial::LineLevel(~output & 0x04)); } } else if(address < 0xfd00 || address >= 0xff40) { - constexpr bool use_hle = true; +// if( +// use_fast_tape_hack_ && +// operation == CPU::MOS6502Esque::BusOperation::ReadOpcode +// ) { +// superspeed_ |= address == 0xe5fd; +// superspeed_ &= (address != 0xe68b) && (address != 0xe68d); +// } + + constexpr bool use_hle = !true; + + if( + use_fast_tape_hack_ && + operation == CPU::MOS6502Esque::BusOperation::ReadOpcode && + address == 0xe5fd + ) { + printf("Pulse %d from %lld ", + pulse_num_, + tape_player_->serialiser()->offset() + ); + + if(tape_player_->serialiser()->offset() == 108080) { + printf(""); + } + } if( use_fast_tape_hack_ && @@ -311,19 +338,19 @@ public: address == 0xe68d ) ) { + ++pulse_num_; if(use_hle) { read_dipole(); } - ++pulse_num_; using Flag = CPU::MOS6502::Flag; using Register = CPU::MOS6502::Register; const auto flags = m6502_.value_of(Register::Flags); - printf("Pulse %d: %c%c%c\n", - pulse_num_, + printf("to %lld: %c%c%c\n", + tape_player_->serialiser()->offset(), flags & Flag::Sign ? 'n' : '-', flags & Flag::Overflow ? 'v' : '-', - flags & Flag::Carry ? 'v' : '-' + flags & Flag::Carry ? 'c' : '-' ); *value = 0x60; } else { @@ -334,36 +361,36 @@ public: } } -/* if(use_fast_tape_hack_ && operation == CPU::MOS6502Esque::BusOperation::ReadOpcode) { - if(address == 0xe9cc) { - // Skip the `jsr rdblok` that opens `fah` (i.e. find any header), performing - // its function as a high-level emulation. - Storage::Tape::Commodore::Parser parser(TargetPlatform::Plus4); - auto header = parser.get_next_header(*tape_player_->serialiser()); - - const auto tape_position = tape_player_->serialiser()->offset(); - if(header) { - // Copy to in-memory buffer and set type. - std::memcpy(&ram_[0x0333], header->data.data(), 191); - map_.write(0xb6) = 0x33; - map_.write(0xb7) = 0x03; - map_.write(0xf8) = header->type_descriptor(); -// hold_tape_ = true; - logger.info().append("Found header"); - } else { - // no header found, so pretend this hack never interceded - tape_player_->serialiser()->set_offset(tape_position); -// hold_tape_ = false; - logger.info().append("Didn't find header"); - } - - // Clear status and the verify flags. - ram_[0x90] = 0; - ram_[0x93] = 0; - - *value = 0x0c; // NOP abs. - } - }*/ +// if(use_fast_tape_hack_ && operation == CPU::MOS6502Esque::BusOperation::ReadOpcode) { +// if(address == 0xe9cc) { +// // Skip the `jsr rdblok` that opens `fah` (i.e. find any header), performing +// // its function as a high-level emulation. +// Storage::Tape::Commodore::Parser parser(TargetPlatform::Plus4); +// auto header = parser.get_next_header(*tape_player_->serialiser()); +// +// const auto tape_position = tape_player_->serialiser()->offset(); +// if(header) { +// // Copy to in-memory buffer and set type. +// std::memcpy(&ram_[0x0333], header->data.data(), 191); +// map_.write(0xb6) = 0x33; +// map_.write(0xb7) = 0x03; +// map_.write(0xf8) = header->type_descriptor(); +//// hold_tape_ = true; +// logger.info().append("Found header"); +// } else { +// // no header found, so pretend this hack never interceded +// tape_player_->serialiser()->set_offset(tape_position); +//// hold_tape_ = false; +// logger.info().append("Didn't find header"); +// } +// +// // Clear status and the verify flags. +// ram_[0x90] = 0; +// ram_[0x93] = 0; +// +// *value = 0x0c; // NOP abs. +// } +// } } else if(address < 0xff00) { // Miscellaneous hardware. All TODO. if(is_read(operation)) { @@ -590,7 +617,7 @@ public: } } - return length; + return superspeed_ ? Cycles(0) : length; } private: @@ -860,6 +887,7 @@ private: // ldy dsamp1+1 ldabs(x, dsamp1); ldabs(y, dsamp1 + 1); + advance_cycles(8); //badeg1 do { @@ -871,15 +899,17 @@ private: pha(); ldabs(a, dsamp2); pha(); + advance_cycles(14); // lda #$10 //rwtl ; wait till rd line is high // bit port [= $0001] // beq rwtl ; !ls! ldimm(a, 0x10); + advance_cycles(2); do { bit(io_input()); - if(advance_cycles(7)) { + if(advance_cycles(6)) { return; } } while(eq()); @@ -889,7 +919,7 @@ private: // bne rwth ; caught the edge do { bit(io_input()); - if(advance_cycles(7)) { + if(advance_cycles(6)) { return; } } while(ne()); @@ -899,6 +929,8 @@ private: // sty timr2h timers_.write<2>(x); timers_.write<3>(y); + advance_cycles(8); + //; go! ...ta // @@ -910,6 +942,7 @@ private: timers_.write<4>(a); pla(); timers_.write<5>(a); + advance_cycles(14); //; clear timer flags @@ -918,6 +951,7 @@ private: // sta tedirq ldimm(a, 0x50); interrupts_.set_status(a); + advance_cycles(6); //; um...check that edge again @@ -931,11 +965,12 @@ private: do { ldimm(a, io_input()); cmp(io_input()); - if(advance_cycles(11)) { + if(advance_cycles(9)) { return; } } while(ne()); andimm(0x10); + advance_cycles(5); } while(ne()); @@ -952,11 +987,8 @@ private: // lda #$10 //wata ; wait for ta to timeout ldimm(a, 0x10); + advance_cycles(3); do { - if(advance_cycles(13)) { - return; - } - // bit port ; kuldge, kludge, kludge !!! <<><>> // bne rshort ; kuldge, kludge, kludge !!! <<><>> bit(io_input()); @@ -968,6 +1000,10 @@ private: // bit tedirq // beq wata bit(interrupts_.status()); + + if(advance_cycles(12)) { + return; + } } while(eq()); @@ -976,21 +1012,21 @@ private: // //casdb2 do { - if(advance_cycles(11)) { - return; - } - // lda port // cmp port ldimm(a, io_input()); cmp(io_input()); + if(advance_cycles(9)) { + return; + } // bne casdb2 } while(ne()); // and #$10 // bne rshort ; shorts anyone? andimm(0x10); + advance_cycles(3); if(ne()) { rshort(); return; @@ -1007,11 +1043,12 @@ private: //; wait for tb to timeout //; now do the dipole sample #2 ldimm(a, 0x40); + advance_cycles(3); do { - if(advance_cycles(7)) { + bit(interrupts_.status()); + if(advance_cycles(6)) { return; } - bit(interrupts_.status()); } while(eq()); @@ -1020,16 +1057,17 @@ private: // cmp port // bne casdb3 do { - if(advance_cycles(11)) { - return; - } ldimm(a, io_input()); cmp(io_input()); + if(advance_cycles(9)) { + return; + } } while(ne()); // and #$10 // bne rlong ; looks like a long from here !ls! andimm(0x10); + advance_cycles(2); if(ne()) { rlong(); return; @@ -1044,6 +1082,7 @@ private: timers_.write<2>(a); ldabs(a, zcell + 1); timers_.write<3>(y); + advance_cycles(16); // ; go! z-cell check @@ -1054,15 +1093,16 @@ private: ldimm(a, 0x10); interrupts_.set_status(a); ldimm(a, 0x10); + advance_cycles(8); //wata2 // bit tedirq // beq wata2 ; check z-cell is low do { + bit(interrupts_.status()); if(advance_cycles(7)) { return; } - bit(interrupts_.status()); } while(eq()); //casdb4 @@ -1070,11 +1110,11 @@ private: // cmp port // bne casdb4 do { - if(advance_cycles(7)) { - return; - } ldimm(a, io_input()); cmp(io_input()); + if(advance_cycles(9)) { + return; + } } while(ne()); // and #$10 @@ -1082,11 +1122,13 @@ private: // bit twordd ; got a word dipole // bmi dipok ; !bra andimm(0x10); + advance_cycles(2); if(eq()) { rderr1(); return; } bit(0x80); + advance_cycles(2); dipok(); } From a1d10adaa31c22397306b55f8ba5c4322e07e355 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 18 Feb 2025 20:46:43 -0500 Subject: [PATCH 6/6] Support only the Vic-20 for PRGs for now. --- Analyser/Static/StaticAnalyser.cpp | 5 ++- Machines/Commodore/Plus4/Plus4.cpp | 61 +++++++++++++++++------------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/Analyser/Static/StaticAnalyser.cpp b/Analyser/Static/StaticAnalyser.cpp index 81313dec0..2aba4c401 100644 --- a/Analyser/Static/StaticAnalyser.cpp +++ b/Analyser/Static/StaticAnalyser.cpp @@ -269,13 +269,14 @@ static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform:: accumulator.try_standard(TargetPlatform::ZX8081, "p81"); + static constexpr auto PRGTargets = TargetPlatform::Vic20; //Commodore8bit; // Disabled until analysis improves. if(accumulator.name_matches("prg")) { // Try instantiating as a ROM; failing that accept as a tape. try { - accumulator.insert(TargetPlatform::Commodore8bit, file_name); + accumulator.insert(PRGTargets, file_name); } catch(...) { try { - accumulator.insert(TargetPlatform::Commodore8bit, file_name); + accumulator.insert(PRGTargets, file_name); } catch(...) {} } } diff --git a/Machines/Commodore/Plus4/Plus4.cpp b/Machines/Commodore/Plus4/Plus4.cpp index 4ce4163e5..6de60402f 100644 --- a/Machines/Commodore/Plus4/Plus4.cpp +++ b/Machines/Commodore/Plus4/Plus4.cpp @@ -241,8 +241,7 @@ public: } // HACK. NOCOMMIT. - int pulse_num_ = 0; - bool superspeed_ = false; +// int pulse_num_ = 0; Cycles perform_bus_operation( const CPU::MOS6502::BusOperation operation, @@ -312,22 +311,18 @@ public: // superspeed_ &= (address != 0xe68b) && (address != 0xe68d); // } - constexpr bool use_hle = !true; + constexpr bool use_hle = true; - if( - use_fast_tape_hack_ && - operation == CPU::MOS6502Esque::BusOperation::ReadOpcode && - address == 0xe5fd - ) { - printf("Pulse %d from %lld ", - pulse_num_, - tape_player_->serialiser()->offset() - ); - - if(tape_player_->serialiser()->offset() == 108080) { - printf(""); - } - } +// if( +// use_fast_tape_hack_ && +// operation == CPU::MOS6502Esque::BusOperation::ReadOpcode && +// address == 0xe5fd +// ) { +// printf("Pulse %d from %lld ", +// pulse_num_, +// tape_player_->serialiser()->offset() +// ); +// } if( use_fast_tape_hack_ && @@ -338,20 +333,20 @@ public: address == 0xe68d ) ) { - ++pulse_num_; +// ++pulse_num_; if(use_hle) { read_dipole(); } - using Flag = CPU::MOS6502::Flag; - using Register = CPU::MOS6502::Register; - const auto flags = m6502_.value_of(Register::Flags); - printf("to %lld: %c%c%c\n", - tape_player_->serialiser()->offset(), - flags & Flag::Sign ? 'n' : '-', - flags & Flag::Overflow ? 'v' : '-', - flags & Flag::Carry ? 'c' : '-' - ); +// using Flag = CPU::MOS6502::Flag; +// using Register = CPU::MOS6502::Register; +// const auto flags = m6502_.value_of(Register::Flags); +// printf("to %lld: %c%c%c\n", +// tape_player_->serialiser()->offset(), +// flags & Flag::Sign ? 'n' : '-', +// flags & Flag::Overflow ? 'v' : '-', +// flags & Flag::Carry ? 'c' : '-' +// ); *value = 0x60; } else { if(is_read(operation)) { @@ -361,7 +356,18 @@ public: } } + + // TODO: rdbyte and ldsync is probably sufficient? + // if(use_fast_tape_hack_ && operation == CPU::MOS6502Esque::BusOperation::ReadOpcode) { +// constexpr uint16_t ldsync = 0; +// switch(address) { +// default: break; +// +// case ldsync: +// break; +// } +// // if(address == 0xe9cc) { // // Skip the `jsr rdblok` that opens `fah` (i.e. find any header), performing // // its function as a high-level emulation. @@ -763,6 +769,7 @@ private: bool play_button_ = false; bool allow_fast_tape_hack_ = false; // TODO: implement fast-tape hack. bool use_fast_tape_hack_ = false; + bool superspeed_ = false; void set_use_fast_tape() { use_fast_tape_hack_ = allow_fast_tape_hack_ && tape_player_->motor_control() && rom_is_paged_ && !tape_player_->is_at_end();