My project partner and I are currently working on making an Intel 8080 emulator that runs Space Invaders. The main things we have done so far are implementing the CPU instructions that are needed to emulate the main functionality of the CPU. We still need to develop the machine, but I already learned a bit from working on the emulator code.
I got an early head start on the instruction sets assigned to me for this sprint, so most of my time was spent peer reviewing, debugging and figuring out how to debug efficiently in C. I mostly work in Visual Studio Code, meaning there was no real built-in debugger for me to use… that is, until I realized that GNU projects use a debugger called GDB (GNU Debugger). It wasn’t until my partner let me know that this debugger existed that I realized I could have made breakpoints to pause the program line by line. Before that, I tried to make sense of the infinitely looping mess that we had initially just by running the code straight with no pauses. The only thing I can make out is the looping instructions were incorrect, but I couldn’t pinpoint anything specific that needed to be debugged.
I also referenced Emulator 101 for some ideas on how to debug this code efficiently. The suggestions were as follows:
- Use a cpudiag.bin to find issues with the Intel 8080 CPU instructions implemented,
- Use a Javascript implementation of the Space Invaders emulation to manually compare CPU states of a working example and our own code,
- Do the same thing as #2, but using the Emulator 101 emulator code instead.
My partner debugged using the first option while I debugged the code using the second and third options, just so we did not assign overlapping tasks. At first, I was debugging by manually going through each instruction using GDB on my code and the Javascript implementation. I realized later this would take a long time, especially since there were 50,000+ instructions that occur on startup before looping infinitely. The main suggestion that helped me save time was to integrate the Emulator 101 into the code for my own project and have error messages set for mismatched states, which was the quickest way to debug the program. For some reason, this did not click for me the first time reading over the debugging methods on the site, but better I realized this later rather than never. While I would have liked to come to this realization a lot sooner, ultimately it was helpful in confirming to me that the code was good to go in order to proceed with the machine emulation portion of the code.
Even though this was a relatively simple thing to learn and something that most people would have probably knew about already, I found that this was one of the few things I did not have practice with in my previous courses until now. One of my goals for this project was to learn more about the technologies I’m unfamiliar with, and so far I’m learning both what goes into an emulator, but also how to efficiently work on a project from start to finish in C/C++, which I will hopefully be a lot stronger in by the time we finish our project.
Reference:
http://www.emulator101.com/finishing-the-cpu-emulator.html