Teletype 56d battery replacement

April 5, 2020

I got a teletype model 56d from last VCF Midwest for free.  It was just labeled ‘amber CRT’ so I figured I’d take a crack at fixing it/replacing the missing keyboard.  I have found no real information on it, no manual, no schematics, no rom dumps.  There is a small entry on the terminals wiki, but it contains very little info.  There’s an instance of someone repairing the power supply for one, and someone else trying to get it to play nice with Sun hardware, but that’s all I find.  I decided to tear into it to at least see what’s up.


Yes, I added the tape over those windows

I feel like I am super justified in being angry about windowed UV eproms not being covered in a production device.  I dumped all those roms (link forthcoming) and noticed that this runs on a z80 so I have some hope of reverse engineering the code.  There’s also a custom teletype branded chip so maybe not… Among the other stuff I found was one too many rs232 transceiver chips meaning that the keyboard probably uses that as well.  


Three cells

The focus of this entry is on the leaking battery though.  I tore it apart and found three mystery cells.  The markings originally read ‘8711japan’ and ‘406099’ and each cell weighed 6.328 grams.  The battery measured 18M ohms in each direction so it’s effectively an open circuit to the terminal and the terminal put out 8-ish volts to the battery terminals.  With a 51 ohm resistor current limiting it, it was proposed that these may be NiCd cells, much more tolerant of having some current run into them at all times than NiMH (which I was planning on using).


I picked up some AAA sized batteries from amazon and used one of those triple AAA holders from cheap LED flashlights as the place to park them.  With these cells installed the terminal puts 9.5mA into them and it started falling, so I think this was the right fix.


Looking pretty sharp

Now I just need a keyboard, unless I use it solely as a display…

Astrofighter color PROM strangeness

March 26, 2020

While dumping random ROMs and proms in an effort to identify boards Frank and I came across something interesting.  We found two color PROMs that were not able to be identified by MAME, but are very VERY similar to some already in MAME.  The color PROMs in question seem like the one used in Astrofighter but with minor differences.  We ran the game with the different color PROM and in emulation we couldn’t tell the difference so Frank whipped up this script to generate a palette based on the PROM information.  What this does is evaluate the information in the PROM to determine what color is displayed based on the analog mixing on the output, and the data bus going into the PROM.  First, let’s generate a palette based on the PROM in MAME:


Original Palette

This shows a decent variety of colors, but that alone doesn’t tell us much.  Let’s look at it against the ones we dumped (there were two identical ones, as well as one original so the dumper isn’t in question here)


Different palette

Here we can see that the orange color is replaced with red and dark red.  That seems to be the only difference between these.  In the game that orange color is only responsible for some of the colorful twinkling stars in the background so it’s unlikely that anyone would notice the difference.  Maybe that color is used by an enemy later on, but in playing the game we haven’t come upon any yet.  The technical difference is that at address 0x09 and 0x19 in the MAME version of the rom the value is 0x07, while in the one we found it’s 0x01.  That’s a two bit difference in data at only two addresses.  I can’t think of a way for two chips to be broken in the same way as to give this sort of a result, so I’m left thinking it’s just a minor variation on the released PROM.  Perhaps a different game uses the same PROM and it makes a bigger difference there, but not in Astrofighter.

We did find another, more different, PROM and run it through the same palette generator script and came up with this:


very different palette

This one only has the first half of the PROM populated with data.  Here I DO suspect hardware damage to the PROM, something about accessing the top address bit caused no output on the data bus whatsoever.  This one seems a clear case of failed hardware.  That being said, while 0x19 has data 0x00, like all the upper bytes…. 0x09 has 0x01 just like the other PROMs we found to be different than the one in MAME.  It seems that before failing this was also deviating from what the known Astrofighter PROM was supposed to be.

Is the slight variation on the star background worth archiving in MAME as a different ROM set? We don’t even have positive confirmation what game this PROM came from, just strong speculation based on what you can see above.

Partial success at reading PAL16L8s

March 5, 2020

I try to archive all the things I think might be important that come through my hands, and I’m a completionist so this usually gets me hung up on things that don’t actually matter functionally but I still feel like Need Doing.  The latest one is archiving the AMPAL16L8s on the “Kuri Kinton (World)” board.  The Roms were in MAME, but the way the driver was written it didn’t use the PALs.  Even though the emulation doesn’t need these, if you have a board and need to replace one of these chips to make it work you are out of luck.  After hunting around I landed on this clever adapter to brute force the logic equations programmed into these chips.


