Assembly Calculator Hacks

This article is under construction and needs to be completed. You can help by expanding it.

From the release of the first TI graphing calculator in 1990 (the TI-81), the TI community has battled Texas Instruments in trying to hack the TI graphing calculators to allow for features and functionality that TI never meant them to have. The release of the first three graphing calculators — TI-81, TI-85, and TI-82 — did not provide access to the built-in assembly language and ROM code that powered the calculators, so the TI community had to figure out the underlying code and internal structures of the calculator on their own. Although this was a rather arduous and lengthy process, it was hastened by the TI community working together in cooperation and sharing information and resources on the Calc-TI mailing list.

Rather ironically, although the TI-81 was the first TI graphing calculator to be released, programming and development for it was quite limited as it lacked the linkport needed to send and receive programs. It was not until twenty years later in 2010 that it was eventually hacked to allow for assembly programming. The TI-85 was actually the first TI graphing calculator to be hacked by the TI community to allow for assembly programming by exploiting a flaw in the custom menu, and the TI-82 followed suit using a similar memory hack.

TI eventually caught on to the fact that the TI community enthusiasm and exuberance for assembly programming was not going away, and they decided to provide built-in support for assembly programming on the TI graphing calculators. The first calculator to receive native assembly programming was the TI-83 released in 1998, and it was made possible using three assembly commands; a person needed to compile hexadecimal code using AsmComp( and then use Asm(9ProgName) to execute the program. TI also provided programming documentation on their website, detailing the underlying code and internal structures of the TI-83.

One of the problems that the TI community has had to deal with is when TI updates the ROM code for a graphing calculator. As all of the assembly programs are written using the specific ROM calls and memory addresses, when those things change the programs cease working. The assembly programs then need to be updated to use the new ROM calls and memory addresses, but this is only possible if the accompanying sourcecode for the programs is included; unfortunately, there are many programs that don't have the sourcecode, and thus the programs become obsolete as they no longer work on the calculator.

(Taken from Calc-TI FAQ)

In order to get a ROM based OS (any OS, including those in the
82/85) to call a machine code program in ROM, you need some way of
telling the OS to stop executing the routines in ROM and execute
routines at an address in RAM. In home computers and suchlike, the
designers were nice enough to put special commands and such to
allow assembly code to be run (i.e USR on the spectrum). On the
Texas Instrument calculators, the designers did not want to
implement this type of function because they believe that it would
violate the integrity of the system (and this is quite a sensible
stand to take, considering the RAM is used as a storage device) So
if we want to get a TI to call a routine in ram, we must take
advantage of some mistake made by the designers… Such mistakes
that would allow this would be: at some point in the execution of
ROM, it takes an address from RAM and calls this, or at some point
calling an address in ram where it had previously put a routine to
be executed. The second option is often found on systems where ROM
swapping is used, but unfortunately not on the TI calculators (they
work by leaving one section of ROM in the same place all the time)
So we're left with examining methods using the first option, which
could be found in a number of situations, though the TI programmers
would have been careful to try and avoid it.

On the TI-85 this loophole was found in the custom menu. The custom
menu consists of addresses which point to a number of tokens which
determine the operation to be taken by the system. The usual token
uses is that meaning ' take the string that this address points to
(gives address) and display it in the custom menu box and when the
item is selected, copy it into the homescreen buffer' On the
Earlier versions of the Ti-85 another take was made use of by the
system to allow you to make custom menu items that ran one of the
TI's 'application' programs (things like the Polynomial solver, the
program editor, etc.). Now the way they implemented this was to
make a token that meant 'display this string (gives string' in the
custom menu box, and when it is selected jump to this address
(gives address)', so in normal use the addresses would point to ROM
routines. (NB the catalog items that did this were removed in later
ROM versions, though they still left in the token system that
allowed it..) So all that was needed to make the OS call a routine
in ram was to edit a backup so that the custom menu was contained
this token, and the address pointed to a place in ram where you had
put your routine. (there were numerous problems with where in ram
to put the routine, but this was the crux of the matter)

This method was noted because there was obviously a method by which
ram was altered in some way to allow the user to call a routine in

Now, no such method could be found on the ti-82, despite a lot of
peoples work on it. But if you believe that there could be a way,
you now know what you need to achieve to do it..

