APU glitch: When turning the APU on while DIV's bit 4 (or 5 in double speed mode), the first DIV/APU event is skipped.
This commit is contained in:
parent
593cb7c107
commit
f64da1864f
@ -181,6 +181,10 @@ static void nrx2_glitch(uint8_t *volume, uint8_t value, uint8_t old_value)
|
|||||||
void GB_apu_div_event(GB_gameboy_t *gb)
|
void GB_apu_div_event(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
if (!gb->apu.global_enable) return;
|
if (!gb->apu.global_enable) return;
|
||||||
|
if (gb->apu.skip_div_event) {
|
||||||
|
gb->apu.skip_div_event = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
gb->apu.div_divider++;
|
gb->apu.div_divider++;
|
||||||
|
|
||||||
if ((gb->apu.div_divider & 7) == 0) {
|
if ((gb->apu.div_divider & 7) == 0) {
|
||||||
@ -426,6 +430,11 @@ void GB_apu_init(GB_gameboy_t *gb)
|
|||||||
{
|
{
|
||||||
memset(&gb->apu, 0, sizeof(gb->apu));
|
memset(&gb->apu, 0, sizeof(gb->apu));
|
||||||
gb->apu.lf_div = 1;
|
gb->apu.lf_div = 1;
|
||||||
|
/* APU glitch: When turning the APU on while DIV's bit 4 (or 5 in double speed mode), the
|
||||||
|
first DIV/APU event is skipped. */
|
||||||
|
if (gb->div_counter & (gb->cgb_double_speed? 0x2000 : 0x1000)) {
|
||||||
|
gb->apu.skip_div_event = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t GB_apu_read(GB_gameboy_t *gb, uint8_t reg)
|
uint8_t GB_apu_read(GB_gameboy_t *gb, uint8_t reg)
|
||||||
|
@ -108,6 +108,8 @@ typedef struct
|
|||||||
|
|
||||||
} noise_channel;
|
} noise_channel;
|
||||||
|
|
||||||
|
bool skip_div_event;
|
||||||
|
|
||||||
} GB_apu_t;
|
} GB_apu_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -350,7 +350,7 @@ struct GB_gameboy_internal_s {
|
|||||||
GB_SECTION(timing,
|
GB_SECTION(timing,
|
||||||
GB_UNIT(display);
|
GB_UNIT(display);
|
||||||
GB_UNIT(div);
|
GB_UNIT(div);
|
||||||
uint32_t div_counter;
|
uint16_t div_counter;
|
||||||
uint8_t tima_reload_state; /* After TIMA overflows, it becomes 0 for 4 cycles before actually reloading. */
|
uint8_t tima_reload_state; /* After TIMA overflows, it becomes 0 for 4 cycles before actually reloading. */
|
||||||
uint16_t serial_cycles;
|
uint16_t serial_cycles;
|
||||||
uint16_t serial_length;
|
uint16_t serial_length;
|
||||||
|
@ -130,6 +130,8 @@ static void GB_set_internal_div_counter(GB_gameboy_t *gb, uint32_t value)
|
|||||||
counter_overflow_check(gb->div_counter, value, GB_TAC_RATIOS[gb->io_registers[GB_IO_TAC] & 3])) {
|
counter_overflow_check(gb->div_counter, value, GB_TAC_RATIOS[gb->io_registers[GB_IO_TAC] & 3])) {
|
||||||
increase_tima(gb);
|
increase_tima(gb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Can switching to double speed mode trigger an event? */
|
||||||
if (counter_overflow_check(gb->div_counter, value, gb->cgb_double_speed? 0x4000 : 0x2000)) {
|
if (counter_overflow_check(gb->div_counter, value, gb->cgb_double_speed? 0x4000 : 0x2000)) {
|
||||||
GB_apu_run(gb);
|
GB_apu_run(gb);
|
||||||
GB_apu_div_event(gb);
|
GB_apu_div_event(gb);
|
||||||
|
Loading…
Reference in New Issue
Block a user