Accurate RTC emulation

This commit is contained in:
Lior Halphon 2021-02-26 00:40:18 +02:00
parent a13469c4e2
commit 71c6fa45e0
2 changed files with 13 additions and 1 deletions

View File

@ -192,7 +192,10 @@ static uint8_t read_mbc_ram(GB_gameboy_t *gb, uint16_t addr)
if (gb->cartridge_type->has_rtc && gb->cartridge_type->mbc_type != GB_HUC3 && if (gb->cartridge_type->has_rtc && gb->cartridge_type->mbc_type != GB_HUC3 &&
gb->mbc3_rtc_mapped && gb->mbc_ram_bank <= 4) { gb->mbc3_rtc_mapped && gb->mbc_ram_bank <= 4) {
/* RTC read */ /* RTC read */
gb->rtc_latched.high |= ~0xC1; /* Not all bytes in RTC high are used. */ gb->rtc_latched.seconds &= 0x3F;
gb->rtc_latched.minutes &= 0x3F;
gb->rtc_latched.hours &= 0x1F;
gb->rtc_latched.high &= 0xC1;
return gb->rtc_latched.data[gb->mbc_ram_bank]; return gb->rtc_latched.data[gb->mbc_ram_bank];
} }
@ -693,6 +696,9 @@ static void write_mbc_ram(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
} }
if (gb->cartridge_type->has_rtc && gb->mbc3_rtc_mapped && gb->mbc_ram_bank <= 4) { if (gb->cartridge_type->has_rtc && gb->mbc3_rtc_mapped && gb->mbc_ram_bank <= 4) {
if (gb->mbc_ram_bank == 0) {
gb->rtc_cycles = 0;
}
gb->rtc_latched.data[gb->mbc_ram_bank] = gb->rtc_real.data[gb->mbc_ram_bank] = value; gb->rtc_latched.data[gb->mbc_ram_bank] = gb->rtc_real.data[gb->mbc_ram_bank] = value;
return; return;
} }

View File

@ -254,6 +254,10 @@ static void GB_rtc_run(GB_gameboy_t *gb, uint8_t cycles)
current_time = time(NULL); current_time = time(NULL);
break; break;
case GB_RTC_MODE_ACCURATE: case GB_RTC_MODE_ACCURATE:
if (gb->cartridge_type->mbc_type != GB_HUC3 && (gb->rtc_real.high & 0x40)) {
gb->rtc_cycles -= cycles;
return;
}
if (gb->rtc_cycles < GB_get_unmultiplied_clock_rate(gb) * 2) return; if (gb->rtc_cycles < GB_get_unmultiplied_clock_rate(gb) * 2) return;
gb->rtc_cycles -= GB_get_unmultiplied_clock_rate(gb) * 2; gb->rtc_cycles -= GB_get_unmultiplied_clock_rate(gb) * 2;
current_time = gb->last_rtc_second + 1; current_time = gb->last_rtc_second + 1;
@ -299,6 +303,8 @@ static void GB_rtc_run(GB_gameboy_t *gb, uint8_t cycles)
if (gb->rtc_real.high & 1) { /* Bit 8 of days*/ if (gb->rtc_real.high & 1) { /* Bit 8 of days*/
gb->rtc_real.high |= 0x80; /* Overflow bit */ gb->rtc_real.high |= 0x80; /* Overflow bit */
} }
gb->rtc_real.high ^= 1;
} }
} }
} }