LAUGHTON ELECTRONICS |
|
|
|
|
The KK Memory Space and Pointer Registers |
The KimKlone adds six new registers to the 6502 programming model, and four of them, the so-called Pointer Registers, support the KK's 16 megabyte addressing capability. The Pointer Registers reside in a register file built with 74HC670's. An extra read port from the register file is what drives the high 8 bits of the 24-bit address sent to memory. The high 8 address lines coordinate exactly with the low 16 address lines supplied straight from the 65C02. One Pointer Register at a time is selected to drive the upper address bus, and this selection can be updated on any bus cycle. Of course the low address bits (from the 65C02) also update on a cycle-by-cycle basis, and the combined result is a complete 24-bit address for every cycle. It's important to be clear that during execution of a single instruction two different Pointer Registers may be sequentially selected (eg: for code access and for data access). The programmer sees memory as a linear 16 MB space composed of 256 "banks," each of which is 64KB in size. Because there are four Pointer Registers, as many as four different banks can be made available simultaneously. Any Pointer Register can indicate any of the 256 banks in the overall 16MB map. Each Pointer Register typically gets used in an associated role; eg, for fetching code or accessing data. Loading the Pointer RegistersBefore the Pointer Registers can be used to generate 24-bit addresses there needs to be some way to load the Pointer Registers themselves. Several of the 65C02's previously undefined opcodes are appropriated for this purpose. In fact, there are several addressing modes by which Pointer Registers can be loaded from memory. Pointer Registers may also be pushed/popped to and from the stack. (Note: To prevent confusion regarding use of the word “pointer," in this article the names of KK's Pointer Registers are always capitalized.) The Current Code Pointer (CCP)The register I call the Current Code Pointer (CCP) is what drives the high address lines during all code fetch cycles. CCP is also the default for data accesses. Obviously, then, it's the CCP that almost always drives the high address lines. However, CCP relenquishes control when a "Far" access is specified. CCP is also ignored during bus cycles for stack and Zero-Page accesses. These go to bank 00h, regardless of the Pointer Registers. Data Pointer 0 and Data Pointer 1 (DP0 and DP1)To reach for data independently of the CCP, a program can use "Far" memory operations. These are just the usual 65xx reads and writes, such as LDA or STX, but with an added specification (explained below) which calls for Data Pointer 0 or Data Pointer 1. Read-Modify-Write operations such as INC and DEC can also be Far. As always, microcode tracks the sequence. On the exact cycle when the 65C02 will read or write the data, DP0 or DP1 will jump in for the data access only and temporarily preempt the CCP on the high address lines. Then the CCP immediately resumes control and the subsequent instruction bytes are fetched as if nothing had happened. Later we'll see why it's pivotal that a single instruction can activate the alternate bank, do the access, then put things back as they were. There are two ways to specify a Far memory operation. The general means (and the most flexible) is to use either the DP0 prefix or the DP1 prefix, aka DP0_PFX and DP1_PFX. (The regret that the mnemonics I coined are impossible to pronounce!) A prefix is a one-byte code which executes in one cycle. It is placed ahead of a standard 65xx op-code; together the prefix and its target perform as a single instruction. In other words the prefix is a modifier. Prefixes are applicable to nearly all the 65C02's instructions and addressing modes; basically "anything goes" that's reasonable. Only a few questionable operations (eg: LDA Immediate Far) aren't implemented. The other type of Far memory specification does not use a prefix. Instead, the prefix and the target op-code are both represented by a single, "2 in 1" op-code byte, thus eliminating one byte and one cycle of overhead. Due to limitations in op-code space, only a handful of instructions are available using this type of specification. These include high-utility operations such as LDA and STA using Absolute and Indirect-Y address modes. The New Code Pointer (NCP)The last of the new 8-bit registers, and the alter-ego of the Current Code Pointer, is the New Code Pointer (NCP). As the name suggests, this is used when the program needs to make a Far Jump or Far Call to a new location. Here's the drill: First, NCP is loaded with the high eight bits of the destination address; then a JMP_NCPX or JSR_NCPX instruction is executed. At the appropriate instant NCP and CCP undergo Register Renaming, in effect exchanging contents with one another. (The letter X in the mnemonics denotes the exchange.) Code at the new location may discard the value in NCP (the former CCP) or preserve and make use of it — to reach back to the calling code for an in-line parameter, perhaps, or perhaps to effect a speedy return using RTS_NCPX. (Of course if you wish to nest the far calls it'll be necessary to push and later pop the NCP.) NCP has one final trick
up its sleeve. Besides being your ticket to Far jumping, it's also
usable in the role of DP2, a third Data Pointer. In other words NCP can
be invoked
with its
own prefix instruction exactly as can DP0 and DP1. The next section presents
an overview of the memory addressing
topic. |
|
< Previous Page KK Index Next Page > | |
visit LAUGHTON ELECTRONICS |
Home Commercial& Manufacturing Stage&Studio Laboratory&OEM |