no memory mapper knowledge---how do they work for PRG?

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

no memory mapper knowledge---how do they work for PRG?

Post by GradualGames »

So I've been wondering how NES game engines use memory mappers for code. I can easily imagine using them for graphics, swapping out patterns and so forth when needed, but say a game engine takes more than one PRG block. How does a game manage jumping between various locations in the code between PRG banks? Is it just when a certain address is written to, that the write is pre-empted and the bank is switched in from PRG-ROM? Or does the engine have to manually perform this switch?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

If the program writes to the PRG bank register, and the program counter is within the switched bank, instruction fetches continue immediately from the new bank. There are three ways for "trampolines", or pieces of code that handle subroutine calls between banks, to work around this:
  • Put some of the trampoline code in RAM (common on multicarts and, for some reason, Chinese-developed games). I've written a demo of this method.
  • Put identical trampoline code in all PRG banks (common on A*ROM and B*ROM, which use 32 KiB bankswitching).
  • Put the trampoline code in a fixed PRG bank (common on U*ROM or S*ROM or T*ROM).
User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

I don't think many "game engines" would take that much code really. The majority of your PRG usage will be for data anyway and not code I imagine. Many games could keep their main code in the fixed upper 16K many mappers have and use the lower 16K for swapping data in at the needed times, including sound engine update routines.
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Post by GradualGames »

I've learned a bit since my OP... I have a simple MMC1 experiment working for example. This has led me to speculate more about how I will be using mappers as I develop a game engine.

Is bankswitching virtually instantaneous? That is to say, could your update routine actually swap in a 16k PRG block for each large chunk of your game engine, and call individual routines within those? For example (pseudo):

Update (a routine in the fixed PRG block):
-swap in massive 16k music engine
-jump to appropriate update routine in the music engine
-swap in massive 16k AI engine
-jump to appropriate update routine in the AI engine
-swap in massive 16k map decoding engine
-jump to appropriate update routine in the map decoding engine

While this example may be extreme, I would assume this sort of thing would be plausible since bankswitching, from what I understand, simply "points" certain address lines at different locations in a ROM, no data is actually being copied.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

ZomCoder wrote:While this example may be extreme, I would assume this sort of thing would be plausible since bankswitching, from what I understand, simply "points" certain address lines at different locations in a ROM, no data is actually being copied.
You are 100% right. There is no real overhead caused by bankswitching other than the time the necessary instructions take. For the MMC1 there is a bit of a waste because of all the shifting and multiple writes, but it should still be reasonable to switch banks some 10 times or more in a frame.
Post Reply