In my previous article, I gave you a high-level overview of the CERBERUS 2080, a recently designed computer with three 8-bit processors. In this article, I’m going to pick up where I left off, and take you through my experience with assembling and programming the CERBERUS 2080. If you didn’t read Part 1, you should go back and give that a read before continuing on.
Assembling the System
Previously, I left off with telling you about how I sourced all the parts to build the CERBERUS. Assembly was straight-forward with lots of soldering. I won’t re-hash the build instructions in the manual – pages 17 onward give you a walkthrough for building the board end-to-end. However, here’s a montage of assembly photos to show you journey that I went through.
Now that I’ve been through the build process, I’d like to offer a few tips that may help, should you decide to take on this project yourself.
Tip #1: Start with the Lowest Profile Components First
Technically, it doesn’t matter what components you start with – but you will make it a lot easier on yourself if you start with the lowest profile components first. If you start soldering the taller components, you’ll have some trouble keeping the shorter ones in place as you flip the board over to solder them.
Tip #2: Organize Your Parts Beforehand
When you’re on a roll during a build, the last thing you want to do is to have to take out your multimeter to measure a resistor because you’ve lost track of its value. Before you start your build, get all your pieces together in one place and label them. One great way to organize the components for a build is to put them in zipper bags like these, with labels.
Tip #3: Keep a Paper Checklist
I love my phone and tablet just as much as the next person, but nothing beats paper when it comes to speed and ease of use. And when assembling a board like this with so many parts, it’s really easy to lose track of where you’re at and miss something. So when doing your build, print out a copy of the CERBERUS parts BOM, stick it on a clip board, and use a pencil to check off the components as you go.
Tip #4: Make Sure to Solder the Sockets Correctly
The CERBERUS 2080 doesn’t have the DIP and PLCC chips all facing in the same direction. So you’ll want to make sure you pay attention to where pin #1 is on each of those components. Even though it doesn’t really matter which direction the sockets are facing, you’re going to thank yourself later if you put them in the right orientation. Otherwise, you’re going to pop a chip out at some point down the road and put it back in backwards.
You’ll want to make sure that you place the chips in correctly as well. If you’ve never used chips in the PLCC package, this may be a little confusing. The arrow on the PLCC socket should point towards the side of the chip with dot.
Tip #5: Replace the Header Pins on the microSD Card Module
If you purchased the Micro SD card module from Amazon (like I did), it probably came with angled pin headers, which you’ll want to replace with straight pin headers. The easiest way to remove them (especially if you don’t have a desoldering tool) is to clip the black plastic block between the pins with your flush cutters and then use tweezers and your soldering iron to remove each pin individually.
Programming the CPLDs
After assembly was completed, I moved on to programming the CPLD and ATmega chips. In fact, one of the more interesting parts of this build for me was working with the CPLDs. I had never used them before, so I learned a lot exploring the code. It also helped me think through how I might incorporate CPLDs into some of my other projects.
Programming a CPLD is rather straightforward if you use the same programmer that Bernardo recommends in the CERBERUS manual. As I mentioned in part 1, I purchased one from the Microchip website for around $80. There may be cheaper alternatives on the market, so if you’re looking to cut down on the build cost, you might want to look around. A search on Amazon for CPLD programmers turns up a bunch of them, but it’s hard to say whether or not they support the ATF15 series Atmel CPLDs used by the CERBERUS.
The programming process was rather simple; I just went around to the JTAG header near each of the three CPLD chips on the board and programmed the appropriate PLD file. The instructions on pages 23 and 24 of the CERBERUS manual were clear and worked fine.
Programming the ATmega
Programming the CPLDs wasn’t at all difficult. The ATmega (also called the CAT), on the other hand, was a little more involved.
Load the Arduino Bootloader
The first step was to load the Arduino bootloader onto the ATmega chip; this enables the chip to run Arduino code. Now, the simplest approach would’ve been to use an existing Arduino that I already had. In fact, the ATmega328P chip in an Arduino Uno can actually just be transplanted straight into the CERBERUS 2080. The BIOS sketch would still need to be uploaded to the chip, but since it already has the Arduino bootloader, that would save a step in the process. The downside, of course, is that I would be left with an Arduino Uno that’s no longer usable without the processor.
I chose not to cannibalize an Arduino Uno, and instead used a different method for loading the Arduino bootloader. There’s actually a couple of different ways to do this. Here are two different options to choose from.
Option 1: Load the Arduino Bootloader using Two Arduinos
The first technique here is the easiest and quickest, but it requires two Arduinos; one plays the role of the Programmer, and the other is the Target. The Target Arduino has to be an official Arduino Uno Rev. 3, which has a socketed ATmega chip that you can remove. None of the other Arduino boards have this.
Start by removing the ATmega328p chip from the Target Arduino Uno. Set the removed chip aside and try not to get it confused with the chip being programmed for the CERBERUS.
Plug the Programmer Arduino into the USB port of your computer and fire up the Arduino IDE. Then load the
ArduinoISP sketch. This sketch uses the Arduino as an In-circuit Serial Programmer that enables it to be used for loading the Arduino bootloader onto other devices with a supported ATmega chip. For more information on how this works, check out this article on the Arduino docs website.
Use the following steps to prepare the Programmer Arduino:
- Open the Arduino app
- Click File > Examples > 11. ArduinoISP > ArduinoISP
- Make sure the correct board is selected from the Tools > Boards menu
- Select the port that the Arduino is using in the Tools > Ports menu
- Upload the sketch by selecting Sketch > Upload
Next, grab the Target Arduino (the one with the now missing chip). Wire it up to the Programmer Arduino using the following configuration:
Next, insert the CERBERUS ATmega chip into the Target Arduino, and make sure it’s in the correct orientation. The semi-circle divot (which indicates pins 1 and 28) should be facing the same direction as in the following picture:
Change the board type in the Arduino software to reflect the board used as the Target Arduino. If using an Uno for both the Programmer and the Target, then there’s nothing to change. However, if a different type of Arduino is used for the Programmer, then the Board setting should reflect the Target board (an Arduino Uno).
The final step before burning the bootloader is to change the programmer to “Arduino as ISP”.
Finally, select the option to burn the bootloader (
Once the bootloader is loaded, go ahead and unplug and remove the wiring from the Programmer and Target Arduinos. Remove the ATmega328P chip from the Target Arduino and put it into the CERBERUS 2080; it’s ready to have the CAT code loaded onto it.
Option 2: Load the Arduino Bootloader using a Breadboard
The second option is the one suggested in the CERBERUS build manual – build a “breadboard” Arduino. Now, this looks more complicated than it actually is. All we’re doing here is essentially adding a clock signal to the ATmega chip and wiring up the SPI lines. Here’s a wiring diagram for this:
I won’t go into the detailed instructions here, as they’re pretty well laid out in the CERBERUS build manual. There are a couple of things that I want to point out, though.
First, the instructions say to place a 10uF capacitor between GND and RESET on the Arduino designated as the Programmer. The reason for this, is that unlike the setup in option 1, the processor is still in the Programmer Arduino. When the serial port is opened for use, the CPU is reset by holding the RESET pin LOW for a couple of microseconds. And when the CPU is reset, the execution of the code also restarts.
By placing the capacitor between the RESET pin and GND, you’re building up a positive charge on the side of the capacitor that’s connected to the RESET pin. So, when the RESET pin is taken down to LOW, that stored charge then flows from the capacitor and into the RESET pin, keeping it at a logic HIGH. Therefore, the capacitor acts as a RESET bypass.
I also want to point out that, in addition to the 5v and GND wires, you’ll notice four other wires coming from the Arduino to the breadboard. Two of these wires (MISO and MOSI) are serial I/O, one is for the serial clock (SCK), and the last one is for the RESET signal to the ATmega chip on the breadboard (don’t confuse this with the RESET signal on the Arduino, which you have the capacitor on).
The two serial I/O pins from the Arduino connect to the complementary I/O pins on the breadboard ATmega. And likewise with the serial clock; SCK from the Arduino connects to the serial clock pin on the breadboard ATmega. These three wires all control the serial communications between the Arduino and the chip on the breadboard.
The fourth wire connects one of the digital I/O pins on the Arduino to the RESET pin of the ATmega (pin 1). You’ll also notice that the instructions have you placing a 10KOhm resistor between that same RESET pin and 5v. This holds the RESET pin HIGH… until the Programmer Arduino pulls it down to LOW.
The last thing I want to point out is the output from the 16MHz crystal oscillator is connected to the crystal oscillator input pin on the breadboard ATmega. This provides the clock signal for the CPU.
The breadboard configuration isn’t really all that complicated, once you understand what’s going on. I ended up using option 2 to load the Arduino bootloader onto the ATmega328P chip.
Upload the BIOS
Finally, I simply followed the steps in the CERBERUS manual to upload the BIOS. I won’t repeat them here, as this part of the build is straightforward.
One thing to understand is that the BIOS is basically just an Arduino sketch. So, modifying the BIOS to add features is actually very easy. In fact, several folks in the CERBERUS community have made modifications to make programming easier and to expose additional capabilities to the 6502 and Z80 CPUs, such as access to the microSD card.
Here are a few of the other BIOSes that you can use on your CERBERUS:
- Andy’s BIOS – Adds serial keyboard input over FTDI and enables the CERBERUS 2080 Emulator to compile directly to the CERBERUS.
- Alexandre’s BIOS – Builds on top of Andy’s BIOS with a couple of nifty features, but most importantly supports his implementation of Forth on the CERBERUS.
- Dean’s BIOS – In addition to many of the features in the other BIOSes, this one also adds two-way communication between the CAT and the CPUs. This enables access the microSD card to save and read data! This is the BIOS that I’m currently using.
- Gordon’s BIOS – Updates to support running Gordon’s RubyOS on the CERBERUS.
I started out with the stock BIOS, just to make sure everything is working as intended. Later on, I ended up trying out the other BIOSes to help make the 6502 and Z80 assembly programming easier. Some of those other BIOSes are also required for running some of the software or games written by others (such as BBC Basic, Forth, or Sokoban). These BIOSes are all easily loaded by using the FTDI adapter and the process described in the CERBERUS manual.
Speaking of which – as I mentioned in part 1 of this series, an FTDI adapter is needed for uploading the BIOS. I used a 5-pin FTDI cable that I already had on hand, which only operates at 5v. However, if you’re using the $2 FTDI adapter that I linked to in part 1, you’ll need to make sure the jumper on the adapter is set to 5v and not 3.3v before using it. Then just follow the instructions on pages 29 and 30 of the CERBERUS manual.
Test Driving the Cerberus
I finished the assembly and programmed the ATmega and CPLDs. But before powering it on, I needed a PS2 keyboard. I didn’t have one on hand, so I attempted to use a USB keyboard with a PS2 converter… but it didn’t work.
After some research, I found that many of the newer USB keyboards will indeed not work with PS2 adapters. Ultimately, it depends on the controller inside the USB keyboard. Some of the older USB keyboards have a controller that understands both USB and the PS2 protocol. Newer USB keyboards tend not to have PS2 protocol support, so the adapter won’t work on those.
With no native PS2 keyboard within the walls of my home, I ventured off to the thrift store and wasn’t disappointed. I scored a Compaq PS2 keyboard for $3. Seeing that Compaq logo brings back some memories; it’s been a long time since I’ve owned any Compaq hardware. I think the last Compaq device I had was a Presario laptop that Compaq gave me back when I worked for them in the early 2000’s, before starting my career at Microsoft.
Then came the moment that simultaneously generates fear and excitement… turning it on for the first time. At this point, there are many questions circulating in the mind, imagining the outcomes associated with flipping that switch. My brain produced 3 likely outcomes… it will do nothing, produce some magic smoke, or boot up normally. With my expectations firmly held on the first possibility (nothing will happen), I plugged everything in and … well, it did something, but not what it was supposed to. Instead of being greeted with a three-headed dog and a command prompt, I received a garbled screen and a sequence of low-grumbling beeps, indicating an error.
After puzzling over this for a bit, I realized what the error was. I had forgotten to put in a microSD card, loaded with the necessary files. A few minutes later, the microSD card was loaded, and I was holding my breath again, as I toggled the power switch.
I have to say – building and playing with the CERBERUS 2080 was a lot of fun. I personally really enjoy building boards that are designed by other people that are more knowledgeable than myself. I always learn something in the process, and that improves my own designs and adds more techniques to my personal toolbox. The CERBERUS 2080 was a lighthouse example of this. It was beautifully designed by a talented engineer, with an accessible architecture that anyone can become familiar with after spending some quality time with the board.
One of the things I enjoyed learning the most from this experience was how the CPLDs were incorporated into the design. Having never used them before, I assumed that they were much more complex to work with. After spending some time going through Bernardo’s videos and looking through the PLD code, I was pleasantly surprised at how accessible it is. Someone with an intermediate programming and electrical engineering background should be able to pick up a CPLD and get off the ground with programming it relatively quickly.
If you think the CERBERUS can serve as a modern-day Commodore 64, then you’re going to be disappointed. For one thing, it only has a character-based, black and white video output. There’s no graphics mode nor any way to display sprites, so you’re not going to be able to port over many of the games that you love. And even if you did, you’re going to be missing a crucial part of the experience… the sound. The only audio emanating from the CERBERUS is the built-in piezo buzzer. While you can get some boops and beeps, it’s definitely not going to give you the immersive experience of a SID chip.
However, that’s not the point of the CERBERUS 2080; it’s not intended to be a modern-day Commodore 64. It’s a learning and experimentation platform, and to be quite honest – it does a great job of being just that.