This is clever because it just uses the address lines as a binary counter trying every combination of inputs and using the 8 output lines as the data bus.  The interesting part comes from the 8 output lines also being able to be configured as input lines.  How do we interrogate something to figure out if it’s an input or an output? In this case we induce a little bus contention and see how the PAL moves.  The theory goes that if the PAL uses a given pin as an output then it will be strongly driven and overcome the address line trying to also drive that pin via the 4.7k resistor.  By going through all possible states of the other pins you will read all possible states of that pin and see no correlation when the only thing that changes is the address line also trying to drive that pin.  If the PAL uses that pin as an input pin then the ‘data’ line will always follow the address pin trying to drive it through the resistor and you will see 100% correlation between the address pin and the data pin.

When we tried this we seemed to see that this pin was always stuck high, regardless of the state of any other pins.  That did not turn into a functional GAL when reinstalled in the arcade board so what happened?


Those high pulses are downtime between read cycles, the top trace is on the address line, the bottom trace is on the PAL.  It would seem we have built a voltage divider.  It is our guess that based on this trace the PAL has an internal pullup of about 2.7k because the technology the chip is built on is good at pulling down and poor at pulling up.  The issue with that is we are not driving the pin strongly enough to get it to a low logic threshold,  We could change the 4.7k resistors to something a little lower resistance to up our drive strength but what would that do on an output pin? there would actually be bus contention and might that burn something out?

The question here is how do we interrogate the chips without knowing if the pins are inputs or outputs without breaking them?


PS: we pulled working JED files from Jammarcade and tested them, they work great.  We managed to get our own working one for the PAL that had all 8 set as outputs, we just couldn’t get any PAL to recognize our inputs through those resistors.

Reading early Commodore PET roms

March 4, 2020

This one is short and can be summed up basically with a link to someone’s suggestion and myself saying ‘yes it will work’.  Here’s the suggestion from

does the 6540 need the clock impulses? to output data?

Yes. You could try to connect clock with A0 and the address lines of the 6540 with the corresponding higher address lines of the EPROM-adapter. Like this:

6540 2732
clk a0
a0 a1
a1 a2
a2 a3
…and so on.

Only each second byte of the resulting image will contain your data, but that’s better than no data 

I can confirm it works.  Here’s an image of the chip pinout we’re talking about:


There are a few things interesting about this chip, first is that it has a clock input, which for a parallel rom is a bit strange to me.  Second is that it has five chip select lines… FIVE.  It has so many chip select lines that normal 2716 chips use four fewer pins than this one of equivalent capacity, it goes up a package size just to accommodate those chip selects.  The reason for this is clear, it means less decoding hardware needed, you can hook a set of address lines up to the chip selects and it then reads as a specific memory region without any more decoding, change which lines go to the active low chip selects and which go to the active high ones and you get different memory regions.  This was accomplished in later PET revisions with the 23xx series of roms which are also bristling with chip selects.  The adapter to use a standard 2716 rom in place of the 6540 uses a 74138 to decode those chip selects.


The adapter to read this rom is pretty easy to build, but I can only tell you that it worked with our dumper which in this case was a GQ-4×4, the timing of that clock pulse is included above.  I mapped the address lines to the pinout of a 2732 with the low address to clk and the other ones shifted up one.  I tied all the active high chip selects to Vcc and the active low ones to !CS on the 2732 pinout.  Doing this resulted in the even bytes containing data and the odd bytes being all 0xFF, we used a python script to chop up the binary into one we could check against the mame archive using “mame –romident foo.bin“.  We found two bad roms already this way.  


Strange parallel ROM pinouts

February 27, 2020

I’ve been working a lot this past year on old computers and arcade machines so that means gaining a familiarity with different rom pin layouts.  Looking up datasheets for each and every one repeatedly got old, so I found some helpful charts.  The first one looks like this:


I have no idea where this came from, but it’s a great resource and covers all common 27xx ROMs in the 24 and 28 pin packages.  Thankfully there’a someone who liked this as much as I did and made it a little prettier and easier to read:


That’s all good, but for some oddball stuff that isn’t quite food enough.  Commodore PETs, Colecovision carts, plenty of older boards use different style roms than the now-standard 27xx series.  Let me introduce you to one of the strangest ones I found, this is taken from the manual for the Midway 8080 Tornado Baseball manual:


This chart has  a lot of information, and some of it is misleading without understanding the rest of the schematic.  The main takeaway is that this chart shows what various pins on each rom should be connected to in order to function.  Three columns however do not represent pins on the rom, they represent pins on the chip select decoder, those are labeled S6a, S6b, and S6c.  ignoring those for a moment this gives us an idea of how the pinouts differ from one rom to another, but what about how the pinouts are the same? well, by correlating the 2708 (the only chip in both the original diagram and this table) you can see how the remaining pins are the single chip select and data and address pins (as well as ground).  Getting back to the columns of address lines, take a look at the schematic right next to this chart:


