It is currently Wed Nov 14, 2018 6:55 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Mon May 19, 2008 8:18 am 
Offline

Joined: Thu Oct 27, 2005 1:44 pm
Posts: 449
Location: CA
Here's another bit of weirdness that appears to only happen on real hardware, not any emulators. When some code is using DPCM for sample playback an extra pulse is generated on the controller read line. That messes up the controller reading routine by shifting the output. When the last read is done all the buttons have already been sent so it gets a false trigger on the right button. The same thing seems to be happening on the Yobo and FC Twin clones, haven't tested NEX or RetroDuo yet.

The pulse is about 3x as wide as the normal read ones, and appears to only happen shortly after the write to $4016. It doesn't always happen and not always the same period after the write. Logic analyzer capture below. The added pulse is between C and D.


Image

Has anyone else seen this before, or can write some good test apps? Audio is one part I don't really understand.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 19, 2008 10:32 am 
Offline

Joined: Wed Mar 22, 2006 8:00 am
Posts: 354
I wonder if this is the reason why SMB3 and other games read the controller data multiple times until they get two consecutive reads which match.

The DPCM causes a DMA every so often, which is 3-4 CPU cycles long. One cycle is needed to read the sample date; the other cycles are used for synchronization and/or internal operations. Since a memory access occurs on every cycle, there will be some dummy reads. If the CPU recently accessed $4016, that address will still be on the bus when the DMA occurs, so it's certainly possible for one or more dummy accesses at $4016 to take place.

_________________
"Last version was better," says Floyd. "More bugs. Bugs make game fun."


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 19, 2008 11:34 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20765
Location: NE Indiana, USA (NTSC)
dvdmth wrote:
I wonder if this is the reason why SMB3 and other games read the controller data multiple times until they get two consecutive reads which match.

I seem to remember that Tetris also reads the controller port twice, despite that it doesn't use DPCM.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 19, 2008 7:15 pm 
Offline
User avatar

Joined: Mon Aug 28, 2006 2:52 am
Posts: 407
So that's why a friend's NSF player randomly switches to the next track! I've been pulling my hair out trying to track this one down!

_________________
- BMF
RuSteD LOgIc


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 19, 2008 7:30 pm 
Offline

Joined: Sun Mar 19, 2006 9:44 pm
Posts: 960
Location: Japan
That explains quite a few bugs in homebrew code, perhaps. Solar Wars had a few "phantom" right-button-presses that I could never figure out.

_________________
http://www.chrismcovell.com


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 19, 2008 8:12 pm 
Offline
User avatar

Joined: Tue Dec 13, 2005 4:19 pm
Posts: 290
Location: Gainesville, FL - USA
Thanks to bunnyboy on IRC - he just linked me to this thread. I spent the last hour or so going crazy, testing devcarts and my Powerpak, as well as numerous emulators, trying to figure out this problem. In some strange coincidence I just came across this problem for the first time today!

_________________
http://www.no-carrier.com


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 20, 2008 8:12 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7567
Location: Chexbres, VD, Switzerland
Thanks god I don't use DPCM so I guess I'm all right.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 20, 2008 8:25 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20765
Location: NE Indiana, USA (NTSC)
I wonder if Codemasters games reread the gamepad. A lot of them (e.g. Fire Hawk) use the DPCM channel for timing.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 20, 2008 11:44 pm 
Offline

Joined: Thu Oct 27, 2005 1:44 pm
Posts: 449
Location: CA
dvdmth wrote:
The DPCM causes a DMA every so often, which is 3-4 CPU cycles long. One cycle is needed to read the sample date; the other cycles are used for synchronization and/or internal operations. Since a memory access occurs on every cycle, there will be some dummy reads. If the CPU recently accessed $4016, that address will still be on the bus when the DMA occurs, so it's certainly possible for one or more dummy accesses at $4016 to take place.


