[stella] A new way to bankswitch

Hopefully this will go through. There hasn't been much traffic on this list
lately.
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.
PREVIOUS SOLUTIONS:
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.
THE NEW SOLUTION:
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:
LDA #>ROUTINE1
PHA
LDA #<ROUTINE1-1
PHA
JMP $FFF8
Or in bank 1, to get back ROUTINE0 to bank 0:
LDA #>ROUTINE0
PHA
LDA #<ROUTINE0-1
PHA
JMP $FFF7
HOW IT WORKS:
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