I really like this setup, it uses a 7442 as a chip select decoder and you get to choose what size roms you have.  For example if you have the smallest roms, 512B ones, you only get 9 bits of address per chip (A0-A8) so A9, A10, and A11 go into the decoder and that picks which of the 8 roms you are talking to based on where in the memory map you are (breaks the memory map into 512B chunks).  If you have 10 bits of address per chip you then run A10, A11, and A12 into the decoder and it’s now breaking up into 1K chunks.  This datasheet only has jumper settings called out for one 2K rom, the 9216, and with that in place you get 8 chunks of 2K using 13 address bits total.  You can’t hook a 2716 directly up using the jumpers and the table, but with a couple of bodge wires between the jumper blocks I think it would work.


This all led me to make my own ‘universal’ rom tables so I could find equivalents or adapters to make one type read as another.  I broke it up into two sheets because otherwise it’s unusably huge (as it is it’s pretty bad).  I have 23xx, 25xx, 27xx, 28xx, tms47xx, 93xx all on one page and all the older stuff from tornado baseball on a second page.  I left the 2704 with the older roms because I haven’t had call for rone and most people start the 27xx series at 2708.  I added the sizes for the roms I’m not familiar with and will be expanding these spreadsheets as I find more information I want to reference.


These screenshots are just a snapshot in time and are not meant to be kept around as the gold standard, it’s kinda hard to read without a ruler they’re so big.  There are other ROM pinouts not included here like the infamous Intel 1702  or various smaller 4bit roms, but those have other pages elsewhere and really this is a tool for my own reference.  Other links are here:

32pin rom strangeness

Reading Irem MASKROM’s


Post script, sometimes I hate commodore:


Google Home Autopsy

February 20, 2020

I had a google home die the other week.  The internet claimed it could have been a bad OTA flash and that I should get support to replace it even out of warranty.  I called and found out that (at least my rep) would extend the warranty out to two years, but not three which I would need.  I also found out that there aren’t any warranty void stickers inside  or anything so I would have taken one of my google homes that was in warranty and swapped out the misbehaving motherboard but that seemed overly complicated and I thought I maybe had a solution anyway.


One thing I did remember was that the google home has a ‘hidden’ usb micro port that is for ‘service’.  After some research it seems that no one has hacked this thing using that port, but there are reports that you can use a chromecast ultra power supply on it and give it a wired network connection (which means it’s a usb on the go port).   I took a look about the chip inside and saw that it runs uboot for a bootloader and that I might be able to dump the onboard flash via that rather than desoldering a bga.  Looking at the ifixit teardown there’s two pads right next to the processor, those are probably serial so off I go.


This is a useful page explaining how to determine the baud rate of an rs232 connection from the shortest pulse, I have duplicated the table here.

Time Baud Rate
3333µs (3.3ms) 300
833µs 1200
416µs 2400
208µs 4800
104µs 9600
69µs 14400
52µs 19200
34µs 28800
26µs 38400
17.3µs 57600
8µs 115200
4.34µs 230400

We were running at 115200, a very common baud rate.  I hooked up to the pins and found that the one closer to the center of the board transmits (the other one presumably is supposed to receive but it wouldn’t listen to me) and they’re a full 5v serial port (I was expecting something dumb like 1.8v).

The first boot capture saved is here.  it all seems to be going well until:

{line: 1131} tz_en_start: 0x120000 tz_en_end: 0x360000 tz_en_size: 0x240000
Uncorrectable error @ 0x00260000
Read failed @ 0x00260000
verify 0k:0x402c0de, 1k:0xd6749664, 2k:0xccd3d16e
verify image 0, size=1237488, waitcount=49
tz_loader: image4 verified.
tz_en image load verify success
verify 0k:0x201c237, 1k:0xf01c0de, 2k:0x0
verify image e0000301, size=0, waitcount=1
{line: 1158} bl_en_start: 0x5a0000 bl_en_end: 0x640000
Uncorrectable error @ 0x005c0000
Read failed @ 0x005c0000
verify 0k:0x400c0de, 1k:0xe16f5f14, 2k:0xe92d43f8
verify image 0, size=120408, waitcount=4

What’s a few uncorrectable errors between friends? There was also a problem with:

[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
block 1021: !!! UNRANDOMIZED !!! (page=0)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
block 1022: !!! UNRANDOMIZED !!! (page=0)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)
[is_chunk_blank:455] not blank! data_len=2080, ecc=48, zero_bits=49
[mv_nand_read_large_page:2232] ECC uncorrectable error (page=0xlx)

