From 64922fff4b0200c17b4933f3b5f73ed73fd79f22 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Mon, 29 Oct 2018 00:44:43 +0200 Subject: [PATCH] Fixed a bug where channels 1 and 2 would start playing earlier than they should have if NRx4 was written to twice. Fixes #86. --- Core/apu.c | 4 ++++ Core/apu.h | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Core/apu.c b/Core/apu.c index 1bdc275..ff1cb5c 100644 --- a/Core/apu.c +++ b/Core/apu.c @@ -172,6 +172,8 @@ static uint16_t new_sweep_sample_legnth(GB_gameboy_t *gb) static void update_square_sample(GB_gameboy_t *gb, unsigned index) { + if (gb->apu.square_channels[index].current_sample_index & 0x80) return; + uint8_t duty = gb->io_registers[index == GB_SQUARE_1? GB_IO_NR11 :GB_IO_NR21] >> 6; update_sample(gb, index, duties[gb->apu.square_channels[index].current_sample_index + duty * 8]? @@ -701,6 +703,8 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value) if ((gb->io_registers[index == GB_SQUARE_1 ? GB_IO_NR12 : GB_IO_NR22] & 0xF8) != 0 && !gb->apu.is_active[index]) { gb->apu.is_active[index] = true; update_sample(gb, index, 0, 0); + /* We use the highest bit in current_sample_index to mark this sample is not actually playing yet, */ + gb->apu.square_channels[index].current_sample_index |= 0x80; } if (gb->apu.square_channels[index].pulse_length == 0) { gb->apu.square_channels[index].pulse_length = 0x40; diff --git a/Core/apu.h b/Core/apu.h index baa56a4..01ca132 100644 --- a/Core/apu.h +++ b/Core/apu.h @@ -75,7 +75,9 @@ typedef struct uint16_t pulse_length; // Reloaded from NRX1 (xorred), in 256Hz DIV ticks uint8_t current_volume; // Reloaded from NRX2 uint8_t volume_countdown; // Reloaded from NRX2 - uint8_t current_sample_index; + uint8_t current_sample_index; /* For save state compatibility, + highest bit is reused (See NR14/NR24's + write code)*/ uint16_t sample_countdown; // in APU ticks (Reloaded from sample_length, xorred $7FF) uint16_t sample_length; // From NRX3, NRX4, in APU ticks