It is currently Mon Oct 23, 2017 7:22 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 61 posts ]  Go to page 1, 2, 3, 4, 5  Next
Author Message
PostPosted: Sun May 29, 2016 4:13 am 
Offline

Joined: Thu Aug 20, 2015 3:09 am
Posts: 284
Okay, I've run this through my head a few times now, and I can't find any problems with it. Someone check my logic.

1) According to Disch's recent tests, DMC DMA always attempts to engage on an odd cycle.
2) It is already well known that the first cycle after an OAM DMA is always an even cycle.

By performing an OAM DMA, then cycle-timing to ensure that all reads from $4016/$4107 occur on even cycles, shouldn't it be possible to ensure that the controller reads are never hijacked? The DMC generates at most one DMA every ~400 cycles, so the alignment after a DMC DMA is irrelevant - the entire routine should be able to complete before a second one can occur.

I don't have the hardware to test it myself (PAL region), but if nobody can find an obvious reason why it won't work I can write a test ROM for others to try.


Top
 Profile  
 
PostPosted: Sun May 29, 2016 9:03 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3944
The problem is that you lose vblank time. You're better off just reading it twice, then reading a third time if they don't agree.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Sun May 29, 2016 10:30 am 
Offline
User avatar

Joined: Thu Mar 31, 2016 11:15 am
Posts: 201
Dwedit wrote:
The problem is that you lose vblank time. You're better off just reading it twice, then reading a third time if they don't agree.

The controller reads don't have to happen in vblank though. You would have sprite DMA as the last part of your vblank code and then the controller reads immediately after.

I think.


Top
 Profile  
 
PostPosted: Sun May 29, 2016 11:02 am 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6303
Location: Seattle
... I'm pretty certain you wouldn't lose significant vblank time...? Unless I'm misunderstanding what Rahsennor is saying, it sounds like it should be possible to just put careful odd-number-of-cycle delays in your reading routine to make it such that the reads from $4016/4017 wouldn't be on the relevant even/odd phase to cause the glitch, and so it should only take one read through?


Top
 Profile  
 
PostPosted: Sun May 29, 2016 11:08 am 
Offline
User avatar

Joined: Mon Oct 01, 2012 3:47 pm
Posts: 152
Location: freemland (NTSC-U)
pubby wrote:
sprite DMA as the last part of your vblank code


That'll break on PAL, as sprite DMA needs to happen within the first 20 scanlines (see point K on http://wiki.nesdev.com/w/index.php/Nestech.txt#PPU).


Top
 Profile  
 
PostPosted: Sun May 29, 2016 11:39 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2963
Location: Tampere, Finland
freem wrote:
pubby wrote:
sprite DMA as the last part of your vblank code


That'll break on PAL, as sprite DMA needs to happen within the first 20 scanlines (see point K on http://wiki.nesdev.com/w/index.php/Nestech.txt#PPU).

