When can HDMA and DMA be used at the same time?
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
-
- Posts: 3140
- Joined: Wed May 19, 2010 6:12 pm
When can HDMA and DMA be used at the same time?
I've heard about some kind of crashing that happens when HDMA and DMA are used at the same time. Does this always happen, or can this be avoided somehow?
Re: When can HDMA and DMA be used at the same time?
It can be avoided by not using a 1/1/1 system.
Re: When can HDMA and DMA be used at the same time?
You can't really demand that from your customers...Revenant wrote:It can be avoided by not using a 1/1/1 system.
Re: When can HDMA and DMA be used at the same time?
Half-serious answer aside, I'm pretty sure the only easy/reliable way around it is just to avoid doing DMA outside of vblank.
I don't remember personally seeing too many details of the DMA crash being discussed - I want to say it only happens if DMA and HDMA start at exactly the same time, not just overlap, but others could possibly clarify that.
I don't remember personally seeing too many details of the DMA crash being discussed - I want to say it only happens if DMA and HDMA start at exactly the same time, not just overlap, but others could possibly clarify that.
Re: When can HDMA and DMA be used at the same time?
The problem is clearly documented (with full explanations/timing diagrams) in the official SNES documentation. Chapter 25, Section 1 describes the problem. It only applies to SNES units using CPU revision 1. Several workarounds/solutions are available.
Re: When can HDMA and DMA be used at the same time?
Basically: if you really need both to happen at the same time (i.e. you can't fit DMA into vblank), use the HV counter to ensure the DMA is timed at a point where it won't stop at the same time HDMA starts?
Re: When can HDMA and DMA be used at the same time?
Or use an IRQ, or use cycle-counted code from a known start point.
In other words, it's no good for speeding up decompression in the presence of HDMA, because a fast decompressor needs to be free-running; it can't afford to wait around for a safe H-position. I stopped bugging psycopathicteen about HDMA audio streaming in the Bad Apple demo when I realized this.
In other words, it's no good for speeding up decompression in the presence of HDMA, because a fast decompressor needs to be free-running; it can't afford to wait around for a safe H-position. I stopped bugging psycopathicteen about HDMA audio streaming in the Bad Apple demo when I realized this.
Re: When can HDMA and DMA be used at the same time?
Real-life example: The PowerPak loads data in chunks of 512 bytes from the CF card using DMA during active display. The original firmware didn't use HDMA at all, so when I implemented the latter for the first time, I had to find a way to avoid the glitch. ikari made the clever suggestion to correctly time the DMA transfers simply by waiting for Hblank before starting them.
So the way it's worked ever since v2.00-beta is roughly like this:
So the way it's worked ever since v2.00-beta is roughly like this:
- Scanline N: Wait for Hblank and start DMA around the time HDMA finishes
- Scanline N+1: DMA is still running. When Hblank occurs, it is interrupted once by HDMA
- Scanline N+2: DMA finishes long before Hblank (and therefore, HDMA) occurs
Some of my projects:
Furry RPG!
Unofficial SNES PowerPak firmware
(See my GitHub profile for more)
Furry RPG!
Unofficial SNES PowerPak firmware
(See my GitHub profile for more)
Re: When can HDMA and DMA be used at the same time?
Either you give up on 1/1/1 users, or you only use DMA during Vblank.
There is unfortunately no other viable option. SNES timing is way too sporadic, and we don't even fully understand exactly what causes the crash yet, nor what actually happens that causes it. The SNES dev manual is too vague about its timing notes to emulate the behavior accurately. I have good theories, but the SNES is very resilient against logical analysis :P
I once came across a US football game that read out the CPU revision, and used DMA on r2, and a block move on r1. But even this was a terrible idea: if the speed is the same, just use the r1 version; and if the speed is different, what a horrible idea that half your users will be complaining of slowdowns. Regular end users have no way of knowing which revision their SNES is: they can't even remove the security screws to find out.
> Basically: if you really need both to happen at the same time (i.e. you can't fit DMA into vblank), use the HV counter to ensure the DMA is timed at a point where it won't stop at the same time HDMA starts?
This is honestly asking too much. There's 1324 usable cycles per scanline, the setup time to trigger the DMA is going to add some cycles to that, the CPU<>DMA and DMA<>CPU syncs add time, there's DRAM refresh in the mix, and you have to add the transfer lengths * 8 cycles per byte, and then you also have to consider if your DMA goes over HDMA transfers (which are even more complex, and can vary timing based on indirect transfers and reloading counters) ... and most likely, DMA transfers are going to be longer than one scanline, so that's most likely certain.
It's way too complex. I would have a ton of trouble implementing that reliably, even using emulation logs to proof everything, and I can't think of anyone who knows more about SNES timing than I do (a couple of people who know as much as I do.)
Pretty much the only way it'd work is if your DMA and HDMA always transferred the same amount of data each time, and your HDMA didn't have weird indirect fetching going on, and you could align the DMA start to a fixed point (whether via $4212's Hblank status, or a timed IRQ/WAI), and you could observe in an emulator that you weren't anywhere near the HDMA start when the DMA ended.
All of those conditions would probably only be true ~3% of the time you wanted to use DMA. And even then, you may be better off just using a block move operation if the length is small enough (I know, mvn/mvp are slow), compared to waiting for a blanking even or IRQ trigger before starting your DMA.
Thus, my strong advice is: don't do it. Find another way to make your code work. I don't care who pulled it off, it should never be done. You're playing with fire.
There is unfortunately no other viable option. SNES timing is way too sporadic, and we don't even fully understand exactly what causes the crash yet, nor what actually happens that causes it. The SNES dev manual is too vague about its timing notes to emulate the behavior accurately. I have good theories, but the SNES is very resilient against logical analysis :P
I once came across a US football game that read out the CPU revision, and used DMA on r2, and a block move on r1. But even this was a terrible idea: if the speed is the same, just use the r1 version; and if the speed is different, what a horrible idea that half your users will be complaining of slowdowns. Regular end users have no way of knowing which revision their SNES is: they can't even remove the security screws to find out.
> Basically: if you really need both to happen at the same time (i.e. you can't fit DMA into vblank), use the HV counter to ensure the DMA is timed at a point where it won't stop at the same time HDMA starts?
This is honestly asking too much. There's 1324 usable cycles per scanline, the setup time to trigger the DMA is going to add some cycles to that, the CPU<>DMA and DMA<>CPU syncs add time, there's DRAM refresh in the mix, and you have to add the transfer lengths * 8 cycles per byte, and then you also have to consider if your DMA goes over HDMA transfers (which are even more complex, and can vary timing based on indirect transfers and reloading counters) ... and most likely, DMA transfers are going to be longer than one scanline, so that's most likely certain.
It's way too complex. I would have a ton of trouble implementing that reliably, even using emulation logs to proof everything, and I can't think of anyone who knows more about SNES timing than I do (a couple of people who know as much as I do.)
Pretty much the only way it'd work is if your DMA and HDMA always transferred the same amount of data each time, and your HDMA didn't have weird indirect fetching going on, and you could align the DMA start to a fixed point (whether via $4212's Hblank status, or a timed IRQ/WAI), and you could observe in an emulator that you weren't anywhere near the HDMA start when the DMA ended.
All of those conditions would probably only be true ~3% of the time you wanted to use DMA. And even then, you may be better off just using a block move operation if the length is small enough (I know, mvn/mvp are slow), compared to waiting for a blanking even or IRQ trigger before starting your DMA.
Thus, my strong advice is: don't do it. Find another way to make your code work. I don't care who pulled it off, it should never be done. You're playing with fire.
Re: When can HDMA and DMA be used at the same time?
I think Uniracers does the same thing.byuu wrote:I once came across a US football game that read out the CPU revision, and used DMA on r2, and a block move on r1.
I assume the developers considered this difference an acceptable engineering tradeoff. Compare it to disc-based game consoles prior to 2013, which slow down if the disc gets scratched. (The PlayStation 4 and Xbox One install the entire game to an internal HDD and read only the lead-in to verify disc presence during gameplay.) Compare it to Game Boy Color dual-mode games, which can run the CPU at double speed and rely on fast LCD response time only in GBC mode. And compare it to PC games, which have to deal with everything from the Atom and Intel integrated graphics in a convertible tablet/laptop to 4K NVIDIA masturbation in a purpose-built desktop.byuu wrote:and if the speed is different, what a horrible idea that half your users will be complaining of slowdowns.
If you have a copy of The Lion King, BARRY will tell you.byuu wrote:Regular end users have no way of knowing which revision their SNES is: they can't even remove the security screws to find out.
Re: When can HDMA and DMA be used at the same time?
Well, there is a third option, which is obvious but should probably be listed as well: just don't use any HDMA when you need to DMA outside of Vblank.byuu wrote:Either you give up on 1/1/1 users, or you only use DMA during Vblank.
There is unfortunately no other viable option.
-
- Posts: 275
- Joined: Wed Jul 09, 2008 8:46 pm
Re: When can HDMA and DMA be used at the same time?
Maybe that's why sometimes the IRQs are used instead of HDMA?
Re: When can HDMA and DMA be used at the same time?
Thanks to this, I now know that I have a 2/1/3 SNES.tepples wrote:If you have a copy of The Lion King, BARRY will tell you.
Edit: Are there any examples of people getting different values on this screen? I've looked around and all I can see is 2/1/3. Any confirmation that this screen is accurate?
Edit 2: Found a video of someone getting 1/1/1 (in an emulator). So I guess 2/1/3 is a lot more common? Kinda sucks for the 1/1/1 users.
Edit 3 (sorry): Looks like bsnes-plus emulates CPU revision 2. At some point I might like to ask someone to test my game on a 1/1/1 system to see if it works properly there, unless bsnes/higan can be made to emulate the DMA/HDMA crash.
SNES NTSC 2/1/3 1CHIP | serial number UN318588627
Re: When can HDMA and DMA be used at the same time?
2/1/3 is probably the most common combination by far, partially because even all of the 1CHIP revisions report it even though it's not strictly the same CPU/PPUs as a "real" 2/1/3 system.
There are definitely others (I own a 2/1/1), but between all the numerous hardware revisions, version 1 S-CPUs are a definite minority. But if you do care about supporting them, I still think the only realistic option is to just keep DMA and HDMA separate at all times.
There are definitely others (I own a 2/1/1), but between all the numerous hardware revisions, version 1 S-CPUs are a definite minority. But if you do care about supporting them, I still think the only realistic option is to just keep DMA and HDMA separate at all times.
Re: When can HDMA and DMA be used at the same time?
My Super NES is 1/1/1 and yellow as fucc, and I have the SNES PowerPak with MUFASA firmware.