-
-
Save bmerrill42/76755345c2660dc6426cc01e6a164283 to your computer and use it in GitHub Desktop.
chip8 emulator by a ruby noob
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'curses' | |
class Chip | |
fontset = [ | |
0xF0, 0x90, 0x90, 0x90, 0xF0,#0 | |
0x20, 0x60, 0x20, 0x20, 0x70,#1 | |
0xF0, 0x10, 0xF0, 0x80, 0xF0,#2 | |
0xF0, 0x10, 0xF0, 0x10, 0xF0,#3 | |
0x90, 0x90, 0xF0, 0x10, 0x10,#4 | |
0xF0, 0x80, 0xF0, 0x10, 0xF0,#5 | |
0xF0, 0x80, 0xF0, 0x90, 0xF0,#6 | |
0xF0, 0x10, 0x20, 0x40, 0x40,#7 | |
0xF0, 0x90, 0xF0, 0x90, 0xF0,#8 | |
0xF0, 0x90, 0xF0, 0x10, 0xF0,#9 | |
0xF0, 0x90, 0xF0, 0x90, 0x90,#A | |
0xE0, 0x90, 0xE0, 0x90, 0xE0,#B | |
0xF0, 0x80, 0x80, 0x80, 0xF0,#C | |
0xE0, 0x90, 0x90, 0x90, 0xE0,#D | |
0xF0, 0x80, 0xF0, 0x80, 0xF0,#E | |
0xF0, 0x80, 0xF0, 0x80, 0x80#F | |
] | |
def initialize | |
# initialize registers and memory | |
memory = Array.new(4096, 0) | |
v = Array.new(16, 0) | |
vf = 0 | |
i = 0 | |
pc = 0x200 | |
gfx = Array.new(64*32) | |
delay_timer = 0 | |
sound_timer = 0 | |
opcode = 0 | |
stack = Array.new(16, 0) | |
sp = 0 | |
key = Array.new(16) | |
memory[0..(fontset.length - 1)] = fontset[0..(fontset.length - 1)] | |
end | |
def loadgame | |
# figure out how to load file into array | |
buffer = [] | |
for i in buffer.len | |
memory[i + 0x200] = buffer[i] | |
end | |
end | |
def emulate_cycle | |
# fetch opcode | |
opcode = memory[pc] << 8 | memory[pc + 1] | |
# decode opcode | |
nnn = opcode & 0x0FFF | |
n = opcode & 0x000F | |
x = opcode 0x0F00 >> 8 | |
y = opcode 0x00F0 >> 4 | |
kk = opcode & 0x00FF | |
case opcode & 0xF000 | |
when 0x0000 | |
case opcode & 0x000F | |
when 0x0000 | |
#clear the screen | |
when 0x000E | |
#return from subroutine | |
end | |
when 0x1000 | |
pc = nnn | |
when 0x2000 | |
sp += 1 | |
stack[sp] = pc | |
pc = nnn | |
when 0x3000 | |
if v[x] == kk | |
pc += 4 | |
else | |
pc += 2 | |
end | |
when 0x4000 | |
if v[x] != kk | |
pc += 4 | |
else | |
pc += 2 | |
end | |
when 0x5000 | |
if v[x] == v[y] | |
pc += 4 | |
else | |
pc += 2 | |
end | |
when 0x6000 | |
v[x] = kk | |
pc += 2 | |
when 0x7000 | |
v[x] = v[x] + (kk) | |
pc += 2 | |
when 0x8000 | |
case n | |
when 0x0000 | |
v[x] = v[y] | |
pc += 2 | |
when 0x0001 | |
v[x] = v[x] | v[y] | |
pc += 2 | |
when 0x0002 | |
v[x] = v[x] & v[y] | |
pc += 2 | |
when 0x0003 | |
v[x] = v[x] ^ v[y] | |
pc += 2 | |
when 0x0004 | |
if (v[x] + v[y]) > 0xFF | |
vf = 1 | |
v[x] = (v[x] + v[y]) & 0xFF | |
else | |
vf = 0 | |
v[x] = (v[x] + v[y]) | |
end | |
pc += 2 | |
when 0x0005 | |
if v[x] > v[y] | |
vf = 1 | |
else | |
vf = 0 | |
end | |
v[x] = (v[x] - v[y]) | |
pc += 2 | |
when 0x0006 | |
if v[x] & 0x0001 == 1 | |
vf = 1 | |
else | |
vf = 0 | |
end | |
v[x] = (v[x] >> 1) & 0xFF | |
pc += 2 | |
when 0x0007 | |
pc += 2 | |
when 0x000E | |
if v[x] & 0x8000 == 1 | |
vf = 1 | |
else | |
vf = 0 | |
end | |
v[x] = (v[x] << 1) & 0xFF | |
pc += 2 | |
end | |
when 0x9000 | |
if v[x] != v[y] | |
pc += 4 | |
else | |
pc += 2 | |
end | |
when 0xA000 | |
i = nnn | |
pc += 2 | |
when 0xB000 | |
pc = nnn + v[0] | |
when 0xC000 | |
v[x] = rand(255) & kk | |
pc += 2 | |
when 0xD000 | |
pc += 2 | |
when 0xE000 | |
pc += 2 | |
when 0xF000 | |
case kk | |
when 0x07 | |
v[x] = delay_timer | |
pc += 2 | |
when 0x0A | |
#keypress listen | |
pc += 2 | |
when 0x15 | |
delay_timer = v[x] | |
pc += 2 | |
when 0x18 | |
sound_timer = v[x] | |
pc += 2 | |
when 0x1E | |
pc += 2 | |
when 0x29 | |
pc += 2 | |
when 0x55 | |
pc += 2 | |
when 0x65 | |
pc += 2 | |
else | |
puts "unknown opcode #{opcode.to_s(16)}" | |
pc += 2 | |
end | |
end | |
end | |
begin | |
chip8 = Chip.new | |
setup_graphics | |
setup_input | |
chip8.loadgame("pong") | |
loop do | |
chip8.emulate_cycle | |
if chip8.draw_flag != 0 | |
draw_graphics | |
end | |
chip8.set_keys | |
end | |
end | |
=begin | |
Curses.init_screen | |
begin | |
nb_lines = Curses.lines | |
nb_cols = Curses.cols | |
Curses.addstr("cols: #{nb_cols}\n") | |
Curses.addstr("lines: #{nb_lines}") | |
Curses.refresh | |
Curses.getch | |
ensure | |
Curses.close_screen | |
end | |
=end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment