Valid addresses for program execution?

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

runaway pancake
Posts: 16
Joined: Thu Jan 05, 2012 1:52 pm

Valid addresses for program execution?

Post by runaway pancake » Thu Jan 05, 2012 2:16 pm

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.

User avatar
cpow
NESICIDE developer
Posts: 1099
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Re: Valid addresses for program execution?

Post by cpow » Thu Jan 05, 2012 2:30 pm

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.
I know there are probably quite a few that execute out of SRAM. For example:

Image

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.

beannaich
Posts: 207
Joined: Wed Mar 31, 2010 12:40 pm

Post by beannaich » Thu Jan 05, 2012 2:59 pm

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?

User avatar
cpow
NESICIDE developer
Posts: 1099
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow » Thu Jan 05, 2012 3:08 pm

beannaich wrote: Side note:
@cpow, is that tool color coded by access frequency?
Sort Of^TM.

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.

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

Post by tepples » Thu Jan 05, 2012 3:26 pm

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?

Post by runaway pancake » Thu Jan 05, 2012 3:38 pm

@cpow:
Thanks for the tip. I checked out Zelda and it starts executing out of SRAM almost immediately :lol:

@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.

User avatar
miker00lz
Posts: 235
Joined: Thu Sep 23, 2010 7:28 pm

Post by miker00lz » Thu Jan 05, 2012 5:44 pm

metroid seems to execute out of SRAM too.

User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla » Thu Jan 05, 2012 6:18 pm

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.

beannaich
Posts: 207
Joined: Wed Mar 31, 2010 12:40 pm

Post by beannaich » Thu Jan 05, 2012 6:21 pm

miker00lz wrote:metroid seems to execute out of SRAM too.
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 tiles :D

EDIT: Just tested this and it turns out that wasn't what was causing it, could have sworn that was the problem. Oh well.

User avatar
Bregalad
Posts: 8008
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Fri Jan 06, 2012 6:46 am

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.
Useless, lumbering half-wits don't scare us.

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

Post by Dwedit » Fri Jan 06, 2012 12:45 pm

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.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

User avatar
Bregalad
Posts: 8008
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Fri Jan 06, 2012 12:56 pm

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.
Useless, lumbering half-wits don't scare us.

User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla » Fri Jan 06, 2012 6:52 pm

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.
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.

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

Post by tepples » Fri Jan 06, 2012 9:31 pm

MottZilla wrote:There is no reason not to emulate this
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*.

runaway pancake
Posts: 16
Joined: Thu Jan 05, 2012 1:52 pm

Post by runaway pancake » Fri Jan 06, 2012 9:54 pm

tepples wrote:
MottZilla wrote:There is no reason not to emulate this
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.
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 8052 :P

Post Reply