Valid addresses for program execution?
Moderator: Moderators
-
runaway pancake
- Posts: 16
- Joined: Thu Jan 05, 2012 1:52 pm
Valid addresses for program execution?
I've searched everywhere but can't find an answer to this. Do any games execute instructions from outside of 0x8000-0xFFFF? I'm writing my cpu and memory handler now and I need to squeeze all the speed I can out of them. I ran into this problem when running blargg's instr-test-v3 single test roms and executing from cpu ram.
- cpow
- NESICIDE developer
- Posts: 1097
- Joined: Mon Oct 13, 2008 7:55 pm
- Location: Minneapolis, MN
- Contact:
Re: Valid addresses for program execution?
I know there are probably quite a few that execute out of SRAM. For example:runaway pancake wrote:I've searched everywhere but can't find an answer to this. Do any games execute instructions from outside of 0x8000-0xFFFF? I'm writing my cpu and memory handler now and I need to squeeze all the speed I can out of them. I ran into this problem when running blargg's instr-test-v3 single test roms and executing from cpu ram.

The red lines in the dark yellow band just above the line directly in the middle are the CPU executing out of SRAM when running Zelda. The image is a 256x256 matrix of the CPU memory space. The bottom half is cartridge memory [$8000-$FFFF]. SRAM is just above that, and takes up the bottom quarter of the top half [$6000-$7FFF].
The yellow dot-dash pattern in the middle of the top half is the APU registers [$4000-$4017]. Above that, the PPU registers [$2000-$2007]. Finally at the very top, CPU RAM [$0000-$0800]. Of course, I'm sure there's games that execute out of RAM, too.
Technically speaking, games could execute out of any portion of memory they want. There is no enforced boundaries on the PC, it operates in the 16-bit range, and all values are valid.
As to how many games ACTUALLY do this, I can only speculate that it's very few.
But for accurate emulation, the PC should be allowed to point to any address in the 16-bit range. And fetch instructions from where it happens to be pointing.
Side note:
@cpow, is that tool color coded by access frequency?
As to how many games ACTUALLY do this, I can only speculate that it's very few.
But for accurate emulation, the PC should be allowed to point to any address in the 16-bit range. And fetch instructions from where it happens to be pointing.
Side note:
@cpow, is that tool color coded by access frequency?
- cpow
- NESICIDE developer
- Posts: 1097
- Joined: Mon Oct 13, 2008 7:55 pm
- Location: Minneapolis, MN
- Contact:
Sort Of^TM.beannaich wrote: Side note:
@cpow, is that tool color coded by access frequency?
EDIT: The red/green/yellow/cyan/magenta coloring represent different CPU accesses. Instruction fetching, memory read, memory write, DMA to PPU, DMA for APU.
It has a fade-out so accesses further in the past appear darker than accesses closer to the present. Much like ICU64's display of the same from the C=64 emulator.
It'd be interesting to change it to frequency though...perhaps I'll play with that.
Multicart engines and games with 32 KiB bankswitching are likely to execute code from RAM, as it's the most reliable place to put a trampoline for switching banks. The protection for Earthworm Jim 2 has a really convoluted way of constructing a mapper driver at the end of RAM. And some of the later games point the NMI vector at RAM so that they can change NMI handlers in mid-game.
-
runaway pancake
- Posts: 16
- Joined: Thu Jan 05, 2012 1:52 pm
Re: Valid addresses for program execution?
@cpow:
Thanks for the tip. I checked out Zelda and it starts executing out of SRAM almost immediately
@beannaich:
I know there's no contraints on the PC, but I need to cut as many corners as I can.
@tepples:
Interesting. I figured it would be rare, but that makes sense for the 32KB bank switching.
Thanks everyone.
Thanks for the tip. I checked out Zelda and it starts executing out of SRAM almost immediately
@beannaich:
I know there's no contraints on the PC, but I need to cut as many corners as I can.
@tepples:
Interesting. I figured it would be rare, but that makes sense for the 32KB bank switching.
Thanks everyone.
Bart Vs Space Mutants copies and runs code from RAM too. Some emulators don't properly handle MMC5's ExRAM which is mapped at $5C00 to $5FFF, as I discovered while making a hack that wanted to use ExRAM as storage for executable program code. You may be able to gain some performance by being less flexible but you must figure out if that is worth the performance gain. On a typical platform like PC, it is not. But on others like mobile devices or old consoles it may be worth it.
This was one of the first bugs I ran into with my emulator. I wasn't handling $E000.4 properly, and the game is unplayable because the screen is covered in background tilesmiker00lz wrote:metroid seems to execute out of SRAM too.
EDIT: Just tested this and it turns out that wasn't what was causing it, could have sworn that was the problem. Oh well.
I think executing from RAM or WRAM is quite common.
There is various reasons you could do that, but this allows self-modifying code (which is potentially faster than normal code), it allows you to store code in CHR-RAM and even to compress it.
Personally I used it in my engine for sprite mazing routine, which should be very fast as it has to be called very often so instead of wasting time to check various variable for sprite cycling I just modify the code that write sprites itself directly.
At least Dragon Quest games, Double Dragon games, Rad Racer, Final Fantasy II and III executes code from RAM, but probably a lot of games I haven't checked does this.
There is various reasons you could do that, but this allows self-modifying code (which is potentially faster than normal code), it allows you to store code in CHR-RAM and even to compress it.
Personally I used it in my engine for sprite mazing routine, which should be very fast as it has to be called very often so instead of wasting time to check various variable for sprite cycling I just modify the code that write sprites itself directly.
At least Dragon Quest games, Double Dragon games, Rad Racer, Final Fantasy II and III executes code from RAM, but probably a lot of games I haven't checked does this.
Useless, lumbering half-wits don't scare us.
Dragon Quest 1 had no WRAM. It's CNROM. Map data was stored in CHR-ROM.
But lots of games which were originally for the FDS used WRAM to store code, probably to simplify porting the game.
And back to the original topic:
There are several "Invalid" places to run code from: The PPU ports area (2000-3FFF), and sound/system ports area (4000-401F). Any jump that goes there is certainly a crash. I don't even attempt to emulate executing code from there.
But lots of games which were originally for the FDS used WRAM to store code, probably to simplify porting the game.
And back to the original topic:
There are several "Invalid" places to run code from: The PPU ports area (2000-3FFF), and sound/system ports area (4000-401F). Any jump that goes there is certainly a crash. I don't even attempt to emulate executing code from there.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
I meant DQ1 also stores CODE in CHR-ROM, copy it to RAM (not WRAM, just internal RAM at $000-$7ff) and execute it from here.
If you emulate $200x and $400x reads correctly then you can emulate executing code here (even if it's pointless), because executing code is just reading opcodes/arguments to some memory locations.
If you emulate $200x and $400x reads correctly then you can emulate executing code here (even if it's pointless), because executing code is just reading opcodes/arguments to some memory locations.
Useless, lumbering half-wits don't scare us.
Exactly. There is no reason not to emulate this, or atleast provide the CPU something. You don't have to go to the trouble of simulating open bus behavior or anything like that, but it is a fact that the real hardware could execute at those addresses and it is in theory possible to have a program rely on proper behavior from this. Some games do except certain open bus behavior to happen afterall.Bregalad wrote: If you emulate $200x and $400x reads correctly then you can emulate executing code here (even if it's pointless), because executing code is just reading opcodes/arguments to some memory locations.
Unless your target platform's CPU is so slow that the only way to make an NES emulator's CPU core run in real time is to deeply special-case the common case of opcode fetches from $0000-$1FFF and $5C00-$FFFF, as opposed to making opcode fetches use the same peekPRG() function that loads and stores use. Nintendo handhelds and old Pocket PC PDAs are probably the only widely used platforms that are this slow. But that's probably why PocketNES doesn't "even attempt to emulate executing code from there." PocketNES even has a problem with crossing the bank boundary from $BFFF to $C000 in some mappers *cough*Magic of Scheherazade*cough*.MottZilla wrote:There is no reason not to emulate this
-
runaway pancake
- Posts: 16
- Joined: Thu Jan 05, 2012 1:52 pm
Yeah this is basically my case. My emulator will be running on a PIC or an AVR, but I haven't decided yet. I'm currently debugging on a board with a souped up 8052tepples wrote:Unless your target platform's CPU is so slow that the only way to make an NES emulator's CPU core run in real time is to deeply special-case the common case of opcode fetches from $0000-$1FFF and $5C00-$FFFF, as opposed to making opcode fetches use the same peekPRG() function that loads and stores use. Nintendo handhelds and old Pocket PC PDAs are probably the only widely used platforms that are this slow.MottZilla wrote:There is no reason not to emulate this