Skip to content

Commit 416aa90

Browse files
Chris EvansChris Evans
authored andcommitted
Report dubious SN76489 write timings when write enable left on.
Useful for developing an advanced sampled sound player that must use cycle accurate timings.
1 parent d7e6552 commit 416aa90

4 files changed

Lines changed: 57 additions & 12 deletions

File tree

bbc.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2658,15 +2658,18 @@ bbc_set_IC32(struct bbc_struct* p_bbc, uint8_t val) {
26582658
* Changing this selection requires various notifications.
26592659
*/
26602660

2661-
/* Selecting or deselecting the keyboard may need to change interrupt and / or
2662-
* bus value status.
2663-
*/
2664-
via_update_port_a(p_bbc->p_system_via);
2665-
26662661
/* The video ULA needs to know about changes to the video wrap-around
26672662
* address.
26682663
*/
26692664
video_IC32_updated(p_bbc->p_video, val);
2665+
2666+
/* The SN76489 needs to see if its write enable line changed. */
2667+
sound_sn_IC32_updated(p_bbc->p_sound, val);
2668+
2669+
/* Selecting or deselecting the keyboard may need to change interrupt and / or
2670+
* bus value status.
2671+
*/
2672+
via_update_port_a(p_bbc->p_system_via);
26702673
}
26712674

26722675
uint8_t*

sound.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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
528531
sound_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

676684
void
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);

sound.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ void sound_set_state(struct sound_struct* p_sound,
4343
uint8_t noise_frequency,
4444
uint16_t noise_rng);
4545

46-
void sound_sn_write(struct sound_struct* p_sound, uint8_t data);
46+
void sound_sn_IC32_updated(struct sound_struct* p_sound, uint8_t value);
47+
void sound_sn_set_bus_value(struct sound_struct* p_sound, uint8_t value);
4748

4849
#endif /* BEEBJIT_SOUND_H */

via.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ sysvia_update_port_a(struct via_struct* p_via) {
474474
struct bbc_struct* p_bbc = p_via->p_bbc;
475475
struct keyboard_struct* p_keyboard = bbc_get_keyboard(p_bbc);
476476
struct cmos_struct* p_cmos = bbc_get_cmos(p_bbc);
477+
struct sound_struct* p_sound = bbc_get_sound(p_bbc);
477478
int fire = 0;
478479
uint8_t IC32 = bbc_get_IC32(p_bbc);
479480
uint8_t peripheral_a = 0xFF;
@@ -511,10 +512,7 @@ sysvia_update_port_a(struct via_struct* p_via) {
511512

512513
via_set_CA2(p_via, fire);
513514

514-
if (!(IC32 & 1)) {
515-
struct sound_struct* p_sound = bbc_get_sound(p_via->p_bbc);
516-
sound_sn_write(p_sound, bus_val);
517-
}
515+
sound_sn_set_bus_value(p_sound, bus_val);
518516

519517
p_via->bus_value_a = bus_val;
520518
}

0 commit comments

Comments
 (0)