Yes, I still use the same hard disk platter as a drink coaster. But I need more ISA cards in my collection.


cr1901
@cr1901

This post was written in January 2022, for a friend's project that's not public. I have permission to post a modified version here.

ATD M117

The ATD Model M117 is an ancient memory expansion ISA card for IBM PC and compatibles, especially 8088-class systems. The M117 can expand a system with up to 384kB of 4164-type and 41256-type DRAM, and the address ranges that the card decodes is configurable using 4 DIP switches. Most of the card's intelligence is inside a PAL16L8 chip, whose behavior is configured using 3 of the 4 DIP switches. This is the main reason the card is rather small.

For the longest time, my M117 was broken, and I was not able to figure out why thanks to not knowing the correct switch settings, which I accidentally changed from working settings long ago. If the switch settings are on TH99, I was unable to find them. I knew from when I got the card that it supported at least 384kB of RAM, because the card came with my IBM 5150 with 384kB of RAM. But 3 banks of 9 DRAM chips each implies that at least one bank will have 256kB 41256-type DRAM. Not only did I never knew the switch settings, I forgot long ago which bank(s) should house the 41256 DRAM :).

I thought trying to fix the card would be a good learning experience, so I RE'd a schematic to figure out the PAL connections (thank goodness for continuity testers!), and then wrote some gateware to dump the PAL. Documentation on the gateware and the schematic can be found on Github. In fact, the above paragraphs were copied from the README.md on Github!

What Is A PAL?

A PAL- or Programmable Array Logic- is an electrical device consisting of a PROM (Programmable Read Only Memory) and digital logic connected to said PROM that is optimized for implementing arbitrary digital logic functions. They are useful for replacing tens of smaller devices in a single package, such as 7400-series chips implementing AND, OR, NOT, etc primitives. However, replacing many smaller primitives means that the PAL becomes effectively a black box. The PAL's functionality must be extracted from trying all possible inputs and outputs; tracing a PCB for connections is necessary but not sufficient!

While most pins on a PAL are either inputs or outputs, some pins can be programmed to be input, output, or bidirectional. I had to infer these pin's directions from context by tracing which components the PAL pins were connected to using a continuity meter. And even after I figured out the pinout of the PAL- a PAL16L8, to be specific- I had to create a circuit to read out the PAL's and store the input-to-output mapping in a text file.

PAL Pin Mapping

Through tracing connections to the PAL with my continuity tester, I was able to figure out which pin goes where on my ATD M117. Note that according to the datasheet pins 13-18 inclusive are bidirectional,

The pin functions can be divided into groups:

  • SW1-3 are user-programmable switches; SW4 is not connected to the PAL and controls whether a parity error halts the system of not. These are the only user-facing inputs into the PAL.
  • A16-A19, Delayed /SMEM{R,W}, /REFRESH, /SMEMR, and /SMEMW are control signals from the rest of the computer system to the ATD M117. Delayed /SMEM{R,W} is the logical AND of /SMEMR and /SMEMW, delayed by one clock cycle of a 14.318 MHz (4*NTSC Colorburst) signal.
  • DRAM A8 All Banks, /CAS Bank 3-1, /RAS All Banks, and /WE All Banks control the DRAM. How the old-style DRAM interface works is beyond the scope of this post, other than to mention /CAS Bank 3-1 needs to be one-hot for proper card operation.
  • Data Bus Direction is a signal the card uses to control data transfer direction between the card and computer.

If you're interested in seeing how all the signals connect together, I provide longer-form descriptions on my Github repo. You can also consult the RE'd schematic above, which is also on the Github repo.

PAL PinSignal NamePin Direction
1SW 1I
2SW 2I
3SW 3I
4A16I
5A17I
6A18I
7A19I
8Delayed /SMEM{R,W}I
9/REFRESHI
10GNDPWR
11/SMEMRI
12DRAM A8 All BanksO
13/CAS Bank 3O
14/CAS Bank 2O
15/CAS Bank 1O
16Data Bus DirectionO
17/RAS All BanksO
18/SMEMWI
19/WE All BanksO
205VPWR

Dumping the PAL

I dumped the PAL using a custom FPGA gateware I wrote using the Amaranth Hardware Description Language. The gateware:

  1. Drives the PAL's inputs.
  2. Reads the PAL's outputs passed through a level shifter.
  3. Dumps the read data to a USB-to-Serial converter.

