01 December 1990

The content below is simply a reformatting of text as published decades ago by 9640 NEWS. The opinions and views expressed are not my (Jedimatt42) own. The content is published here to preserve and make accessible the technical data contained within.

Taken from the disk distributions archived at http://ftp.whtech.com/Geneve/9640 News disks v1-3/pc99 disks/


Enclosed on this disk is FULLC-ZIP. This is an IBM Archive that must be either transferred via MODEM to an IBM and dearced with PKUNZIP or possibly transferred to an IBM Disk with PC-Transfer. Myself, I had problems with PC-Transfer getting the file back and forth, but it was probably just me. I now have an IBM (386SX with VGA) to actually support software development and other necessary book-keeping where some more highly professional programs do exist that can set my software higher than others.

While also owning the IBM 386, I am considering setting up a BBS that would be a center clearing house for all Geneve Software. This being only a Geneve Board with a 40 MB hard drive for storage capacity. To support this though to maintain the phone line, and to set one up, the board would not be free. I feel a $12 per year fee would be adequate and would allow others to check on stats, questions, etc and be very informative. As informative as 9640 News has been. If you are interested in supporting this adventure of mine, I need your support now. If you send $12 now and I get enough response to pay phone charges for a year, I will open my system up to those that purchase the usage. There will be no pirate software on this system, only programs and info that sometimes can not be used in 9640 News due to the fact I like originality. If you send $12 and I don't get enough response, I will return your uncashed check at the end of January. The decision is yours.....

P.S. The TICDOC-ARK file is a TI Archived file. Use Barry Boone's archiver to dearc.

Well, as I close off this end of the year, I would like to inform everyone that I have been able to obtains some software from other vendors at a reduced price that I can pass on to my subscribers. I have the following packages at the indicated REDUCED prices. There is NO shipping and handling charge to ANYWHERE in the world.

4A/9640 Fortran (Version 4 for eithe 4A/GPL or MDOS) $50.00
TI-Base (V3.02) $21.00
TI-Artist+ (V1.02) $21.00
TI-Sort $13.00

And of course, I have the following software myself....

Global War (ABASIC Game) $15.00
Tetris (MDOS Game) $15.00
Barricade (ABASIC Game) $15.00
WINDOWS 9640 (MDOS Utility) $15.00
Mouse Driver Kit (MDOS Development/Utility) $12.95

And last but not least, I hope everyone has a Merry Christmas and a Happy new Year from all of here in the Miller House.

Merry Christmas


Just as I was finishing this disk up, another new disk of material arrived from Martin Zeddies of West Germany giving many new programs and source code to 9640 News. A brief description is as follows:

 COPYW    Diskcopy for CorComp Controller
 COPYWTI  Diskcopy for TI Controller
 FDC-DOC  German instructions for the copy program
 FDC_H    C-Header file for Disk Access
 FDC_O    C-Library for CorComp disk access
 FDC_OTI  C-Library for TI Disk access
 KEY_DOK  German instructions for keyboard XOP
 KEY_PGM  Demonstration program for keyboard XOP
 KEY_SOU  Sourcecode for KEYBOARD XOP
 RT       Track-Copier for CorComp
 RTTI     Track Copier for TI Controller

As tested, I tested the corcomp version without difficulty. For some reason, KEY_PGM created a screen of undefined characters. Source code was provided so perhaps someone can isolate the problem.

Questions From Martin Zeddies.... and My replies

Hello Beery !,

A new problem on my GENEVE appears and I unfortunatly think that it was not the last one.

Surely You know that the GENEVE automaticlly starts a file which named AUTOEXEC after the system had load the SYSTEM/SYS programm file.In the handbook of the GENEVE stand that I can made a software-reset (warmboot) on my system,when I press the CNTL-ALT-DEL key combination.

But I found out that this Reset of the computer only works,when you have your 'working-diskette' at A:.When you change to another drive -for example B: - to work on this disk and press the CNTL-ALT-DEL combination the M-DOS operating system restarts the computer,but it looks for the AUTOEXEC file in actually activated diskdrive.

I think that the real function of a CNTL-ALT-DEL keypress is trying to load the AUTOEXEC file from the A:-disk and waiting with an A:-prompt for the next keyboard input,when it can not found an AUTOEXEC file on the A:-disk.

Do you know a way to get this function out of our GENEVE computer ?

Thanks for your support of the MYARC computer family !

With greetings from sunny Germany

Martin Zeddies


Martin, try at the B: prompt typing &AUTOEXEC with a filename called AUTOEXEC in drive B. That will force a warm boot. Make sure you include the ampersand in front of the filename, but not as the true actual filename on the disk. MDOS interprets any DV80 batch file that when called with an & in front of it as a warm boot of the entire operating system without having to load SYSTEM/SYS. Hope this helps.

Also, to answer an earlier question you once had, I have not been able to locate a chip that could be programmed to replace the GATE ARRAY on the Geneve. If anyone else knows where to locate/buy one (already burned, or one that could be burned), please write Martin with the details. His address follows in the next question. Also, the DEBUG files you were missing should be on there way soon.

Since a longer time I order programs in the United states for other german MYARC GENEVE computer freaks. But my last order to McCann software comes back to my home adress with an label on its envelope which says: "Return to sender / No forward order on file / unable to forward" !

So I think that I had used a wrong adress on the letter.I control the adress on the envelope but I can not found an error,so the only way is that Mike McCann had changed his adress.I use the following one:

                     McCann software
                     P.O Box 34 160
                     Omaha , NE 68 134

                     United states of America

Do you know another adress of McCann software ?

REPLY, yes Martin, his new address is as follows:

McCann Software
4411 N. 93rd Street
Omaha, NE 68134

Hope this helps and Merry Christmas



       FDC_O: Floppy-Disk-Software-Treiber

       Autor:Ing. Florian Laschitz, Erlaaerstrasse 133/7/3,A-1232 Wien 

       FDC_O implementiert in das c99 v4.1 System (MDOS!) Routinen, um
       den  Floppy-Controller direkt anzusteuern.  Dies erm|glicht das
       Schreiben von Universalkopierprogrammen wie COPY-C (z.B.:  CPY-
       Demoprogramm) oder  das Erstellen  eines eigenen  individuellen

       FDC_O  unterst}tztE nurF die Laufwerke 1 und 2.  FernerE mu~F FDC_O
       beim Linken als erstes Programm (z.B.: LDR A:FDC_O, B:MYPROG_O,
       C99LIB B:MYPROG) geladen werden.
       Vor dem Aufruf einer  Funktion mu~ ein Datenblock ({hnlich PAB)
       gesetzt werden.  FDC_H stellt alle  notwendigen  Vereinbarungen
       zur Verf}gungR (int dbl[6];R mu~ global vereinbart werden!).  

       Folgende Routinen stehen zur Verf}gung: 

       rst(dbl).....restore, positioniert Kopf auf Spur 0. Mu~ vor dem
                    Aufruf einer  anderen Funktion  f}r jedes Laufwerk
                    ausgef}hrt werden.  

       rdadd(dbl)...liest alle ID-Felder einer Spur in idbuff u. setzt
                    SECZ und ID-C.
                    Wenn kein ID-Feld  vorhanden und ST=>10, SKST=>02,
                    so ist eine Indexmarke vorhanden (es k|nnen trotz-
                    dem sinnvolle Daten vorhanden sein).
                    Bei ST=>10, SKST=>00 ist die Spur sicher leer.  

       rdsec(dbl)...liest SECZ Sektoren  einer Spur in buff, wobei die
                    Sektordaten in idbuff stehen m}ssen.Wird bei einem
                    ID-Feld kein Datenfeld  gefunden, wird SECZ decre-
                    mentiert und das ID-Feld markiert (CRC=>FFFF).  

       wtsec(dbl)...schreibt SECZ Sektoren von buff auf eine Spur, wo-
                    bei die Sektordaten in idbuff stehen.ID-Felder mit
                    CRC=>FFFF werden ignoriert.  

       rdtr(dbl)....liest eine ganze  Spur in  buff mit  allen L}cken.
                    Aufgrund der fehlenden Taktimpulse werden aber die
                    Addressmarken  nicht richtig  wiedergegeben (z.B.:
                    CE statt FE). Diese Funktion sollte deshalb nur zu
                    Diagnosezwecken verwendet werden (z.B.: RT_C Demo-

       wttr(dbl)....schreibt  Daten von buff  auf eine Spur von Index-
                    puls zu Index-puls.  

       inittr(dbl)..initialisiert eine Spur in buff  mit ID-C  ID-Fel-
                    dern, wobei alle  ID-Felder mit  CRC=>FFFF  keinen
                    Datensektor haben.  


       Der Datenblock mu~ folgendes Aussehen haben: 
             1.byte 2.byte
       dbl[0]=0xTR    DR          TR......phys.Track Nr. (>00 bis >27)
       dbl[1]=0xSD    DE          DR......Drive Nr.      (>01 od. >02)
       dbl[2]=0xID-C  SECZ        SD......Seiten Nr.     (>01 od. >02)
       dbl[3]=0x  buff            DE......Dichte         (>01 od. >02)
       dbl[4]=0xST    SKST        ID-C....Anzahl der ID-Felder
       dbl[5]=0x idbuff           SECZ....Anzahl der Sektoren
                                  buff....Buffer Addresse
                                  SKST....Seek-Status     R
                                  idbuff..Buffer Addresse f}r die

       Derzeit ist FDC_O EnurF f}r den Corcomp- oder  Atronic-Controller
       verwendbar. Wenn aber gen}gend  Anfragen eintreffen, so bin ich
       gerne bereit, dies auch f}r den TI-Controller zu adaptieren.  

       Falls Sie diese Routinen n}tzlich finden, so bitte ich um einen
       kleinen Fairwarebeitrag (z.B.: \S 100.-). Sie erhalten dann auf
       Wunsch detaillierte Unterlagen }ber Controllerchips, Statusbits
       usw.  (Auch }ber den Sourcecode l{~t sich reden).  

       PS:Ich }bernehme selbstverst{ndlichE keinerleiF Verantwortung f}r
       eventuell auftretende Sch{den an Hard-und Software (was ohnehin
       nur besondere Talente fertigbringen).  

                              mfg.   Florian Laschitz


MYARC GENEVE 9640 = Der Homecomputer f}r sinnvolle Freizeit

