"To err is human. To really mess things up you need a computer."
Created: 12th September 1999
Last Modified: 27th November 1999
This page will explain what assembly actually is, along with the difference between assembly and machine code.
Assembly is another kind of programming language for the ti86. It is far more powerful than the built-in language, allowing the programmer access to features of the calculator impossible to access using the built-in language. For example, in assembly you can write fast greyscale scrolling platform games. Using the built-in language, graphics are unbelievably slow, greyscale is impossible and scrolling graphics would take about 30 seconds to move everything one pixel to the left. Assembly allows you to write programs which access the linkport or change the contrast, but using the built-in language you can do neither of those.
However, such power and speed has a cost. Assembly is much harder to write or learn, and there are no shortcuts. One mistake and you could find your entire memory reset and you would have to take the batteries out of your calculator and put them back in again before you could even turn it on.
To make things even more annoying any assembly program you write for a ti86 will only run on a ti86 (most ti85 assembly programs can be run on the ti86 with a bit of conversion work). This is because the instructions you give deal with the processor directly. Since the ti86 has some form of a z80 as the processor this tutorial will teach you only z80 assembly, and more specifically, only for the ti86.
Whilst Assembly is more powerful and thousands of times faster it does have disadvantages besides being more complicated. The most significant of these is that you need a computer to write the programs. A few people claim to be working on assemblers that will run on the calculator but I'm fairly sure that if they ever actually get them working they will either be hopeless or take up all the memory on the calculator. (Actually, there is one now, but it crashes all the time and is completely hopeless). You can't write an assembly program and test it in a maths or physics class because you need a computer with an assembler on it, whereas if you were using the built-in language you could quickly develop a program to solve some problem very quickly.
To illustrate the differences between the two languages a sample program will follow. Whilst the fact that the assembly version is more complicated can easily be seen, the speed difference isn't that obvious between the two, although the assembly version does actually run a lot faster (you can't really see this because the programs are too small).
Create a program for the ti86. The program should display the numbers 1, 2, 3, 4 and 5 in that order on separate lines. The calculator should then pause until the enter key is pressed, then clear the screen and display the numbers 6, 7, 8, 9 and 10, pause and so on up to 50. The claculator should then wait for enter to be pressed, clear the screen and exit.
The following program using the built-in language will perform the above task. It is pretty much self explanatory, the mod function is used to detect every five numbers (it divides and takes the remainder).
Source: count1.txt
Compiled: count1.86p
:ClLCD :For(x,1,50 :Disp x :If (mod(x,5))==0 :Then :Pause :ClLCD :End :End :Stop
This version is more complicated, but the comments explain it (sort of). If you can't understand any of it don't worry - it's quite complicated and it will all be explained later.
Source: count2.asm
Compiled: count2.86p
#include "ti86asm.inc" .org _asm_exec_ram call _clrScrn ; Clear screen call _homeup ; Cursor to top left ld b,10 ; Set Outer Loop Counter to 10 xor a ; Set a to 0 ld h,a ; Set hl to 0 ld l,a OuterLoopStart: push bc ; save Outer Loop Counter ld b,5 ; Inner Loop Counter InnerLoopStart: inc l ; Add one to number push hl ; Save number xor a ; Set a to 0 (some calls may change it) call _dispAHL ; Display Number call _newline ; New Line pop hl ; Restore number (_dispAHL trashes it) djnz InnerLoopStart ; Dec loop counter, loop if <> 0 push hl ; Save number (call _pause trashes it) call _pause ; Pause calc call _clrScrn ; Clear screen, cursor to top left call _homeup pop hl ; Restore number pop bc ; Restore OuterLoopCounter djnz OuterLoopStart ; Dec loop counter, loop if <> 0 ret ; Return from program .end
Either type the first program into the calculator or use a program to transfer the .86p file to the calculator. Run it by typing in count1 and pressing enter. You should get a display that looks like the screenshot shown below. Note that there could be a second or so delay before the program actually runs.
Copy the above program into Assembly Studio, or use the .asm file provided. Assemble it and send it to the calculator as described previously. Run the program by typing in Asm(count2) and pressing enter. The program should run instantly giving the result shown below.
![]() |
![]() |
| Built-in Language | Assembly |
Note that the Assembly program puts the numbers futher to the left of the screen than the version using the built-in language. It would be easy enough to right-align the numbers in Assembly, but as the specification did not state where to put the numbers I have written the Assembly program in the quickest (two lines shorter) way I could think of. The program could be optimised futher but I'm too lazy to spend half an hour making a program run a few milliseconds faster or take up two or three bytes less of memory.
Machine code is the actual language of the calculator. It is stored as a load of 0s and 1s in the calculator's memory and is practically impossible to write. A program that would clear the screen and bring the cursor to the top left of the screen might look something like
CD824ACD954AC9
using hexadecimal notation or in 'true 0 and 1 format'
11001101100000100100101011001101100101010100101011001001
As you can see, it would be stupid to write programs like that unless there was no choice. So someone invented Assembly. Assembly offers identical functionability to machine code, but rather than writing 11001001 you would write ret and let an assembler turn it into numbers (the ret instruction is short for return - it ends a subroutine or program). Assembly does not add any new instructions, it merely lets us use mnemonics to represent the numbers used by the computer. Assembly exists because computers can only work with numbers, but humans find it easier to work with words. The above example in assembly with the numbers it represents next to it is:
CD824A call _clrScrn CD954A call _homeup C9 ret
If you look carefully, you can see that both the call instructions start with the same
two characters. This is not a coincidence - CD is the
machine code equivalent of call, and the next for characters
state the memory location of the command being called. The two commands ending in
the same two characters is a coincidence (the two commands are very close to each
other in the ROM).
Also note that only the first few letters of the alphabet are used, along with various numbers. The reason for this is explained in the next page.