• Please review our updated Terms and Rules here

Building a Z80-based ROM dumper

cjs

Veteran Member
Joined
Nov 5, 2021
Messages
1,762
I've got various friends with a T48 or similar PROM programmer which we also try to use to dump ROMs from vintage 8- and 16-bit systems. Unfortunately, they don't have definitions that enable reading of ROMs from many of the vintage parts, particularly 23xx and the like, so I'm finally getting to the point where I feel I should build my own system to do this. I know I could hack on some Arduino thing with a modern ATMega or ARM CPU, but if I'm going to be hacking on code, I'd rather do it on a vintage-era system (where I already have good development tools) than bring in yet more modern tools that I wouldn't use for anything else. And besides, 8-bit assembly hacking is just more fun (for me) than programming in C++.

To start with, using PIO instead of trying to hook the ROM up directly to a bus seems to me obviously the better approach to take: while it's going to be slower, this gets around a whole load of potential timing issues (especially if running the code on a relatively fast machine) as well as giving you much more direct control over pins without having to do any hardware for them. (For example, you can handle inverted chip select lines in software.)

So I now have a pile of SuperAKI-80 boards which seem ideal for this since they have gobs of PIO. As well as the 16 bits of Z80PIO that come along with the Toshiba TMPZ84C015BF (Z80 CPU, CGC, CTC and PIO) it has a Toshiba 82C265, essentially two 8255 chips in on unit, adding another 48 pins of GPIO that, handily, are all together on a 50P (2×25) 0.1" header along with GND and Vcc. This lets me easily bring out a ribbon cable to whatever on the other end, whether it be a socket on a board, an edge connector to a ROM cartridge (e.g., Atari VCS), or whatever.

Obviously I'm going to have to have some sort of definitions for what is on what pins: GND, Vcc, D0‥D7 or D0‥15; A0‥A18 (or maybe higher if I find myself with a >256 Kword ROM), chip selects and pins that need to be held at a particular level.

One of my main worries about this is accidentally driving output pins and creating short circuits, but it would also be nice to have auto-detection of potential errors in hook-up. Does anybody have any ideas on how to deal with these concerns?
 
Perhaps download a schematic for the willem eprom programmer? That could answer a lot of questions I would think.
 
First question: Are you going to stick with +5V only devices in READ mode?

If so, you would generally require relay drives for GND and VCC pins rather than logic outputs driving power pins.

OK, you could use modern FETs instead of relays, but the advantage of relays are that you can arrange for series-connected relay changeover contacts so only one source can drive the IC pin at any one time. However, you need to take a careful look at your device support list and see exactly which pins require this treatment.

I would have a 'master' relay in series with the +5V supply to the relays to ensure that everything is setup correctly (power relays, logic port direction) BEFORE turning on the power.

You could also consider current limiting the +5V supply to the relays and then (assuming everything was OK) increasing the current limit for operation. This will complicated the power supply side if things of course.

Dave
 
Last edited:
Perhaps download a schematic for the willem eprom programmer? That could answer a lot of questions I would think.
Do you have a good link for this? I found this super-sketchy site with a PDF that it won't let me download unless I upload something, and the preview is too small to see the details. This image does look like a copy of that in slightly better resolution, but that looks like it's fairly hardwired to certain pinouts and I don't see anything related to protection against errors in hook-up.

First question: Are you going to stick with +5V only devices in READ mode?
Yes, that's the plan.

If so, you would generally require relay drives for GND and VCC pins rather than logic outputs driving power pins.
Yeah. I was thinking I might be a bit optimistic in having the GPIOs drive power for the chips. Last time I looked at doing something like this it was with an ATMega which can source and sink a lot more current on its GPIO pins than the TMP82C65A can. And looking at a typical old part, such as this 2364, it can sink up to 140 mA on Vcc, which is just crazy high for that early '90s CMOS 8255-style chip.

