PPUSTATUS not being read

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
babai
Posts: 10
Joined: Thu Aug 03, 2017 7:15 am
Location: India

PPUSTATUS not being read

Post by babai »

Hello, I'm coding an NES emulator in JavaScript, and currently I'm facing a problem that I can't overcome.
I've not implemented any mappers or scrolling, and toying with simplest games like donkey kong.

DK runs, just that its slow. I've made a forums post previously but I didn't bump it https://forums.nesdev.com/viewtopic.php?f=3&t=16293

The reason for slowness is that in a second, the game is only triggering 20-25 NMIs. MS Pac-man in particular doesn't trigger NMIs at all.
I debugged and compared instruction flow with fceux, and found out that in my emulator, bit 7 of PPUCTRL is being disabled, so the emulator can't do NMI. On further inspection I found out that PPUSTATUS is not being read sometimes by the games. MS pac man reads PPUSTATUS once or twice, then never reads it and as a result the NMI bit is not set and the game renders nothing.

My CPU implementation is good, as it matches the nintendulator nestest.log.

Do any of you guys have any idea that what wrong/missing implementation might be responsible for this?
babai
Posts: 10
Joined: Thu Aug 03, 2017 7:15 am
Location: India

Re: PPUSTATUS not being read

Post by babai »

Oh, I forgot to mention that i've not implemented APU at all, ignoring writes to the registers and returning 0 on read.
Is handling of APU IRQs required for correct game functioning?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: PPUSTATUS not being read

Post by tokumaru »

Games don't use PPUSTATUS to detect vblank, except during initialization while waiting for the PPU to become stable. After that, games usually enable NMIs and that's what they use to know when vblank starts. Games may or may not read PPUSTATUS to "acknowledge" the NMI, but that's not necessary since the NMI flag clears itself at the end of vblank. Games may also read PPUSTATUS to reset the $2005/6 hi/lo latch, but that's also optional, so it's highly possible that some games will only use PPUSTATUS during initialization and then never again.
MS pac man reads PPUSTATUS once or twice, then never reads it and as a result the NMI bit is not set
As long as NMIs are enabled via PPUCTRL, they'll fire every time vblank starts, the game code doesn't have to do anything to "trigger" NMIs, they'll fire regardless of what the CPU is doing.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: PPUSTATUS not being read

Post by tepples »

If it matters, Ms. Pac-Man is on the tricky list for some edge-case stuff it does with PPUSTATUS. Lolo 2 and Spelunker have the same problem.
These rely on 1 cycle NMI delay when PPUSTATUS ($2002) bit 7 gets set inside vblank (if $2002 has not been read yet), in which PPUSTATUS bit 7 can be read as true.
Here's how I understand what's going on in games like that:
  1. CPU reads $AD (LDA abs) or $2C (BIT abs) from PC++
  2. CPU reads $02 (low byte of $2002) from PC++
  3. CPU reads $20 (high byte of $2002) from PC++
    Vertical blanking begins between these cycles. /NMI goes low, because the CPU checks for falling edges on /NMI only between instructions, the CPU's interrupt circuit doesn't notice.
  4. CPU reads $80 from $2002
    /NMI goes high because the read has acknowledged the interrupt
I'm not sure whether the NMI handler gets called at this point. I know there's a minimum high time of one cycle for it to recognize the next falling edge, but I couldn't find anything about a minimum low time.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: PPUSTATUS not being read

Post by lidnariq »

NMI goes to an S/R latch, so the minimum time will be an analog effect instead of a digital one. (Look at visual6502 nodes "NMIP" and "#NMIP")
babai
Posts: 10
Joined: Thu Aug 03, 2017 7:15 am
Location: India

Re: PPUSTATUS not being read

Post by babai »

Thanks for the replies everyone. I've figured out the error by comparing the execution with fceux & mesen.
I noticed that in my case, write to PPUCTRL was hugely delayed. My emulator is of a catch up design with scanline accuracy.
Due to a bug, the cycle counting algorithm was incorrect which slowed the cpu down.
Now with proper cycle counting, Donkey Kong and pac man are running fine. I'm not introducing any delay after reading ppustatus, although I do NMI right after the first vblank scanline is rendered.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: PPUSTATUS not being read

Post by tokumaru »

How exactly does Ms. Pac-Man rely on such a fine timing detail like this? Is it something intentional or is it more like "the game ignores this hardware quirk that luckily prevents the program from crashing"?
Post Reply