Nobody asked for a recap of a logic chip rewrite. But honestly this story is way more fun than any capacitor I've ever replaced. Strap in.
If you've been following along, you'll know the A4092 is my reproduction of the A4091 SCSI-2 controller for the Amiga. The original used a bunch of PAL chips to implement the glue logic — the kind of stuff that in the 90s you'd burn once, lose the source for, and spend the rest of your life praying nobody accidentally cooks the board. For the A4092, I wanted to do things right and use a CPLD, something that could replace multiple discrete PALs while giving us room to improve on the original design.
My first instinct was the Atmel ATF1508. It's a nice chip, it's still in production, and the toolchain is reasonably sane. The only problem: it doesn't exist in large enough pin count configurations for this design — or rather, it does exist, in a datasheet. In reality, ATF1508 devices only go up to 100 pins in QFP packages that you can actually buy, and that's not enough. So I went with the Xilinx XC95144XL in a 144-pin TQFP. Yes, it's end of life. Yes, the community gave me grief about it. But so is the NCR 53c710 at the heart of the whole design, and nobody seems to mind that. You can't have a vintage SCSI controller without a little end-of-life silicon. That's just the aesthetic.

Enter Dorken
Now, logic chips don't program themselves. Writing Verilog for a Zorro III card is a niche enough skill that the list of people on earth willing to spend their evenings on it is... short. I got very lucky.
If you've been around the ReA4091 project — the A4091 reproduction that Chris Hooper and I built and presented at VCF East a few years back — you might know the name Dorken from the community forums. That's Olaf Kordwittenborg, and he's the person who previously went in and optimized the GAL source code on those ReA4091 boards. When I had my first A4092 prototypes in hand at the end of June 2025, I sent one his way and asked if he would be willing to take a look at the CPLD logic.
Sending a bare prototype board to someone across an ocean and asking them to write the glue logic for it is either a bold ask or an act of total shamelessness, depending on your perspective. Olaf said yes.
My helpless attempts at Verilog
Before Olaf entered the picture, there was a period I like to call "Stefan confidently does the wrong thing for several weeks."
The A4091 GAL source code had already been tracked down and documented as part of the ReA4091 project. It's not a huge amount of logic — it's a handful of PAL equations describing bus decode, chip selects, DMA arbitration. And look, I'm a firmware engineer. I've written coreboot code for close to two decades. I've stared at assembly listings for fun. How hard can Verilog be, really? It feels enough like software that a low-level software person should be able to just… port it over. Right?
It was not that simple.
After a few weeks of wrestling with the toolchain and the syntax, I had something that compiled. No errors. No warnings I hadn't already convinced myself to ignore. I was feeling good. I flashed the CPLD, plugged the prototype board in, and — hmm, something smells funny.
I should mention that I had anticipated at least some problems, so I came prepared. Specifically, I came prepared with a thermal camera app on my phone. And it was a good thing I did, because within a second or two of powering up, the 74FCT16543 bus transceivers on the board were showing up as a festive shade of scorching red on the camera. We're talking 100°C, almost instantly. I killed the power before anything actually died, which felt like a small miracle.
The root cause, once I figured it out, was embarrassingly simple. I had forgotten to connect certain signals from the top-level Verilog module down into one of the submodules — specifically the ones driving the output enable lines of those 16543 transceivers. So those enables were just… floating. And a floating enable on a fast bus transceiver means the outputs are toggling at something approaching the speed of light, dissipating all of that switching energy as heat. The chips weren't broken; they were working perfectly — just doing completely the wrong thing at maximum effort.
So that was week one with the prototype board in hand: debugging with a thermal camera, tweaking the Verilog, reflashing, holding my breath, pointing the camera at the transceivers, and waiting to see whether this attempt would be "warm but stable" or "red and alarming." Eventually the board settled down to a comfortable room temperature and I had something that at least wasn't actively trying to destroy itself.
Whether it actually worked correctly was a whole separate question. I am proud to say at least my "DIP switch emulation" code somewhat worked, but that was about it.
First signs of life
It was a Friday afternoon in early July 2025 when the first email arrived. Olaf's message: "Hier der aktuelle Stand, es gibt die ersten Lebenszeichen der Karte." — roughly, "here's the current state of things, there are first signs of life from the board." Just like when you put the last capacitor on a recapped Amiga and it boots for the first time, those words hit different.
The day after, a second version arrived, which Olaf called the "VHDL Bastelstand" — the VHDL tinkering build. This one already had Autoconfig, Flash ROM access, and NCR SCSI chip access working. To put that in context: those are the three fundamental things the glue logic needs to do. If Autoconfig works, the Amiga sees the board. If Flash works, you can update the firmware. If NCR access works, you can actually talk to the SCSI controller. In one weekend. From scratch.
The Fitter Problem
The weeks that followed were an ongoing dance between writing logic and convincing the synthesis fitter to actually fit it. The XC95144XL is not a small device by vintage Amiga standards, but it is absolutely a small device by "we want to implement everything and the kitchen sink" standards.
Olaf's standing advice for the more complex builds: either enable exhausted fitting mode, or set the Collapsing Input Limit to 23 with -inputs 23. Without that, the fitter throws its hands up.
**The SPI ROM State Machine and the A3000 problem **
Once the basics were solid, the next big piece was the SPI ROM interface. The A4092 uses a small SPI flash chip — a W25x40 — for the boot ROM. Rather than the parallel ROM interface of the original A4091, SPI made sense in 2025: the chips are cheap, plentiful, and come in a tiny SO-8 footprint.
Olaf implemented a state machine for this. The flow goes: SPI_IDLE pulls chip select active and loads a counter with either 8 or 40 cycles depending on whether we're doing a command or a read. Then the machine bounces between SPI_N (clock low, put the MOSI bit out) and SPI_P (clock high, capture MISO) until the counter hits zero. Then SPI_DTACK asserts the Zorro acknowledge and hands the data back. Clean, elegant, and compact enough to fit in the CPLD — mostly.
There was a sneaky address mapping bug to sort out first: the original code duplicated A[23] in the address concatenation to work around some missing address lines, but this caused reads to land in the wrong SPI region sometimes. The fix was to AND together address bits A[3] through A[20] — if they're all set, you're at the top of the 2MB space where the command registers live. One line of Verilog. Several headaches, resolved.
Meanwhile I was debugging the spiutil command-line tool from the Amiga side. My scope showed SPI clock pulses on MOSI, but MISO stayed stubbornly silent. Olaf's response: "Your software is fine and works great as far as I tested it! There was a bug in the CPLD code." For a moment I felt vindicated. For a moment.
The real bug was weirder: intermittently, CS wasn't going active before the first eight SPI clocks, so the flash chip never saw the command opcode. Since CS gets set before the state machine leaves SPI_IDLE, this shouldn't be possible — and yet. "Ich grübel schon den ganzen Tag was da genau abgeht" — "I've been puzzling over this all day." One of those bugs where you stare at the code and the code stares back at you with complete indifference.
The workaround for flashing in the meantime: temporarily switch the CPLD image back to parallel ROM mode so the SPI outputs go high-impedance, then flash the chip externally with a T56 Minipro and an SO-8 adapter. The Dediprog I tried first didn't even recognize the chip connected to the board. The T56 Minipro complained about not being able to drive the /HOLD line, but as Olaf noted, you can just ignore that. Chip flashed. Problem progressed.
The 68030-based A3000 has different bus cycle behavior, and an early version of the driver hit a wall with Write Allocation enabled on the 030 cache. The fix: disable Write Allocation before the SPI operation and restore it afterward. Inelegant but effective. "Boah ey. Jetzt klappt es endlich auch mit dem 030." — roughly "Oh wow. It finally works with the 030 too." Some victories deserve more than one exclamation mark.
The DMA Arbiter: Where Things Get Wild
The DMA arbiter manages who gets the Zorro III bus — CPU, SCSI DMA engine, and whatever other cards are fighting for the same 32-bit highway. Olaf had initially ported this faithfully from the original A4091 PAL equations.
Then he tried rewriting it as a clean FSM. The result? Transfer rates swinging between 2 MB/s and 5 MB/s with no obvious pattern. Not ideal for a storage controller. The original version went back in, and the FSM went on the pile of things to revisit on a rainy weekend.
Also on that pile: the Super Buster revision 9 workaround. Certain A4000 boards shipped with Buster rev 9, which has a known quirk with DMA arbitration timing. The A3000 often even came with a Buster rev 7, but that one is hopeless and needs to be updated. The original A4091 does not work on a Buster 9 or earlier. Dave Haynie once told me that the A4091 was built to prove that he needed to release another version of Super Buster: The Super Buster rev 11. Since all the relevant signals are available in the CPLD — unlike in the original fixed PAL — and there's a little logic budget to spare, a proper fix is at least theoretically possible here, and by now we have experimental support with an extra CPLD firmware available. Watch this space.
Quick Interrupts
One of the nicest additions Olaf worked on were "quick interrupts" — a mechanism for the SCSI controller to assert its interrupt more efficiently, with lower latency. This landed as pull request #9 on the a4091-logic GitHub repository, and I spent quite a few November evenings getting the matching driver changes implemented on the software side.
Quick Interrupts work nicely, if the CPU accelerator board supports them. So be careful before you enable them. Luckily starting with the upcoming driver release 42.37 it will be possible to skip driver loading by pressing the left mouse button during boot-up, so you can still boot your system from the A4092 floppy disk, and reset the setting in case it doesn't work on your system. When it does, you will get a nice little speed boost specifically for smaller transfers, like loading a lot of icon files from disk.
CPLD Real Estate and the Multiplexer Problem
A recurring theme throughout all of this: the XC95144XL is a small world and real estate is precious. The data bus logic is implemented as a large multiplexer — the CPU data lines get switched between autoconfig reads, flash reads, SPI reads, register reads, and NCR accesses depending on what's happening on the bus. Every time Olaf wanted to add something that touched the data bus, the fitter started sweating.
We discussed the idea of a hardware version register — a readable field that lets the software know exactly what version of the CPLD logic is running. Great idea in theory. In practice, the Function Blocks handling the data lines were already packed, and adding more data bus multiplexing pushed the fitter over the edge. We ended up reporting the CPLD version number in the serial number field of Zorro III autoconfig. That field needs to exist anyways, so we might as well use it for something useful.
Where Things Stand
As I write this, the A4092 logic is at version 1.4.3, the SPI flasher works, quick interrupts are in, the DMA arbiter is stable, and a larger number of boards are incoming from JLCPCB. The Verilog lives on GitHub, MIT licensed, ready for whoever wants to pull them apart and improve them. Hint, hint!
Olaf tested on a system with Ramsey 7 and "SKIP" mode enabled (you nee 60ns RAM for this), and got an astounding 9200KB/s from the SCSI controller to the Amiga 4000D's fast memory. That is pretty much maxing out the SCSI bus and almost maxing out realistic Zorro III throughput at this point.
The journey from first sign of life to working logic took the better part of a year of evenings and weekends, across two countries, in two languages, and several iterations of the toolchain setup. It's not glamorous. But neither was soldering 400 pins into a 68040-to-68060 adapter. This is just the kind of thing you do when you love these machines and want them to have new tricks to show the world.
Enormous thanks to Olaf/Dorken for the engineering work that made this possible. Without his deep knowledge of PAL logic, CPLD synthesis, and Zorro III bus timing, this project would have stalled somewhere around "Autoconfig doesn't work and I have no idea why." The Amiga community keeps delivering.
If you want to build one, head over to the GitHub project. If you'd prefer to get a professionally built A4092 in a beautiful box and a nice manual, stay tuned at scsi.me. And if you have ideas for the DMA arbiter — or a cleverer way to pack more logic into 144 macrocells — the repo is open. Pull requests welcome.
Note: I translated the German email excerpts above while trying to keep the spirit of the conversation intact. Olaf's native language is German, and so is mine — sometimes engineering in your mother tongue is just easier.
> COMMUNICATION_LOGS
Transmit Log