Mapper/board naming (was: Who edited the AOROM page?)

Discussion about the site's wikis, including bugs/issues encountered.

Moderator: Moderators

User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Did someone edit the AOROM page?

Post by tokumaru »

Bregalad wrote:
- 512 KiB of data is awkward to manage with only 32KiB at-a-time banking and only 2 KiB of internal RAM.
I don't think it's awkward to manage
I agree. 32KB out of 512KB isn't any harder to manage than 32KB out of 256KB.
32k banks also means less banks, so easier to manage.
Interesting point, but I don't know if I agree with this. Even though there are less banks, you have to think more carefully about how you'll organize the code/data within them, always considering how the game engine will work, in order to minimize the amount of bankswitching operations per frame and the amount of data you have to copy to RAM.
Also the size of PRG banks has no relationship ever with RAM size.
I think lidnariq's reasoning was that since you can only have one bank mapped at any given time, you can't access data from multiple banks at the same time, and with more RAM you could copy the data from one bank, swap another bank in and you'll effectively be accessing data from 2 different banks. Again, the total ROM size is mostly irrelevant anyway, so 512KB isn't any harder to manage than 256KB. If anything, 512KB would make things easier because you'd be able to duplicate some of the data to combine it with other things in different banks.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Did someone edit the AOROM page?

Post by tepples »

With 256K or more you could almost organize the game as a multicart. Perhaps that's why Battletoads includes such diverse play styles.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Did someone edit the AOROM page?

Post by rainwarrior »

I'm quite fond of 32k banking. I like to divide the banks by function, e.g. one for music, a few for level maps, one for CHR tiles, one for gameplay code, etc.

The only thing I find it really unsuitable for is DPCM, unless you want to duplicate your samples across all banks that may be used during playback, but I am happy to live without.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Did someone edit the AOROM page?

Post by tepples »

How big is your game's NMI handler? If you hit a lag frame, the CPU could be in any bank while it executes.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Did someone edit the AOROM page?

Post by tokumaru »

tepples wrote:How big is your game's NMI handler? If you hit a lag frame, the CPU could be in any bank while it executes.
The NMI code present in all banks could very well be a stub, like the Reset handler, that selects the bank with the actual code and jumps to it. The only difference is that you have to remember the index of the previous bank, in order to restore it before returning from the NMI.

The good thing is that you don't even have to sacrifice any time detecting whether the NMI interrupted the frame calculations, since the 32KB banking scheme allows you to change the CPU vectors. When there is no lag, you can safely select the NMI bank (which has the NMI vector point directly to the NMI handler) before waiting for VBlank. On the other banks, the NMI vector points to the stub NMI.
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Did someone edit the AOROM page?

Post by thefox »

tepples wrote:How big is your game's NMI handler? If you hit a lag frame, the CPU could be in any bank while it executes.
Who cares? Just duplicate a tiny NMI handler that saves the bank, switches in the correct bank, and jumps to the real NMI handler. Doesn't take many cycles.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Did someone edit the AOROM page?

Post by rainwarrior »

Every bank has an NMI, RESET and IRQ vector, and corresponding code, obviously (though I'm not actually using IRQ for anything, it's just an RTI).

The bank switching routine is organized like a function call, it pushes the current bank number, changes banks, executes the routine from that bank, returns to finish by popping the original bank number and switching back to it before RTS to the place the banked routine was called from.

For an NMI, you can either have one true NMI routine and have all the other NMIs bankswitch to it, or simply duplicate it in each bank. For the time being, I'm duplicating it in each bank, since it's the simpler solution. The NMI itself is currently about 480 bytes of code (some is unrolled loops that could be taken in if needed). I don't really anticipate needing to save those bytes, but if I need them back, there's enough time left in vblank to include a bank switch (the NMI just does OAM DMA + 32 byte palette + 32 byte nametable, not too heavy a load).


As an aside, I really enjoy that the cc65 toolchain's separation of assembling and linking lets me assemble common code only once before linking it in all the banks that need it. (Assembling doesn't really take a significant amount of time, I just enjoy the conceptual efficiency.)


Also, the music runs in the NMI handler, but all of its code is in its own bank. This is obviously not part of the 480 bytes I just mentioned. The music routine would never run a whole frame, but I have a flag anyway to prevent a re-entrant NMI.

I actually turn the NMI once at startup, and then my game never turns it off. This lets the music continue while screen transitions are being uploaded with rendering off, etc. and as I was getting at above, there's no need to worry what bank was active when the NMI hit (lag frames or otherwise). When a bank call is made it remembers via the stack to return to the calling bank; that's all you need to do to keep it robust.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Did someone edit the AOROM page?