I’m not sure if this is normal because I’ve only opened a broken one but I assume it’s not.  I also tried to boot it while holding the mute button, that ended the boot cycle with :

Detected button press — booting from USB
USB: Register 10011 NbrPorts 1
scanning bus for devices… 1 USB Device(s) found
0 Storage Device(s) found
ERROR: No USB storage device detected
Booting from NAND failed, booting from USB….!
USB: Register 10011 NbrPorts 1
scanning bus for devices… 1 USB Device(s) found
0 Storage Device(s) found
ERROR: No USB storage device detected
FATAL ERROR! There is no bootable image on this machine!
tbdzz—- Img_Ld_And_Start error! Spinning now!

So it looks like you can boot this from a flash drive which is cool.  if I were more skilled I could probably dump a good one and make a bootable image out of it to boot the bad one but alas I’m not.  this is where I box it up and wait until someone else comes up with a solution for this.

Designing a watchdog timer

January 3, 2020

Recently we had a problem at work, we were using a specific watchdog timer and it became unavailable.  The people who were supposed to source it suggested an alternative which turned out to not do anything close to what we wanted and I was presented with a problem: find or make a replacement for the watchdog timer we were using.  The first thing I did was try to find an equivalent, which did not appear to exist, and then it was suggested that I make one using an arduino.  That would be relatively simple, but with this being a safety oriented design I don’t want the entire stack of the arduino libraries, compiler, assembler and other junk becoming a possible source of issues that I couldn’t anticipate.  So I decided to make one out of discrete components.


This would have been a lot faster to build

The module we had before had several parameters I needed to replicate and one that I threw out for simplicity’s sake.

  • Powered off of a 5v usb port
  • Take a 24v ~50% duty cycle signal as a heartbeat
  • Turn a relay on if the heartbeat goes away
  • Turn the relay off when the heartbeat resumes
  • Set the minimum acceptable frequency of the heartbeat over USB

I threw out the last one.


dual astable watchdog, has a reset button though

After much googling I found a quintessential 555 timer circuit used as a watchdog timer.  Set up the 555 timer in an astable configuration and use the heartbeat to continually drain the capacitor on the trigger/threshold pin to inhibit an upcoming pulse.  People often refer to the act of inhibiting the watchdog timer from resetting your target circuit as ‘tickling’ the watchdog or ‘waging’ the tail, but this circuit has some issues for my application.  First, the output is a pulse that repeats if the timer is not reset quickly and I need it to latch.  Second, it will not detect a stuck ‘on’ state. The final issue was that I want to run at 24v, but using a 2n7000 N-FET I can run whatever voltage pulse I want and it just comes out as an open collector (drain) output which inverts the signal but whatever.


This version has the latch work for only one of the stuck states because of the auto-reset bit

The astable mode of the 555 works by charging a capacitor slowly and when it reaches a certain state of charge it triggers a pulse which drains the capacitor and it starts again.  This means that to inhibit the pulse, you pull the capacitor to ground and drain it, then let it start charging again.  The problem there is if you don’t let it start charging again then it can never trigger a fault either, so a stuck state is not detected as a fault.  If you have a 1% duty cycle signal for a heartbeat then 99% of the time when the software fails then it will be in a state where a fault can be detected and that might be acceptable.  Mine is 50% duty cycle.


This is the fixed version with two latches, I never even built this one

The easiest way I can think to fix this is to have two watchdogs, one watching for a high state and one watching for a low state.  If you drive them from the same signal then you necessarily have to alternate or you will upset one of the state detectors and it will throw an error.  This fixes one of the two issues I had, the second is that I need it to latch.  I figured an SR latch would do the job, so I hooked the outputs of the two astable timers so either of them could set the latch, then I just had to press a button to reset it once the heartbeat was going again.  At this point I realized that it was supposed to reset itself so I hooked the reset line to the input signal so as soon as the signal started up again it would reset itself.  That was a problem because if it was stuck on then the watchdog for that state would trigger but the input signal would also be holding the latch in reset and it would negate having a latch altogether.  Clearly the solution is to have two latches whose resets are complementary and whose outputs are gated together.


dual monostable, pile of FETS to isolate things

This design has now grown beyond two chips and some FETs, time for a rethink.  Maybe what I want isn’t a 555 in astable mode, maybe I want one in monostable mode.  That way I can have a pulse going constantly and I can extend it by draining that capacitor.  When the pulse ends it latches itself and doesn’t resume until the trigger pin is hit.  This gives me my latching for free, but the trigger and threshold pins cannot be connected for this mode to work otherwise the charging of the capacitor is not done right.  My solution then is to use two FETS to trigger both of those pins to be grounded when a pulse comes in but not to have them shorted together the rest of the time.


