Tuesday, December 1, 2020

If at first you don't succeed boil it in acid

In a previous post we discussed extracting TMS32010 ROMs optically. This information helps the arcade community better understand these cabinets for repairs and historical reference. In this post we investigate later generation TMS320 using a combination of electrical test interfaces and microscope images.

The first generation Digital Signal Processor (DSP) chips in the first post were succeeded by the TMS320C10 and then the TMS320C25 as seen above. This is Namco Winning Run's TMS320C25FNL (decap G82) which was extracted via a similar decapping and imaging process as TMS32010. It's part of Namco System 21 where it accelerates 3D graphics operations. Additional analysis will give the community a much deeper understanding of how the graphics engine works. Special thanks to Nathan Gilbert for converting microscope images into firmware!

TMS320C25 was then succeeded by TMS320C5X which is the focus of this article.

The origin of the TMS320C5X project is a TMS320BC53PQ80 found on Taito Operation Tiger. Similar to the Winning Run TMS320, Operation Tiger uses TMS320 as part of it's graphics engine and detailed analysis will help the community understand how it works. This was thought to possibly be a straightforward project as these chips have several digital interfaces that might be used to quickly extract firmware.

To make things easy we got a TMS320C5X DSP Starter Kit (DSK) development board with matching software. It has a very similar part (TMS320C50 vs TMS320BC53) in the same footprint which should allow us to run some tests and then transplant the target chip onto the DSK board.

This is roughly our understanding of how the intended development flow works:

  • Tiny mask ROM firmware loads an external PROM
  • External PROM knows how to talk to serial port
  • DOS system downloads debug kernel over serial port
  • Debug kernel can load additional programs
We can omit the last step since we just need to send simple commands to the debug kernel. Let's see if we can get that running.

The big catch is that the software runs on DOS with unusual serial port settings (ex: 2 stop bits) which caused some setup issues. The DSK uses this to automatically detect baud rate based on timing between the first command data bits and the stop bits. In the end, VMWare with an FTDI adapter did the job.

Once the software is up it's relatively straightforward as there are commands to dump memory to files. The only catch is that they have a bug/feature where address 0 can't be saved, but can be seen in the visual display. So we save most of the data and then manually patched the word at address 0. And so we have the TMS320C50 bootloader!

Now to try the same thing but with TMS320BC53.


However we weren't sure if this would work as the external PROM firmware was written for TMS320C50 which has a different address layout than TMS320C53.

We swapped the chips and unfortunately it's not working. We put a logic analyzer on and are able to show that DOS is communicating with the board but then something goes wrong. Specifically above shows PROM memory fetches changing in response to serial port data. We can possibly adjust the PROM firmware but there are a few more options to explore.

What about JTAG support? Even if this works we have a few chips that support JTAG but not the bootloader (ex: Winning Run). So seems like a good excuse to investigate that.

Unfortunately while these chips attempted to support JTAG there are several major issues. First, their JTAG implementation is non-compliant, making it incompatible with many adapters. Second, when it does work it's very bare bones and doesn't even support common instructions like IDCODE.

Most importantly though even with the right adapter the software is very difficult to setup. The only reference we could find involved patching a very specific version of Code Composer Studio version 3. And even then this probably only gave you TMS320C25 support which we'd then have to extrapolate to TMS30C50.

We tried to find some older DOS software that might support some form of XDS510 (such as the original ISA card above) but were unsuccessful. Since completing this project we have received additional software that might help if we encounter more TMS320. That said, if you have more TMS320 software, especially related to JTAG, we'd love to hear from you.

Anyway this means JTAG is not going to be easy. In the spirit of moving forward we begrudgingly decapped the chip and imaged the ROM.  While somewhat labor intensive this has a relatively straightforward path to completion.

Official designation is TMS320C53CS programmed with ROM D17336.

Zooming in on the ROM you can see it's very sparsely populated: there are a few bits at the top middle, and a few at the bottom. This makes sense as it only has a minimal bootloader and the vast majority of the code is in the external PROM.

A few puzzles though. First, why do the empty areas alternate 1's and 0's? Second, why is code split between the top and bottom? Fortunately we have the ROM from the TMS320C50 which significantly accelerates decoding. Take this section after the initial firmware:

