Bank Switching

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

Celius
Posts: 2157
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius » Sat Mar 04, 2006 8:28 pm

Really? Okay. Thank you Quietustsan :). You have answered my question. Thanks =)!

User avatar
Bregalad
Posts: 7818
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Sun Mar 05, 2006 2:56 am

Actually bankswitching under a SUROM board is just as simple as a normal MMC1 card. Just add a similar code :

Code: Select all

Bankswitch
          sta BankNmr
          pha
          and #$0f
          jsr WriteMMC1Reg3
          pla
          and #$10
          jmp WriteMMC1Reg1

WriteMMC1Reg1
          sta $bfff
          lsr A
          sta $bfff
          lsr A
          sta $bfff
          lsr A
          sta $bfff
          lsr A
          sta $bfff
          rts

WriteMMC1Reg3
          sta $ffff
          lsr A
          sta $ffff
          lsr A
          sta $ffff
          lsr A
          sta $ffff
          lsr A
          sta $ffff
          rts
Got it ?
Life is complex: it has both real and imaginary components.

tepples
Posts: 21893
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sun Mar 05, 2006 9:55 am

Bregalad wrote:Actually bankswitching under a SUROM board is just as simple as a normal MMC1 card.
Except as I understand it, the "fixed" bank normally present at $C000-$FFFF also gets bankswitched. Either you need to use identical "fixed" banks or you need to do some jump table stuff to move between the banks safely.

User avatar
Bregalad
Posts: 7818
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Sun Mar 05, 2006 10:14 am

Huh ?? I didn't understood it that way. I was sure that the fixed bank was the last 16kb bank. Now you said it... I'll watch at DW 3 and 4 better.
Life is complex: it has both real and imaginary components.

User avatar
Quietust
Posts: 1514
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Post by Quietust » Sun Mar 05, 2006 10:38 am

The "fixed bank" is, in this case, the last 16KB of the current 256KB selected.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

User avatar
Bregalad
Posts: 7818
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Sun Mar 05, 2006 11:45 am

Awww.... that hurts. Thanks for clearing that.
So, the SUROM has some 32kb switching aspects... I mean the main PRGROM bank have to be swapped. Two options are to do everything with 32kb switching.
The option I'd do is to copy NMI, IRQ and very important routine in both main banks. Then, the non-important routines that are affilated with the first 256kb of data would come in bank 15 and the routines affilated with the second 256kb of data would code in bank 31.
Life is complex: it has both real and imaginary components.

tepples
Posts: 21893
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sun Mar 05, 2006 12:58 pm

SUROM looks a lot like a multicart mapper. In fact, the Final Fantasy multicart for Famicom used the same technique. So if you have two nearly separate game engines, stick them in separate banks. I don't know what Celius's demo is supposed to do, but in an RPG, you could stick all the battle related stuff in one bank and all the map related stuff in the other bank.

User avatar
Bregalad
Posts: 7818
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Sun Mar 05, 2006 1:04 pm

Great trick, tepples. Since your battle and menu routine would have nothing in common, not even the NMI routine, I think that really is a great idea. I'd stuck "rest" such as title screen and menus with battle, beacuse battle data is most probably getting a bit smaller than playfield data.

However, most FF1 and FF2 engine is the same. All the engine that move characters and playfield arround is the exact same in both games.
Only menu, music, intro and ending really differs (in an engine point of view, of course).
Life is complex: it has both real and imaginary components.

Celius
Posts: 2157
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius » Sun Mar 05, 2006 1:18 pm

So what I'm understanding is that you have to have two banks with vectors in them. The 15th bank of PRG in the first 256k, and then the 15th bank in the second 256k? But I'm hearing about $C000-$FFFF being switched as well. Why would you do that? Why couldn't you just switch $8000-$BFFF, leaving $C000-$FFFF fixed to the 15th bank of whatever 256k your in? I don't think you have to be switching $C000-$FFFF. I see no reason why it would have to be switched.

My DEMO doesn't really require SUROM. My GAME requires SUROM. Many banks full of maps, like, MANY banks full of maps. And it also requires many banks full of graphics, and many banks full of enemy data. Don't forget text, and event data as well.
Last edited by Celius on Sun Mar 05, 2006 1:29 pm, edited 1 time in total.

