It is currently Tue Jan 16, 2018 2:49 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: PPUSTATUS not being read
PostPosted: Mon Nov 27, 2017 2:11 am 
Offline

Joined: Thu Aug 03, 2017 7:15 am
Posts: 7
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 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?


Top
 Profile  
 
PostPosted: Mon Nov 27, 2017 3:31 am 
Offline

Joined: Thu Aug 03, 2017 7:15 am
Posts: 7
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?


Top
 Profile  
 
PostPosted: Mon Nov 27, 2017 8:00 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10228
Location: Rio de Janeiro - Brazil
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.

Quote:
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.


Top
 Profile  
 
PostPosted: Mon Nov 27, 2017 8:35 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19477
Location: NE Indiana, USA (NTSC)
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.


Top
 Profile  
 
PostPosted: Mon Nov 27, 2017 8:39 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6633
Location: Seattle
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")


Top
 Profile  
 
PostPosted: Mon Nov 27, 2017 9:51 am 
Offline

Joined: Thu Aug 03, 2017 7:15 am
Posts: 7
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.


Top
 Profile  
 
PostPosted: Mon Nov 27, 2017 9:53 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10228
Location: Rio de Janeiro - Brazil
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"?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google [Bot] and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group