OAM/DMC DMA tests

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

User avatar
Zepper
Formerly Fx3
Posts: 3192
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: OAM/DMC DMA tests

Post by Zepper » Sat Apr 23, 2016 5:57 pm

Rahsennor wrote:
fred wrote:Isn't it easier to say that a DMA (and only one DMA) starts after an instruction finishes? Did I miss something here or is it referring to something else?
The DMA starts after the writes finish. The DMA unit has no knowledge of where instructions start and end. It can only watch the bus to see if the CPU is writing or reading, and it can only pause the CPU after a read, so it always waits for a single read to complete before it starts. The result of that read is then discarded, turning it into a dummy read.
Almost. From previous posts, the DMA won't start before the next CPU read. As I said, it doesn't trigger in the 1st write because the following cycle is the operation + another write to $4014. So, the opcode fetch (instruction read) triggers the DMA.

Rahsennor
Posts: 475
Joined: Thu Aug 20, 2015 3:09 am

Re: OAM/DMC DMA tests

Post by Rahsennor » Sat Apr 23, 2016 6:04 pm

That's what I just said. One read, then the DMA.

User avatar
Zepper
Formerly Fx3
Posts: 3192
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: OAM/DMC DMA tests

Post by Zepper » Sat Apr 23, 2016 8:11 pm

Here is the ambiguous part:
The DMA starts after the writes finish.
It's after the second write and on the next CPU read. Just to be crystal clear, sorry.

User avatar
Disch
Posts: 1849
Joined: Wed Nov 10, 2004 6:47 pm

Re: OAM/DMC DMA tests

Post by Disch » Sat Apr 23, 2016 8:39 pm

I like examples!

Code: Select all

        This code:
INC $4014
NOP

        Yields these cycles
        
read:   'INC' opcode
read:   #$14
read:   #$40
read:   $4014
write:  $4014           <- trigger
write:  $4014           <- DMA attempts to halt, can't because it's a write
read:   'NOP' opcode    <- DMA attempts to halt, success!  This becomes a dummy read
  -rd:  'NOP' opcode    <- 'alignment' dummy read **ONLY IF** DMA unit is on a 'put' cycle
read:   $xx00           <- DMA starts here .. this is a DMA read
write:  $2004           <- DMA write
...

Rahsennor
Posts: 475
Joined: Thu Aug 20, 2015 3:09 am

Re: OAM/DMC DMA tests

Post by Rahsennor » Sat Apr 23, 2016 9:06 pm

Zepper wrote:Here is the ambiguous part:
fred asked if the DMA occured after the instruction finishes. That's true, but misleading; it's the write cycles the DMA is actually waiting on. That's what the statement you just quoted was addressing.

The rest of my post explained exactly the same thing you just felt the need to correct, twice, although my choice of words was admittedly very poor. I do that a lot, and from what I gather English isn't your first language, so the miscommunication is understandable. I'll shut up now.

This is why I don't help people. :roll:

User avatar
Disch
Posts: 1849
Joined: Wed Nov 10, 2004 6:47 pm

Re: OAM/DMC DMA tests

Post by Disch » Sat Apr 23, 2016 9:19 pm

Ah.

In that case, it's worth nothing that on BRK/interrupt, the writes are NOT the end of the instruction. That is why the distinction is important. While a $4014 write can't happen during an interrupt, a DMC fetch certainly can.

More examples!

Code: Select all

        This code:
BRK

        Can yield these cycles, assuming DMC wants to fetch on the indicated cycle:
        
read:   'BRK' opcode
read:   byte following opcode
write:  $01xx push PCH      <- DMC DMA tries to halt here, fails
write:  $01xx push PCL      <- tries to halt here, fails
write:  $01xx push status   <- tries to halt here, fails
read:   $FFFE               <- tries to halt here, success -- this is a dummy read
read:   $FFFE               <- another dummy read for DMC
--rd:   $FFFE               <- 'alignment' dummy read only if DMA unit is on a put cycle
read:   $xxxx               <- DMC DMA fetch
read:   $FFFE               <- normal BRK read
read:   $FFFF

Drag
Posts: 1308
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: OAM/DMC DMA tests

Post by Drag » Sun Apr 24, 2016 1:22 am

Is it only the halting read cycle that shows up outside the 6502? Do the DMA's dummy reads not cause actual pin activity?

User avatar
Disch
Posts: 1849
Joined: Wed Nov 10, 2004 6:47 pm

Re: OAM/DMC DMA tests

Post by Disch » Sun Apr 24, 2016 1:30 am

There shouldn't be any functional difference between dummy reads and normal reads.

fred
Posts: 64
Joined: Fri Dec 30, 2011 7:15 am
Location: Sweden

Re: OAM/DMC DMA tests

Post by fred » Sun Apr 24, 2016 2:45 am

