Skip to content

Commit 78a6f39

Browse files
committed
More accurate emulation of background counting
1 parent fe1e250 commit 78a6f39

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

Core/apu.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,12 +1049,6 @@ restart:;
10491049
}
10501050
step_lfsr(gb, cycles - cycles_left);
10511051
}
1052-
if (divisor != 2) {
1053-
gb->apu.noise_background_counter_active = false;
1054-
if (unlikely(!gb->apu.noise_counter_active)) {
1055-
break;
1056-
}
1057-
}
10581052
}
10591053
if (cycles_left) {
10601054
if (likely(gb->apu.noise_counter_active || gb->apu.noise_background_counter_active)) {
@@ -1227,9 +1221,11 @@ static void prepare_noise_start(GB_gameboy_t *gb)
12271221
parameters. It is neither 0 or the equaly unexplained 0x0055.
12281222
*/
12291223
gb->apu.noise_counter_active = gb->io_registers[GB_IO_NR42] & 0xF8; // Resets on APU off and DAC disable
1224+
bool was_started_with_dac_disabled = gb->apu.noise_started_with_dac_disabled;
1225+
gb->apu.noise_started_with_dac_disabled = !gb->apu.noise_counter_active;
12301226
unsigned divisor = (gb->io_registers[GB_IO_NR43] & 0x07);
12311227
bool was_background_counting = gb->apu.noise_background_counter_active;
1232-
gb->apu.noise_background_counter_active = divisor == 0;
1228+
gb->apu.noise_background_counter_active = true;
12331229
bool instant_step = false;
12341230
bool div_1_glitch = false;
12351231

@@ -1316,6 +1312,26 @@ static void prepare_noise_start(GB_gameboy_t *gb)
13161312
}
13171313
}
13181314

1315+
/* Background counting glitches */
1316+
/* TODO: Double speed mode not tested */
1317+
if (divisor > 1) {
1318+
if (!gb->apu.noise_counter_active && !(gb->apu.noise_channel.alignment & 3)) {
1319+
gb->apu.noise_channel.counter_countdown += 4;
1320+
}
1321+
}
1322+
else {
1323+
if (was_background_counting && !gb->apu.is_active[GB_NOISE] && !(gb->apu.noise_channel.alignment & 3)) {
1324+
if (divisor == 0) {
1325+
if (was_started_with_dac_disabled) { // TODO: Why is it different?
1326+
gb->apu.noise_channel.counter_countdown += 28;
1327+
}
1328+
}
1329+
else {
1330+
gb->apu.noise_channel.counter_countdown -= 4;
1331+
}
1332+
}
1333+
}
1334+
13191335
/* TODO: This is weird, is the clock going out of sync? */
13201336
if (!divisor && gb->model <= GB_MODEL_CGB_C && was_background_counting && !gb->apu.is_active[GB_NOISE] && gb->cgb_double_speed) {
13211337
gb->apu.noise_channel.counter_countdown--;
@@ -2033,6 +2049,13 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value)
20332049
case GB_IO_NR42: {
20342050
if ((value & 0xF8) == 0) {
20352051
/* This disables the DAC */
2052+
if (gb->apu.is_active[GB_NOISE] && gb->io_registers[GB_IO_NR43] & 7) {
2053+
if (gb->apu.noise_channel.counter_countdown <= 2) {
2054+
gb->apu.noise_channel.counter++;
2055+
}
2056+
gb->apu.noise_background_counter_active = false;
2057+
}
2058+
20362059
gb->io_registers[reg] = value;
20372060
gb->apu.is_active[GB_NOISE] = false;
20382061
update_sample(gb, GB_NOISE, 0, 0);

Core/apu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,13 @@ typedef struct
153153

154154
bool apu_cycles_in_2mhz; // For compatibility with 0.16.x save states
155155
bool pending_envelope_tick;
156+
156157
// Move to noise struct when breaking compat
157158
bool noise_counter_active;
158159
bool noise_background_counter_active;
159160
bool lfsr_stepped_in_narrow;
160161
bool lfsr_bit_7_before_step; // Used by some corruptions?
162+
bool noise_started_with_dac_disabled; // TODO: Background counting behaves slightly different this way?
161163
} GB_apu_t;
162164

163165
typedef enum {

0 commit comments

Comments
 (0)