1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-08 14:25:05 +00:00

Merge pull request #375 from TomHarte/UndefinedBehaviour

Resolves various pieces of undefined behaviour.
This commit is contained in:
Thomas Harte
2018-03-22 22:01:19 -04:00
committed by GitHub
17 changed files with 50 additions and 16 deletions

View File

@@ -16,9 +16,9 @@ namespace Static {
namespace Acorn { namespace Acorn {
struct Target: public ::Analyser::Static::Target { struct Target: public ::Analyser::Static::Target {
bool has_adfs; bool has_adfs = false;
bool has_dfs; bool has_dfs = false;
bool should_shift_restart; bool should_shift_restart = false;
}; };
} }

View File

@@ -22,7 +22,7 @@ struct Target: public ::Analyser::Static::Target {
CPC6128 CPC6128
}; };
Model model; Model model = Model::CPC464;
}; };
} }

View File

@@ -32,8 +32,8 @@ struct Target: public ::Analyser::Static::Target {
}; };
// TODO: shouldn't these be properties of the cartridge? // TODO: shouldn't these be properties of the cartridge?
PagingModel paging_model; PagingModel paging_model = PagingModel::None;
bool uses_superchip; bool uses_superchip = false;
}; };
} }

View File

@@ -22,8 +22,8 @@ struct Target: public ::Analyser::Static::Target {
ThirtyTwoKB ThirtyTwoKB
}; };
MemoryModel memory_model; MemoryModel memory_model = MemoryModel::Unexpanded;
bool has_c1540; bool has_c1540 = false;
}; };
} }

View File

@@ -14,8 +14,8 @@ namespace Static {
namespace Oric { namespace Oric {
struct Target: public ::Analyser::Static::Target { struct Target: public ::Analyser::Static::Target {
bool use_atmos_rom; bool use_atmos_rom = false;
bool has_microdisc; bool has_microdisc = false;
}; };
} }

View File

@@ -22,8 +22,8 @@ struct Target: public ::Analyser::Static::Target {
SixtyFourKB SixtyFourKB
}; };
MemoryModel memory_model; MemoryModel memory_model = MemoryModel::Unexpanded;
bool isZX81; bool isZX81 = false;
}; };
} }

View File

@@ -68,6 +68,10 @@ template <class T> class MOS6560 {
set_output_mode(OutputMode::NTSC); set_output_mode(OutputMode::NTSC);
} }
~MOS6560() {
audio_queue_.flush();
}
void set_clock_rate(double clock_rate) { void set_clock_rate(double clock_rate) {
speaker_.set_input_rate(static_cast<float>(clock_rate / 4.0)); speaker_.set_input_rate(static_cast<float>(clock_rate / 4.0));
} }

View File

