package emulator import "errors" type CHIP8 struct { memory [4096]byte v [16]byte i uint16 pc uint16 sp uint16 delayTimer uint8 soundTimer uint8 stack [16]uint16 keypad [16]bool // To transform the linear Memory to a 2D array for easier drawing, // having a (x, y) coordinate then (x, y) = graphics[x + (y * 64)] graphics [64 * 32]bool opcode uint16 fonts [80]byte } func NewChip8() *CHIP8 { chip8 := &CHIP8{ memory: [4096]byte{}, v: [16]byte{}, i: 0, // The original 0x200 code of the CHIP-8 interpreter was from 0x0 to 0x200, pc: 0x200, sp: 0, delayTimer: 0, soundTimer: 0, stack: [16]uint16{}, keypad: [16]bool{}, graphics: [64 * 32]bool{}, opcode: 0, fonts: [80]byte{}, } chip8.Initialize() return chip8 } func (c *CHIP8) Initialize() { charMap := [80]byte{ 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 } // Char map goes from 0x050 to 0x9F for i, charByte := range charMap { c.memory[i+0x50] = charByte } } func (c *CHIP8) LoadROMIntoMemory(dat []byte) error { if len(dat) > len(c.memory)-0x200 { return errors.New("ROM is too large to fit into memory") } // Roms start from 0x200 for i, datByte := range dat { c.memory[i+0x200] = datByte } return nil }