The volume envelope is delayed on CGB-D and CGB-E in double speed mode

This commit is contained in:
Lior Halphon
2025-10-14 15:31:31 +03:00
parent 421fd132e3
commit ed8c952995
3 changed files with 42 additions and 12 deletions
+37 -12
View File
@@ -630,7 +630,27 @@ static void trigger_sweep_calculation(GB_gameboy_t *gb)
}
}
void GB_apu_div_event(GB_gameboy_t *gb)
noinline void GB_apu_delayed_envelope_tick(GB_gameboy_t *gb)
{
gb->apu.pending_envelope_tick = false;
if (!gb->apu.global_enable) return;
GB_apu_run(gb, true);
gb->apu.pcm_mask[0] = gb->apu.pcm_mask[1] = 0xFF;
unrolled for (unsigned i = GB_SQUARE_1; i <= GB_SQUARE_2; i++) {
if (gb->apu.square_channels[i].envelope_clock.clock) {
tick_square_envelope(gb, i);
}
}
if (gb->apu.noise_channel.envelope_clock.clock) {
tick_noise_envelope(gb);
}
}
noinline void GB_apu_div_event(GB_gameboy_t *gb)
{
GB_apu_run(gb, true);
gb->apu.pcm_mask[0] = gb->apu.pcm_mask[1] = 0xFF;
@@ -648,7 +668,7 @@ void GB_apu_div_event(GB_gameboy_t *gb)
}
if ((gb->apu.div_divider & 7) == 7) {
unrolled for (unsigned i = GB_SQUARE_2 + 1; i--;) {
unrolled for (unsigned i = GB_SQUARE_1; i <= GB_SQUARE_2; i++) {
if (!gb->apu.square_channels[i].envelope_clock.clock) {
gb->apu.square_channels[i].volume_countdown--;
gb->apu.square_channels[i].volume_countdown &= 7;
@@ -660,18 +680,23 @@ void GB_apu_div_event(GB_gameboy_t *gb)
}
}
unrolled for (unsigned i = GB_SQUARE_2 + 1; i--;) {
if (gb->apu.square_channels[i].envelope_clock.clock) {
tick_square_envelope(gb, i);
if (gb->cgb_double_speed && (gb->model == GB_MODEL_CGB_D || gb->model == GB_MODEL_CGB_E)) {
gb->apu.pending_envelope_tick = true;
}
else {
unrolled for (unsigned i = GB_SQUARE_1; i <= GB_SQUARE_2; i++) {
if (gb->apu.square_channels[i].envelope_clock.clock) {
tick_square_envelope(gb, i);
}
}
if (gb->apu.noise_channel.envelope_clock.clock) {
tick_noise_envelope(gb);
}
}
if (gb->apu.noise_channel.envelope_clock.clock) {
tick_noise_envelope(gb);
}
if ((gb->apu.div_divider & 1) == 1) {
unrolled for (unsigned i = GB_SQUARE_2 + 1; i--;) {
unrolled for (unsigned i = GB_SQUARE_1; i <= GB_SQUARE_2; i++) {
if (gb->apu.square_channels[i].length_enabled) {
if (gb->apu.square_channels[i].pulse_length) {
if (!--gb->apu.square_channels[i].pulse_length) {
@@ -718,13 +743,13 @@ void GB_apu_div_event(GB_gameboy_t *gb)
}
}
void GB_apu_div_secondary_event(GB_gameboy_t *gb)
noinline void GB_apu_div_secondary_event(GB_gameboy_t *gb)
{
GB_apu_run(gb, true);
gb->apu.pcm_mask[0] = gb->apu.pcm_mask[1] = 0xFF;
if (!gb->apu.global_enable) return;
unrolled for (unsigned i = GB_SQUARE_2 + 1; i--;) {
unrolled for (unsigned i = GB_SQUARE_1; i <= GB_SQUARE_2; i++) {
uint8_t nrx2 = gb->io_registers[i == GB_SQUARE_1? GB_IO_NR12 : GB_IO_NR22];
if (gb->apu.is_active[i] && gb->apu.square_channels[i].volume_countdown == 0) {
set_envelope_clock(&gb->apu.square_channels[i].envelope_clock,
+2
View File
@@ -152,6 +152,7 @@ typedef struct
uint8_t pcm_mask[2]; // For CGB-0 to CGB-C PCM read glitch
bool apu_cycles_in_2mhz; // For compatibility with 0.16.x save states
bool pending_envelope_tick;
} GB_apu_t;
typedef enum {
@@ -230,6 +231,7 @@ internal void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value);
internal uint8_t GB_apu_read(GB_gameboy_t *gb, uint8_t reg);
internal void GB_apu_div_event(GB_gameboy_t *gb);
internal void GB_apu_div_secondary_event(GB_gameboy_t *gb);
internal void GB_apu_delayed_envelope_tick(GB_gameboy_t *gb);
internal void GB_apu_init(GB_gameboy_t *gb);
internal void GB_apu_run(GB_gameboy_t *gb, bool force);
#endif
+3
View File
@@ -279,6 +279,9 @@ static void timers_run(GB_gameboy_t *gb, uint8_t cycles)
gb->apu.apu_cycles += 1 << !gb->cgb_double_speed;
gb->apu_output.sample_cycles += (gb->apu_output.sample_rate << !gb->cgb_double_speed) << 1;
GB_SLEEP(gb, div, 2, 4);
if (unlikely(gb->apu.pending_envelope_tick)) {
GB_apu_delayed_envelope_tick(gb);
}
}
}