It’s alive!

This is part three of my series on writing an emulator for CHIP-8 in Golang. If you need to catch up parts one and two are available.

Control Freak

The biggest change since part two has been the implementation of controls. So I can actually play games on my emulator now, which is awesome! The CHIP-8 has a very simple control system in the form of a 16 key hex keyboard. For ease of use on a modern keyboard I have implemented the following grid of controls:

+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+
| Q | W | E | R |
+---+---+---+---+
| A | S | D | F |
+---+---+---+---+
| Z | X | C | V |
+---+---+---+---+

Detection of keys and handling the input is a two tier process. Firstly I rely on the pixel package to tell me if a given key has been pressed. More specifically I have a defined map of keys and I simple ask Pixel if any of them are pressed on each cycle:

keys = map[byte]pixelgl.Button{
    0x1: pixelgl.Key1, 0x2: pixelgl.Key2, 0x3: pixelgl.Key3, 0xC: pixelgl.Key4,
    0x4: pixelgl.KeyQ, 0x5: pixelgl.KeyW, 0x6: pixelgl.KeyE, 0xD: pixelgl.KeyR,
    0x7: pixelgl.KeyA, 0x8: pixelgl.KeyS, 0x9: pixelgl.KeyD, 0xE: pixelgl.KeyF,
    0xA: pixelgl.KeyZ, 0x0: pixelgl.KeyX, 0xB: pixelgl.KeyC, 0xF: pixelgl.KeyV,
}
...
for i, key := range keys {
    if window.Pressed(key) {
        vm.KeyDown(i)
    }
}
Notice that I am then calling the KeyDown method on the Chip8 VM itself. This method simple sets the appropriate element in a keys slice of byte on the VM to 1. This may seem strange as it doesn’t actually affect any of the memory or registers on the VM. That is because the Chip8 has 3 opcodes dedicated to key handling: one blocks execution until a key is pressed, one skips instructions if a key is pressed and the other skips execution if a key is not pressed.

Look for yourself

The emulator is now in a usable state; albeit a bit rough around the edges. All of the opcodes documented for the Chip8 have been implemented, so it should be able to play any ROM thrown at it.

To that end I have made the source code available on GitHub. Feel free to clone the repo down and give it a play.

The future

As I said the code is a bit rough right now. I am going to spend some time tidying it up and adding a whole bunch of tests. After that I’ll most likely have a think about what emulator to tackle next ;)