Stokes wrote: ↑
Sun Nov 08, 2020 11:18 am
Hello there. I haven't been on this site for a while, but this is a good emulator, I just want to know if the NES game is normal or changed and where does the ROM start, $10000, $8000, or $4000.
Short answer: NES ROM data starts at file address $040000. The NES ROM data itself isn't changed but NES banks are ordered differently and sometimes mirrored.
For more details...
This is HiROM and the file is mapped at $800000+. I never use file addresses in my notes. Converting SNES HiROM (not ExHiROM) address to file is: snes_addr & $3fffff
The first 4 64kb banks are reserved for the emulator ($80-$83 and $C0-C3).
In v1.1, PRG ROM starts in bank $84 while CHR ROM starts in bank $C4.
Each PRG bank will be mirrored if the mapper uses banks smaller than 32kb, this is because using DB and direct 16-bit address saves time. SNES can only change 32kb at a time. Mappers using 8kb banks will mirror in a "cascade" format because the disassembler can't cross bank boundaries. Crystalis had code crossing banks in sequential order. The data within each PRG bank remains unchanged.
Each CHR bank is added to the lower part of banks $C4+, using a different SNES bank for each 32kb of data. The CHR data is not transformed because it is compatible with SNES 4bpp layers and sprites, if you ignore the MSB of each VRAM word that is.
The iNES header is contained in a very different format for better access. This information, as well as settings, are stored at the very beginning of bank $C0.
6 lookup tables exist starting at $C00100, they are as follow:
$C00100 = PRG bank conversion for $8000-$9FFF
$C00200 = PRG bank conversion for $A000-$BFFF
$C00300 = PRG bank conversion for $C000-$DFFF
$C00400 = PRG bank conversion for $E000-$FFFF
$C00500 = CHR bank, starting SNES address page
$C00600 = CHR bank, starting SNES address bank
CHR bank size reflects the mapper's bank size rather than staying true to iNES format.
AOT compiled code start in the bank following the last CHR data and up to bank $FE. There's a bug in my assembly code that prevents using $FF for code. While AOT is done by the EXE, it is actually emulating my 65816 code so I don't have to rewrite the recompiler in 2 different languages. It is possible to trigger AOT compiler on a different emulator by simply allowing writes to ROM regions.
All addresses here are for v1.1 and are subject to change. The only static address is $80FF00 ($00FF00 file address) which is a 24-bit pointer to strings that define settings name, type, accessibility and address. These strings are used to show "advance settings" on the EXE.