This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Basic mapperless PGR bank switching. How?

Basic mapperless PGR bank switching. How?
by on (#112961)
Hello everyone!
This is my first post.

So I've been making a couple of small NES projects lately, using shiru's library with famitone and the CC65 compiler.
Recently however I started on a bigger project - I'm making a complete game (I felt I had the skills).
Previously I've been satisfied with the NROM128 (16k pgr, 8k chr) - but now I'm feeling greedy and want double the pgr space.

My game is pretty much split in two parts (the tavern is one part, it has all the story; and the other part, the dungeon crawling has the actual game).
So I thought this would make perfect sense: put all the item data and text data in the first bank,
and then switch banks and have the monster data, quest structure and dungeon structure in the second bank.

My question is how do I accomplish this? Shiru didn't write much about this subject in his document.
Basically the functionality I want is "put the following constant variables and code in bank 2" and then in the runtime to be able to say "change to bank 2 and run this new gameloop function".

Thanks a lot in beforehand,
// Mattias from Sweden

PS: I'll gladly put your name in the special thanks of the credits (if you'd like) for any help you can give me. Thanks.
Re: Basic mapperless PGR bank switching. How?
by on (#112963)
There's no such thing as "mapperless bankswitching", you can only switch banks by using a mapper. However, you can go up to 32KB without a mapper, so you can double up the ROM as you wanted to, there's just no switching involved at all, all 32KB are accessible linearly at all times, from $8000 to $FFFF (you are probably only using $C000-$FFFF now).
Re: Basic mapperless PGR bank switching. How?
by on (#112964)
I like to use AxROM and organize banks by function. It banks the entire 32k space at once, so it's very simple to use.

I can put my music player and all music data in one bank, put all the level data and level decoding in another bank, all the graphics data and CHR decoding/loading in a third bank, all the gameplay code in a fourth bank, etc. Generally you don't want to use any DPCM with this scheme (unless you want to duplicate the DPCM data in every bank), but other than that I find it a really convenient way to divide the banks.
Re: Basic mapperless PGR bank switching. How?
by on (#112965)
Quote:
There's no such thing as "mapperless bankswitching", you can only switch banks by using a mapper.

I'm terribly disappointed, I was under the impression he invented a technique. :lol:

That being said, mapperless bankswitching could be done by manually taking a cart out of your NES and instert another one. Not the most simple, true, but it'd be "mapperless bankswitching".
Re: Basic mapperless PGR bank switching. How?
by on (#112966)
Maybe maninboots is using an assembler that has a builtin notion of banks (like nesasm) and is asking how to tell the assembler which bank to use? But if that's the case, we'll need to know what assembler it is, since they all do it differently.
Re: Basic mapperless PGR bank switching. How?
by on (#112968)
tokumaru wrote:
all 32KB are accessible linearly at all times

Ok, now I feel a bit stupid.
But does it still have two banks technically?
I ask because of this line in shiru's docs "It has two 16K PRG ROM banks, so 32K in total for code and data.".
Anyways, I'm close to crossing the 16KB mark of data, so I'll see what happens soon enough.
Thanks for your quick answer!

rainwarrior wrote:
I like to use AxROM and organize banks by function. It banks the entire 32k space at once, so it's very simple to use.

I will keep that in mind if I ever need to upgrade to a rom with a mapper.

Bregalad wrote:
mapperless bankswitching could be done by manually taking a cart out of your NES and instert another one

I wonder if you could create a mechanical cart to do this for you on command - without it crashing. Hmmm.... =P

Quietust wrote:
we'll need to know what assembler it is, since they all do it differently

I don't know if I can answer that myself. I use cc65, which includes a compiler, linker (cl65), assembler (ca64) and more.

I'm sorry, everyone, for wasting your time. Happy to know that the nesdev community is this quick to answer though.
Thanks
Re: Basic mapperless PGR bank switching. How?
by on (#112975)
maninboots wrote:
But does it still have two banks technically?

We often refer to 16KB chunks as banks on the NES because that's the basic unit used by the iNES header, but hardware-wise, there's no reason to say that the 32KB of ROM the NES can see are banked in anyway, as the console itself doesn't impose any sort of separation between the two halves. In reality, the size of a bank is defined by the mapper being used: some use 32KB banks, others 16KB and some even 8KB.
Re: Basic mapperless PGR bank switching. How?
by on (#112988)
Is it possible to do chipless bankswitching by rerouting CHR pins to select the high PRG bank?
Re: Basic mapperless PGR bank switching. How?
by on (#112989)
Dwedit wrote:
Is it possible to do chipless bankswitching by rerouting CHR pins to select the high PRG bank?
It doesn't look like it to me. "If there are less than 8 sprites on the next scanline, then dummy fetches to tile $FF occur for the left-over sprites..."

But, maybe it is possible to do chipless bankswitching by using the IRQ (if IRQ is disabled), by connecting it to OUT2 in the Famicom expansion port. (But this would still use something other than the cartridge being required.)
Re: Basic mapperless PGR bank switching. How?
by on (#113005)
The only way I can think of is to use WRAM, compress your program data, and decompress it to WRAM as needed. :P You wouldn't want to do this multiple times per frame though (so you wouldn't want to decompress your music engine every frame), just for the sections of the game where it'd make sense to insert a (hypothetical) loading screen. You could also compress your music, and whenever you load a track, you decompress it to WRAM.

I dunno, does this count? You technically don't need a mapper to put WRAM on the cart.

Now in the actual heyday of the NES, I don't know if this would have any advantage over just simply using a discrete mapper and using a larger ROM chip.

Edit: You could also use the FDS! :V
Re: Basic mapperless PGR bank switching. How?
by on (#113008)
Super Mario Bros. already uses streaming decompression of map data from ROM.

Or you could add an IC that implements SPI or I2C, and then load things from a flash chip into RAM. It's how saves worked on Bandai's Dragon Ball games, and you could make your own home-grown solid-state FDS-alike that way.
Re: Basic mapperless PGR bank switching. How?
by on (#113011)
Drag wrote:
I dunno, does this count? You technically don't need a mapper to put WRAM on the cart.

Yeah but you need a chip to decode WRAM, and if you count the WRAM as a chip you've now got 2 chips for you 'chipless' bankswitching...

And FDS is MUCH more than a single chip, so that hardly counts as chipless bankswitching.

A discrete mapper costs about a dime by itself... If you really just simply want more ROM then splurge on the small cost of one. The extra ROM will actually cost you more than the mapper anyways.

tepples wrote:
Or you could add an IC that implements SPI or I2C, and then load things from a flash chip into RAM. It's how saves worked on Bandai's Dragon Ball games, and you could make your own home-grown solid-state FDS-alike that way.

Yes, serial ROM unloaded/decompressed into RAM is the key to unlimited ROM for dirt cheap expansion cost. :)
Re: Basic mapperless PGR bank switching. How?
by on (#113022)
infiniteneslives wrote:
Drag wrote:
I dunno, does this count? You technically don't need a mapper to put WRAM on the cart.

Yeah but you need a chip to decode WRAM, and if you count the WRAM as a chip you've now got 2 chips for you 'chipless' bankswitching...

We're talking about mapperless, not chipless. :P You still have a point though, the cart has to decode the RAM address itself, rather than the NES just doing it for you and giving you a /RAMSELECT pin. Therefore, the RAM chip would be the only IC on the cart that didn't just directly use a signal that came from the NES, but instead, used a signal generated from circuitry within the cart. I guess that'd make a WRAM circuit qualify as a mapper, even if there aren't any bankswitching capabilities of any kind. :P
Re: Basic mapperless PGR bank switching. How?
by on (#113024)
There is also the NROM-368 option, which also works for CxROM and Sunsoft-1 mappers!

http://wiki.nesdev.com/w/index.php/NROM-368
Re: Basic mapperless PGR bank switching. How?
by on (#113025)
Dwedit wrote:
Is it possible to do chipless bankswitching by rerouting CHR pins to select the high PRG bank?
Possibly you can, although there will be some restrictions. If most banks have the same code and then some have data which is loaded into RAM sometimes, if it can be loaded when rendering is disabled, then it might be possible, because then you can adjust the CHR address.
Re: Basic mapperless PGR bank switching. How?
by on (#113075)
Dwedit wrote:
Is it possible to do chipless bankswitching by rerouting CHR pins to select the high PRG bank?

If you don't mind sacrificing half of the pattern tables (set both BG and sprites to use $0000-0FFF), you could tie CHR A12 to A15 of your PRG ROM. That would give you 64k PRG (two 32k banks at $8000-FFFF), but it'd be tricky to work with:

To access the second bank, you'd need to point the PPU to either $1000-1FFF, or $3000-3FFF, and do it at a time where the PPU will stay there, such as from within vblank (Warning: the bank will spontaneously switch back to the first bank once vblank ends) or while rendering is off (safest). Obviously, this means you cannot manipulate the palette unless you do it from the second bank.

You must set both the bg and the sprites to use $0000-0FFF, or else the screen rendering will cause spontaneous bank switches.

Since the second bank isn't freely available, you'd only be able to store data there that you can fetch during a screen transition, or from within vblank (if you can do it before it ends, that is). An interesting idea would be to use 4kb CHR-RAM, to compensate for the reduced pattern table. To load tiles from the first bank, write them to $0xxx; to load them from the second bank, write them to $1xxx. I personally would keep the graphics in the second bank, since the only time you can update the pattern tables coincides with the only time you can access the second bank. :P
Re: Basic mapperless PGR bank switching. How?
by on (#113469)
Is anyone going to actually try this? This literally is bankswitching without a mapper. Christ, compared to using the internal nametable ram as chr-ram (which people were willing to try!), this is luxury. :P
Re: Basic mapperless PGR bank switching. How?
by on (#113475)
It's quite restrictive and takes a large hit to your tileset which is presumably only 8KB to start before you slice it in half. All for what? Saving 10cents on not putting a discrete mapper on the PCB. Yeah you're saving 10cents on a board design, but it's hard to begin to think the large cost you have to the loss in PT data and restricted access to your extra 'bank' is somehow worth all the hassle.

The only point to try what you're saying is just for an exercise. There's no real value there worth expending the effort to try it out...

If you're that excited about it try it out yourself! :) We're not stopping ya, and we'll be here to comment on your results as always. ;)
Re: Basic mapperless PGR bank switching. How?
by on (#113625)
Heh, sorry, I guess I fell into my trap of taking this place too seriously again. :P

I saw someone wanted to know if there were a way to do some form of bankswitching without needing any mappers or additional cart components (it's an interesting puzzle!), and just assumed there must be a legitimate interest for such a thing, and due to my assumption, I got really disappointed when a week went by without anyone making any comments (neither good nor bad, just zero feedback), after I pieced together a way to do it.

In fact, this very thing has been a source of repeated frustration on my end, and for the longest time, I was really put off by this community because of it, but considering how it seems to only be a problem with me personally, I guess the person at fault here is me, with just an interest in solving puzzles and wanting to contribute something useful, except that no contribution is actually desired.

My bad! I'm still working on this issue of mine, and I'll continue to work on not taking it so hard when nobody cares. :P

infiniteneslives: That's basically the response I was expecting out of everyone, but then... there wasn't an "everyone". :P And yeah, I agree, such bankswitching would be a bit of a hurdle, and I'm not sure it would be cost-worthy, but none the less, it's doable. :P
Re: Basic mapperless PGR bank switching. How?
by on (#113633)
Drag, I have the same issue :D I did finally get over no one giving a rat's butt about my assembler, which by the way is the best assembler ever ;)

I thought your solution was rather interesting. I could see this being very useful for applications that wouldn't need much character space, like a text adventure. In a similar way to how we use VBlank to update the PPU, in such a program you might have a VBlank handler that pulls data from storage banks.

I might have to write up a Nintendulator mapper for this :) It's so interesting and it'd be a nice break from what I'm working on.
Re: Basic mapperless PGR bank switching. How?
by on (#113636)
Yeah, one thing you have to realize to is this topic started off as a completely different question. We then took off and ran with our babbling in typical fashion and started dreaming up mapper ideas like we all love to do.

The other thing is if you come up with an idea you love and want to see come to life, generally you've got to to the heavy lifting yourself. Other people may like your idea and think it's novel, but they have ideas of their own generally and desire to spend time doing the things they dream up. It's not us 'not caring' it's just a discussion that we enjoy engaging in regardless of whether what we're rambling on about will ever see the light of day. It's just the nesdev way...

Don't be too hard yourself. For me personally and many here, I think my signature sums up this dilemma. ;)
Re: Basic mapperless PGR bank switching. How?
by on (#113637)
Interestingly, this might play nicely with mapper 218 (chrless). It looks like you might even be able to "free up" PPU A11 by restricting the tiles used to the lowest 128, and always fixing Y scroll to 0. A10's definitely not available because of the 34 pattern table fetches per scanline.

In terms of practicality, cribbing something from the Vs. System and connecting OUT2 to an expansion port pin makes for a saner experience. But this idea is kinda hilarious to me.
Re: Basic mapperless PGR bank switching. How?
by on (#113643)
NES Dev: Dream big, make puzzle games
NES Dev: Now serving mapper 18,473
NES Dev: Where the OP stops caring long before anyone else does

Take your pick with this one :)

I'm not very clear on how to use the expansion pins on the NES cart edge. How do those work exactly? I thought they were somehow software controllable, but I can't seem to find documentation about that. Also, does anyone know if they function of Famiclones?
Re: Basic mapperless PGR bank switching. How?
by on (#113649)
qbradq wrote:
I'm not very clear on how to use the expansion pins on the NES cart edge. How do those work exactly? I thought they were somehow software controllable, but I can't seem to find documentation about that.
Normally the pins EXP0..EXP9 are completely unconnected. Very few things (MMC5, the Expansion port test cartridge) used them in its commercial lifetime. A few others are used by 60-to-72 pin converters and the CopyNES.

The OUT1 and OUT2 pins from the CPU are on the 48-pin NES expansion port, so a wire could connect either or both to an underallocated EXPx pin to make those signals available to any cartridge. This is probably what I'd do if I were trying to make a "Vs NES" system.

Quote:
Also, does anyone know if they function of Famiclones?
The OUT1 and OUT2 pins have to be available on "full" famiclones with the DA15 Famicom expansion port connector. Zzo38 pointed out that one could reuse the IRQ line (at the cost of disabling IRQs and so not getting any IRQs from the APU) on those systems. But I don't know just how available that would actually be.
Re: Basic mapperless PGR bank switching. How?
by on (#113801)
Yeah, the EXP pins that go to the cartridge are connected to the same EXP pins that go to the expansion port. I'm not sure what advantage the NES would've had by having the cart hardware directly interface with the expansion port; one of those times where it'd be nice to know what Nintendo had in mind. :P

The EXP pins aren't directly controlled by software; writing to $4016 provides 3 bits of output to the expansion port, and reading $4016 and $4017 provides 10 bits of input on 10 pins (5 bits for $4016 and for $4017).

So for the cart and th CPU to communicate to the cart via the EXP pins, you'd need a jumper on the expansion port. Not very handy, and completely incompatible with the FC. :P

It's kind of a shame; the NES could've had a software-controlled latch whose bits could be fed directly to the cart (and then to the upper address lines), and there you go; bankswitching done by the NES itself instead of a mapper. It'd be like a GNROM or a CNROM depending on how the cart's wired, and it'd require no extra hardware on the cart. With four bits, you could address 512kb of PRG (with chr-ram, unless you want fixed CHR), but CHR would be tricky because you'd only be able to swap the whole 8kb at a time without a mapper. I wonder if that would've had any significant impact on costs, both of the console and of cartridges.
Re: Basic mapperless PGR bank switching. How?
by on (#113804)
Drag wrote:
Yeah, the EXP pins that go to the cartridge are connected to the same EXP pins that go to the expansion port. I'm not sure what advantage the NES would've had by having the cart hardware directly interface with the expansion port; one of those times where it'd be nice to know what Nintendo had in mind. :P

My hypothesis has always been that these pins were intended for communication between the Disk System RAM card and the disk drive without having to have a cable between the two like the FDS has. (Nintendo abandoned bringing the FDS to North America after widespread copyright infringement of FDS games began to cut into publishers' earnings.)