diff --git a/execute.go b/execute.go index e2d792d..e387b1e 100644 --- a/execute.go +++ b/execute.go @@ -13,9 +13,12 @@ const modeNone = -1 const modeImmediate = 0 const modeZeroPage = 1 const modeZeroPageX = 3 +const modeZeroPageY = 6 const modeAbsolute = 2 const modeAbsoluteX = 4 const modeAbsoluteY = 5 +const modeIndexedIndirectX = 7 +const modeIndirectIndexedY = 8 // https://www.masswerk.at/6502/6502_instruction_set.html @@ -47,6 +50,9 @@ func opLDR(s *state, line []uint8, opcode opcode) { case modeZeroPageX: address := line[1] + s.registers.getX() value = s.memory[address] + case modeZeroPageY: + address := line[1] + s.registers.getY() + value = s.memory[address] case modeAbsolute: address := getWordInLine(line) value = s.memory[address] @@ -56,20 +62,48 @@ func opLDR(s *state, line []uint8, opcode opcode) { case modeAbsoluteY: address := getWordInLine(line) + uint16(s.registers.getY()) value = s.memory[address] + case modeIndexedIndirectX: + addressAddress := uint8(line[1] + s.registers.getX()) + address := s.memory.getZeroPageWord(addressAddress) + value = s.memory[address] + case modeIndirectIndexedY: + address := s.memory.getZeroPageWord(line[1]) + + uint16(s.registers.getY()) + value = s.memory[address] } s.registers.setRegister(opcode.reg, value) + + // TODO: Update flags (N, Z) } var opcodes = [256]opcode{ 0x00: opcode{"BRK", 1, 7, modeImmediate, regNone, opNOP}, + 0xA0: opcode{"LDY", 2, 2, modeImmediate, regY, opLDR}, + + 0xA1: opcode{"LDX", 2, 6, modeIndexedIndirectX, regA, opLDR}, + + 0xA2: opcode{"LDX", 2, 2, modeImmediate, regX, opLDR}, + 0xA4: opcode{"LDY", 2, 3, modeZeroPage, regY, opLDR}, 0xA5: opcode{"LDA", 2, 3, modeZeroPage, regA, opLDR}, - 0xB5: opcode{"LDA", 2, 4, modeZeroPageX, regA, opLDR}, + 0xA6: opcode{"LDX", 2, 3, modeZeroPage, regX, opLDR}, 0xA9: opcode{"LDA", 2, 2, modeImmediate, regA, opLDR}, + + 0xAC: opcode{"LDY", 3, 4, modeAbsolute, regY, opLDR}, 0xAD: opcode{"LDA", 3, 4, modeAbsolute, regA, opLDR}, + 0xAE: opcode{"LDX", 3, 4, modeAbsolute, regX, opLDR}, + + 0xB1: opcode{"LDX", 2, 5, modeIndirectIndexedY, regA, opLDR}, // Extra cycles + + 0xB4: opcode{"LDY", 2, 4, modeZeroPageX, regY, opLDR}, + 0xB5: opcode{"LDA", 2, 4, modeZeroPageX, regA, opLDR}, + 0xB6: opcode{"LDX", 2, 4, modeZeroPageY, regX, opLDR}, + 0xB9: opcode{"LDA", 3, 4, modeAbsoluteY, regA, opLDR}, // Extra cycles + 0xBC: opcode{"LDY", 3, 4, modeAbsoluteX, regY, opLDR}, // Extra cycles 0xBD: opcode{"LDA", 3, 4, modeAbsoluteX, regA, opLDR}, // Extra cycles + 0xBE: opcode{"LDX", 3, 4, modeAbsoluteY, regX, opLDR}, // Extra cycles } func executeLine(s *state, line []uint8) { diff --git a/execute_test.go b/execute_test.go index 7a4a64a..82b3e33 100644 --- a/execute_test.go +++ b/execute_test.go @@ -57,4 +57,13 @@ func TestLDA(t *testing.T) { t.Error("Error in LDA abs, Y") } + s.memory[0x24] = 0x74 + s.memory[0x25] = 0x20 + s.registers.setX(0x04) + s.memory[0x2074] = 0x66 + executeLine(&s, []uint8{0xA1, 0x20}) + if s.registers.getA() != 0x66 { + t.Error("Error in LDA (oper,X)") + } + } diff --git a/memory.go b/memory.go index 367b8be..5288ace 100644 --- a/memory.go +++ b/memory.go @@ -1,3 +1,12 @@ package main type memory [65536]uint8 + +func (m *memory) getWord(address uint16) uint16 { + return uint16(m[address]) + 0x100*uint16(m[address+1]) +} + +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? +}