diff --git a/Components/AY38910/AY38910.cpp b/Components/AY38910/AY38910.cpp index 7756cf908..239b8785d 100644 --- a/Components/AY38910/AY38910.cpp +++ b/Components/AY38910/AY38910.cpp @@ -108,3 +108,41 @@ uint8_t AY38910::get_port_output(bool port_b) { return _registers[port_b ? 15 : 14]; } + +void AY38910::set_data_input(uint8_t r) +{ + _data_input = r; +} + +uint8_t AY38910::get_data_output() +{ + return _data_output; +} + +void AY38910::set_control_lines(ControlLines control_lines) +{ + ControlState new_state; + switch((int)control_lines) + { + default: new_state = Inactive; break; + + case (int)(BCDIR | BC2 | BC1): + case BCDIR: + case BC1: new_state = LatchAddress; break; + + case (int)(BC2 | BC1): new_state = Read; break; + case (int)(BCDIR | BC2): new_state = Write; break; + } + + if(new_state != _control_state) + { + _control_state = new_state; + switch(new_state) + { + default: break; + case LatchAddress: select_register(_data_input); break; + case Write: set_register_value(_data_input); break; + case Read: _data_output = get_register_value(); break; + } + } +} diff --git a/Components/AY38910/AY38910.hpp b/Components/AY38910/AY38910.hpp index 3f0348982..49080a482 100644 --- a/Components/AY38910/AY38910.hpp +++ b/Components/AY38910/AY38910.hpp @@ -21,9 +21,14 @@ class AY38910: public ::Outputs::Filter { void get_samples(unsigned int number_of_samples, int16_t *target); void skip_samples(unsigned int number_of_samples); - void select_register(uint8_t r); - void set_register_value(uint8_t value); - uint8_t get_register_value(); + enum ControlLines { + BC1 = (1 << 0), + BC2 = (1 << 1), + BCDIR = (1 << 2) + }; + void set_data_input(uint8_t r); + uint8_t get_data_output(); + void set_control_lines(ControlLines control_lines); uint8_t get_port_output(bool port_b); @@ -39,6 +44,19 @@ class AY38910: public ::Outputs::Filter { int _envelope_divider; int _evelope_volume; int _channel_ouput[3]; + + enum ControlState { + Inactive, + LatchAddress, + Read, + Write + } _control_state; + + void select_register(uint8_t r); + void set_register_value(uint8_t value); + uint8_t get_register_value(); + + uint8_t _data_input, _data_output; }; }; diff --git a/Machines/Oric/Oric.hpp b/Machines/Oric/Oric.hpp index 06dfc3f2d..5c3167602 100644 --- a/Machines/Oric/Oric.hpp +++ b/Machines/Oric/Oric.hpp @@ -119,8 +119,7 @@ class Machine: } else { - _port_a_output = value; - update_ay(); + ay8910->set_data_input(value); } } @@ -132,7 +131,7 @@ class Machine: } else { - return _port_a_input; + return ay8910->get_data_output(); } } @@ -152,18 +151,8 @@ class Machine: 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); - else ay8910->set_register_value(_port_a_output); - } - else - { - if(_ay_bc1) _port_a_input = ay8910->get_register_value(); - } + ay8910->set_control_lines( (GI::AY38910::ControlLines)((_ay_bdir ? GI::AY38910::BCDIR : 0) | (_ay_bc1 ? GI::AY38910::BC1 : 0) | GI::AY38910::BC2)); } - uint8_t _port_a_output, _port_a_input; bool _ay_bdir, _ay_bc1; unsigned int _half_cycles_since_ay_update; };