Only if the total amount of vblank code actually takes more than ~20 scanlines (which is usually not the case, to maintain NTSC compatibility). BTW there might be other "windows" in which the OAM DMA can be done (instead of just the first 20 scanlines). All that has been tested is that if the DMA was done slightly after 20 scanlines, the update got corrupted. (This also seemed to cause the strange results in blargg's OAM tests on PAL NES -- after I forced all reads to happen right after start of vblank, the tests passed.)

Then again, the DPCM glitch also doesn't seem to affect PAL NES in the first place.

lidnariq wrote:
... I'm pretty certain you wouldn't lose significant vblank time...? Unless I'm misunderstanding what Rahsennor is saying, it sounds like it should be possible to just put careful odd-number-of-cycle delays in your reading routine to make it such that the reads from $4016/4017 wouldn't be on the relevant even/odd phase to cause the glitch, and so it should only take one read through?

Yeah, assuming one would just be reading the values and storing them for later processing, let's say 8 CPU cycles per read, that's only ~64 cycles wasted (~100 at most).

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sun May 29, 2016 1:45 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10068
Location: Rio de Janeiro - Brazil
thefox wrote:
Only if the total amount of vblank code actually takes more than ~20 scanlines (which is usually not the case, to maintain NTSC compatibility).

But 20 PAL scanlines have less CPU cycles than 20 NTSC scanlines. The difference is about 142 cycles, if I'm not mistaken.


Top
 Profile  
 
PostPosted: Sun May 29, 2016 1:53 pm 
Offline

Joined: Thu Aug 12, 2010 3:43 am
Posts: 1589
freem wrote:
pubby wrote:
sprite DMA as the last part of your vblank code


That'll break on PAL, as sprite DMA needs to happen within the first 20 scanlines (see point K on http://wiki.nesdev.com/w/index.php/Nestech.txt#PPU).

I think the actual point just was "don't consider joypad reading as part of your vblank code".


Top
 Profile  
 
PostPosted: Sun May 29, 2016 2:38 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19122
Location: NE Indiana, USA (NTSC)
freem wrote:
pubby wrote:
sprite DMA as the last part of your vblank code

That'll break on PAL, as sprite DMA needs to happen within the first 20 scanlines

Even if your engine is designed to take advantage of PAL's longer vblank when available, as RHDE is, I imagine that "If PAL NES then do OAM first else do OAM last" would handle all cases. Incidentally, so would reading the controller in a DMC IRQ handler, if you're using it as a crude raster timer.


Top
 Profile  
 
PostPosted: Sun May 29, 2016 3:09 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10068
Location: Rio de Janeiro - Brazil
Yeah, PAL vblank is so long that reading the controllers during that time shouldn't make any difference... Just take care of the sprite DMA and controller reading right away, while on NTSC you'd do both these things last, with the controller part possibly spilling into the visible frame.


Top
 Profile  
 
PostPosted: Sun May 29, 2016 5:07 pm 
Offline

Joined: Thu Aug 20, 2015 3:09 am
Posts: 284
Yes, the idea was to do the DMA last and let the controller reading spill over into the visible frame. Gives you something to do while you wait for sprite 0.

I wasn't aware that there was any special constraint on OAM DMA on PAL systems. I just did it first out of habit. :oops: It only takes 11 cycles to decide whether to do the DMA first or last, assuming you have a flag in the top two bits of a zero page variable. Or if you can make sure your NMI handler always takes an even number of cycles (tricky, but not as bad as making it constant-time) you can just do the DMA first and the controller reading last and it should work fine in either case.

There's also the possibility of using this trick to perform VRAM reads, which you'd want to do inside vblank anyway. In fact, that might be a better way to test it, since you have full control over the contents of the nametables/pattern tables.


Top
 Profile  
 
PostPosted: Sun May 29, 2016 9:01 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3944
Is nametable reads during DMC what caused all the attribute glitches in Castlevania II?

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Sun May 29, 2016 11:00 pm 
Offline
User avatar

Joined: Sat Jul 12, 2014 3:04 pm
Posts: 936
You're trying to be hackish and fancy (½ compliment).

If you're cycle-timing your controller read relative to DMC, then you can just stick it in the time you know there isn't going to be a DMC?


Top
 Profile  
 
PostPosted: Mon May 30, 2016 5:55 am 
Offline

Joined: Thu Aug 20, 2015 3:09 am
Posts: 284
Slapped together the simplest test I could come up with, and to my surprise, it works perfectly in Nestopia... but on odd cycles instead of even. None of the other emulators I tested emulate DMC conflicts at all. Can anyone here try it out and tell me what it does on real hardware?

I made two versions of the test, one that always reads on even cycles, and one that always reads on odd cycles. The test is as simple as it gets: it plays a DMC loop at the highest rate and runs the polling code in a tight loop, with rendering off. If right is pressed on either controller, the screen goes white. Otherwise the screen should stay black. This assumes a standard controller that pads with all 1s, so that glitched reads always result in right being pressed.


Attachments:
dma_sync_test.zip [581 Bytes]
Downloaded 100 times
Top
 Profile  
 
PostPosted: Mon May 30, 2016 6:59 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 910
Location: Gothenburg, Sweden
Tested on PAL hardware with nes-004 controller for a couple of minutes on each test. Both work 100% of the times tested, assuming that the only thing to test for is the screen to go white. If i raise the tv volume quite a bit, i hear a bright tone that's interrupted for as long as i hold right pressed.

fceux on the other hand, crashes upon rom load.

Post edited for additional findings.

_________________
http://www.frankengraphics.com - personal NES blog


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

All times are UTC - 7 hours


Who is online

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