Glitch-free controller reads with DMC?
Moderator: Moderators
Glitch-free controller reads with DMC?
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.
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.
Re: Glitch-free controller reads with DMC?
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!
Re: Glitch-free controller reads with DMC?
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.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.
I think.
Re: Glitch-free controller reads with DMC?
... 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?
Re: Glitch-free controller reads with DMC?
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).pubby wrote:sprite DMA as the last part of your vblank code
Re: Glitch-free controller reads with DMC?
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.)freem wrote: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).pubby wrote:sprite DMA as the last part of your vblank code
Then again, the DPCM glitch also doesn't seem to affect PAL NES in the first place.
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).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?
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Re: Glitch-free controller reads with DMC?
But 20 PAL scanlines have less CPU cycles than 20 NTSC scanlines. The difference is about 142 cycles, if I'm not mistaken.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).
Re: Glitch-free controller reads with DMC?
I think the actual point just was "don't consider joypad reading as part of your vblank code".freem wrote: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).pubby wrote:sprite DMA as the last part of your vblank code
Re: Glitch-free controller reads with DMC?
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.freem wrote:That'll break on PAL, as sprite DMA needs to happen within the first 20 scanlinespubby wrote:sprite DMA as the last part of your vblank code
Re: Glitch-free controller reads with DMC?
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.
Re: Glitch-free controller reads with DMC?
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. 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.
I wasn't aware that there was any special constraint on OAM DMA on PAL systems. I just did it first out of habit. 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.
Re: Glitch-free controller reads with DMC?
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!
Re: Glitch-free controller reads with DMC?
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?
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?
Re: Glitch-free controller reads with DMC?
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.
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 992 times
- FrankenGraphics
- Formerly WheelInventor
- Posts: 2064
- Joined: Thu Apr 14, 2016 2:55 am
- Location: Gothenburg, Sweden
- Contact:
Re: Glitch-free controller reads with DMC?
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.
fceux on the other hand, crashes upon rom load.
Post edited for additional findings.