In this thread:
viewtopic.php?p=62690#p62690blargg mentions the DMA takes 4 cycles normally, or 3 if it lands "on" a write cycle.
But... a DMA occuring "on" a cycle is a little ambiguous... since the DMA and the write can't occur at the same time... they aren't really happening "on" each other -- one must be happening first. Or at least... that's the way my brain is conceptualizing it
So does "on" the cycle mean before it? Or after it?
STA zero page:
Code:
cycle 1) READ: opcode fetch
cycle 2) READ: operand fetch
** DMA possibility 'A'
cycle 3) WRITE: store A
** DMA possibility 'B'
Is 'A' "on" the write? Or is 'B'?
Do any of the posts referenced from
this one help?
I guess I can read those threads when i get home.
Really I was just hoping for a simple, straight answer though. I mean there's only 2 possibilities here. Either A is on the write or B is.
EDIT: Actually your posts were very interesting! The DEC $4014,X one in particular -- that is not behavior I would have expected. These answered questions I didn't know I had -- but they don't seem to ask the question in this post.
Though I can probably play around with Visual6502 to figure it out myself. I'll see about doing that this afternoon.
Ah! Yes that post seems like exactly what I'm looking for!
Thanks!
EDIT:
Here's my summary of the logic. If I'm misunderstanding anything, please correct me:
- DMC and OAM share the same DMA unit.
- DMA unit alters between read/write phases... so writes can only occur on odd cycles and [meaningful] reads can only occur on even cycles.
- When a DMA happens (either triggered by 4014 or by DMC)... the DMA allows the CPU to perform 1 cycle:
-- If that cycle is a read, it's effectively a dummy read. The CPU will need to re-perform this read after the DMA. Another dummy read is performed after this.
-- If that cycle was a write, it's performed normally. DMA allows the CPU perform another cycle.... write is performed normally, read is a dummy
- After those two cycles performed (writes and/or dummy reads), if the DMA unit is on a "write" phase, another dummy read is performed
- All dummy cycles out of the way, CPU cannot possibly be writing at this point (never more than 2 consecutive write cycles), and DMA unit is in a "read" phase. This is where the actual DMA starts.
For DMC: DMA performs 1 read cycle, and immediately returns control to the CPU
For OAM: DMA alternates reads/2004 writes consuming 512 cycles
If DMC DMA occurs during an OAM DMA, the process of cutting into the CPU has already started, so no extra dummy cycles need to be added.
Does this look correct?
Thanks a million, cpow. This is way more interesting/informative than I thought.
I just realized there are 3 consecutive write cycles in interrupts (3 stack pushes)
So maybe the "dummy cycle" process is repeated 3 times instead of 2 for the DMC. This would explain why DMC DMA takes 4 cycles instead of 3. This would also suggest the DMC expires its counter and triggers a reload during the "write" phase of the DMA unit. So write/read/write phases are dummy cycles, leaving the DMA unit on a read phase for when the value is actually fetched.
Though OAM DMA would only need to perform 1 dummy cycle -- because it has to be happening during a normal write or RMW instruction, and therefore there can't be more than 1 write cycle after the 4014 write. With 1 EXTRA cycle added only if the DMA unit is on a write phase.
EDIT:
Revised behavior summary:
"Prep Cycle" behavior:
- CPU does 1 read/write cycle.
-- If a read, that cycle is ignored (dummy) and will be repeated again next cycle
-- If a write, that cycle completes normally
OAM DMA:
- Triggered by 4014 write
- 1 prep cycle is performed. If this cycle was a write to 4014, it replaces the original written value for the DMA (page number to read from)
- If DMA unit is on a 'write' phase, do a dummy read (?from PC?) to get unit in 'read' phase.
- Perform 512 cycle transfer to $2004
DMC DMA:
- If OAM DMA in progress, no need for prep cycles. DMA unit will "cut in" the OAM operation and spend 2 cycles to read the DMC byte during the read phase, and do a dummy read (?PC?) for the write phase.
- Otherwise...
-- Do 3 prep cycles
-- DMA unit will always be on a 'read' phase at this point due to DMC freqs all being even
-- Read the DMC byte
Does
this post help? It is in the same set of threads I posted earlier. It shows the RDY for the DMC DMA being held off until after the three writes. Unfortunately I just realized the Visual2A03 links aren't working. Hm.
cpow wrote:
Unfortunately I just realized the Visual2A03 links aren't working. Hm.
Yeah, Quietust got rid of the non-expert simulator, replacing it with the expert simulator.
i.e. replace "expert.html" with "index.html" or nothing at all.
cpow wrote:
Does
this post help? It is in the same set of threads I posted earlier. It shows the RDY for the DMC DMA being held off until after the three writes.
I think I grasp the logic. Do you see any mistakes in my above summary? The most helpful thing at this point would be pointing them out.
EDIT:
Crap... no so my logic is wrong. I would have expected the DMC fetch to occur at cycle 40 if 37,38,39 were write cycles. But in your log it's happening on 42
Ugh... I need to piece all of this together.
Okay so I wanted to do my own tests with visual2a03 to corroborate what cpow did and answer a few unanswered questions.
... but I can't for the life of me get visual2a03 to do a 2nd DMC fetch.
Enabling looping doesn't work -- increasing the length doesn't work. In both cases I have the freq set to fastest speed. I would expect the 2nd read to come ~432 cycles after the first... but 800+ cycles in there's no sign of a 2nd read.
I might be able to do another 4015 write to trigger a 2nd fetch, but that limits by testing options. The whole point of this is I want a larger window of cycles before the DMA happens -- there's too few between the 4015 write and the first fetch.
Test prog (with looping) that should be producing a 2nd read but isn't:
http://www.qmtpro.com/~nes/chipimages/v ... 20300010feIs there like an APU warm up time I have to wait for? What's going on?
It also doesn't help that it keeps crashing around the 900 cycle mark =x
So... the so-called visual6502 has a flaw.
What's worst in my view... NO-BODY here to run a test program in a NES!?
Zepper wrote:
So... the so-called visual6502 has a flaw.
What's worst in my view... NO-BODY here to run a test program in a NES!?
I would love to be able to monitor reads/writes on the NES, but I have like zero hardware knowledge so I don't know how to build a rig that would allow me to test that. The only thing I can think of would be to program a custom PowerPak mapper which logs all cartridge reads/writes somehow -- but since the PowerPak is driven by the 6502's clock, I'm not sure that can even be done.
Zepper wrote:
So... the so-called visual6502 has a flaw.
It's actually Visual 2A03 (the 6502 doesn't have any DMA functionality). And what do you mean by "so-called"? That's the program's name, what else would we call it? I don't find it surprising that it has flaws, it's a very complex program.
Quote:
What's worst in my view... NO-BODY here to run a test program in a NES!?
Is this a complaint?
I mean... in easy words... you write a test rom... and someone would run it in a NES.
I don't know a thing about the
accuracy level when using a PowerPak-like device, instead of a SMB-for-tests cartridge set.
Zepper wrote:
I mean... in easy words... you write a test rom... and someone would run it in a NES.
I'm not really testing stuff as much as I'm trying to observe behavior.
Quote:
I don't know a thing about the accuracy level when using a PowerPak-like device, instead of a SMB-for-tests cartridge set.
PowerPak is no good for testing anything mapper related -- or anything cartridge side (since it is also just an emulator) -- nor is it good for testing power-on state (since the PowerPak has to run its own code before it passes control to your ROM)
But for testing any other core NES functionality, it should be fine.
Hi Disch
If the DMA-unit works like you assumed this behavior can cause errors.
Lets say the CPU executes the Opcode "LDA $2002" and the DMA gets active
in that moment the CPU requests the PPU for $2002. With the "next cpu tick"
the PPU returns PPUSTATUS with a set Vblank-Bit and clears Vblank internally.
In this next tick the CPU gets holded, the DMA takes control over the addr/data
bus and requests a byte of audio stream which will be available with the next cpu
tick. With this third tick the request to $2002 have to be repeated, cause the
previously requested byte got lost. But now the PPU returns a PPUSTATUS
without VBlank set which can result in faulty behavior of the software.
Chris
Sorry, missed that thread. But very interesting.
Forget everything i wrote before. It includes my considerations completely.