package chip8 import "fmt" const graphicsBufferSize = 64 * 32 type Chip8 struct { address_register uint16 beep_timer uint16 draw_required bool delay_timer uint16 graphics [graphicsBufferSize]uint8 keys [16]uint8 memory [4096]uint8 opcode uint16 pc uint16 registers [16]uint8 // an array - has a fixed length stack []uint16 // a slice - basically a c++ vector } // we can't have const arrays in go // This is a good a solution as any func getLetters() []uint8 { return []uint8{ 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 } func NewCHIP8(prog []uint8) *Chip8 { cpu := Chip8{pc: 0x200} memory_slice := cpu.memory[:80] copy(memory_slice, getLetters()) memory_slice = cpu.memory[200:] copy(memory_slice, prog) // Do some extra checking to ensure the right // Stuff is copied return &cpu } func (cpu *Chip8) GetGraphicsBuffer() [graphicsBufferSize]uint8 { return cpu.graphics } func (cpu *Chip8) clearDisplay() { // fuck it the gc can do the hard work for us cpu.graphics = [64 * 32]uint8{} cpu.draw_required = true } // what if there's nothing in the stack? // return something sensible func (cpu *Chip8) leaveFunction() { cpu.pc = cpu.stack[len(cpu.stack)-1] cpu.stack[len(cpu.stack)-1] = 0 cpu.stack = cpu.stack[:len(cpu.stack)-1] } func (cpu *Chip8) goTo() { cpu.pc = cpu.opcode & 0x0FFF } func (cpu *Chip8) callSubroutine() { cpu.stack = append(cpu.stack, cpu.pc) cpu.pc = cpu.opcode & 0x0FFF } func (cpu *Chip8) skipIfRegisterEqual() { r := (cpu.opcode) >> 8 & 0x0F if cpu.registers[r] == uint8(cpu.opcode&0xFF) { cpu.pc += 2 } } func (cpu *Chip8) skipIfRegisterNotEqual() { r := (cpu.opcode) >> 8 & 0x0F if cpu.registers[r] != uint8(cpu.opcode&0xFF) { cpu.pc += 2 } } func (cpu *Chip8) skipIfRegistersEqual() { x, y := (cpu.opcode>>8)&0x0F, (cpu.opcode>>4)&0x0F if cpu.registers[x] == cpu.registers[y] { cpu.pc += 2 } } func (cpu *Chip8) setRegisterTo() { r := (cpu.opcode >> 8) & 0x0F cpu.registers[r] = uint8(cpu.opcode & 0xFF) } func (cpu *Chip8) RegisterPlusEqualsNN() {} // QUESTION HERE - WHAT DO IF IT WOULD WRAP ROUND? func main() { fmt.Printf("Hello world!\n") prog := []uint8{1, 2, 3, 4} new_cpu := NewCHIP8(prog) fmt.Printf("%d\n", new_cpu.opcode) }