void IMemoryBus.RemoveMirroring(IMemoryMirroring mirroring) { MemoryMirroring mirroringToRemove = this.mirroringsArray.FirstOrDefault(m => m.SourceStartAddress == mirroring.SourceStartAddress && m.SourceSize == mirroring.SourceSize && m.MirrorStartAddress == mirroring.MirrorStartAddress && m.MirrorEndAddress == mirroring.MirrorEndAddress); if (mirroringToRemove != null) { this.mirrorings.Remove(mirroringToRemove); this.mirroringsArray = this.mirrorings.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); }
IMemoryMirroring IMemoryBus.SetMirroringRange(int sourceStartAddress, int sourceEndAddress, int mirrorStartAddress, int mirrorEndAddress) { int sourceSize = (sourceEndAddress - sourceStartAddress) + 1; int mirrorSize = (mirrorEndAddress - mirrorStartAddress) + 1; if (mirrorSize % sourceSize != 0) { throw new InvalidOperationException("Size of mirrored range must be a multiple of size of source range!"); } MemoryMirroring mirroring = new MemoryMirroring(sourceStartAddress, sourceSize, mirrorStartAddress, mirrorEndAddress); this.mirrorings.Add(mirroring); this.mirroringsArray = this.mirrorings.ToArray(); return(mirroring); }