Except the long pulse comes before the $4016 read, and after many other instructions passed from the previous read, so its not left over bus capacitance? Does the DMA interrupt the currently executing instruction, so the $4016 address would have been calculated but not used yet?


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 21, 2008 8:57 am 
Offline

Joined: Wed Mar 22, 2006 8:00 am
Posts: 354
DMA can (and does) interrupt CPU operations in the middle of an instruction. In fact, accurate SNES emulation is impossible without supporting it, which is why BSNES executes all instructions one cycle at a time (and other SNES emulators use hacks to work around the issue).

EDIT - I just thought of something. What about $2007 accesses? Surely, this problem would affect other serial I/O registers as well. Yet, if $2007 were also affected, why would we not have seen it by now? I would think that a dummy $2007 read would screw up the VADDR counter, which would cause data fed to VRAM to be shifted over...

When this "long pulse" occurs, is it always next to a normal $4016 access, or can it happen elsewhere? Does it happen if you change the location of DPCM sample data?

_________________
"Last version was better," says Floyd. "More bugs. Bugs make game fun."


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 21, 2008 12:10 pm 
Offline

Joined: Thu Oct 27, 2005 1:44 pm
Posts: 449
Location: CA
Maybe its actually a feature, for reading from the expansion port? $4017 is also affected but I don't have an easy way to check other regs like $2007. If someone can write a test app that accurately places the interrupt then I can run it on real hardware and record results. I think I have only seen the long pulse within the controller reading routine, but my logic analyzer trigger may have not been set right to catch it other places.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 21, 2008 5:14 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I threw together a couple of tests that have DMC DMA occur during $4016 read and $2007 read. Both are affected. $2007 has some weird effects for a double read, even when causing it "normally" via LDA $20F7,X with X=$10. Full ca65 source included.

dmc_dma_during_read.zip (obsolete; see below for newer tests)

bunnyboy, for your testing, should I make versions that continuously trigger the effect as often as possible?


Last edited by blargg on Wed May 21, 2008 7:12 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Wed May 21, 2008 5:57 pm 
Offline

Joined: Wed Mar 22, 2006 8:00 am
Posts: 354
OK, so reading $4016 and $2007 is unreliable during DMC playback...

What about $2007 writes?

And if $2007 writes are affected, how in the world can VRAM updates be reliably done while a sample is playing? (And why is it that games using the channel haven't suffered from this?)

You can simulate a $2007 read/write combo on consecutive cycles with the STA $2007,X with X = 0 (the STA opcode always has a dummy read). A double write following a read can be done with INC $2007, and a double read followed by a double write can be done with INC $2007,X (again, X = 0).

_________________
"Last version was better," says Floyd. "More bugs. Bugs make game fun."


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 21, 2008 6:48 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
$2007 writes are also affected. For $2007 read/write, two or three extra reads are inserted before the actual read/write. The number depends on the CPU-PPU synchronization at reset. $4016 reads always seem to have one extra read inserted. I also added a test that verifies that a $2007 read just before a write (using STA $2007,X) works normally, rewrote the tests to use a shell that sets up the DMC, and added some CRCs for easy verification of output. NES ROMs + full ca65 source:

dmc_dma_during_read3.zip

Since the DMC DMA has to occur on exactly the right clock for this problem to occur, it would probably be very rare in any affected games.


Last edited by blargg on Wed May 21, 2008 8:15 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Wed May 21, 2008 7:45 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20765
Location: NE Indiana, USA (NTSC)
blargg wrote:
$2007 writes are also affected. [But] Since the DMC DMA has to occur on exactly the right clock for this problem to occur, it would probably be very rare in any affected games.

For a wave at rate $F (1 sample per 54 NTSC cycles, or 33144 Hz; 1 byte every 54*4 = 432 cycles), wouldn't this glitch happen on average once every 432 writes? There are over twice that many writes when a nametable gets copied into VRAM. Or do I misunderstand "exactly the right clock"?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 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