LE LANGAGE ASSEMBLEUR MOTOROLA

Plusieurs personnes m'ont demandé des explications sur ce langage peu connu mais extrêmement puissant pour les 92, et d'ailleurs pour toutes les calculatrices Texas Instruments depuis la TI-73 (hormis la 80 et la 81). Il est vrai que sur le Net, il est plus facile de trouver des programmes ASM (assembleur) que des explications à ce sujet, et particulièrement en français.

Néanmoins, je recommande d'ores et déjà pour les personnes intéressées par l'apprentissage de l'ASM pour 89 et 92, de télécharger gratuitement ZGuide, un guide complet, en français et très bien réalisé par Florian Drevet. Attention, ce lien étant ancien, je ne suis pas sûr qu'il soit encore fonctionnel. Je le vérifierai sous peu.

petitefleche.gif (1928 octets) Qu'est-ce que l'assembleur ?

L'ASM est un langage commun à toute machine possédant un microprocesseur. Ainsi, les ordinateurs comme les calculatrices "parlent" assembleur, mais différemment (puisque leurs procs (processeurs) sont différents, leur assembleur est différent: c'est ainsi que l'assembleur Intel (pour les procs Pentium par exemple) est différent de l'assembleur Motorola (pour les procs 68000 qui équipent les 89 & 92). L'ASM est un langage dit de "bas niveau", c'est-à-dire intégrant directement les fonctions du proc. Les instructions disponibles sont donc quasiment limitées aux instructions qu'il peut réaliser. Mais comme ces instructions ne s'expriment dans le proc que sous la forme de 0 et de 1 (état bas, état haut), ce que l'on appelle le langage machine, l'assembleur utilise des "mnémoniques" qui remplacent ces suites binaires et surtout barbares par des mots plus ou moins explicites. Ainsi, l'ASM n'est qu'une version "humainement lisible" du langage machine. Par exemple, l'instruction permettant d'ajouter deux registres entre eux s'écrit peut-être 0111010101110101 etc... (je n'en sais strictement rien!) en langage machine, mais s'écrira en assembleur ADD AX,BX par exemple (ici, on ajoute BX à AX, et on stocke dans AX; BX et AX sont deux registres (sortes de cases mémoires intégrées au proc) de la famille des x86 d'Intel, comme le Pentium). L'assembleur se distingue des langages de "haut niveau" (tel le C, le Pascal, le Basic, le Cobol, etc.) du fait qu'il n'automatise pas des procédures communes (par exemple il n'y a pas d'instruction directe pour effacer l'écran, ce qui est très pratique, mais qu'aucun proc (donc aucun ASM) n'intègre comme instruction directe).

petitefleche.gif (1928 octets) Quels sont les avantages de l'assembleur en général ?

Sans se concentrer directement sur le cas des calculatrices TI, parlons d'abord des avantages en général de l'ASM. L'assembleur se révèle être un langage bien à part. Son principal atout est de permettre un contrôle total de l'ordinateur. Ainsi, chaque instruction codée sera ni plus ni moins exécutée. On sait précisément à chaque ligne de code ce que l'ordinateur va faire pour exécuter ça. Grâce à un tel pouvoir, il est possible de réaliser certaines tâches extrêmement poussées, de gestion pure du matériel, des calculs puissants etc... C'est la raison pour laquelle un OS (système d'exploitation, comme Windows ou Linux) a ses principales routines codées en ASM : il doit en effet avoir accès à tous les composants de l'ordinateur, et avoir un contrôle total sur tout. L'ASM permet aussi l'accès direct à certaines interruptions matérielles, ou aux interruptions du BIOS (des routines de gestion directe de l'ordinateur). On peut ainsi contourner certaines limitations des OS's, ce qui sera utile avec les calc comme expliqué au paragraphe suivant. Le deuxième avantage majeur de l'ASM est sa rapidité: en effet, les instructions génériques fournies par des langages de haut niveau sont élaborées de telle façon qu'elle s'adapte à chacune de leur utilisation. Car ces instructions, pour être compilées, ne sont ni plus ni moins d'abord traduites en ASM, puis ensuite en langage machine (le programme permettant de compiler de l'ASM ne fait, lui, que la dernière étape, bien évidemment). Mais comme ces instructions sont génériques, leur traduction ASM peut prendre par exemple 10 fois plus de mnémoniques que vous n'en auriez utilisé si vous aviez directement tapé en ASM (donc environ 10 fois plus de temps): pourquoi ? Parce qu'elles doivent gérer les erreurs, s'adapter à tous les périphériques etc... Par exemple, si vous voulez effacer l'écran, vous allez taper en Basic "CLS"; mais cette instruction traduite d'abord et automatiquement en ASM par votre compilateur Basic, prendra beaucoup de mnémoniques, car le programme doit utiliser des méthodes très génériques pour fonctionner avec n'importe quelle carte graphique, et doit rester vigilant face à d'éventuelles erreurs, pour éviter de faire crasher l'ordinateur ! Vous, en ASM, sachant quelle carte graphique vous avez (d'où un relatif inconvénient, voir plus bas), vous pouvez programmer en quelques mnémoniques un équivalent de CLS, beaucoup, beaucoup plus rapide. Le dernier avantage de l'ASM est sa faible taille: en effet, moins de mnémoniques, moins d'octets utilisés. Si vous avez un programme compilé Basic, ne faisant que CLS, il prendra plus de place sur votre ordinateur que si vous le faites vous même en ASM, puisque moins de mnémoniques seront nécessaires. L'ASM optimise en taille et en vitesse un programme.

petitefleche.gif (1928 octets) Quels sont les avantages de l'assembleur pour ma calculatrice ?

Comme expliqué plus haut, l'ASM permet de contourner certaines limitations des OS's des calculatrices. Par exemple, sur la 92, il n'existe pas d'instruction en TI-Basic (le langage "de haut niveau" de la calculatrice) permettant d'enlever la barre de menus, ou la barre de statut. C'est pour cela qu'un jeu ne pourra pas être en plein écran (vous aurez toujours ces deux barres). Avec l'assembleur, quelques mnémoniques et vous les enlevez. De ce fait, l'assembleur, en tant que langage de bas niveau, permet d'accéder à toutes les fonctions directes de la calculatrice, et permet donc de la "pousser à fond". Les graphiques réalisables sont époustouflants, extrêmement rapides d'affichage, et même en plusieurs couleurs ! (voir plus bas). Tout cela, en prenant moins de place sur votre calculatrice: vous pouvez donc mettre plus de programmes, eux-mêmes rapides et graphiquement intéressants.

petitefleche.gif (1928 octets) Quels sont les inconvénients de l'assembleur ?

Que ce soit pour un ordinateur ou une calculatrice Texas, les symptômes sont les mêmes si vous avez oublié des bugs dans votre programme ASM: plantage (ou "crash") irrémédiable. Sur votre ordinateur, vous pouvez parfois "rebooter" (redémarrer), ou bien il faut mettre sur OFF, et rallumer. Pour la calculatrice, c'est la même chose: il faut couper la tension. Mais au contraire de l'ordinateur, où l'interrupteur Power est mécanique, le bouton ON de la calculatrice n'est pas électriquement directement lié à l'alimentation. Il faut donc parfois ôter les piles pour couper la tension, ou bien utiliser une combinaison de touches pour la rebooter (ça marche assez souvent), voir pour cela plus bas. C'est le seul inconvénient direct de l'assembleur (car côté performance, vitesse, et possibilités, l'assembleur est le meilleur langage), hormis le fait qu'il soit "peu humain", un autre inconvénient qui crée son instabilité. En effet, puisque seules les instructions proc sont accessibles, il faut bien connaître le fonctionnement de la machine pour que ça fonctionne: pour reprendre l'exemple ci-dessus, en Basic, on ne se pose pas la question si l'on veut effacer l'écran: un bête CLS (qui vient de CLear Screen), dont on est sûr qu'il ne plantera pas la machine. En assembleur, il faut bien savoir manipuler des notions complexes pour arriver au même résultat (et en fait, à de meilleurs résultats). Ainsi, seuls des programmeurs expérimentés arrivent à faire des programmes ASM vraiment sans défaut. Mais bien malgré eux encore, l'ASM peut malgré tout planter. Et ceci à cause de conflits de librairies : c'est particulièrement valables pour les calculatrices. En général, les programmeurs ASM testent leurs progs sur une calculatrice vide, mais les utilisateurs peuvent avoir plusieurs progs ASM différents sur la même calculatrice. Pour gagner de la place et du temps de codage, les programmeurs ASM utilisent des fonctions toutes prêtes présentes dans des librairies partagées. Ainsi, sous PlusShell (un OS ASM pour 92+, c'est-à-dire un programme permettant de lancer des progs ASM, ce qui n'est normalement pas faisable, voir plus bas), la librairie "util" contient des fonctions pour effacer l'écran, afficher une chaîne de caractères, changer l'état de l'indicateur BUSY etc... C'est très pratique... mais les librairies évoluent également, et un programme peut nécessiter une ancienne version d'une librairie que vous aurez remplacé par la nouvelle en installant un autre programme. Résultat: le premier va planter (ou afficher, avec un peu de chance, un simple message d'erreur). C'est un conflit de version. Enfin, un dernier désavantage de l'assembleur est qu'il a une très faible portabilité: en effet, un programmeur ASM écrit ses sources pour un proc particulier, mais aussi une carte graphique particulière, une carte son particulière etc...: sur un autre matériel, le prog plantera. Au niveau calculatrice, cela se constate quand des utilisateurs essaye de passer de Fargo (92 I) à PlusShell ou DoorsOS (92+): les calculatrices étant fondamentalement différentes, tout plante. Le moyen est d'utiliser un convertisseur de format dans le cas de PlusShell (convert.exe fourni avec PlusShell), car les développeurs de PlusShell ont eu l'heureuse idée d'implémenter la compatibilité descendante, c'est-à-dire que grâce à de mineurs changements, les programmes 92 I (ou II) peuvent tourner sous PlusShell.

petitefleche.gif (1928 octets) Comment installer l'ASM sur ma calculatrice ?

Pour n'importe quelle calculatrice Texas, les programmes ASM que vous trouverez par exemple sur http://www.ticalc.org sont directement transférables sur votre calculatrice, mais ne pourront marcher sans l'OS ASM qui leur convient. "OS ASM" est un abus de langage, car l'OS originel, le TI-OS (Texas Instruments' Operating System) n'est pas effacé (heureusement!) et deux OS's ne peuvent normalement pas cohabiter. Ici, on entend par OS ASM un programme lançable par différentes méthodes (quelques fois "exotiques", voir point n°5), et qui permet ensuite par un Shell (une interface) de lancer des programmes ASM sur la calculatrice. Voici les étapes à suivre pour installer correctement de l'ASM sur sa calculatrice (notez que l'on ne peut transférer un OS ASM à une calculatrice que via un ordinateur et un câble de liaison; calculatrice à calculatrice, ça ne peut pas fonctionner (sauf dans les cas particuliers de la 89 et de la 92+, voir plus bas)):

1. SAUVEGARDEZ le contenu de votre calculatrice (sous forme de Groupe ou de Fichiers séparés, PAS sous forme de Backup) ! L'ASM plantera bien une fois votre calculatrice, je peux vous l'assurer ! Attention, pour les 82, 83, 85, 86, 92 I et 92 II, l'installation de l'OS ASM effacera le contenu de votre calculatrice. Pensez à le restaurer une fois le point n°4 réalisé.

2. Vérifiez que vous avez suffisamment d'espace mémoire disponible. Référez-vous au Readme joint à l'OS ASM pour savoir de combien de place il faut disposer.

3. Si vous avez une 92 I ou II, vérifiez la version de votre ROM, car les backups de Fargo sont différentes selon les versions. Installer une mauvaise version provoque un plantage. Pour vérifiez, faites: 'F5' puis 'Diamond' puis '(' (parenthèse ouverte). Frappez 2nd - QUIT pour quitter cette page.

4. Transférez l'OS ASM. Sur 82, 83, 85, 86, 92 I et 92 II, il s'agit d'une Backup contenant à des endroits normalement inaccessibles le code de l'OS ASM. Par exemple, David Ellsworth, concepteur du génial Fargo pour 92 I & II, a d'abord réalisé une Backup d'une calculatrice vide, puis changé directement sur son ordinateur cette backup afin d'y incorporer le code de Fargo. Sur 89 et 92+, il s'agit du programme Kernel (= noyau en anglais). Voyez plus bas pour les spécificités relatives à ces calculatrices.

5. Transférez les progs ASM désirés et les librairies adéquates.

6. Lancez l'OS ASM, qui doit avoir installé le Shell. Sur 85 par exemple, il faut faire Custom - F1 pour le lancer; sur 92 I et II, c'est Shift + On. Sur 92+, on lance par exemple shell() comme un programme Basic traditionnel.

7. Lancez les progs désirés depuis le shell. Remarque: pour 89 et 92+, il existe des programmes ASM "nostub", ce qui signifie qu'ils n'ont même pas besoin d'un OS ASM pour se lancer. Dans ce cas il suffit de taper leur nom suivi d'une paire de parenthèses directement depuis l'écran Home, comme pour un programme classique.

petitefleche.gif (1928 octets) Comment récupérer une calculatrice plantée ?

Si votre calculatrice est "hangée" (to hang en anglais), "crashée" (to crash), "freezée" (to freeze), bref en français... plantée (l'écran est figé, aucune touche (y compris ON-OFF ne répond etc...), vous avez plusieurs possibilités pour la remettre dans son état originel. Essayez tout d'abord les combinaisons de récupération: je ne les connais pas toutes, elles sont différentes selon les calculatrices. Sur 92 I-II-+, c'est 2nd + LOCK + On (une deuxième existe, plus "puissante": ) + (-) (parenthèse fermée, et touche (-) à droite du point)). Référez-vous au Readme de l'OS ASM pour les combinaisons valables. Si elles ne fonctionnent pas, essayez d'ôter les piles bâtons puis de les remettre. Si ça ne marche toujours pas, commencez à paniquer: il reste d'autres alternatives, mais le plantage est grave. Essayez d'ôter les piles bâtons, d'appuyer frénétiquement sur On (10 fois environ) tout en les remettant. 10 pressions sur On sont sensées "resetter" la calculatrice. Si ça ne marche toujours pas, ôter les piles bâtons et la pile lithium, puis remettez-les en appuyant aussi sur On frénétiquement. N'oubliez pas entre chaque tentative décrite d'essayer d'augmenter le contraste: la calculatrice peut avoir resettée, mais vous ne le voyez pas car elle est en contraste minimum par défaut...

Notez en tout cas que si l'on récupère quasiment toujours la calculatrice (heureusement!), un plantage ne peut se résoudre que par un reset, et une perte de tout le contenu de la mémoire: d'où l'intérêt d'avoir sauvegardé ses données.

petitefleche.gif (1928 octets) Certaines prouesses incroyables de l'ASM

Quel tableau sombre ai-je dressé dans le précédent paragraphe :-) ! Heureusement, à force de plantages et de réglages fins (j'entends par là utiliser les bonnes librairies, éviter deux programmes qui sont en conflit entre eux etc...), on peut conserver des programmes ASM très intéressants. Voici quelques réalisations de l'ASM qui rendent réellement la calculatrice plus performante et divertissante:

1. Le son: en effet, à condition de construire un petit module électronique approprié, que l'on branche sur le port I/O de la calculatrice, on peut obtenir du son ! Les jeux ASM déjà très rapides et très beaux prennent une dimension supplémentaire, et c'est réellement surprenant.

2. L'espace de stockage supplémentaire: je pense par exemple au fameux "Expandeur SF": relié au port I/O de la calculatrice, il lui adjoint un espace mémoire considérable, contrôlé entièrement par ASM. Je ne me rappelle plus des chiffres exacts, mais c'est de l'ordre du mégaoctet de mémoire supplémentaire (branché par exemple sur une 85, ça représente plus de 32 fois plus de mémoire... !

3. Le graphisme 3-D: la rapidité extraordinaire de l'ASM permet d'envisager le texture-mapping, le ray-casting et d'autres techniques en temps réel permettant de faire d'une façon simplifiée un DOOM-Like... ! Par exemple, est sorti tout récemment le FAT-Engine (http://tict.ticalc.org), qui obtient presque du 15 frames par secondes sur 92+.

4. Le graphisme 4 couleurs: ce principe, basé sur la persistence rétinienne, donne l'impression de 4 couleurs sur la calculatrice, normalement limitée au noir et blanc. En fait, plusieurs images noir et blanc se succèdent très rapidement (grâce à la vitesse de l'ASM, on ne voit pas (trop) de clignotement), mais à des vitesses différentes: selon que l'image reste plus ou moins longtemps, son contraste nous est différent, et on perçoit donc du blanc, du gris clair, du gris foncé et du noir ! Ce graphisme 4 couleurs (ou GrayScale) est particulièrement notable sur l'écran de la 89 et de la nouvelle 92 Plus, lesquelles disposent de nouvelles technologies LCD (cristaux liquides).

5. Le graphisme 7 couleurs: c'est le même principe, bien que les couleurs soient moins bien discernables.

6. La transmission Infra-Rouge: au moyen de modules électroniques branchés sur le port I/O, il est possible de chatter, d'échanger des progs etc... à distance !

7. Un moteur de jeu d'échecs: toujours sur http://tict.ticalc.org, on trouve l'excellent TI-Chess, qui non content d'être un programmes "nostub" (cf plus haut), est également très performant... et pas facile à battre !

petitefleche.gif (1928 octets) La 89 et la 92+ sont sensées intégrer l'accès direct à l'ASM : qu'en est-il réellement ?

Depuis les nouvelles versions du TI-OS (v2.05 actuellement, à télécharger sur le site de TI pour flasher sa calculatrice), on peut lancer les programmes ASM depuis la ligne de commande si ces derniers sont "nostub", c'est-à-dire qu'ils ne requièrent pas de OS ASM (cf doc de ces progs). Sinon, il faut donc d'abord installer le Kernel d'un OS ASM (les plus connus: DoorsOS, UniversalOS et PlusShell), en lançant kernel() : il s'agit d'un prog ASM, lui directement lançable depuis la ligne de commande. On obtient normalement "nom de l'OS installed version ..." ; vous pouvez alors taper DelVar Kernel, ce programme étant maintenant inutile. Dès lors, les progs ASM Doors ou PlusShell peuvent être lancés depuis la ligne de commande, ou depuis le Shell de l'OS de façon classique (Shell qui ne se lance plus par une combinaison de touches "exotique" (comme Shift + On sur 92 I/II), mais simplement en tapant Shell() ).

L'autre disponibilité théorique de l'ASM sur 89 et 92+ est l'instruction Exec. Selon le manuel d'instruction, elle permet d'exécuter une chaîne d'instructions proc Motorola 68000. Cette instruction est plutôt difficile à utiliser, et tout ce que j'ai jamais réussi à faire, c'est Exec "", qui fait planter la calculatrice ! :-). Vous trouverez ci-dessous (en anglais) un descriptif technique de la commande Exec provenant de Texas Instruments. Avis aux amateurs éclairés en ASM...


The Exec Command

(c) Copyright 1999 Texas Instruments Incorporated. All rights reserved.



Warning: Exec gives you access to the full power of the microprocessor. Please be aware that you can easily make a mistake that locks up the calculator and causes you to lose you data. We suggest you make a backup of the calculator contents before attempting to use the Exec command.

The TI-89 and TI-92 Plus have a new command which executes Motorola 68000 native code.
The Exec command accepts a string of hexadecimal ASCII characters, and optional parameters.
The TI-89 and TI-92 Plus have Exec "..." [,arg1,...,argn]

The string argument is converted to binary and executed as native 68000 machine instructions.
The string argument must end with four "zero" digits (0000).

The Exec command first converts the hexadecimal-ASCII string into a block of memory. The memory block is locked in place so it will not move once execution is handed off to the native code.

When the native code routine returns from execution via the RTS instruction, Exec frees the memory block containing the native code, then continues execution with the next program statement.

Relocatable Code

The Exec command expects the string to contain relocatable instructions. This implies PC-relative subroutine calls and jumps and PC- and stack-frame-relative local data storage.

For example, a call to a local subroutine RANDOM would be coded as:

BSR RANDOM

or

JSR RANDOM(PC)

Small amounts of initialized data storage area can be accessed with PC-relative pointers.

LEA SEED(PC),A4 ;PC-relative address of data
MOVE.W (A4),D0 ;get seed into d0
: ;calculate new seed
MOVE.W DO,(A4) ;update seed
:
SEED: .WORD 29

The above example loads the address of seed into register A4 because 68000 addressing does not permit storing directly to PC-relative addresses.

Larger amounts of uninitialized data storage can be allocated from the stack or heap.

The LINK instruction allocates memory on the hardware stack and points a stack frame register to it. Be sure to use the UNLK instruction to free the stack memory before returning from the native code routine. See 68000 programming literature for details on the use of the LINK and UNLK instructions.

The TI-89 and TI-92 Plus hardware stack is 16 KBytes in size-do not allocate large amounts of data storage from the stack. Use, instead, the heap.

Register Usage

Native code routines may use registers D0, D1, D2, A0, and A1 as scratch registers. Any other registers must be saved before they are used then restored before returning. Save registers with the MOVEM.L instruction near the beginning of the subroutine.

MOVEM.L D5-D7/A5,-(SP) ;save d5, d6, d7, and A5 on stack

Restore saved registers near the end of the subroutine.

MOVEM.L (SP)+,D5-D7/A5 ;restore saved registers from stack

Jump Table

Many ROM-located routines are available to native code routines. A table of subroutine entry points is located in ROM. A pointer to this table at absolute address 200 is initialized at power up.
This pointer will always be located in the same place in low memory. File exec.inc contains a constant named JUMP_TABLE which contains the address of the table pointer.

Set aside an address register and always keep the jump table pointer in it. This will facilitate quick and easy access to ROM-based routines.

For instance, near the beginning of the routine place the instruction:

MOVE.L JUMP_TABLE,A5

Make certain A5 has been saved before using it to hold the jump table address

Call a routine such as getBCD with a jump-table relative call:

MOVE.L EX_getBCD(A5),A0
JSR (A0)

At offset JumpTableSize in the table is the number of entries in the table. This value will increase as routines are added to the table in later releases.

Services

Service routines are available to ease retrieving arguments passed to the native code routine and to store results back in calculator memory.


EX_getBCD

This routine retrieves an argument passed in on the Exec command line

short EX_getBCD(short n, BCD16 *bcd)

PEA bcd(A6) ;push address to store retrieved BCD value
MOVE.W #1,-(SP) ;request 1st argument
MOVE.L EX_getBCD(A5),A0 ;A5->jump table
JSR (A0) ;call EX_getBCD
ADDQ.L #6,SP ;pop parameters from stack
TST.W D0 ;did it work?
BEQ.S rats ;no --->
: ;yes, bcd(A6) contains value of 1st arg



EX_stoBCD

void EX_stoBCD(unsigned char *name, BCD16 *bcd)

PEA bcd(FP) ;address of BCD value to store
PEA name(PC) ;address of zeros-terminated string
MOVE.L EX_stoBCD(A5),A0
JSR (A0) ;call EX_stoBCD
ADDQ.L #8,SP ;pop parameters from stack



BCD Math Package


Native code routines can access the floating-point arithmetic package. Routine _bcd_math
performs arithmetic in the SMAP II binary coded decimal floating point format. Add a two-byte
code word after the call to _bcd-_math to instruct the emulator on which operation to perform,
where its operands are, and operand size.

operator.gif (5404 octets)

; Last change: JPP 31 Mar 1999 1:07 pm
; TI-92+ ROM entry points
;
; Copyright (C) Texas Instruments, Incorporated, 1997


;
.struct WINDOW
Flags: .space.w 1
CurFont: .space.b 1
CurAttr: .space.b 1
Background: .space.b 1
.space.b 1
TaskId: .space.w 1
CurX: .space.w 1
CurY: .space.w 1
CursorX: .space.w 1
CursorY: .space.w 1
ClientLeft: .space.b 1
ClientTop: .space.b 1
ClientRight: .space.b 1
ClientBottom: .space.b 1
WindowLeft: .space.b 1
WindowTop: .space.b 1
WindowRight: .space.b 1
WindowBottom: .space.b 1
ClipLeft: .space.b 1
ClipTop: .space.b 1
ClipRight: .space.b 1
ClipBottom: .space.b 1
PortLeft: .space.b 1
PortTop: .space.b 1
PortRight: .space.b 1
PortBottom: .space.b 1
DupScr: .space.w 1
Next: .space.l 1
Title: .space.l 1
.ends

.struct WIN_RECT
left: .space.w 1
top: .space.w 1
right: .space.w 1
bottom: .space.w 1
.ends

; BCD arithmetic package

operator.gif (5404 octets)

bcdCmp = 0x0000
bcdAdd = 0x1000
bcdDiv = 0x2000
bcdMul = 0x3000
bcdSub = 0x4000
bcdIntz = 0x5000
bcdMove = 0x6000
bcdNeg = 0x7000
bcdTst = 0x8000

bcdByte = 0x0000
bcdWord = 0x0200
bcdLong = 0x0400
bcdSingle = 0x0600
bcdDouble = 0x0800
bcdUnsigned = 0x0A00

; Source operand
bcdFP0 = 0x0000
bcdFP1 = 0x0010
bcdFP2 = 0x0020
bcdFP3 = 0x0030
bcdFP4 = 0x0040
bcdFP5 = 0x0050
bcdFP6 = 0x0060
bcdFP7 = 0x0070
bcdD0 = 0x0080
bcdD1 = 0x0090
bcdD2 = 0x00A0
bcdD3 = 0x00B0
bcdD4 = 0x00C0
bcdD5 = 0x00D0
bcdD6 = 0x00E0
bcdD7 = 0x00F0
bcdLongImm = 0x0100
bcdShortImm = 0x0110
bcdFrameSrc = 0x0120
bcdAbsSrc = 0x0130
bcdZeroImm = 0x0140

; Destination operand
bcdR0 = 0x0000
bcdR1 = 0x0001
bcdR2 = 0x0002
bcdR3 = 0x0003
bcdR4 = 0x0004
bcdR5 = 0x0005
bcdR6 = 0x0006
bcdR7 = 0x0007
bcdFrameDest = 0x0008
bcdAbsDest = 0x0009
bcdRetReg = 0x000A

JUMP_TABLE = 200

JUMP_TABLE_SIZE = 972

; Jump table offsets

FirstWindow = 0
WinActivate = 4
WinAttr = 8
WinBackupToScr = 12
WinBackground = 16
WinBegin = 20
WinBitmapGet = 24
WinBitmapPut = 28
WinBitmapSize = 32
WinCharXY = 36
WinChar = 40
WinClose = 44

WinClr = 48
WinDeactivate = 52
WinDupStat = 56
WinEllipse = 60
WinFill = 64
WinFillLines2 = 68
WinFillTriangle = 72
WinFont = 76
WinGetCursor = 80
WinHide = 84
WinHome = 88
WinLine = 92
WinLineNC = 96
WinLineTo = 100
WinLineRel = 104
WinMoveCursor = 108
WinMoveTo = 112
WinMoveRel = 116
WinOpen = 120
WinPixGet = 124
WinPixSet = 128
WinRect = 132
WinReOpen = 136
WinScrollH = 140
WinScrollV = 144
WinStr = 148
WinStrXY = 152
DrawWinBorder = 156
ScrRectDivide = 160
RectWinToWin = 164
RectWinToScr = 168
UpdateWindows = 172
MakeWinRect = 176
ScrToWin = 180
ScrToHome = 184
ScrRect = 188
Dialog = 192
NoCallBack = 196
DialogDo = 200
DialogAdd = 204
DialogNew = 208
DrawStaticButton = 212
MenuBegin = 216
MenuCheck = 220
MenuEnd = 224
MenuKey = 228
MenuOn = 232
MenuPopup = 236
MenuSubStat = 240
MenuTopStat = 244
MenuTopSelect = 248
MenuTopRedef = 252
MenuGetTopRedef = 256
MenuAddText = 260
MenuAddIcon = 264
MenuNew = 268
PopupAddText = 272
PopupNew = 276
PopupClear = 280
PopupDo = 284
PopupText = 288
MenuUpdate = 292
Parse2DExpr = 296
Parse2DMultiExpr = 300
Print2DExpr = 304
Parms2D = 308
display_statements = 312
Parse1DExpr = 316
pushkey = 320
ngetchx = 324
kbhit = 328
sprintf = 332
getcalc = 336
sendcalc = 340
LIO_Send = 344
LIO_Get = 348
LIO_Receive = 352
LIO_GetMultiple = 356
LIO_SendData = 360
LIO_RecvData = 364
SymAdd = 368
SymAddMain = 372
SymDel = 376
HSymDel = 380
SymFind = 384
SymFindMain = 388
SymFindHome = 392
SymMove = 396
FolderAdd = 400
FolderCur = 404
FolderDel = 408
FolderFind = 412
FolderGetCur = 416
FolderOp = 420
FolderRename = 424
FolderCount = 428
SymFindFirst = 432
SymFindNext = 436
SymFindPrev = 440
SymFindFoldername = 444
AddSymToFolder = 448
FindSymInFolder = 452
FolderCurTemp = 456
FolderAddTemp = 460
FolderDelTemp = 464
FolderDelAllTemp = 468
TempFolderName = 472
IsMainFolderStr = 476
ParseSymName = 480
DerefSym = 484
HSYMtoName = 488
StrToTokN = 492
TokToStrN = 496
CheckGraphRef = 500
ClearUserDef = 504
CheckLinkLockFlag = 508
TokenizeSymName = 512
SymCmp = 516
SymCpy = 520
SymCpy0 = 524
ValidateSymName = 528
VarRecall = 532
VarStore = 536
VarStoreLink = 540
QSysProtected = 544
CheckSysFunc = 548
GetSysGraphRef = 552
CheckReservedName = 556
SymSysVar = 560
ValidateStore = 564
ResetSymFlags = 568
HeapAvail = 572
HeapAlloc = 576
HeapAllocESTACK = 580
HeapAllocHigh = 584
HeapAllocThrow = 588
HeapAllocHighThrow = 592
HeapCompress = 596
HeapDeref = 600
HeapFree = 604
HeapFreeIndir = 608
HLock = 612
HeapLock = 616
HeapGetLock = 620
HeapMax = 624
HeapRealloc = 628
HeapSize = 632
HeapUnlock = 636
HeapMoveHigh = 640
HeapEnd = 644
HeapAllocPtr = 648
HeapFreePtr = 652
NeedStack = 656
TE_close = 660
TE_checkSlack = 664
TE_empty = 668
TE_focus = 672
TE_handleEvent = 676
TE_indicateReadOnly = 680
TE_isBlank = 684
TE_open = 688
TE_openFixed = 692
TE_pasteText = 696
TE_reopen = 700
TE_reopenPlain = 704
TE_select = 708
TE_shrinkWrap = 712
TE_unfocus = 716
TE_updateCommand = 720
_bcd_math = 724
bcdadd = 728
bcdsub = 732
bcdmul = 736
bcddiv = 740
bcdneg = 744
bcdcmp = 748
bcdlong = 752
bcdbcd = 756
EX_getArg = 760
EX_getBCD = 764
EX_stoBCD = 768
CB_replaceTEXT = 772
CB_fetchTEXT = 776
CU_restore = 780
CU_start = 784
CU_stop = 788
EV_captureEvents = 792
EV_clearPasteString = 796
EV_getc = 800
EV_getSplitRect = 804
EV_notifySwitchGraph = 808
EV_paintOneWindow = 812
EV_paintWindows = 816
EV_restorePainting = 820
EV_sendEvent = 824
EV_sendEventSide = 828
EV_sendString = 832
EV_setCmdCheck = 836
EV_setCmdState = 840
EV_setFKeyState = 844
EV_startApp = 848
EV_startSide = 852
EV_startTask = 856
EV_suspendPainting = 860
EV_switch = 864
MO_currentOptions = 868
MO_defaults = 872
MO_digestOptions = 876
MO_isMultigraphTask = 880
MO_modeDialog = 884
MO_notifyModeChange = 888
MO_sendQuit = 892
ST_angle = 896
ST_batt = 900
ST_busy = 904
ST_eraseHelp = 908
ST_folder = 912
ST_graph = 916
ST_helpMsg = 920
ST_modKey = 924
ST_precision = 928
ST_readOnly = 932
ST_stack = 936
ST_refDsp = 940
OSCheckBreak = 944
OSClearBreak = 948
OSEnableBreak = 952
OSDisableBreak = 956
OSRegisterTimer = 960
OSFreeTimer = 964
OSTimerCurVal = 968
OSTimerExpired = 972
OSTimerRestart = 976
acos = 980
asin = 984
atan = 988
atan2 = 992
cos = 996
sin = 1000
tan = 1004
cosh = 1008
sinh = 1012
tanh = 1016
exp = 1020
log = 1024
log10 = 1028
modf = 1032
pow = 1036
sqrt = 1040
ceil = 1044
fabs = 1048
floor = 1052
fmod = 1056
top_estack = 1060
next_expression_index = 1064
gr_active = 1068
gr_other = 1072
ABT_dialog = 1076
HomeExecute = 1080
HomePushEStack = 1084
SP_Define = 1088
store_data_var = 1092
recall_data_var = 1096
CharNumber = 1100
spike_optionD = 1104
spike_geo_titles = 1108
spike_in_editor = 1112
dv_create_graph_titles = 1116
spike_titles_in_editor = 1120
dv_findColumn = 1124
spike_chk_gr_dirty = 1128
GetStatValue = 1132
partial_len = 1136
paint_all_except = 1140
EQU_select = 1144
EQU_setStyle = 1148
EQU_getNameInfo = 1152
checkCurrent = 1156
BN_power17Mod = 1160
BN_powerMod = 1164
BN_prodMod = 1168
CAT_dialog = 1172
caddcert = 1176
cdecrypt = 1180
ceof = 1184
cfindcertfield = 1188
cfindfield = 1192
cgetc = 1196
cgetcert = 1200
cgetflen = 1204
cgetfnl = 1208
cgetnl = 1212
cgetns = 1216
cgetvernum = 1220
copen = 1224
copensub = 1228
cputhdr = 1232
cputnl = 1236
cputns = 1240
cread = 1244
ctell = 1248
cwrite = 1252
cacos = 1256
casin = 1260
catan = 1264
cacosh = 1268
casinh = 1272
catanh = 1276
ccos = 1280
csin = 1284
ctan = 1288
ccosh = 1292
csinh = 1296
ctanh = 1300
csqrt = 1304
cln = 1308
clog10 = 1312
cexp = 1316
CustomBegin = 1320
CustomMenuItem = 1324
CustomEnd = 1328
ReallocExprStruct = 1332
SearchExprStruct = 1336
handleRclKey = 1340
CustomFree = 1344
ERD_dialog = 1348
ERD_process = 1352
ER_throwVar = 1356
ER_catch = 1360

ER_success = 1364
EV_centralDispatcher = 1368
EV_defaultHandler = 1372
EV_eventLoop = 1376
EV_registerMenu = 1380
EX_patch = 1384
EM_abandon = 1388
EM_blockErase = 1392
EM_blockVerifyErase = 1396
EM_delete = 1400
EM_findEmptySlot = 1404
EM_GC = 1408
EM_moveSymFromExtMem = 1412
EM_moveSymToExtMem = 1416
EM_open = 1420
EM_put = 1424
EM_survey = 1428
EM_twinSymFromExtMem = 1432
EM_write = 1436
EM_writeToExtMem = 1440
FL_addCert = 1444
FL_download = 1448
FL_getHardwareParmBlock = 1452
FL_getCert = 1456
FL_getVerNum = 1460
EQU_deStatus = 1464
cmpstri = 1468
fix_loop_displacements = 1472
FL_write = 1476
fpisanint = 1480
fpisodd = 1484
round12 = 1488
round14 = 1492
GD_Circle = 1496
GD_Line = 1500
GD_HVLine = 1504
GD_Pen = 1508
GD_Eraser = 1512
GD_Text = 1516
GD_Select = 1520
GD_Contour = 1524
GKeyIn = 1528
GKeyDown = 1532
GKeyFlush = 1536
HelpKeys = 1540
QModeKey = 1544
QSysKey = 1548
WordInList = 1552
BitmapGet = 1556
BitmapInit = 1560
BitmapPut = 1564
BitmapSize = 1568
ScrRectFill = 1572
ScrRectOverlap = 1576
ScrRectScroll = 1580
ScrRectShift = 1584
QScrRectOverlap = 1588
FontGetSys = 1592
FontSetSys = 1596
FontCharWidth = 1600
DrawClipChar = 1604
DrawClipEllipse = 1608
DrawClipLine = 1612
DrawClipPix = 1616
DrawClipRect = 1620
DrawMultiLines = 1624
DrawStrWidth = 1628
FillTriangle = 1632
FillLines2 = 1636
SetCurAttr = 1640
SetCurClip = 1644
LineTo = 1648
MoveTo = 1652
ScreenClear = 1656
GetPix = 1660
SaveScrState = 1664
RestoreScrState = 1668
PortSet = 1672
PortRestore = 1676
DrawChar = 1680
DrawFkey = 1684
DrawIcon = 1688
DrawLine = 1692
DrawPix = 1696
DrawStr = 1700
GM_Value = 1704
GM_Intersect = 1708
GM_Integrate = 1712
GM_Inflection = 1716
GM_TanLine = 1720
GM_Math1 = 1724
GM_Derivative = 1728
GM_DistArc = 1732
GM_Shade = 1736
YCvtFtoWin = 1740
DlgMessage = 1744
SetGraphMode = 1748
Regraph = 1752
GrAxes = 1756
gr_xres_pixel = 1760
CptFuncX = 1764
XCvtPtoF = 1768
YCvtPtoF = 1772
YCvtFtoP = 1776
XCvtFtoP = 1780
GrLineFlt = 1784
FuncLineFlt = 1788
GrClipLine = 1792
CptDeltax = 1796
CptDeltay = 1800
CkValidDelta = 1804
GR_Pan = 1808
FindFunc = 1812
FindGrFunc = 1816
grFuncName = 1820
gr_initCondName = 1824
CptIndep = 1828
gr_CptIndepInc = 1832
gr_del_locals = 1836
gr_DelFolder = 1840
gr_openFolder = 1844
setup_more_graph_fun = 1848
unlock_more_graph_fun = 1852
execute_graph_func = 1856
cpt_gr_fun = 1860
cpt_gr_param = 1864
cpt_gr_polar = 1868
gr_execute_seq = 1872
CountGrFunc = 1876
FirstSeqPlot = 1880
cleanup_seq_mem = 1884
time_loop = 1888
InitTimeSeq = 1892
seqWebInit = 1896
run_one_seq = 1900
gr_seq_value = 1904
StepCk = 1908
seqStepCk = 1912
rngLen = 1916
gdb_len = 1920
gdb_store = 1924
gdb_recall = 1928
gr_DispLabels = 1932
GraphOrTableCmd = 1936
ck_valid_float = 1940
CreateEmptyList = 1944
QSkipGraphErr = 1948
gr_find_de_result = 1952
InitDEAxesRng = 1956
InitDEMem = 1960
de_loop = 1964
cleanup_de_mem = 1968
gr_de_value = 1972
gr_find_func_index = 1976
CptLastIndepDE = 1980
de_initRes = 1984
gr_del_vars_in_folder = 1988
gr_de_axes_lbl = 1992
gr_execute_de = 1996
gr_delete_fldpic = 2000
gr_remove_fldpic = 2004
gr_add_fldpic = 2008
gr_stopic = 2012
gr_find_el = 2016
deStepCk = 2020
gr_ck_solvergraph = 2024
GR3_addContours = 2028
GraphActivate = 2032
GR3_freeDB = 2036
GR3_handleEvent = 2040
GR3_paint3d = 2044
GR3_xyToWindow = 2048
GS_PlotTrace = 2052
GS_PlotAll = 2056
PlotDel = 2060
PlotPut = 2064
PlotGet = 2068
PlotInit = 2072
PlotDup = 2076
PlotSize = 2080
PlotLookup = 2084
QActivePlots = 2088
QPlotActive = 2092
GT_BackupToScr = 2096
GT_CalcDepVals = 2100
GT_CenterGraphCursor = 2104
GT_CursorKey = 2108
GT_DspFreeTraceCoords = 2112
GT_DspTraceCoords = 2116
GT_DspMsg = 2120
GT_Error = 2124
GT_Format = 2128
GT_FreeTrace = 2132
GT_IncXY = 2136
GT_KeyIn = 2140
GT_QFloatCursorsInRange = 2144
GT_Regraph = 2148
GT_Regraph_if_neccy = 2152
GT_Open = 2156
GT_SaveAs = 2160
GT_SelFunc = 2164
GT_SetGraphRange = 2168
GT_SetCursorXY = 2172
GT_ShowMarkers = 2176
GT_Trace = 2180
GT_ValidGraphRanges = 2184
GT_WinBound = 2188
GT_WinCursor = 2192
GYcoord = 2196
GXcoord = 2200
round12_err = 2204
GT_Set_Graph_Format = 2208
GT_PrintCursor = 2212
GT_DE_Init_Conds = 2216
GZ_Box = 2220
GZ_Center = 2224
GZ_Decimal = 2228
GZ_Fit = 2232
GZ_InOut = 2236
GZ_Integer = 2240
GZ_Previous = 2244
GZ_Recall = 2248
GZ_SetFactors = 2252
GZ_Square = 2256
GZ_Standard = 2260
GZ_Stat = 2264
GZ_Store = 2268
GZ_Trig = 2272
HeapGetHandle = 2276
HeapPtrToHandle = 2280
FreeHandles = 2284
HS_chopFIFO = 2288
HS_countFIFO = 2292
HS_deleteFIFONode = 2296
HS_freeAll = 2300
HS_freeFIFONode = 2304
HS_getAns = 2308
HS_getEntry = 2312
HS_getFIFONode = 2316
HS_popEStack = 2320
HS_newFIFONode = 2324
HS_pushFIFONode = 2328
HToESI = 2332
OSInitKeyInitDelay = 2336
OSInitBetweenKeyDelay = 2340
OSCheckSilentLink = 2344
OSLinkCmd = 2348
OSLinkReset = 2352
OSLinkOpen = 2356
OSLinkClose = 2360
OSReadLinkBlock = 2364
OSWriteLinkBlock = 2368
OSLinkTxQueueInquire = 2372
OSLinkTxQueueActive = 2376
LIO_SendProduct = 2380
MD5Init = 2384
MD5Update = 2388
MD5Final = 2392
MD5Done = 2396
convert_to_TI_92 = 2400
gen_version = 2404
is_executable = 2408
NG_RPNToText = 2412
NG_approxESI = 2416
NG_execute = 2420
NG_graphESI = 2424
NG_rationalESI = 2428
NG_tokenize = 2432
NG_setup_graph_fun = 2436
NG_cleanup_graph_fun = 2440
push_END_TAG = 2444
push_LIST_TAG = 2448
tokenize_if_TI_92_or_text = 2452
setjmp = 2456
longjmp = 2460
VarGraphRefBitsClear = 2464
VarInit = 2468
memcpy = 2472
memmove = 2476
strcpy = 2480
strncpy = 2484
strcat = 2488
strncat = 2492
memcmp = 2496
strcmp = 2500
strncmp = 2504
memchr = 2508
strchr = 2512
strcspn = 2516
strpbrk = 2520
strrchr = 2524
strspn = 2528
strstr = 2532
strtok = 2536
_memset = 2540
memset = 2544
strerror = 2548
strlen = 2552
SymAddTwin = 2556
SymDelTwin = 2560
LoadSymFromFindHandle = 2564
MakeHsym = 2568
SymFindPtr = 2572
OSVRegisterTimer = 2576
OSVFreeTimer = 2580
sincos = 2584
asinh = 2588
acosh = 2592
atanh = 2596
itrig = 2600
trig = 2604
VarOpen = 2608
VarSaveAs = 2612
VarNew = 2616
VarCreateFolderPopup = 2620
VarSaveTitle = 2624
WinWidth = 2628
WinHeight = 2632
XR_stringPtr = 2636
OSReset = 2640
SumStoChkMem = 2644
OSContrastUp = 2648
OSContrastDn = 2652
OSKeyScan = 2656
OSGetStatKeys = 2660

off = 2664
idle = 2668
OSSetSR = 2672
AB_prodid = 2676
AB_prodname = 2680
AB_serno = 2684
cgetcertrevno = 2688
cgetsn = 2692
de_rng_no_graph = 2696
EV_hook = 2700
_ds16u16 = 2704
_ms16u16 = 2708
_du16u16 = 2712
_mu16u16 = 2716
_ds32s32 = 2720
_ms32s32 = 2724
_du32u32 = 2728
_mu32u32 = 2732
assign_between = 2736
did_push_var_val = 2740
does_push_fetch = 2744
delete_list_element = 2748
push_ans_entry = 2752
index_after_match_endtag = 2756
push_indir_name = 2760
push_user_func = 2764
store_func_def = 2768
store_to_subscripted_element = 2772
index_below_display_expression_aux = 2776
get_key_ptr = 2780
get_list_indices = 2784
get_matrix_indices = 2788
init_list_indices = 2792
init_matrix_indices = 2796
push_float_qr_fact = 2800
push_lu_fact = 2804
push_symbolic_qr_fact = 2808
are_expressions_identical = 2812
compare_expressions = 2816
find_error_message = 2820
check_estack_size = 2824
delete_between = 2828
deleted_between = 2832
delete_expression = 2836
deleted_expression = 2840
estack_to_short = 2844
estack_to_ushort = 2848
factor_base_index = 2852
factor_exponent_index = 2856
GetValue = 2860
im_index = 2864
index_numeric_term = 2868
index_of_lead_base_of_lead_term = 2872
index_main_var = 2876
is_advanced_tag = 2880
is_antisymmetric = 2884
is_complex_number = 2888
is_complex0 = 2892
is_free_of_tag = 2896
is_independent_of = 2900
is_independent_of_de_seq_vars = 2904
is_independent_of_tail = 2908
is_independent_of_elements = 2912
is_monomial = 2916
is_monomial_in_kernel = 2920
is_narrowly_independent_of = 2924
is_symmetric = 2928
is_tail_independent_of = 2932
lead_base_index = 2936
lead_exponent_index = 2940
lead_factor_index = 2944
lead_term_index = 2948
main_gen_var_index = 2952
map_unary_over_comparison = 2956
min_quantum = 2960
move_between_to_top = 2964
moved_between_to_top = 2968
numeric_factor_index = 2972
push_between = 2976
push_expr_quantum = 2980
push_expr2_quantum = 2984
push_next_arb_int = 2988
push_next_arb_real = 2992
push_next_internal_var = 2996
push_quantum = 3000
push_quantum_pair = 3004
reductum_index = 3008
remaining_factors_index = 3012
re_index = 3016
reset_estack_size = 3020
reset_control_flags = 3024
can_be_approxed = 3028
compare_complex_magnitudes = 3032
compare_Floats = 3036
did_push_cnvrt_Float_to_integer = 3040
estack_number_to_Float = 3044
float_class = 3048
frexp10 = 3052
gcd_exact_whole_Floats = 3056
init_float = 3060
is_Float_exact_whole_number = 3064
is_float_infinity = 3068
is_float_negative_zero = 3072
is_float_positive_zero = 3076
is_float_signed_infinity = 3080
is_float_transfinite = 3084
is_float_unsigned_inf_or_nan = 3088
is_float_unsigned_zero = 3092
is_nan = 3096
likely_approx_to_complex_number = 3100
likely_approx_to_number = 3104
norm1_complex_Float = 3108
push_Float = 3112
push_Float_to_nonneg_int = 3116
push_Float_to_rat = 3120
push_cnvrt_integer_if_whole_nmb = 3124
push_overflow_to_infinity = 3128
push_pow = 3132
push_round_Float = 3136
should_and_did_push_approx_arg2 = 3140
signum_Float = 3144
did_push_to_polar = 3148
push_degrees = 3152
push_format = 3156
push_getkey = 3160
push_getfold = 3164
push_getmode = 3168
push_gettype = 3172
push_instring = 3176
push_mrow_aux = 3180
push_part = 3184
push_pttest = 3188
push_pxltest = 3192
push_rand = 3196
push_randpoly = 3200
push_setfold = 3204
push_setgraph = 3208
push_setmode = 3212
push_settable = 3216
push_str_to_expr = 3220
push_string = 3224
push_switch = 3228
push_to_cylin = 3232
push_to_sphere = 3236
cmd_andpic = 3240
cmd_blddata = 3244
cmd_circle = 3248
cmd_clrdraw = 3252
cmd_clrerr = 3256
cmd_clrgraph = 3260
cmd_clrhome = 3264
cmd_clrio = 3268
cmd_clrtable = 3272
cmd_copyvar = 3276
cmd_cubicreg = 3280
cmd_custmoff = 3284
cmd_custmon = 3288
cmd_custom = 3292
cmd_cycle = 3296
cmd_cyclepic = 3300
cmd_delfold = 3304
cmd_delvar = 3308
cmd_dialog = 3312
cmd_disp = 3316
cmd_dispg = 3320
cmd_disphome = 3324
cmd_disptbl = 3328
cmd_drawfunc = 3332
cmd_drawinv = 3336
cmd_drawparm = 3340
cmd_drawpol = 3344
cmd_else = 3348
cmd_endfor = 3352
cmd_endloop = 3356
cmd_endtry = 3360
cmd_endwhile = 3364
cmd_exit = 3368
cmd_expreg = 3372
cmd_fill = 3376
cmd_fnoff = 3380
cmd_fnon = 3384
cmd_for = 3388
cmd_get = 3392
cmd_getcalc = 3396
cmd_goto = 3400
cmd_graph = 3404
cmd_if = 3408
cmd_ifthen = 3412
cmd_input = 3416
cmd_inputstr = 3420
cmd_line = 3424
cmd_linehorz = 3428
cmd_linetan = 3432
cmd_linevert = 3436
cmd_linreg = 3440
cmd_lnreg = 3444
cmd_local = 3448
cmd_lock = 3452
cmd_logistic = 3456
cmd_medmed = 3460
cmd_movevar = 3464
cmd_newdata = 3468
cmd_newfold = 3472
cmd_newpic = 3476
cmd_newplot = 3480
cmd_newprob = 3484
cmd_onevar = 3488
cmd_output = 3492
cmd_passerr = 3496
cmd_pause = 3500
cmd_plotsoff = 3504
cmd_plotson = 3508
cmd_popup = 3512
cmd_powerreg = 3516
cmd_printobj = 3520
cmd_prompt = 3524
cmd_ptchg = 3528
cmd_ptoff = 3532
cmd_pton = 3536
cmd_pttext = 3540
cmd_pxlchg = 3544
cmd_pxlcircle = 3548
cmd_pxlhorz = 3552
cmd_pxlline = 3556
cmd_pxloff = 3560
cmd_pxlon = 3564
cmd_pxltext = 3568
cmd_pxlvert = 3572
cmd_quadreg = 3576
cmd_quartreg = 3580
cmd_randseed = 3584
cmd_rclgdb = 3588
cmd_rclpic = 3592
cmd_rename = 3596
cmd_request = 3600
cmd_return = 3604
cmd_rplcpic = 3608
cmd_send = 3612
cmd_sendcalc = 3616
cmd_sendchat = 3620
cmd_shade = 3624
cmd_showstat = 3628
cmd_sinreg = 3632
cmd_slpline = 3636
cmd_sorta = 3640
cmd_sortd = 3644
cmd_stogdb = 3648
cmd_stopic = 3652
cmd_style = 3656
cmd_table = 3660
cmd_text = 3664
cmd_toolbar = 3668
cmd_trace = 3672
cmd_try = 3676
cmd_twovar = 3680
cmd_unlock = 3684
cmd_while = 3688
cmd_xorpic = 3692
cmd_zoombox = 3696
cmd_zoomdata = 3700
cmd_zoomdec = 3704
cmd_zoomfit = 3708
cmd_zoomin = 3712
cmd_zoomint = 3716
cmd_zoomout = 3720
cmd_zoomprev = 3724
cmd_zoomrcl = 3728
cmd_zoomsqr = 3732
cmd_zoomstd = 3736
cmd_zoomsto = 3740
cmd_zoomtrig = 3744
OSenqueue = 3748
OSdequeue = 3752
OSqinquire = 3756
OSqhead = 3760
OSqclear = 3764
did_push_divide_units = 3768
has_unit_base = 3772
init_unit_system = 3776
is_units_term = 3780
push_auto_units_conversion = 3784
push_unit_system_list = 3788
setup_unit_system = 3792
all_tail = 3796
any_tail = 3800
is_matrix = 3804
is_square_matrix = 3808
is_valid_smap_aggregate = 3812
last_element_index = 3816
map_tail = 3820
map_tail_Int = 3824
push_list_plus = 3828
push_list_times = 3832
push_reversed_tail = 3836
push_sq_matrix_to_whole_number = 3840
push_transpose_aux = 3844
push_zero_partial_column = 3848
remaining_element_count = 3852
push_offset_array = 3856
push_matrix_product = 3860

is_pathname = 3864
next_token = 3868
nonblank = 3872
push_parse_prgm_or_func_text = 3876
push_parse_text = 3880
push_var = 3884