Reading NES rom in c++

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
RomarioSilva
Posts: 7
Joined: Sat Nov 12, 2016 6:03 am

Reading NES rom in c++

Post by RomarioSilva » Sat Nov 12, 2016 6:30 am

hi, i'm programing one NES emulator, and i have problems with the rom's read. the content read is strange.
Attachments
print_out.png
print_out.png (4.76 KiB) Viewed 6473 times
main.cpp
(2.15 KiB) Downloaded 347 times

Joe
Posts: 447
Joined: Mon Apr 01, 2013 11:17 pm

Re: Reading NES rom in c++

Post by Joe » Sat Nov 12, 2016 6:50 am

Looks normal to me.

Maybe you should read about the iNES file format and the NES 2.0 file format.

User avatar
Kasumi
Posts: 1292
Joined: Wed Apr 02, 2008 2:09 pm

Re: Reading NES rom in c++

Post by Kasumi » Sat Nov 12, 2016 6:53 am

In the future, be more specific about what you expect to happen vs what is actually happening.

The first bytes of the rom are probably

Code: Select all

4E 45 53 1A 01 01 00
Zero (00, 0x00, however you represent it) is the terminator character for a char string in C.

Your program is printing 6 characters terminated by that zero, so all seems to be in order. If you want to display a printout of all the bytes as hex or something, using cout on the buffer alone is not a great way to accomplish this. You could create a formatted string of each byte as hex, or various other things.

User avatar
Dwedit
Posts: 4411
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Reading NES rom in c++

Post by Dwedit » Sat Nov 12, 2016 9:39 pm

The first thing you consider is the Memory Map. It's what the NES's CPU sees when it tries to access memory.

0000-07FF = RAM
0800-1FFF = mirrors of RAM
2000-2007 = PPU registers accessable from the CPU
2008-3FFF = mirrors of those same 8 bytes over and over again
4000-401F = sound channels, joypads, and other IO
6000-7FFF = cartridge PRG-RAM (if present), or PRG-ROM depending on mapper
8000-FFFF = cartridge memory, usually ROM.

The cartridge ROM is usually bankswitched in either 32K, 16K, or 8K chunks.

If you're starting out on an emulator, start with something simple, like a mapper 0 game such as Balloon Fight.

Loading a iNES file:
16 bytes header, parse this to get the rom and vrom size, mapper number, and flags.
PRG ROM - size depends on the header (prg size * 16K)
CHR ROM (if present) - size depends on the header (chr size * 8K)

For a simple Mapper 0 (NROM) game, the 32K of ROM appears in memory at 8000-FFFF. If it's 16k in size, it appears in memory at 8000-BFFF and C000-FFFF.
Other mappers arrange the cartridge memory differently, see documentation for more details. Some mappers have the last 16K bank of the ROM fixed into C000-FFFF.

The first instruction executed depends on the Reset Vector, and not the first byte of the PRG ROM. The reset vector is a 16-bit value read from Memory address FFFC, first the low byte then the high byte.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

RomarioSilva
Posts: 7
Joined: Sat Nov 12, 2016 6:03 am

Re: Reading NES rom in c++

Post by RomarioSilva » Mon Nov 14, 2016 6:49 am

tanx, guys. :D

RomarioSilva
Posts: 7
Joined: Sat Nov 12, 2016 6:03 am

Re: Reading NES rom in c++

Post by RomarioSilva » Tue Nov 15, 2016 5:30 am

hey guys, i have a question.
that's my example, the two first lines of hex code, when the first is the header. what byte of second line is the opcode ? can you explain ?
4E 45 53 1A 01 01 00 00 00 00 00 00 00 00 00 00
4C F5 C5 60 78 D8 A2 FF 9A AD 02 20 10 FB AD 02

tepples
Posts: 22288
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Reading NES rom in c++

Post by tepples » Tue Nov 15, 2016 7:01 am

4C F5 C5 disassembles to JMP $C5F5.

But though you start reading PRG ROM bytes immediately after the end of the header (this ROM has $4C as its first byte), you don't execute at the start of PRG ROM. For that, you have to read through to the end of the PRG ROM and look up the reset vector, which is stored at $FFFC-$FFFD. (The corresponding offset in the ROM image in iNES format depends on the mapper and PRG ROM size. In an NROM-128 game in iNES format, this is stored with its low byte at file offset $400C and its high byte in $400D.) When reset is asserted, the CPU does something very similar to the instruction JMP ($FFFC). This copies the value at $FFFC into the low byte of the program counter and the value at $FFFD into the low byte of the program counter.

User avatar
tokumaru
Posts: 12003
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Reading NES rom in c++

Post by tokumaru » Tue Nov 15, 2016 7:17 am

There's nothing specifying which bytes are opcodes, operands, or data... As far as the CPU is concerned, all bytes could be anything. The good news is that you don't need to make this distinction at all. You will simply interpret whatever the program counter points to as an opcode, and depending on the opcode, 0 to 2 bytes that follow it as its operand. The person who programmed the game is the one responsible for making sure that the program counter will never point to something that isn't an instruction, otherwise the program would most likely crash.

The initial value for the program counter is obtained from the reset vector (16-bit value at $FFFC-$FFFD). Just copy the address at that location to the program counter and start executing from there.

Post Reply