=                                                 Martin Zeddies       =
=                                                 Hauptstra~e 26       =
=                                                 3180 Wolfsburg 22    =
=                                                 ==== ------------    =

Reislingen,im November 1990


Der Zugriff auf h{ufig ben|tigte Programmteile wird bei der Programmierung des GENEVE in Maschinensprache etwas anders durchgef}hrt als bei der Programmierung des TI 99/4A.

Solche vorprogrammierten Programmteile werden beim GENEVE als externe Operationen zur Verf}gung gestellt,was den Vorteil besitzt,das sie nicht im RAM-Bereich,des CPU Arbeitsspeichers zu liegen brauchen. Dadurch bleiben dem Anwender praktisch nahezu die gesamten 64 K RAM f}r den eigenen Programmcode zur Verf}gung.

Die in diesem Programmsatz vorgestellte externe Operation wurde von den MYARC leuten geschaffen um die Kommunikation zur,am Rechner angeschlossenen Tastertur zu vereinfachen.Sie kann daher am besten mit der KSCAN-Routine des TI 99 verglichen werden,die durch ein Unterprogramm zur Verf}gung stand.Der Zugriff wurde meist durch einen BLWP Sprung durchgef}hrt. Im GENEVE wird die Tasterturabfrage programmtechnisch anderes aufgebaut,liefert aber die vom KSCAN her gewohnten Ergebnisse.

Die folgenden Dateien geh|hren zu dieser Erkl{rung und sollte ebenfalls auf dieser Diskette zu finden sein:

KEY_DOK    (diese Anleitung)             
KEY_SOU    (der dokumentierte Sourcecode)
KEY_PGM    (startf{higes MDOS-Programm)  

Um die Benutzung von externen Operationen }bersichtlicher zu gestalten wurde die gesamten zur Verf}gung stehenden XOP's in verschiedene Bibliotheken aufgeteilt.Die Bilbliothek in der wir die externe Operation f}r den Tasterturzugriff finden ist sehr kurz,da dort nur eine Routine zur Verf}gung steht. Daher kann in diesem Fall auch auf einen OP-Code verzichet werden,der bei den meisten anderen Zugriffen auf die externe Bibliotheken notwendig ist.Der Aufruf einer externe Operation in der Bibliothek 'KEYBOARD' erfolgt prinzipell durch folgende Sourcecode-Programmzeile:

(Label) XOP 5,0  (Kommentar)

Die '5' verzweigt in die notwendige Bibliothek,w{hrend die '0' das Register enth{lt,welches }blicherweise den Opcode der Funktion enth{lt die aus dieser Bibliothek abgerufen werden soll. Die KEYBOARD-Bibliothek bildet hier eine Ausnahme,da im Register 0,was zu diesem Zweck am h{ufigsten benutzt wird,beim Zugriff auf die KEYBOARD-Bibliothek der Tasterturmode stehen muss,in dem die Tastertur abgefragt werden soll.Dabei sind die vom TI99/4A bekannten Tasterturmodi 0 bis 5 zugelassen.Mein Demoprogramm gestattet allerdings auch die ]bergabe aller anderen Werte bis >FF.Dieses wurde f}r Versuchszwecke installiert. Mehr ]bergaben sind beim Aufruf der einizigen Funktion in der KEYBOARD-Bibliothek nicht notwenig.Vor dem Aufruf muss also:

R0 = gew}nschter Tasterturmode

eingestellt werden und dann die externe Operation aufgerufen werden.

Nach deren Durchf}hrung gibt die externe Operation in folgenden Registern,folgende Werte zur}ck :

R0 LB = Tastenwert  (entspricht >8374 beim TI 99/4A)
R1 HB = Tasterturmodus         (entspricht >8375)   
R2 LB = Joystick X-Wert        (entspricht >8376)   
R2 HB = Joystick Y-Wert        (entspricht >8377)   

Wird ein Code von >FF zur}ckgegeben,so befandet sich kein Wert im Puffer der Tasterur,es war also keine Taste gedr}ckt zu dem Zeitpunkt,als die Tastertur abgefragt wurde.

