Learn Multi platform TMS9900 Assembly Programming... With Workspaces!
This is work in progress... This tutorial is planned to start in 2020

Don't like to read? you can learn while you watch and listen instead!

Every Lesson in this series has a matching YOUTUBE video... with commentary and practical examples

Visit the authors Youtube channel, or Click the icons to the right when you see them to watch the Lessons video!
The TMS9900 is a 16 bit CPU, a miniature version of the TI 990 minicomputer, it was designed for home computer use, but it was really only used in the Ti-99

Despite it's failure in the market the TMS9900 is a fascinating chip, it has virtually no registers, instead using 'Workspaces'... banks of 32 bytes that make the 16 regsiters (like a zeropage)... it also has no stack!

When a function is called, one register is used as a 'Link pointer' - pointing to the return address... if we need new registers for our subroutine, we allocate another 'workspace' giving us a new set of registers - when we're done we restore the original workspace.

If you want to learn TMS9900 get the Cheatsheet! it has all the TMS9900 commands, it also covers the extra commands used by the 65c02 and PC-Engine HuC6280

Systems covered in these tutorials

What is the TMS9900 and what are 8 'bits' You can skip this if you know about binary and Hex (This is a copy of the same section in the Z80 tutorial)
The TMS9900 is an 16-Bit processor with a 15 bit Address bus!
What's 8 bit... well, one 'Bit' can be 1 or 0
four bits make a Nibble (0-15)
two nibbles (8 bits) make a byte (0-255)
two bytes (16 bits) make a word (0-65535)

And what is 65535? well that's 64 kilobytes ... in computers 'Kilo' is 1024, because binary works in powers of 2, and 2^10 is 1024 
64 kilobytes is the amount of memory a basic 8-bit system can access

6502 is 8 bit so it's best at numbers less than 256... it can do numbers up to 65535 too more slowly... and really big numbers will be much harder to do! - we can design our game round small numbers so these limits aren't a problem.

You probably think 64 kilobytes doesn't sound much when a small game now takes 8 gigabytes, but that's 'cos modern games are sloppy, inefficient,  fat and lazy - like the basement dwelling losers who wrote them!!!
6502 code is small, fast, and super efficient - with ASM you can do things in 1k that will amaze you!

Numbers in Assembly can be represented in different ways.
A 'Nibble' (half a byte) can be represented as Binary (0000-1111) , Decimal (0-15) or  Hexadecimal (0-F)... unfortunately, you'll need to learn all three for programming!

Also a letter can be a number... Capital 'A'  is stored in the computer as number 65!

Think of Hexadecimal as being the number system invented by someone wit h 15 fingers, ABCDEF are just numbers above 9!
Decimal is just the same, it only has 1 and 0.

TMS9900 assembler 
TI99 Assembler
123 123
0FF00h >FF00
"A" 'A'

ASW and Byte definitions
Be careful with BYTE definitions - they are automatically Word aligned... EG
Will produce data 1,0,2,0 ... You probably want
BYTE 1,2
instead which will result in 1,2

We're going to use Macro AS in these tutorials, it uses the same syntax as Intel x80 chips... this is very different to the original TI99 Assemblers, but will make it easier for us to learn.
Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ... 255
Binary 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111   11111111
Hexadecimal 0 1 2 3 4 5 6 7 8 9 A B C D E F   FF

Another way to think of binary is think what each digit is 'Worth' ... each digit in a number has it's own value... lets take a look at %11001100 in detail and add up it's total

Bit position 7 6 5 4 3 2 1 0
Digit Value (D) 128 64 32 16 8 4 2 1
Our number (N) 1 1 0 0 1 1 0 0
D x N 128 64 0 0 8 4 0 0
128+64+8+4= 204            So %11001100 = 204 !

If a binary number is small, it may be shown as %11 ... this is the same as %00000011
Also notice in the chart above, each bit has a number, the bit on the far right is no 0, and the far left is 7... don't worry about it now, but you will need it one day!

If you ever get confused, look at Windows Calculator, Switch to 'Programmer Mode' and  it has binary and Hexadecimal view, so you can change numbers from one form to another!
If you're an Excel fan, Look up the functions DEC2BIN and DEC2HEX... Excel has all the commands to you need to convert one thing to the other!

But wait! I said a Byte could go from 0-255 before, well what happens if you add 1 to 255? Well it overflows, and goes back to 0!...  The same happens if we add 2 to 254... if we add 2 to 255, we will end up with 1
this is actually usefull, as if we want to subtract a number, we can use this to work out what number to add to get the effect we want

Negative number -1 -2 -3 -5 -10 -20 -50 -254 -255
Equivalent Byte value 255 254 253 251 246 236 206 2 1
Equivalent Hex Byte Value FF FE FD FB F6 EC CE 2 1

All these number types can be confusing, but don't worry! Your Assembler will do the work for you!
You can type %11111111 ,  &FF , 255  or  -1  ... but the assembler knows these are all the same thing! Type whatever you prefer in your ode and the assembler will work out what that means and put the right data in the compiled code!

The TMS9900 is a BIG ENDIAN machine... what's stranger is that byte operations (like MOVB) work with the TOP BYTE of the register.

The TMS9900 Registers
The 3 real registers in the CPU are as follows
Register Purpose
PC Program Counter
WP Workspace Pointer
ST Status

The 16 Workspace registers (in ram) have the following Names and functions
Register Purpose
R0 Bits 12-15 Shift Count
R1 -
R2 -
R3 -
R4 -
R5 -
R6 -
R7 -
R8 -
R9 -
R10 -
R11 Return address (PC BL)
R12 CRU Addressing
R13 Context Switching (WP BLWP)
R14 Context Switching (PC BLWP)
R15 Context Switching (ST BLWP)

    Flags: I I I I - - - - / - X P O C = A> L>

Bit Details
L> Logical Greater than
A> Arithmatic Greater than
= Equal
C Carry
O Overflow 1=overflow?
P Parity
X Xop
I Interrupt Mask

The TMS9900 Addressing Modes
The TMS9900 has 8 different addressing modes... many are similar to much later systems... in addition it has 4 'effective modes' which are defined by using Reg 7 as a parameter
'Deferred' addressing is known as indirect addressing on other systems

Syntax Effect
R Workspace Regsiter Addressing
*R Workspace Regsister Indirect Addressing
*R+ Workspace Regsister Indirect Auto Increment Addressing
@Label Symbolic (Direct) Addressing
Indexed Addressing
n Immediate Addressing

Program Counter Relative Addressing

CRU Relative Addressing (R12)