dual monostable, pile of FETS to isolate things

Now I have two watchdog timers, one detecting high states and one detecting low states, each will latch if an error is detected and automatically clear when the signal resumes.  This is pretty ideal, but I still have two timers to set since I’m using a 556 for both halves of this watchdog.  I think I can get it smaller.


edge detector and single monostable timer

My next thought was that I need an edge detector.  I don’t care what state the circuit is in, but I do care that it keeps switching.  So, the question now is how to detect both high and low edges and convert them to a 0-5v pulse train out.  My initial thought was an op-amp to do differentiation and give me spikes, but half of those spikes would be negative and I didn’t want to get away from the 5v single supply design.  Then it was proposed to use a XOR gate and an RC delay on one of the lines.  This is perfect because if a XOR gate is fed the same signal on both lines then the output is low, but when that output is changing if both inputs don’t get the change at the same time there will be a brief pulse because of the difference.


Now that we have converted our 50% duty cycle square wave into a pulse train based on the edges we can safely go back to the beginning and use one 555 timer since I know it can’t get stuck in the high state since the high state is generated by transitions.  Since I still want the output to latch I’ll use the 555 in monostable mode and have some FETs to isolate the trigger and threshold pins.  Now I think this is pretty slick and nicely compact.  I’m done, right?


A coworker threw this up on the board and then left for the day.  Ok.  What am I supposed to do with this.  Here’s my understanding about what’s going on.  The capacitor blocks DC but lets the AC component of the signal through.  What that means is it will generate a series of positive and negative going pulses (just like my differentiator idea above) and I don’t want those negative going pulses.  The diode is (I think) supposed to snub the negative pulses.  The capacitor and resistor are supposed to constitute a decay that is charged by the input pulses and drained by the resistor.  The transistor obviously runs the relay coil when the capacitor is charged enough.


My stab at analog design still uses a FET as a switch

I’m not super comfortable with this level of analog circuit design, but I gave it a shot and this is what I found.  The diode was drawn wrong, it should have been a series diode because as drawn the negative going pulses drain the second capacitor and no matter what components you choose at best you will get a 50% duty cycle output as the second half of the signal blows away any progress you made charging the cap.  I solved this with a bridge rectifier so I could use both pulses (despite the forward voltage drop incurred).  The last change I made was to use a FET instead of a BJT since I’m more comfortable with the capacative input of the FET not loading down the capacitor I’m trying to charge.  I also found that you pretty much have to tune all aspects of this circuit together, the resistances and capacitances which makes it great for a single application, but not a universal design to be inserted other places unchanged.  I think the dissimilarity in the pulses seen in the second picture are because if different forward voltage drops in my diodes, the tolerances are that tight on this one.


capacitor being kept charged, output being held low


drop the duty cycle and now it resets on missed pulses (doesn’t latch though)

After all that effort and iteration I realized some things:

  • I need to detect edges, not states
  • I don’t actually care if it’s both edges

I can detect on one edge because implicitly if there’s a second positive edge it implies the presence of a negative edge and the signal falling some time before it rises again, I just get the edges half as often.  With this knowledge I can pick any number of off-the-shelf timers, I was just surprised that no one had a simple circuit to work on an arduino that detects both stuck high and low states.  Hopefully this explanation gives some insight as to how you can easily build a hardware watchdog to suit your particular needs.

Reverse engineering a Shop Bot ROM

November 13, 2019

After dumping the ROM from the shop bot we were intrigued by what we found.  Some of the strings in the ROM indicated that there was a basic interpreter on there, and there was even plaintext BASIC.  After some digging this is what we found.


Blue Earth Research was a company that made microprocessor development boards, presumably for industrial use.  They packaged (in our case) an 80c32 processor, a ROM chip, and I/O expander, and made it all as compact as possible.  They also did work with the 8052 and other processors in that line.  Among the series of boards they offered was the Xplor 32d, the ‘d’ standing for digital as there were boards with on board analog to digital converters.  They provided the BASIC interpreter’s hex file, the assembly source for a program that could load that hex file onto the microprocessor, and the source for libraries for use with peripherals such as a keypad, an HD44780 LCD screen, and X-10 automation hardware.  There were also example BASIC programs that showed some of their BASIC’s more unique features.  There was also a C compiler for this architecture, but since that doesn’t have anything to do with our ROM dump we’ll skip that.

