refactor + some instructions + stack implementation
This commit is contained in:
parent
3feed8e5c0
commit
e31a6a3b64
|
@ -1,13 +1,23 @@
|
|||
package chip8
|
||||
|
||||
const (
|
||||
MemorySize = 4096 // 4KB of memory
|
||||
StackSize = 16
|
||||
InstructionSize = 2
|
||||
)
|
||||
|
||||
const (
|
||||
ProgramAddress = uint16(0x0200)
|
||||
StackAddress = uint16(0x0EA0)
|
||||
VideoBufferAddress = uint16(0x0F00)
|
||||
)
|
||||
|
||||
type Emulator struct {
|
||||
V [16]uint8 // general registers
|
||||
I uint16 // address register
|
||||
SP uint16 // stack pointer
|
||||
PC uint16 // program counter
|
||||
Memory [4096]uint8 // 4KB of system RAM
|
||||
Stack []uint8 // 32 bytes of stack. starting at 0x0EA0
|
||||
Screen []uint8 // 256 bytes of display buffer. starting at 0x0F00
|
||||
Memory [MemorySize]uint8 // 4KB of system RAM
|
||||
Timer struct {
|
||||
Delay uint8 // delay timer
|
||||
Sound uint8 // sound timer
|
||||
|
@ -23,13 +33,11 @@ func NewEmulator() *Emulator {
|
|||
|
||||
func (emulator *Emulator) Reset() {
|
||||
emulator.V = [16]uint8{}
|
||||
emulator.I = 0x00
|
||||
emulator.SP = 0x00
|
||||
emulator.PC = 0x0200
|
||||
emulator.Memory = [4096]uint8{}
|
||||
emulator.Stack = emulator.Memory[0x0EA0:]
|
||||
emulator.Screen = emulator.Memory[0x0F00:]
|
||||
emulator.I = 0
|
||||
emulator.SP = StackAddress
|
||||
emulator.PC = ProgramAddress
|
||||
emulator.Memory = [MemorySize]uint8{}
|
||||
emulator.Timer.Delay = 0
|
||||
emulator.Timer.Sound = 0
|
||||
copy(emulator.Memory[0x0200:], emulator.ROM)
|
||||
copy(emulator.Memory[ProgramAddress:], emulator.ROM)
|
||||
}
|
||||
|
|
43
chip8/instructions.go
Normal file
43
chip8/instructions.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package chip8
|
||||
|
||||
func (emulator *Emulator) ClearScreen() {
|
||||
// TODO: clear the screen buffer
|
||||
emulator.PC += InstructionSize
|
||||
}
|
||||
|
||||
func (emulator *Emulator) Return() {
|
||||
emulator.StackPop()
|
||||
}
|
||||
|
||||
func (emulator *Emulator) Jump(addr uint16) {
|
||||
emulator.PC = addr
|
||||
}
|
||||
|
||||
func (emulator *Emulator) Call(addr uint16) {
|
||||
emulator.StackPush()
|
||||
emulator.PC = addr
|
||||
}
|
||||
|
||||
func (emulator *Emulator) SkipEqual(x uint8, value uint8) {
|
||||
if emulator.V[x] == value {
|
||||
emulator.PC += InstructionSize * 2
|
||||
} else {
|
||||
emulator.PC += InstructionSize
|
||||
}
|
||||
}
|
||||
|
||||
func (emulator *Emulator) SkipNotEqual(x uint8, value uint8) {
|
||||
if emulator.V[x] != value {
|
||||
emulator.PC += InstructionSize * 2
|
||||
} else {
|
||||
emulator.PC += InstructionSize
|
||||
}
|
||||
}
|
||||
|
||||
func (emulator *Emulator) SkipRegistersEqual(x uint8, y uint8) {
|
||||
if emulator.V[x] == emulator.V[y] {
|
||||
emulator.PC += InstructionSize * 2
|
||||
} else {
|
||||
emulator.PC += InstructionSize
|
||||
}
|
||||
}
|
1
chip8/instructions_test.go
Normal file
1
chip8/instructions_test.go
Normal file
|
@ -0,0 +1 @@
|
|||
package chip8_test
|
20
chip8/stack.go
Normal file
20
chip8/stack.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package chip8
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
func (emulator *Emulator) StackPush() {
|
||||
if emulator.SP == StackAddress+StackSize*2 {
|
||||
panic("chip8: stack overflow")
|
||||
}
|
||||
binary.BigEndian.PutUint16(emulator.Memory[emulator.SP:], emulator.PC)
|
||||
emulator.SP += 2
|
||||
}
|
||||
|
||||
func (emulator *Emulator) StackPop() {
|
||||
if emulator.SP == StackAddress {
|
||||
panic("chip8: nothing to pop from stack")
|
||||
}
|
||||
emulator.SP -= 2
|
||||
emulator.PC = binary.BigEndian.Uint16(emulator.Memory[emulator.SP:])
|
||||
binary.BigEndian.PutUint16(emulator.Memory[emulator.SP:], 0x00) // clean the stack position
|
||||
}
|
31
chip8/stack_test.go
Normal file
31
chip8/stack_test.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package chip8_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tangzero/chip8-emulator/chip8"
|
||||
)
|
||||
|
||||
func TestEmulator_StackPush(t *testing.T) {
|
||||
emulator := chip8.NewEmulator()
|
||||
|
||||
emulator.PC = 0xABCD
|
||||
emulator.StackPush()
|
||||
|
||||
assert.Equal(t, uint8(0xAB), emulator.Memory[chip8.StackAddress])
|
||||
assert.Equal(t, uint8(0xCD), emulator.Memory[chip8.StackAddress+1])
|
||||
assert.Equal(t, chip8.StackAddress+2, emulator.SP)
|
||||
}
|
||||
|
||||
func TestEmulator_StackPop(t *testing.T) {
|
||||
emulator := chip8.NewEmulator()
|
||||
|
||||
emulator.SP = chip8.StackAddress + 32
|
||||
emulator.Memory[chip8.StackAddress+30] = 0xEE
|
||||
emulator.Memory[chip8.StackAddress+31] = 0xFF
|
||||
emulator.StackPop()
|
||||
|
||||
assert.Equal(t, uint16(0xEEFF), emulator.PC)
|
||||
assert.Equal(t, chip8.StackAddress+30, emulator.SP)
|
||||
}
|
Loading…
Reference in New Issue
Block a user