mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-06-14 02:29:29 +00:00
Much faster resolution avoiding a single getSet with callbacks.
This commit is contained in:
parent
b2b009037e
commit
6387e93f06
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user