TI-99 Platform Specific Series
<- Back to the Main Contents & Basic TMS9900 Assembly Lessons

Introduction to the Platform Specific Series...
In this series we'll be looking at examples that use the TI-99 hardware.

Lesson P1 - Bitmap graphics on the TI-99
The Ti-99 screen is basically the same as the MSX1 (The TMS9918) - it has two areas of VRAM which define tiles - one set for the bitmap data - and one set for the colors


The TMS9918 VDP memory works differently depending on the screenmode, but today we'll be using it in this setup.

We need to define Tile Patterns for our Font and Chibiko bitmap, set colors in the Colormap, and define the Tilemap to get them showing onscreen.

Patterns are just 1bpp... so 2 color... colors are defined by the Pixel Line... not tile, so each 8x8 tile has 8 color lines...  each a single byte containing a foreground and background color (&FB)
From To Meaning
0000 07FF VRAM: Tile Patterns
1800 1AFF VRAM: Tilemap
1B00 1B7F VRAM: Sprite Attributes
1B80 1BAF VRAM: Palette Table
2000 27FF VRAM: Colormap
3800 3FFF VRAM: Sprite Patterns

Notice the weird 'gap' between &800 and &17FF?.. well the VDP can have two extra sets of pattern definitions... although the MSX1 always uses a tilenumber between 0-255, the screen can split into 3 'thirds'... each third will use a separate tilemap (the 2nd at &800 and 3rd at &1000)... this is how we faked a bitmap mode before!
I suppose if you wanted to have your UI in the bottom third (with font definitions and lives etc)... and the top two thirds the playing area (with common tile definitions?) it would work quite nicely!

In this example we're going to show a Chibiko bitmap... This image is 48x48 split into 8x8 tiles
We can create the bitmap data using my 'AkuSprite' editor (included in Sources.7z)... For this example you want to use 'TI99 -> Save RAW Bitmap'

This will export the bitmap as a black and white bitmap in the correct order for the VDP's tilemap ...
We need to initialize our screen, we need to set the VDP control registers, buy writing bytes to the VDP control port...

The first byte is the new value... the second byte is the register number + 128 (bit 7=1)

We have to set up the VDP's registers so that when we out data to the VDP it will be written to memory.

We do this by writing the R0 memory address to the Control port... we add 4000h to the address to tell the VDP we want to WRITE not read data.

We also have a 'GetVdpScreenPos function' this calculates the Vram tile pos from an X,Y position.
Each line is 32 tiles - so we multiply the Ypos by 32
We then add the tilemap base 1800h
We're defining a command for bulk transfer called OTIR... this will transfer a sequence of bytes to VRAM
(OTIR is OutIncRepeat from the Z80 command set)
We import our Bitmap data, and have our color data defined as bytes - each tile needs 8 bytes - and each 'horizontal strip' is 6 tiles.

Color can be set for each 8x1 pixel area (8 pixels wide, 1 line)...
Color definitions start at memory address 2000h... the 8 lines of color definitions for  each 8x8 block are lumped together, so we separate out the last 3 bits of C, and add them last.

Each byte defines a foreground and background color... foreground in the first nibble, background in the second... &FB

The color palette is fixed, and there are no brightness or other limitations (unlike the speccy!)
0 1 2 3 4 5 6 7
8 9 A B C D E F
Note: Color 0 is transparent.
We have our bitmap data and color data to transfer to VRAM... we use OTIR to transfer the bitmap and color data.

When we want to draw the Chibiko bitmap, we will use the 'FillAreaWithTiles function...  this takes an XY position in R3,R4, a Width and Height in R5,R6, and a start tile number in R7...

The effect of this routine is to build the chibiko character out of tiles.

0 1 2 3 4 5 6 7 8 9

2             128 129 130 131 132 133      

134 135 136 137 138 139

140 141 142 143 144 145

146 147 148 149 150 151

152 153 154 155 156 157

158 159 160 161 162 163

Here is the result.
The TMS9900's color graphics are rather odd really, as it uses as much data for the color map as the bitmap... if you want to see it used 'properly' please take a look at the Grime Z80 project... which has line level color info for it's tiles...

of course you can always cheat, and set all 8 lines of a tile to the same color, like ZX spectrum color attributes!

The TMS9900 can also do hardware sprites, but we're not covering them here.
Lesson P2 - Joystick and Key Reading on the TI-99 with the CRU
Like many systems the Joystick is part of the Keyboard on the TI99, unlike many systems the TI-99 keyboard has to be read with some 'special commands' via the CRU

the 'CRU' is a special connection between the TMS9900 and external peripherals (a bit like OUT on the Z80) - we have to use Register 12 to transfer data between the processor and the CRU, it effectively selects the 'port' of the CRU we want to read from or write to.


