PLA (C64 chip)
From C64-Wiki
The C-64 uses the PLA to implement bankswitching. This lets the CPU access both 64 Kbytes RAM as well as 20 Kbytes internal ROM, various I/O hardware and any extra ROM, I/O etc. added through the use of a cartridge: By setting three of the I/O pins in the on-chip port of the 6510 CPU, and through a pair of control lines in the expansion port, access to various "zones" of ROM, RAM etc. can be enabled and disabled as needed. For example, the memory area 53248–57343/$D000–$DFFF is where the VIC, SID, and CIA I/O devices are mapped into the address space. Through bankswitching via the CPU on-chip port, this I/O area can be replaced by character ROM (to make the character patterns readable by the CPU, e.g. to copy them to RAM), or provide access to the four Kbytes of underlying RAM.
Caution should be taken when setting the system up in non-standard configurations: Since the standard interrupt handling routines in ROM access the I/O hardware (in order to scan the keyboard), normal interrupt operations should be disabled as long as the I/O hardware is banked out of the address space (i.e. when it's not accessible by the CPU). Likewise care should be taken to avoid the CPU trying to execute code expected from ROM, when that ROM is banked out.
[edit] CPU port lines
The three least significant bit in the port register (address 1) for the CPU on-chip port corresponds to the three lines in the port used for bankswitching purposes:
- Bit 0 (weight 1): /LORAM
- Bit 1 (weight 2): /HIRAM
- Bit 2 (weight 4): /CHAREN
To use these port lines, they must be configured as outputs, i.e. the same three least significant bits in the port's directional register (at address 0) must be set to "1". This is by default the case upon power-up, but as a programmer one may want to make certain this is the case before operating the bankswitching port lines themselves.
[edit] Cartridges
The bankswitching scheme in the C-64 also handles external ROM in the form of a cartridge plugged into the expansion port: Two lines in this port; /GAME (pin 8) and /EXROM (pin 9), are pulled logically "high" or "1" through internal pull-up resistors. Cartridges pull either or both of these lines logically "low" (by connecting them to "ground") to "announce their presence", and these two signals are evaluated along with the three CPU port lines in determining what's banked in and out of the address space.
The cartridge may contain one or two 8 Kbyte "blocks" of ROM, to be mapped into the system, and thus most modes involving a low /GAME and/or /EXROM pin has one or both these areas mapped in. It's easy to hook up one or two ROMs, EPROMs etc. onto the expansion port, and these two areas are referred to the "low" and the "high" cartridge ROM areas.
[edit] Overview
To understand the bankswitching system in the C-64, the 64 Kbyte address space can be broken down to the folowing seven "zones":
| The various zones can be configured as either:
|
The first four kilobytes are always internal RAM, whereas the remaining six zones depend on the state of the three least significant bits/lines in the CPU on-chip port, and the /GAME and /EXROM "flags" from the cartridge.
| # | Control lines | Addres zones | |||||||||
| From CPU port | From cartridge | 4096–32767 $1000–$7FFF | 32768–40960 $8000–$9FFF | 40960–49151 $A000–$BFFF | 49152–53247 $C000–$CFFF | 53248–57343 $D000–$DFFF | 57344–65535 $E000–$FFFF | ||||
| /CHAREN | /HIRAM | /LORAM | /GAME | /EXROM | |||||||
| 1 | 1 | 1 | 1 | 1 | 1 | Int. RAM | Int. RAM | BASIC ROM | Int. RAM | I/O | Kernal ROM |
| 2 | 0 | 1 | 1 | 1 | 1 | Int. RAM | Int. RAM | BASIC ROM | Int. RAM | Charset ROM | Kernal ROM |
| 3 | 1 | 0 | 1 | 1 | X | Int. RAM | Int. RAM | Int. RAM | Int. RAM | I/O | Int. RAM |
| 1 | 0 | 1 | 0 | 0 | |||||||
| 4 | 0 | 0 | 1 | 1 | X | Int. RAM | Int. RAM | Int. RAM | Int. RAM | Charset ROM | Int. RAM |
| 5 | 0 | 0 | 1 | 0 | 0 | Int. RAM | Int. RAM | Int. RAM | Int. RAM | Int. RAM | Int. RAM |
| X | 0 | 0 | 1 | X | |||||||
| 6 | 1 | 1 | 0 | 1 | X | Int. RAM | Int. RAM | Int. RAM | Int. RAM | I/O | Kernal ROM |
| 1 | 0 | 0 | X | 0 | |||||||
| 7 | 0 | 1 | 0 | 1 | X | Int. RAM | Int. RAM | Int. RAM | Int. RAM | Charset ROM | Kernal ROM |
| 0 | 0 | 0 | X | 0 | |||||||
| 8 | 1 | 1 | 1 | 1 | 0 | Int. RAM | Cart. ROM (L) | BASIC ROM | Int. RAM | I/O | Kernal ROM |
| 9 | 0 | 1 | 1 | 1 | 0 | Int. RAM | Cart. ROM (L) | BASIC ROM | Int. RAM | Charset ROM | Kernal ROM |
| 10 | 1 | 1 | 0 | 0 | 0 | Int. RAM | Int. RAM | Cart. ROM (H) | Int. RAM | I/O | Kernal ROM |
| 11 | 0 | 1 | 0 | 0 | 0 | Int. RAM | Int. RAM | Cart. ROM (H) | Int. RAM | Charset ROM | Kernal ROM |
| 12 | 1 | 1 | 1 | 0 | 0 | Int. RAM | Cart. ROM (L) | Cart. ROM (H) | Int. RAM | I/O | Kernal ROM |
| 13 | 1 | 1 | 1 | 0 | 0 | Int. RAM | Cart. ROM (L) | Cart. ROM (H) | Int. RAM | Charset ROM | Kernal ROM |
| 14 | X | X | X | 0 | 1 | Open | Cart. ROM (L) | Open | Open | I/O | Cart. ROM (H) |
The X'es in the above table indicate a "don't care" bit state; either a "0" or a "1" will work in these places.
FIXME: Include info from The Transactor Volume 6, Issue 05, page 55 - R(BA) vs. R(~BA); what memory does the VIC see?
Note that on power-up, the three CPU port lines "seem" logically high: This means that the system will start out in one of the rows in the table above where the three CPU lines are all high, i.e. row 1, 8, 12, or 14, depending on whether a cartridge is present in the port, and what it "does" to the /GAME and /EXROM lines. In "normal" cartridges the /GAME and /EXROM lines would be hardwired directly to ground, rendering either or both lines permanently "low" for as long as the system is running with that cartridge inserted. But the CPU port lines may be manipulated during run-time, and along with the "don't-care-X'es" in the table above, this allows for some "jumping around" between different modes (rows in the table) during run-time:
- From row 1 in the table (default with no cartridge inserted), the CPU port may take the system to rows 2, 3, 4, 6, and 7.
- When booting in row 8 in the table, the CPU may bankswitch to rows 4, 6, 7, and 9.
- From row 8, the CPU can attain rows 5, 10, 11, and 13.
- No such jumps can be performed "away" from row 14.