Ich hoffe das diese Einleitung und der beiliegende Sourcecode,die Anwendung der KEYBOARD-Bibliothek verst{ndlich macht,Sollten Fragen oder Probleme auftreten (von dennen ich bei der Maschinenspracheprogrammierung selbst noch so einige habe),so stehe ich gerne mit Rat zur Seite,sofern mir dieses m|glich ist.

Ein Problem der hier ver|ffentlichten Programmversion ist so z.B.,da~ bei einem eingestellten Tasterturmode >03 eine Funktion der F1-Taste mehr gegeben ist und somit auch keine weitere Umstellung des Tasterturmodes erfolgen kann.Leider bin ich bis jetzt noch nicht darauf gekommen,warum dieses Problem besteht. Sollte hierzu jemand einen konstruktiven Gedanken haben,so m|ge er diesen Bitte an mich mitteilen.Vielen Dank !


*                                          *
*      Idee : Martin Zeddies               *
*             Hauptstrasse 26              *
*             D-3180 Wolfsburg 22          *
*             ====== ------------          *
*             West - Germany               *
*                                          *
*          ! NO COPYRIGHTS !               *
*                                          *
*  Fuer Verbesserungen oder Veraenderungen *
*  bitte ich um eine schriftliche Nach-    *
*  richt. Danke                            *
*                                          *
*  Programmstand : 21.Nov 1990             *
*                                          *
SFIRST    B    @HAUPT    *ERSTE ANWEISUNG wird auf Adr. >0400 abgelegt wenn das
*                        Programm geladen wird
* Daten und Buffer
UTIL      DATA 9
ONE       DATA 1
FOUR      DATA 4
MAPPER    EQU  >F110     Die zugeteilten Seiten stehen im MAPPER an den Adresse
*                        F110= Page 0  bis >F117 = Page 7
LIBPAG    EQU  >2000
MDOS      EQU  >0000     BLWP-Returnadresse zum MDOS Betriebssystem
DOSWSP    EQU  >F020
KBD       DATA 5
MMG       DATA 7
VID       DATA 6

* Fehlertext bei zuwenig freiem Speicher
       TEXT 'Zuwenig freier Speicher im RAM !!!!'
       BYTE >0D,>0A,>0
UEBER1 TEXT 'Testprogramm fuer den KEYBOARD-XOP des MDOS' Ueberschrift
UEBER2 TEXT '-------------------------------------------'
R1TXT  TEXT 'Return-Wert ist HB aus R1= >'
R0TXT  TEXT 'Tasterturmode ist LB R0  = >' Textausgabe mit Inhalt von R0 bei KBD
R0INF  TEXT 'F1 = R0-Wert aendern'  Infotext zum Aendern von R0
ENDINF TEXT 'F10 = Programmende'    Infotext zum Programmende
HINWEI TEXT 'F10 und F1 nur bei Tasterturmodus >00 !'  Hinweis zu F1 und F10
R0TXT1 TEXT '+ = Erhoehen   - = Verringern'
VDPK01 DATA >0002,>0008,0052  SET CURSOR,Zeile 8 ,Spalte 44
VDPK02 DATA >0000,>0001       SET VIDEOMODE auf 80 Zeichen
VDPK03 DATA >002A,R0ANZ,2,>0000 WRITE CHAR STRING/R1ANZ ausgeben Cursor wandert
VDPK04 DATA >0002,>000A,0052  SET CURSOR um R1ANZ auszugeben
VDPK05 DATA >002A,R1ANZ,2,>0000 WRITE CHAR String um R1 auszugeben
VDPK06 DATA >0002,>0008,0022    SET CURSOR fuer R0 Fuehrungstext
VDPK07 DATA >002A,R0TXT,0028  WRITE CHAR String R0-Fuehrungstext
VDPK08 DATA >0002,0010,0022   SET CURSOr Fuehrungstext R1
VDPK09 DATA >002A,R1TXT,0028  WRITE CHAR String R1-Fuehrungstext
VDPK0A DATA >0002,>0014,>001E  SET CURSOR fuer R0-Infotext
VDPK0B DATA >0027,R0INF,20    WRITE TTY  R0-Infotext
VDPK0C DATA >0002,>0015,>001F  SET CURSOR Ende-Infotext
VDPK0D DATA >0027,ENDINF,18   WRITE TTY  Ende-Infotext
VDPK0E DATA >0002,25,10     Cursor auf Startposition Hinweisausgabe
VDPK0F DATA >0027,R0TXT1,29   Hinweistext 'Verringern / Erhoehen ausgeben'
VDPK10 DATA >002E,25,0,>20,80  Hinweistext loeschen
VDPK11 DATA >000A,>040F,>0000,>0000 CALL SCREEN auf dunkelblau-weiss
VDPK12 DATA >0002,>0004,18  SET CURSOR fuer die Ueberschrift
VDPK13 DATA >002A,UEBER1,43   WRITE CHAR Ueberschrift 1. Zeile
VDPK14 DATA >0002,>0005,18  SET CURSOR fuer die Ueberschrift
VDPK15 DATA >002A,UEBER2,43   WRITE CHAR Ueberschrift 1. Zeile
HX0000 DATA >0000        Konstantenvereinbarung fuer HEX-Werte
HX0003 DATA >0003
HX0004 DATA >0004
HX0008 DATA >0008
HX0009 DATA >0009
HX3030 DATA >3030
UPGMRT DATA >0000        Hier steht die Ruecksprungadresse eines lfd. UPGMs
UPGM2  DATA >0000        Hier steht :Ruecksprungadresse fuer UPGMs in 2.Ebene
R0HEX  DATA >0000        Dieser Wert wird vom UPGM HOLTAS in R0 uebertragen
R1HEX  DATA >0000        Dieser Wert wurde vom letzten KDB-XOP ermittelt
R0ANZ  DATA >0000        ASC Anzeigewerte vom R0 (HB)
R1ANZ  DATA >0000        ASC Anzeigewerte von R1 (HB)
F1TAS  BYTE >83          Keyboardrueckgabe bei F1
F10TAS BYTE >BC          Keyboardrueckgabe bei F10
TASPL  BYTE >2B          Keyboardwert bei '+'
TASMI  BYTE >2D          Keyboardwert bei '-'
MODE   DATA >0000        Zwischenspeicher des Tasterturmodes waehrend des Aender
PGVPG  DATA >0000        Vom Programm benutzte Videopage
       EVEN              Datenbloecke auf gerade Systemadressen schieben
PGETBL BSS 10            Zwischenbuffer fuer PAGEadressen des CPU-Bereichs

HAUPT  LI   R0,1         *R0 enthaelt den OP-Code fuer die MMG-XOP Funktion
*                         1= Bitte um Speicherzuteilung durchs SYSTEM
       LI   R1,7         *7 Seiten zuteilen lassen
       LI   R2,1         *Die Zuteilung soll erst ab Page #1 (ADR >2000) begin
*                        *da Page #0 durch diesen PGM-Code belegt wird
       CLR  R3           *Slow RAM, SETO 3 would let us use fast ram if it were
*                         available
       XOP  @MMG,0       *System nach Speicher fragen
       ABS  R0           *Ist ein Fehler aufgetreten ?
       JEQ  GATMEM       *NEIN,dann weiter bei GATMEM
       LI   R0,>27       OP-Code fuer VID-XOP Funktion (Stringausgabe bis >0)
       LI   R1,NOMEM     Hier beginnt der Textbuffer
       LI   R2,NOMEML   Solang ist die KOMPLETTE Fehlermeldung
       XOP  @VID,0       Ausgaberoutine fuer Text (TTY) aufrufen
       BLWP @MDOS        Warmstart des Systems durchfuehren
*  Speicherzuteilung war erfolgreich  jetzt in den MAPPER uebertragen
GATMEM LI   R0,4         OP-Code fuer MMG-XOP (Adressliste holen)
       LI   R1,PGETBL    Adressen in PageGETBLock ablegen
       LI   R2,8         Dieser Block ist 8 Bytes lang
*                        Mehr ist nicht notwendig,da die Zuteilung nur 8 PAGES
*                        mit je 8 K (= 64 K-CPU Adressbereich ) bekommt
       XOP  @MMG,0       MEMORY MANAGER zur Funktionsdurchfuehrung bewegen
*                        GATMEM hat den angeforderten Speicher in PGETBL ueber
*                        tragen.Als naechstes muessen diese Daten in den MAPPER
       MOVB @PGETBL+1,@>F111        PAGE #0 nicht uebertragen,da diese ja auch
       MOV  @PGETBL+2,@>F112        nicht zugeteilt wurde.Die Hier eingeschriebn
       MOV  @PGETBL+4,@>F114        PAGEADRESSEN machen den Speicher im entsprec
       MOV  @PGETBL+6,@>F116        henden Adressbereich fuer die CPU verfuegbar
* Speicherzuteilung und Verfuegbarkeit abgeschlossen
* Das Programm kann beginnen
       LWPI DOSWSP       Hier liegt mein eigenes Workspace

* VideoPAGES (Speicher) einstellen

       BL   @SAVMDS       MDOS-Betriebsparameter fuer Ruecksprung sichern

*Videopage fuer dieses Programm einstellen

       LI   R6,VDPK02    80 Zeichen Mode waehlen
       BL   @VDP4
       MOV  @MDVPAG,R1   Von MDOS benutzte Videopage holen
       INC  R1           Dieses Programm benutzte die naechsthoehere PAGE
       MOV  R1,@PGVPG    Bestimmten Wert fuer spaetere Anwendungen retten
       LI   R0,>0004     SET DISPLAY PAGE
       XOP  @VID,0       MDOS fuehrt diesen Befehl aus
       LI   R6,VDPK11   Bildschirmfarben einstellen
       BL   @VDP4        Ein XOP tut das
       BL   @CLS
       BL   @KOPF        Kopfzeile ausgeben

* Tasterturroutine aufrufen und R1 umwandeln

       CLR  R1           R1 soll >00 an REGDIS uebergeben
       BL   @REGDIS      HB von R1 in ASCII-Werte umwandeln
       MOV  R1,@R1ANZ    ASCII-Werte retten

* Hinweistext ausgeben

       LI   R6,VDPK12    Cursor fuer 1.Zeile der Ueberschrift positionieren
       BL   @VDP4
       LI   R6,VDPK13    1. Textzeile der Ueberschrift ausgeben
       BL   @VDP4
       LI   R6,VDPK14    Cursor auf Beginn der 2.Zeile (Ueberschrift)
       BL   @VDP4
       LI   R6,VDPK15    2.Textzeile der Ueberschrift ausgeben
       BL   @VDP4
       LI   R6,VDPK06    Cursor fuer R0 Fuehrungstext positionieren
       BL   @VDP4
       LI   R6,VDPK07    Text fuer R0 aus Monitor
       BL   @VDP4
       LI   R6,VDPK08    Cursor fuer R1 Fuehrungstext positionieren
       BL   @VDP4
       LI   R6,VDPK09    R1-Fuehrungstext ausgeben
       BL   @VDP4
       LI   R1,>3030     Bei Programmstart die Register mit >00 ausgeben
       MOV  R1,@R1ANZ    Hier erwartet RFUEL den 'ASC-R1' Wert
       MOV  R1,@R0ANZ    Hier erwartet RFUEL den 'ASC-R0' Wert
       BL   @RFUEL        Registerwerte in Ausgabepositionen eintragen
       LI   R6,VDPK0A    Cursor fuer Infotext R0 setzen
       BL   @VDP4
       LI   R6,VDPK0B    R0-Infotext ausgeben
       BL   @VDP4
       LI   R6,VDPK0C    Cursor fuer PGM-Ende-Text positionieren
       BL   @VDP4
       LI   R6,VDPK0D    PGM-Ende Text ausgeben
       BL   @VDP4
DAULAU MOV  @R0HEX,R0    Tasterturmode fuer XOP-KEY vorbereiten
       BL   @TASPRU      Tastenfeld pruefen (Mit R0HEX / R1HEX)
       CI   R1,>0000     Ist eine Taste gedrueckt worden ?
       JEQ  STTAST       Nein -> Gleich Steuertasten abfragen
       MOV  R1,@R1HEX    Tasterturrueckgabewert retten
       BL   @REGDIS      Rueckgabewert(im HB von R1) in ASC-Wert umwandeln
       MOV  R1,@R1ANZ    Fuer RFUEL UPGM erreichbar ablegen
       BL   @RFUEL       Aktuelle Werte des KBD-XOPs auf Bildschirm

* Kontrolle auf Steuertasten

STTAST CLR  R0            Tasterturmode >00 erzwingen
       BL   @TASPRU       Tastertur pruefen
       CB   @F10TAS,R1    Wurde die F10-Taste benutzt (PGM-Ende) ?
       JEQ  ENTE
       CB   @F1TAS,R1     Wurde F1 gedrueckt (R0 aendern) ?
       JEQ  R0WECH
       B    @DAULAU       Nein -> Im alten Tasterturmode weiterpruefen

* Tasterturmodus umstellen

R0WECH LI   R6,VDPK0E    Cursor auf Hinweiszeilenanfang
       BL   @VDP4
       LI   R6,VDPK0F    Text 'Verringern / Erhoehen ausgeben'
       BL   @VDP4
       MOV  @R0HEX,@MODE Letzter R0-Tasterturwert wird aktueller MODEwechselwert
R0W1   CLR  R0           Zum Aendern des Modewertes im >00-Tastertur abfragen
       LI   R1,>4FF0     Wartezeit um die Aenderungsgeschwindigkeit anzupassen
PTW    DEC  R1
       JNE  PTW          Wartezeit abgelaufen ?
PT     BL   @TASPRU      Auf einen Tastendruck warten
       CB   R1,@HXFFFF   Wurde eine Taste gedrueckt ?
       JEQ  PT           Nein -> Weiter Tastertur pruefen
       CB   R1,@F1TAS    Ist F1 noch gedrueckt ?
       JEQ  PT           JA -> Weiter Tastertur abfragen
       CB   R1,@TASPL
       JEQ  ADDI         Es war das +
       CB   R1,@TASMI
       JEQ  MINU         Es war das -
       MOV  @MODE,@R0HEX Geaenderten MODE-Wert fuer Hauptprogramm greifbar mache
       LI   R6,VDPK10    Ausgegebene Hinweiszeile loeschen
       BL   @VDP4
       B    @DAULAU      Alle anderen Tasten gehen in die Dauerfunktion zurueck
ADDI   INC  @MODE        Modewert erhoehen
       MOV  @MODE,R1     REGDIS braucht den umzuwandelnden Wert in R1
       SWPB R1           im HB
       BL   @REGDIS      in ASC-Werte umrechnen
       MOV  R1,@R0ANZ    Wert muss als R0 erscheinen
       MOV  @HX3030,@R1ANZ als Inhalt von R1 >00 ausgeben
       BL   @RFUEL       aktuelle Registerwerte ausgeben
       JMP  R0W1         Weitere Veraenderungen ermoeglichen
MINU   DEC  @MODE        Modewert verringern
       MOV  @MODE,R1     REGDIS will ihn da haben
       SWPB R1           und zwar im HB
       BL   @REGDIS
       MOV  R1,@R0ANZ    Rueckgabewert ist des ASC-Code fuer die Ausgabe
       MOV  @HX3030,@R1ANZ >00 wird als Inhalt von R1 festgeschrieben
       BL   @RFUEL       Registeranzeige mit aktuellen Werten fuellen
       JMP  R0W1         Weiter Aenderungen ermoeglichen

* Programmende erreicht

ENTE   BL   @RETMDS      Vorgefundene MDOS-Werte wiedereinstellen
       BLWP @MDOS        Programsteuerung an MDOS zurueckgeben

       CI   R0,>FFFF
       JNE  PAUSE
       B    *R11

CLS    LI   R0,>2E       HCHAR OPcode (VID-LIB)
       CLR  R1           Beginne bei Zeile 0
       CLR  R2           Beginne bei Spalte 0
       LI   R3,>0020     Schreibe Leerzeichen (>20) auf den Bildschirm
       LI   R4,2080      80*20 Positionen lang
       XOP  @VID,0       HCHAR-Anweisung an VDP-Prozessor uebergeben
       B    *R11         Zurueck an HPGM

* HB von REG #1 in ASCII-Werte umwandeln und R1 HB/LB zurueckgeben

       SRL  R1,4         HB enthaelt HN / LB enthaelt LN des Ausgangwertes
       MOVB R1,R2        HN des uebergebenen Bytes wird HB in R2
       SWPB R2           Zum Rechnen besser ins LB
       AI   R2,>30       ASCII-Offset
       CI   R2,>3A       Wurde ein Buchstabe uebergeben ?
       JLT  REG1         Nein -> dann 2. Teil bearbeiten
       AI   R2,>7        Buchstabenoffset addieren
REG1   ANDI R1,>00F0     LN des uebergebenen Wertes ausblenden
       SRL  R1,4         uebergebener LN des Bytes wird LN im HB von R1
       AI   R1,>30       ASCII-Offsetwert
       CI   R1,>39       Wurde ein Buchstabe uebergeben ?
       JGT  REG2         Ja -> Buchstabenoffset addieren
       JMP  REG3         PGM ruecksprung vorbereiten
REG2   AI   R1,>7        Buchstabenoffset
REG3   SWPB R2           bestimmter ASCII-Wert wandert ins HB
       MOVB R2,R1        und wird HB vom Ausgangsregister

* Tastenfeld abfragen

TASPRU MOV  R11,@UPGMRT  Ruecksprungadresse retten
       XOP  @KBD,0       Tastertur abfragen
       MOV  @UPGMRT,R11  Ruecksprungadresse herstellen
       B    *R11         und zurueck ins HPGM

* Kopfzeile ausgeben

KOPF   MOV  R11,@UPGMRT   Ruecksprung sichern
       LI   R1,KOPF1     Bufferadresse des Kopftextes
       LI   R2,KOPFLG    Laenge des Strings
       LI   R0,>27       WRITE TTY
       XOP  @VID,0
       MOV  @UPGMRT,R11  Ruecksprung ins HPGM
       B    *R11

       TEXT '   Idee: Martin Zeddies   NO COPYRIGHTS'
       TEXT '   Datum: 21.Nov 1990  Zeit: 12:44'
       BYTE >0D,>0A

* Registerwerte von R0 und R1 an zugeordneten Positionen ausgeben

RFUEL  MOV  R11,@UPGMRT   Ruecksprung sichern
       LI   R6,VDPK01    Uebertragungswerte an VDP (R6 ist Pointer)
       BL   @VDP4        Daten in Workspace uebergeben und XOP ausloesen
       LI   R6,VDPK03    Befehlspointer R0ANZ anzeigen
       BL   @VDP4
       LI   R6,VDPK04    Cursor positionieren fuer naechste Anzeige
       BL   @VDP4
       LI   R6,VDPK05    Befehlspointer R1ANZ anzeigen
       BL   @VDP4
       MOV  @UPGMRT,R11  Ruecksprungadr. holen
       B    *R11         Ruecksprung ins Hauptprogramm

* X Byte-Kommando an Videoprozessor uebergeben

VDP4   MOV  R11,@UPGM2  Unterprogramm in 2.Ebene
       MOV  *R6+,R0      R0 uebertragen
       MOV  *R6+,R1      R1 uebertragen
       MOV  *R6+,R2      R2 uebertragen
       MOV  *R6+,R3      R3 uebertragen
       MOV  *R6,R4      R4 uebertragen
       XOP  @VID,0       In R0 finden wir den OP-Code des Befehls
       MOV  @UPGM2,R11   Ruecksprung auf CALL PGM vorbereiten
       B    *R11         Ruecksprung durchfuehren

* Betriebsparameter von MDOS retten

SAVMDS MOV  R11,@UPGMRT  Ruecksprung sichern
       LI   R0,>01       GET VIDEOMODE
       XOP  @VID,0
       MOV  R0,@MDMODE   benutzten Mode retten
       MOV  R7,@MDFARB   Farben des Textmodes sichern
       LI   R0,>05       GET-DIS-PAGE Funktionsopcode  (VID-LIB)
       XOP  @VID,0       Info ueber benutzte Videoseite aus dem Rechner holen
       MOV  R0,@MDVPAG   gefundenen Wert fuer Ruecksprung retten
       LI   R0,>03       GET CURSOR POSITION
       XOP  @VID,0
       MOV  R0,@MDZEIL   benutzte Zeile retten
       MOV  R1,@MDSPAL   benutzte Spalte retten
       MOV  @UPGMRT,R11
       B    *R11

* Wiederherstellen der ausgelesenen MDOS-Betriebsparameter

RETMDS MOV  R11,@UPGMRT   Ruecksprungadresse sichern
       CLR  R0            SET VIDEO MODE
       MOV  @MDMODE,R1
       XOP  @VID,0
       LI   R0,>0002      SET CURSOR POSITION
       MOV  @MDZEIL,R1    Zeilenwert
       MOV  @MDSPAL,R2   Spaltenwert
       XOP  @VID,0
       LI   R0,>0004     SET DISPLAY PAGE
       MOV  @MDVPAG,R1   Pagenummer
       XOP  @VID,0
       LI   R0,>000A     CALL SCREEN
       MOV  @MDFARB,R1   Vordergrund (HB) / Hintergrund (LB) einstellen
       CLR  R3           Vordergrund aendern (FLAG-Wert)
       XOP  @VID,0
       MOV  @UPGMRT,R11  Ruecksprungadresse holen
       B    *R11
       EVEN              Daten muessen an geraden Adressen beginnen
MDVPAG DATA >0000        Hier steht die von MDOS benutze Videopage
MDMODE DATA >0000        Hier steht der von MDOS benutzte Videomode
MDZEIL DATA >0000        Hier steht der von MDOS benutzte Bildschirmzeile
MDSPAL DATA >0000        Hier steht der von MDOS benutzte Bildschirmspalte
MDFARB DATA >0000        Hier steht der von MDOS benutzte Farbkombination


This directory contains the a99 cross-assembler, the cross-loader, and the TIC compiler. This is for MSDOS; and also contains Clint Pulley's sieve program and his library routine CSUP (not sure if it is the latest available for MDOS).

To rebuild the executables for sieve, then do:


This will invoke the TIC compiler, the a99 assembler, and the cross-loader to produce the output files:


These can be xmodemed to a geneve (they have the tifiles headers) and directly run from MDOS.

A list of the files in the archive and function are:

   A99.EXE     The A99 Cross Assembler
   LOADER.EXE  The A99 Cross Loader
   TIC.EXE     The TIC C Compiler
   SIEVE.C     Clint Pulley's C Sieve Program Source
   SIEVE.C99   Linker File for Loader
   CSUP        C99 Supervisor (for MDOS)
   BUILD.BAT   Automatically builds SIEVE.P99, SIEVF.P99

al beard



TI 99/4A and GENEVE 9640 Cross-Assembler/Cross Loader

This is the source and documentation for the TI-99/4A and MYARC GENEVE 9640 cross assembler and cross loader. The assembler portion was developed from an assembler written by Dr. Bruce E. Wampler of the University of New Mexico. This was posted on BIX (Byte Information Exchange) by Ron Lepine, and extensively modified by Al Beard (co-moderator of the TI-99 conference) to produce object in TI-99/4A format.

In release 2.3, a companion cross-LOADER was included. This LOADER produces a TIFILES XMODEM file suitable for downloading directly to the TI-99/4A and MYARC GENEVE.

The latest version has extensions to support TIC, the FAIRWARE C compiler for the TI-99/4A and MYARC Geneve. Programs are more compatible if long ref and def names can be used, hence the assembler and loader now support longnames of 31 characters or less.

I have dropped in this version (version 2.9) the FAIRWARE requirement, it didn't raise a single dime, and I don't want to bother with it anymore. Keep in mind that this program is copyrighted, which means you can use it, copy it, but you can't in any way sell it or use it for commercial applications.

As a final disclaimer, if this program works for you, fine. If it doesn't, too bad. If you let me know what is wrong, I'll try to look at it, but I don't guarantee this program will work for you and your application.



TI-99/4A, TMS9900, TMS99000, & MYARC Geneve Cross Assembler

User's Guide

  1. Overview

This is the guide for the TMS99x series of microprocessors Cross Macro Assembler. This assembler was taken originally from the TI-990 Cross Macro Assembler used by the University of New Mexico Computer Science Department for CS-255.

A cross assembler is an assembler that runs on one computer (e.g. a TI-PRO, an IBM PC, or AMIGA) and assembles code intended to run on another computer (the TI-99/4A, MYARC Geneve, TMS9900 or TMS99000).

Creating and running a TI-99/4A Assembly Language Program requires the following procedures:

  1. Create Assembly Language source program on PC or UNIX or whatever.

  2. Assemble the program using the a99 cross assembler.

  3. Download the hex object code file using some type of downloader program. It must be downloaded into a DISPLAY/FIXED 80 file.

  4. Load the program using the editor/assembler load and run option, or the mini-memory load and run option, or the BASIC/Extended BASIC CALL LOAD subroutine.

Alternately, the module can be created in a LOAD module using the cross- loader, and downloaded via some XMODEM package (e.g. FASTERM) into a PROGRAM file suitable for running on the MYARC GENEVE or TI-99/4A.

This manual describes the use of a99, the cross assembler. It does not describe in detail the TMS9900 assembly language instruction set or addressing modes, refer to the TI-99/4A editor/assembler manual for a description of this.

  1. a99 - The TMS99x Cross Assembler

2.1 Running a99

A99 is a -c- program which is contained within several source modules, as follows:

         a99.h       header file
         a99main.c   main program
         a99pass1.c  pass 1 source
         a99pass2.c  pass 2 source
         a99psop.c   psuedo-operands
         a99proto.h  header file for subroutine definitions
         loader.c    the loader source program

It is written using standard -c- constructs, so it should be compatible with most -c- compilers. The version included in the archive file was compiled on an AMIGA, using Lattice -C-, and on a TI-PRO, also using Lattice -C-.

Ron Lepine has spent considerable effort in ensuring that a99 will compile on a variety of C compiler products, so the chance of you getting it working with your C compiler is good.

A source file input into the cross assembler must have an extension of '.a99'. The `.a99' is not specified when a99 is run. A99 optionally creates 2 output files, the filename specified on a -l switch, with the extension of '.l99', and the filename specified on a -o switch, with the extension of '.x99'.

A99 provides a parameter switch (-p) which allows options to be turned on for the assembly. These options are:

         m -  extended Mode, provides long ref/def names (>6 chars)
         n -  No register definitions (don't define R0, R1, etc.)
         c -  Produce compressed object format (default=uncompressed)
         g -  Provide TMS9995 extensions, including the instructions:
                    MPYS - Signed Multiply
                    DIVS - Signed Divide
                    LST  - Load Status Register
                    LWP  - Load Workspace Pointer
         h - Provide TMS99105A and TMS99110A extensions, which include
             the TMS9995 extensions, and also the instructions:
                    BIND - Branch Auto-Increment
                    BLSK - Branch and Link through Stack
                    TMB  - Test Memory Bit
                    TCMB - Test and Clear Memory Bit
                    TSMB - Test and Set Memory Bit
                    AM   - Add Double
                    SM   - Subtract Double
                    SLAM - Shift Left Arithmetic Double
                    SRAM - Shift Right Arithmetic Double
                    LDS  - Long Distance Source
                    LDD  - Long Distance Destination
                    AR   - Add Real
                    SR   - Subtract Real
                    MR   - Multiply Real
                    DR   - Divide Real
                    LR   - Load Real
                    STR  - Store Real
                    CIR  - Convert Integer to Real
                    CRI  - Convert Real to Int
                    NEGR - Negate Real
                    CRE  - Convert Real to Ext Int
                    CER  - Convert Ext Int to Real
                    CR   - Compare Reals
                    MM   - Multiply Multiple

A typical a99 command line to assemble the program newops.a99, create a listing file in file newops.l99, create an object file in file newops.x99, and compile with the TMS99105A/TMS99110A extensions would be:

          a99 -pch -lnewops -onewops newops

A99 is a two pass assembler. At the end of the first pass, it displays the value of the last memory location used. It displays the number of errors detected at the end of the second pass.

2.2 Errors

A99 will detect most syntax errors. Offending lines are displayed on the terminal screen, followed by the error message. In addition, the offending lines are marked in the '.l99' listing file.

2.3 Instruction set

A99 supports the complete instruction set as described in the TI-99/4A Editor/Assembler User's Guide.

If the -pg parameter is chosen, then four additional opcodes are recognized for the TMS9995 microprocessor.

If the -ph parameter is chosen, then 24 new opcodes for the TMS99105A/ TMS99110A processors, as well as the four additional TMS9995 instructions are recognized.

Refer to the TI TMS9995 Data Manual, and the TMS99105A/TMS99110A manuals for a description of the new instructions..

2.4 Operand Addressing Modes

A99 supports all TI-990 addressing modes. The symbols R0-R15 are predefined for registers (if the -pn option was not chosen). Any symbols used as operands may use the rules for labels described below. In addition, expressions as described below may also be used. For example, "CLR @VAR+4" is a legal operation which refers to the contents of the 2nd word following the label VAR. (VAR+0 is the word at VAR, VAR+2 is the 1st word, VAR+4 the 2nd following word.)

2.5 Upper and Lower Case

A99 is totally case insensitive. Thus `ABC' is treated as being identical to `abc'. This is true for opcodes, operands, and labels.

2.6 Labels

A99 allows labels to be up to 128 characters long. Labels can begin with any character except: 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, >, @, (, ), *, ;, -, ', ", comma, space,tab, or :. Following characters may use 0 to 9 and in addition. Labels are defined by appearing in the label field, which is a symbol beginning in column 1. Labels are terminated by a space or tab, as well as a colon. If a label is followed by a colon, it need not begin in column 1, but must be the first symbol on the line. The following are valid labels:



Comment lines are indicated by the first character in the line being a semi-colon or an asterick. Comments may be included on the same line as an instruction by preceding them by a blank or a semi-colon.

There are certain cases were you must precede the comment with a semi- colon. In particular, if the first character of your comment beings with a comma (,) or colon (:), then it must be preceded by a semi-colon.

2.8 Expressions

More general expressions are allowed in a99. The operations +, -, , /, | (logical or), and & (logical and) are supported. Expressions may not use parens, and are evaluated strictly left to right. ( does not have precedence over +, for example.) In general, expressions may use any symbol defined anywhere in the program, as well as constants. Hex constants begin with >.

Restrictions: the current version of a99 does not allow spaces between expression symbols and operators. Symbols used in an expression in an "EQU" directive must not be forward references.

2.9 AORG address

The AORG statement works exactly the same as in the 99/4 assembler. If AORG is omitted, the assembly is assumed to be relocatable as if the statement RORG 0 preceded any object code generation.

2.10 RORG address

The RORG statement works exactly the same as in the 99/4 assembler. If RORG is omitted, a99 defaults to a starting relocatable address of >0000.

You should not mix AORG mode with RORG mode.

2.11 BSS blocksize

This reserves a block of of memory of blocksize bytes. If blocksize is odd, it will NOT be rounded up to an even size.

2.12 DATA valuelist

This reserves a word of storage for each item in the list. Items are separated by commas. Unlike the UNIBUG assembler, you may have several values following the DATA statement, each taking one word of memory.

2.13 END

Denotes the end of the program. Every program must have an END statement.

2.14 label EQU value

This directive will give value to the symbol label. The value may be any expression, but must not use any symbols defined after the EQU statement (a forward reference is not allowed, in other words). It is possible, however, to use the label of the EQU anywhere in the program.

2.15 TEXT /string/

This reserves storage for the given string. The string is delimeted by two matching characters, e.g.:

   "string"   or  /string/  or  'string'

If double single quotes are included in the string, they will be interpreted as a single quote, i.e.:

   'don''t do it'

2.16 BYTE valuelist

This reserves a byte of storage for each item in the list. Items are separated by commas. Note it is possible to leave the location counter odd with this statement (as with the TEXT directive). This allows you to freely mix TEXT and BYTE expressions.

2.17 DORG address

The DORG statement works exactly the same as in the 99/4 assembler. It differs from AORG in that object code generation is suppressed.

2.18 DEF label[,*label* ... [,*label*]

Provides an external definition. Most useful to indicate an entry point into the program for the load and run option. Multiple labels are allowed per one DEF statement. Each label must be sepereated by a comma, and the DEF list must be terminated by a blank or tab.

2.19 IDT ident

An up to six character program identifier can be provided. Merely includes it in the object file.

2.20 PAGE

Causes a page eject on the listing file.

2.21 TITL up-to-50-character-title

An up to 50 character title line can be included within quotes. This line will be put at the top of each listing page.

2.22 REF label[,*label*] ... [,*label*]

Provides an external reference. The label field must be specified in another program using the DEF statement. Multiple labels are allowed per one REF statement. Each label must be sepereated by a comma, and the REF list must be terminated by a blank or tab.

2.23 RT

The RT psuedo instruction provides a convenient means of executing a standard TI return from subroutine. It actually generates the same code as the instruction:

                 B  *R11

2.24 COPY

The COPY psuedo instruction provides a means for including source files with the compilation. This is useful say, to create a small module which "INCLUDES" or "COPIES" other modules in its address space. It is also useful to COPY in common equate files (e.g. what was created for the MYARC GENEVE).

The SYNTAX of the command is:

                 COPY "*filename*"

where filename is the DOS full file name (not the TI-99 file name). For example, on the Amiga, an equates file called "vid.eq9" exists in directory "df2:equates/", so the COPY directive would be:

                 COPY "df2:equates/vid.eq9"

A COPY'd file may not contain another COPY command, or an error will result.

2.25 IFxx expression / ELSE / ENDIF

The IFxx/ELSE/ENDIF statements allow you to create modules with conditionally assembled code. The expression is evaluated, and if the expression is non-zero, then the following code is assembled. If the expression is zero, then the following code is not assembled, until an ELSE or ENDIF statement is encountered.

This is especially useful in writing code for two different machines or operating systems. Only one source module need be maintained, and the proper code for each operating system can be generated by merely setting an equate in the program or in an equate file.

For example, to generate code for MDOS or GPL, one could create a flag set to one or zero, e.g.:

  MDOS   EQU  0             ; MDOS=1, GPL=0

and then generate two sets of code, i.e.:

         IFEQ  MDOS
         XOP  @DKEYOP       ; In MDOS, call keyboard XOP
         BLWP @KSCAN        ; In GPL, call keyboard scan

Note that if the MDOS flag is set to non-zero, then the XOP code will be generated, else the KSCAN routine will be called. The ELSE condition is optional, however the ENDIF statement must be present.

The following conditionals, when TRUE, will cause any following code to be assembled up to any following ELSE or ENDIF statement:

   IF         -  if expression NOT 0
   IFEQ       -  if expression 0
   IFNE       -  if expression not 0 (same as IF)
   IFLT       -  if expression less than 0
   IFLE       -  if expression less than or equal to 0
   IFGT       -  if expression greater than 0
   IFGE       -  if expression greater than or equal to 0
  1. Macros

A macro is a facility for text replacement. A single line of source assembly code that uses a macro will be replaced by possibly many lines of assembly code defined in the body of the macro definition. Thus, to use a macro, it must first be defined, then "called" from within the assembly language program. While a macro may be considered to be somewhat like a subroutine, there is a major difference. When a subroutine is called, the PC changes value, and the program begins executing code in a different place in memory. When a macro is called, the code from the macro body is actually substituted at the place of the call. This substitution process is called expanding the macro. Macros may have parameters that can be substituted within the body when the macro is expanded. Figure 1 illustrates a macro definition and call:

         SOURCE CODE                    EXPANDED CODE
        AORG    >300                    AORG    >300
JLSEQ   MACRO           ; "Jump \<="
        JLT     %1      ; %1 is param
        JEQ     %1
        ENDM            ; end
;                               ;
        C       R1,R2   ; compare       C       R1,R2
        JLSEQ   LBL1    ; jmp \<=        JLT     LBL1    [expansion]
                                        JEQ     LBL1
        A       R1,R2                   A       R1,R2
LBL1    ...                     LBL1    ...
Figure 1.  A Macro Example

This macro allows a jump on arithmetic less than or equal using one line of assembly source code. It is expanded at assembly time to two actual instructions, JLT and JEQ, using the parameter provided in the call: LBL1. The macro definition starts with the directive MACRO and ends with the directive ENDM. Parameters in the definition are denoted with a %, and provided in the call just like an ordinary operand.

3.1 Macro Definition

A macro is defined with an initial line of the form:

               MACRONAME   MACRO.

The macro name may be any standard label, and must be present with the MACRO directive. When assembling, the macro definition table is checked last. Thus, it is not legal to define a macro with the same name as a valid instruction such as MOV or INC since a99 will match the regular MOV instruction first and never get to the macro definition table.

3.2 Macro body

The body of a macro consists of any number of legal TI assembly language instructions. There must not be calls to other macros within the body of a macro definition. Nested macros are not allowed. The macro is ended with the ENDM directive. Macros definitions appear in the .l99 file with dashes in place of the usual address/value fields.

3.3 Macro Formal Parameters

Any macro definition may use up to 9 parameters. Parameters are implicitly defined, and can appear in the body of the macro definition as the symbols %1 to %9. Any given parameter may be used as often as needed within the macro body. Parameters will be expanded whenever they are found within the macro body, regardless of the context. Thus, you may not use an unprotected % in a macro body (See Protected values, below). Parameters must be used in order from %1 to %9.

3.4 Local Labels

It is sometimes necessary to use labels within a macro definition. If a standard label were used, it would result in a multiple definition of a label error whenever the macro was called more than once. A99 allows local labels to be defined within the body of a macro that will be expanded to unique labels whenever the macro is called. Local labels have the form ?x. The ? denotes a local label, and the x is any letter from a to z that the programmer chooses. Thus, any one macro may have up to 26 local labels. Labels may be re-used in different macro definitions - ?a can be used in more than one macro definition. When local labels are expanded, the ?x portion remains constant, and two additional letters are automatically appended to generate a unique label of the form ?xyz. Each time any macro is called, the label generator produces a new label, whether labels are used or not. Thus, the very first macro call will have generated labels of the form ?xaa, the second macro call ?xab, and so on. Thus up to 676 macro calls may appear in any one program -- far more than will ever be needed for this class. The ? is a special character, just like the % and may require protection.

3.5 Protected Values

Sometimes you may want to protect portions of the macro body. For example, you may have a string with a ? or % within the macro body definition. If such values are left as is, they would be confused with parameters or local labels. Square brackets ([ and ]) may be used to protect any portion of a macro body. Thus a string text[?] would be expanded to text? with no label expansion of the ?.

3.6 Invoking a Macro

A macro is invoked by using the macro name followed by any parameters. A macro call will look just like a regular instruction in the source code, and may be followed by up to 9 operands. The operands in the order given are then substituted for the formal parameters %1 to %9 in the macro body as the macro is expanded.

3.7 LIST Directive

The LIST assembler directive is used to control the listing of generated code for macro calls and TEXT directives. These directives affect only the .l99 file, and in no way change the code generated in the .x99 object code file.

LIST    NOTEXT  ; default

The TEXT and NOTEXT options control how generated code for TEXT directives is listed in the .l99 file. With NOTEXT, the default, the starting address of the string is given, along with the number of bytes the string takes in the value field. Using the LIST TEXT option has a99 list the address and value of each word of data generated by the TEXT directive in the .l99 file. The NOTEXT option makes the .l99 file much smaller.

LIST    MONCE   ; default

These LIST options control the .l99 expansion of macro calls. The MOBJECT option is the defaulted option and causes the MACRO not to be expaned in the listing, only the original source line and the resultant object are listed. The MNEVER option forces a99 to never list the expanded code produced by a macro call. The default MONCE option will have a99 list the full expansion of a macro the first time it is called. Subsequent calls to the same macro will not be expanded in the listing. The MALWAYS option will have a99 show the full macro expansion every time a macro is called. This option is most useful for debugging to make sure the parameter expansion and label generation works as expected. Comments present in the original macro definition will be removed from the expanded code. Expanded code is also formatted on tab stops. This automatic provision means that strings may have some spaces replaced with tab stops. This can be avoided by being sure string defined with TEXT directives inside the macro body use double quotation marks:


Other forms of the LIST statement:

  LIST "file_name"

These directives serve two distinct purposes. The LIST statement with no arguments restores output to the listing file which had been previously disabled using the UNL (unlist) command. The list statement with a file name enclosed in double quotation marks will cause the listed output to be redirected from the file specified on the -l command line switch to the file_name specified.

TI-99/4A, TMS9900, and TMS99000 Cross Loader

User's Manual

1.0 Overview

The TI-99/4A and MYARC Geneve Cross Loader simulates the "CALL LOAD" and PROGRAM SAVE facilities on the TI-99/4A. It differs somewhat in that:

  1. Programs can be loaded anywhere in memory, including the Geneve locations of 0400-F000.

  2. Program load module format is compatible with MYARC Geneve MDOS format transient commands (Program File).

  3. Instead of producing a "pure" program file, a file with a TIFILES header is produced. This allows for downloading the file directly to the Geneve or TI-99/4A using a standard AmigaDOS or MSDOS XMODEM facility, and FASTERM, 4A/TALK, MASS80COL, or TELCO.

Before using the cross-loader, you must assemble your program(s) using the TI-99/4A cross-assembler, creating one or more .X99 file(s) (object files). Once you have the object assembled, you must create a loader command file, containing the following statements:


2.0 Commands

A loader command file consists of multiple commands, intended to describe the type of object to be created (OPTION), which object (.X99) files are to be included (INCLUDE), the name and format of the resulting SAVE file (SAVE), and the module termination.

2.1 OPTION command

The OPTION command tells the loader whether to create a TI-99/4A program file, a GENEVE fast memory file, or a GENEVE slow memory file, as follows:

     OPTION N         (not GENEVE, produce TI-99/4A GPL Object)
     OPTION G         (Geneve SLOW memory, normal MDOS mode)
     OPTION F         (Geneve FAST memory, fast MDOS mode)

The OPTION command has an optional second parameter which specifies the start load address for relocatable object, i.e.:

     OPTION N,>A000   would start TI-99/4A load at address >A000
     OPTION G,>0400   would start MDOS compatible load at address >0400

The parameter is optional. If unspecified, and relative loads are performed, the cross-loader will start loading the relative object at location >A000 (for TI-99 object), or >0400 (for MDOS object).

2.2 INCLUDE command

The INCLUDE command may be specified one or more times, and defines an object module (a .X99 file) to be included. Note that this loader only recognizes TI-99 aorg'd uncompressed object, such as is produced by the cross-assembler. The format of the include file is:

      INCLUDE filename

where: filename is the DOS name of the file to be included. It must be terminated by a blank. For example, to include the object modules TEST.X99 and TEST1.X99 that are located in the Amiga directory df2:objects/, the commands would be:

      INCLUDE df2:objects/test.x99
      INCLUDE df2:objects/test1.x99

2.3 PAGEBOUND and SEGBOUND commands

The PAGEBOUND and SEGBOUND commands allow you to "round-up" where the next module is to be loaded. This wastes space in the overall executable program, but makes debugging much easier, since an odd offset need not be added to the listing.

The commands are:

      PAGEBOUND      -  rounds the program counter to next >100
      SEGBOUND       -  rounds the program counter to next >800

There are no parameters.

For example, if the following commands were given:

      INCLUDE OBJ1.X99

Module OBJ1 would start at the next page boundry following OBJD. If module OBJD ended at location >0E6A, then module OBJ1 would start at location >0F00.

2.4 SAVE command

The SAVE command actually causes the PROGRAM file to be produced. It defines the name of the program image file(s) (with XMODEM headers), and the start and end addresses to use in the program image. The syntax is:

      SAVE filename,start_address,end_address[,length]

The filename parameter specifies the DOS filename to create. The start_address and end_address parameters define the starting and ending addresses to include in the program file. They may be specified as hexadecimal addresses (by preceding them with a greater than symbol, e.g. >A000), or as program symbol DEF'd names (e.g. START,SEND). For example, to create a program file called TEST.P99, with a start address and ending address of >A000 and >B123, the command could be:

           SAVE TEST.P99,>A000,>B123

Note that this is rather hard-code-ish. It is recommended that symbols be DEF'd in your program pointing to the start and end of the file, as follows:

                DEF     START
                DEF     SEND
         START  EQU     $
                 .  program body
        SEND    EQU     $

Then the command could be specified as:

            SAVE TEST.P99,START,SEND

The SAVE command observes the TI-99 restriction of 8k program modules. If more than 8k is being saved, then multiple output modules will be created, each with its own TIFILES header. If more than one file needs to be created, then the last character of the filename (character preceding ".", or last character of filename if filename doesn't include a ".") will be incremented for each file, in the same manner as the TI-99 SAVE facility.

The last parameter on the end is the maximum size program files to create. If not specified, the default is >2000 bytes per program module. If your loader on the TI-99 can accept more, use a larger default. For example, If you want each module to be >4000 bytes maximum, then specify:

           SAVE TEST.P99,START,SEND,>4000

Note that MDOS currently has a restriction of 15.5k per module (according to Paul Charlton).

2.5 END Command

The END Command is used to terminate the cross-loader. It has no parameters and is specified as:


Upon encountering the END statement, the cross loader displays the contents of the REF/DEF symbol table. The list is in the order in which the REF/DEF's where encountered in the object module(s). REF's are indicated with the letter 'R', and DEF'd symbols with the letter 'D'. Following a list of all of the defined symbols, a REF list of unresolved symbols is listed (if any). The number of unresolved symbols is also displayed.

The following is an example of the REF/DEF symbol list:

                Symbol File (REF/DEF entries)
                  Total Entries = 2
                1. CRASH  D A000 0200
                2. CEND   D A058 0
                NO unresolved references

The six character def name, the REF(R) or DEF(D) status of the symbol, and the symbol location (e.g. A000) is displayed. The next hex number is the current contents of that memory location.

3.0 Example

An example command file called test.c99 would be:

    OPTION G,>0400                  (produce GENEVE slow memory)
    INCLUDE "test.a99"              (include first module)
    PAGEBOUND                       (start next at page boundry)
    INCLUDE "test1.a99"             (include second module)
    SAVE TEST.P99,START,SEND        (save it)

The command file would be invoked by:

    loader test.c99

and would result in the program file:


The file could then be downloaded to the MYARC geneve using FASTERM, or MASS80COL (using XMODEM). This will cause a program file (e.g. TEST) to be created on the disk. Type TEST under MDOS to execute your program.

A TI-99 compatible file (MYARC GENEVE GPL Mode) could be created by the command file:

    OPTION N,>A000                  (Not a GENEVE)
    INCLUDE "test.a99"              (include first module)
    PAGEBOUND                       (start next at page boundry)
    INCLUDE "test1.a99"             (include second module)
    SAVE TEST.P99,START,SEND        (save it)


Example Program Notes:

Included in the archive is an example program taken from the editor/ assembler user's manual. This program creates a crash sound (forever repeating). I started here with two source modules:

            example.a99  -  The program source
            example.c99  -  The command file for the loader

and performed the following steps:

  1. Assembled the example.a99 program, creating the list file example.l99, and the object file example.x99, using the command:

            a99 -oexample -lexample example
  2. Linked the example program using the loader command:

            loader example.c99

This created the XMODEM compatible object module example.p99.

  1. Downloaded the example.p99 to the TI-99/4A using VT100 (on Amiga side) and 4A/Talk (on TI-99/4A side), creating a program file called DSK1.EXAMPLE on the TI-99 disk.

  2. Executed DSK1.EXAMPLE using item 5 on the Editor/Assembler menu. It loaded & ran automatically, and created the CRASH sound.

The following documents what was changed for each version of the assembler:

Version 2.0:

The CS-255 TI-990 cross macro assembler was modified to use somewhat TI-99/4A compatible code. The following changes were made over the original Wampler code:

o The object output was modified to be consistent with the un-compressed form of the TI-99/4A assembler.

o The psuedo opcodes PAGE, TITL, IDT, DEF, BYTE, EVEN, and DORG were added.

o The listing was modified to include line numbering, page numbering.

o A restriction was removed on the AORG address.

o Astericks were now allowed to indicate comment lines.

o The requirement for a semicolon to indicate the start of a comment on a line was removed.

o Text string handling was reworked, so that TEXT and BYTE statements can be intermixed without the assembler adding extra pads to null out odd strings.

o The RT instruction was included.

o The number of symbols was increased to 2000, the total symbol table space increased to 10000 characters.

The following items were added in version 2.1:

o The REF statement

o The UNL (unlist) statement was added which turns the listing off.

o The LIST statement was expanded in the following manner:

    - A LIST statement with no arguments turns the listing on (undos the UNL statement)

    - A LIST statement with a file name enclosed in double quotes (e.g. "df0:listing2") will cause furthur output for the listing to be directed to the specified disk file.  Useful when you are trying to keep a listing file down to a certain maximum size.

    - A new MACRO list option MOBJECT was added, which will output from a macro the original source line, and then any object.  This made very nice listings for pseudo languages built with MACROs.  This mode was made the default macro list mode.

o Two compilation time switches were added, the -l (specify listing file) and -o (specify object file). The object and listing file are not now produced by default; they are only produced if specified by the -l and -o switches. It is not necessary to use the file extension on the -l and -o switches, they are automatically provided by the assembler. The following would be a perfectly valid command line:

         a99 -ltest -otest test

which specifies taking input from the input file test.a99, write the listing file to the file test.l99, and write the object file to test.x99.

o The BSS was changed not to round up the next address produced (forcing an EVEN directive). This was for compatibility with the standard TI-99/4A assembler.

o The TEXT directive was changed to correctly recognize the existance of two quotes meaning a single quote, e.g.:

            TEXT 'Don''t do it'

o A minor change was made so the last record (: 99/4 Assembler) was padded with blanks, so that the resulting downloaded record to the TI-99/4A was clean (no garbage).

o The symbol table was hashed instead of using a sequential lookup. This really improved execution speed on large files, 3800 line file on Lattice AMIGA took 6 min on 2.0, took 2 min on 2.1 hashed version.

o Allowed MACRO lines to have comments starting with blanks

o Increased MACRO space in header file from 20 to 200 (You may want to decrease this, it does greatly increase the resulting object size of the program.

o Changed the way local branch names are assigned within macros. The old method bumped the name on every macro call, regardless of whether any local labels were used, causing an unecessary overflow error about every 1400 macro invocations.

o And, oh yes, split the program into three seperate files, since it got too big to compile with one. It is now contained within files a99main.c (the main program), a99pass1.c (sort of pass 1 routines) and a99pass2.c (sort of pass 2 routines). The file a99.h remains the header file with the parameters.

The following items were added in version 2.2:

Several minor changes were made to correct problems found by Ron Lepine. Decreased number of macros from 200 to 80. Removed check for "extra operands present". Check was not necessary since anything past the required operands is now considered a comment.

The following items were added in version 2.3 (November 30, 1987):

o Added COPY directive, which operates as an INCLUDE file directive. This was mainly done so I could include EQUATE files for the MYARC Geneve.

The following items were added in version 2.4 (December 20, 1987):

o Added IF/ELSE/ENDIF statements. This was done so I could write conditional code for GENEVE (e.g. IF GENEVE, ELSE, ENDIF).

o UNL (UNLIST) code now works properly.

The following items were added in version 2.6 (March 3, 1988):

o Added more conditionals, IFEQ, IFNE, IFGT, IFGE, IFLT, IFLE.

o Added relative object code generation.

o Added RORG directive

o Added multiple REFS/DEFS per REF/DEF line (compatibility with TI-99 assembler)

o Changed the emtref routine so that REF's which are included in source but not used in the body of the program will not be emitted into object, and a warning issued. Problem was REF's rorg'd to location 0 in object, and location 0 was getting wiped out when loader was run. This has a side effect that the first location in a program cannot be a ref'd value.

o Added a new parameter option line (-p) with parameters for no register definitions (n), MYARC 9640 GENEVE extensions (g), and TMS99000 extensions (h). Thanks to Tony Lewis for his help in defining these.

o Changed the opcode lookup algorithm to be a binary search instead of a sequential search. Resulted in a 25% improvement in assembly times over previous release.

The following items were changed in version 2.7 (15-AUG-1988):

o Fixed form feed on listings (bug found by Ron). This minor fix was released in the 2.6 MSDOS version of the cross-assembler.

o Allowed relocatable arguments of internal opcodes, e.g. LWPI instruction now allows relocatable (RORG'd) workspace pointer.

o Many cleanups of compilation warnings by Ron Lepine.

o Fixed up the TIME definition to be standard across many systems

o Changed the last object record (: 99/4a assembler) to have a sequence number. Corrected some difficulties I was having with TI-99 kermit.

o Fixed the ELSE construct, previously worked erratically.

o Fixed the RT instruction, don't know how it got broke.

The following items were changed in version 2.9 (31-MAY-1989):

o Added a new "compress" option, to produce TI-99 compressed object code. This permits an almost 3/1 reduction in object code size, and allows the assembler/loader to run even faster.

o Fixed the last ":" colon record to fill out to 80 characters

o The object code format now is strict 80 characters. The old format had 80 characters and a n/l, 80 characters and a n/l. The new format is just 80 characters without a n/l. This was required since compress mode may include a n/l in the middle of the object! (or any other non-printable character).

The assembler will now produce code in the same manner as the standard TI/994A assembler, with the following general restrictions:

o No compressed object

o An inconsistency has been noted with code of the form:

          ABC  EQU  $-GHI

be careful! A good alternate form to work around the bug might be:

          ABC  EQU  ABC-GHI

Version 2.10:

Added extended assembler feature, allowing ref/def names of 7 to 31 chars. Corrected some problems with listing and object when no listing or object file requested. Changed def's to always capitalize def'd names in object files.

The following documents the releases of the companion loader:

Version 1.0 (30-November-1987)

INITIAL RELEASE. Not extensively tested with multiple program files.

Version 1.1 (09-December-1987)

Fixes to multiple object program generation.

Version 1.2 (27-December-1987)

Added optional argument to SAVE directive, which is the maximum program module size to save (since MDOS supports a 15.5k program module size, vs. the TI-99/4A 8k module size).

Version 1.3 (02-January-1988)

Made various changes for MSDOS compatibility, with Ron Lepine's help.

Version 1.4 (28-January-1988)

Version 1.4 supports relative object code. The SEGBOUND and PAGEBOUND commands were added.

Version 2.9 (31-May-1989)

Changed version number to be consistent with a99 version number. Added compressed object code format. Removed debug statements. Changed the object code format to strict 80 bytes per object line.

Version 2.10 (29-Jul-1990)

Added extended mode assembler. Corrected some problems if object and list files were NOT specified on command line.


TI-C Release 1.3 - Notes

Enclosed in the archive are the TIC Compiler, the A99 Cross Assembler, and the Cross-Loader for MSDOS (IBM PC Compatibles). The A99 Cross Assembler are quite stable and functional; they have been in use in one form or another by myself for the last three years. The TIC C compiler isn't quite fully debugged yet, but I am releasing it at the time with the hope that the user community will "help" me shake it out.

What am I looking for? I'm looking for you to compile your favorite c99 programs or public domain/user written C programs, and let me know what doesn't work. Right now, quite a bit SHOULD work; I've compiled a few simple c99 tasks (like sieve and untab) and these generate good programs.

Right now I'm involved in compiling the TIC compiler to produce a native runnable version on a GENEVE. This serves two purposes, it gives us a native C compiler, and also checks out the TIC compiler (if the compiler can reproduce itself, that is the true test of a compiler).

What am I up against? Well, the register allocation (which you won't run into if you use the c99 compatible version) is a toughy, and the indexing into arrays is still somewhat troublesome. But, be aware that the TIC compiler is making it quite a ways into compiling itself, it should just be a matter of time before the whole thing is functional. Also ahead is the writing of a subroutine swapper, the compiler currently extends to >d500 without dynamic memory for the compile operation; the easiest way to make more room for the dynamic tables is to play "swapper" with the subroutines.

TIC is quite an achievement of Matthew Brandt (who wrote the original 68000 version). I don't know if I would have done everything Matthew did (he made extensive use of linked packets; forever allocating memory and linking it as needed), but did produce quite a nice full PD C compiler.

What is missing? Well... The pre-processor is quite simple, basically a K&R pre-processor (with minor extension on #include). Most data types of interest are supported, with the exception of longs, floats, & doubles (the compiler has hooks for these, I'm going to have to get them in sometime).

But TIC DOES support structs, unions, enumerated data types, arrays, while's, for's, data initialization, and most other features of a good C compiler. The code generation I believe is also quite decent (the TIC compiler compiles to about 50k on a GENEVE, it compiles to about 120K using Turbo C++ under MSDOS, and about 70K on an Amiga using Lattice C 1.0). Not bad for a PD compiler.

I'm distributing two archives with this release:

  TICDOCARK -   The documentation file in Barry Boone format
  TICEXEZIP -   An MSDOS PKZIP file for MSDOS only

To use TIC on a PC while the native GENEVE version is under construction, then you need to get the TICEXEZIP file to a PC. This can be done with PCTRANSFER (I don't have the right disk controller to get PCTRANSFER to work, so I'm making a few assumptions here) or by using XMODEM to XMODEM to a PC file. Once on a PC, put the file into its own archive, and use PKUNZIP to unzip the file (PKUNZIP is fairware and is available just about anywhere).

Remember, use TIC with caution; and give me some FEEDBACK. (Examples on floppies with hints on the problems would be MOST appreciated).

           Alan L. Beard
           LGMA Products
           5618 Apple Butter Hill Rd
           Coopersburg, PA  18036


TIC - TI-99/4A and 9640 GENEVE C Compiler 4-Dec-90

User Manual v1.3

I. Introduction

TIC (TI-C) is a K&R style C compiler that compiles C source code into TI-99/4A and 9640 assembly language. It supports many more -C- features than c99; some features (e.g. the #asm directive) are lost.

TIC was derived from a 68000 based C compiler developed by Matthew Brandt. Matthew did a fantastic job in writing the original compiler. His attention to addressing modes and the modularity of the original compiler made the conversion of the 68000 C compiler to TMS9900 a reality.

The following statement is taken from the original Matthew Brandt 68000 compiler:

This compiler is intended as an instructive tool for personal use.
Any use for profit without the written consent of the author is

This author honors the intent of the original author.

Considerable effort has gone into making the compiler produce quality TMS9900 code. The author (LGMA Products) of this code is placing this compiler into the TI and MYARC user community as a shareware product.

TIC does a fairly decent job of conditional branches and making use of various addressing modes of the TMS9900 processor to produce optimal code. Things could always be better, but my code sizes on the non-c99 compatible version are approaching the better MSDOS sizes (e.g. Turbo C and Microsoft C).

TIC supports two modes in compilation. A c99 compatibility mode allows you to generate programs that should be compatible with all c99 libraries (please let me know if you find cases that aren't). A non-c99 compatibility mode produces much more efficient code, but is NOT compatible with the c99 library routines. Why? ---

During implementation of TIC, it was found that by letting the stack grow "up" in memory (rather than "down" as using c99), then much more efficient "pushes" to the stack could be performed. Also, by saving several registers on the stack when subroutines were called, register optimizations on the code could be implemented. The result is almost a 2-1 reduction in the size of some programs (like TIC itself!).

Certainly much more could be done to trim the resulting source code. Experimentation has shown a point of diminishing return, by adding more code to the compiler to produce furthur optimizations, the danger of "over-optimizing" (e.g. producing code that doesn't work) becomes high and the compilations slow to a crawl.

TIC, with the exception of the normal C library routines, is written entirely in C. This allows portability of the compiler to various operating system environments. Three operating systems are currently supported:

    9640 GENEVE (Conversion in-progress)
    Amiga DOS

Other operating systems are easily supported by simply recompiling/linking the compiler under those systems (assuming the system has a quality C compiler).

Creating and running a TIC program is quite simple and involves:

  1. Creation of the source file on the target machine

  2. Compilation of the source using the TIC compiler

  3. Assembly of the resulting source using the a99 assembler or GenASM

  4. Linkage of the object with library modules using the a99 loader or GenLink (note that the object will probably have to be linked with standard c99 libraries, as with any c99 program)

  5. Running the program on the target machine

Note with a cross-compiler, it should be able to create runnable programs for either a TI-99/4A or a MYARC GENEVE 9640, just by linking to the correct c99 library for that machine.

II. Running TIC

Regardless of the machine environment, running TIC is essentially the same. The TIC compiler is invoked with the command line:

TIC *options> filename1 filename2


 *options>  are options specified in the form of +option or -option,
            depending on whether the option is to be added or
            removed.  There are four options:

            +I or +i -  Specify an include file directory

            +O or +o -  Turn ON Optimization (default)
            -O or -o -  Turn OFF Optimization

            +9       -  c99 compatible (default)
            -9       -  not c99 compatible (more efficient, but
                        won't work with c99 libraries)

            +l       -  generate listing file (default)
            -l       -  turn off listing file

    filename1 - is the -c- source file to compile; the filename is in
                the form of:

                       filename.c  -  for MSDOS & Amiga Versions
                       FILENAME_C  -  for Geneve Versions

                The compiler will produce output files of:

                       assembly source - filename.a99 or FILENAME_A99
                       listing file    - filename.lis or FILENAME_LIS


Examples of doing TIC compiles under MSDOS are:


specifies that:

the directory C:\TIC\INCLUDE\ contains header files (e.g.  STDIO.H) that will be used in the compilation (and are referenced by filenames in brackets, e.g. #include *stdio.h>)

optimization, c99 compatibility, and listing files are turned ON

in this case, the files:

            SIEVE.A99  -  Assembly Source file
            SIEVE.LIS  -  Listing file

will be produced.


specifies that:

      the directories C:\TIC\INCLUDE\ and C:\TIC\ENVIRON\ will be scanned for header files during compilation (for files that are specified with #include \<\> format), and

      optimization (+O) and listing file (+L) are turned ON, and

      c99 compatibility (-9) is turned OFF.

Examples of TIC compiles under MYARC 9640 GENEVE MDOS are:


specifies that:

    the directory E:INCLUDE/ is to be scanned for header files
    during compilation (for files that are specified with #include \<\>
    format), and

    optimization, listing, and c99 compatibility are turned on.

In this case, the files:

       SIEVE_A99 -  Source file
       SIEVE_LIS -  Listing file

will be produced.

Appendix I - MSDOS Version

The MSDOS Version of the compiler is similar to the other versions. The MSDOS version has somewhat limited internal buffers (64k) in relation to the 68000 version (limited only by memory available) so that some programs may not compile under MSDOS (in the current version).

The MSDOS distribution kit places the following files in the directories:


      TIC.EXE            -  The TIC compiler
      A99.EXE            -  The Cross-Assembler
      LOADER.EXE         -  The Cross-Loader

Place the following in a -C- header directory:


      STDIO.H            -  Standard I/O routines (from c99 release)

Place the following in a -C- Library Directory:


      CSUP               -  The C Supervisor Directory

Appendix II - TIC Syntax

TIC does NOT support the following C functions:

  1. The #asm and #endasm procs are not supported (this makes life with c99 a bit complicated, as c99 programs were typically written dropping to inline assembler).

  2. The pre-processor is a simple K&R type pre-processor. ANSI extensions to the preprocessor are not supported (with the exception of the bracket #include <> file syntax).

  3. Long INT's, Floats, Doubles are not currently supported (TIC can be extended to these, but aren't currently fully implemented)