Exidy Sorcerer ROM PAC replica

March 10, 2024

I’ve talked about the aftermarket expansion modules I reverse engineered for the Sorcerer, but what about something first party? I was going to wait because I haven’t been able to get it to work completely, but that may be the fault of the sorcerer I have, not the reproduction. Today I bring you a replica PCB of the ROM PAC.

Now hold on, some of you have realized something silly about these, but we’ll get there I promise. These are the ROM expansion cartridges for the Exidy sorcerer. By 1981 they released six first party ones from what I could find.

  • EPROM PAC (DP 2001)
    • for making your own PACs, this was essentially a ‘blank’ one with a label so you could write what you put on it (board was set for 2716s, not the PROMs in the others)
  • Standard Basic (DP 2002)
    • I can find a couple ROMs of these out there, I think at least one is a homebrew fix, but there may have been two OEM releases
  • Wordprocessor (DP 2004)
    • This is referred to as an early version of Spellbinder, how apt
  • Development PAC (DP 2003)
    • Z80 development tools for assembly programming
  • Auto Program Load Pac (DP 2005)
    • Automatically loads and initializes CP/M operating system on Sorcerer power up or reset. Used for Display/ disk or Floppy disk (DP 6300 or DP 6400).
  • Terminal Pac (DP 2006)
    • Transforms the Sorcerer keyboard computer into a glass teletype unit. This turnkey communications software powers-on with a menu of selections including parity, stop bits, 300/1200 baud and full or half duplex

Those are just the first party ones that I could find, there’s also the:

  • Software Source Disk Pac
    • automatically boots your disk when you press RESET or switch on your Sorcerer
  • IOPac
    • adds ROM, RAM, and parallel memory mapped IO
  • The Ultimate Pac
    • a battery backed RAM cartridge with selectable write line to make it act like ROM (or partially like ROM)
  • RAM PAC
    • just a regular PAC fitted and jumpered for the 6116 SRAM chips and with the write line hooked up to an unused pin, this should be able to get you 56K of contiguous memory which is good for CP/M.

I have a sorcerer 1 and an old revision BASIC pac, so let’s take a look.

This is the inside of my (non-functional) basic cartridge. It is now time to talk about that shell. You can see inside and it’s very obvious that the shell is made from an 8-track cartridge. They even snapped off and melted some of the internal plastic to make the PCB fit. Another detail is that the cart is inserted into the machine component side down. This is important if you want to try things out before reassembling. Now why was my cart not working? I had a bad ROM chip. I removed and tested all the ROMs in the cart against the ROM images floating around on the internet and I found that I had a bad EXSB1-2. To determine this I had to ‘build’ an adapter to dump the ROMs I had.

I plugged it into a standard chip tester, but into a socket so I could lean one leg out and have it not be in the chip tester. I then clamped a 24 pin chip clip on top and wired that pin to ground like the pac pcb did for reading. This is because the mask ROMs in the cart are almost but not exactly a 2716 pinout, the difference is pin 21 on the AM9218 is a programmable chip select and Exidy programmed it to require it to be grounded. On the 2716 that pin is Vpp and should have 5v on it while being read.

My fix there is to pull that pin out of the socket and solder it directly to 5v on pin 24. The board, as you can see, has jumpers you can cut in order to set the pac for different types of ROMs. I’ll obviously keep that in my replica, but what do all those jumpers do? This gets complicated. Let’s look at the schematic one section at a time.

The sorcerer is unique in that it combines address line A15 with the read line meaning that it is high only if:

  • there is a memory request
  • the request is a read
  • it is not a memory refresh cycle
  • a15 is high (it is in the top 32k of memory)

One of these interferes with the features of some of the pacs described above, but we’ll get to that later. How does this get implemented in the cartridge?

lots of cuttable jumpers. We have 7 jumper blocks and I’ll go through them out of order and one at a time.

Jumper block 7 determines which lines must be high to enable the ‘LS138 decoder. You have a choice of any combination of: A15, A14, and A12. A15 is already required to be high, but for the other two you can pick. You can even pick to have only A15 being high as needed. The configurations are:

  • ROMRD15 and ROMRD15
    • enabled for all regions $8000 to $FFFF
  • ROMRD15 and A14
    • enabled only for the upper $C000 to $FFFF
  • A14 and A12
    • enabled for two non-contiguous regions, $D000 to $DFFF and $F000 to $FFFF but only the first one can be read from the cart slot
  • ROMRD15 and A12
    • enabled for four non-contiguous regions, $9000 to $9FFF, $B000 to $BFFF, $D000 to $DFFF and $F000 to $FFFF but this would put the next decoding section into nonsensical areas so I don’t believe it was ever intended to be used

Jumper block 6 determines how the regions enabled by block 7 are split up. You have available A10, A11, A12, A13, and A14 to pick how finely to divide up the larger region. This all gets very complicated very fast. The ‘LS138 uses 3 of those address lines, in whatever order you want, to decode to 8 evenly spaced regions of memory. Of those regions of memory two are fixed to two specific ROM locations (U3 and U4) and two can be remapped from banks 0 and 1 to banks 4 and 5. Through these combinations you can choose how broken up the memory map gets and which ROM each region enables. The overarching truths are these:

  • If you use 1K ROMs, you need to use A10 somewhere so it splits into 1K chunks and the different ROMs end up contiguous
  • If you use 2K ROMs you need to use A11 somewhere but not A10 so it splits into 2K chunks
  • If you use 4K ROMs you need to use A12 somewhere but not A11 or A10, same reason but 4K

Beyond that where you place the address lines determine what order the memory map is decoded, so to which pins the chip enable signals are sent, As mentioned above only 6 of the 8 signals on the ‘138 go anywhere we can use and of those two are mutually exclusive with the others and the remaining two are fixed. To decide where we actually want these ROMs mapped we need to look at the overall memory map of the sorcerer

