@@ -60,6 +60,9 @@ struct sound_struct {
6060 double iir_second_pass_output_history [2 ];
6161
6262 /* sn76489 state. */
63+ int is_write_enabled ;
64+ int had_write_disabled ;
65+ uint64_t prev_bus_change_ticks ;
6366 uint16_t counter [k_sound_num_channels ];
6467 uint8_t output [k_sound_num_channels ];
6568 uint16_t noise_rng ;
@@ -528,6 +531,11 @@ void
528531sound_power_on_reset (struct sound_struct * p_sound ) {
529532 uint32_t i ;
530533
534+ /* Mirrors initial IC32 state. */
535+ p_sound -> is_write_enabled = 1 ;
536+ p_sound -> had_write_disabled = 0 ;
537+ p_sound -> prev_bus_change_ticks = 0 ;
538+
531539 /* EMU: initial sn76489 state and behavior is something no two sources seem
532540 * to agree on. It doesn't matter a huge amount for BBC emulation because
533541 * MOS sets the sound channels up on boot. But the intial BBC power-on
@@ -674,11 +682,46 @@ sound_tick(struct sound_struct* p_sound, uint64_t curr_time_us) {
674682}
675683
676684void
677- sound_sn_write (struct sound_struct * p_sound , uint8_t value ) {
685+ sound_sn_IC32_updated (struct sound_struct * p_sound , uint8_t value ) {
686+ int is_write_enabled = !(value & 1 );
687+ if (is_write_enabled == p_sound -> is_write_enabled ) {
688+ return ;
689+ }
690+
691+ p_sound -> is_write_enabled = is_write_enabled ;
692+ if (!is_write_enabled ) {
693+ p_sound -> had_write_disabled = 1 ;
694+ p_sound -> prev_bus_change_ticks = 0 ;
695+ }
696+ }
697+
698+ void
699+ sound_sn_set_bus_value (struct sound_struct * p_sound , uint8_t value ) {
678700 uint8_t command ;
679701 uint8_t channel ;
702+ int32_t new_period ;
703+ uint64_t ticks ;
704+ uint64_t prev_bus_change_ticks ;
705+
706+ if (!p_sound -> is_write_enabled ) {
707+ return ;
708+ }
709+
710+ ticks = timing_get_scaled_total_timer_ticks (p_sound -> p_timing );
711+ prev_bus_change_ticks = p_sound -> prev_bus_change_ticks ;
712+ if ((prev_bus_change_ticks != 0 ) && p_sound -> had_write_disabled ) {
713+ uint64_t delta = (ticks - prev_bus_change_ticks );
714+ if ((delta % 32 ) != 0 ) {
715+ log_do_log (k_log_audio ,
716+ k_log_warning ,
717+ "bad bus timing for multiple writes: %" PRIu64 ", value $%.2X" ,
718+ delta ,
719+ value );
720+ }
721+ }
722+ p_sound -> prev_bus_change_ticks = ticks ;
680723
681- int32_t new_period = -1 ;
724+ new_period = -1 ;
682725
683726 if (sound_is_active (p_sound ) && p_sound -> synchronous ) {
684727 sound_advance_sn_timing (p_sound );
0 commit comments