When reviewing the electronic boardgame Dark Tower, I learnt that it was programmed using one of the TMS1000 series of microcontrollers. I’ve since fallen in love with this little processor, discovering that it powered so many other electronic games from my childhood as well: Big Trak, Electronic Battleship, Merlin, Simon, Speak & Spell, etc.
The TMS1000 was the first microcontroller. Being first, TI didn’t even call it a microcontroller, but a microcomputer (a term later coopted by 8-bit personal computers). It grew out of the TMS0100 single-chip calculator family, created in part because a TI executive was sick of how much business travel he had to do for custom ICs for calculators. Steven Leibson describes the chip:
As with many first-of-a-kind devices, the Texas Instruments (TI) TMS0100 calculator chip family was a narrowly defined microcontroller, mostly good for making calculators. However, the first chip in the TMS0100 family…incorporated everything a microcontroller requires to be a microcontroller: a CPU, RAM, ROM, and I/O. Granted, it was a specialized microcontroller. Its I/O was application-specific and designed to be attached to a matrix keyboard and a seven-segment display. Nevertheless, the TMS1802NC was a microcontroller.
…These chips quickly took over the calculator market. TI suddenly had all-new worlds to conquer. The company quickly realized that it could serve multiple markets with the same programmable silicon if that silicon could be engineered to be sufficiently general. TI applied what it had learned from the family of devices it built from the original programmable calculator chip to produce its first line of general-purpose microcontrollers, the TMS1000 family, which it announced in 1974.
Cameron Kaiser provides a concise technical summary:
The 1970s birthed a lot of odd microarchitectures but the TMS1000 family is surely one of the strangest. The TMS1000 has a 4-bit accumulator (A), a 4-bit Y register (Y), a 2-bit (three in the TMS1100) X register (X) as the RAM page address register, a 6-bit program counter (PC), a 6-bit subroutine return register (SR, i.e., the link register), a one-bit call latch (CL) to prevent the SR from being accidentally overwritten, a 4-bit ROM page address register (PA), a 4-bit ROM page buffer register (PB, also used with the subroutine return register), a 5-bit O-output register (O), a single status bit (S) that defaults to true, and a bit each for the R-outputs indexed by Y (R(Y)). (The K-inputs are read with specific instructions.)
How underpowered is this? It can only address 32 bytes (bytes, not kilobytes!) of RAM (64 nybbles). Again, how underpowered is this? This ASCII sentence is 32 bytes!
With that much RAM, if you’re designing a calculator, you could store 10 digits (10 nybbles) for the current display, 10 digits for the prior number, 10 for any M (Memory) value, and still have 34 nybbles to spare for scratchpad or working processes.
No surprise given its calculator heritage that the TMS1000 used Simple Binary-Coded Decimal (SBCD), which avoids the need to convert binary digits into ASCII representations (converting binary to ASCII is a well-established algorithm, but one that took me half of a 1-credit college course to implement in 80286 Assembler). Basically, rather than store binary numbers from 0 to 15 in 4 binary digits (a nybble), instead it stores binary numbers from 0 to 9, which can then drive a seven-segment display. This does mean that when binary addition produces a binary number from 10 to 15, it needs to have 6 added to it (and a carry flag) to push the nybble back into the range 0 to 9. In fact, the TMS1000 has the instruction A6AAC (Add 6 to Accumulator) precisely because this is so common with BCD math!
Floating-point math is also much easier using BCD representations, simply requiring padding the shorter number with zeroes on both sides so that it is of the same length and the decimal points line up. Floating-point binary math, on the other hand, is so complex that Bill Gates and Paul Allen didn’t do it themselves but hired Monte Davidoff to implement such math when they developed Altair BASIC.
A6AAC is not the only oddity in the instruction set of the TMS1000.
Call and branch instructions are always conditional. Most assemblers have unconditional jumps; to save instruction space, the TMS1000 doesn’t. Even worse, you are limited to a single CALL and RETN as there is no stack: no subroutine can call another subroutine.
Here is the entire instruction set:

Here’s an example subroutine from the programmer’s reference manual:

These aren’t registers in the traditional sense, but instead are areas of the 64 nybbles of RAM set aside for seven-digit BCD numbers.

It has taken all my resistance not to code a little emulator for this device. You can use MAME if you really want to play with it.
Bitsavers, as usual, has copies of the documentation.
While primitive by today’s standards, the TMS1000—with its BCD-oriented architecture and limited instruction set—was inexpensive to manufacture in volume, allowing companies to mass-produce electronic entertainment at prices families could afford. Its severe limitations forced programmers to be incredibly creative, squeezing engaging gameplay out of just 32 bytes of RAM and a handful of instructions, somehow sufficient to create worlds of adventure, competition, and fun! The next time you spot a vintage Merlin or Simon game at a thrift store, take a moment to appreciate the humble microcontroller inside that helped usher in the age of digital play.
Photo credit: Binarysequence.
You must be logged in to post a comment.