This is from the sorcerer 2 technical manual, as a note the sorcerer 1 could be equipped with as little as 8K of internal RAM and that would obviously be from $0000 to $2000 as you could extrapolate from this picture. From this picture you can also see three different sizes of ROM PAC: 4K, 8K, and 16K. So for our PAC we will want to decode ROMs to fill those sections and only those sections to be used as different sizes of PAC.

  • for a 4K PAC we want to fill from $D000 to $DFFF only, and that can be done in three ways
    • 4 1K ROMs at $D000, $D400, $D800, and $DC00
    • 2 2K ROMS at $D000, and $D800
    • 1 4K ROM at $D000
  • for an 8K PAC we want to fill from $C000 to $DFFF
    • we only have 4 spots for ROMs so this cannot be done with 1K ROMs without doing some DIY stuff that’s beyond the scope of figuring out how to strap these jumpers
    • 4 2K ROMs at $C000, $C800, $D000, and $D800
    • 2 4K ROMs at $C000, and $D000
    • 1 8K ROM is not possible with simple jumpers because the only 24 pin ROM I know that is 8K is the 2364 and that would need A12 on pin 21 and A12 is not brought out to these jumper blocks
  • for a 16K PAC we need to fill all the way from $A000 to $DFFF
    • The only way we have to do that with this board is with 4 4K ROMs at $A000, $B000, $C000, and $D000 for the reasons mentioned above

You can make other configurations that are non-contiguous and that use different sections for different things (like the IOPac above) but for this board, I think these are the intended configurations. But why is it so important to only map the ROMs we intend to use?

Well, here we have some AND gates that are acting like inverted logic OR gates. That means if either input is low, then the output is low. This generates a signal called ROMPRE or ‘ROM Present’. What this does is it tells the sorcerer that there is a ROM there and to turn off accesses to anything else that may be in that section of memory. This sort of works like the PHANTOM line in the s100 world which lets two things exist at the same location, but you decide which one to access and then disable the enable signal to the other. In a normal sorcerer memory map there is nothing in the same section of memory as a 4K or 8K PAC, but the 16K PAC overlaps the top RAM if you have a 48K system. If you have something that expands the sorcerer on the rear 50 pin connector like the S100 chassis then anything could be in that section of memory and it needs to be disabled when the 8K or even the 4K PAC is installed.

I mentioned it breifly above, but two of those decoding signals are not cut-and-jumperable which means they will always disable other chunks of memory when they are activated. This means certain jumper configurations of the PAC can screw with other areas of memory that we may not be intending to take over. To decode all the many possibilities Frank helped write me a python script to generate mappings for different configurations. It has the following things to try:

  • All combinations of block 7
  • All combinations of block 6
  • whether to set block 5 to the a, b, or neither set of jumpers

The output of that script helped make this mappings file that details which memory blocks decode to which ROMs

This helped determine the configurations for the PAC that are valid. Obviously with some tinkering you can make it do different things, you could even add chips to make some areas RAM and some areas ROM. We should talk about that, but first I can show you how I made my boards a lot more user friendly.

You can see that I labeled each pad and also indicate which pads were originally jumpered for the PROMs in the standard PACs with silkscreen (not in the copper layer though, I didn’t want you to have to cut anything, just solder).

And on the back, oh boy. It’s free real estate as they say. I have what I consider the master configurations of all the variants you could want for memory mappings and ROM sizes. I also indicated the pinouts of the most common ROM and RAM chips so you know how to set the individual jumpers for pins 18-21 on each chip. I keep saying RAM though, and above we saw a schematic that showed the ROMRD15 signal has the memory request and the read signal both mixed into it so it will not go high during a write. Well, that was true for the sorcerer 1…

The sorcerer 2 leaves out that signal. This means that if there is a write to a memory address in the PAC region, the chip enable signal is also set. That write signal has to reach the cartridge though, so how does that happen?

The sorcerer 2 took an unused pin and added write to it. Why didn’t they hook it up all the time? Well, look at my OEM cartridge and see how that one pin is massive? That’s ground, and it connects both pins 28 and 30. Look at the same spot on my cart and you will see I put a cuttable jumper there (actually it’s not connected in the copper). I did that so that when my cart is inserted into a sorcerer that has pin 28 hooked to the write pin it doesn’t try to ground that signal. The OEM cart didn’t do that and people were instructed to take their original carts apart and carve a groove in the copper there to separate the pins so it doesn’t cause issues. I’m not one for hacking up original carts so I made a general purpose solution to protect your RAM modded sorcerers from rampaging original ’70s carts.

The sorcerer extension cart. Or, the ROM PAC to ribbon adapter. Or just the Cart condom. This does three things, it extends the cart slot outside of the sorcerer case, it provides you a place to stick a ribbon cable to a breadboard and develop your own carts for the sorcerer (or just read some bus signals), and it disconnects the write pin so you can plug in old carts without any concern for damaging anything. New sorcerer owners may not even know that they have one that has this potential issue and with this you just have an abundance of caution. If it wasn’t obvious to make this work you solder a cart slot on the left side of the board, but edge mounted. Another way you could solve this is to put a schottky diode on the write line so that the write line can only pull down, but if it’s not writing and tries to assert that pin as high then it’s blocked by the diode and a pull up resistor is on the other side. In that case if you plug in a cart that grounds that pin you are simply wiring that pull up across 5v to ground the entire time the cart is inserted. It’s not ideal, but it may work. The problem is at around 3Mhz is the diode fast enough and will it give a crisp enough edge to work reliably. I dunno, so following all period mods I just made the add-on board.

So how are you supposed to jumper the PAC for RAM if the write line isn’t at any of those pads for configuring each chip? well ,this is how.

the write pins, as indicated on the silkscreen on the back of the board for 6116s are connected to the write line on the cart connector. I’ve actually run into a conundrum here. The sorcerer 2 enables the ROM PACs whenever a memory request is being made to or from the top 32K of memory. If there is a ROM PAC installed, it disables any other hardware that might respond to that request in the regions it is present. However, what happens if you have ROM there and not RAM and the sorcerer tries to write to that area of memory?

Here I have the truth table for a 6116. Based on my jumpers outlined in the silkscreen /OE is always low so we can ignore line 3. When the chip is not selected, it disconnects itself from the bus, that’s the top line. When the chip is selected and the write line is asserted, the chip is in write mode and takes in the bits on the bus. When the chip is selected and not in write mode it is outputting bits onto the bus. That’s fine for a chip that is aware of the write signal, but what about a 2716 that is not aware that it’s a write that’s trying to happen?

