Emulate the delayed NR44 write on the DMG
This commit is contained in:
parent
6b30de5fb1
commit
dffc12331b
24
Core/apu.c
24
Core/apu.c
@ -451,6 +451,22 @@ void GB_apu_run(GB_gameboy_t *gb)
|
||||
uint8_t cycles = gb->apu.apu_cycles >> 2;
|
||||
gb->apu.apu_cycles = 0;
|
||||
if (!cycles) return;
|
||||
bool start_ch4 = false;
|
||||
if (gb->apu.channel_4_dmg_delayed_start) {
|
||||
if (gb->apu.channel_4_dmg_delayed_start == cycles) {
|
||||
gb->apu.channel_4_dmg_delayed_start = 0;
|
||||
start_ch4 = true;
|
||||
}
|
||||
else if (gb->apu.channel_4_dmg_delayed_start > cycles) {
|
||||
gb->apu.channel_4_dmg_delayed_start -= cycles;
|
||||
}
|
||||
else {
|
||||
/* Split it into two */
|
||||
cycles -= gb->apu.channel_4_dmg_delayed_start;
|
||||
gb->apu.apu_cycles = gb->apu.channel_4_dmg_delayed_start * 2;
|
||||
GB_apu_run(gb);
|
||||
}
|
||||
}
|
||||
|
||||
if (likely(!gb->stopped || GB_is_cgb(gb))) {
|
||||
/* To align the square signal to 1MHz */
|
||||
@ -572,6 +588,9 @@ void GB_apu_run(GB_gameboy_t *gb)
|
||||
render(gb);
|
||||
}
|
||||
}
|
||||
if (start_ch4) {
|
||||
GB_apu_write(gb, GB_IO_NR44, gb->io_registers[GB_IO_NR44] | 0x80);
|
||||
}
|
||||
}
|
||||
void GB_apu_init(GB_gameboy_t *gb)
|
||||
{
|
||||
@ -978,6 +997,10 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value)
|
||||
|
||||
case GB_IO_NR44: {
|
||||
if (value & 0x80) {
|
||||
if (!GB_is_cgb(gb) && (gb->apu.noise_channel.alignment & 3) != 0) {
|
||||
gb->apu.channel_4_dmg_delayed_start = 6;
|
||||
}
|
||||
else {
|
||||
unsigned divisor = (gb->io_registers[GB_IO_NR43] & 0x07) << 2;
|
||||
if (!divisor) divisor = 2;
|
||||
gb->apu.channel_4_delta = 0;
|
||||
@ -1023,6 +1046,7 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value)
|
||||
gb->apu.noise_channel.length_enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* APU glitch - if length is enabled while the DIV-divider's LSB is 1, tick the length once. */
|
||||
if ((value & 0x40) &&
|
||||
|
Loading…
Reference in New Issue
Block a user