So that leaves me forced to use some sort of adapter board to handle getting proper Vcc and ground to the appropriate pins on the device, which has just massively increased the complexity. If I wanted to go with "arbitrary pins can be programmed in software for this" that means, as you point out, FET or relay drives for each pin; while a nice general solution that's also now big and expensive (especially for supporting some of the late-'80s 42-pin ROMs I'd like to dump), so I think I'd rather go with some sort of manual configuration for this (maybe even just slap the thing into a breadboard and wire it by hand). Ugh.

So I guess the question is, if I assume that the user has correctly identified and connected the power pins separately, and I'm not using GPIO for those, what's the minimal protection I need to avoid damage should the user accidentally swap e.g. an address pin and a data pin, causing a GPIO to be driving a data pin that the ROM is also driving? And is there some easy way to detect this, beyond just "the dump produced trash output"?

...but the advantage of relays are that you can arrange for series-connected relay changeover contacts so only one source can drive the IC pin at any one time.
Can you explain in more detail how this works?

However, you need to take a careful look at your device support list and see exactly which pins require this treatment.
I don't really have a device support list, because I'm wanting to handle whatever random ROM devices show up in the various vintage machines I buy. At least, all the ones that work in some reasonably normal way: 5V power, ground, and TTL or CMOS address and select inputs and data outputs. If it requires someone to do a bit of wiring to handle that, that's fine; per above it's obviously not going to happen entirely in software, though I'd like have it be slightly nicer than, "wire it up entirely by hand on a breadboard."

You could also consider current limiting the +5V supply to the relays and then (assuming everything was OK) increasing the current limit for operation. This will complicated the power supply side if things of course.
Yeah, that's definitely going further on the hardware side than I care to.

BTW, for a sense of the largest/newest devices I'd be dealing with, it would be along the lines of the Mac Classic ROM below, taken from this schematic.

1751244340395.png
 
The first option is to permanently wire up all of the pins as per the attachment.

With neither relay (RL0 and RL5) energised, each ZIF socket pin is connected through to the 8255 - i.e. a signal pin - address, data or chip select.

When RL5 is energised, the ZIF pin is disconnected from the 8255 and directly connected to +5V. I would, however, include a 'master relay' in the +5V supply so that +5V is not actually applied until this 'master relay' is operated.

When RL0 is energised, the ZIF pin is disconnected from the 8255 and directly connected to 0V. I would also include a 'master relay' in the 0V supply.

If RL5 and RL0 is accidentally energised at the same time (a software fault), the 0V relay (RL0) will take priority - so there is absolutely no way that the 8255, the 0V supply or the +5V supply can power the ZIF pin at any given time. Likewise, there is no way of accidentally shorting out the +5V supply or by frying the 855.

The downside of this is the number of relays required - two per ZIF pin (one for +5V and one for 0V). You can economise by only wiring up pins that could be power pins. This does assume that you do your homework and identify all of the (EP)ROM pinouts you may require.

Dave
 

Attachments

  • 20250630_104301.jpg
    20250630_104301.jpg
    1.1 MB · Views: 7
Last edited:
  • Like
Reactions: cjs
Another solution is attached.