@@ -45,6 +45,7 @@ AsyncTaskQueue::AsyncTaskQueue()
AsyncTaskQueue::~AsyncTaskQueue() { AsyncTaskQueue::~AsyncTaskQueue() {
#ifdef __APPLE__ #ifdef __APPLE__
flush();
dispatch_release(serial_dispatch_queue_); dispatch_release(serial_dispatch_queue_);
serial_dispatch_queue_ = nullptr; serial_dispatch_queue_ = nullptr;
#else #else
@@ -82,6 +83,7 @@ void AsyncTaskQueue::flush() {
DeferringAsyncTaskQueue::~DeferringAsyncTaskQueue() { DeferringAsyncTaskQueue::~DeferringAsyncTaskQueue() {
perform(); perform();
flush();
} }
void DeferringAsyncTaskQueue::defer(std::function<void(void)> function) { void DeferringAsyncTaskQueue::defer(std::function<void(void)> function) {

View File

@@ -126,6 +126,10 @@ class AYDeferrer {
speaker_.set_input_rate(1000000); speaker_.set_input_rate(1000000);
} }
~AYDeferrer() {
audio_queue_.flush();
}
/// Adds @c half_cycles half cycles to the amount of time that has passed. /// Adds @c half_cycles half cycles to the amount of time that has passed.
inline void run_for(HalfCycles half_cycles) { inline void run_for(HalfCycles half_cycles) {
cycles_since_update_ += half_cycles; cycles_since_update_ += half_cycles;

View File

@@ -26,6 +26,10 @@ class Bus {
tia_sound_(audio_queue_), tia_sound_(audio_queue_),
speaker_(tia_sound_) {} speaker_(tia_sound_) {}
virtual ~Bus() {
audio_queue_.flush();
}
virtual void run_for(const Cycles cycles) = 0; virtual void run_for(const Cycles cycles) = 0;
virtual void apply_confidence(Analyser::Dynamic::ConfidenceCounter &confidence_counter) = 0; virtual void apply_confidence(Analyser::Dynamic::ConfidenceCounter &confidence_counter) = 0;
virtual void set_reset_line(bool state) = 0; virtual void set_reset_line(bool state) = 0;

View File

@@ -125,6 +125,10 @@ class ConcreteMachine:
joysticks_.emplace_back(new Joystick); joysticks_.emplace_back(new Joystick);
} }
~ConcreteMachine() {
audio_queue_.flush();
}
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override { std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
return joysticks_; return joysticks_;
} }

View File

@@ -61,6 +61,10 @@ class ConcreteMachine:
speaker_.set_input_rate(2000000 / SoundGenerator::clock_rate_divider); speaker_.set_input_rate(2000000 / SoundGenerator::clock_rate_divider);
} }
~ConcreteMachine() {
audio_queue_.flush();
}
void set_rom(ROMSlot slot, const std::vector<uint8_t> &data, bool is_writeable) override final { void set_rom(ROMSlot slot, const std::vector<uint8_t> &data, bool is_writeable) override final {
uint8_t *target = nullptr; uint8_t *target = nullptr;
switch(slot) { switch(slot) {

View File

@@ -144,6 +144,10 @@ class ConcreteMachine:
tape_player_.set_sleep_observer(this); tape_player_.set_sleep_observer(this);
} }
~ConcreteMachine() {
audio_queue_.flush();
}
void setup_output(float aspect_ratio) override { void setup_output(float aspect_ratio) override {
vdp_.reset(new TI::TMS9918(TI::TMS9918::TMS9918A)); vdp_.reset(new TI::TMS9918(TI::TMS9918::TMS9918A));
} }

View File

@@ -215,6 +215,10 @@ class ConcreteMachine:
Memory::Fuzz(ram_, sizeof(ram_)); Memory::Fuzz(ram_, sizeof(ram_));
} }
~ConcreteMachine() {
audio_queue_.flush();
}
// 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(

View File

@@ -76,6 +76,10 @@ template<bool is_zx81> class ConcreteMachine:
clear_all_keys(); clear_all_keys();
} }
~ConcreteMachine() {
audio_queue_.flush();
}
forceinline HalfCycles perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) { forceinline HalfCycles perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
const HalfCycles previous_counter = horizontal_counter_; const HalfCycles previous_counter = horizontal_counter_;
horizontal_counter_ += cycle.length; horizontal_counter_ += cycle.length;

View File

@@ -134,9 +134,9 @@ class ProcessorStorage {
uint8_t carry_result_; // the carry flag is set if bit 0 of carry_result_ is set uint8_t carry_result_; // the carry flag is set if bit 0 of carry_result_ is set
uint8_t halt_mask_ = 0xff; uint8_t halt_mask_ = 0xff;
int flag_adjustment_history_ = 0; // a shifting record of whether each opcode set any flags; it turns out unsigned int flag_adjustment_history_ = 0; // a shifting record of whether each opcode set any flags; it turns out
// that knowledge of what the last opcode did is necessary to get bits 5 & 3 // that knowledge of what the last opcode did is necessary to get bits 5 & 3
// correct for SCF and CCF. // correct for SCF and CCF.
HalfCycles number_of_cycles_; HalfCycles number_of_cycles_;

View File

@@ -56,7 +56,7 @@ std::map<std::size_t, Storage::Encodings::MFM::Sector> Storage::Encodings::MFM::
case 2: new_sector->address.sector = shifter.get_byte(); ++position; break; case 2: new_sector->address.sector = shifter.get_byte(); ++position; break;
case 3: case 3:
new_sector->size = shifter.get_byte(); new_sector->size = shifter.get_byte();
size = static_cast<std::size_t>(128 << new_sector->size); size = static_cast<std::size_t>(128 << (new_sector->size&7));
++position; ++position;
is_reading = false; is_reading = false;
shifter.set_should_obey_syncs(true); shifter.set_should_obey_syncs(true);