That's true, but misleading; it's the write cycles the DMA is actually waiting on.
Oh, I see! I just assumed it worked similarly to interrupts. Thanks for explaining it.

Drag
Posts: 1308
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: OAM/DMC DMA tests

Post by Drag » Sun Apr 24, 2016 10:59 am

If the CPU is interrupted during a $4016 read, it was only a single bit deletion. Is that information incorrect or is there another explanation for it? Would this also mean that an interrupted $2007 read triggers up to three extra PPU address increments?

User avatar
Disch
Posts: 1849
Joined: Wed Nov 10, 2004 6:47 pm

Re: OAM/DMC DMA tests

Post by Disch » Sun Apr 24, 2016 11:11 am

the wiki wrote:For the controller registers, this can cause an extra rising clock edge to occur, and thus shift an extra bit out. For the others, the PPU will see multiple reads, which will cause extra increments of the address latches, or clear the vblank flag.
Sounds like controller ports only process 1 extra read, but the PPU processes all of them. That suggests multiple reads do in fact take place, but 4016/7 process them in a way where some of them get ignored. Maybe they ignore successive reads similar to how MMC1 ignores successive writes?

lidnariq
Posts: 9395
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: OAM/DMC DMA tests

Post by lidnariq » Sun Apr 24, 2016 11:18 am

Disch wrote:Sounds like controller ports only process 1 extra read, but the PPU processes all of them. That suggests multiple reads do in fact take place, but 4016/7 process them in a way where some of them get ignored. Maybe they ignore successive reads similar to how MMC1 ignores successive writes?
$4016 and $4017 have no special logic to that effect. If you're seeing different behavior between $2007 and $4016, there's got to be something else going on.

Drag
Posts: 1308
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: OAM/DMC DMA tests

Post by Drag » Sun Apr 24, 2016 12:07 pm

Knowing the logic involved in generating the CLK pulse sent to the controller ports would help. /OE1 and /OE2 might be involved, though it's hard to imagine that the DMA disconnects those (seemingly unrelated) signals as well. The wiki could also be wrong, and we might be misremembering the effects of the conflict.

lidnariq
Posts: 9395
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: OAM/DMC DMA tests

Post by lidnariq » Sun Apr 24, 2016 12:11 pm

The clock pulse is exactly

NOT(A15…A0 = h'4016' AND M2 = 1 AND R/W = 1)

You can trace it in visual2a03, it's called "r4016"
Last edited by lidnariq on Sun Apr 24, 2016 4:54 pm, edited 1 time in total.

User avatar
Disch
Posts: 1849
Joined: Wed Nov 10, 2004 6:47 pm

Re: OAM/DMC DMA tests

Post by Disch » Sun Apr 24, 2016 2:44 pm

If a $4016 read is triggered on r4016 going low, then it would ignore successive reads because r4016 stays low for the entire duration (it does not toggle with phi2):


http://www.qmtpro.com/~nes/chipimages/v ... 4010fe30fe

Code: Select all


cyc      ab  db rw               pc   a  x  y  s    p          r4016
=======================================================================
1398    0084 ad 1 LDA&nbsp;Abs  0084 00 a2 00 bd Nv&#8209BdIzc   1      <- LDA $4016 
1399    0084 ad 1 LDA&nbsp;Abs  0084 00 a2 00 bd Nv&#8209BdIzc   1 
1399    0085 16 1               0085 00 a2 00 bd Nv&#8209BdIzc   1 
1400    0085 16 1               0085 00 a2 00 bd Nv&#8209BdIzc   1
1400    0086 40 1               0086 00 a2 00 bd Nv&#8209BdIzc   1
1401    0086 40 1               0086 00 a2 00 bd Nv&#8209BdIzc   1
1401    4016 00 1               0087 00 a2 00 bd Nv&#8209BdIzc   0      <- DMA halt
1402    4016 00 1               0087 00 a2 00 bd Nv&#8209BdIzc   0
1402    4016 00 1               0087 00 a2 00 bd nv&#8209BdIZc   0
1403    4016 00 1               0087 00 a2 00 bd nv&#8209BdIZc   0
1403    4016 00 1               0087 00 a2 00 bd nv&#8209BdIZc   0
1404    4016 00 1               0087 00 a2 00 bd nv&#8209BdIZc   0
1404    c001 00 1               0087 00 a2 00 bd nv&#8209BdIZc   1      <- actual DMA read
1405    c001 00 1               0087 00 a2 00 bd nv&#8209BdIZc   1
1405    4016 00 1               0087 00 a2 00 bd nv&#8209BdIZc   0      <- proper 4016 read
1406    4016 00 1               0087 00 a2 00 bd nv&#8209BdIZc   0
1406    0087 10 1 BPL&nbsp;     0087 00 a2 00 bd nv&#8209BdIZc   1      <- next instruction

Post Reply