It is currently Wed Oct 18, 2017 2:16 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: Reading NES rom in c++
PostPosted: Sat Nov 12, 2016 6:30 am 
Offline

Joined: Sat Nov 12, 2016 6:03 am
Posts: 7
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 1613 times ]
main.cpp [2.15 KiB]
Downloaded 58 times
Top
 Profile  
 
PostPosted: Sat Nov 12, 2016 6:50 am 
Offline

Joined: Mon Apr 01, 2013 11:17 pm
Posts: 437
Looks normal to me.

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


Top
 Profile  
 
PostPosted: Sat Nov 12, 2016 6:53 am 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1019
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:
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.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Sat Nov 12, 2016 9:39 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3943
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!


Top
 Profile  
 
PostPosted: Mon Nov 14, 2016 6:49 am 
Offline

Joined: Sat Nov 12, 2016 6:03 am
Posts: 7
tanx, guys. :D


Top
 Profile  
 
PostPosted: Tue Nov 15, 2016 5:30 am 
Offline

Joined: Sat Nov 12, 2016 6:03 am
Posts: 7
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


Top
 Profile  
 
PostPosted: Tue Nov 15, 2016 7:01 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19093
Location: NE Indiana, USA (NTSC)
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.


Top
 Profile  
 
PostPosted: Tue Nov 15, 2016 7:17 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10050
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group