diff --git a/cpu.go b/cpu.go index c1a1166..d02d2f4 100644 --- a/cpu.go +++ b/cpu.go @@ -8,9 +8,10 @@ type Cpu struct { } const ( - ResetVector = 0xFFFC + ResetVector = 0xFFFC // 0xFFFC-FFFD ) +// Create an new Cpu instance with the specified AddressBus func NewCpu(bus *AddressBus) (*Cpu, error) { return &Cpu{bus: bus}, nil } @@ -19,7 +20,18 @@ func (c *Cpu) HasAddressBus() bool { return c.bus != nil } +// Reset the CPU, emulating the RESB pin. func (c *Cpu) Reset() { c.PC = c.bus.Read16(ResetVector) c.P = 0x34 } + +// Load the specified program data at the given memory location +// and point the Program Counter to the beginning of the program +func (c *Cpu) LoadProgram(data []byte, location uint16) { + for i, b := range data { + c.bus.Write(location+uint16(i), b) + } + + c.PC = location +} diff --git a/cpu_test.go b/cpu_test.go index 0b690bb..cab31a0 100644 --- a/cpu_test.go +++ b/cpu_test.go @@ -12,6 +12,8 @@ func NewRamMachine() (*Cpu, *AddressBus, *Ram) { bus.Attach(ram, 0x0000) cpu, _ := NewCpu(bus) + cpu.Reset() + return cpu, bus, ram } @@ -29,7 +31,7 @@ func TestCpuAddressBus(t *testing.T) { assert.True(cpu.HasAddressBus()) } -func TestCpuState(t *testing.T) { +func TestCpuReset(t *testing.T) { assert := assert.New(t) cpu, _, _ := NewRamMachine() @@ -46,3 +48,18 @@ func TestCpuState(t *testing.T) { // Read PC from $FFFC-FFFD assert.Equal(0x1234, cpu.PC) } + +func TestProgramLoading(t *testing.T) { + assert := assert.New(t) + + program := []byte{0xEA, 0xEB, 0xEC} + + cpu, bus, _ := NewRamMachine() + cpu.LoadProgram(program, 0x0300) + + assert.Equal(0xEA, bus.Read(0x0300)) + assert.Equal(0xEB, bus.Read(0x0301)) + assert.Equal(0xEC, bus.Read(0x0302)) + + assert.Equal(0x0300, cpu.PC) +}