|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Replacing a ZX Spectrum's DRAM with a Microcontroller
This project isn't so much of a practical Spectrum upgrade as a is-it-possible sort of experiment. I was thinking about whether hardware sprites might be implemented on a ZX Spectrum by having some hardware writing directly into the Spectrum's lower RAM (where the screen memory lives). In order to do that, the original 4116 DRAM ICs would need to be replaced by something a bit more flexible. "Flexible" these days realistically means a microcontroller. In principle, it's not that difficult. Plug a microcontroller-equipped board into the Spectrum's DRAM sockets, then program the microcontroller to emulate the behaviour of the 1970s 4116 DRAM chips. Those chips aren't that complicated. They save a bit of data when the Z80 writes it in, and they return the bit of data when the Z80 reads it back. It doesn't sound that hard to emulate, to be honest. The issue here is that transaction times for the 4116s are measured in tens of nanoseconds. Even on a fast, modern microcontroller, the timings were going to be tight. There's another complication here as well: the ZX Spectrum actually has two devices which access the machine's lower 16K of RAM. One is the Z80, the other is the ULA chip. The ULA is responsible for reading the data out of the DRAM chips and converting it into a video image. In order to do so without slowing the machine down too much it needs to complete those reads as quickly as possible, which means driving the original 4116 DRAMs to their limits. With the ULA (unwittingly) driving a microcontroller, that microcontroller would need to be running very fast (as fast as 1970s silicon) otherwise it wouldn't work. A challenge, then. :) I was talking to a friend, amen, about this about 3 years ago (2022-ish), and we decided that we should give it a try. amen designed a small PCB which carries a Raspberry Pi Pico, which is based on a Raspberry Pi RP2040 microcontroller. Made up, the underside of his board looks like this: ![]() It's basically just 3 level shifters to go from the Spectrum's +5V to the RP2040's +3V3, and a voltage regulator. The pins plug into the correct sockets in the original DRAM slots. On the other side of the board there's just a Raspberry Pi Pico. Back in 2022, after weeks of work, we came to a conclusion: the RP2040 wasn't fast enough. I was trying to get the program working in C. amen was trying his hand at ARM assembly language. Neither of us could get it running fast enough. I had a particularly compliant Pico overclocked to 360MHz, and that could run fast enough to keep up with the Z80's requirements. The Spectrum would start up. But the ULA runs a lot faster than the Z80, and the Pico couldn't get close to the required speed. It was missing signals and reads all over the place, so the video generated was almost all noise. ![]() The project went on ice for 3 years. Eventually I dug it out again for another look. Having learned a few things in the intervening years, I refactored and optimised the code. Unfortunately my Pico which would overclock to 360MHz was lost to time and other projects, and the only ones I had maxed out at 260MHz. That wasn't even fast enough to let the Z80 run. However, in 2025 we have a new weapon to hand. The Pico2 with its RP2350 microcontroller. Nominally clocked a bit faster than the original Pico at 150MHz, this chip is known to overclock a bit more reliably than its predecessor. I bought a couple, and they both ran at 360MHz. And that, plus more speed from the improved internal efficiency of the RP2350, appears to solve the speed problem. It works: ![]() Well, it nearly works. That photo shows there's still a bit of noise in the Spectrum's generated video image. The ULA is still just a bit fast for it. But it would be just about usable, if you don't mind that bit of noise. And the fact you can't get the keyboard back on the Spectrum. Oh, and hardware sprites? No. I set up the second core on the RP2350 to write graphics data into the memory buffer that's exposed to the Spectrum, and it does work, provided it only injects data a few bytes at a time. Any more than that and the first core, running the DRAM emulation, stalls on memory access. Basically the RP2350's RAM isn't high enough bandwidth to have both the cores using it, and to keep up with the demands of the Spectrum's ULA. That was the original suspicon, and it only took 3 years to confirm it. :) Derek Fountain, September 2025 |
||||||||||||||||||||||
Site and content Copyright 2023 Derek Fountain - All Rights Reserved |