Post by tokumaru »

Back when I learned what mappers were, I thought working with 32KB banks would be very limiting, but now I realize that's not necessarily the case.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Did someone edit the AOROM page?

Post by rainwarrior »

I think it's no more limiting than most other arrangements.

With 16k or 8k banks you have more fragmentation, wasted space that you can't fill at the edges of each smaller bank. On the other hand, you don't have to duplicate code, as you can have one bank of code read data from many banks. 8k banking is especially useful for Sunsoft style DPCM banking, if that's the kind of soundtrack you want.

With 32k banks you have the least amount of fragmentation, almost no ROM layout tetris to do, but some amount of code duplication is unavoidable. For example, in my case, the level unpacking code appears in each level data bank. DPCM duplication is another potential source of waste space, and multiple DPCM banks is probably out of the question.

So, the space tradeoff is probably a wash. DPCM is the biggest issue, in my opinion, but it depends on your soundtrack goal.
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Did someone edit the AOROM page?

Post by thefox »

rainwarrior wrote:As an aside, I really enjoy that the cc65 toolchain's separation of assembling and linking lets me assemble common code only once before linking it in all the banks that need it. (Assembling doesn't really take a significant amount of time, I just enjoy the conceptual efficiency.)
How did you do it? I thought code duplication in cc65 was only realistically possible with macros.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 568
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Did someone edit the AOROM page?

Post by Jarhmander »

Well, if you assemble each bank separately, include the shared code in each bank but don't export its symbols, and carefully craft a linker script, it is certainly possible. These are examples from blargg.
((λ (x) (x x)) (λ (x) (x x)))
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Did someone edit the AOROM page?

Post by rainwarrior »

It's simpler than that. I just link each bank separately and combine the resulting binaries into the NES ROM. This way there's no potential conflict between symbols.

You don't need to link them together because 32k banks don't need to know about each other's symbols. The only interaction between banks is through the banked calls, which go through switching routine I described which has to be at a fixed location anyway. Similarly, all of my RAM reservations are gathered into a single object that gets linked with all of them.


You could link them all together, sure, but then you have to resolve the symbol conflicts. I did this in the past by using .scope around an .include of a shared code file, but once I realized the different banks didn't need to be linked together I abandoned this approach.
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 568
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Did someone edit the AOROM page?

Post by Jarhmander »

Ok, so each used 32K bank is a memory region in your linker script, and you use the file attribute to link banks individually to output files and then, in the next pass, you make a NES file out of the generated binary files, with a script or another asm file that incbins each bank? Or you forget the file attribute altogether and just generate several differently named bin files? (could easily be done that way with a makefile, and indeed be even easier)
((λ (x) (x x)) (λ (x) (x x)))
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Did someone edit the AOROM page?

Post by rainwarrior »

No, I'm not using multiple output files in a single link. Each bank is its own separate link operation. They all use the same linker CFG, which looks like this, currently:

Code: Select all

MEMORY {
	ZP:       start = $00,   size = $100,  type = rw, file = "";
	STACK:    start = $100,  size = $100,  type = rw, file = "";
	BSS:      start = $200,  size = $600,  type = rw, file = "";
	PRG:      start = $8000, size = $8000, type = ro, file = %O, fill = yes, fillval = $EA;
}

SEGMENTS {
	ZEROPAGE: load = ZP,     type = zp;
	STACK:    load = STACK,  type = bss;
	OAM:      load = BSS,    type = bss, start = $200;
	RAM:      load = BSS,    type = bss;
	ALIGNED:  load = PRG,    type = ro,  start = $8000, optional = yes;
	CODE:     load = PRG,    type = ro;
	DATA:     load = PRG,    type = ro;
	FIXED:    load = PRG,    type = ro,  start = $FE00;
	VECTORS:  load = PRG,    type = ro,  start = $FFFA;
}
I just concatenate the header and binaries after linking.

ALIGNED is a place for a couple of timing critical routines, so I can be sure they don't cross a page.

FIXED is the place for the bankswitch routine, though I have also put my common NMI routine here.
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: Did someone edit the AOROM page?

Post by Drag »

Couldn't you hypothetically extend AxROM to a size as big as 4 MB with an octal latch? You wouldn't even need to move the nametable select bit if you didn't want to break compatibility with smaller AxROM games.
Post Reply