mirror of https://github.com/bsnes-emu/bsnes.git
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;
|
uint8_t cycles = gb->apu.apu_cycles >> 2;
|
||||||
gb->apu.apu_cycles = 0;
|
gb->apu.apu_cycles = 0;
|
||||||
if (!cycles) return;
|
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))) {
|
if (likely(!gb->stopped || GB_is_cgb(gb))) {
|
||||||
/* To align the square signal to 1MHz */
|
/* To align the square signal to 1MHz */
|
||||||
|
@ -572,6 +588,9 @@ void GB_apu_run(GB_gameboy_t *gb)
|
||||||
render(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)
|
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: {
|
case GB_IO_NR44: {
|
||||||
if (value & 0x80) {
|
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;
|
unsigned divisor = (gb->io_registers[GB_IO_NR43] & 0x07) << 2;
|
||||||
if (!divisor) divisor = 2;
|
if (!divisor) divisor = 2;
|
||||||
gb->apu.channel_4_delta = 0;
|
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;
|
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. */
|
/* APU glitch - if length is enabled while the DIV-divider's LSB is 1, tick the length once. */
|
||||||
if ((value & 0x40) &&
|
if ((value & 0x40) &&
|
||||||
|
|
Loading…
Reference in New Issue