[stella] A new way to bankswitch

Subject: [stella] A new way to bankswitch
From: "Fred Quimby" <c9r@xxxxxxxxxxx>
Date: Wed, 9 Mar 2005 16:49:58 -0500
Hopefully this will go through.  There hasn't been much traffic on this list 

Anyway, I thought I'd introduce a new method of F8 bankswitching here.  I 
originally proposed this to solve a problem with bankswitching, namely that 
you will enter the second bank at a fixed location and it can be a hassle to 
keep the banks aligned.

For example, the following code in bank 0:

F000: LDA $FFF9

will always enter bank 1 at $F003.  This can be a pain to keep track of when 
you're trying to develop an 8k game.


Up until now, two approaches have tried to help this along.  The first is to 
write a routine into RAM containing LDA $FFFx then a JMP, and then jump to 
RAM, but this takes 6 bytes of RAM and around 27 bytes of ROM so init the 
RAM.  Another method is to place the LDA $FFFx in the upper part of ROM and 
a JMP in the next bank, three bytes ahead, at the upper part of the ROM 
where it's easier to deal with fixed locations.


In bank 0, place an RTS at $FFF8, and in bank 1, place an RTS at $FFF7.  
Then, for example, to switch banks and jump to a new location in bank 1 
called ROUTINE1, you may do:


Or in bank 1, to get back ROUTINE0 to bank 0:



The LDA and PHA simply push an address onto the stack just like a JSR would 
do.  Note that a JSR actually stores the low byte of the address minus one 
on the stack, so this behavior is copied above.  This will work in all cases 
except when the low byte of the address is zero.

Conspicuously absent is the LDA $FFFx to switch banks.  This is done by the 
RTS instead!  But how?  If an access to $FFF8 will switch from bank 1 to 0, 
why was the RTS placed at $FFF7?  Well, here's why:  This method relies on a 
design artifact of the 6502, pointed out by Kroko, who invented the 
Krokodile Cart.  Namely, the instructions BRK, RTI, and RTS are single 
bytes, but they actually use immediate mode (as I understand) which means 
that the processor will first access the opcode, but then will access the 
"operand" at the next byte in the next cycle, but it will ignore the value.  
This means that a RTS placed at $FFF7 in bank 1 or $FFF8 in bank 0 will 
actually do its last address access at $FFF8 and $FFF9, thus switching to 
the other bank when the processor tries to get the "operand".

So far this has been tested and works in Stella and Z26, and in real 
hardware on a Kroko cart.  More testing is needed to ensure it will work 
with various types of bankswitching hardware.

This method has the advantage that it can be used multiple times without 
adding additional complications of keeping banks aligned.  It could also be 
easily extended to work with F6 and F4, as long as you put enough RTS's in 
upper ROM jump to the correct RTS.

Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://stella.biglist.com

Current Thread