You can purchase relatively cheap 3.5 mm (1/8") mono audio (panel mount) sockets. These need to be SWITCHED.

You can wire up each ZIF pin to a 3.5mm socket. With nothing plugged in, the ZIF pin would be routed to the 8255 - so it is a logic pin.

When you plug a mono 3.5mm (1/8") plug into the corresponding socket, it disconnects the ZIF pin from the 8255 and routes it to the plug.

You would have a number of flying leads (with plugs on) attached to a switched +5V and 0V supply (again, controlled my a 'master relay').

You can only plug one plug in a a time, so a ZIF pin can either be logic (no plug installed), +5V (flying lead plug inserted connected to the switched +5V supply) or 0V (flying lead plug inserted connected to the switched 0V supply).

This scheme can be extended to multiple-rail devices by doing the same thing with +12V and -5V supplies (as required).

You can have some 'dummy' sockets to keep the flying lead plugs in when not in use (to avoid accidental short circuits).

These type of audio connectors are 'cheap and cheerful' on the surplus supply market - but you require the type with the in-built switch.

Again, a modification of this idea is to use the sockets on pins that could be wired as power pins.

Dave
 

Attachments

  • 20250630_104307.jpg
    20250630_104307.jpg
    1.3 MB · Views: 6
Last edited:
Ah, thanks for that! I now understand what you're saying about there relays. And this:

When you plug a mono 3.5mm (1/8") plug into the corresponding socket, it disconnects the ZIF pin from the 8255 and routes it to the plug.
This is substantially similar to what I was thinking of for an adapter board, except I think I would make it smaller and (for me, anyway) easier by simply using two-row .1" headers for the that for "connect to logic" (or, actually, "connect to default") and, for those pins that need to change, using short "dupont" jumper cables to DTRT. Something like this:

1751291422655.png

In case it's not clear, the idea here is that this does is have a header pin connected every pin on the 42-pin ZIF socket, and we place the chip always towards the bottom of the socket. All the other pins on the board are connected to fixed GPIO pins permanently assigned to address A0.., data D0.., chip select (both positive and negative logic available) and power pins. The adjacent pins with a little red line between them are normally jumpered to the adjacent pin; these follow the common parts of the JEDEC standard pinouts for 24- and 28-pin devices. (This should probably be expanded to 32-pin devices, actually.) For all the rest, you need to use a "dupont" jumper wire to connect the pins to the corresponding GPIO connections a little further out to the sides of the board.

This is actually a complete reversal of my original plan; all the configuration for the pinout is done in hardware with the jumpers, and the software needs no changing at all. On reflection this seems the better way to go about it.
 
This still leaves the question of what safety features I can add to avoid shorting Vcc to ground when an output on one side is high and the other low.

For Vcc and GND, this seems relatively simple to me: rather than directly connecting each host pin to Vcc or ground, I have a pull-up/pull-down resistor for each host pin with a value calculated to limit the current that can flow to something "reasonable." (I am not yet sure what this is.) I guess one would do the same for the chip selects.

For the GPIO pins it seems more difficult. I don't have any internal pull-ups/pull-downs in the 8255 that I can enable/disable through software, so what I can do (if anything) to detect that, e.g., a host address output has been connected to a pin that's also driving that line and complain about that? (I think I can read an 8255 output to see if it's being driven externally to a different level than I've set, but actually I'm not sure; I know I can do this on a 6820 PIA, but have never tried this on an 8255-style chip.)
 
>>> This still leaves the question of what safety features I can add to avoid shorting Vcc to ground when an output on one side is high and the other low.

Can you give me an example?

>>> but have never tried this on an 8255-style chip.

The datasheets I have looked at do not define whether an input instruction on a port configured as an output returns the latched register output status or the pin readback status. You will have to test this for yourself.

Dave
 
Can you give me an example?
Yes. Someone connects a host address output to a ROM data output, and the host is driving that line low, but the device is driving that line high (or vice versa). If directly connected, that would be a short circuit, right?
 
Have you seen this project:
It is billed as an "Arduino-based EEPROM programmer" however it is capable of reading many devices including the oddball 23xx ROMs.

Likely you already know about this, but the ME27000 (Martin Eberhard's Orphan EPROM Programmer II) is capable of reading and programming many old ROMs that modern programmers like the T48 are not capable of handliing:
 
Thinking about it further, if I put, say, a 2k2 resistor on every output from the host, that should limit the current flow on an incorrect connection to a maximum of a couple of mA or so, which at least gives some hope that neither side will be damaged. This of course will slow things down, but I'm not to worried about speed, and it's no problem to put delays in the software to let things settle. (And, come to think of it, do multiple reads per location to see if we're getting consistent data out.
 
I was just posting a similar thing when your post came in...

I was going to suggest a nice round number of a 1k resistor in series with each output pin. This would limit the current (at +5V) to a nice round 5 mA per pin.

You may want to 'double up' on your 8255 ports though...

Use an output port with a 1k series current limiting resistor to the ZIF socket and an input port directly on the ZIF pin. This will avoid the problem of the non-standard readback of an output pin. Adding the current limiting resistor will also mess up the readback. it is highly likely that an 8255 output driving a series resistor of 1k to an accidental ROM output pin of 0V would even be detected on a readback. This way, the output should be HIGH, but the readback (via a dedicated input pin) will be guaranteed to yield a LOW.

Dave
 
Have you seen this project
I've seen various projects like this out there. But the first thing it needs to be able to do is handle whatever the heck the 42-pin ROM is from an 8086-based late-80's Japanese Word Processor I happen to have. Nothing that's just for 24/28 pin devices will do that, obviously. And even things that have a 42-pin socket may or may not, depending (and at the least they would have to have some options for dealing with custom masking of the select lines: most mask ROMs let you change the select pins arbitrarily to be positive or negative logic as convenient for the system designer.

Another thing I'd like to be able to do is build a simple edgeboard to DIP IDC cable that would let me connect carts directly to the reader without having to desolder the ROMs, such as this Super Cassette Vision cart:
1751299574882.png1751299682083.png
That kind of thing is likely to require extensive custom wiring of the pins, and PROM programmers don't generally support that.

So what I'm trying to avoid here is: I buy some existing programmer, find out it won't read my odd ROM anyway, set up a whole development system different from the standard one I use already so I can modify the existing programmer's code, figure out how the code works, try to modify it to read my ROM, discover there's a hardware issue that means I need to rewire pins, and end up building essentially this board I've discussed above to make the thing work anyway.
 
I was going to suggest a nice round number of a 1k resistor in series with each output pin. This would limit the current (at +5V) to a nice round 5 mA per pin.
Any particular reason for that value? I guess I need to go back to the datasheet and figure out what the maximum sink of the pins on the 82C65 is.

You may want to 'double up' on your 8255 ports though...
Use an output port with a 1k series current limiting resistor to the ZIF socket and an input port directly on the ZIF pin. This will avoid the problem of the non-standard readback of an output pin. Adding the current limiting resistor will also mess up the readback.
Ah, excellent point! The only question is whether I have enough GPIOs to do this. (And here I was thinking that with two 8255s and a Z80-PIO I could never run out.)

So, with a maximum of 42 pins on the ROM, subtracting two for power and 16 for data, that leaves me with 24 I need to double up, for 48 outputs and 16 inputs, which exactly uses up everything. It could work.

That said, that seems to be heading towards that unfortunate area where I keep adding complexity to my designs to the point where I never get the damn thing built. (And it would be nice to have the option of making this work on a different system with just, say, two 8255s. Such as an I/O card or two that I happen to have for my PC-8801.) So I think I might go with protection but no detection here, at least as the first step.
 
Agreed!

But the design is still on paper - which means you have made the necessary decisions with all of the facts at your disposal.

Dave
 
The power and ground problems reminds me of my solution to a generic retro-computer tester. Instead of PIO, I used a CPLD so input/output can be reconfigured for a particular CPU being tested. For power and ground pins, there are two pigtail with pin sockets, one is VCC other is ground, to plug into the corresponding VCC/ground of the particular CPU. 1K series resistor for every pin is a good idea to guard against contentions, but I didn’t implement that idea.

https://www.retrobrewcomputers.org/doku.php?id=builderpages:plasmo:protor5:anycpu
 
  • Like
Reactions: cjs
Ah, that's a much more readable schematic. Thanks.

It does point out a typical example of problems that would cause me pain with other readers. For example, unless someone mucks about with the software, this can't dump a 2364 (or at least, not some 2364s) because it's got A12 hard-wired to pin 2 of a DIP-28, but that needs to be on pin 21 of a DIP-24, where A11 is hardcoded. (And pin 21/DIP-24 is actually a chip select of varying polarity on xx16 and xx32 devices.

And I've got to say that the DIP switch makes my head hurt slightly; I find the idea of just directly wiring jumpers pin to pin easier to think about. Though that's probably in part because I need to fully understand the pin layout of any ROM I want to dump, rather than just thinking of it as a "23128" and looking up settings for it.

And that also makes me realise how this board deals with the potential for misconnection of programer outputs to device outputs: it simply can't happen because it's so heavily hardwired. Unfortunately I'm not able to go so far with hardwiring, so I guess I just have to live with the risk in my design.
 
Back
Top