Page 1 of 1
DMA queue clash with early frame code
Posted: Tue May 10, 2016 3:47 pm
by cero
Is the following issue possible?
- use the DMA queue to sync a few kb
- the v-int callback does not wait for DMA
- thus the frame code can start *while the DMA is going*
- then, if there's early frame code that accesses the VDP, even with interrupts disabled, it can conflict and blow up
I believe I'm hitting this, but I'm not certain.
Re: DMA queue clash with early frame code
Posted: Tue May 10, 2016 3:59 pm
by cero
Yep, sticking VDP_waitDMACompletion() at the frame start seems to fix the corruption.
Re: DMA queue clash with early frame code
Posted: Tue May 10, 2016 4:34 pm
by Stef
I guess you are doing some DMA fill operation then... nothing to do with the DMA queue which is used only for DMA transfer (ROM/RAM to VRAM) and retains BUS (and so the 68k) while it is operating.
Re: DMA queue clash with early frame code
Posted: Tue May 10, 2016 7:02 pm
by cero
No, just a normal ROM-to-VRAM copy. And the DMA queue is the only DMA I use, so how could that fix it?
edit: The corruption was visible in the couple tiles following the last DMA target. As if the DMA copy randomly wrote too much, or if it interrupted another VDP call, leaving the dest address there.
But, as mentioned, adding the wait at the frame start fixed it. Very curious.
Re: DMA queue clash with early frame code
Posted: Tue May 10, 2016 7:56 pm
by Mask of Destiny
ROM to VRAM copies lock the 68K out of the bus until they are done so waiting for DMA completion should have no effect.
Re: DMA queue clash with early frame code
Posted: Wed May 11, 2016 7:55 am
by cero
Indeed, yet it has an effect. On multiple emulators, not yet tested on hw.
It must have something to do with the DMA due to which tiles get corrupted - ones right after the final DMA copy. How would you track this?
edit: Another idea. Is the following possible:
- the frame takes just slightly too long, and the last thing has ints disabled
- we enter VDP_waitVSync one line after the v-int would have fired
- thus the v-int does not fire that frame, the DMA queue is not flushed
- the next frame adds the new DMAs to the queue, going over the 7.2kb limit
That would explain the corruption, but not why the DMA wait fixes it.
Re: DMA queue clash with early frame code
Posted: Wed May 11, 2016 10:33 am
by cero
Indeed, on some frames the DMA queue is not empty at the start. Trying to clear it now.
Re: DMA queue clash with early frame code
Posted: Wed May 11, 2016 11:48 am
by Stef
The DMA queue implementation has changed since the current guthub version, will try to push the changes soon. Hopefully it will have better handling of case where you are going over DMA bandwidth limit.
Re: DMA queue clash with early frame code
Posted: Wed May 11, 2016 12:27 pm
by cero
According to the code, it's not possible for the queue to have contents after waitVSync, yet that's what I repeatably saw. This is a very interesting bug.
Re: DMA queue clash with early frame code
Posted: Wed May 11, 2016 1:32 pm
by Stef
Look like github already contains a recent version of dma.c file. In fact it all depends if you defined a maximum transfer size per frame (using DMA_setMaxTransferSize(..) method), in which case the DMA won't transfer more than the given size, but by default there is no limit indeed.
Re: DMA queue clash with early frame code
Posted: Wed May 11, 2016 2:36 pm
by cero
I did not set any limit.
Re: DMA queue clash with early frame code
Posted: Wed May 11, 2016 6:35 pm
by Stef
So i don't see how the queue can have some entries after the vint callback :-/ Are you sure you don't retain interrupts disabled for too much time ??
Re: DMA queue clash with early frame code
Posted: Thu May 12, 2016 7:40 am
by cero
They may be disabled long enough for the framerate to drop to 30fps temporarily. But they are always enabled before waitVSync.