Based on the jumpers indicated for the 2716 we have 3 available modes, and that’s really 2 because read and verify are the same thing for us. So we are either outputting data on the bus, or we are disconnected from the bus. A regular ROM PAC in a factory sorcerer 2 or a sorcerer 1 modded for write capability seems to have bus contention if you try to write to a section of memory and a ROM PAC is installed. But contention with what?

Here is the CPU side of the data bus during that contention event. The data bus is buffered through an 8304 tri state bus transceiver. I think of this as a late ’70s 74LS245, as you notice they are using ‘241s everywhere on this schematic, but no ‘244s or ‘245s. That chip is hooked up so the lower current capable side is out towards the bus which seems backwards, but maybe that’s to prevent the harm it could cause if there’s some serious contention. What sort of specs does it have?

We have in the datasheet that it will sag the voltage to as low as 2.7v on the output if it tries to output a logical 1 and has to drive as little as 3mA, but the converse shows that it can sink 16mA of current and it’s only a max of 0.5v off of ground. I read this as the chip is good at pulling down, but sucks at pulling up. That’s pretty standard in the TTL days, so when there is bus contention the chip outputting a logical “0” will inevitably win and the other chip won’t be too bothered by getting pulled down. It’s kinda like everything is open collector with a weak pull up, but all that is inside the chip. Now we know what will happen if there is contention, do we know it will happen? I know the sorcerer’s monitor ROMs can detect how much RAM you have installed at boot, so it must be checking that somehow.

Here’s the ram check code. In summary, it starts at 0 (you’ll have to trust me that “RAM” was initialized to zero up above) reads what’s there in to A and B, inverts A, writes A back to the same memory location it came from, checks if it is the inverted or the original version, then puts it back from B (how it was originally). Once it has done that it checks to see if the inverted write took, and if it did it knows RAM is there and increments to the next location and tries again. If it hits a point where it writes something and when it reads it back that’s not the same then it knows it tried to write to ROM and it stops, backs off two locations and says that is the location of the top of RAM. In this case a factory sorcerer 2 with 48K of memory and an 8K ROM PAC (like standard basic) inserted will have two instances of bus contention every power up. I didn’t think this would be how it works, but I guess it is. Now, how can we fix it?

I don’t think we do. I mean, you could modify your cartridges that are ROM only to have a separate gate in there to detect a write and disable any ROM chips. That would mean modifying every cart that might be plugged in to your sorcerer though.

I know I could 3d print cases for these, but with innumerable 8-tracks being broken, or super common commercial releases not worth saving I decided to do some recycling and get a bunch from estate sales to make into shells. I happened to find the exact mold the sorcerer carts are meant to fit in.

If you ever want perfect replacements for sorcerer PAC shells, get yourself some AudioMagnetics Tracs 90 carts and it’ll be the right mold. Just clip or melt out the right sections and you’re good to go. You can find my ROM PAC board design up on github here, and my protection/experimenter PCB is also up in the same repo. I hope to get around to documenting more of the standard recommended mods to a sorcerer 1 soon because that will give me a single place I can refer to remember what I did. This is a fun machine where in order to make it work as intended you need to cut and jumper a bunch of stuff.

DuPAL quality of life upgrades

March 2, 2024

Having the need to dump PALs means that this piece of interesting equipment came across my desk. The DuPAL is a device based on easy to find parts that can use brute force to determine the equations inside a PAL so you can make more of them for reproductions, backups, or just to understand how a circuit works. I decided to get one, but honestly it wasn’t the easiest thing to build and I wanted to make some upgrades for the sake of usability. I have tried other methods with mixed success.

Having watched some videos and read the github readmes it was a little annoying to set up, but I’ll give you a rundown here:

  • solder together the board
  • download and compile optiboot for the atmega328 with a 20mhz crystal
  • program the fuses and flash of the atmega328 with the bootloader (I used the ICSP header)
  • download and compile the dupal firmware
  • upload the firmware to the dupal over serial

I don’t really like this method where there are no binaries I can find for this thing even though it hasn’t significantly updated in over 4 years. I also don’t get why there wouldn’t just be a binary for the bootloader and firmware together so I only have to flash it once. When you do get it going however you will see that in order to use it you need:

  • A real rs232 serial port with control lines
  • A 12v power brick

I guess the reason for this was to make the board entirely through hole, but man do I not like that usability. So I decided to give it a simple upgrade.

I have adapted it here to be powered and communicate over a single USB C connection. For this I used a USB C breakout board that has the resistors to set it to behave like a regular usb 2.0 device wanting 5v. I also have the remains of a usb to serial converter that I don’t really like. The reasoning is that it does not use the FTDI pinout that I like and while it is 3.3v or 5v logic switchable, you cannot really power the target from it in the factory configuration:

That picture isn’t the exact variant I had, but it shows why I don’t really like it as a piece of test equipment. I don’t have anything against the CH340G though, it has the DTR pin that I needed for the communication to work properly so I simply connected to it on the SOIC and ran that to the spot on the board where it would come out of the max232 if I were using one. The DTR pins is used to hit the reset line through a 100nf capacitor just like the old school arduinos do. That is needed for both flashing the firmware and using the DuPAL Analyzer program to dump PALs (I didn’t initially have it hooked up).

Here’s two variants I built, one with USB B and one with USB C. I actually went through all this because someone asked me about dumping PALs and wanted one of my spare boards. I figured it would be nice to actually build it and prove that it worked before mailing it out. That brings up some pages I have that are not posts on this blog, the one of stuff I have but don’t want and stuff I want but don’t have. Feel free to ask for any stuff in the former list, and I’d appreciate leads on stuff in the latter.

Poly88 keyboard lid / GRI keyboard spacebar stabilizer

February 26, 2024

I modeled the lid for the poly88 keyboard (the one without the numpad). There were two variants and I have this one so I have the aluminum modeled for anyone missing theirs.

The original 0.090″ aluminum panel had studs pressed in to the inside where I have holes. Mine had three of those 4 snap off so I thought I’d put some holes and chamfer them for countersunk bolts. The originals are 6-32 and that material is just barely not quite enough to accommodate that chamfer, but I think it’ll be alright as an assembly technique.

