Bank Switching Parallax on the NES

Made something in Assembly? Show it off, and tell us how it works...
Absolute beginners welcome... we want to see what you've done!
Forum rules
There is a special rule on this forum...
This forum is intended to offer equal amounts encouragement and constructive feedback...
Therefore, if you say 2 negative things about someones work, you must think of 2 or more equally positive things...

Eg: "Great first effort, the idea is absolutely fascinating... However I noticed a few bugs, and maybe the graphics could be improved..."

If you can't think of anything good to say, then don't say anything!

If we don't encourage newbie programmers they won't have the confidence and motivation to stick at it and become great programmers! *speaking from experience*
Post Reply
puppydrum64
Posts: 34
Joined: Thu Apr 22, 2021 9:30 pm

Bank Switching Parallax on the NES

Post by puppydrum64 » Sun May 16, 2021 6:14 pm

So I had heard about a clever technique from Retro Game Mechanics Explained for creating the illusion of parallax scrolling (something the NES isn't capable of since it only has one background layer). This trick uses the Konami VRC6 chip's ability to switch CHR-ROM banks, but something similar was used in Battletoads. I'll explain how I did it below.

Each CHR file takes up 8 KB (8192 bytes) of data. In an NROM cartridge (the original Famicom/NES cartridges used in early black box games) you can only store 1 of these. So all your game's graphics had to fit in just 8 KB. Below is a picture of the latter half of Super Mario Bros.'s CHR file. Typically, the first 4 KB are used for sprites and the second four KB are used for background tiles. You decide which is which by setting bit 4 of CPU address $2000, aka PPU Control. On an NROM cartridge, there is no bank switching, so these graphics cannot be rearranged except by editing the CHR file which obviously cannot be done during gameplay.
parallax3.png
parallax3.png (9.74 KiB) Viewed 2198 times
The Konami VRC6 was used in the Japanese release of Castlevania 3. It's mostly famous for its enhanced music capabilities, which sadly do not work on an American or PAL NES (For its US and PAL release the game was ported to a cartridge with a different chip altogether.) Other than sound, one of its features is CHR-ROM bank switching. In the attached image I drew red lines between each 4-tile-tall section. By writing to certain memory addresses in the ROM you can rearrange these sections of the CHR-files. Below is a picture of the edited CHR file I used in my test ROM. It's very wasteful to do it like this, but I was making this just as a tech demo so I'll work out how to conserve space later.
parallax2.PNG
parallax2.PNG (38.69 KiB) Viewed 2198 times
I'll go ahead and give a quick rundown of how you do this in the ROM.

First, you need your registers set up. The CHR-ROM banking registers are memory mapped just like the PPU ports. You can write to them but you can't read from them so it's best to create "soft" zero page versions of these that you write to, and then transfer them to the real thing during NMI.

$D000 controls the first 1 KB of CHR-ROM
$D001 controls the second 1 KB of CHR-ROM
$D002
$D003
$E000
$E001
$E002
$E003

Although you will most likely have executable code in these locations, it has no effect on your CHR-ROM banks or vice versa. As part of the startup routine for the rom, I wrote 0 to $D000, 1 to $D001, 2 to $D002, and so on. This sets up the CHR-ROM how you would expect. Another cool feature is that you can have multiple CHR-ROM files and swap out to those as well if you write numbers higher than 7, but I didn't do that for this. (My test ROM has two CHR-ROM files loaded but the routine I'm about to share only uses the first one.)

Hopefully this isn't too confusing (it took me quite some time to understand how this works, the NESdev wiki doesn't explain it well.) If you're still reading along I'll go ahead and explain the trick.

In the code I have a controller input handling section set up to scroll right when you press right and scroll left when you press left. I also wrote the same screen to both nametables so that it loops around. To make the bank swapping happen, I used a temp variable to store one of the banks, and wrote each into the one before it, then put that temp variable back at the end. The code looks like this:

Code: Select all

ScrollRight:
	inc scroll
	
	lda softE001
	sta tempBank
	
	lda softE002
	sta softE001
	
	lda softE003
	sta softE002
	
	lda tempBank
	sta softE003
	
The effect is that CHR-ROM sections 5, 6, and 7 are cycled where section 4 (the top one in the pictures) is stationary. Moving to the left, I set up the same code but in reverse.
The source code for this test rom is pretty long, if you're interested I'll reply to this post and paste it. If you like you can see the rom in action here, but I don't think this video does it justice:
https://vimeo.com/550048533

puppydrum64
Posts: 34
Joined: Thu Apr 22, 2021 9:30 pm

Re: Bank Switching Parallax on the NES

Post by puppydrum64 » Sun May 16, 2021 9:25 pm

I'll admit I was feeling pretty clever until I re-watched that video and realized there is a much MUCH easier way to do this. :lol:

Post Reply

Return to “Show and Tell”