mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-22 09:30:19 +00:00
104 lines
2.5 KiB
Go
104 lines
2.5 KiB
Go
package core6502
|
|
|
|
const (
|
|
modeImplicit = iota + 1
|
|
modeImplicitX
|
|
modeImplicitY
|
|
modeAccumulator
|
|
modeImmediate
|
|
modeZeroPage
|
|
modeZeroPageX
|
|
modeZeroPageY
|
|
modeRelative
|
|
modeAbsolute
|
|
modeAbsoluteX
|
|
modeAbsoluteY
|
|
modeIndirect
|
|
modeIndexedIndirectX
|
|
modeIndirectIndexedY
|
|
)
|
|
|
|
func getWordInLine(line []uint8) uint16 {
|
|
return uint16(line[1]) + 0x100*uint16(line[2])
|
|
}
|
|
|
|
func resolveValue(s *State, line []uint8, opcode opcode) uint8 {
|
|
getValue, _, _ := resolve(s, line, opcode)
|
|
return getValue()
|
|
}
|
|
|
|
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) func(uint8) {
|
|
_, setValue, _ := resolve(s, line, opcode)
|
|
return setValue
|
|
}
|
|
|
|
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
|
|
|
|
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:
|
|
address = uint16(line[1] + s.reg.getX())
|
|
case modeZeroPageY:
|
|
address = uint16(line[1] + s.reg.getY())
|
|
case modeAbsolute:
|
|
address = getWordInLine(line)
|
|
case modeAbsoluteX:
|
|
address = getWordInLine(line) + uint16(s.reg.getX())
|
|
case modeAbsoluteY:
|
|
address = getWordInLine(line) + uint16(s.reg.getY())
|
|
case modeIndexedIndirectX:
|
|
addressAddress := uint8(line[1] + s.reg.getX())
|
|
address = getZeroPageWord(s.mem, addressAddress)
|
|
case modeIndirect:
|
|
addressAddress := getWordInLine(line)
|
|
address = getWord(s.mem, addressAddress)
|
|
case modeIndirectIndexedY:
|
|
address = getZeroPageWord(s.mem, line[1]) +
|
|
uint16(s.reg.getY())
|
|
}
|
|
|
|
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 {
|
|
// Todo: assert impossible
|
|
}
|
|
}
|
|
return
|
|
}
|