Help with dmc_dma [SOLVED]

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Help with dmc_dma [SOLVED]
by on (#75202)
[As small note, the following represents an emulation point of view, an abstraction layer over the true hardware operation.]

- What's the timing diagram of a DMC DMA? Let's say there's a DMC DMA ready and it'll take 4 CPU cycles.

1. The CPU is suspended by 4 CPU cycles. Is the APU clocked? Plus, during this time, the PPU should run for 3x4 = 12 PPU cycles (NTSC) before the DMA starts, but is this correct?
EDIT: looks like it's true.

2. Once the DMC DMA is complete, is the DMC immediately clocked?
EDIT: nothing stops the DMC to be clocked, as it seems so.

3. After clocking the DMC, the sample buffer is empty and DMC length counter is not zero. Does the DMA occur in the next CPU cycle or does the memory fetch occur immediately after that?
EDIT2: it occurs in the next CPU cycle.

by on (#75300)
- Does the DMC wait for the current instruction to be completed, or could it occur in mid-instruction? Take a STA $4014. If a DMC lands in mid-instruction (before the effective write to the address), it'll take 3 cycles; otherwise, if it triggers during the sprite DMA, yes, 2 cycles. In other words, it makes a huge difference.

- I can't "play" of try-and-error all the time, until I got a "random" success. The only emu that passes it is NESICIDE, for good.

EDIT: Fixed dmc stealing cycles during the sprite dma; for some reason, the test suite (as it seems) doesn't trigger a dmc fetch during the last cycles of sprite dma. I wonder if the +1 or +2 extra cycles should occur before starting the effective sprite dma transferring. The test suite display all the cycles increased by 1 - my current error. Everything looks correct, but you never knows... :(

EDIT 2: As far as I can tell you, from my tests & notes, I'd say yes, mid-instruction. I trapped DMC landing during the first 3 cycles of a STA $4014, then during the effective write. So, 3 cycles if landing before the effective write, then 2 during the sprite DMA. I wonder: since the sprite DMA takes 513 cycles, is this extra cycle clocked after the 256 fetches? :(

EDIT 3: There are DMC DMAs landing in STA mid-instruction. Currently, I'm not considerating the type of instruction it lands, but only adding cycles on reads (+4), writes (+3) or during a sprite DMA (+2, +1 or +3). Well, is this the error? Should I do another table to identify a write-instruction??? :( Ideas?

by on (#75332)
Test #1 (sprdma_and_dmc_dma.nes)
Image
It's more general and no finetuning required.

by on (#75398)
edited

I'd like some advice now. I could beat test #2 (sprdma_and_dmc_dma_512.nes) today with a patch. I have problems at lines $0A and $0B displayed: it's +1 extra clock and I was wondering why, since my DMC stealing was somewhat correct.

Image
line $0A should be 526
line $0B should be 527


Well, from line $0A of the test, there's a STA $0100 (steals 3) followed by a RTS (should steal 4) after the sprite DMA with a DMC DMA triggering right in the instruction fetch cycle, affecting lines $0A and $0B. For the later lines, it triggers after the first cycle of the RTS, so it's fine. I'm patching my DMC code to steal 3 cycles instead of 4 to get a pass.
Code:
STA $0100
RTS <---- DMC DMA occurs here (instruction fetch).
<---- later DMC DMA occurs from here.

;in the first cycle of RTS, a DMC DMA should steal 3 cycles,
;but instead, it steals 4 because it's not a write-instruction/CPU write.


Could someone help me with this?

FINAL EDIT: I was doing 512/513 cycles for sprite DMA, which looks incorrect, so an extra cycle was added. It matches the condition: DMC DMA takes 3 cycles if it lands in the last SPR DMA cycle. For now, in order to get a Passed, I must to put a DMC DMA request to steal 3 cycles after a STA $xxxx write. Probably an hack, probably reverse-engineering the test suite... but no, I just want to understand the things, and the STA+RTS is a problem: a DMC DMA lands exactly in the first cycle of the RTS, in my emulator anyways.

by on (#75440)
Image

by on (#75441)
Zepper wrote:
Image

LOL, wish I could help. This stuff is beyond my understanding :/

by on (#75442)
cartlemmy wrote:
LOL, wish I could help. This stuff is beyond my understanding :/

I believe that's the case for most of us... Probably only blargg tested stuff this obscure, and he doesn't seem to be around anymore, so...

by on (#75471)
Well, about the test suite, here's a quote from blargg:
Quote:
You can see this in the STA $100 after OAM DMA,
where DMC DMA takes three cycles for two different times.
This is because both times it's landing on the fourth cycle of STA $100.


If you think about the last cycle of an instruction sharing the next instruction fetch cycle, I believe it's ok.
As register, the final screenshot:

sprdma_and_dmc_dma_512.nes
Image
Requires a precise finetunning.

by on (#75477)
Zepper wrote:
Well, about the test suite, here's a quote from blargg:
Quote:
You can see this in the STA $100 after OAM DMA,
where DMC DMA takes three cycles for two different times.
This is because both times it's landing on the fourth cycle of STA $100.


Can you please provide the thread where this is quoted from? I didn't have to do anything weird to get these tests to pass, but I can't find the information I was using that led me to the passing result.

I'm not sure by reading through your lengthy description whether or not you are saying you had to do something you didn't think was "ordinary" to get the test to pass...perhaps you can explain what "requires precise finetune" means?

by on (#75481)
cpow wrote:
Can you please provide the thread where this is quoted from?


- Surely. The same with the test suite. :)

Quote:
I didn't have to do anything weird to get these tests to pass, but I can't find the information I was using that led me to the passing result.


- The only problem here is a DMC DMA landing in a RTS, right after a STA $0100. So, I had to request the DMC to steal 3 cycles *after* the effective write of the STA instruction.

Quote:
I'm not sure by reading through your lengthy description whether or not you are saying you had to do something you didn't think was "ordinary" to get the test to pass...perhaps you can explain what "requires precise finetune" means?


- Nothing special, but only calls to my dmc_runfor(cycles) before (certain) CPU reads/writes. During the SPR DMA, I had to follow what's written in the test suite page, regarding the number of cycles to steal depending of where in the SPR DMA a DMC DMA lands. :)