00000270  be 4d bf b0 00 ff 6d 68  90 68 be 1f a7 68 b8 01  |.M....mh.h...h..|

00000280  be 1e 7b 90 01 31 69 66  be 20 be 4d e0 00 01 46  |..{..1if. .M...F|

00000290  be 4c ec 00 79 80 01 49  ff ff ff ff ff ff ff ff  |.L..y..I........|

000002a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

000002b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

000002c0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

000002d0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

000002e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

000002f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00000300  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

00000310  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

We can see the transition from normal firmware to an alternating 1/0 fill pattern. While it's unclear why they do this, it's likely this is the actual ROM pattern as opposed to say obfuscation. Our best guess why they do this is that it plays a similar role to CMP fill on planarized ICs. That is, if it was filled with one polarity it would deviate a lot more from normal data and could cause yield issues. We couldn’t find an introductory article to link, but check out something like this for more information.

Anyway, also note our TMS320C50 dump has a footer:

00000f00  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

00000f10  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

00000f20  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00000f30  00 00 00 00 00 00 00 00  00 00 bc 00 5d 07 00 30  |............]..0|

00000f40  ae 11 00 00 8b 8d bf 0d  80 00 bb 02 a5 a0 07 fd  |................|

00000f50  f4 00 5d 6a 80 00 5d 26  02 f0 5e 26 ff ef b9 f8  |..]j..]&..^&....|

00000f60  88 22 88 32 ae 21 a5 96  ae 31 59 a3 b4 01 be c5  |.".2.!...1Y.....|

Sometimes chip memory gets divided into pages to break up memory into small sections. It looks like TMS320C50 has one page and TMS320BC53 has four pages, so we think these might be page footers.

With this in mind Nathan Gilbert did the heavy lifting here. First he decoded the four pages separately and munged until they roughly resembled the TMS320C50 data. We then compared footers between pages and found bits to order the pages as labeled above. These bits are believed to be an absolute address as part of an assembly routine but significant analysis has not been done.

Now with the ROM decoded we can compare TMS320C50 and TMS320BC53. While the main firmware is identical the footer has a number of differences. We don't believe anyone has yet looked into specifics.

Finally, there was a brief effort to decode an unknown TMS320C52 wafer with a large amount of firmware. Someone attempted to use computer vision to automatically extract the bits but it was ultimately abandoned due to some combination of insufficient data quality and low perceived impact of having a successful decode.

That about wraps it up. Lots of people helped complete this project! Special thanks to the following:

  • Nathan Gilbert: decoding, bit typing
  • jordigahan: board purchase
  • ClawGrip: board purchase
  • Montornés Solé: board purchase
  • Philip Åkesson: bit typing
  • James Sun: bit typing

Enjoy this post? Please support us on Patreon or follow us on TwitterNote: with the Indiegogo campaign over we unfortunately don't currently have a way to accept one time donations.

Wednesday, November 4, 2020

Extracting the elusive TMS32010 mask ROM

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:


  • 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:

01 10 10 10
00 10 01 11
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:
  • 0xE
  • 0x1
  • 0xA
  • 0xC
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.

Enjoy this post? Please support us on Patreon or follow us on TwitterNote: with the Indiegogo campaign over we unfortunately don't currently have a way to accept one time donations.

Wednesday, September 16, 2020

Macroprobing a fried Dardomania EPROM

Source (actual unit)

Dardomania is a dart throwing game from Sleic. Main circuit board:

There are a few EPROMs seen with stickers. Unfortunately one of the EPROMs, marked in purple, is behaving erratically. Upon closer inspection:

The VCC bond wire is broken. Unfortunately it's not just snapped but rather has balled up. This implies it melted from excessive current and the die itself may be damaged. If this is the case the data may still be there but it would beyond our current capabilities to extract.

So how can we show the chip is still salvageable?

  • Run small test currents through I/O ESD diodes to verify they still function. This will help find gross damage on the chip by verifying bond wires and ground is intact
  • Inspect die, especially around the melted wire, for damage
  • Power VCC, carefully monitoring current draw

Fortunately VSS is still intact which makes running the ESD diode test simple. It produced promising readings indicating most I/Os at least were intact.

Next we sawed off the top of the EPROM to reveal the bare die:

We used a diamond saw to cut the majority of the window away. The chip is soldered into a socket, filled with nail polish to protect the die, and then the center is mechanically sheared off:

