diff --git a/chip8/chip8.go b/chip8/chip8.go index bfec8cc..abff6e4 100644 --- a/chip8/chip8.go +++ b/chip8/chip8.go @@ -1,5 +1,7 @@ package chip8 +import "encoding/binary" + const ( MemorySize = 4096 // 4KB of memory StackSize = 16 @@ -41,3 +43,20 @@ func (emulator *Emulator) Reset() { emulator.Timer.Sound = 0 copy(emulator.Memory[ProgramAddress:], emulator.ROM) } + +func (emulator *Emulator) Step() { + instruction := binary.BigEndian.Uint16(emulator.Memory[emulator.PC:]) + + switch instruction & 0xF000 { + case 0x1000: // 1nnn - JP addr + emulator.Jump(instruction & 0x0FFF) + case 0x2000: // 2nnn - CALL addr + emulator.Call(instruction & 0x0FFF) + case 0x3000: // 3xkk - SE Vx, byte + emulator.SkipEqual(uint8(instruction&0x0F00>>8), uint8(instruction&0x00FF)) + case 0x4000: // 4xkk - SNE Vx, byte + emulator.SkipNotEqual(uint8(instruction&0x0F00>>8), uint8(instruction&0x00FF)) + case 0x5000: // 5xy0 - SE Vx, Vy + emulator.SkipRegistersEqual(uint8(instruction&0x0F00>>8), uint8(instruction&0x00F0>>4)) + } +} diff --git a/chip8/instructions.go b/chip8/instructions.go index 89dff7b..b74c736 100644 --- a/chip8/instructions.go +++ b/chip8/instructions.go @@ -9,31 +9,50 @@ func (emulator *Emulator) Return() { emulator.StackPop() } -func (emulator *Emulator) Jump(addr uint16) { - emulator.PC = addr +// Jump to location nnn. +// +// The interpreter sets the program counter to nnn. +func (emulator *Emulator) Jump(nnn uint16) { + emulator.PC = nnn } -func (emulator *Emulator) Call(addr uint16) { +// Call subroutine at nnn. +// +// The interpreter increments the stack pointer, then puts the current PC +// on the top of the stack. The PC is then set to nnn. +func (emulator *Emulator) Call(nnn uint16) { emulator.StackPush() - emulator.PC = addr + emulator.PC = nnn } -func (emulator *Emulator) SkipEqual(x uint8, value uint8) { - if emulator.V[x] == value { +// Skip next instruction if Vx = kk. +// +// The interpreter compares register Vx to kk, and if they are equal, +// increments the program counter by 2. +func (emulator *Emulator) SkipEqual(x uint8, kk uint8) { + if emulator.V[x] == kk { emulator.PC += InstructionSize * 2 } else { emulator.PC += InstructionSize } } -func (emulator *Emulator) SkipNotEqual(x uint8, value uint8) { - if emulator.V[x] != value { +// Skip next instruction if Vx != kk. +// +// The interpreter compares register Vx to kk, and if they are not equal, +// increments the program counter by 2. +func (emulator *Emulator) SkipNotEqual(x uint8, kk uint8) { + if emulator.V[x] != kk { emulator.PC += InstructionSize * 2 } else { emulator.PC += InstructionSize } } +// Skip next instruction if Vx = Vy. +// +// The interpreter compares register Vx to register Vy, and if they are equal, +// increments the program counter by 2. func (emulator *Emulator) SkipRegistersEqual(x uint8, y uint8) { if emulator.V[x] == emulator.V[y] { emulator.PC += InstructionSize * 2