| Level 0 | Level 1 | Level 2 | Level 3 | Level 4 |
| Level 5 | Level 6 | Level 7 | Level 8 | Level 9 |
| Level 10 | Level 11 | Level 12 | Level 13 | Level 14 |
| Level 15 | Level 16 | Level 17 | Level 18 | Level 19 |
As many know, the address space for active loaded ROM memory is $8000 - $FFFF. When you have more banks and data than what can fit into this space is when you need to use bankswitching. Also there is a situation where you have a few banks that need to be loaded into a certain memory range, like $8000 $8FFF for example. Many games have done this, such as Metroid, Zelda, and many many more.
However, all we need to do is use bankswitching for NSF files that have eliminated everything but the driver or music engine. Before we get into the process, I am going to describe bank sizes for you.
| Bank Size Select | Hex Size | Address Range | Mapper |
|---|---|---|---|
This chart will generically handle nearly any mapper. For example, MMC3 or mapper 4 is either 8KB or 16KB bankswize select. AOROM, which is listed is 32KB bankseized select, or what most people are familiar with, that's Mapper 7. There are other mappers that will not be handled well by the chart that I showed you. MMC2 or Mapper 9 is a good exmple. Mapper 9 has a 24KB fixed bank at $A000 - $FFFF, the 8KB bank is switched in and out at $8000 - $9FFF. Another example would be Mapper 42, this is a FDS port that has a fixed 32K bank at $8000 - $FFFF, a 8KB bank is switched in and out in address range $6000 - $7FFF. How you deal with these odd mappers depends on the sound driver and in some cases, takes some strategy in order to rip. MMC2 no longer has any games that need to be ripped. However, one may pop up in the future, so I mention it to be complete. For FDS port games, I suggest to set the FDS bit in the header and rip it as though it was a FDS game (if the sound data or code is $6000 - $7FFF).
Now it's time to start digging into a game to locate the banks. First off, I suggest to make every available effort to prevent a NSF from bankswitching, if it's possible. If you only have a string of code, then it should be moved near the sound engine core, located in some freespace somewhere. For example, I have ripped a game called Golden KTV. The game is standard ripping fair and quite easy until you find out that only 3 tunes plays along with some sound effects. Since this is a large scale game with a lot of tune selections in the game, it's logical to assume this game will be bankswitching. Assuming that you made every available effort to locate the tunes. Now, here is how I done it and that's by a indirect jump routine so that I could simply plug in the banks and use the same index number for all the different tunes.
Basic Initialization Start
00:F450:48 PHA 00:F451:A9 40 LDA #$40 00:F453:8D 17 40 STA $4017 = #$FF 00:F456:A9 00 LDA #$00 00:F458:8D 10 40 STA $4010 = #$FF 00:F45B:A9 1F LDA #$1F 00:F45D:8D 15 40 STA $4015 = #$FF ; turn all channels on 00:F460:68 PLA 00:F461:0A ASL 00:F462:AA TAX 00:F463:BD 70 F4 LDA $F470,X @ $F470 = #$F0 00:F466:85 00 STA $0000 = #$00 ; store low jump byte 00:F468:BD 71 F4 LDA $F471,X @ $F471 = #$F4 00:F46B:85 01 STA $0001 = #$00 ; store high jump byte 00:F46D:6C 00 00 JMP ($0000) = $0000
Intialize 1
00:F4F0:A9 04 LDA #$04 00:F4F2:85 02 STA $0002 = #$00 ; bankswitch variable 1 00:F4F4:20 20 F4 JSR $F420 ; bankswitch sub 1 00:F4F7:A9 09 LDA #$09 ; tune # 00:F4F9:4C 42 F4 JMP $F442
Bankswitch Sub-routine 1
00:F420:A5 02 LDA $0002 = #$00 ; bankswitch variable 1 00:F422:8D F8 5F STA $5FF8 = #$FF ; NSF reigster to load $8000 - $8FFF 00:F425:60 RTS
Intialize 2
00:F442:8D A6 07 STA $07A6 = #$00 ; tune variable 00:F445:20 9B CA JSR $CA9B ; jump to main sound driver initialization 00:F448:60 RTS
This is how I set the NSF up after I realized that only the sequence data is being loaded at $8000 - $9FFF, the core of the sound driver is at $C000 - $DFFF, also has DPCM. I gave you a quick run down of the code first and then you start plugging in the banks. So, the game is UNROM or Mapper 2, which means 16KB banksize select, there are 64 - 16KB sized banks. So, safe to say, I used a file splitter and divided the ROM into 16KB sections and gradually worked on them to remove anything that wasn't needed. I also saved $F000 - $FFFF as my "hardwired" bank to write the code. Most of the tunes did not go over 4KB, those that don't use address range $8000 - $8FFF, a few others use $8000 - $9FFF. I loaded them using the following NSF bank registers, using them in the initialization code.
You may want to know how to load the banks, it's simple, you use the NSF bankswitching registers to load the banks at certain times. I will now show you the registers. No matter what strategy you use, these registers will switch the banks.
| Register | Address Range |
|---|---|