diff --git a/core6502/addressing.go b/core6502/addressing.go index 072ab88..7997a1f 100644 --- a/core6502/addressing.go +++ b/core6502/addressing.go @@ -29,46 +29,44 @@ func getWordInLine(line []uint8) uint16 { } func resolveValue(s *State, line []uint8, opcode opcode) uint8 { - getValue, _, _ := resolve(s, line, opcode) - return getValue() + switch opcode.addressMode { + case modeAccumulator: + return s.reg.getA() + case modeImplicitX: + return s.reg.getX() + case modeImplicitY: + return s.reg.getY() + case modeImmediate: + return line[1] + } + + // The value is in memory + address := resolveAddress(s, line, opcode) + return s.mem.Peek(address) } -func resolveGetSetValue(s *State, line []uint8, opcode opcode) (value uint8, setValue func(uint8)) { - getValue, setValue, _ := resolve(s, line, opcode) - value = getValue() - return -} +func resolveSetValue(s *State, line []uint8, opcode opcode, value uint8) { + switch opcode.addressMode { + case modeAccumulator: + s.reg.setA(value) + return + case modeImplicitX: + s.reg.setX(value) + return + case modeImplicitY: + s.reg.setY(value) + return + } -func resolveSetValue(s *State, line []uint8, opcode opcode) func(uint8) { - _, setValue, _ := resolve(s, line, opcode) - return setValue + // The value is in memory + address := resolveAddress(s, line, opcode) + s.mem.Poke(address, value) } func resolveAddress(s *State, line []uint8, opcode opcode) uint16 { - _, _, address := resolve(s, line, opcode) - return address -} - -func resolve(s *State, line []uint8, opcode opcode) (getValue func() uint8, setValue func(uint8), address uint16) { - hasAddress := true - register := regNone + var address uint16 switch opcode.addressMode { - case modeAccumulator: - getValue = func() uint8 { return s.reg.getA() } - hasAddress = false - register = regA - case modeImplicitX: - getValue = func() uint8 { return s.reg.getX() } - hasAddress = false - register = regX - case modeImplicitY: - getValue = func() uint8 { return s.reg.getY() } - hasAddress = false - register = regY - case modeImmediate: - getValue = func() uint8 { return line[1] } - hasAddress = false case modeZeroPage: address = uint16(line[1]) case modeZeroPageX: @@ -103,25 +101,10 @@ func resolve(s *State, line []uint8, opcode opcode) (getValue func() uint8, setV // Two addressing modes combined. We refer to the second one, relative, // placed one byte after the zeropage reference address = s.reg.getPC() + uint16(int8(line[2])) // Note: line[2] is signed - default: panic("Assert failed. Missing addressing mode") } - - if hasAddress { - getValue = func() uint8 { return s.mem.Peek(address) } - } - - setValue = func(value uint8) { - if hasAddress { - s.mem.Poke(address, value) - } else if register != regNone { - s.reg.setRegister(register, value) - } else { - panic("Assert failed. Should never happen") - } - } - return + return address } func lineString(line []uint8, opcode opcode) string { diff --git a/core6502/operations.go b/core6502/operations.go index 36c169f..4bdf917 100644 --- a/core6502/operations.go +++ b/core6502/operations.go @@ -12,20 +12,20 @@ func buildOpTransfer(regSrc int, regDst int) opFunc { func buildOpIncDec(inc bool) opFunc { return func(s *State, line []uint8, opcode opcode) { - value, setValue := resolveGetSetValue(s, line, opcode) + value := resolveValue(s, line, opcode) if inc { value++ } else { value-- } s.reg.updateFlagZN(value) - setValue(value) + resolveSetValue(s, line, opcode, value) } } func buildOpShift(isLeft bool, isRotate bool) opFunc { return func(s *State, line []uint8, opcode opcode) { - value, setValue := resolveGetSetValue(s, line, opcode) + value := resolveValue(s, line, opcode) oldCarry := s.reg.getFlagBit(flagC) var carry bool @@ -44,7 +44,7 @@ func buildOpShift(isLeft bool, isRotate bool) opFunc { } s.reg.updateFlag(flagC, carry) s.reg.updateFlagZN(value) - setValue(value) + resolveSetValue(s, line, opcode, value) } } @@ -58,9 +58,8 @@ func buildOpLoad(regDst int) opFunc { func buildOpStore(regSrc int) opFunc { return func(s *State, line []uint8, opcode opcode) { - setValue := resolveSetValue(s, line, opcode) value := s.reg.getRegister(regSrc) - setValue(value) + resolveSetValue(s, line, opcode, value) } } @@ -96,12 +95,13 @@ func buildOpBranchOnBit(bit uint8, test bool) opFunc { func buildOpSetBit(bit uint8, set bool) opFunc { return func(s *State, line []uint8, opcode opcode) { - value, setValue := resolveGetSetValue(s, line, opcode) + value := resolveValue(s, line, opcode) if set { - setValue(value | (1 << bit)) + value = value | (1 << bit) } else { - setValue(value &^ (1 << bit)) + value = value &^ (1 << bit) } + resolveSetValue(s, line, opcode, value) } } @@ -117,17 +117,17 @@ func opBIT(s *State, line []uint8, opcode opcode) { } func opTRB(s *State, line []uint8, opcode opcode) { - value, setValue := resolveGetSetValue(s, line, opcode) + value := resolveValue(s, line, opcode) a := s.reg.getA() s.reg.updateFlag(flagZ, (value&a) == 0) - setValue(value &^ a) + resolveSetValue(s, line, opcode, value&^a) } func opTSB(s *State, line []uint8, opcode opcode) { - value, setValue := resolveGetSetValue(s, line, opcode) + value := resolveValue(s, line, opcode) a := s.reg.getA() s.reg.updateFlag(flagZ, (value&a) == 0) - setValue(value | a) + resolveSetValue(s, line, opcode, value|a) } func buildOpCompare(reg int) opFunc { @@ -305,6 +305,5 @@ func opBRKAlt(s *State, line []uint8, opcode opcode) { } func opSTZ(s *State, line []uint8, opcode opcode) { - setValue := resolveSetValue(s, line, opcode) - setValue(0) + resolveSetValue(s, line, opcode, 0) }