mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-04 14:30:19 +00:00
Uses GI::AY38910::Utility
far and wide.
This commit is contained in:
parent
53ba0e67d1
commit
8a11a5832c
@ -169,19 +169,21 @@ template <bool is_stereo> class AY38910: public ::Outputs::Speaker::SampleSource
|
|||||||
AY-deploying machines of the era.
|
AY-deploying machines of the era.
|
||||||
*/
|
*/
|
||||||
struct Utility {
|
struct Utility {
|
||||||
template <typename AY> static void select_register(AY &ay, uint8_t reg) {
|
template <typename AY> static void write(AY &ay, bool is_data_write, uint8_t data) {
|
||||||
ay.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BDIR | GI::AY38910::BC2 | GI::AY38910::BC1));
|
ay.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BDIR | GI::AY38910::BC2 | (is_data_write ? 0 : GI::AY38910::BC1)));
|
||||||
ay.set_data_input(reg);
|
ay.set_data_input(data);
|
||||||
ay.set_control_lines(GI::AY38910::ControlLines(0));
|
ay.set_control_lines(GI::AY38910::ControlLines(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename AY> static void select_register(AY &ay, uint8_t reg) {
|
||||||
|
write(ay, false, reg);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename AY> static void write_data(AY &ay, uint8_t reg) {
|
template <typename AY> static void write_data(AY &ay, uint8_t reg) {
|
||||||
ay.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BDIR | GI::AY38910::BC2));
|
write(ay, true, reg);
|
||||||
ay.set_data_input(reg);
|
|
||||||
ay.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename AY> static uint8_t read_data(AY &ay) {
|
template <typename AY> static uint8_t read(AY &ay) {
|
||||||
ay.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BC2 | GI::AY38910::BC1));
|
ay.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BC2 | GI::AY38910::BC1));
|
||||||
const uint8_t result = ay.get_data_output();
|
const uint8_t result = ay.get_data_output();
|
||||||
ay.set_control_lines(GI::AY38910::ControlLines(0));
|
ay.set_control_lines(GI::AY38910::ControlLines(0));
|
||||||
|
@ -347,18 +347,11 @@ class ConcreteMachine:
|
|||||||
update_audio();
|
update_audio();
|
||||||
|
|
||||||
if(cycle.operation & Microcycle::Read) {
|
if(cycle.operation & Microcycle::Read) {
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BC2 | GI::AY38910::BC1));
|
cycle.set_value8_high(GI::AY38910::Utility::read(ay_));
|
||||||
cycle.set_value8_high(ay_.get_data_output());
|
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
} else {
|
} else {
|
||||||
// Net effect here: addresses with bit 1 set write to a register,
|
// Net effect here: addresses with bit 1 set write to a register,
|
||||||
// addresses with bit 1 clear select a register.
|
// addresses with bit 1 clear select a register.
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(
|
GI::AY38910::Utility::write(ay_, address&2, cycle.value8_high());
|
||||||
GI::AY38910::BC2 | GI::AY38910::BDIR
|
|
||||||
| ((address&2) ? 0 : GI::AY38910::BC1)
|
|
||||||
));
|
|
||||||
ay_.set_data_input(cycle.value8_high());
|
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
}
|
}
|
||||||
return delay + HalfCycles(2);
|
return delay + HalfCycles(2);
|
||||||
|
|
||||||
|
@ -287,9 +287,7 @@ class ConcreteMachine:
|
|||||||
case 0x52:
|
case 0x52:
|
||||||
// Read AY data.
|
// Read AY data.
|
||||||
update_audio();
|
update_audio();
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BC2 | GI::AY38910::BC1));
|
*cycle.value = GI::AY38910::Utility::read(ay_);
|
||||||
*cycle.value = ay_.get_data_output();
|
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -324,16 +322,12 @@ class ConcreteMachine:
|
|||||||
case 0x50:
|
case 0x50:
|
||||||
// Set AY address.
|
// Set AY address.
|
||||||
update_audio();
|
update_audio();
|
||||||
ay_.set_control_lines(GI::AY38910::BC1);
|
GI::AY38910::Utility::select_register(ay_, *cycle.value);
|
||||||
ay_.set_data_input(*cycle.value);
|
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
break;
|
break;
|
||||||
case 0x51:
|
case 0x51:
|
||||||
// Set AY data.
|
// Set AY data.
|
||||||
update_audio();
|
update_audio();
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BC2 | GI::AY38910::BDIR));
|
GI::AY38910::Utility::write_data(ay_, *cycle.value);
|
||||||
ay_.set_data_input(*cycle.value);
|
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
break;
|
break;
|
||||||
case 0x53:
|
case 0x53:
|
||||||
super_game_module_.replace_ram = !!((*cycle.value)&0x1);
|
super_game_module_.replace_ram = !!((*cycle.value)&0x1);
|
||||||
|
@ -525,9 +525,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
case 0xa2:
|
case 0xa2:
|
||||||
update_audio();
|
update_audio();
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BC2 | GI::AY38910::BC1));
|
*cycle.value = GI::AY38910::Utility::read(ay_);
|
||||||
*cycle.value = ay_.get_data_output();
|
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xa8: case 0xa9:
|
case 0xa8: case 0xa9:
|
||||||
@ -552,9 +550,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
case 0xa0: case 0xa1:
|
case 0xa0: case 0xa1:
|
||||||
update_audio();
|
update_audio();
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BDIR | GI::AY38910::BC2 | ((port == 0xa0) ? GI::AY38910::BC1 : 0)));
|
GI::AY38910::Utility::write(ay_, port == 0xa1, *cycle.value);
|
||||||
ay_.set_data_input(*cycle.value);
|
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xa8: case 0xa9:
|
case 0xa8: case 0xa9:
|
||||||
|
@ -472,22 +472,15 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
HalfCycles time_since_ay_update_;
|
HalfCycles time_since_ay_update_;
|
||||||
inline void ay_set_register(uint8_t value) {
|
inline void ay_set_register(uint8_t value) {
|
||||||
update_audio();
|
update_audio();
|
||||||
ay_.set_control_lines(GI::AY38910::BC1);
|
GI::AY38910::Utility::select_register(ay_, value);
|
||||||
ay_.set_data_input(value);
|
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
}
|
}
|
||||||
inline void ay_set_data(uint8_t value) {
|
inline void ay_set_data(uint8_t value) {
|
||||||
update_audio();
|
update_audio();
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BC2 | GI::AY38910::BDIR));
|
GI::AY38910::Utility::write_data(ay_, value);
|
||||||
ay_.set_data_input(value);
|
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
}
|
}
|
||||||
inline uint8_t ay_read_data() {
|
inline uint8_t ay_read_data() {
|
||||||
update_audio();
|
update_audio();
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(GI::AY38910::BC2 | GI::AY38910::BC1));
|
return GI::AY38910::Utility::read(ay_);
|
||||||
const uint8_t value = ay_.get_data_output();
|
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
inline void update_audio() {
|
inline void update_audio() {
|
||||||
speaker_.run_for(audio_queue_, time_since_ay_update_.divide_cycles(Cycles(2)));
|
speaker_.run_for(audio_queue_, time_since_ay_update_.divide_cycles(Cycles(2)));
|
||||||
|
@ -336,7 +336,7 @@ template<Model model> class ConcreteMachine:
|
|||||||
if((address & 0xc002) == 0xc000) {
|
if((address & 0xc002) == 0xc000) {
|
||||||
// Read from AY register.
|
// Read from AY register.
|
||||||
update_audio();
|
update_audio();
|
||||||
*cycle.value &= GI::AY38910::Utility::read_data(ay_);
|
*cycle.value &= GI::AY38910::Utility::read(ay_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for a floating bus read; these are particularly arcane
|
// Check for a floating bus read; these are particularly arcane
|
||||||
|
Loading…
x
Reference in New Issue
Block a user