Hieu Nguyen

Handle Interrupt for Chip 8

Sep 27 2016


Introduction (Reference)

Interrupt in chip 8 is very simple: signal from its keyboard. Chip 8 has a 16-key hexadecimal with the following layout:

1 2 3 C
4 5 6 D
7 8 9 E
A 0 B F

To be able to emulate this, we just need to map this keyboard to our current keyboard (in this example, I will use normal QWERTY keyboard)

Implementation

In Chip8 instruction codes, there are two codes which relate to keyboard:

Because Chip8 supports multiple keys press, we have to store an array to check if a key is pressed or not:

keys = Array.new(0xF)

In my chip 8, I use gosu for catching keyboard events. Gosu #button_up and #button_down will return a variable represent the key which is pressed or released. We need a way to convert this variable to the index of the keys array:

def button_up(key)
  key_char = Gosu.button_id_to_char(key)
  return unless key_char # we only process non-control keys

  button_name = KEY_MAP[key_char] # KEY_MAP is a map which map the keyboard keys to chip_8 keys, for ex: 'a' => 0xA
  return unless button_name # we only process valid keys

  keys[button_name] = 1
end

We can implement the instruction now:

when 0xE000
  key = chip.registers[(opcode & 0x0F00) >> 8]

  case opcode & 0x00FF
  when 0x009E
    if chip.keys[key] != 0
      increase_program_counter
    end

  when 0x00A1
    if chip.keys[key] == 0
      increase_program_counter
    end
  end
# ...

The chip 8 program will response to your keyboard now :)

Result

You can check out the code in chip_8 and take a look.