In the late 1970s Texas Instruments made the TMS5100 for the Speak and Spell. This special purpose processor could quickly do math operations required for speech synthesis. This is an early form of Digital Signal Processing (DSP) where code creates signal digital filters instead of using discrete components like capacitors and resistors. Following the success of that project they looked into higher performance DSP architectures which resulted in the TMS320 family being released in the early 1980s.
This was welcome news to game designers of the 1980s. Arcade machines require a wide variety of high performance audio and video processing. Unfortunately CPUs of the day were relatively slow meaning cutting edge games required expensive custom logic made with large circuit boards or custom ASICs. DSPs introduced a new option by focusing on high performance math operations rather than traditional code execution.
Specifically the first generation TMS320 included the TMS320M10, a version with 3K bytes of mask ROM. This was used in a few Toaplan games like Flying Shark (decap G72, G210) and Kyukyoku Tiger (also known as Twin Cobra, decap G71):
More info can be found here. Anyway, here's a TMS320M10 die shot:
Close up of the logo:
Note the die part number is "32010C", not "320M10" as in marketing material. This is similar to how "TMS5100" is a marketing name but its internally a "TMC0280." Also note the second line of text, diffusion on the silicon substrate, matches the package:
Checking out the ROM area we vaguely see bits but with poor contrast:
Zooming in helps a little, but its still pretty hard to read:
Looks like it might be a diffusion ROM and delayering to silicon substrate will improve contrast. This is consistent with D70015, presumably the mask ROM ID, being encoded in diffusion. Die after delayering:
The ROM is now way easier to read:
Now we can also see the contrast issue: the polysilicon and metal was mostly overlaid on the diffusion lines above, hiding most of the detail. Now that the polysilicon and metal is removed the bits can be resolved clearly.
Next the ROM photograph is converted into a 2D bit array so we can figure out the bit order. Usually bit order is very linear, such as grouping bits into columns with the least significant bit at the left and most significant bit at the right. Consider a 4 bit CPU with this ROM layout:
Where:
- B0 means bit 0, the least significant bit and B3 is the most significant bit
- Bits are grouped into columns
- Each bit column starts upper left, scans right, and then wraps around to the next row
Lets say your ROM is typed as:
Where spaces have been added to emphasize the bit columns and the first word is highlighted in bold. Using the decoding scheme above results in the following 4 bit words:
Unfortunately there are many variants on this type of scheme and it may not be obvious which scheme is used in this particular type of memory. However there are a couple of ways to narrow it down:
- Reverse engineer logic and deduce the scheme from first principles
- Make educated guesses
The first always works, but can be a lot of effort. Instead, we usually rely on the fact that most architectures have a few regular patterns that we can look for. For example, here are a few TMS32010 binaries disassembled:
000: f900 0010 b 0010h
002: f900 00af b 00AFh
...
010: 7f8a rovm
011: f500 0013 bv 0013h
000: f900 0004 b 0004h
002: f900 0d96 b 0D96h
004: 7f81 dint
005: 7f8a rovm
000: f900 00d7 b 00D7h
002: f900 0642 b 0642h
...
0d7: 7f8b sovm
0d8: 6e00 ldpk 0
It looks like a pretty good guess for the first word and third word is 0xF900. Let's use this as a heuristic to determine if we have the correct memory layout.
It's also worth mentioning we don't yet know the bit polarity: does a squiggle in the image mean it's a 0 or a 1? One way to intuitively deal with this is to think about things more in terms of bit transitions or hamming distance than the actual values. If using a program to extract the bits we usually try both polarities and see which works better.
Unfortunately we tried a few simple layouts and didn't see 0xF900's coming out. Fortunately Nathan Gilbert volunteered to help and had several major contributions. First, he digitized all three ROM photographs into bits in a .txt file. The bits are then compared between chips which shows where common data is. In particular this gives us a hint which side of the memory layout the initial branch instruction, 0xF900, might be.
Nathan then poured over the bits in great detail but had trouble finding a simple solution. Next he looked at our die shots to see if they provide hints. For example, they show how large memory blocks are and may show things like unusual bit ordering on data buses.
Unfortunately we were still struggling. But we thought we might have a silver bullet: a previous project had decoded the BSMT2000 audio chip, a TMS320C15. Maybe we could dig up this data, study the encoding, and use that to decipher the order?
We found the binary and bsmt2000 scanning electron microscope (SEM) images from Dr Decap:
Unfortunately we didn't find any info on the bit ordering or the intermediate photograph typed bits, but having the final binary and the source image is a good starting point nonetheless.
Zooming in on some bits:
Where bits are represented by contacts shown in bright white. But that's a problem: TMS32010C is a diffusion ROM while TMS320C15 is a contact ROM. This means it may not help decoding TMS32010C.
First, you can figure out high level structure without knowing the exact data. For example, what is the relationship between the top and bottom memory blocks? There are a few ways they could structure this but generally the most simple is to put memories in parallel. This means half of the 16 bit word comes from the top and half from the bottom memory structure. This is a good baseline assumption and turns out to be true for this chip.
Next, the specific column order needs to be figured out. Nathan dug in and matched the reference words (0xF900) to find the bit order roughly looks like this (simplified example with 2 bits):
This ordering is a bit more complicated than previous as column layouts are in mirrored pairs rather than all being identical. Good to know, but unclear if anything that will help with TMS32010C.
Going back to TMS32010C, let's summarize clues we have so far:
- 16 bit words
- Expect first word to be 0xf900
- Know possibly related memory layout
- Hint which side of the die is address 0
- Have several firmware files to try
And then a breakthrough: Nathan notices that decaps 72 and 210, although very similar, have some code inserted in the middle, shifting words to a higher address. This is a crucial key: we have an example of what it looks like to move data to a higher address.
After some serious permuting, intuition, and a little binary magic, Nathan discovers that bytes are permuted according to a table like "7, 2, 6, 3, 5, 4, 0, 1". It appears to be related to some logic in the address decoder itself:
Where we find a very similar, but not identical table. This pattern is repeated all along the bit lines and is likely muxing them in roughly this fashion.
Both the row and column depend on this table, so it makes for a somewhat involved decoding. We tossed around some engineering ideas for why this table might make sense (ex: similar to Gray encoding => may share address lines), its unclear if this is an optimization or an obfuscation strategy.
Anyway, nice! Let's take a look at 71 to verify we have a real binary:
000: f900 0019 b 0019h
002: f900 0020 b 0020h
...
020: 7f81 dint
021: 7000 lark AR0,00h
We see jumps to instructions like dint like seen before, so this seems like a plausible binary. Huzah!
Special thanks to Nathan Gilbert for processing the photographs into binaries! In our next post we'll discuss how we extracted TMS320C5X data using a combination of electronic and decapping techniques.