Having had some hands-on experience now with the SSD1963 display I was somewhat disappointed in the performance. That should not have surprised me since there are a lot of pixels to be moved around with 24 bits colour depth. That’s roughly 1 MByte of memory that needs to be addressed with a humble 8 bits CPU. Even when it would run at 50 MHz, optimized assembly code is required and tricks to get the optimal results. And even then it probably would disappoint. There is a reason why our old home computers only had a few KByte of video memory to play with.
So I went looking for another solution and a while ago I stumbled on a Crowdsupply campaign which looked very interesting. In short this more or less promised Amiga like powers for our humble eZ80 CPU (as I hope the video’s below show). So I placed my order.
After experimenting a bit with it on an Arduino Uno I decided to make a PCB that would be a drop in replacement for the SSD1963 LCD display. It would take its power and signals from the 40 pin connector. Instead of using an LCD display, a HDMI connector is used to connect to a video screen at a 1280 by 720 pixel resolution. And audio is provided over HDMI as well. Next to that, The Gameduino allows to have 2 Wii controllers connected and an SD Card.
In the end, most of the work was getting the software running (isn’t it that always?). After clearing the hurdle of having the Gameduino properly initialized, I tackled the Gameduino library which is written in C++ by James Bowman. As you might know, the ZDS environment only has a C89 compliant C compiler, so that was a bit of challenge as well to get all code translated to plain C.
The BT815 - Embedded Video Engine
What makes the Gameduino tick is the BT815 - Embedded Video Engine chip. The BT815 is part of a series of easy to use graphic controllers targeted at embedded applications to generate high-quality Human Machine Interfaces by BridgeTek. From the Crowdsupply web page:
- 32-bit internal colour precision
- OpenGL-style command set
- Up to 2000 sprites - sprites can be any size
- 1 megabyte of video RAM, 8 megabytes of attached flash
- Smooth sprite rotate and zoom with bilinear filtering
- Smooth circle and line drawing in hardware - 16x anti-aliased
- Hardware support for JPEG, PNG and ASTC images
- AVI format video playback
- Built-in rendering of gradients, text, dials and buttons
Unlike the SSD1963, where you have to calculate and write every single pixel to video memory, you send openGL like commands to the BT815 chip (over a SPI interface) which will do all the hard work for you. The speed increase with this technique is somewhat incredible compared to a SSD1963 while the cost is roughly the same as for an SSD1963.
What the Gameduino adds is an FPGA that converts the LCD interface signals to a HDMI signal for an external monitor and it adds the audio from the BT815 to the HDMI signal as well. Next to that, the Gameduino also supports an SD Connector and 2 Wii controllers. All of which can be accessed via the Gameduino library.
As a gentle introduction, a simple
Hello World program producing the
picture above looks like this:
GD_begin_default_options(&my_GD, &my_GD_Transport, &my_GD_SDCard, &my_GD_Reader); GD_ClearColorRGB(&my_GD, 0x803000); GD_Clear(&my_GD); GD_cmd_text(&my_GD, (my_GD.w / 2), (my_GD.h / 2), 31, OPT_CENTER, "My my. It works on the Z20X!"); GD_swap(&my_GD);
Let’s go over it line by line.
GD_begin_default_options() initializes the Gameduino with the default options
(which includes access to the SD Card as well):
GD_begin_default_options(&my_GD, &my_GD_Transport, &my_GD_SDCard, &my_GD_Reader);
Now we set the colour we want to clear the screen with. This is a 24 bits
0x803000). In this case mainly red (
0x80) mixed with a bit of
0x30) and no blue (
Now we send the
GD_Clear() command to clear the screen with the defined
GD_cmd_text() we can put a string on the screen. Here we give the
OPT_CENTER argument to centre the text in the middle of the
my_GD.h give us the size of the screen):
GD_cmd_text(&my_GD, (my_GD.w / 2), (my_GD.h / 2), 31, OPT_CENTER, "My my. It works on the Z20X!");
It’s important to realize that the screen doesn’t show the output of the
above string of commands that are send to the BT815 yet! To see the result,
we need to send a closing
The ported Gameduino library (from C++ to C89) plus a few examples for the Z20X can be found here. Be aware that this project is set for an eZ80F91 CPU. If you have another CPU installed, adjust the project settings accordingly.
The schematic is quite simple and the PCB layout isn’t complex although I had to make my own footprints for the Gameduino, SD Card and Wii controller connector. The KiCAD design can be found here. Be aware that the KiCAD design has a few small revisions while adding an SD Card select LED to signal any SD Card activity and is now at version 1.0.1.
All photo’s in this blog post are taken from version 1.0.0 since I didn’t want to go in the expanse of making a new batch of PCB’s (and having 4 leftovers again) while v1.0.0 is perfectly fine in the end (after scratching one, wrongly connected, track…).
Although my initial hope was that I would only need what’s provided by the
40 pins connector for the SSD1963, it turned out I needed a third SPI
select signal (to select the Gameduino itself) which I took from the Z20X
expansion connector (wired to
PB5 of the eZ80)
Final construction photo’s
Here are some photo’s showing how this board fits together with the Z20X main board on the expansion bus:
I only needed to pick up 1 signal from the Z20X expansion bus so I could use a left over header instead of wasting an expensive 72 pin header. It also helps to make the construction feel really solid.
Encountered problems during testing
In the beginning, it happened quite often that I got the Gameduino hanging. No matter what I did could bring it back to live. Even removing power from the Z20X didn’t help. Then it dawned to me that the Gameduino might receive some power over the HDMI connector as well. And indeed, removing the power from the Z20X and disconnecting the HDMI connector and then plug everything back in again brought the Gameduino back to live.
Luckily, this kind of hangs happened less and less after I got the code more and more stable. So this should not happen that much anymore. But if it happens, try unplugging everything before going into an endless debugging session.
When you write code that requires the Wii controller, the Wii controller needs to be present. Otherwise the Gameduino will hang and won’t do anything. I guess the code could be made a bit more robust/tolerant here.
Not everything from the Gameduino code has been ported (there’s lots of code). There are still plenty of examples that could be ported and explored. Some are for older versions of the Gameduino and do need some adaptation as well. So porting those could be a good learning experience.
Although I spend a good amount of time porting the Gameduino Library, it could be I missed functionality. So if you feel there is something missing, it could be wise to look if it’s present in the original Gameduino Library.
Not everyone likes to use an external monitor and might want to have a SSD1963/LCD like solution. In that case, it could be a solution to consider something like the EVE3 products from Matrix Orbital. They offer quite a few LCD screens (in sizes up to 7", just like the original SSD1963 used by the Z20X) using the same BT815 chip. Another manufacturer of such display is Riverdi
It should not be to difficult to design a replacement PCB for those solutions just like I did for the Gameduino. Things that will be different is that a small amplifier will be needed to support audio. Also, support for the Wii controllers is not part of the BT815 chip. If that’s needed circuitry will have to be added as well.
There will be code changes of course. Definitely initializing code will be a bit different. But there shouldn’t be much changes to the library code itself.
This is the Cobra demo running on the Z20X. The movement is a bit jittery. This is not because the Gameduino can’t handle it but simply because the eZ80 can’t do the 3D floating point calculations fast enough. Converting the floating point code to fixed point should solve this problem. Once you’ve done that, there shouldn’t be anything holding you back to make a super version of the famous Elite game.
This video is the demo screen of the Manic Miners game that was available in the Gameduino library as an example and which I ported to the Z20X as well. This uses a Wii controller to jump around and get to the next levels. Unfortunately, I have no talent at all in gaming and I never got past the first level… But it works.
This is definitely one of those projects without an ending and there are lots of areas for improvement. But most of all have fun!