fastgear wrote:
Recently I came to the point where I need to implement the C64 bank switching within the emulator...
To be pedantic about it (something for which I'm infamous), what is going on is not "bank switching."
In the eight bit world, especially that of the 6502 family, the term "bank" generally refers to large extents of RAM (or, less so, ROM) that lie beyond the normal 6502 addressing range of
$0000-$FFFF. For example, in the Commodore C-128, which really does have 128KB of RAM (lots of DRAMs in there), there are two banks, numbered
$0 and
$1. That was also true of the Commodore B-128, whose MPU, the 6509, did indeed do banking, albeit in a weird fashion.
Even the 65C816, which can directly address 16 MB, refers to each 64KB piece of that 16 MB space as a "bank"—there are potentially 256 of them. My POC V2 unit has 1 MB of RAM, which means it has 16 banks, addressable from
$00xxxx-$0Fxxxx. The register that tells the '816 from which bank to retrieve program code is
PB, the program bank register. The content of
PB is concatenated to the program counter (
PC) during an opcode or operand fetch, forming a full 24 bit address. So if
PB contains
$0C and
PC contains
$1234, and the '816 is getting ready to fetch an opcode, the opcode will come from
$0C1234.
Something similar happens with
DB, the 65C816's data bank register. If the address operand for a load/store instruction is 16 bits, as in
LDA $1234, the content of
DB is concatenated to the $1234 address to form a 24 bit address from which the data will be loaded. So if
DB contains
$56 and the 16 bit address is
$1234, the data will come from
$561234.
In both cases, what is happening is banking. The '816 selects a particular memory bank—a 64KB range—and then reads or writes on a particular address within that range.
What is going on in the C-64 is "memory mapping," which makes RAM, ROM or I/O appear at the same address in a mutual exclusive fashion. For example, one can make the BASIC ROM appear at
$A000-$BFFF, the power-on default, or RAM. A similar thing can be done with the E-ROM, which contains the final extent of BASIC, as well as the kernel ("Kernal"). Plugging in a cartridge may cause
/GAME and/or
/EXROM to be asserted, causing the cartridge to replace RAM at
$8000 or
$E000 with cartridge RAM or ROM (the technique used in the Xetec Lt. Kernal hard drive subsystem's host adapter to make the DOS run in the same address space as user programs). It's just memory mapping, not bank switching, even though Commodore themselves occasionally referred to "banking in" or "banking out" different things within the 64KB address space when they should have said "mapped in" or "mapped out."
Incidentally, the PLA that was used in the C-64 to carry out the memory mapping features was an off-the-shelf part, not anything special. All Commodore did was program it to suit their requirements. A number of replacements schemes for this PLA have been devised in order to revive dead C-64s. This PLA has a 20 year data retention life, which means it was possible that it would simply forget what was burned into it, causing the computer to cease operation—a common occurrence with the C-64.
Almost anything programmable is potentially subject to the same failure, including modern E(E)PROMs, CPLDs and GALs. For example, Atmel's data sheet for the ATF150x series of CPLDs says these parts have a guaranteed 20 year data retention capability. That means that 19 years from now I had better refresh the code in the ATF1504AS in my POC V2 unit, as well as in the EPROM.
I'll be sure to do that if I'm still around at that time and playing with this stuff—I'll be 90 by then.