That being said, sesndcutsend will press in studs to that material for a very reasonable price, and the whole thing assembled comes to just over $50 before shipping. I have the design up on github here even though I have not ordered that part and don’t need to since my keyboard is complete-ish. At least the enclosure is.

Between the time I posted this about building up a GRI 753K keyboard and now one came up for sale on ebay. Sadly it went for more than I wanted to pay, but I managed to snag some pictures of it so I had a little better idea of how to build the elusive spacebar stabilizer.

This is pretty good, it validates some assumptions from the original design but also shows me a problem with my parts on hand.

That’s not the same spacebar. Sure, it fits the cross shaped keyswitch, but it is not the original spacebar. Even if I had the original hardware it probably wouldn’t fit so I have to make my own anyway.

The design is pretty simple, but there are no dimensions and I can’t take this for a scale drawing anyway no matter how nice it looks. But I can get some inspiration. In order to use the hardware I had however I drilled out the holes in the board from 1.3mm to 2mm to fit some M2 bolts. From there I designed this:

Now this is a second revision that doesn’t fit so tight around the rod because the original one snapped from repeated insertion and removal. With this in place I could take a stab at the spacebar brackets.

This is what I came up with. Notice that I didn’t do the entirely captured version that seemed to be on the original design. These are somewhat based on the more modern cherry stabilizer brackets seen in this video on them

Now for the bar. This was the hardest part because the closest thing I found was some 3/32″ copper tubing and I bent/squished it with some round profile jewelry pliers. Having to keep the different parts of that colinear and parallel to each other is very fiddly and I could probably take another whack at it but this seems to actually work so I’m not going to jinx it.

That’s it. The design and iterations took about 4-6 hours total and now I have a working spacebar that kinda has an even amount of forcer across it and does push the switch and spring back no matter where you press it. I have the files up on github here if you want to see what I did, but I highly doubt these exact files will be useful for anyone else.

Ribbon to wire wrap pin adapter PCB

February 23, 2024

As part of an upcoming project I needed to connect to some wirewrap pins. These are on the back of a nice cardcage with a load of edge connectors.

The original connector that I am replacing was somewhat special, here have a look:

This is what remains of an IDC (insulation displacement connector) that spanned this 0.2″ gap between the pins. IDC connectors are basically connectors that push the insulation out of the way to get to the wire inside, you crimp them on through wire and they make contact. What I mean in this case is something like an IDE connector, it adapts a ribbon to some 0.1″ header pins. The difference here is the spacing between the long rows is not 0.1″, it’s 0.2″ which is very strange to me. Maybe this was common back in the day, but I’ve never seen a connector like this before.

If you look closely you can see these pins are sticking straight out of a card edge connector. An interesting thing about that is they are so long. I called them wirewrap pins above and I think that’s the case. I think the manufacturer designed these square profile pins to be used with wirewrap to connect them. They have very sharp corners so when you wrap the wire around them they ‘weld’ on the corners to make a solid connection (I’m not super familiar with the process). If you look closely you may also notice these connectors are press-fit into the PCB and the sharp corners bite right into the plated holes to make the connection. That means tracing out the connection is pretty hard since the connector is mounted flush on the top with no stand off to look under.

This is a schematic / wiring diagram showing where the connector interfaces with the backplane (bottom left rectangle). This backplane is somewhat interesting in that the connections do not go straight across. There is an ongoing effort to document as many variations of this backplane as we can find (so far at least one real one and one that we only have the schematic for). This connector takes about 18 signals and power from the backplane and sends it to another module. Since I can’t get that connector (and honestly even if I could this is cheaper) I designed a little interposer board to adapt it.

You can assemble it four ways, based on which orientation you place each header and how you plug in the ribbon. 0.1″ pin header fits right on these pins, just like the original IDC connector did. The spacing is such to warrant our own connector though, 0.2″ instead of the more standard narrow DIP IC spanning 0.3″. The board is almost the simplest design you can imagine, 50 pins that adapt to 50 other pins 1:1. This board is sponsored by PCBWay, but you wouldn’t know it by looking at it. It is so small I couldn’t cram anything else on the silkscreen other than what it is and where to find more information on it. When you order boards from PCBWay they usually add a small unobtrusive number somewhere on it for tracability reasons which is good, but this board is so packed they couldn’t fit that anywhere on it. That’s fine because being so simple there’s no way it’s anything other than perfect and you can tell just by looking at it.

I don’t know which orientation is correct yet, but there are parts incoming that will hopefully be keyed on one end and the layout diagram will help on the other. Originally it didn’t matter what the pinout was because the intention was to build something DIY such that the other end can be built to suit. Recently a real button / power box came up so this is in the mail:

Using the diagrams we’ve uncovered we could assemble our own, but this one from ebay is on the way. You may be thinking “breadboard spanning ribbon adapters exist for the raspberry pi, why not use those?” The answer is twofold, first we need 50 pins to pick up all the signals needed on these pins (the pi is either 26 pins or 40 pins depending on the revision), and second:

Breadboard span spacing is 0.3″ because that’s what narrow package DIP chips are, this is something special.

The documentation for the card cage and reverse engineering of this system is on github here, and this adapter board specifically is here. You can buy these at PCBWay if you want (do it unassembled please, until I know the orientation) here, more details are coming on this reassembly project for the cyberamic control system.

Exidy Sorcerer EPROM Programmer

February 19, 2024

This will be a quick one, I didn’t build this one and I don’t have any software that uses it. I did reproduce it in CAD and work out in theory how it would operate though.

I was inspired to take this on by another post from Michael Borthwick. There was an EPROM programmer available as third party content for the Exidy Sorcerer. I didn’t have anything to go on except these pictures at first.

This is my educated guess at the placement and layout of the original board. I made some changes like adding silkscreen, making it double sided , and as a result that resistor now has a second pad on the board. The switch is also different because it’s not my intention to make this super hard to reproduce.

This is also a best guess, but I think it will work. I traced the lines I could see and in shadow I looked at what the resulting schematic would end up being and made some educated guesses. I also labeled the parallel port pins and where they go so if anyone has the software they can check it, or if not they can write some.

