diff --git a/src/Emulator/Main/Core/Machine.cs b/src/Emulator/Main/Core/Machine.cs index 0978f68e4..601974479 100644 --- a/src/Emulator/Main/Core/Machine.cs +++ b/src/Emulator/Main/Core/Machine.cs @@ -1027,10 +1027,11 @@ public void PostCreationActions() } } - // Register io_executable flags for all ArrayMemory peripherals + // Register io_executable flags for all non-IMapped peripherals so that + // instruction fetches from them go through I/O callbacks instead of aborting. foreach(var context in SystemBus.GetAllContextKeys()) { - foreach(var registration in SystemBus.GetRegistrationsForPeripheralType(context)) + foreach(var registration in SystemBus.GetRegistrationsForPeripheralType(context).Where(r => !(r.Peripheral is IMapped))) { var range = registration.RegistrationPoint.Range; var perCore = registration.RegistrationPoint.Initiator; diff --git a/src/Emulator/Main/Peripherals/Bus/SystemBus.cs b/src/Emulator/Main/Peripherals/Bus/SystemBus.cs index 4f6cb174d..ad6a1eace 100644 --- a/src/Emulator/Main/Peripherals/Bus/SystemBus.cs +++ b/src/Emulator/Main/Peripherals/Bus/SystemBus.cs @@ -1260,7 +1260,7 @@ public void MoveRegistrationWithinContext(IBusPeripheral peripheral, BusRangeReg AddMappingsForPeripheral(peripheral, newRegistration, context); } - if(peripheral is ArrayMemory) + if(!(peripheral is IMapped)) { foreach(var cpu in GetCPUsForContext(context)) { @@ -2054,6 +2054,16 @@ private void RegisterInner(IBusPeripheral peripheral, PeripheralAccessMethods me }); // let's add new mappings AddMappingsForPeripheral(peripheral, registrationPoint, context); + // For non-IMapped peripherals, mark the range as executable I/O so that + // instruction fetches go through I/O callbacks instead of causing cpu_abort. + if(!(peripheral is IMapped)) + { + foreach(var cpu in GetCPUsForContext(context)) + { + var range = registrationPoint.Range; + cpu.RegisterAccessFlags(range.StartAddress, range.Size, isIoMemory: true); + } + } // After adding new mappings, if the address range is locked, the mappings possibly have to be modified/unmapped on the CPU's side // RelockRange to make this happen if(IsAddressRangeLocked(registrationPoint.Range, context))