Getting Started

Probably the place where you'll get the most confused at first is the bank scheme for variables and the paging of program memory that is imposed on you by the SX chip architecture itself. that's where a high level language like BASIC or C helps by hiding the architecture from you and doing a lot of work behind the scenes. It's also the reason that high level languages are never as efficient as programming assembly. Of course, most people find they are more efficient programmers when using high level languages, so you need to consider the tradeoff of execution speed versus time to create and debug the program itself. If you want to use high level languages with the SX, you have numerous choices, but they pretty much all cost money. Programming in assembly is "free" on the SX once you have something like the SX-Key. Programming in a high level language means paying for a compiler as well.

Assembly isn't so bad. There are macros available to automate access to subroutines and lookup tables over multiple pages. For SASM (in the new SXKey 2.0 beta or above) see sasmmem.src as used in the sasmtemp.src program template and for the SXKey internal assembler see keymacs.src.

Most instructions are fairly clearly described in the instruction set. The syntax can be a bit confusing (remember: everything is a number in the end, 2 or PC is the program counter, #2 is the number two). The tricky stuff is usually figuring out how to do things that are not listed in the instruction set:

Math: A common question is "How do I use numbers bigger than 255? I mean, I have a 32-bit pentium processor, which counts over 4,294,967,296..."  and the answer is: Use a second register. The first does 0 to 255, if the second is 0, but it represents 256 to 511 if the second register is 1 and so on. The result is 256 times 256 different possible values or 65536 total values. This can continue with three or more registers untill you reach a point where all the memory locations are used or you have a big enough number range.

And despite the fact that the SX only does addition and subtraction, you can write code that does all sorts of other things. It turns out that the rotate instructions can multiply or divide by a multiple of 2 and that combinations of that can handle any number. Almost anything can be accomplished. The expression evaluator can help you to translate most mathimatically formulas into a sequence of (mostly) available assembley routines.

Program Flow: Here are some good examples of high level language constructs and how you can do them in ASM on the SX:

Loops: The instructions like JNZ and JZ are the key here. Basically you need to load the W register with a value and then decrement it. You then execute the JNZ or JZ instruction to determine if you need to keep looping or if it's time to stop. Here's a more concrete example:

    mov w, #4        <- We're going to loop 4 times

Top_Of_Loop    <- This is a label

    ; Here is where you would put the
    ; instructions that do the actual work
    ; inside the loop.

    dec w                <- Decrement the loop counter by 1
    jnz Top_Of_Loop    <- IF W not equal to  0, THEN GOTO Top_Of_Loop

This is a fairly useless example, but it demonstrates the basic concept. Just like in any language, you need to have a place to keep track of how many times you have gone through the loop. In this example I use the W register. You could just as easily use any other register. After loading it with the number of times to want to loop, then you enter the loop. It is critical that the place where you initialize the counter is <outside> the loop itself, or else you'll just keep resetting the counter forever. Inside the loop, you'll have some instructions that do some work. At the end of the work, you decrement the counter and then see if it equals zero yet. When the "dec" instruction is executed, it will automatically set the "zero" flag in the CPU if register equals zero after the "dec". That's why we use the JNZ (Jump if Not Zero) instruction here - if the zero flag is not set, then we jump back to the label following the "jnz" instruction.

If/Then: As you can see in the above example, the JNZ instruction is basically an if/then in a single instruction. That's why I wrote out the description the way I did. The instruction itself is just (J)ump if (N)ot (Z)ero, but that's really just an incredibly compact way of saying "If the zero flag is not set, then perform the jump".

There are macros available that can make most of this automatic. For SASM (in the new SXKey 2.0 beta or above) see sasmcond.src and for the SXKey internal assembler see keymacs.src

Input and Output: At 50-100 MIPS (not just MHz, MIPS!) SX uCs are so fast, that many hardware functions can be "virtualized" into the software, reducing chip count and increaseing versatility. Turning a hardware chip into a processor routine is a lot easier that you might think... If you can describe the signal that needs to be generated or decoded, and you can think about being really fast and what you would do to translate the signal in or out, then you can probably come up with a sequence of SX instruction that will do the job. There is a library of existing code that does some pretty amazing things.

Online books:

Interested: