Page 1 of 1
newbie needs answer regarding adress $4014
Posted: Mon Oct 29, 2012 5:58 pm
by klonoa
Hello everybody!
I'm currently following bunnyboys programming tutorial and for so far i more or less understand it.
But this piece of code keeps bothering me:
Code: Select all
NMI:
LDA #$00
STA $2003 ; set the low byte (00) of the RAM address
LDA #$02
STA $4014 ; set the high byte (02) of the RAM address, start the transfer
RTI
I don't know what NMI means, i do know kinda what it does. It's the piece of code that updates the sprites right?
http://www.nintendoage.com/forum/messag ... eadid=4440
I get why i need to tell the cpu where to store all the titles in the ram at ($0200)
at least that's what i understand from the tutorial:
http://www.nintendoage.com/forum/messag ... eadid=6082
Now here's my problem: I get why i would write to 2003 (because it's a ppu I/O port)
But
WHY do i need to write the higher byte to $4014??????
looking at the nes Architecture
http://www.nintendoage.com/forum/messag ... eadid=4291
I'm writing the $02 to an adress somewhere in the APU/controler I/O ports.
Sorry if this is a simple or stupid question but i could realy pull my hair out now.
Thanks in advance!
Re: newbie needs answer regarding adress $4014
Posted: Mon Oct 29, 2012 6:01 pm
by 3gengames
The first write sets a pointer to the 256-byte OAM page. Then the $02 means it points to the $0200 block of CPU RAM ($0200-$02FF) and then it transfers everything from there to sprite RAM in the PPU. It's in the APU addressing range, but it works with the PPU.

Re: newbie needs answer regarding adress $4014
Posted: Mon Oct 29, 2012 6:35 pm
by tepples
That NMI handler really should start with PHA and then do PLA before returning. Otherwise it'll change the A register behind the main program's back.
You write the destination address in OAM to $2003 and the source address in CPU memory to $4014, and then the APU stops the CPU to copy 256 bytes from the source into the PPU.
Re: newbie needs answer regarding adress $4014
Posted: Mon Oct 29, 2012 6:54 pm
by tokumaru
klonoa wrote:I don't know what NMI means, i do know kinda what it does.
On the NES, the NMI is an interrupt that fires when VBlank starts (if you have set up the PPU that way - you can optionally turn this off). Since VBlank is the time of the frame when we can freely access the PPU, anything that deals with updating sprites, backgrounds and palettes is usually in the NMI.
Keep in mind that an interrupt interrupts the program (hence the name): no matter what the CPU is doing, when an NMI fires it will save the current address and the status flags to the stack and jump to the NMI code. This is the reason we usually save any registers we plan on modifying to the stack too, so we can restore them later and the code that was interrupted can continue normally.
I get why i need to tell the cpu where to store all the titles in the ram at ($0200)
It doesn't
have to be $0200-$02FF, it could be any other 256-byte page, like $0700-$07FF, but most games go with $0200.
I get why i would write to 2003 (because it's a ppu I/O port)
Yes, that selects the target address in OAM for the bytes that will be copied from RAM. We typically start writing from $00, but apparently it's possible to start from other addresses (can be useful for sprite cycling).
I'm writing the $02 to an adress somewhere in the APU/controler I/O ports.
The reason why this register is not near the other PPU registers is that the sprite DMA is performed by the CPU, not the PPU. The NES CPU is a modified 6502, which includes audio and DMA for sprites. The CPU has this really fast built-in copy routine, which reads 256 bytes from RAM and writes them to $2004. Anyway, the value written to $4014 selects which page the 256 bytes are copied from (if you used $0700-$07FF for sprites, you'd write $07 to $4014).
Re: newbie needs answer regarding adress $4014
Posted: Tue Oct 30, 2012 10:37 am
by klonoa
I think i get it now.
So $4014 is sort of a magical address that copies everything from 0200 cpu ram to the OAM ($2004) witch the ppu uses to display the sprites.
and has nothing to do with the APU or controller IO ports.
is this drawing that i made any good? :
if it is than i pretty much got it
The oam holds a piece of memory ($00 to $FF) for the ppu to know what sprite goes where etc.
to point at an adress of that memory you write to $2003
Then you can use the magical adress $4014 it will copy everything from a given ram adress to [the given ram adress+FF] to the oam via $2004 (oam data adress)
Code: Select all
LDA #$02
STA $4014 ; i give the magic adress 02 so everything between 0200 and 02FF is copied to the oam, filling it up.
Is this about right?
Thank you very much for the great responses everyone!

Re: newbie needs answer regarding adress $4014
Posted: Tue Oct 30, 2012 10:56 am
by tepples
You appear to understand correctly.
If your program put the local copy of OAM in $0700-$07FF instead of $0200-$02FF, for example, it should write #$07 instead of #$02 to $4014. In general, it looks like this:
Code: Select all
lda #$00
sta $2003
lda #>local_oam
sta $4014
where local_oam is a pointer to the local copy of OAM, and > is the operator that returns the high byte (also called bits 15-8, also called the page number) of an address.
Re: newbie needs answer regarding adress $4014
Posted: Tue Oct 30, 2012 3:19 pm
by qbradq
Hrm, I never write anything to $2003. I see that in the power-on state it's initialized to $00, so that's good, but could this cause misbehavior if a reset occurs during a DMA event? Do I have to write to this every time I do a sprite DMA, or just once at reset?
Re: newbie needs answer regarding adress $4014
Posted: Tue Oct 30, 2012 4:55 pm
by lidnariq
It should not be necessary to write to $2003 ever; several commercial games don't.
It shouldn't be necessary to write to it at all unless you're doing something like using it for sprite priority cycling (
which apparently doesn't work very well).
Re: newbie needs answer regarding adress $4014
Posted: Tue Oct 30, 2012 6:30 pm
by tokumaru
Writing $00 to $2003 is one of those things I do "just to be sure", even if they aren't required, like clearing the decimal flag. Who knows, maybe there are PPU revisions with different $2003 behavior? I seem to remember something different about $2004 in early Famicom PPUs (something like $2004 not being readable, but I'm not sure), for example.
Re: newbie needs answer regarding adress $4014
Posted: Wed Nov 07, 2012 8:34 pm
by unregistered
klonoa wrote:I don't know what NMI means
NMI means
Non-
Maskable
Interrupt, I think...
think tokumaru told me that too.
Re: newbie needs answer regarding adress $4014
Posted: Wed Nov 07, 2012 8:40 pm
by blargg
It's funny though that virtually all systems that use a processor's NMI provide some sort of external hardware mask for it, making it maskable.