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...

(w) ThunderBlade/DMAgic

1999 GO64! Redax & Count Zero/SCS*TRC for all HTML Stuff

[ To Part 4 ][ To Index ][ To Part 6 ]