In this project, we sought to write a software emulator for a retro game console and run it on the Raspberry Pi. We were motivated in part by the discovery of a discarded cathode ray television, and aimed to combine hardware and software systems to convert it into a fully embedded retro gaming console.
The Pi Arcade is a CHIP 8 and SUPERCHIP 8 emulator written using Python and Pygame, running on a Raspberry Pi with support for a joystick, pushbuttons, a numeric keypad, as well as a regular keyboard.
A software emulator is a program that allows a computer to run code compiled for a different machine. People often write software emulators for old arcade consoles such as the Nintendo NES and the Gameboy, so that old games can be played on a regular laptop. However, access to these games is restricted due to copyright issues. The Chip 8 is essentially a 'soft' computer, with a simplified memory system, input/output mechanism, and opcodes designed specifically for games. As a result, a number of people have written free and open-source games for the Chip 8, and introduced extensions to improve graphics and opcode support.
Our project consists of four distinct components: a software implementation of the Chip 8 and SuperChip 8 microprocessors, a custom arcade game written in Chip 8 machine code, a module to interface with input hardware on the Pi, and a pygame user interface to tie everything together. We began by designing our software classes and a simple pygame interface, then moved on to implementing the emulator locally, and finally ported our code to the Raspberry Pi and added support for joystick and keypad inputs. At the same time, we studied Chip 8 machine code in detail, and modified an existing game to create one of our own.
At a high level, our design is composed of the following subsystems:
The pygame core, implemented in emulator.py, forms the primary user interface for the program. It manages the game menu, keyboard inputs, sounds, and coordinates the interaction between the cpu and gpio input modules. A detailed explanation of the design and testing involved in this section is given here.
The cpu modules, implemented in chip8.py and superchip8.py, are classes that accurately represent all hardware components and characteristics of the Chip 8 cpu. They contain memory, registers, a stack, a program counter, and functions that emulate various opcodes that the cpu can execute. A detailed explanation of the design and testing involved in this section is given here.
The gpio module, implemented in inputs.py, uses the RPi.GPIO library to define callbacks for each pushbutton and joystick. It handles switch debouncing and keypad scanning. It interacts with emulator.py through a set of two callable functions, minimizing the work emulator.py needs to do. A detailed explanation of the design and testing involved in this section is given here.
Our custom game, while not strictly a software module, is described here.
At the end of the semester, we managed to achieve what we had initially planned for the project. We managed to create a fully functional emulator written in python from scratch which can run on the Raspberry Pi. We have also made a custom ROM that runs on a Chip 8 CPU.
We also implemented additional functionality to our emulator in order to run SuperChip 8 games. SuperChip 8 games have better graphics as well as better gaming features, thus giving users a choice to play better quality games.
In addition, we have also implemented an arcade game console which consists of a CRT TV and arcade joysticks and buttons. The CRT TV is able to display our emulator on the screen successfully.
Finally, the Pi is able to detect the joystick movements and button presses successfully, thus allowing a user to fully experience the good old days of a retro arcade game console.
One of our main goals in writing this emulator was to learn in greater detail about how a CPU works. In conclusion, we believe that this project has certainly allowed us to learn a lot about the intricate details of a CPU as we have to write up the code from scratch in order to implement the emulator.
Even though we faced many challenges and obstacles throughout the course, we are satisfied that we have eventually managed to complete the project. However, we discovered a few issues that did not work. There are unfortunately a few SuperChip 8 ROMs that do not function correctly on our emulator. In general though, most of the SuperChip 8 ROMs work as intended on our emulator.
In summary, despite the challenges faced, we are extremely satisified with our project as a whole. Observing the entire arcade system working as we had planned was truly a remarkable moment as it demonstrated that our efforts and hard work have paid off.
Given enough time, we would definitely want to implement more advanced emulators,such as a gameboy emulator, that can run more advanced games. We would also want to implement more arcade buttons to enhance gaming quality.
Also, creating our own debuggers for the SuperChip 8 emulator would be useful in debugging our emulators. If there was additional time, implementing a debugger would have definitely enhanced our efficiency. It could also help other prospective programmers who would like to delve into the world of emulation development.
Last but not least, we also hope to learn more about disassemblers and compilers as they can help us greatly in creating and editing existing ROMs in order to create our own custom ROMs to enhance the variety of Chip 8/SuperChip 8 games available.
Finally, we would like to thank Professor Skovira as well as the TAs for actively assisting us during the course of the project by providing us with resources and advice. We truly appreciate the help that they have rendered to us throughout the entire semester as well. All in all, we certainly had a fun and enjoyable experience in the class.