Understanding the layout of a rom.
Moderator: Moderators
Understanding the layout of a rom.
I'm having trouble wrapping my head around how the .nes file and the emulator (or cartridge/NES) interact with each other. From what I understand, the layout for a .asm file goes as such:
.iNes header : 16Bytes
PRG-ROM : 16KB blocks
CHR-ROM : 8KB blocks
Why must the CHR-ROM data come after the PRG-ROM section and why couldn't you include it right after the iNes header instead? Couldn't I tell the assembler to start at address $0000 where the NES RAM is and then include the CHR data and switch to the PRG section at $C000? It seems strange to me how the end of the section is padded to $FFFA to write the NMI/Reset/IRQ addresses, and then the CHR data goes afterwards. Wouldn't that cause the NES CPU to overflow back to $0000?
I guess my question is, how do the addresses in a .asm/nes file relate to the NES CPU? From what I'm starting to believe is the .nes file doesn't sit on the CPU addresses at all, but instead sends bits and bytes from itself towards the CPU. So the CHR-ROM data isn't actually on the NES until the PRG-ROM section 'sends' it, but I'm not completely sure. In that case, why does it matter to set the addresses in the .nes file?
.iNes header : 16Bytes
PRG-ROM : 16KB blocks
CHR-ROM : 8KB blocks
Why must the CHR-ROM data come after the PRG-ROM section and why couldn't you include it right after the iNes header instead? Couldn't I tell the assembler to start at address $0000 where the NES RAM is and then include the CHR data and switch to the PRG section at $C000? It seems strange to me how the end of the section is padded to $FFFA to write the NMI/Reset/IRQ addresses, and then the CHR data goes afterwards. Wouldn't that cause the NES CPU to overflow back to $0000?
I guess my question is, how do the addresses in a .asm/nes file relate to the NES CPU? From what I'm starting to believe is the .nes file doesn't sit on the CPU addresses at all, but instead sends bits and bytes from itself towards the CPU. So the CHR-ROM data isn't actually on the NES until the PRG-ROM section 'sends' it, but I'm not completely sure. In that case, why does it matter to set the addresses in the .nes file?
Re: Understanding the layout of a rom.
Bingo.Orsi wrote:From what I'm starting to believe is the .nes file doesn't sit on the CPU addresses at all
The iNES file describes the content of two separate ROM chips on two separate buses. The PRG ROM is connected to the CPU; the CHR ROM is connected to the PPU. You have to consider each bus separately.but instead sends bits and bytes from itself towards the CPU.
Some mappers support having everything in a single PRG ROM. The most common are UNROM (2), AOROM (7), and SNROM (1). In these cases, the cartridge has a RAM chip where the CHR ROM chip normally sits, and the program copies data from PRG ROM to CHR RAM through the PPU.
Excellent, thanks for the quick reply
. So what is the meaning of starting at $C000 instead of where the NES's PRG-ROM register begins at $8000?
I'm finding it a little confusing trying to piece together my understanding of everything from different sources, which always seem to assume or leave out little details that would make it sooo much easier.
I'm finding it a little confusing trying to piece together my understanding of everything from different sources, which always seem to assume or leave out little details that would make it sooo much easier.
The area mapped to the cartridge is actually $4018-$FFFF. Most cartridges map the PRG ROM chip into $8000-$FFFF. A 32 KiB ROM chip fills the entire area. A 16 KiB ROM chip ignores bit 14 of the address, which means that the ROM is mirrored at $8000-$BFFF and $C000-$FFFF.
Some kinds of data used by the NES CPU, such as the vectors and sampled sound, have to be in $C000-$FFFF. It's easier to explain these if the code is considered to sit at $C000 and get mirrored down than if the code is considered to sit at $8000 and get mirrored up.Orsi wrote:Why do most examples start at #C000 instead of $8000 then?
The reason that many .ORG their code at $C000 when using 16K PRG is that you can then .ORG $FFFA for the vectors and they'll be at the right place. If you told the assembler to start the code at $8000 the resulting file would be 32K.
For example this would produce 16K ($4000 bytes):
This produces 32K ($10000-$8000 = $8000 bytes)
Now you could do this but it's not obviously as pretty:
This will work fine because 16K PRG is mirrored to $C000+ so even though you defined vectors at $BFFA they'll also appear at $FFFA.
I hope that didn't come out as too confusing.
For example this would produce 16K ($4000 bytes):
Code: Select all
.ORG $C000
; some code here
.ORG $FFFA
; vectors here
Code: Select all
.ORG $8000
; some code here
.ORG $FFFA
; vectors here
Code: Select all
.ORG $8000
; some code here
.ORG $BFFA
; vectors here
I hope that didn't come out as too confusing.
Quoted for emphasis. Good thing this forum exists. Though when I first came here, EVERYONE was REALLY over my head about EVERYTHING. At least now I've taken a computer architecture class, learned C and MIPS assembler and have a basic idea of how everything works. Now I just have to learn about all the little NES-specific peculiarities, like how it mirrors memory and how you need to write to certain addresses several times to make something happen etc, but I still find the many documents lacking in the way described in the quote above. I guess the whole point of the Wiki is to solve that problem, but it, too, is very far from complete.Orsi wrote:I'm finding it a little confusing trying to piece together my understanding of everything from different sources, which always seem to assume or leave out little details that would make it sooo much easier.
Last edited by Dafydd on Wed Mar 24, 2010 8:52 am, edited 1 time in total.
That's why lately, when I answer newbie questions, I've been summarizing some of the answers on the wiki, like this.Orsi wrote:I'm finding it a little confusing trying to piece together my understanding of everything from different sources, which always seem to assume or leave out little details that would make it sooo much easier.
I think the main issue is not being able to find what you are looking for unless you already know the technical name for it. For instance, the article above is hidden in the Cartridge Board section, under NROM, in a small paragraph. That's means you'd understand enough about all the different cartridges and are looking up specs for one particular ROM. Now, do you think that kind of person would not know this information already?That's why lately, when I answer newbie questions, I've been summarizing some of the answers on the wiki, like this.
I wish I could think of a better place for it, but NROM is really the only place you see 16 KiB PRG ROM. By the time you've decided on a 16 KiB PRG ROM, you've decided on a mapper, and you can look up mapper 0 to learn more about this mapper, which leads you to the NROM page.