This is what I’ve got, let’s go through it one bit at a time. The optoisolator was obvious from the package, the part number I guessed at, but it ought to work. What it’s doing is switching the high voltage programming voltage to the Vpp pin on the EPROM. The signal comes from bit 4 on the output port and cannot be activated unless the hardware switch is enabled. It is active low so bit 4 sinks current through the optoisolator while the hardware write protect toggle sources it. On the output of the optoisolator the programming voltage (labeled 9v) is switched, but through a series red LED dropping the voltage by a couple volts. On the output is Vpp, but we also have the same power controlled by the hardware switch piped to Vpp through a diode. This seems to let the Vpp pin rest at 5v until the Out4 bit commands it up to programming voltage. The switched power also powers the EPROM and the LS164.

The LS164 works, but in a limited fashion. We do not have access to DSB or /MR, but from the timing diagram we can see we don’t really need them. DSB high enables the shift register at all times and we are unable to clear it but we can keep shifting things out to make sure we have 8 good bits in there. With most of the other output bits used to directly control the remainder of the EPROM pins, how do we actually clock things in to the 164? the serial data bit is hooked to an input port bit? This is the particularly clever part.

This is the function table of the LS299. Let me simplify things a bit. The first column, labeled /CLR is the same as ~MR on our chip, and is pulled high when the toggle is flipped. That means that before it is low and the switch flip is a high going transition on that pin. We can therefore ignore the first three rows as we are not operating in that mode. The column for output control is always pulled low, both of those pins, so the outputs are always enabled. S1 is pulled high all the time so we are always shifting left, or loading (depending on the state of S0, the Out6 bit). Ds0 is the same as SR which is pulled low, but that seems to just be to keep the input from floating, when S1 is high, SR does not matter.