TI Key Map

To select a column of the Keymap we use CRU Address 0024h, we can then read in from the address 0006h
We can read a whole column into R4 with ST R4,8
We can test a single bit with TB n - where n is the bit (offset from 0006h) to test 

CRU Address Col 0 Col 1 Col 2 Col 3 Col 4 Col 5 Col 6 Col 7   Bit  
0006h = . , M N / J1-Fire J2-Fire 0
0008h space L K J H ; J1-Right J2-Right 1
000Ah enter O I U Y P J1-Left J2-Left 2
9 8 7 6 0 J1-Down J2-Down 3
000Eh fctn 2 3 4 5 1 J1-Up J2-Up 4
0010h shift S D F G A

0012h ctrl W E R T Q



Reading a whole column of the keyboard

R12 is used to select the CRU address...

First we select address 0024h - we use this to select the column we want to read.
We transfer a column number (0-7) with LDCR - we need to transfer 3 bits.

Now we need to select the start of the keyboard rows... 0006h
We can now transfer 8 bits to a register with STCR - this read an entire column of the keyboard into that register.
The example here reads each column, showing it to the screen as hex and binary.

In this example Space,Enter and X are held down..

Space and Enter are shown on the top line as 0 (2,3 bits of Col 0) ... X is on the 2nd line (7th bit of Col 1)

Testing a single button of the Joystick

Rather than read the whole column, maybe we just want to test one button, for example if we want to check if Joy1 Up is pressed.

As before, we select a column of the keyboard with R2 (Column 6 - Joy 1)
We transfer this to the Keyboard column select with address 0024h

We then select the address 0006 again... This time rather than using STCR, we test bits of the CRU data with TB... in this case we test bit 4... since we selected Column 6 - this tests UP
This example will show an ! when UP is pressed.
The CRU is a bit weird - it can only use register R12 - and it has special commands and it's own address space... it's used by the keyboard and a few other bits of hardware... but strangely not for the VDP or sound chip - which are memory mapped... therefor we won't actually need it much.

Lesson P3- Sound with the TMS9919 on the TI-99
The TI-99 uses a sound chip called the TMS9919 - its' similar to the sound chip of the Genesis and Master System...

In this lesson we'll create a TI99 version of 'ChibiSound'... the simple sound FX 'driver' I use in my programs.... ChibiSound takes a byte in R0 - and uses 1 volume bit... one 'Noise' bit... and 6 tone bits.

Basics of the TMS9919
The sound chip takes all its data from a single 8 bit port... at memory mapped address 8400h
The 7th bit is the 'latch bit' which tells the chip if a new command is being sent (1) or a second part of the last command (0)
Bits 6 and 5 are the channel number... 0-2 are tone chanels, 4 is the noise channel
Bit 4 is the 'Type bit'... 0 defines the sound... 1 defines the Volume

The purpose of the remaining bits (0-3)  vary depending on the first 4

Command Bit Details  7  6  5  4  3  2  1  0
Format Template L=Latch C=Channel T=Type XXXX=Data L C C T D D D D

Tone - Command 1/2 C=Channel L=tone Low data 1 C C 0 L L L L
Tone - Command 2/2 H= High tone data (Higher numbers = lower tone) 0 - H H H H H H
Volume C=Channel (0-2)  V=Volume (15=silent 0=max) 1 C C 1 V V V V
Noise Channel (Channel 3)  M=Noise mode (1=white) R=Rate (3=use tone 2) 1 1 1 0 - M R R

Here's ChibiSound!
The sound port is 8400h... we load this into R1 - this means we can send sound data to reg *r1

First we silence the sound chip - we need to do this by setting the volume to 15 (higher is quieter)... we define a volume setting with bit 4- the volume is defined by the bottom 4 bits... the channel number is bits 5 and 6

Chibisound uses two channels... channel 2 for tones and channel 3 for noise.

Chibisound uses a 1 byte parameter in R0 - if it's zero, then we're done, as we're not playing any sound
We're going to set the volume of Channel 2 - to do this Bit 7 and Bit 4 need to be 1.

What happens next depends on if we want to make a tone or a noise
If we're making a tone we'll set up the tone channel pitch... to define the tone we first write a byte with bit 7 as 1, and bit 4 as 0... the bottom 4 bits are the low bits of the tone... we're defining channel 2

Next we send the second byte - with bit 7 as 0 - bits 0-5 are the high bits of the tone.
If we're making a noise then we need to do two things. We need to set up channel 3 for noise - but channel 3 will be linked to channel 2