Unfortunately this caused 2 more bond wires to come loose and now three need to be reattached. This is believed to be caused by the new procedure using a socket. The vise didn't grip the package as firmly and led to some slop during shearing. We believe using the socket is the right direction (strengthens pins during and after shearing) but in the future need to grip the package directly even if it's socketed.

Unfortunately aluminum wires have a non-conductive oxide surface that makes repairs more difficult. For example, while silver conductive epoxy bonds well to gold it doesn't to aluminum. This leaves two primary options:

  • Use wire bonder to place new wires
  • Microprobe the pads

Wire bonders are finicky and if you aren't careful you can damage the chip. So we elected to probe the pads instead of attaching new wires.

Anyway, we inspected the die and didn't see anything alarming. For example here is what damaged I/O can look like:

With this out of the way, next step is to power up the chip. We probed VCC and put the EPROM into a high end chip reader that monitors for excessive current. We omitted probing the other two pins as they were just address/data. Somewhat to our surprise the read went normally: no overcurrent and plausible looking data came out!

So next we added a few more probes to get the other pins connected. This process is relatively straightforward as bond pads are relatively large ("macro") vs traditional microprobing.

Unfortunately data did not come out reliably. Fortunately data analysis indicates read errors are closer to random noise than fundamental issues. We repositioned the probes for better contact and data began reading reliably! We compared the new stable result to older reads and found all older reads are just a few bits away from the new stable version. Success!

Finally preliminary inspection of the EPROM data vs the others in the set looks reasonable. Testing on real hardware is pending and we'll post a small update once its verified.

In other news we have also started more serious microprobing but a lot more effort is required before we get usable results. We also extracted some PICs:

These include:

  • Gaelco F3 Hardance (PIC16C56)
  • PUZZLE ME (PIC16C54)
  • Magic Card Export 94 (PIC16C54)
  • Magic Card Wien (PIC16C54A)
  • Bingo Roll / Turbo Bingo (PIC16C54)
  • Mystery chip "unkte06" (PIC16C56)

We also tried laser glitching some PIC16F84s but were unsuccessful. We've had success in the past and believe this is a test setup issue. We'll retry in the near future with a different laser.

Enjoy this post? Please support us on Patreon or follow us on TwitterNote: with the Indiegogo campaign over we unfortunately don't currently have a way to accept one time donations.

Saturday, April 18, 2020

Help us preserve the original Furby!

Update 2020-04-27

Given submissions have tapered off we've taken down the server. Thanks to all that have contributed so far! We'll let everyone know when more information is available.

Update 2020-04-26

Thanks to all of those who have contributed! We've been running for about a week, and results have leveled off around 80% complete and currently around 84 complete%. We've now have some statistics and a few proposals.

Some basic statistics:
  • Pages: 297
  • Lines: 19510
  • Page submissions: 744
  • Line changes (roughly): 10297
  • Change 2/3 agree: 9191
  • Can't 2/3 agree: 1106
Of those 297 pages, we have all of them with at least two submits and about 50% have three submits. These results were combined to result in about 50% of lines flagged for adjustment. Of those suggestions, about 89% of agree. Based on existing data, getting all 3 sets of challenges completed will reduce that to about 600 still requiring manual review.

A few more advanced heuristics were also tried (ex: partial line matching, weighting user results based on how much we trust their results), but ultimately wasn't convinced any of these are the right approach.

So, where does this leave things? Two main options are being considered:
  • Push the annotated source to github or gitlab as is. We estimate that it would take someone about 6-12 hours to fix, which is not intractable. Default would have been the furby-source repository on github, but they have stopped responding
  • Restart the crowdsource server using the best result with annotated conflicts. Users would need to delete the extra lines and submit. However, we suspect users need a break, so at a minimum we would probably hold off a few months to regain momentum
Note we suspect additional fixes will be required upon eventual manual review, whichever path is taken. Generally the first option seems like the best. A few dedicated users could knock this out fairly quickly without too much coordination. If we get a few volunteers (or one very dedicated volunteer), we'll figure out where to push this and move the project forward. Ideally one of these people would also be interested in coordinating other community contributions.

So we're asking if people are interested in the first option and we'll likely default to the second if we don't get traction. Please let us known here in the comments or on Twitter!

Update 2020-04-20

