TI-86 Assembly
Hello, World
To make TI-86 assembly programs, download the Assembly Studio 8X 4.0 from
ACZ. It's the most user-friendly compiler. Next, make sure to have RBP2.inc, my extensive header file. A header file contains equates for the compiler to use. A compiler takes commands from a source file and converts (compiles) them to binary machine code. Binary is a number base, which, along with decimal and hexadecimal, can be used within source files. Please view the Base Conversions document for more help. We're going to start a bit more advanced than others, since I believe you're not retarded... Source files are text files with a .z80 or .asm extension; open one and here we go:
That's good and all, but bulky. Perhaps you're confused, so line 1: .plugin asm86. That is a directive, only for this compiler, and tells which DLL to use when compiling. Several DLL's exist for most z80 TI's; there are 3 for the 86: string86 (.86s), asm86 (regular .86p), and lite86 (compressed .86p). Several coders prefer lite86 compression, but use it on your own time :-) The #include directive allows for header or source files. In the example we're using it to find a header file, which has all the needed equates. To find a header file, the compiler looks in the source file's directory, or in it's own /include directory. If not found an error occurs and compilation stops. .org $D748 puts the code at the TI-86's "current program location", byte $D748 (hexadecimal). call _clrLCD executes code at the memory address $4A7E, for which _clrLCD is just an easier-to-remember acronym. af, bc, de, hl, and ix are 16-bit registers, meaning each can hold 2 bytes. With ld hl,Hello we set hl to where the data at label Hello is located. Next, 2 is stored to the accumulator, register a (we can't set register f). Any register can hold the values -128 to 255. Of course, _curRow and _curCol are acronyms for memory addresses. The happen to control 'large text' coordinates and are $C00F and $C010, respectively. Being next to each other in memory means both can be loaded at the same time by a 16-bit register (loaded to _curRow). call _puts displays zero terminated text (ie: .db "WTF!",0) at (_curRow,_curCol), and also points the hl register to just after that zero. ret is self explanatory, as is the rest of the code. Remember, I called that "bulky", so here's a smaller version:
Here the only differences are that _curRow is loaded by a 16-bit register and we're using jp _puts instead of call _puts. Whenever you have a call instruction followed by the ret instruction, feel free to substitute the smaller, faster jp instruction. Thusfar you've learned how to use the given codes, but not how to manipulate them for your own uses. We're going to backtrack and show a full explanation on registers.
Registers
There are several registers; 8-bit and 16-bit. They are as follows:
8-bit: a, a', b, b', c, c', d, d', e, e', f, f', h, h', i, l, l', r
16-bit: ix, iy, pc, sp
The 8-bit registers followed by an apostrophe are shadow registers. a, b, c, d, e, h, and l can
be directly accessed by the CPU, and are often paired: af, bc, de, and hl. f is special for each
bit has a special meaning. a is the accumulator and by far the most important. pc is the program
counter, always pointing to the address being executed, and can't be directly accessed. sp is the
stack pointer, the stack being a location for storing/retrieving 16-bit values using push/pop
instructions (explained later). ix and iy function much like hl, all 3 of which are used to
determine which byte we're referring to. iy is most often used for system flags. Much more detail
will surface later on the nature and function of each register, so if you're still awake
READ ON!.
Text Styles
Overwhelmed? The stack, subroutines, and flag manipulation are new. Subroutines are easiest; they are small bits of code performing a specific task according to an argument or several (usually registers). In BigText and SmallText we need hl to point to the text data (easy enough) and de is used as the coordinates. The subroutine Inverse checks if the system flags are set to inverse text and flips that setting. bit $03,(iy+$05) checks a bit in the 5th byte from iy (blah, blah, blah) and if the bit is set to 1, resets it to zero; if the bit is zero, it sets it to 1. Please look at the System Flags documentation in the appendices for more information. The stack can be accessed by pushing and popping 16-bit values. The stack itself is like a storage bin; to save a value you push it in (ie: push af)m which can be restored later to most 16-bit value , but usually the original (ie: pop ix). In this example we take load bc with 10,000 ($2710), push it several times, and restore it to almost all 16-bit registers and their shadows:
We could've popped it to iy, but that 16-bit register should never be altered because it almost always points to the system flags. This concludes Lesson 1. Please don't continue unless you're comfortable with all material here and much of what is shown in the listed appendices.
Appendices: TI-86 Basics,
Base Conversions,
System Flags
Now, on to
Lesson 2: Keyboard & Menus