Back to the '74 with a 8080 emulator - part 2: rendering
David Guida
Posted on October 10, 2019
And finally I got something working! Took me a bit of searching and head scratching, but at the end I managed to get some pixels on the screen :)
If you remember my last post, we discussed a bit about emulators and why I started this project. The Intel 8080 is a quite easy platform to emulate and honestly, also a very interesting programming exercise.
I managed to quickly implement the first 50 opcodes, which cover more or less 45k instructions of the original Space Invaders.
But just looking at registers dump in the console is not very appealing, at least not for me. So once I made sure the implementation was running fine, I started working on the rendering part.
Now, Space Invaders has an interesting mechanism for displaying pixels on the screen. The video hardware generates 2 interrupts at a fixed time, each at 60Hz. This means that each interrupt occurs 60 times per second, which is approximately 16ms.
When an interrupt occurs, normally the current Program Counter is PUSHed into the stack and then is replaced with a low memory location. This location most of the times contains a CALL (or RST) to some routine. After that the Program Counter is reset to its initial value stored in the stack.
As I previously wrote, there are 2 video interrupts, each one handling half of the screen. This was done at the time to achieve smoother animations: when one of these interrupt occurs, half of the framebuffer gets updated, while the other one can be safely rendered.
As you can imagine, updating the entire framebuffer and rendering it at the same time would have caused lots of performance problems plus other issues I guess.
For this project I'm using MonoGame to handle the grunt work for window creation and 2d rendering. I used XNA a lot during its glory days so the setup for me was a no-brainer.
Code for now is very easy and doesn't fully handle all the cases. If the interrupts are enabled (via the 0xfb EI opcode), it is triggering the two interrupts every 16ms in the Update() method.
Once the CPU has completed its job, the framebuffer is copied to a texture and rendered on the screen. I'm not handling the half-screen update discussed before, and I'm not sure if I'm going to ever implement it.
There's still a lot to do of course, but the results are encouraging :)
this article is available also on my blog, check it out!
Posted on October 10, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.