Debugging the RAM sideloader
After two weeks, I finally got the RAM sideloader to work. The purpose of the sideloader is to initialize the state of a 64KB RAM (which replaces the entire addressable space of a BBC Micro), and to allow individual addresses to be read while the computer is operating using time multiplexing of the address bus.
For the last two weeks, reading addresses has produced inconsistent behaviour. Usually this manifested as outputting the data stored at the address below the current address. Sometimes it would just output complete garbage. It took me a long time to work out that these were actually two completely different behaviours, caused by two different bugs.
Given the mess of a circuit I’d managed to build, I suspected noise on one of the address lines. Specifically, I assumed Address was hosed, since it seemed to always output a value one less than expected (addresses were written with sequential values from 0 to FF).
To test this, I recorded the frequency with which each bit was set when reading an address produced an incorrect value. Interestingly, bits 11 and 0 were almost always set when an error occurred. These two address bits are on the other side of the IC to all other address bits (why!?), near an active high Chip Enable (CE), and active low Chip Output (CO). After a bunch of poking around, I realised I’d disconnected CO while debugging another problem, then left for a 3 week trip to the US and forgot. Connecting it up fixed the errors, until I power cycled the circuit.
For multiple days, the circuit would work when I first powered it on, even after resetting it, but would fail as soon as I cycled the power. This failure was persistent - once cycled the circuit would not work until the next day. I suspected the RAM could only be written once per session, but verified this was not the case by writing random values to the the RAM each time the circuit was reset (not power cycled).
Eventually I noticed that the power LED didn’t quite turn off when the circuit was powered down. I measured 1.5V across VCC with the power disconnected, and tracked this down to the VCCIO pin on an FT232, which was tied to VCC. I cut this connection, and instead pulled this to the 5V line on the USB header - and finally a working circuit. It seems like the 1.5V (which was well below the RAM’s operating voltage) was causing corruption of the controller.
These bugs were particularly hard to narrow down for two reasons:
- These bugs were non-deterministic. Reading a given address did not always fail. Sometimes, no addresses would fail at all.
- The 2nd bug was stateful. Even worse, power cycling the circuit (which would normally be guaranteed to clear state) was what triggered the bug.
Not included in this account is 1.5 weeks of scoping every signal with an Oscilloscope and DLA. These helped eliminate a huge number of possible other problems, so I could narrow it down to these two, but boy was it frustrating.
I can’t imagine why this doesn’t work
Synchronization for the lazy
To monitor the memory of my microcomputer, I added a sideloader which can read memory locations during the high portion of the CPUs 2MHz clock (during which the CPU is guaranteed to not need memory access).
Reading is performed by an AVR running at 16MHz. A latching shift register is used to latch the output of the RAM on the falling edge of the 2MHz clock, so that the AVR can read it asynchronously. To ensure that data isn’t relatched while the AVR is reading the shift register, it can disable latching at any time. Because enabling/disabling latching is not synchronized to the 2MHz clock this can cause setup time violations - in practice these cropped up about 1 in 1M reads.
Solution: Read every address three times and take the most consistent value. Success!
A brief sidetrack while I wait for some new parts. This is a text-mode display controller written in VHDL, driving an LCD at 640 x 480. Text is written to a 2400 byte dual-port RAM block and read back by a simple VGA controller.
January 21, 2011 at 10:41pm
This is a small application I wrote to help debug problems with the BBC. It allows me to spy on the 32KB of RAM in the microcomputer, and to manipulate addresses directly. Interesting regions of memory are highlighted (e.g. the control registers for the video controller). The orange square at the top is the contents of the video memory, rendered using the current video mode.
I switch operating systems reasonably frequently, so I wanted a cross-platform GUI that looked nice and would Just Work. I’ve tried wxWidgets and pyGTK before, but neither is easy to deploy on OS X, and neither looks particularly great.
The same two waveforms as below, but with 100nF decoupling capacitors on each IC. This removes approx. 1.6V p2p of noise.
These capacitors aren’t shown on the BBC schematic, but they make such a big difference that I suspect they were excluded for being obvious.
The BBC’s input 2MHz clock, delayed by 125nS (one 8MHz clock cycle). This is performed twice by the stretching circuit to produce an inverted and synchronized /2MHz clock.
Circuit completed, except for a 74HCT51, which I’m missing. Everything else appears to be working as expected. My 2MHz divider needs to be modified to reset to a known state to conform to the BBC’s behaviour.
Day one build out, about 3 hours work.
I’ll be using this tumblr to track the status of a number of projects that I am working on. The first of these is an attempt to rebuild the 1981 BBC Microcomputer (http://en.wikipedia.org/wiki/BBC_Micro) at the IC level. The BBC microcomputer was the computer on which I learned to program (in primary school) and I’ve always wanted one of my own. In 2004 I found a repair manual for the microcomputer, which included a full schematic, and decided that I would build it. Six years later (2010) I started seriously examining the schematic and planning the build.
So far I’ve managed to build the sound-subcircuit, and a good portion of the video ULA (modified to upscale to 1280 x 1024 60Hz VGA to drive a modern LCD). I’ll be posting bits and pieces of those builds interspersed with updates on progress on the remainder of the system.