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 {
|
func resolveValue(s *State, line []uint8, opcode opcode) uint8 {
|
||||||
getValue, _, _ := resolve(s, line, opcode)
|
switch opcode.addressMode {
|
||||||
return getValue()
|
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)) {
|
func resolveSetValue(s *State, line []uint8, opcode opcode, value uint8) {
|
||||||
getValue, setValue, _ := resolve(s, line, opcode)
|
switch opcode.addressMode {
|
||||||
value = getValue()
|
case modeAccumulator:
|
||||||
return
|
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) {
|
// The value is in memory
|
||||||
_, setValue, _ := resolve(s, line, opcode)
|
address := resolveAddress(s, line, opcode)
|
||||||
return setValue
|
s.mem.Poke(address, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveAddress(s *State, line []uint8, opcode opcode) uint16 {
|
func resolveAddress(s *State, line []uint8, opcode opcode) uint16 {
|
||||||
_, _, address := resolve(s, line, opcode)
|
var address uint16
|
||||||
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 {
|
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:
|
case modeZeroPage:
|
||||||
address = uint16(line[1])
|
address = uint16(line[1])
|
||||||
case modeZeroPageX:
|
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,
|
// Two addressing modes combined. We refer to the second one, relative,
|
||||||
// placed one byte after the zeropage reference
|
// placed one byte after the zeropage reference
|
||||||
address = s.reg.getPC() + uint16(int8(line[2])) // Note: line[2] is signed
|
address = s.reg.getPC() + uint16(int8(line[2])) // Note: line[2] is signed
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("Assert failed. Missing addressing mode")
|
panic("Assert failed. Missing addressing mode")
|
||||||
}
|
}
|
||||||
|
return address
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lineString(line []uint8, opcode opcode) string {
|
func lineString(line []uint8, opcode opcode) string {
|
||||||
|
|
|
@ -12,20 +12,20 @@ func buildOpTransfer(regSrc int, regDst int) opFunc {
|
||||||
|
|
||||||
func buildOpIncDec(inc bool) opFunc {
|
func buildOpIncDec(inc bool) opFunc {
|
||||||
return func(s *State, line []uint8, opcode opcode) {
|
return func(s *State, line []uint8, opcode opcode) {
|
||||||
value, setValue := resolveGetSetValue(s, line, opcode)
|
value := resolveValue(s, line, opcode)
|
||||||
if inc {
|
if inc {
|
||||||
value++
|
value++
|
||||||
} else {
|
} else {
|
||||||
value--
|
value--
|
||||||
}
|
}
|
||||||
s.reg.updateFlagZN(value)
|
s.reg.updateFlagZN(value)
|
||||||
setValue(value)
|
resolveSetValue(s, line, opcode, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildOpShift(isLeft bool, isRotate bool) opFunc {
|
func buildOpShift(isLeft bool, isRotate bool) opFunc {
|
||||||
return func(s *State, line []uint8, opcode opcode) {
|
return func(s *State, line []uint8, opcode opcode) {
|
||||||
value, setValue := resolveGetSetValue(s, line, opcode)
|
value := resolveValue(s, line, opcode)
|
||||||
|
|
||||||
oldCarry := s.reg.getFlagBit(flagC)
|
oldCarry := s.reg.getFlagBit(flagC)
|
||||||
var carry bool
|
var carry bool
|
||||||
|
@ -44,7 +44,7 @@ func buildOpShift(isLeft bool, isRotate bool) opFunc {
|
||||||
}
|
}
|
||||||
s.reg.updateFlag(flagC, carry)
|
s.reg.updateFlag(flagC, carry)
|
||||||
s.reg.updateFlagZN(value)
|
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 {
|
func buildOpStore(regSrc int) opFunc {
|
||||||
return func(s *State, line []uint8, opcode opcode) {
|
return func(s *State, line []uint8, opcode opcode) {
|
||||||
setValue := resolveSetValue(s, line, opcode)
|
|
||||||
value := s.reg.getRegister(regSrc)
|
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 {
|
func buildOpSetBit(bit uint8, set bool) opFunc {
|
||||||
return func(s *State, line []uint8, opcode opcode) {
|
return func(s *State, line []uint8, opcode opcode) {
|
||||||
value, setValue := resolveGetSetValue(s, line, opcode)
|
value := resolveValue(s, line, opcode)
|
||||||
if set {
|
if set {
|
||||||
setValue(value | (1 << bit))
|
value = value | (1 << bit)
|
||||||
} else {
|
} 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) {
|
func opTRB(s *State, line []uint8, opcode opcode) {
|
||||||
value, setValue := resolveGetSetValue(s, line, opcode)
|
value := resolveValue(s, line, opcode)
|
||||||
a := s.reg.getA()
|
a := s.reg.getA()
|
||||||
s.reg.updateFlag(flagZ, (value&a) == 0)
|
s.reg.updateFlag(flagZ, (value&a) == 0)
|
||||||
setValue(value &^ a)
|
resolveSetValue(s, line, opcode, value&^a)
|
||||||
}
|
}
|
||||||
|
|
||||||
func opTSB(s *State, line []uint8, opcode opcode) {
|
func opTSB(s *State, line []uint8, opcode opcode) {
|
||||||
value, setValue := resolveGetSetValue(s, line, opcode)
|
value := resolveValue(s, line, opcode)
|
||||||
a := s.reg.getA()
|
a := s.reg.getA()
|
||||||
s.reg.updateFlag(flagZ, (value&a) == 0)
|
s.reg.updateFlag(flagZ, (value&a) == 0)
|
||||||
setValue(value | a)
|
resolveSetValue(s, line, opcode, value|a)
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildOpCompare(reg int) opFunc {
|
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) {
|
func opSTZ(s *State, line []uint8, opcode opcode) {
|
||||||
setValue := resolveSetValue(s, line, opcode)
|
resolveSetValue(s, line, opcode, 0)
|
||||||
setValue(0)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user