There fore we still need to set the tone of Channel 2 (though we'll mute it)

We then set up the noise - we set the noise type to 1 which means White Noise... we set the rate to 3 which means the rate is taken from channel 2

finally we silence channel 2 and set the volume for channel 3
If we're feeling clever, we can use the TI99 sound chip to play digital samples... this was previously covered in the z80 series on the SMS (basically the same chip)... take a look here


View Options
Default Dark
Simple (Hide this menu)
Print Mode (white background)

Top Menu
***Main Menu***
Youtube channel
Introduction to Assembly (Basics for absolute beginners)
Amazon Affiliate Link
AkuSprite Editor
Dec/Bin/Hex/Oct/Ascii Table

Alt Tech
Please note: I wlll upload more content to these alt platforms based on the views they bring in

Z80 Content
***Z80 Tutorial List***
Learn Z80 Assembly (2021)
Learn Z80 Assembly (old)
Hello World
Simple Samples
Advanced Series
Multiplatform Series
Platform Specific Series
ChibiAkumas Series
Grime Z80
Z80 Downloads
Z80 Cheatsheet
DevTools kit
Z80 Platforms
Amstrad CPC
Elan Enterprise
Gameboy & Gameboy Color
Master System & GameGear
Sam Coupe
ZX Spectrum
Spectrum NEXT
Camputers Lynx

6502 Content
***6502 Tutorial List***
Learn 6502 Assembly
Advanced Series
Platform Specific Series
Hello World Series
Simple Samples
Grime 6502
6502 Cheatsheet
DevTools kit
6502 Platforms
Apple IIe
Atari 800 and 5200
Atari Lynx
BBC Micro
Commodore 64
Commodore PET
Commander x16
Super Nintendo (SNES)
Nintendo NES / Famicom
PC Engine (Turbografx-16)
Vic 20

68000 Content
***68000 Tutorial List***
Learn 68000 Assembly
Hello World Series
Platform Specific Series
Simple Samples
Grime 68000
68000 Cheatsheet
DevTools kit
68000 Platforms
Amiga 500
Atari ST
Neo Geo
Sega Genesis / Mega Drive
Sinclair QL
X68000 (Sharp x68k)

8086 Content
Learn 8086 Assembly
Platform Specific Series
Hello World Series
Simple Samples
8086 Cheatsheet
DevTools kit
8086 Platforms

ARM Content
Learn ARM Assembly
Learn ARM Thumb Assembly
Platform Specific Series
Hello World
Simple Samples
ARM Downloads
ARM Cheatsheet
DevTools kit
ARM Platforms
Gameboy Advance
Nintendo DS
Risc Os

Risc-V Content
Learn Risc-V Assembly
Risc-V Downloads
Risc-V Cheatsheet
DevTools kit

MIPS Content
Learn Risc-V Assembly
Platform Specific Series
Hello World
Simple Samples
MIPS Downloads
MIPS Cheatsheet
DevTools kit
MIPS Platforms

PDP-11 Content
Learn PDP-11 Assembly
Platform Specific Series
Simple Samples
PDP-11 Downloads
PDP-11 Cheatsheet
DevTools kit
PDP-11 Platforms

TMS9900 Content
Learn TMS9900 Assembly
Platform Specific Series
Hello World
TMS9900 Downloads
TMS9900 Cheatsheet
DevTools kit
TMS9900 Platforms
Ti 99

6809 Content
Learn 6809 Assembly
Learn 6309 Assembly
Platform Specific Series
Hello World Series
Simple Samples
6809/6309 Cheatsheet
DevTools kit
6809 Platforms
Dragon 32/Tandy Coco
Fujitsu FM7
TRS-80 Coco 3

65816 Content
Learn 65816 Assembly
Hello World
Simple Samples
65816 Cheatsheet
DevTools kit
65816 Platforms

eZ80 Content
Learn eZ80 Assembly
Platform Specific Series
eZ80 Downloads
eZ80 Cheatsheet
DevTools kit
eZ80 Platforms
Ti84 PCE

IBM370 Content
Learn IBM370 Assembly
Simple Samples
IBM370 Downloads
IBM370 Cheatsheet
DevTools kit

Super-H Content
Learn SH2 Assembly
Hello World Series
Simple Samples
SH2 Downloads
SH2 Cheatsheet
DevTools kit
SH2 Platforms

PowerPC Content
Learn PowerPC Assembly
Hello World Series
Simple Samples
PowerPC Downloads
PowerPC Cheatsheet
DevTools kit
PowerPC Platforms

Work in Progress

Misc bits
Ruby programming

Buy my Assembly programming book
on Amazon in Print or Kindle!

Buy my Assembly programming book

Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!

Buy my Assembly programming book
on Amazon in Print or Kindle!

Buy my Assembly programming book

Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!