Before even starting in on the code we traced the whole board to determine which pins were where as far as I/O and how the chips were wired up to determine the memory map.  This information is all in one spreadsheet contained in multiple tabs, the memory map was eventually expanded to contain details of the code we disassembled.


To help with this we employed the disassembler dasmx.  This is extremely easy to use, and even though it is not open source it is free to use.  This program is fairly smart, but it’s not magic.  It will interpret all the memory as code memory unless told otherwise and because there are no distinctions calling out the beginning of data it tries to decode plaintext as code.  We originally were concerned that the ROM dump was incomplete because a hole in the BASIC exists between 0x10C1 and 0x13FF.  Upon closer inspection the code after 0x13FF references line numbers that should be in the top code snippet and are not present, implying that it is not from the same program.  In addition to that, one of the new BASIC commands is CALL which jumps to a memory location and starts executing the assembly there, and the BASIC snippet starting at 0x1000 ends with CALL 7000.  Interestingly, that command is referenced in the source files of the example programs explaining how to use this development board, so that confirms our suspicions.



Part of the instructions for how to use this dev board include assembly libraries that can be called from BASIC that use the peripherals.  Things like the LCD, keypad, and X-10 integration were provided by Blue Earth Research and instructions were given for them to be loaded at 0x1E00.  Our ROM includes these exactly, and by adding the line labels to the symbol file they disassemble and are readable (even if I don’t think the main shop bot program is using them).  It’s a bummer that the source for Xplor Tiny BASIC is not provided, but it helps that the same person wrote that as wrote the loader for it.  RELOAD.A51 contains some routines that are almost, but not exactly like routines in BASIC.  Specifically the string printing and console output routines.  The differences seem to come from the fact that BASIC has built in support for the LCD and therefore has to check if it should print there or to the console.


The other source files also helped determine how our program was interfacing to the 82c55.  The wiring only decodes some of the address lines so it would be possible to write to the peripheral chip with a number of memory locations, but the source files clearly show constants of 0x2000 for port A, 0x2100 for port B, 0x2200 for port C, and 0x2300 for the control registers.  This is in the disassembly as well, but the assembler eliminated the constants and now references to these numbers are sprinkled throughout the code.  This helps determine what is going on with certain sections of code and labeling has progressed based on this.  As a note, some of the labels in the source code we have are not present in the disassembled code.  This is because if nothing calls that memory location then the disassembler doesn’t know it is supposed to be logically distinct and there is no placeholder label generated.


This BASIC is interesting in that the coding convention calls subroutines and then immediately after the call is the data to be used in that subroutine.  This means that the subroutine can get the data by looking where the program would jump back to and pulling information from there until it hits the end.  One example of this is the keyword subroutine.  When reading the BASIC program the interperter needs to know if it’s reading a valid command, and if it is then it needs to execute that command.  Our code contains a call to the keyword routine and then immediately after is the basic command in plaintext, except the last character has the most significant bit set.  This is so the routine knows when to stop reading data (there’s code after that).  There are no null terminated strings here, just checking to see if the byte is greater than 0x80, if it is 0x80 is subtracted and that is the last character in the keyword.  This convention is also used when printing strings to the console or the LCD.


Doesn’t this look a lot like the init section of an arduino program, complete with the serial print of what it is and that it’s booting

The remaining parts of the disassembly were made by recognizing when special registers were being used.  Things like transferring data to or from the serial buffer are fairly obvious (either moving things in or out of the sbuf register).  Setting up interrupts and timers, as well as setting the direction of ports can all be gleaned without looking closely enough to see which bits are being set, just that those registers are all being written with values in succession near the beginning of the program.

This is where we are right now with the disassembly, it’s been interesting and we might dig further into this at a later date, but for now our curiosity has been satisfied.  All the files we used for this are up on github, that includes the last version of the disassembler, the rom dump, the latest revision of symbol file for it, and the listing that it decodes.  The board wiring and memory map are also there.  The source files from Blue Earth Research are also there although they are also in the internet archive.

Dumping the x88c64 multiplexed rom

November 12, 2019


The 8051 is in everything.  I’ve won pitchers of alcohol by betting that a given device contained an 8051.  It’s in USB hubs, bluetooth microprocessors, UPSes, and even SOIC16 packages and smaller.   That’s not to say it’s a sane architecture, but it’s ubiquitous.  The problem I have is pin multiplexing.  The 8051 has internal rom, that’s all fine if you’re only using that internal space but the 8031 is the rom-less version.  The 8031 has all of it’s program memory offboard which is very nice for the purpose of accessing it to dump the data for analysis and modification, except in this case.  To save pins on the 8051 series the data pins are multiplexed with the lower 8 bits of the address bus.  In most circuits that just means that a latch is used and the processor interfaces with a standard parallel rom.  This architecture became so ubiquitous though, that special multiplexed roms were created to deal with this exact scheme and allow for smaller boards and less circuit design work.  The x88c64 is one of those chips.


