From 51bdac27ae5162303025e5cc73173d2e4c5c5144 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 15 Oct 2016 17:45:39 -0400 Subject: [PATCH] Made some AY advances; it's now being polled for samples and collecting more information on what it needs to output. --- Components/AY38910/AY38910.cpp | 37 ++++++++++++++++++++++++++++++++++ Components/AY38910/AY38910.hpp | 5 ++++- Machines/Oric/Oric.cpp | 2 ++ Machines/Oric/Oric.hpp | 14 +++++++++++-- 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/Components/AY38910/AY38910.cpp b/Components/AY38910/AY38910.cpp index 04be00902..313a3391c 100644 --- a/Components/AY38910/AY38910.cpp +++ b/Components/AY38910/AY38910.cpp @@ -14,8 +14,18 @@ AY38910::AY38910() : _selected_register(0) { } +void AY38910::set_clock_rate(double clock_rate) +{ + set_input_rate((float)clock_rate); +} + void AY38910::get_samples(unsigned int number_of_samples, int16_t *target) { + printf("%d\n", number_of_samples); + for(int c = 0; c < number_of_samples; c++) + { + *target++ = (c & 64) * 64; + } } void AY38910::skip_samples(unsigned int number_of_samples) @@ -30,6 +40,33 @@ void AY38910::select_register(uint8_t r) void AY38910::set_register_value(uint8_t value) { _registers[_selected_register] = value; + if(value < 14) + { + int selected_register = _selected_register; + enqueue([=] () { + _output_registers[selected_register] = value; + switch(selected_register) + { + case 0: case 2: case 4: + _tone_generator_controls[selected_register >> 1] = + (_tone_generator_controls[selected_register >> 1] & ~0xff) | value; + break; + + case 1: case 3: case 5: + _tone_generator_controls[selected_register >> 1] = + (_tone_generator_controls[selected_register >> 1] & 0xff) | (uint16_t)((value&0xf) << 8); + break; + + case 11: + _envelope_period = (_envelope_period & ~0xff) | value; + break; + + case 12: + _envelope_period = (_envelope_period & 0xff) | (uint16_t)(value << 8); + break; + } + }); + } } uint8_t AY38910::get_register_value() diff --git a/Components/AY38910/AY38910.hpp b/Components/AY38910/AY38910.hpp index b71eb3bde..888a3763a 100644 --- a/Components/AY38910/AY38910.hpp +++ b/Components/AY38910/AY38910.hpp @@ -16,6 +16,7 @@ namespace GI { class AY38910: public ::Outputs::Filter { public: AY38910(); + void set_clock_rate(double clock_rate); void get_samples(unsigned int number_of_samples, int16_t *target); void skip_samples(unsigned int number_of_samples); @@ -28,8 +29,10 @@ class AY38910: public ::Outputs::Filter { private: int _selected_register; - uint8_t _registers[16]; + uint8_t _registers[16], _output_registers[16]; + uint16_t _tone_generator_controls[3]; + uint16_t _envelope_period; }; }; diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index bfa0bf06a..4a5cc855c 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -73,11 +73,13 @@ void Machine::setup_output(float aspect_ratio) { _videoOutput.reset(new VideoOutput(_ram)); _via.ay8910.reset(new GI::AY38910()); + _via.ay8910->set_clock_rate(1000000); } void Machine::close_output() { _videoOutput.reset(); + _via.ay8910.reset(); } void Machine::mos6522_did_change_interrupt_status(void *mos6522) diff --git a/Machines/Oric/Oric.hpp b/Machines/Oric/Oric.hpp index af9ce4a47..c7315fb81 100644 --- a/Machines/Oric/Oric.hpp +++ b/Machines/Oric/Oric.hpp @@ -22,6 +22,7 @@ #include #include +#include namespace Oric { @@ -70,7 +71,7 @@ class Machine: virtual void setup_output(float aspect_ratio); virtual void close_output(); virtual std::shared_ptr get_crt() { return _videoOutput->get_crt(); } - virtual std::shared_ptr get_speaker() { return nullptr; } + virtual std::shared_ptr get_speaker() { return _via.ay8910; } virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor::run_for_cycles(number_of_cycles); } // to satisfy MOS::MOS6522IRQDelegate::Delegate @@ -128,12 +129,20 @@ class Machine: } } - std::unique_ptr ay8910; + inline void run_for_half_cycles(unsigned int number_of_cycles) + { + _half_cycles_since_ay_update += number_of_cycles; + MOS::MOS6522::run_for_half_cycles(number_of_cycles); + } + + std::shared_ptr ay8910; std::shared_ptr keyboard; private: void update_ay() { + ay8910->run_for_cycles(_half_cycles_since_ay_update >> 1); + _half_cycles_since_ay_update &= 1; if(_ay_bdir) { if(_ay_bc1) ay8910->select_register(_port_a_output); @@ -146,6 +155,7 @@ class Machine: } uint8_t _port_a_output, _port_a_input; bool _ay_bdir, _ay_bc1; + unsigned int _half_cycles_since_ay_update; }; VIA _via; std::shared_ptr _keyboard;