Difference between revisions of "ROM Addressing"
(→Memory) |
|||
Line 150: | Line 150: | ||
==CPU Memory Map== | ==CPU Memory Map== | ||
+ | When the game is running, the 16bit address space on the NES is mapped out roughly like so from the [https://wiki.nesdev.com/w/index.php/CPU_memory_map CPU's perspective]: | ||
+ | {| class="wikitable" | ||
+ | !Offset | ||
+ | !Size | ||
+ | !Area | ||
+ | |- | ||
+ | |0x0000||0x800||RAM | ||
+ | |- | ||
+ | |0x2000||0x2020||Hardware Registers | ||
+ | |- | ||
+ | |0x6000||0x2000||Cartridge SRAM | ||
+ | |- | ||
+ | |0x8000||0x4000||Low PRG Bank (swappable) | ||
+ | |- | ||
+ | |0xC000||0x4000||Upper PRG Bank (fixed to bank 7) | ||
+ | |} | ||
− | + | This memory map, which is dictated by the way the MMC1 memory mapper maps memory, means that the area of memory between 0x8000 and 0xC000 is switchable. Addresses in this range can refer to any of the 8 PRG banks in the ROM (though in practice, will only ever refer to the first 7). Addresses above 0xC000, however, will *always* map to the last bank ([[PRG Bank 7]]). | |
==Bank And Offset== | ==Bank And Offset== | ||
+ | |||
+ | In order to describe a part of the cartridge's ROM, you can refer to it in terms of its bank number and offset within that bank. An address described this way could look like this: | ||
+ | |||
+ | 5:0x1234 (or bank 5, offset 0x1234) | ||
+ | |||
+ | This allows for pretty easy conversion to other addressing styles. In order to get the offset into a dumped ROM, you can use the following formula: 0x10+(bank*0x4000)+offset. The above address would be found at 0x15244. | ||
+ | |||
+ | This is a pretty rarely used way to refer to locations, but is useful to understand anyways. You can always recognize this address format by the fact that it includes a bank number and another number that is less than 0x4000. | ||
+ | |||
+ | ==Bank And Memory Address== | ||
+ | |||
+ | More convenient for working with addresses in memory, this representation is used a lot by emulator debugging interfaces in particular. As in [[#Bank And Offset]], an address in this format starts with a bank number, but the second number is its address as mapped into RAM at runtime. So, for example, the above address would be: | ||
+ | |||
+ | 5:0x9234 | ||
+ | |||
+ | All addresses in banks 0 through 6 will be represented as within the range 0x8000-0xBFFF in this format, while addresses in bank 7 will be in the range 0xC000-0xFFFF: | ||
+ | |||
+ | 7:0xD234 | ||
+ | |||
+ | Unfortunately, this format is more complicated to convert into ROM file offsets, or vice versa, because you have to know more about how the game maps memory. For Zelda II in particular, the formula for converting to a dumped ROM offset is 0x10+(bank*0x4000)+(address%0x4000) -- where % is modulus (or remainder). | ||
=Converting= | =Converting= |
Revision as of 07:18, 15 April 2021
There are several different ways to refer to data in memory in Zelda II. Which one you use depends on your reasoning for doing so. This page will explain where they're useful and how to translate between them.
Contents
ROM File
NES ROM files are in a format generally called iNES. Most ROMs (including Zelda 2 ROMs) are in iNES 1.0 format. The layout of a Zelda II ROM file is as follows (an MMC1 cartridge with 8 PRG ROM banks, 16 CHR-ROM banks, and 4KB of SRAM -- for more details see Data Crystal):
Type | Number | File Offset | Size | Contents |
---|---|---|---|---|
iNES Header | 0x00000 | 16bytes (0x10) | ||
PRG Bank | 0 | 0x00010 | 16KB (0x4000) | |
1 | 0x04010 | 16KB (0x4000) | Western Hyrule | |
2 | 0x08010 | 16KB (0x4000) | Eastern Hyrule | |
3 | 0x0C010 | 16KB (0x4000) | Towns(?) | |
4 | 0x10010 | 16KB (0x4000) | Normal Palaces | |
5 | 0x14010 | 16KB (0x4000) | Great Palace | |
6 | 0x18010 | 16KB (0x4000) | Music(?) | |
7 | 0x1C010 | 16KB (0x4000) | Global State (permanently mapped) | |
CHR Bank | 0 | 0x20000 | 8KB (0x2000) | |
1 | 0x22000 | 8KB (0x2000) | ||
2 | 0x24000 | 8KB (0x2000) | ||
3 | 0x26000 | 8KB (0x2000) | ||
4 | 0x28000 | 8KB (0x2000) | ||
5 | 0x2a000 | 8KB (0x2000) | ||
6 | 0x2c000 | 8KB (0x2000) | ||
7 | 0x2e000 | 8KB (0x2000) | ||
8 | 0x30000 | 8KB (0x2000) | ||
9 | 0x32000 | 8KB (0x2000) | ||
10 | 0x34000 | 8KB (0x2000) | ||
11 | 0x36000 | 8KB (0x2000) | ||
12 | 0x38000 | 8KB (0x2000) | ||
13 | 0x3a000 | 8KB (0x2000) | ||
14 | 0x3c000 | 8KB (0x2000) | ||
15 | 0x3e000 | 8KB (0x2000) |
Memory
CPU Memory Map
When the game is running, the 16bit address space on the NES is mapped out roughly like so from the CPU's perspective:
Offset | Size | Area |
---|---|---|
0x0000 | 0x800 | RAM |
0x2000 | 0x2020 | Hardware Registers |
0x6000 | 0x2000 | Cartridge SRAM |
0x8000 | 0x4000 | Low PRG Bank (swappable) |
0xC000 | 0x4000 | Upper PRG Bank (fixed to bank 7) |
This memory map, which is dictated by the way the MMC1 memory mapper maps memory, means that the area of memory between 0x8000 and 0xC000 is switchable. Addresses in this range can refer to any of the 8 PRG banks in the ROM (though in practice, will only ever refer to the first 7). Addresses above 0xC000, however, will *always* map to the last bank (PRG Bank 7).
Bank And Offset
In order to describe a part of the cartridge's ROM, you can refer to it in terms of its bank number and offset within that bank. An address described this way could look like this:
5:0x1234 (or bank 5, offset 0x1234)
This allows for pretty easy conversion to other addressing styles. In order to get the offset into a dumped ROM, you can use the following formula: 0x10+(bank*0x4000)+offset. The above address would be found at 0x15244.
This is a pretty rarely used way to refer to locations, but is useful to understand anyways. You can always recognize this address format by the fact that it includes a bank number and another number that is less than 0x4000.
Bank And Memory Address
More convenient for working with addresses in memory, this representation is used a lot by emulator debugging interfaces in particular. As in #Bank And Offset, an address in this format starts with a bank number, but the second number is its address as mapped into RAM at runtime. So, for example, the above address would be:
5:0x9234
All addresses in banks 0 through 6 will be represented as within the range 0x8000-0xBFFF in this format, while addresses in bank 7 will be in the range 0xC000-0xFFFF:
7:0xD234
Unfortunately, this format is more complicated to convert into ROM file offsets, or vice versa, because you have to know more about how the game maps memory. For Zelda II in particular, the formula for converting to a dumped ROM offset is 0x10+(bank*0x4000)+(address%0x4000) -- where % is modulus (or remainder).