casprog wrote:Interesting, so that's why it doesn't matter where you write to within the $8000 - $FFFF range? As soon as you try to write to ROM, by design of the board, the NES knows you are performing a mapping operation / bank switch.
Exactly. More complex mappers with more than one register you can write to will snoop more address lines and select a register based on the address being accessed.
So when you write #$00 to ROM at a location where #$00 already exists, the output is basically guaranteed to be #$00 and the 'latch' then intercepts this value?
Yes, if both the CPU and the ROM chip are putting the same value on the data bus, the result is guaranteed to be that value, and that's what'll get picked up by the latch.
After a write does the NES immediately perform a read from that location in memory and see #$00?
Not "after", but "during". The CPU will fetch the write instruction from the ROM, and then output the target address to the address bus, then the value to the data bus, and will finally activate the write signal. The PRG-ROM completely ignores the write signal, and upon seeing the address on the address bus it will proceed to fetch the value at that address and output it AT THE SAME TIME as the CPU is outputting the value to be written. The mapper will then pick up on the write signal and copy the value on the data bus (which is a mix of what the CPU and the ROM are outputting) to the latch.
When I declare the following for my header:
The NES will expect 32KB for CHR right?
I put that at the top to make a few configurable parameters easier to change, so you don't have to mess with the statements that generate the iNES header a few lines down, but that's exclusively for the header, and the header is only used by emulators. An emulator will use those size fields to know how much PRG and CHR to load from the .NES file, but a real NES doesn't "load" anything, the chips are just sitting there and they each have a certain capacity and that's that, there's no need to specify the size of anything in a real cartridge.
so is that how four .incbin directives load up all the chr data needed into CHR ROM auto-magically? I'm assuming the assembler is looking for '.chr'?
An .NES file is just a "mirror" of the 2 chips contained in an NES cartridge, the PRG-ROM and the CHR-ROM, of the data that is permanently in those chips. Emulators have to load that data into their internal memory to simulate the chips, but on a real NES there's absolutely no "loading" of any kind.
Also, .CHR is only a file extension that helps us know what a file contains, but it doesn't enforce any particular format to a file... you could just as well use .BIN, .TXT, .EXE, whatever, as long as the actual contents were NES tiles. Even if you .incbin a file that doesn't contain NES tiles, as long as the size is right (exactly 8KB), the result will still be a valid NES ROM, but when run, the graphics will look like total garbage, because some other kind of arbitrary data will be interpreted as if it was CHR data.
And do these includes always need to be under .org $FFFA?
Like tepples said, that's just because the vectors are the last thing in the PRG-ROM, and the CHR-ROM data immediately follows the PRG in the .NES format.