From 3aa0f413db86605c24334f43c8c1e474c9b16622 Mon Sep 17 00:00:00 2001 From: Ivan Izaguirre Date: Sun, 10 Feb 2019 00:15:14 +0100 Subject: [PATCH] Passing tests up to 9 --- execute.go | 34 +++++++++++++++++++++++++++------- main.go | 18 +++++++++++++++++- memory.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/execute.go b/execute.go index 6f44e79..fbcf6f8 100644 --- a/execute.go +++ b/execute.go @@ -1,5 +1,7 @@ package main +import "fmt" + type state struct { registers registers memory memory @@ -94,7 +96,7 @@ func resolveWithAddressMode(s *state, line []uint8, addressMode int) (value uint type opcode struct { name string - bytes int + bytes int8 cycles int action opFunc } @@ -228,6 +230,7 @@ func buildOpAdd(addressMode int) opFunc { s.registers.setA(truncated) s.registers.updateFlagZN(truncated) s.registers.updateFlag(flagC, total > 0xFF) + // TODO: missing overflow flag } } } @@ -245,6 +248,7 @@ func buildOpSub(addressMode int) opFunc { s.registers.setA(truncated) s.registers.updateFlagZN(truncated) s.registers.updateFlag(flagC, total <= 0xFF) + // TODO: missing overflow flag } } } @@ -274,10 +278,15 @@ func pullWord(s *state) uint16 { } -func buildOpPull(reg int) opFunc { - return func(s *state, line []uint8, opcode opcode) { - s.registers.setRegister(reg, pullByte(s)) - } +func opPLA(s *state, line []uint8, opcode opcode) { + value := pullByte(s) + s.registers.setA(value) + s.registers.updateFlagZN(value) +} + +func opPLP(s *state, line []uint8, opcode opcode) { + value := pullByte(s) + s.registers.setP(value) } func opPHA(s *state, line []uint8, opcode opcode) { @@ -328,8 +337,8 @@ var opcodes = [256]opcode{ 0x48: opcode{"PHA", 1, 3, opPHA}, 0x08: opcode{"PHP", 1, 3, opPHP}, - 0x68: opcode{"PLA", 1, 4, buildOpPull(regA)}, - 0x28: opcode{"PLP", 1, 4, buildOpPull(regP)}, + 0x68: opcode{"PLA", 1, 4, opPLA}, + 0x28: opcode{"PLP", 1, 4, opPLP}, 0x09: opcode{"ORA", 2, 2, buildOpLogic(modeImmediate, operationOr)}, 0x05: opcode{"ORA", 2, 3, buildOpLogic(modeZeroPage, operationOr)}, @@ -504,3 +513,14 @@ func executeLine(s *state, line []uint8) { opcode := opcodes[line[0]] opcode.action(s, line, opcode) } + +func executeInstruction(s *state) { + pc := s.registers.getPC() + opcode := opcodes[s.memory[pc]] + fmt.Printf("%#04x %s: ", pc, opcode.name) + pcNext := pc + uint16(opcode.bytes) + s.registers.setPC(pcNext) + line := s.memory[pc:pcNext] + opcode.action(s, line, opcode) + fmt.Printf("%v, %v\n", s.registers, line) +} diff --git a/main.go b/main.go index 7905807..67b9228 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,21 @@ package main -func main() { +import "fmt" +func main() { + var s state + s.memory.loadBinary("6502_65C02_functional_tests/bin_files/6502_functional_test.bin") + + s.registers.setPC(0x0400) + for true { + for i := 0; i < 20; i++ { + testCase := s.memory[0x0200] + fmt.Printf("[ %d ] ", testCase) + pc := s.registers.getPC() + executeInstruction(&s) + if pc == s.registers.getPC() { + panic("No change in PC") + } + } + } } diff --git a/memory.go b/memory.go index 5288ace..d3af089 100644 --- a/memory.go +++ b/memory.go @@ -1,5 +1,10 @@ package main +import ( + "bufio" + "os" +) + type memory [65536]uint8 func (m *memory) getWord(address uint16) uint16 { @@ -10,3 +15,26 @@ func (m *memory) getZeroPageWord(address uint8) uint16 { return uint16(m[address]) + 0x100*uint16(m[address+1]) // TODO: Does address + 1 wraps around the zero page? } + +func (m *memory) loadBinary(filename string) { + f, err := os.Open(filename) + if err != nil { + panic(err) + } + defer f.Close() + + stats, statsErr := f.Stat() + if statsErr != nil { + panic(err) + } + + size := stats.Size() + bytes := make([]byte, size) + + buf := bufio.NewReader(f) + buf.Read(bytes) + + for i, v := range bytes { + m[i] = uint8(v) + } +}