package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
)
|
|
|
|
type chip8 struct {
|
|
opcode uint16
|
|
memory [4096]byte
|
|
|
|
// register
|
|
v [16]byte
|
|
|
|
index uint16
|
|
pc uint16
|
|
|
|
gfx [64 * 32]byte
|
|
|
|
delayTimer byte
|
|
soundTimer byte
|
|
|
|
stack [16]uint16
|
|
sp int
|
|
|
|
key [16]byte
|
|
|
|
drawFlag bool
|
|
}
|
|
|
|
// Initialize registers and memory once
|
|
func (c *chip8) initialize() {
|
|
c.pc = 0x200
|
|
c.opcode = 0
|
|
c.index = 0
|
|
c.sp = 0
|
|
}
|
|
|
|
func (c *chip8) emulateCycle() {
|
|
// Fetch Opcode
|
|
c.opcode = uint16(c.memory[c.pc])<<8 | uint16(c.memory[c.pc+1])
|
|
|
|
// Decode Opcode
|
|
// https://en.wikipedia.org/wiki/CHIP-8#Opcode_table
|
|
// http://www.multigesture.net/wp-content/uploads/mirror/goldroad/chip8_instruction_set.shtml
|
|
switch c.opcode & 0xF000 {
|
|
case 0x0000:
|
|
switch c.opcode & 0x000F {
|
|
case 0x0000: // 0x00E0
|
|
// clear screen
|
|
// TODO
|
|
c.pc += 2
|
|
break
|
|
case 0x000E: // 0x00EE
|
|
// TODO
|
|
break
|
|
default:
|
|
fmt.Printf("Unknown opcode [0x0000]: 0x%X\n", c.opcode)
|
|
}
|
|
case 0x2000:
|
|
c.stack[c.sp] = c.pc
|
|
c.sp++
|
|
c.pc = c.opcode & 0x0FFF
|
|
break
|
|
case 0x6000:
|
|
pos := (c.opcode & 0x0F00) >> 8
|
|
c.v[pos] = byte(c.opcode)
|
|
c.pc += 2
|
|
break
|
|
default:
|
|
fmt.Printf("Unknown opcode: 0x%X\n", c.opcode)
|
|
}
|
|
|
|
// Update timers
|
|
if c.delayTimer > 0 {
|
|
c.delayTimer--
|
|
}
|
|
if c.soundTimer > 0 {
|
|
if c.soundTimer == 1 {
|
|
fmt.Printf("Beep!\n")
|
|
}
|
|
c.soundTimer--
|
|
}
|
|
}
|
|
|
|
func (c *chip8) loadGame(filepath string) error {
|
|
return nil
|
|
}
|
|
|
|
func (c *chip8) drawGraphics() {
|
|
|
|
}
|
|
|
|
func (c *chip8) setKeys() {
|
|
|
|
}
|
|
|
|
func main() {
|
|
filepath := flag.String("file", "file-path", "file path of the input file")
|
|
|
|
flag.Parse()
|
|
|
|
// setupGraphics()
|
|
// setupInput()
|
|
|
|
var c chip8
|
|
c.initialize()
|
|
err := c.loadGame(*filepath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
for {
|
|
c.emulateCycle()
|
|
if c.drawFlag {
|
|
c.drawGraphics()
|
|
c.setKeys()
|
|
}
|
|
}
|
|
}
|