The Arduino Mega is a very nice tool for twiddling bits, it’s 5v logic, got lots of I/O and the only connector on it you will likely need is a 2×16 0.1″ pitch male header.  The arduino platform had always annoyed me with its non-grid pin spacing so shields have to be custom laid out rather than just using protoboard and only populating some of the grid.  The mega avoids that in part by the new big connector being a monolithic 36 pin header.  5v and ground are available on the top and bottom two pins and the remaining 32 pins are I/O.  All of ports A, C, and L as well as hardware SPI pins are available in those 32 pins, even though I usually abstract that out and ignore the underlying hardware ports in my code.


One useful thing about this rom is that in addition to there basically being a write protect pin, the write cycle needs three whole writes of specific data basically saying ‘are you sure’ and if all that goes correctly then on the fourth write you can change the data in the rom.  This is one way to do away with funky programming voltages and still have some form of protection so you (I) don’t accidentally blow away the rom you’re (I’m) trying to archive.


The code to dump this rom is abstracted out and will run on the atmega2560 under the arduino ide, the board made is for the arduino mega although I know you could use any atmega2560 breakout to read one of these roms with this code.  I didn’t write the code to dump this one, Frank did.  I tried and was stymied probably by jumper wires with no continutiy.  We sorted that out by soldering up an adapter instead. Let this be a lesson to you: never breadboard where you can solder, you’ll spend more time debugging it than making it.  The code is fairly straightforward, but as it’s probably just the first in a series of custom rom dumpers a couple routines were abstracted out.

void WriteAll(int pinstart, int numpins, int incdec, int value) takes the first pin of a set of pins you want to change, how many pins you want to change, whether you’re counting up or down, and a value you want to write to those pins.  That value is not just binary, this function takes an int and strips it down bit by bit setting pins in a series.  This is limited to adjacent arduino pins because of how the counting works, but is still incredibly useful.

int ReadAll(int pinstart, int numpins, int incdec) does the same thing as writing out, except it returns the value put together from reading individual bits.  These functions can be turned into specific functions per program by simply using one #define statement for each new function you want to create.  #define WRITE_AD(value) WriteAll(22,8,1,value) writes the value passed to it starting at pin 22 and counting up for 8 bits of data.  #define WRITE_A(value) WriteAll(37,5,-1,value) writes the value passed to it starting at pin 37 and counting down for 5 bits of data.  #define READ_D(value) ReadAll(22,8,1) reads 8 bits of data starting at pin 22 and counting up.

The remainder of the code is a straightforward interpretation of the timing diagram in the datasheet, hopefully this will help anyone who needs to dump this oddball eeprom.



Vtech Pre Computer Power Pad upgrades

November 5, 2019


All inspiration for this came from a recent hackaday post.  It is a bit fragmented so let me try to bring the information sources together as well as add my own.

Hackaday post project (linked from above)

Thingiverse (contains best image of pcb traces)

Original creator’s personal blog

z88dk thread

Additional information on a similar computer

There is much more information out there that needs to be compiled as well.

Now, as for my contribution.


I want to eventually use this as a CollapseOS machine, I think it’s in the spirit of that operating system to be built out of salvage components, but this right here seems to be a ready made machine for the job.  After Makerfaire Detroit Frank and I got an s100 bus system consisting of two poly88 chassis, an ithica audio z80, a percom monitor rom, a solid state music io-4, an sd systems expandoram, and a zrt-80 terminal.  We got the various cards fixed and Frank modified the monitor and streamed basic over to it over a serial port to run from RAM.  It’s a pretty capable system and I already have four more cards for it and one more in the mail (none of these were really needed, but whatever).  That is the main workhorse z80 system and has been extremely useful for learning how the whole architecture works as well as learning some tricks from back in the day.  We will probably end up running CollapseOS on there some day, and probably a version of CP/M if we ever get disk controller cards.  Using that knowledge I’m going to try to make the Pre Computer Power Pad a useful z80 laptop.

Rom Dumping

The first thing to do after learning about all the work already done in MAME was to dump this rom and see if it was already emulated.  After looking at this nice annotated layout it seems that the mask rom used in these computers is pin compatible with the 27c2001 2 megabit rom, and an eeprom programmer will dump it as if it were one.  It turns out we are the first ones to dump the rom contents of this computer (27-5373-04) and put it on the internet.  With some minor patching it runs in the pc2000 mame driver as a gl4000 (just swapped the rom and recompiled).  This is incredibly powerful and lets us interrogate the code as it runs, setting watchpoints and single stepping as we see it handling functions like printing (we’ll get to that).  This rom should be up on the MAME guys repository soon and the new addition to the mame driver shortly after.  There’s still work to be done to add the printer port to the driver for computers that come with one, but we haven’t got that done yet.

Printer Port addition


Now, I don’t say parallel port because this port really is only equipped to print.  I started from here with the helpful information on the missing components.  From there I determined what jumper wires were needed by analyzing the circuit and links to nearby chips.  This was complicated somewhat as it seems that under battery power some circuit generates a negative voltage and that is what the rf ground is running at? I don’t know the power situation with this board but I don’t really like it.


The original transistors of Q10 and Q11 were LM9014C and LM9015C respectively and I replaced them with a PN101 and a PN2907, which roughly work out to a 2n3904 and 2n3906.  The PNP transistor serves to pull down the strobe pin as a noninverting output (10k pull up) and the NPN transistor acts as an inverting input from the printer’s /BUSY line.  This plus all the resistors that are missing being 10k and the fairly obvious 74ls244 (obvious because of the wacky pinout) gives you a working printer port circuit.


This won’t let you print, but you have an electrically functional port.  The english rom has the commands LPRINT and LLIST missing from the BASIC keyword table so you can’t exercise the port, but flashing the german rom to a W49F002 (thank you salvage BIOS roms) and it prints just fine.  Work is progressing to add those commands back to the english rom, it’s just not done yet.


One final word on the printer port, and speculation on why it was not on the US version of the laptop.  The ‘244 is hardwired to be on all the time, at least that’s what it looks like to me.  The data lines for the printer port are shared with the key matrix, and from what I can see the key matrix scanning signal is being broadcast out all the printer port data lines at all times.  The printer doesn’t respond because the strobe line isn’t used, but the data’s there.  This reminds me of Bill Herd’s story of the commodore that had full system bus speed scanning the keyboard matrix with no buffer and it would crash if you got it near a TV.  The FCC may have had the final say about this design.

NiMH charging addition


The last one was really puzzling out exactly what to do based on information from the last guy.  This is a new contribution.  I decided that since this was a laptop that it should behave like one.  To me that means a rechargeable battery with charging circuit inside.  This comes partly out of all AA batteries in my house being Enloop NiMHs and my desire to not take them out all the time to charge.  I also wanted to keep the original functionality of being able to use non rechargeable batteries for emergencies or just situations where you can’t get rechargeable or you lose one.


I implemented this with a switch on the back to switch between R(echargeable) and A(lkeline) batteries.  What that does is when the switch is in the A(lkeline) position and you are running off batteries the battery ground is run to the pass-through pin of the barrel jack and thus connected to the system ground.  The positive is connected to the ~5v input to the pcb.  When you are using the barrel input the pass-through is disconnected and the batteries are out of the circuit (on the ground side).  The input to the barrel jack goes through a dc-dc converter and also goes to the ~5v input on the PCB.  This is different from stock in that the barrel jack used to feed a different part of the pcb with ~9v but it would have complicated my circuit to do that so I regulated it down to simulate the battery voltage.  This means the allowable input voltage is now a much wider range, instead of being just 9v you can feed it 7-20v and it would survive just fine.  I had to swap the barrel to one that would accept standard 12v supplies, the original one had a center pin that was too big.


In the R(echargeable) position the pass-through and system ground are connected together.  Also the barrel jack moves from supplying the pcb through a dc-dc converter to running a NiMH charger to charge the batteries.  This means that in R(echargeable) mode the batteries are always powering the laptop, just sometimes the charger for them is being powered too.  The charger’s LED was relocated to the front lip of the laptop to indicate charging status.


These modifications allow the laptop to be run off a wider range of voltages, charge its own batteries, and in a pinch you can swap out the batteries if you need to.  Truly a versatile configuration in preparing for the collapse.




test and install supercap and diode circuit to keep internal sram alive when AA batteries are removed

maybe patch internal chip select lines to unused cartridge pins for remapping without opening the case (would then need jumper cart)

bigger screen? looks like the hd44780 lines just go from the main board to the top of the laptop

patch english rom to allow LPRINT and LLIST

patch all roms to restore peek and poke (list of commands seems based on microsoft basic for the z80)

fix mame driver printer routines/clock frequency

upload dumped power pad rom to mame

port CollapseOS