Higher quality .pngs have been swapped in after reports that compression is swapping letters (!). Special thanks to Video Game Preservation Collective for the above image! The old set was from the text annotated version while the new set is believed to be the original scan. Unfortunately these images are about 5x larger, but should improve accuracy.

Also now we've done a very crude analysis of the existing submits and used them to make a quick guess at better default text to present. This effects about 85% of entries. So going forward you'll typically get higher quality defaults. But please still be attentive and look for errors!

There have also been a few backend tweaks, notably favoring showing pages with fewer submissions. However these generally should not be visible externally.

Update 2020-04-19

We're up to 197 submissions! Thanks to all of you that have posted so far! We need to meet a minimum of 297, so we're making great progress. Our goal is to get 3 submissions to help correct errors, for a total of 891.

We will briefly bring down the site for maintenance at 2020-04-21 6:00 AM. We will use this window to improve the default text based on submissions so far. This should make challenges much easier as mostly you'll only need to do small corrections instead of large edits. We will also fix the overall progress indicator, which currently says 1485 required, but it should be 891.

Once again, thanks for your help and please let us know if you have any feedback!

Micro update: the progress indicator fix has been pushed out (it was not necessary to bring the server down)


The Furby is an iconic talking toy from the late 90s. A couple of years ago scans of the original Furby source code were acquired. Unfortunately the scans are noisy and automatic image to text conversion is difficult. So we're asking the community to help preserve game history by proofreading computer generated transcripts. Generating a proper copy of the Furby source code will be enormously valuable to understanding how it works!

Project TLDR:
  • Complete using your web browser
  • You need a large screen (laptop or desktop)
  • Scanned image at left, noisy text interpretation at right
  • Fix errors in the image to text translation and submit
  • Remove headers and footers (ex: "Page 6", "A-121", "Diag7.asm" ) 
  • Unreadable: put best guess if possible, or random characters as last resort (will flag for review)

Although the crowdsourcing system wasn't a good fit for Great Swordsman, it spurred some conversations on what it could be used for. It has been revived and adapted to work on improving pdf image to text conversion.

Join the effort by signing up for an account! If you had an account on the previous TGP project, it likely is still available. Additional instructions are available after creating an account. If you have some time, please try a few images!

Finally, the person who gets the most pages accepted (ie with acceptable accuracy) will get early blog access for 3 months! Note however you must provide your e-mail address to qualify so that we can actually send it to you.

Sounds good? Sign up here! Instructions are available after logging in.

Note: due to various issues we are unable to split the pages into smaller tasks. So the images are relatively large and this is best completed on systems with a large screen such as a laptop or a desktop. So apologies if you only have mobile, but you may not be able to help with this specific project.

Special thanks to Andrew Gardner for writing the original tool and John McMaster for recent modifications!


We'd also love if you have suggestions for improving the work flow. These are things already on our mind:

Q: What happened after the last crowd sourcing project? (Fujitsu DSPs / TGPs)

A: Post processing took a while, but it ultimately led to massive improvements on how well the community understands these games. However we've been doing a poor job at communicating those results and still need to write a post about it. See for example this MAME post which mentions recovering "...the Sega Model 1 coprocessor TGP programs for Star Wars Arcade and Wing War, making these games fully playable."

Q: Can you make the challenges smaller?

A: Not easily. The pages aren't well aligned, we'd need to both figure out correct straightening and cropping

Q: Can you align the text editor to the images better? Maybe rich text features like find and replace?

A: While the chip community can unlock the secrets of the micro universe, we can't code websites for beans. Really it's a miracle that the site is running at all. If you can help with improving text entry, please reach out! FYI its written in Python/Django and could use some cleanup. If you haven't been scared off, more info is here

Q: What happens after its captured?

A: First we'll post process to remove errors. After that we'll use the CPU manual to make a special 6502 assembler to create a binary. Ideally we'll also combine this with the Furby 70-800 ROM microscope images (sample above) at some point.

Q: Where did the source come from?

A: Not sure exactly, but some information is available at the Internet Archive

Q: Can I edit my result after submission?

A: It is not possible to modify it at this time. But don't worry, most of the time we can detect errors by combining a few results.

Q: Can you reset my password?

A: Yes, but it requires manual admin intervention. We suggest creating a new account if you aren't really tied to your old one

