ARM package now receives environment instance

environment used to test the extent of the ARM.Plumb() function. this
function is called often from the caching package. some of the work done
by the Plumb() function is not needed for caching purposes and cases a
lot of memory churn
This commit is contained in:
JetSetIlly 2024-05-03 11:30:27 +01:00
parent 8e4838d582
commit 578e2a846a
7 changed files with 39 additions and 21 deletions

View file

@ -106,7 +106,7 @@ func (cart *Ace) PlumbFromDifferentEmulation(env *environment.Environment) {
}
cart.arm = arm.NewARM(cart.env, cart.mem.model, cart.mem, cart)
cart.mem.Plumb(cart.arm)
cart.arm.Plumb(cart.armState, cart.mem, cart)
cart.arm.Plumb(cart.env, cart.armState, cart.mem, cart)
cart.armState = nil
cart.yieldHook = coprocessor.StubCartYieldHook{}
}
@ -118,7 +118,7 @@ func (cart *Ace) Plumb(env *environment.Environment) {
panic("cannot plumb this ELF instance because the ARM state is nil")
}
cart.mem.Plumb(cart.arm)
cart.arm.Plumb(cart.armState, cart.mem, cart)
cart.arm.Plumb(cart.env, cart.armState, cart.mem, cart)
cart.armState = nil
}

View file

@ -189,12 +189,18 @@ type ARMState struct {
instruction32bitOpcodeHi uint16
}
// Snapshort makes a copy of the ARMState.
// Snapshot implements the mapper.CartMapper interface.
func (s *ARMState) Snapshot() *ARMState {
n := *s
return &n
}
// Plumb implements the mapper.CartMapper interface.
func (s *ARMState) Plumb(env *environment.Environment) {
s.mam.Plumb(env)
s.rng.Plumb(env)
}
// ARM implements the ARM7TDMI-S LPC2103 processor.
type ARM struct {
env *environment.Environment
@ -353,7 +359,7 @@ func (arm *ARM) SetDeveloper(dev coprocessor.CartCoProcDeveloper) {
arm.dev = dev
}
// Snapshort makes a copy of the ARM state.
// Snapshot implements the mapper.CartMapper interface.
func (arm *ARM) Snapshot() *ARMState {
return arm.state.Snapshot()
}
@ -364,25 +370,32 @@ func (arm *ARM) Snapshot() *ARMState {
// The ARMState argument can be nil as a special case. If it is nil then the
// existing state does not change. For some cartridge mappers this is acceptable
// and more convenient
func (arm *ARM) Plumb(state *ARMState, mem SharedMemory, hook CartridgeHook) {
//
// Plumb implements the mapper.CartMapper interface.
func (arm *ARM) Plumb(env *environment.Environment, state *ARMState, mem SharedMemory, hook CartridgeHook) {
arm.env = env
arm.mem = mem
arm.hook = hook
// always clear caches on a plumb event
arm.ClearCaches()
if state != nil {
arm.state = state
arm.state.Plumb(env)
}
// if we're plumbing in a new state then we *must* reevaluate the
// pointer the program memory
// any more plumbing work is superfluous unless we're dealing with the main
// emulation environment
if !arm.env.IsEmulation(environment.MainEmulation) {
return
}
// if we're plumbing in a new state then we *must* reevaluate the
// pointer the program memory
if state != nil {
arm.checkProgramMemory(true)
}
}
// ClearCaches should be used very rarely. It empties the instruction and
// disassembly caches.
func (arm *ARM) ClearCaches() {
// execution cache must be cleared because the old cache will be pointing to
// functions in another instance of ARM
arm.executionCache = make(map[uint32][]decodeFunction)
}

View file

@ -59,7 +59,8 @@ func newMam(env *environment.Environment, mmap architecture.Map) mam {
}
}
func (m *mam) Reset() {
func (m *mam) Plumb(env *environment.Environment) {
m.env = env
}
func (m *mam) updatePrefs() {

View file

@ -57,6 +57,10 @@ func NewRNG(env *environment.Environment, mmap architecture.Map) RNG {
}
}
func (r *RNG) Plumb(env *environment.Environment) {
r.env = env
}
func (r *RNG) Reset() {
r.control = 0x0
}

View file

@ -170,7 +170,7 @@ func (cart *cdf) Plumb(env *environment.Environment) {
if cart.armState == nil {
panic("cannot plumb this ELF instance because the ARM state is nil")
}
cart.arm.Plumb(cart.armState, cart.state.static, cart)
cart.arm.Plumb(cart.env, cart.armState, cart.state.static, cart)
cart.armState = nil
}
@ -181,7 +181,7 @@ func (cart *cdf) PlumbFromDifferentEmulation(env *environment.Environment) {
panic("cannot plumb this ELF instance because the ARM state is nil")
}
cart.arm = arm.NewARM(cart.env, cart.version.mmap, cart.state.static, cart)
cart.arm.Plumb(cart.armState, cart.state.static, cart)
cart.arm.Plumb(cart.env, cart.armState, cart.state.static, cart)
cart.armState = nil
cart.yieldHook = &coprocessor.StubCartYieldHook{}
}

View file

@ -155,7 +155,7 @@ func (cart *dpcPlus) Plumb(env *environment.Environment) {
if cart.armState == nil {
panic("cannot plumb this ELF instance because the ARM state is nil")
}
cart.arm.Plumb(cart.armState, cart.state.static, cart)
cart.arm.Plumb(cart.env, cart.armState, cart.state.static, cart)
cart.armState = nil
}
@ -166,7 +166,7 @@ func (cart *dpcPlus) PlumbFromDifferentEmulation(env *environment.Environment) {
panic("cannot plumb this ELF instance because the ARM state is nil")
}
cart.arm = arm.NewARM(cart.env, cart.version.mmap, cart.state.static, cart)
cart.arm.Plumb(cart.armState, cart.state.static, cart)
cart.arm.Plumb(cart.env, cart.armState, cart.state.static, cart)
cart.armState = nil
cart.yieldHook = &coprocessor.StubCartYieldHook{}
}

View file

@ -192,7 +192,7 @@ func (cart *Elf) PlumbFromDifferentEmulation(env *environment.Environment) {
panic("cannot plumb this ELF instance because the ARM state is nil")
}
cart.arm = arm.NewARM(cart.env, cart.mem.model, cart.mem, cart)
cart.arm.Plumb(cart.armState, cart.mem, cart)
cart.arm.Plumb(cart.env, cart.armState, cart.mem, cart)
cart.armState = nil
cart.mem.Plumb(cart.arm)
cart.yieldHook = &coprocessor.StubCartYieldHook{}
@ -205,7 +205,7 @@ func (cart *Elf) Plumb(env *environment.Environment) {
panic("cannot plumb this ELF instance because the ARM state is nil")
}
cart.mem.Plumb(cart.arm)
cart.arm.Plumb(cart.armState, cart.mem, cart)
cart.arm.Plumb(cart.env, cart.armState, cart.mem, cart)
cart.armState = nil
}