tepples
Posts: 21893
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sun Mar 05, 2006 1:23 pm

Yes. An NMI or especially a reset could happen at any time.

User avatar
Bregalad
Posts: 7818
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Sun Mar 05, 2006 1:50 pm

Celius wrote:Why couldn't you just switch $8000-$BFFF, leaving $C000-$FFFF fixed to the 15th bank of whatever 256k your in? I don't think you have to be switching $C000-$FFFF. I see no reason why it would have to be switched.
The reason is that the MMC1 does the OR logic needed for that on it's PRG outputs, but not on its CHR outputs. Since PRG A18 is wirted to CHR A16, CHR A16 won't be ORed with PRG A14, which is the only way to have a hardwired bank (in other word, when the programm counter is above $c000, so bit 14 set, all bankswitching lines are forced to be one with the OR logic internal to MMC1 to have the last bank acceded).

I'd say to first code your game as a normal SNROM game. The day you'll run out of space (wich isn't probably today), you'll have to think about more complex SUROM bankswitching, and splitting your "hardwired" space in two banks. Since WLA has a special option to keep two track of the same code in two banks, it won't cause problem to duplicat some essencial code, such as the Reset code.
Life is complex: it has both real and imaginary components.

Celius
Posts: 2157
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius » Tue Mar 07, 2006 9:10 pm

Okay, I'm sorry to keep this thread going, but I thought it'd be better to post here than to start a new one.

Is it possible to keep track of the Program Counter? Because I want to switch banks, and then jump back to the same place. Is it possible? Hey, Memblers, you were saying about jsring to banks. I said it wasn't neccissary. I lied. How do you do such a thing?

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

Post by tokumaru » Tue Mar 07, 2006 11:32 pm

Celius wrote:Is it possible to keep track of the Program Counter?
When you execute a JSR command the PC is stored on the stack. You could JSR to a routine that will pull that and use as you want. AFAIK, the only way to read the PC is getting it from the stack.

User avatar
Memblers
Site Admin
Posts: 3802
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers » Wed Mar 08, 2006 4:41 am

Celius wrote: Hey, Memblers, you were saying about jsring to banks. I said it wasn't neccissary. I lied. How do you do such a thing?
What helped for me was having a byte in RAM that keeps track of your current selected bank. There's a couple JSR's needed (so the routine can be called from anywhere). Pretty much like this, with music code for example:

Code: Select all

 jsr playmusic   ; .org anywhere

playmusic:    ; .org in fixed bank, RAM or manually mirrored PRG for 32kB pages
 lda current_bank
 pha
 lda #NSF_play_banknumber
 sta current_bank
 sta $8000 ; mapper write
 jsr NSF_play 
 pla
 sta $8000 ; insert mapper write here
 rts
Whenever you bankswitch, then update the current_bank at the same time. Pushing it on the stack like that makes it recursive, so you could JSR between several banks within that routine and still return to the original (if you really wanted to). But it complicates the code a bit, it could be simplified if you don't need to do anything really fancy.

User avatar
Guyver
Posts: 13
Joined: Sat Aug 19, 2017 5:47 pm
Location: Russia, Sinegorie
Contact:

Re: Bank Switching

Post by Guyver » Thu Aug 31, 2017 4:21 am

MMC1.

I took the game from the example (NESASM3 source) and added 1 bank of graphics to it.

Code: Select all

  .bank 13
  .org $A000
Graphics2:
  .incbin "graphics2.nes"
  .incbin "graphics2.nes"

  .bank 14
  .org $C000   ;;8KB graphics in this fixed bank
Graphics:
  .incbin "graphics1.nes"
  .incbin "graphics1.nes"
Uncommented the following code:

Code: Select all

bankvalues:  ;;This is the old bank switching code for UNROM
  .db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
BankSwitch:
  lda sourceBank
  tay
  sta bankvalues, y  ;;make sure byte written = byte in ROM so there is no bus conflict
  rts
What else should I do? How to switch bank of graphics to bank 13? Now the game shows the graphics from the bank 14.
Attachments
help.rar
(36.77 KiB) Downloaded 112 times

Post Reply