Q: Isn't that Furby image for the Furby 2012, not the original Furby?

A: Maybe... Actually we have a 70-800 image now


More questions? Type them below, or reach out to us on Twitter. Thanks again for your help!

Tuesday, April 14, 2020

You are great swordsman!

Great Swordsman (not to be confused with Hiro Protagonist) is a Taito arcade game where you engage in various styles of sword play ranging from fencing to samurai combat.

The game firmware is comprised of Z80 EPROMs, AA-013, AA-016, and AA-017. The EPROM is easy as Z80 architecture is well understood and EPROMs are trivial to extract. However, little was known about the last three. Collectively though they handle things like getting player inputs, reading DIP switches, and tracking coins.

Previous decapping showed that AA-013 is an Intel D8741A.

Unfortunately it was received with severe damage which discouraged us from looking at it.

We then decapped AA-016 (#8) and AA-017 (#9) which are both NEC D8041AH. Fortunately neither NEC D8041AH nor Intel 8741A have protection schemes, so in theory we can simply read the data out. Unfortunately we were unable to activate the test interface. After some analysis we suspected that the algorithm we tried to dump them with (as 8741 IIRC) might have over-voltaged EA and damaged them. More on that later.

Unfortunately the EPROM based 8741A is difficult to read as is. But D8041AH are contact ROMs which traditionally we've been reasonably successful with (example). So we attempted to visually read them but got a lot of errors. It was hard to read the bits and attempting to disassemble them resulted in something only vaguely reassembling a valid program.

So due to the combination of noisy bits and severely damaged chips the project essentially got shelved some time ago. However somewhat recently we got another chip set and a little later there was a forum post asking about the state of the project. In general lockdown and with a little more time right now, this prompted us to take a second look. These acquisitions ultimately gave us 3 ROM sets to work with: the original STARRIDER set via Guru (8/9/10), a set from STARRIDER via Smitdogg (C030/C031/C032), and a set that was separately acquired.

With these extra sets, the first priority was to analyze the test interface and assess if it was healthy. We used small test currents to characterize the ESD diodes on sample chips and compared them to 8741A and 8041AH chips from Great Swordsman. This showed the chips from Great Swordsman consistently have different responses on EA pins vs samples, indicating this pin was likely intentionally damaged to prevent read out.

This may have been a common practice at one time as commercial systems from companies like RunFei have a "special protect" option that does exactly this. We've also seen it on other chips like the NEC D8748D EA pin shown above

So a few options. One is that we may be able to repair or bypass the blown pad. Repair would be easier if we had FIB access but this isn't easily available. We could bypass it but there were misc complications at the time and this wasn't seriously considered. We do however plan on attempting this for AA-013.

That said we figured there was a chance that the test interface *might* still work even if it was damaged. To our surprise we managed to get a plausible dump out of one of the new AA-016s! The interface only worked once or twice and then rapidly deteriorated. Unfortunately due to the test interface instability and some disassembly errors we weren't confident we had a good dump. Finally it didn't remotely match our earlier attempts to decode the mask ROM into binaries. This gave us low confidence that the EPROM dump was correct.

So anyway we at least had an answer: the test interface is not reliable and probably wont't yield anything more. So we decided to revisit brute force ROM capture by photographing bits. How could we improve the accuracy? Let's say the existing capture has about 100 bad bits out of 8192 => about 1% error rate. This means that if you took two of these captures, the expected number of bad bits is about 8192 * 0.01 * 0.01 = 0.8. So while it might not be perfect (say a few bit errors might be expected), it would drastically improve the accuracy to something usable.

With this in mind, few weeks ago we decapped the second ROM set as C031 (AA-016) and C032 (AA-017). And for one reason or another the contrast was considerably better!

We then asked the community to help convert these images into bits. This was broadcast here on this blog, on twitter, and on mameworld. We suggested using rompar, a specialized tool for this task, although in general it wasn't easy enough for people to setup. There is an open ticket about easier Windows support which the rompar team has been working on addressing.

That said, we got a combination of submissions in rompar, typed as .txt files, or even as colorful spreadsheets (AA-017 above, other images are AA-016).

One lesson learned is that we should have aligned all of the image sets (or at least C031 and C032). This would have made some of the post processing easier as sometimes we were trying to resolve bits by comparing several different image sets.

Anyway, once we got around 3 submits for each set we did a cursory inspection on each set to gauge the submission quality. If the submission is reasonable (say 99%+ accurate), we then add it to the submission pool. Then all of the locations in the pool that didn't fully agree with the entire ROM pool are flagged for review and displayed in rompar. After reviewing these we got ROMs that we think are probably within a few bits of being correct.

D8041AH datasheet

But unfortunately we have a problem: the ROMs still don't disassemble well. So next we read up a bit on MCS-48 architecture and learned that the interrupt vectors are at the start of the chip: 0, 3, and 7. Usually these are comprised of either a jump (typically LJMP, 0xX4 0xXX, or RET 0x83). Here's the start of a sample keyboard BIOS ROM:

00000000 04 08 00 83 00 00 00 83 15 23 f0 90 85 95 22 14 |………#….“.|

Here you can at 0x0000 (reset) there's JMP 0x008 which skips over the reset of the vector table. Similarly there's RET on the other vectors to basically ignore them.

With that in mind, here's the start of our old AA-016 microscope based submit:

00000000  40 d9 96 a9 fa 03 1f aa  e8 a8 04 13 04 d8 04 e0  |@...............|

Hmm there are some 4's in there, but doesn't really look valid. For comparison though, here is the AA-016 EPROM submit:

00000000  04 08 00 83 00 00 00 83  15 23 f0 90 85 95 22 14  |.........#....".|

Aha! This looks much better. So we started thinking: maybe the ROM decoding script doesn't really work? It is producing mostly valid disassembly, but maybe we missed something? The scheme was relatively complicated and its entirely possible something was missed.

So after some munging, we came up with a new physical address space layout. Now AA-016 starts with:

00000000  04 08 00 83 00 00 00 83  15 23 f0 90 85 95 22 14  |.........#....".|

Aha! Now this matches the EPROM dump. In fact we verified against the original EPROM dump and decided it is 100% accurate.

But there's still one more problem: if the EPROM dump is good, why didn't it disassemble properly? Why did we get told the submitted dump was unusable? First, the unusable dump was probably someone talking about the earlier AA-016 dump vs the newer EPROM dump. Second, although we tried several ways to disassemble the dumps (notably MAME,  Ghidra, but also some others), they generally were biased towards MCS-48 (classic 8048) and not some of the finer points of UPI-41, the family D8041AH is from. One source described it as “The 8042 and 8041 is code compatible with the 8048, except that there are no external program memory instructions, and that data bus register instructions have been added.” For example, Ghidra 8048 gave:

CODE:0008 15              DIS        I
CODE:0009 23 f0           MOV        A,#0xf0
CODE:000b 90              MOVX       @R0,A
CODE:000c 85              CLR        F0
CODE:000d 95              CPL        F0
CODE:000e 22              ??         22h    "

MAME mcs48 gave:

unidasm -arch mcs48 great_swordsman_aa-016_d8041ah_decap-c031.bin
0:008: 15     dis  i
0:009: 23 f0  mov  a,#$F0
0:00b: 90     movx @r0,a
0:00c: 85     clr  f0
0:00d: 95     sel  an1
0:00e: 22     illegal

But really should have been upi41:

unidasm -arch upi41 great_swordsman_aa-016_d8041ah_decap-c031.bin
008: 15     dis  i
009: 23 f0  mov  a,#$F0
00b: 90     mov  sts,a
00c: 85     clr  f0
00d: 95     sel  an1
00e: 22     in   a,dbb

Which looks good!

So to summarize, the hurdles were:

  • Intentionally damaged test interface
  • Possibly unintentionally damaged test interface
  • Noisy microscope images
  • Not using the right disassembler
  • Getting people to look at the data
  • Incorrect address decoding

Finally, there were a lot of people that helped with this project. Some of them include:

  • Our Patreon contributors
  • STARRIDER: chips, ROM capture
  • rompar team (John McMaster et al): software support
  • EdHunter: ROM layout decoding
  • Guru: logistics
  • Smitdogg: logistics
  • f205v: ROM capture
  • sadikyo: ROM capture
  • belegdol: ROM capture

Enjoy this post? Please support us on Patreon or follow us on TwitterNote: with the Indiegogo campaign over we unfortunately don't currently have a way to accept one time donations.