diff --git a/retro-core/components/nofrendo/nes/nes.c b/retro-core/components/nofrendo/nes/nes.c index f599f2ebc..94441114f 100644 --- a/retro-core/components/nofrendo/nes/nes.c +++ b/retro-core/components/nofrendo/nes/nes.c @@ -33,20 +33,16 @@ nes_t *nes_getptr(void) /* run emulation for one frame */ void nes_emulate(bool draw) { - int elapsed_cycles = 0; - while (nes.scanline < nes.scanlines_per_frame) { - nes.cycles += nes.cycles_per_scanline; + // Running a little bit ahead seems to fix both Battletoads games... + int elapsed_cycles = nes6502_execute(86 - 12); ppu_renderline(nes.vidbuf, nes.scanline, draw); if (nes.scanline == 241) { - /* 7-9 cycle delay between when VINT flag goes up and NMI is taken */ - elapsed_cycles = nes6502_execute(7); - nes.cycles -= elapsed_cycles; - + elapsed_cycles += nes6502_execute(6); if (nes.ppu->ctrl0 & PPU_CTRL0F_NMI) nes6502_nmi(); @@ -55,9 +51,16 @@ void nes_emulate(bool draw) } if (nes.mapper->hblank) + { + // Mappers use various techniques to detect horizontal blank and we can't accommodate + // all of them unfortunately. But ~86 cycles seems to work fine for everything tested. + elapsed_cycles += nes6502_execute(86 - elapsed_cycles); nes.mapper->hblank(nes.scanline); + } + + nes.cycles += nes.cycles_per_scanline; - elapsed_cycles = nes6502_execute(nes.cycles); + elapsed_cycles += nes6502_execute(nes.cycles - elapsed_cycles); apu_fc_advance(elapsed_cycles); nes.cycles -= elapsed_cycles; @@ -83,20 +86,6 @@ void nes_settimer(nes_timer_t *func, int period) nes.timer_period = period; } -void nes_setcompathacks(void) -{ - // Hack to fix many MMC3 games with status bar vertical alignment issues - // The issue is that the CPU and PPU aren't running in sync - if (nes.cart->checksum == 0xD8578BFD || // Zen Intergalactic - nes.cart->checksum == 0x2E6301ED || // Super Mario Bros 3 - nes.cart->checksum == 0x5ED6F221 || // Kirby's Adventure - nes.cart->checksum == 0xD273B409) // Power Blade 2 - { - nes.cycles_per_scanline += 2.5; - MESSAGE_INFO("NES: Enabled MMC3 Timing Hack\n"); - } -} - /* insert a cart into the NES */ int nes_insertcart(const char *filename, const char *biosfile) { @@ -172,8 +161,6 @@ int nes_insertcart(const char *filename, const char *biosfile) MESSAGE_INFO("NES: BIOS file loaded from '%s'.\n", biosfile); } - nes_setcompathacks(); - nes_reset(true); return status; diff --git a/retro-core/components/nofrendo/nes/nes.h b/retro-core/components/nofrendo/nes/nes.h index 49de6b75a..60861667e 100644 --- a/retro-core/components/nofrendo/nes/nes.h +++ b/retro-core/components/nofrendo/nes/nes.h @@ -62,11 +62,11 @@ typedef struct nes_s nes_t; typedef enum { - SYS_UNKNOWN, SYS_NES_NTSC, SYS_NES_PAL, SYS_FAMICOM, - SYS_DETECT = 0, + SYS_UNKNOWN, + SYS_DETECT = -1, } nes_type_t; typedef void (nes_timer_t)(int cycles); @@ -91,15 +91,14 @@ typedef struct nes_s int overscan; /* Timing constants */ - /* TO DO: re-check if float is still necessary...*/ int refresh_rate; int scanlines_per_frame; - float cycles_per_scanline; - float cpu_clock; + int cycles_per_scanline; + int cpu_clock; /* Timing counters */ int scanline; - float cycles; + int cycles; /* Periodic timer */ nes_timer_t *timer_func;