SuperCPU Illuminated - Part 5
Since we gave you such a concentrated load of information last time, we'll start with a
somewhat less complex subject: We'll get to know new forms of memory addressing
available in the SuperCPU from CMD. Additionally, you'll learn a few new commands
which will really light up your life!
When you think of addressing memory, you probably think back to when you learned Assembly
language (maybe that's not so long ago). Words like, "indirect y indices"
probably bring you back to that time, when it took a while before you got used to such
types of memory addressing.
A Little More About That
The 65816, the logical development in the 6510 line, comes with a few new types of memory
address. Let's start with something a little unusual: Most of you know the
command JMP ($A000), which is located in ROM and doesn't reference $A000 but rather the
address where $A000 and $A001 are located. This command is good for jumping over
vectors, but many use self modifying code at this location, and they change the two bytes
directly behind the JMP. With the 65816 there is also the following possibility:
JMP($7000,X) ! If there's a 2 in X, it will jump to the address where
$7002 and $7003 are located! So it becomes clear what you can use this new address
form to do: Jump tables! You have to make sure that you always raise the X
register by two, so that you don't get a false address from the High byte of a table entry
and the Lowbyte of the next one. This type of address isn't just used by JMP, but
also by JSR - for example JSR($7000,X). Listing 5.1
shows how it's done.
Less is More
Last time in this tutorial we discussed how the zero page (know as direct page with the
65816) can be placed in any memory area that you please. To give the coder a small
speed boost and to be eventually able to keep another register free, a new type of
addressing was developed for the Direct Page (Zero page). Seasoned programmers
probably have an idea of how this works: If you want to set a pointer (which is in
the zero page) to an area of memory, it's just like you'd expect, for example LDA($FD),Y.
Often, however, you'll want to reset the pointer to every read byte (raise $FD and $FE if
necessary) - with that the Y register stays 0 and must stay 0, so that the correct address
will be effected. In the other case, you'd only want to switch the one byte, (or two
bytes with the 65816) at which the pointer in zero page is pointing to. It's troublesome
to have to occupy the Y register with 0 every time, and then to eventually to have to save
it from somewhere. For this reason, there's a new address type now: LDA($FD).
In Listing 5.2 you can see how it works.
Relative Jumps
With jumps, we know of two possibilities: either the absolute or the relative jump.
The relative is always a jump "from here on", from some byte back or forwards
(127 byte range). This interval is saved with the command so that we have only 2
bytes per branch command (the disassembler always knows what to do). It's always a
bad feeling to have to jump over a sequence of a few bytes with a JMP command. You
might think that a BNE will do it too - but the zero flag may never be set at this
location though ... this works most of the time, but if it doesn't, the location of the
error takes a large amount of effort. That's why the 65816 has the BRA (BRanch
Always) command (finally!). It will jump in every case, but is otherwise just like other
branch commands relative to the program counter. But it's not enough: You can
totally forget about the JMP command! If the BRA command has not reached its maximum jump
width of 127 bytes, just use the command BRL (BRanch always Long). This is a 3 byte
command like JMP, however the aim of the jump is relative to the current command address,
which is a great advantage!
One Bit Please
If you want to set or erase individual bits in a byte, often done with the VIC register,
the commands LDA, ORA (or AND), and STA would have been used up until now. Three
commands to change one bit! That's been done away with: The SuperCPU has two
new commands. One of these is TSB - Test and Set Bits against accumulator. What does
that really mean? Quite simply: You use the LDA command to get a byte in memory in
which all of the bits which are added to are 1 and the others are 0. Next, issue a
TSB address, through which an OR combination will be executed: All bits in memory
will also be set into memory, all other bits stay untouched. In addition, another
operation will be carried out: the memory will be combined with the memory location,
but the result will not be saved (just like with a BIT command). The zero flag will
be set if the result is 0. The opposite is the TRB command (Test and Reset Bits
against accumulator). Here as well, the memory must be occupied with a value.
This time, all the set bits in memory which are in the addresses behind the TRB will be
erased. Caution: This is exactly the opposite of the TRB command - all the
bits which are to be erased should be set to 0, and the rest to 1. With the TRB command,
however, it is the other way around. Just pay close attention to the orientation of
the bits, erased 0, untouched 1. With a TRB execution, the second operation stated
above will be executed (a real AND which, however, only effects the zero flag, not the
memory). In Listing 5.3 you can see the functioning
of this command.
You're a Zero!
In contrast to the development of other processors, the numerous commands as well as the
soldom used commands built into the 65816 are a foresight by the designers of the 65816.
They saw that one of the most common words written to memory was zero. If you look
at source code, you'll probably see that this is true. That's why there's a special
command that does nothing but save a zero to memory: STZ. With this, you can quickly
set one or more memory locations to 0, without having to write an LDA #$00 (or LDA #$0000)
and lose the contents of memory. Caution: The STZ command doesn't work with
all types of memory addressing. The variations are STZ addr, STZ dp, STZ addr,X and
STZ dp,X ("dp" = direct page). So don't be confused when the assembler
won't deal with an STZ addr,Y.
That was just the beginning
Next time we'll get right to it: There are actually more types of memory addressing,
which have to do with stacks. These have "another dimension" with the
65816 - they really make interesting things happen...
© 1999 GO64! Redax & Count Zero/SCS*TRC for all HTML Stuff