Fixed a bug where channels 1 and 2 would start playing earlier than they should have if NRx4 was written to twice. Fixes #86.

This commit is contained in:
Lior Halphon 2018-10-29 00:44:43 +02:00
parent 9ffeef88d5
commit 64922fff4b
2 changed files with 7 additions and 1 deletions

View File

@ -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;

View File

@ -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