(Taken from

ZShell History


Programmability has always been a great strength of Texas Instruments Graphics Calculators. In the original TI-81 and all models following this programmability has manifested itself in the form of TI-BASIC. TI-BASIC benefits from relative ease-of-use and power, however, it is very slow. Quickly, programmers wanted to use Assembly language on their calculator, because it would allow them to create much quicker programs. Unfortunately, TI had designed its calculators originally not to allow this. This didn't deter the developers of ZShell.

The first release of ZShell was in 1994. It was a lot simpler than most shells that are in use today, but the important part was that it worked. It was a marvelous hack that was used to make it. Many people who had played with the TI-85, realized that it had a custom menu. Upon further examination, they discovered that the custom menu stored pointers for the items that you put on it. These pointers were generally to ROM routines, but they could be edited to point to a piece of memory where ZShell was located. Once the processor control came into ZShell's control any other program could be run. The early versions of ZShell were written by Dan Eble.

The last version of ZShell to be produced was written mainly by Magnus Hagander. It was version 4.0. It is still a popular shell for the TI-85, and it enjoys stability and basic functionality. Today, the TI-85 and ZShell are all but forgotten, but it is this humble start that led to all the Assembly developments we enjoy today.

Fargo History

With the TI-92's release, there was a lot of excitement. Not only was the TI-92 going to have symbolic algebra capabilities, but it was also using the 68000 chip, an assembly programmer's dream chip. Interest in programming on it was great. Unfortunately, TI wasn't going to make it as easy as before to create programs in assembly. This did not deter Dan Eble and David Ellsworth.

The problems they faced creating an assembler shell for the TI-92 were great. First of all, it was a whole new chip, so the old ideas were pretty much out the window. Additionally, TI fixed the loophole they left with the TI-92, and now the Custom menu was used parsed symbols opposed to hard coded pointers. This meant that the old trick couldn't work anymore. Fortunately, ingenuity prevailed.

The method finally decided for the TI-92 was to take a backup of the TI-92. Then you add a little bit more onto the backup so that it was slightly too big. When you sent it back to the calculator, the memory overflowed and the remaining part got put at the beginning. By no coincidence, at the beginning memory is what is known as the interrupt vector. This is a table that contains all the pointers to what you call interrupts, things that interrupt the CPU to do other things. One example of an interrupt is the keyboard handler. This extra code at the end of the backup rewrote the vector table to include Fargo locations.

Fargo was released slightly early. Its first release was an unofficial beta that was "leaked." David Ellsworth continued to develop Fargo. The newest version is known as Fargo II. Fargo marked a remarkable "hack." Despite the nature, it was very cleanly implemented. It contained libraries. It will definitely be remembered as a great achievement of the TI world.

TI-89 Assembly

TI released the 89 in August 1998. It was snatched up by many students taking precalculus and calculus, and it was hailed as a great alternative to the large, unwieldy TI-92 Plus. It was also touted as lacking a QWERTY keyboard, so it could be used on standardized tests. The 89 also had an interesting new feature - FLASH upgradeability. FLASH could be used to upgrade the ROM version or to add new programs to the 89's wide range of abilities. Since then, two new ROM versions - 1.05 and 2.03 - have been released by TI. Both of these have caused much unrest in assembly coders because their games were rendered incompatible. Fortunately, a patching utility has been written for AMS v1.05 that fixes most problems in that ROM version. 2.03, being a very new ROM version, has had lackluster support at press time. Also of note was the new hardware version that TI released for the 89, called Hardware v2.00. This caused major problems with grayscale games. Scott Noveck of ACZ and Niklas Brunlid have released patching utilities that help to fix this, but a great deal of flickering still results. Several programmers are working to fix the bugs inflicted in their games by the new ROM and hardware versions. The Doors team has released DoorsOS II, a shell designed to work on AMS v2.03. Many new developments are being released, so stay tuned!

Assembly Language Programming

When the TI-85 was released, a loophole was found that made it possible to run machine code on the calculator's 6 MHz Z80 processor, bypassing the usual interface. Such programs were smaller, faster, and more graphical than TI-BASIC programs could ever hope to be, and assembly language programs became very popular. After the TI-92 became available, another loophole was found, allowing even more powerful programs on its 68000 processor. Finally recognizing customer demand for assembly support, TI built assembly ability into its recent TI-83 and TI-86 calculators. However, the TI-82 was still left in the dust until recently, when yet another loophole was discovered. It is now possible to program in assembly on any TI graphing calculator with linking capabilties.

As mentioned, the TI-83 and TI-86 feature documented assembly language ability. However, in TI's earlier calculators, such functionality was obtained "the hard way." Following is a chronological history of how these discoveries were made on the various calculators.

TI-85 (ZShell, Usgard, Rigel, PhatOS): An analysis of memory backups sent to a computer showed that items in the CUSTOM menu were represented in the backup as pointers to memory locations. Assembly code was stored in a string variable and sent to the calculator in a fixed position - the first variable sent after a memory erasure - and its memory address was found after another backup to the computer. This address was placed in a CUSTOM menu entry field in the backup file, the file was sent back to the calculator, and when the CUSTOM entry was selected, it executed the new assembly code.

TI-92 (Fargo): It was discovered that sending a memory backup from the computer to the calculator with excess information would cause an overflow into other areas of memory. The correct amount of overflowing data was deduced, and placed in such a position that it would overwrite the 68000's vector table, which points to routines that the processor calls to handle certain events. These routine pointers were modified to point to machine code in RAM. (Note: this explanation is included solely for historical purposes. A better method was discovered later; it does not require an oversized backup file.)

TI-82 (Ash, CrASH, OS-82): The TI-82 was a mystery for a long time. People passed the idea of assembly language support off as a joke, saying it was impossible. Finally, in the middle of 1997, a shell was produced. This first shell was called OShell-82 (later renamed to OS-82), and it was followed shortly by Ash. These both use a similar approach. The TI-82 uses a buffer (as does the TI-85) that points to the next routine that needs to be called when a key is pressed. When the pointer is changed and a key is pressed we can execute assembly. A dummy variable is used that points to a location in RAM where assembly code is stored.

(Taken from

2.2.1 TI-83 ASM
Shells include Ashell83, SOS, Ion, and ZeS. Ion is the most commonly used TI-83 shell.

2.2.2 TI-83 Flash family ASM
The 83 Flash family won't run 83 assembly programs. The 83 Plus Silver Edition is generally compatible with 83 Plus assembly programs, although speed issues often cause separate versions to be produced. Presumably whatever works on the 83 Plus Silver Edition will be okay on the 84 Plus and 84 Plus Silver Edition, but it's too early to say for sure. The first shell out for the 83 Plus was Ion, which has a version for both the 83 and 83 Plus. Programs written for Ion require it to run. Other shells include Ice, Inferno, Izzard, CrunchyOS, GlobalOS, Doorways Pro, Plasma, PSE, and NimbusOS. Most if not all of them are Ion-compatible. MirageOS is a Flash application shell, it is also Ion-compatible. Ion seems to be the de facto standard for TI-83 Flash family assembly, the only attempt at an alternative that I am aware of is TSE. MirageOS is the most commonly used TI-83 Flash family shell. There's a nice comparison of several shells here. To run assembly programs that do not require a shell (if there are any) from the home screen, use the following syntax: Asm(NAME .

2.2.3 TI-86 ASM
The TI-86 has the distinction of being the only calculator for which assembly programs are regularly written based around the calculator's native assembly functions and not any specific shell. Shells for the 86 are there mostly to provide program menus and other assorted goodies. Shells include ASE, Anaconda, Rascall, Byronic Shell, Mini-Shell, Micro Shell, Omega Shell, Iridus, YAS, Zap-2000, and Ion86 (Ion emulation). Shells from the 85 won't run on the 86, but a few of the 86 shell do provide ZShell emulation for running 85 assembly programs on the 86.. To run assembly programs from the home screen, use the following syntax: Asm(NAME . The Asm( command is found only in the catalog, but it can be placed in the custom menu for quick access.

2.2.4 TI-89 Flash family ASM
(See also: the TI-89 Flash family section of Patrick Davidson's FAQ)

The 89 Flash family contains built in assembly abilities like the 83 and 86, however programming using shells and/or kernels remains popular, and they must be used for many assembly programs. Available shells and kernels for the 89/92+/V200 include Doors OS, TEOS, VisualOS, Prosit, PreOS, ProShell, Universal OS, and LexOS. (The shells provide a menu list of available programs, but you can also run them from the command line like Basic program as long as the kernel is installed.) These shells often make use of external library files that are required to run certain games. DoorsOS was once the most popular, but it has fallen into disuse. Universal OS and PreOS are the most commonly used kernels for the 89/92+/V200.

The TI-89 Titanium, as with most new models, sent programmers scrambling to update the kernels. Iceberg can be used in concert with the HW3 patch and older 89 Flash family programs that have been patched using GhostBuster. The latest version of PreOS also supports the 89Ti. As to which is better to use, it's all still so new that opinions have yet to emerge.

Note that the shells and programs written for the 89 Flash family are made for specific ROM (AMS) versions. If you Flash upgrade beyond the version the shell was designed under, it will probably not function. If you have already done this, you can e-mail TI for the old ROM (provided your e-mail provider can accept file attachments that large). Also note that if your calculator came with AMS 1.05 or higher, that means you have Hardware Version 2.00 and cannot downgrade to AMS version 1.00. Of course at this point, if the shell you have won't work with at least AMS 2.05, it's so outdated you probably shouldn't be using it anyway.

There is also the issue of the hardware version. Program size limits imposed by TI in Hardware Version 2 and various other complicated things that the programmers don't like having to deal with are defeated by applying a patch file to the AMS. Part of what the patch does is to make the AMS allow TSR hooks for the purpose of enabling memory resident programs and a few other things which are not allowed by the OS by default. The HW2 patch can be found at The HW2 patch is not needed when using the PreOS kernel. There's also a HW3 patch for the TI-89 Titanium (it works in place of the HW2 patch on the earlier calculators as well). If the appropriate patch or kernel is not installed, the size limit manifests itself as the error message "Error: ASAP or Exec string too long".

Assembly programs termed nostub tend to work across a wider variety of AMS versions as they are, and they generally do not require a shell or kernel at all unless it is to avoid the size limit. Many 89 Flash family owners only use assembly programs that are nostub, and their popularity has increased while the disadvantages and difficulties of using shells have remained. The TI Chess Team has developed a nostub Start Utility that is intended to defeat the size limit for nostub programs without using a shell or the HW2 patch. KerNO is another program for nostub users, it provides features that kernels do while remaining nostub.

2.3.1 TI-82 ASM
Ash, CrASH, and OS-82 are 82 ASM shells.

2.3.2 TI-85 ASM
There are several 85 assembly shells out there, ZShell is the most widespread as it was the first one. However, all subsequent 85 ASM shells have retained ZShell compatibility. ZShell was developed by hackers and likely is the reason it occurred to TI to build ASM capability into the calculators starting with the 83. TI does not support or acknowledge the existence of ZShell or other hacker made programs. It works because the hackers messed with an 85 computer backup and stuck a command in the custom menu pointing to a place in memory that gave them access to the Z-80 processor functions. ZShell and the other TI-85 shells can only be installed by backup from a computer or another 85 because the command can't be put in the custom menu from the calculator. If the command is erased from the menu, the ZShell backup must be reloaded. Other 85 ASM shells include Usgard (probably the most popular after ZShell), SuperNova, Rigel, PhatOS, CShell-NT, Menu Independant SHell, OS/7, OS-85, and Summit.

2.3.3 TI-92 ASM
Only one shell was ever made for the original TI-92, Fargo. Fargo II updated the original Fargo, though a program module is available that allows Fargo II to run programs written for the original Fargo. Be sure to read the fargo.txt file that comes with the Fargo program files for instructions on installing Fargo to your TI-92. A TI-92 with the Plus Module will use its own ASM capability, without need for Fargo.

Fargo and Fargo II utilize add-on files called libraries which contain common routines for use by programs. Most programs require a specific set of library files to run. This is done to save space (instead of each program having a copy of a routine, they share a single copy), however it has been known to cause confusion.

Interestingly enough, years after the original 92 has faded from most people's memory, it seems the TIGCC folks are experimenting with allowing one to make Fargo programs using TIGCC.