IMemoryMapping IMemoryBus.RegisterMappedDevice(IMemoryMappedDevice device, int startAddress, int endAddress) { MemoryMapping mapping = new MemoryMapping(device, startAddress, endAddress); this.mappings.Add(mapping); this.mappingsArray = this.mappings.ToArray(); return(mapping); }
void IMemoryBus.RemoveMapping(IMemoryMapping mapping) { MemoryMapping mappingToRemove = this.mappings.FirstOrDefault(m => m.Device == mapping.Device && m.StartAddress == mapping.StartAddress && m.EndAddress == mapping.EndAddress); if (mappingToRemove != null) { this.mappings.Remove(mappingToRemove); this.mappingsArray = this.mappings.ToArray(); } }
private IMemoryMappedDevice GetDeviceAtAddress(ref int address) { // This method is on a very hot path - use arrays instead of List<T>, indexed loops instead // of foreach or LINQ, and inline as much as possible. Improves perf by ~40%. MemoryMapping activeMapping = null; for (int i = 0; i < this.mappingsArray.Length; i++) { MemoryMapping mapping = this.mappingsArray[i]; if (mapping.StartAddress <= address && mapping.EndAddress >= address) { activeMapping = mapping; break; } } if (activeMapping == null) { // If we weren't able to find a mapping for the address, check to see if the address is in a mirrored range MemoryMirroring activeMirroring = null; for (int i = 0; i < this.mirroringsArray.Length; i++) { MemoryMirroring mirroring = this.mirroringsArray[i]; if (mirroring.MirrorStartAddress <= address && mirroring.MirrorEndAddress >= address) { activeMirroring = mirroring; break; } } if (activeMirroring != null) { // Calculate the base address and try to find a mapping again address = activeMirroring.SourceStartAddress + ((address - activeMirroring.MirrorStartAddress) % activeMirroring.SourceSize); for (int i = 0; i < this.mappingsArray.Length; i++) { MemoryMapping mapping = this.mappingsArray[i]; if (mapping.StartAddress <= address && mapping.EndAddress >= address) { activeMapping = mapping; break; } } } } return(activeMapping?.Device); }