Those are all the states we can switch between and I crossed out the unused output. We control CLK, S0, and SL. Qa` goes to input bit 7 and the input of the address shift register (the 164 we talked about above), and the bidirectional data bus goes to the EPROM’s data bus. Here’s how I read the order of operations for shifting data in.

  • SL (output bit 0) sets the bit you want to shift in
  • S0 (output bit 6) is set low to tell us we are shifting
  • CLK is pulsed (high going pulse) to shift the bit from SL in
  • This is repeated until all 8 bits are filled
  • From here the bits will begin shifting out into the address shift register
  • Continue shifting bits through the 299 and into the 164
  • CP (output bit 7) clocks data into the 164 when it is present on the output of the 299
  • Once the 164 is filled up and the 299 is also filled up you now have data present on all the address and data lines of the EPROM
  • You can now write the data into the EPROM with Vpp and the EPROM control lines
  • repeat, shifting through the 299 and into the 164 to get to the next address and following up with data to be written
  • note: Out0 does double duty as a control line of the EPROM, but as long as you don’t clock the 299 it can do whatever and not affect things

This works using the available pins and has a very clever method of keeping the chip count down. I would have expected to add a second 164 to free up Out2 and Out3 and then using one of those to have a second serial shift path in to the 164 without having to go through the 299. Now we can write the chip, but how do we verify that it was written correctly?

  • clock address bits as shown above
  • set EPROM to output data using control lines
  • flip SL high and clock the 299 to load all the data from the bus into the shift register
  • un-set control lines on EPROM
  • flip SL low and clock out the data one bit at a time
  • instead of sending it into the 164, read it into the sorcerer on input bit 7
  • repeat, shifting through the 299 and into the 164 to get to the next address

This is a rather convoluted way of doing things, but it manages to be done in essentially two logic chips with 8 bits of output available and it only uses one bit of input. Based on the pinout of the EPROM I determined it must be a 2716 and then I found this in a Sorcerer magazine:

In this case M means machine code and H means hardware, so the program for reading or writing EPROMs did not require the Basic PAC. I can also see I was right that it was designed to program 2716 chips. But what about that programming voltage? That screenshot came from a 1982 edition of Sorcerer’s Apprentice, so what are the specs of the 1982 vintage 2716 chips?

This comes form the 1982 Intel databook and shows a programming voltage of 25v. Might it work with a little less? sure. Would it work with 9v? I really doubt it. We also have that LED ins series dropping some voltage so we need closer to 27v to feed into those 9v battery terminals, but how do we get 27 volts into there?

There, I give you 27 volts made of three 9v batteries, which also may be made of a total of 18 AAAA batteries. This is kinda nuts and you might think it won’t work, but look at the picture from the tweet again. The 9v battery snap only has the positive wire connected. I don’t think that is unintentional. I think that the ground lead used to be hooked to a separate 9v battery snap that hooked to the other side of this sort of tower of batteries. I’m making stuff up at this point, but that’s the way I would have done it, especially in 1982.

My github repo with the board designs is located here, but I never had this board made. If someone has the software to use with it I would love to test it just to prove out the design, but I don’t think this is a very practical thing to build in 2024.

TTL to composite video interface

February 17, 2024

I thought I posted about this before, but I guess not. In an effort to make up for having two *and a half* northstar advantages I wanted to have some solution for the video that the third one is missing. To that end I initially looked at the Mac SE video converter that uses a pi pico to read the video signals from a mac and turn it into VGA. Theoretically this project is similar, it just has different timings. I started down that path but when I realized the project was mostly one of software hacking I quickly looked for another solution.

Enter the zrt80 and its simple composite generation circuit. I did some reverse engineering and repair of this back in 2020 and during that ordeal I remembered that it has a nice simple example of a composite generation circuit. Being a 5v logic based device I decided to investigate the circuit to see how the stages leading up to the combination differed from the advantage.

This is the ZRT80’s video circuit. starting from the end we can see composite video is made by the 2n2222 transistor and the 75 ohm output impedance is achieved by the 75 ohm resistor so that’s good. That all makes sense for standard video. The transistor is driven by two resistors of different values, meaning that the effect that each of those signals will have on the resulting signal will be at different levels. Going into those resistors are some inverter gates so we know that’s getting a 5v logic signal. Technically TTL logic gates are a lot better at pulling down than up, so if we use the same 74-series gates that this design uses we’ll be closer to the intended voltages than if we use 4000-series CMOS gates.

At this point anything we do that has a TTL output into each of these resistors will give the right voltages, but what signals do we need? The bottom chain has two inverters fed by something, but they also feed a XOR gate with a switch on the other input that has an output labeled video out. I thought composite was our video out? Well it is, but this board can output a different video standard for different monitors. Looking above we have a single inverter that feeds our composite out but it also feeds that XOR gate and the output is labeled composite sync. From this it looks like we can drive a composite monitor or one with a separate composite sync and video signal. The video signal is what you would expect, it contains the pixel data for the screen, but the composite sync tells the monitor when it is done with a horizontal line or a vertical frame (one whole image). Feeding that composite sync we can see that horizontal sync and vertical sync are XORed together to generate that composite sync.

In this case the horizontal and vertical sync come straight off the CRTC video generation chip, but will this exact circuit always work? Those XOR gates with the switches are interesting, what do they do? They are effectively used as selectable inverters. If the input with the switch is high, the output is the inverted state of the other input. If the switch forces its input low then the output is exactly the same as the other input. This is because the output is high when only one input is high, exclusively, so not when both are high (and like any other OR gate, not when both are low). Those switches are because different monitors want different polarity video and composite sync signals. We can use this technique later.

This is the video output section of the Northstar Advantage. These schematics came from a guy who has actual paper manuals for the northstar advantage 8/16 (the motherboard I think is needed to support the northnet server card) and I have uploaded these nice, legible scans to the internet archive. Looking at the right side for now we see the video connector. 12v power, ground, video, negative logic horizontal sync and negative logic vertical sync. Feeding into that however we see three more of those XOR gates set up as selectable inverters. It looks like the northstar advantage motherboard was made flexible enough to allow for different monitors to be installed without changes to the board except for a couple jumpers.

How is the video on the advantage being generated though? Well this schematic I grabbed from an apple 2e to show how standard some of these techniques are. Here you can see the same LS166 shift register hooked directly to a ROM where a whole byte can be shifted in and then clocked out one pixel at a time. The Advantage still uses a 166, but it is a lot more sophisticated. Instead of pulling from a fixed character ROM it pulls from a bank of RAM. This display ram can be filled with arbitrary data that means you can address every single pixel on the screen. The older apple design is set up to just show specific sequences out of the ROM it came with.

I showed how the video was generated, but how about the horizontal and vertical clocks? Well, on the Advantage that is done with the timing PROMs. Basically there are high speed ROMs that operate as fast as logic circuits so rather than having a big arrangement of OR and AND and other gates, these PROMS output a specific set of bits as an output for a specific set of bits as input. It’s a pre-computed logic table. This particular computer syncs the screen refresh rate to the frequency of the voltage coming in to minimize flicker on the CRT and that means there are 50hz and 60hz timing PROMs for it.

Each PROM, or set of PROMs will generate a waveform like the one shown above. This has a lot of implications for memory cycles, RAM access, but also the horizontal or vertical sync timing. Helpfully the PROMS are all detailed in the technical manual so you can recreate them if you have a bad one (that’s where these pictures came from). Unhelpfully all the PROMs I had in my machines differed from the ones in the manuals. I figure they made some changes between when the manuals were printed and when the machines went out for final production. I have the real PROMs archived as well, but I haven’t done a deep analysis except to check that they are all at least a little different.

With complete control of the CRT’s horizontal sync and vertical sync you can drive the tube at a range of frequencies and it will obey the commands to move the beam to the next line or move it back to the top of the screen. The sync information is literally driving analog circuitry in the monitor to steer the beam around and if the components in the monitor can work at different speeds, then you can have timings that are not quite the same as NTSC composite video. This is the sort of monitor the ZRT-80 could connect to all the way back up at the top, one with separate sync and video inputs. The essential information here is that I could edit these PROMs to be more exactly NTSC video timings, but if this is close enough I won’t have to muck with the other aspects of the RAM timing and such.

This is my generic polarity selectable TTL logic to composite video generator. I based the circuit off the one in the ZRT-80 but I made each input individually polarity selectable like the advantage has on its outputs. That makes this design fairly generic and able to be used on a variety of computers to replace monitors that may have failed or video outputs that did not fir the composite video voltage levels. You could even hook this up to a raspberry pi pico or an FPGA and use it to generate a good solid composite signal as long as your video timings were correct.

I made one on some protoboard to test, especially because I wasn’t completely sure the polarities I needed for my advantage (the rest of the manual is detailed, but questionably accurate at this point). By using this I determined experimentally the right settings and produced a board design.

And here is the board. This project was sponsored by PCBWay and as usual everything turned out great. The silkscreen is nice and crisp, the corners are rounded and smooth, everything worked alright. I think for my next rounds of boards I will start rotating through their soldermask colors because while I’m impatient and green is usually faster, I don’t always end up getting to these projects right away anyway and having some other colors around sounds cool.

There’s available inverters if you want to use the spares for something, but I tie the inputs to ground. Because TTL chips pull down with a transistor, but the outputs just float high with a resistor having the outputs go high burns less power when they’re unused. My little board also has a 7805 regulator because the video connector for the advantage monitor only exposes 12v to power it so I can use that and make 5v myself on the board. It’s a TO220 instead of the 78L05 or something else because these are more readily available as salvage and I have a bunch to use up. You may also notice, if you’re not colorblind, that I don’t always use the exact resistors called out. In this case I called out 4.7k resistors as pull ups, but I used 3.9k resistors. I did that because the additional current draw is negligible, but also I had them in large quantities and for pull ups they work fine. In my case, building one configuration that I will never change the polarity on I didn’t need pull ups, I could have just tied each input high or low and saved a little current in resistor dissipation.

I have a pass-through pin header so I can plug this into an advantage and have the original monitor also plugged in if it has one.

There you go, it’s not perfect, but it works pretty darn well for something that’s not even supposed to support composite video out.

There’s a little silkscreen explanation on it for my use, and some lines to indicate how to use the inverters (which input go to which output). I have the board up on PCBWay if you want one for yourself. Or you can go check it out on my github if you want to make some changes to optimize it for your use case. I know I didn’t make it super compact or low chip count, this just uses what I had to be as generic as possible.

Exidy Sorcerer Sound ‘Card’

February 15, 2024

I’m going to start with my documentation of work done on the exidy sorcerer with something easy, a parallel sound ‘card’. This device is something that’s period correct (it was available at the time by magazine order) and there is extant software to use with it. If you’re familiar with the Covox Speech Thing for PC parallel ports, it’s kinda like that.

This is the original Howard Arrington sound card found and reproduced by Michael Borthwick. This guy has been doing some excellent work in the area of Sorcerer preservation and recreation.

I met a guy at VCFMW in 2022 That had one of these recreations and I took note of the board design differences between the original and this one with a switch for ‘music or game’ mode. So I decided to do my own version of this project.

This is my variation of this project, I rounded the corners, added a small switch that is not in the 3d render for kicad properly, and changed the connectors to things I find easier to use (right angle connectors, and a headphone jack so you don’t need an adapter to some powered speakers). This was cool and all, but there was something bugging me.

Here’s the schematic for the sound card. It’s very very simple in that it uses a TTL inverter to drive a resistor ladder made of mostly R-2R math to make it function. There’s a little bit of dc blocking and level conversion for the output, but there’s not much else to it. It turns out that ‘game’ switch changed the most significant bit of the DAC from bit 7 to bit 0 of the parallel port (seen in the technical manual here. It appears that the music program uses a whole byte of parallel data, but the games only use one bit for sound. That makes sense since these things are all aftermarket and support for the third party peripherals would vary in software. The bodge wire that was done to the original design allowed for it to be used with games that would never originally work with it. Now why would a program that uses the whole 8 bit port only use the upper 6 bits and not even connect the lower two? It looks to be a limitation of how many gates are on the chip.

Well, it appears the software folks made use of all of it and the hardware folks cost reduced it for mass consumption. But with 5% resistors would it even benefit from the least significant two bits?

Python to the rescue! With Frank’s help we plotted the voltage at the output for a 6-bit setup (ideal 6-bit values) and then we plotted the range of values we could get if we had all 8 bits of data but they were all at the max or min of that 5% range. What we found was that for certain values near the high end we could certainly tell that there was not a full 8 bits of resolution and you would be able to hear it. I can see why they wouldn’t bother for a device made of parts with ’70s or ’80s pricetags, but with modern stuff we can double the chip count and not really care. That being said, if you use 1% resistors (like most 0603 resistors are these days) then the range where you can be sure to hear a difference from the 8-bit sound is the entire range. The schematic can just be extended with two more gates driving the mixed audio rail through two more resistors.

[EDIT] The original does seem to use 1% resistors, just not in the non-sound parts. So the 8-bits would even have helped back in the day.

Here’s my condensed surface mount version of the sound card. The resistor values are fairly obvious, you just continue out the parts in the chain of doubling. Above ~80k we get ~160k and then ~330k as in the python script. With those bits populated you could actually leave the switch in the music position the entire time, you would just get very very little sound on games that only use bit 0 for sound.

I ended up getting the wrong package for the logic chip, I’m sure I could find a smaller one, I just didn’t think to check the chip width. My boards for both the updated surface mount version and the original-ish one are up on github here along with the python for calculating the voltage at the output of each resistor ladder configuration. I still have a couple of the surface mount boards (I never made the older design) so if you want one ask. After I’m out I’ll probably upload them to PCBWay so you can get them to assemble one for you.

Atari Lynx low battery circuit

February 15, 2024

In trying to diagnose the atari lynx issues I’ve been having I was very confused by this circuit:

U10 here is labeled on the schematic as S-8054. The two that I have are marked T7 64 and T7 21 indicating an abbreviated part number of T7. The Datasheet I found has the part numbers and their features, but not the abbreviated part number table so I don’t technically know which one I have. The circuit has this voltage detect IC connected to the input voltage rails (just past a diode), and since the buck converter is on the negative rail that means the +5v rail is common with the rest of the system, but VSS is not when the device is off. This means the voltage detect IC is always being driven when there are batteries in the lynx, but since the circuit beyond that is grounded after the buck converter those are floating instead of grounded. The input labels are also misleading, the +5v rail is only +5v relative to ground, not Vss. Vss is the battery negative terminal, meaning this device has up to 9v or so on it at all times. When the switching converter is on Vss is effectively an unregulated rail below ground. 

This voltage detect IC seems important to be always powered, and with the soft-power circuit of the lynx and the strange low side buck converter topology I have some question as to what its doing. Maybe it has something to do with the feedback circuit on the switching converter? Anyway, since I don’t know which of these parts lets test it. Very carefully ramp the input voltage up and down with a voltmenter on the input and one on the output (pulled up with a 100k, since it might be open collector). Doing that, on the upswing it turns the output high at 5.03v and on the downswing it turns the output low at 4.734v. It does this with pull ups or pull downs of 100k, so CMOS output is confirmed. Looking at the table that makes this part a S-8054ALO-LO-X. 

What does this tell us? Not much. After puzzling out the feedback circuit on the lynx power supply I found myself still wondering about this circuit. Cross connected transistors, a big electrolytic in the middle not as a smoothing or bus cap. The output seems to just drive the power LED. 

Oh. 

If I turn the voltage down below about 5v (when the switching regulator stops switching) the LED starts blinking. It was a low battery indicator this whole time. But that is a CMOS chip holding its output transistor on the entire time there are batteries in this thing. That has to have some power consumption impact. All to have a precise voltage detect IC for a low battery oscillator. And the main power supply still uses just a zener diode to set the output voltage. I don’t think I will ever understand atari, they built this thing out of literal 2n3904 and 2n3906 parts like you would get at radio shack, then they overengineered the low battery blink and under-engineered the power supply regulation. This shit is nuts. 

rat-ratgdo esphome sensor board build

February 15, 2024

Well, I built it. It took some modifications and the software was not as straightforward as I would have liked, but it all works now. This post is helpfully sponsored by PCBWay, and was in my recent order of four boards at once so this makes two. Two more to come. The Bracket is nothing special, same design as I have used before. I have started using slightly different design techniques though. 

I modeled the exact dimensions of the board, then I did an offset to give some tolerance to have the board fit in the bracket. I may move on eventually to using the step file from kicad to make sure the board fits, but for now this is as far as I have gone. To design the sidewalls I’m just using another offset so I don’t have to worry about curve radii or anything. 

The board went mostly smoothly, with one issue. I didn’t run a DRC or ERC for this design and the ground fill didn’t reach the negative pin on the usb port. While we’re on this picture though, I did start to shrink the text and it still works great. This is 0.7mm width, height, and 0.1mm thickness. I think with PCBWay I can go further though. I end up pushing things around and even making boards bigger to fit some text in just the right place, having smaller legible text will help me further optimize these designs.

It tried, but a combination of the rules for ground pours and the size of those pins meant it didn’t get connected. The real board matches it perfectly, but my design just does not connect the ground pin.

This is it fixed, on the real part I soldered a small wire from the ground pin to the mechanical mounting pad next to it. For the non-2n7002 fet I used the PMV20ENR, which is close to the original AO3400A but I could source it from mouser. 

The software was not terrible, but it was not as straightforward as the original esphome ratgdo designers made it. For their hardware there is a relatively easy web-based picker that adopts into homeassistant automatically. Mine is a .yaml file that you can manually include in the esphome plugin in your homeassistant instance and manage it from there. 

This is the main part of the difference in my implementation (except removing things). I have the pin definitions at the top for my board, the includes that add the other sensors I have on this board (those files are in my repo as well), and the board definition that I created as 2.5e (e for Evan) because I wasn’t sure if the ratgdo instance would try to pull in things I don’t want. I’m a little annoyed that to set the board I have such a small list. I’d really like to be able to pick the AI-Thinker module I want to put on a board of my own design rather than figure out which dev board is close to my module choice.

The remainder of the file is one of the yaml files for the ratgdo, but with some parts removed. The main reason I had the go this deep is to disable the features that make the ratgdo work as a wall control panel. Those automations were integral to the software, so cutting them out was mostly all it took to get the yaml file going for my needs. This makes for a very minimal implementation that you can add to any esphome sensor or button box. There are no button inputs or relay outputs based on the garage state mostly because my unit is mounted high up so it also works as a temperature sensor for the peak of my roof. 

The reason I mounted it so high is so I can activate my garage roof vent based on the differential temperature between the upper and lower temperature, or the upper and outside temperature. The dumb thermostat in the roof vent controller uses a bimetalic strip, but that set point can be set to a reasonable temperature like 90F, but if the exterior air is also 90F then it will never turn off. 

The updated version of this board can be ordered from PCBWay but it uses sensor breakout boards sourced from… my parts bin. I have yet to work out how to get them to assemble the board for you, but you can order blanks and do it yourself. 

misc 3d models (part 1 of ?)

February 15, 2024

I have recently re-learned solidworks and am taking advantage of this ability to make 3d models for whatever I need. For my circuit boards it usually means brackets (which I post about when I explain those boards). For everything else the uses are many and varied. 

This is the plastic cover for an IBM 5154. It covers the screws and matches the surface texture to make the design appear more clean. The issue with just filling a repaired one with epoxy is that the divet in the middle is required for the screw head, so when the tab snaps off making a new one is ‘easier’. This was the first thing I modeled, but I still haven’t printed it because it requires a resin printer. It’s also not the easiest thing to design, but it helped me figure out a decent number of aspects of solidworks. 

This is my latest design. The lever for a Shugart SA455-3AA 5.25″ floppy drive. The original cracked, this is modeled from my remaining good one. I had some issue with it because the original had some draft angles and it was hard for me to implement them all exactly as the original. I also made this part twice. My first time was trying to make a 2d sketch including every feature on top of each other and then do extrudes and cuts from the same sketch, but only certain aspects of it. I had so many overlapping lines, curves, rectangles, circles… It did not work. This model is largely made one feature at a time and carved out of a large block of material. It got a little questionable near the end where I removed material and then put it back from another direction, that means this model is not quite as parametric as I would like. It’s not a complete house of cards that will fall apart if I change one dimension, but you should double check that you didn’t unintentionally create a hole if you modify it. 

This is an adapter. I originally bought an LED light bar for my prusa mk3, but then I upgraded to a mk4. I didn’t want to re-model the whole thing so I made a 3-part adapter to allow me to make a standalone light out of the original light bar mounting hardware and then mount it to the top of the mk4. It uses more plastic and is more cumbersome, but I only had to model mostly flat parts and none of them required any support material. 

If you look closely in the picture above you can see my printer sitting on an ikea based drybox/buffer with a broom handle through it. I found that when my spools got nearly empty they pulled off the rollers and got stuck in that drybox design. I fixed it by sticking a broom handle through the whole thing (I have yet to seal that hole very well) and putting a shaft collar on the end of the handle so it doesn’t fall out. This is just an M4 bolt and nut, I may have even accounted for an M4 washer under the bolt head, but it’s not needed. 

This is a setup I designed, but haven’t coded yet. My intention was to have a cheap differential pressure transducer for esphome. I didn’t design a board, but I have a holder for the two dev boards. The DFRobot part is cheap, but I don’t think it’s in esphome yet. The second part is a flange that’s supposed to mount on your furnace on either side of the air filter to see how ‘full’ it is. I may have to redesign that part to add an o-ring groove, or make it large enough to put some weather-stripping between the sheet metal screw holes and the pressure port. 

This one was real dumb, I knocked my fallout blind box funko pop off the shelf and lost the base. It was easier for me to model and print a new base than try to find and glue the original base back on. I could print this out of transparent plastic to make it look more original, but I think black is fine. 

This is my first contribution to the gridfinity standard. I saw this video on the Tamiya Handy Drill and immediately went out to get one. I spend enough time drilling out holes in 3d prints that I was going to get a pin vise to do it, but this is just super cool. After building the kit and looking around I found that I had some leftover dremel collets from before I switched to a slightly larger jacobs chuck rotary tool and with a little kapton tape around the base to space them out they fit in this drill perfectly. I went out to harbor freight and got a $3 assortment of small metric drill bits (or at least drill bits labeled in metric). That assortment is covered here with the holes, but even drilling them out it’s way easier to stick the small drill bits in the trough. I added some 12mm magnets there for holding spare drill bits and the small ones just all went there. 

All my models are up on github here. I may start putting stuff up on printables or something like that, but my models are mostly for me and have very specific uses (I didn’t put much effort into making them generically useful). If you need these in a different format feel free to ask, and if you have any suggestions for upgrades I’ll take whatever you care to share.