Views: 26,161,898 Homepage | Main | Rules/FAQ | Memberlist | Active users | Last posts | Calendar | Stats | Online users | Search 07-14-25 03:04 PM
Guest:

0 users reading DMA/NDMA priority stuff | 1 bot

Main - Development - DMA/NDMA priority stuff Hide post layouts | New reply


Arisotura
Posted on 07-05-25 09:51 AM (rev. 2 of 07-05-25 10:02 AM) Link | #7799
researching this


our case: Let's Golf (again)

there is a timing issue that causes rolling in the camera preview thing

what happens:

NDMA1 is used to retrieve picture data, but on some occasions DMA3 is used to copy some data to VRAM, which prevents NDMA1 from running, breaking the camera transfer

first evident problem is that melonDS doesn't handle this situation correctly, instead assuming that the "attempt to fire camera DMA" operation will succeed, and resetting the FIFO state anyway. the FIFO state should only be changed by actually reading data from it. this will require remodeling the thing as a proper FIFO...

then this situation would cause a FIFO overflow error. no idea if that's what happens on hardware, and the game just silently recovers from those?


second problem is that of DMA vs NDMA priority.


so far, observations with NDMA cnt = 0 or 80060000, NDMA channel bcnt = 0:

* DMA can preempt a lower priority DMA channel (ie. DMA0 preempts DMA1)
* NDMA can't preempt another NDMA channel
* NDMA can't preempt a DMA channel
* DMA can't preempt a NDMA channel


with bcnt = 2:

* NDMA can't preempt a DMA channel
* DMA can preempt a NDMA channel
* NDMA can preempt another NDMA channel

____________________
Kuribo64

Arisotura
Posted on 07-06-25 02:46 PM (rev. 2 of 07-06-25 03:01 PM) Link | #7801
notes on the Let's Golf case


the basic issue:

* NDMA1 is used to copy camera picture data to RAM
* periodically, DMA3 is used to copy the entire top screen frame from RAM to VRAM (at 0x06200000)
* when DMA3 is running, it prevents NDMA1 from running, delaying it long enough to cause a camera FIFO overrun


melonDS had a bug where it assumed that the "try to fire camera DMA" command would always be successful, which was why the bug caused rolling and weird shit.

with some remodelling, this behaves as expected, and triggers a FIFO overrun error.

however, this situation seems to cause the game to just give up entirely on acquiring camera data, and stay stuck on the same camera frame.


I ran hardware tests on DMA priority, and NDMA channels just can't preempt old DMA channels.

the other way around (ie. whether old DMA can preempt NDMA) depends on the physical block and priority settings on NDMA side. but nothing seems to make NDMA able to preempt old DMA.


I reproduced a setup equivalent to Let's Golf in a homebrew. camera, NDMA1 copying to RAM, DMA3 copying from RAM to VRAM.

tested it on hardware. it gets stuck after a couple frames or less, with a camera FIFO overrun error.


I tried copying the exact camera init sequence Let's Golf uses. I see nothing fancy in there. I see no attempts from the game at keeping camera VBlank synced to display.

the part that calls DMA3 is originally invoked on LCD VBlank, but due to some time consuming processing, DMA3 ends up running during active display. not that when it runs matters a lot, since this DMA3 is somewhat synced to display and the camera stuff isn't.


I tried changing the game's camera error handler to an infinite loop, to see if it ever gets triggered... it does not, that modified ROM ran just fine.


the only possible explanations at this point are that

a) that DMA3 transfer should not happen, or should happen at a different time, or not sure how that would work tbh

b) there is something obscure that I missed that affects camera timings in a way that makes this work

____________________
Kuribo64

Arisotura
Posted on 07-06-25 06:48 PM Link | #7802
ran a modified ROM to see if the game was doing anything that might sync camera input to the LCD...

nope.

it works the same way as in melonDS (after my last commit that revises the timings), ie. it's not synced to the LCD.


this leaves only two possibilities

a) game somehow knows when to avoid doing a DMA transfer
b) DMA3 can somehow be preempted in this situation?

____________________
Kuribo64

Arisotura
Posted on 07-07-25 01:40 AM (rev. 2 of 07-07-25 01:49 AM) Link | #7803
NOTE on this

it's a case of "works out of sheer luck"

basically with the 32bit VRAM bus, the DMA3 transfer takes just enough time that it can fit between two NDMA1 chunks and not disrupt the flow too much

I still have trouble modeling the shit in melonDS tho

if I add a secondary buffer of 512 words, it works, but I don't know if it's correct emulation

but, like

say DMA3 starts at the worst possible time, right before NDMA1, when the FIFO is at the fullest or almost

then new scanlines keep piling up but the FIFO is full

if the hardware can manage to avoid this, clearly there's some degree of resilience

double buffers?

I need to figure out how to determine this...

____________________
Kuribo64


Main - Development - DMA/NDMA priority stuff Hide post layouts | New reply

Page rendered in 0.071 seconds. (2048KB of memory used)
MySQL - queries: 29, rows: 82/82, time: 0.041 seconds.
[powered by Acmlm] Acmlmboard 2.064 (2018-07-20)
© 2005-2008 Acmlm, Xkeeper, blackhole89 et al.