Primitive wrote:
The background tiles seems to start at $100 in the .chr, and the sprites start $000.
You mean $1000? Which half of your chr-rom/ram is used by sprites, and which half is used for backgrounds is controlled by the number you write to $2000:
http://wiki.nesdev.com/w/index.php/PPU_ ... _.3E_writeYou can even use the same half for both.
Quote:
None of this is in the nerdynights tutorial...
Based on some recent posts from people who have learned from it, I am beginning to think that tutorial is not the best place to learn from since it does a lot (too much) for you. That may impede understanding more than just reading good docs like the wiki. You get the appearance of progressing quickly with it, but the second one wants to do something not described in it... bad things happen.
Quote:
edit: Okay, I think I'm starting to get it now. The data given to the .db are numbers and only treated as addresses in the .chr after they're put in RAM when DMA is used to get the actual data.
Don't refer to .db statements as .chr, because (at least in the case of the .db statements under the "sprites" label) that's just plain old ROM. CHR refers specifically to ROM or RAM that contains the actual data for the graphic tiles. (i.e. data that is 2 bits per pixel and contains an actual image) And as far as I know, the DMA doesn't deal with CHR data at all. It may pass info that refers to it to the PPU, though.
I will try to explain data to you:
When you make a .db statement, you are adding bytes to ROM. It is no different than when you write code, or incbin your CHR data. To prove it, change this code:
Code:
LDX #$00 ; start out at 0
into this:
Code:
.db $A2, $00
$A2 is what ldx # becomes, and 00 is the actual number. When that's assembled and run, you'll get the same thing.
The reason "LDX/LDA/JSR"exists is to make things easier for the programmer, but the NES NEVER sees it.
You can even do something crazy like this:
Code:
label:
ldx #$02
lda label;What ends up in the accumulator?
The answer? $A2. You have just loaded the byte following the label. That bytes just happens to be an instruction. But the NES doesn't care. It does what you tell it to do.
That's why it doesn't make sense to put # before .db statements. They're all numbers. That can't be changed while the program is run. Allowing the user to put a # before them would make it seems like there is a distinction, when there is not. And because there is not, it's just an extra character to type. Putting # before a value with lda/ldx/ldy is actually changing what byte the instruction is assembled to. (which changes its behavior.) It means it's loading that exact value, rather than value contained at that location in RAM or ROM.
Quote:
This comment in the nerdynights tutorial in particular threw me off: "load data from address (sprites + x)" That makes it sound like you are loading the actual data
You are loading the data. Or rather, you're moving it.
LDX #$00
LDA sprites,x
loads the byte immediately after sprites. As the loop continues, it keeps loading the bytes in the .db statements and storing them to $0200,x. You're doing this, because even if DMA
CAN work from ROM, you have to waste 4 bytes for every sprite and they can't move. Nerdy Nights has four sprites, using 16 bytes. DMA copies 256 bytes from whatever address you give it. That means you would have to put 240 bytes of .db $00 following the 16 bytes already there, otherwise DMA would just copy the bytes from whatever code is following the last sprite .db statement. The NES, and the DMA doesn't really make a distinction between ROM and RAM, or what you think your data should be used for.
Quote:
But you're loading the address, you never touch the data.
Incorrect, as explained above.
Quote:
The DMA loads the data, not you, ever.
You have to touch the data, so the DMA copies the right values. All the DMA does is keep you from writing all the bytes to the PPU individually.
Quote:
In retrospect, it does seem silly that I thought the entire data of the tile was loaded into the 8-bit accumulator, but I was just blindly following the instructions assuming they were correct.
The DMA has nothing to do with tile data. A "hardware sprite" on the NES is 4 bytes that describe the position, palette, and number that refers to the tile the sprite will be draw with.
The actual graphic data is in your chr, and is 16 bytes per tile, 2 bits per pixel.
Quote:
What confused me also is that you can only give the numbers as $xy to the .db directive. This makes them seem as addresses, when they are in fact numbers (numbers used as addresses later by DMA)
The only number in each hardware sprite that could be considered an address, is the one that tells the PPU which tile to draw. The others are actually used straight by the PPU.
I know I write too much, so if any of that is confusing ask a question and someone more laconic may be able to do better.