As-is, the gateware was explicitly written for the iCEBreaker FPGA using its PMOD connectors, but there is no technical reason it couldn't be adapted to many other boards if necessary. I just wanted to write a gateware fast :D. Unfortunately I don't have a picture of my circuit setup before I tore it down to reuse the breadboard for another project :(.

Pal Input/Output Logic Functions

Each of the output pins of a PAL can be represented in terms of a logic function of the input pins. I dumped the PAL in two formats- a CSV-formatted file for my friend, the other a text file for manual analysis using the standard Unix fare (although I ended up using both files, as seen in the next section).

Manual Logic Minimization Using Unix

Yes, I did logic minimization using Unix text processing tools rather than an actual logic minimizer I really wanted to fix the card there and then, and I couldn't find a Quine-McCluskey or similar solver that worked well.

Manual Process

The PAL has 11 inputs and 7 outputs- that is 2048 possible inputs I have to examine for each output! I made the analysis easier by dividing the 2048 inputs into octants- one for each of the 8-possible switch settings. Note that for reasons I don't remember, switch settings are the last input bits in the text file, but the first input bits in the CSV file.

Let's look at the value of the /RAS All Banks signal for all 256 possible inputs for switch setting 0,0,0:

RAS_BIT_POSITION=13
grep "^0,0,0" adt.csv | cut -d',' -f$RAS_BIT_POSITION | tr --delete '\n'
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000011111111111111111111111111111111

Based on the above, /RAS All Banks is usually 0. Let's extract the input values for which /RAS All Banks is 1 (remember that bits are reversed between the text file and CSV):

RAS_BIT_POSITION=2
OUT_IGN1=`expr 7 - $RAS_BIT_POSITION`
OUT_IGN2=`expr 7 - $OUT_IGN1 - 1`
grep -E "000: .{$OUT_IGN1}1.{$OUT_IGN2}" adt.txt
11100000000: 0111111
11100001000: 1111111
11100010000: 0111111
11100011000: 1111111
11100100000: 0111111
11100101000: 1111111
11100110000: 0110111
11100111000: 1110111
11101000000: 0110111
11101001000: 1110111
11101010000: 0111111
11101011000: 1111111
11101100000: 0111111
11101101000: 1111111
11101110000: 0111111
11101111000: 1111111
11110000000: 0111111
11110001000: 0111111
11110010000: 1111111
11110011000: 1111111
11110100000: 0111111
11110101000: 0111111
11110110000: 1110111
11110111000: 1110111
11111000000: 0110111
11111001000: 0110111
11111010000: 1111111
11111011000: 1111111
11111100000: 0111111
11111101000: 0111111
11111110000: 1111111
11111111000: 1111111

The last three bits before the colon are the switch settings and therefore don't matter here. From visual inspection alone, I can tell that /RAS All Banks is only high when the top 3 bits are 1; the middle 5 bits count out the binary values from 0 to 31, and can be treated as don't care.

The top three bits correspond to /SMEMR, /SMEMW, /REFRESH signals respectively, so I believe that the logic equation for the /RAS All Banks signal for switch setting 000 is:

/RAS All Banks == /REFRESH && /SMEMW && /SMEMR

In other words, /RAS All Banks is only 1 if all of /SMEMR, /SMEMW, and /REFRESH are also 1. I know based on how 4164-style DRAM works that this is a reasonable-looking logic equation for controlling the /RAS signal on these DRAM chips. In fact, the same logic equation is used for all (implemented) switch settings.

I repeated this process for the /CAS Bank 3-1 and A8 DRAM All signals for the remaining 7 switch settings to extract their logic equations, and wrote some scripts to help automate the process. In all cases /CAS Bank 3-1 are one hot signals (only one of the three, if any, is ever low for any input), so I am fairly confident that I dumped the PAL correctly. It is hardly efficient or elegant, but it worked! And it was quicker than fighting with getting a dedicated boolean equation minimizer to work!

Aftermath and Future Directions

The above signals were all I needed to RE in order to figure out switch settings and ultimately fix the card. The PAL was fine; there was another chip that was indeed bad (one of the 7400-series multiplexer chips, I don't remember the exact part). However, without REing the PAL, I would've not have had enough information to know which signals were which, let alone which signals weren't functioning properly because of a bad chip.

I deliberately have not RE'd the /WE All Banks nor Data Bus /OE signals yet. A friend is working on a project in the spirit of the ESPRESSO bool minimizer, and I want to test her tool using my RE'd truth tables.

As of right now, the M117 is currently back in my IBM 5150 and has been functioning properly since I desoldered and replaced the bad mux chip. It's been a few months- I should run another thorough memory test soon.


cr1901
@cr1901

Maybe I should do a post like this once every week, even if it's short. And then combine relevant posts into actual blog posts on my website. We'll see how long this lasts.


You must log in to comment.