Jump to content

- - - - -

Back to my roots: Hello TI!

Posted by gregwarner, 13 February 2013 · 958 views

As many may know already, I got started in computing when I was a kid with the TI-99/4A home computer. ("Home computer" being a term for anything that wasn't a PC.) In order to "find my roots", so to speak, I've recently taken it upon myself to learn Assembly programming on this thing, seeing as though I missed out on this opportunity when I was younger.

Since all the reference documentation for the TI is decades old, there wasn't a single tutorial for the obligatory "Hello World", so I had to make do with what I could find. By stitching together bits and pieces from various reference manuals and tutorials, I was able to cobble together my first ever Assembly program on my beloved first computer! (Only took me about 30 minutes!)

Holding my breath, I invoke the assembler. A few seconds and grinds of the massive floppy drive later, I see:
appear on my screen. Wow! First try! I wasn't expecting that.

Next, I load up the object file and execute it, and I am presented with the following screen:

Attached Image

Success! I pat myself on the back for taking the first step toward accomplishing this little personal challenge.

Here's another screenshot with a bit of code. Working in a 40x24 character screen sure feels restrictive!

Attached Image

For those who are interested, I've included below a source listing and an explanation of the program. There are some pretty interesting facts about the TI which make themselves apparent in the code, as I'll explain after the listing.

(Comments added after the fact.)
DEF  HELLO                defines the entry point to the program
       REF  VMBW,KSCAN           looks up the addresses of ROM routines from the OS's symbol table
MSGTXT TEXT 'HELLO WORLD!'       allocates space for a text message
MSGLEN EQU  12                   equates the symbol 'MSGLEN' to the number 12
SCRLIN BSS  32                   allocates a Block Starting with Symbol 'SCRLIN' of 32 bytes in length
WRKSPC BSS  32                   allocates another block of 32 bytes for the workspace registers.
STATUS EQU  >837C                equates the location of the status register with the symbol 'STATUS'
SAVRTN DATA >0000                allocates a word of memory for the return pointer
KEYADR EQU  >8374                locations in memory of the results of the Key SCAN routine.
KEYVAL EQU  >8375                 (I ended up not using these, but they're needed if you wish to determine which key was pressed.)
ANYKEY BYTE >20                  Allocates a byte of memory to hold a bit mask which will tell us if any key was pressed later.
HELLO  MOV  R11,@SAVRTN          ENTRY POINT! Save the old return pointer for safe keeping
       LWPI WRKSPC               load the workspace pointer, pointing to our allocated block of memory
       LI   R1,SCRLIN            load some values into the registers
       LI   R2,32
CLRWRD CLR  *R1                  clear the word pointed to by R1
       INCT R1                   increment r1 by two
       DECT R2                   decrement r2 by two
       JNE  CLRWRD               jump to CLRWRD if r2's new value is not zero
       LI   R0,0                 load some more values into the registers
       LI   R1,SCRLIN
       LI   R2,32
       LI   R3,24
CLRLIN BLWP @VMBW                call the OS Video Multi Byte Write routine to write a line of null chars to the screen (Blanking that line)
       AI   R0,32                add 32 (the length of a screen row) to R0, effectively moving to the next line.
       DEC  R3                   decrement R3
       JNE  CLRLIN               jump to CLRLIN if r3's new value is not zero
       LI   R0,4*32+5            set print position to row 5, column 6
       LI   R1,MSGTXT            load some more registers
       LI   R2,MSGLEN
       BLWP @VMBW                print the message 'HELLO WORLD!' to the screen
KEYSCN CLR  @STATUS              clear the status register
       BLWP @KSCAN               call the OS's Key SCAN routine
       CB   @ANYKEY,@STATUS      use our bit mask on the status register to see if the OS reports any key has been pressed
       JNE  KEYSCN               if no key has been pressed, jump to KEYSCN and scan again
       MOV  @SAVRTN,R11          Cleanup. Restore the return pointer to R11
       CLR  @STATUS              Clear the status register (Lets the OS know everything went ok.)
       RT                        Return control of the computer to the OS
       END  HELLO                End program, indicate to the loader program that HELLO should be automatically entered upon loading
I should point out that in TI Assembly, hex numbers are prefixed with the '>' symbol, as in the line: STATUS EQU >837C

One of the most important things about the TI is that it doesn't actually have very many hardware registers. All your working registers are held in RAM, in a space known as the "Scratch Pad". Because of this, tracing through jumps and function calls can sometimes be confusing, but to over simplify it, any time the TI executes a "context switch", it allocates a new space of 32 contiguous bytes to use as the new scratch pad, and stores the return address in R11 of the new scratch pad. In my code above, when we enter the program, R11 holds the value of the next instruction address that the OS expects us to return to after completion of our program. So I save this in a dedicated word of memory to restore later. Then, I use the 32 bytes of memory I allocated toward the beginning of the listing as a fresh new set of registers to work with.

Another interesting point is how you call routines in the computer's ROM. The OS provides a reference table with the names of many routines, from reading and writing to video memory, to floating point calculations, to I/O instructions for interfacing with any expansion peripherals that might be installed. You must list all the routines you wish to call so the assembler can look up these addresses for you and assemble them into the object code.

It's a neat architecture, and fun to play with. I'm really looking forward to getting my hands even more dirty with TI Assembly in the near future! If you all are interested in seeing what comes out of this endeavor, be sure to check back with this blog!

  • 1

nice one :)

    • 1

You, make me remember the first computer I make a program with: Apple, with 32kb of RAM!

After a while, they build the Apple II with 64kb of RAM! That was a moooonsterrrr. 

And it had MS-DOS on a special memory card inside and 2 floppy DD 360kb each.

Of course, I make that program in BASIC not assembly language. So, that's awesome.


I also remember the first "file server" I worked with and it was a tower and it has 300MB! of

disc space to share in a office with 15 other computers, using 3Com operating system and

coax cable. Who needed more disc space??!!! It's amazing how things have changed.

    • 1
Powered by binpress