From 41ee29d6502fe7c72d3185698118d8a9de688faf Mon Sep 17 00:00:00 2001 From: Sour Date: Tue, 26 Mar 2019 22:34:48 -0400 Subject: [PATCH] Debugger: Improved memory tools performance --- Core/IMemoryHandler.h | 1 + Core/MemoryDumper.cpp | 4 +- Core/MemoryManager.cpp | 9 ++ Core/MemoryManager.h | 2 + Core/RamHandler.h | 11 ++ Core/RegisterHandlerA.h | 6 + Core/RegisterHandlerB.cpp | 6 + Core/RegisterHandlerB.h | 1 + UI/Debugger/Controls/ctrlHexViewer.cs | 4 +- UI/Debugger/HexBox/StaticByteProvider.cs | 181 ++++++++++++++++++++++- UI/Forms/frmMain.cs | 2 + 11 files changed, 219 insertions(+), 8 deletions(-) diff --git a/Core/IMemoryHandler.h b/Core/IMemoryHandler.h index 9f44751..d2a3433 100644 --- a/Core/IMemoryHandler.h +++ b/Core/IMemoryHandler.h @@ -10,6 +10,7 @@ protected: public: virtual uint8_t Read(uint32_t addr) = 0; virtual uint8_t Peek(uint32_t addr) = 0; + virtual void PeekBlock(uint8_t *output) = 0; virtual void Write(uint32_t addr, uint8_t value) = 0; __forceinline SnesMemoryType GetMemoryType() diff --git a/Core/MemoryDumper.cpp b/Core/MemoryDumper.cpp index c26b597..f1fba5a 100644 --- a/Core/MemoryDumper.cpp +++ b/Core/MemoryDumper.cpp @@ -55,8 +55,8 @@ void MemoryDumper::GetMemoryState(SnesMemoryType type, uint8_t *buffer) { switch(type) { case SnesMemoryType::CpuMemory: - for(int i = 0; i <= 0xFFFFFF; i++) { - buffer[i] = _memoryManager->Peek(i); + for(int i = 0; i <= 0xFFFFFF; i+=0x1000) { + _memoryManager->PeekBlock(i, buffer+i); } break; diff --git a/Core/MemoryManager.cpp b/Core/MemoryManager.cpp index b9f642e..c923fbb 100644 --- a/Core/MemoryManager.cpp +++ b/Core/MemoryManager.cpp @@ -224,6 +224,15 @@ uint16_t MemoryManager::PeekWord(uint32_t addr) return (msb << 8) | lsb; } +void MemoryManager::PeekBlock(uint32_t addr, uint8_t *dest) +{ + if(_handlers[addr >> 12]) { + _handlers[addr >> 12]->PeekBlock(dest); + } else { + memset(dest, 0, 0x1000); + } +} + void MemoryManager::Write(uint32_t addr, uint8_t value, MemoryOperationType type) { IncrementMasterClock(addr); diff --git a/Core/MemoryManager.h b/Core/MemoryManager.h index ab2d7ef..e535a97 100644 --- a/Core/MemoryManager.h +++ b/Core/MemoryManager.h @@ -53,8 +53,10 @@ public: uint8_t Read(uint32_t addr, MemoryOperationType type); uint8_t ReadDma(uint32_t addr, bool forBusA); + uint8_t Peek(uint32_t addr); uint16_t PeekWord(uint32_t addr); + void PeekBlock(uint32_t addr, uint8_t * dest); void Write(uint32_t addr, uint8_t value, MemoryOperationType type); void WriteDma(uint32_t addr, uint8_t value, bool forBusA); diff --git a/Core/RamHandler.h b/Core/RamHandler.h index 8aaf05d..80b8957 100644 --- a/Core/RamHandler.h +++ b/Core/RamHandler.h @@ -34,6 +34,17 @@ public: return _ram[addr & _mask]; } + void PeekBlock(uint8_t *output) override + { + if(_mask != 0xFFF) { + for(int i = 0; i < 0x1000; i++) { + output[i] = _ram[i & _mask]; + } + } else { + memcpy(output, _ram, 0x1000); + } + } + void Write(uint32_t addr, uint8_t value) override { _ram[addr & _mask] = value; diff --git a/Core/RegisterHandlerA.h b/Core/RegisterHandlerA.h index 12505cf..2a56679 100644 --- a/Core/RegisterHandlerA.h +++ b/Core/RegisterHandlerA.h @@ -39,6 +39,12 @@ public: return 0; } + void PeekBlock(uint8_t *output) override + { + //Avoid side effects for now + memset(output, 0, 0x1000); + } + void Write(uint32_t addr, uint8_t value) override { addr &= 0xFFFF; diff --git a/Core/RegisterHandlerB.cpp b/Core/RegisterHandlerB.cpp index 8b88669..414fb6e 100644 --- a/Core/RegisterHandlerB.cpp +++ b/Core/RegisterHandlerB.cpp @@ -36,6 +36,12 @@ uint8_t RegisterHandlerB::Peek(uint32_t addr) return 0; } +void RegisterHandlerB::PeekBlock(uint8_t *output) +{ + //Avoid side effects for now + memset(output, 0, 0x1000); +} + void RegisterHandlerB::Write(uint32_t addr, uint8_t value) { addr &= 0xFFFF; diff --git a/Core/RegisterHandlerB.h b/Core/RegisterHandlerB.h index 88f138d..8c28e2a 100644 --- a/Core/RegisterHandlerB.h +++ b/Core/RegisterHandlerB.h @@ -22,6 +22,7 @@ public: uint8_t Read(uint32_t addr) override; uint8_t Peek(uint32_t addr) override; + void PeekBlock(uint8_t *output) override; void Write(uint32_t addr, uint8_t value) override; AddressInfo GetAbsoluteAddress(uint32_t address) override; diff --git a/UI/Debugger/Controls/ctrlHexViewer.cs b/UI/Debugger/Controls/ctrlHexViewer.cs index f720eb4..7d71206 100644 --- a/UI/Debugger/Controls/ctrlHexViewer.cs +++ b/UI/Debugger/Controls/ctrlHexViewer.cs @@ -60,9 +60,9 @@ namespace Mesen.GUI.Debugger.Controls if(data != null) { bool changed = true; - if(this._byteProvider != null && data.Length == this._byteProvider.Bytes.Count) { + if(this._byteProvider != null && data.Length == this._byteProvider.Length) { changed = false; - for(int i = 0; i < this._byteProvider.Bytes.Count; i++) { + for(int i = 0; i < this._byteProvider.Length; i++) { if(this._byteProvider.Bytes[i] != data[i]) { changed = true; break; diff --git a/UI/Debugger/HexBox/StaticByteProvider.cs b/UI/Debugger/HexBox/StaticByteProvider.cs index 3184304..2cd824e 100644 --- a/UI/Debugger/HexBox/StaticByteProvider.cs +++ b/UI/Debugger/HexBox/StaticByteProvider.cs @@ -6,20 +6,193 @@ using System.Threading.Tasks; namespace Be.Windows.Forms { - public class StaticByteProvider : DynamicByteProvider + public class StaticByteProvider : IByteProvider { - public StaticByteProvider(byte[] data) : base(data) + /// + /// Contains information about changes. + /// + bool _hasChanges; + /// + /// Contains a byte collection. + /// + byte[] _bytes; + + /// + /// Initializes a new instance of the DynamicByteProvider class. + /// + /// + public StaticByteProvider(byte[] data) + { + _bytes = data; + } + + public void SetData(byte[] data) + { + _bytes = data; + } + + /// + /// Raises the Changed event. + /// + void OnChanged(EventArgs e) + { + _hasChanges = true; + + if(Changed != null) + Changed(this, e); + } + + /// + /// Raises the LengthChanged event. + /// + void OnLengthChanged(EventArgs e) + { + if(LengthChanged != null) + LengthChanged(this, e); + } + + /// + /// Gets the byte collection. + /// + public byte[] Bytes + { + get { return _bytes; } + } + + #region IByteProvider Members + /// + /// True, when changes are done. + /// + public bool HasChanges() + { + return _hasChanges; + } + + /// + /// Applies changes. + /// + public void ApplyChanges() + { + _hasChanges = false; + } + + /// + /// Occurs, when the write buffer contains new changes. + /// + public event EventHandler Changed; + + /// + /// Occurs, when InsertBytes or DeleteBytes method is called. + /// + public event EventHandler LengthChanged; + + public delegate void ByteChangedHandler(int byteIndex, byte newValue, byte oldValue); + public event ByteChangedHandler ByteChanged; + + public delegate void BytesChangedHandler(int byteIndex, byte[] values); + public event BytesChangedHandler BytesChanged; + + /// + /// Reads a byte from the byte collection. + /// + /// the index of the byte to read + /// the byte + public byte ReadByte(long index) + { + if(_partialPos == index) { + return _partialValue; + } else { + return _bytes[(int)index]; + } + } + + /// + /// Write a byte into the byte collection. + /// + /// the index of the byte to write. + /// the byte + public void WriteByte(long index, byte value) + { + if(index == _partialPos) { + _partialPos = -1; + } + + if(_bytes[(int)index] != value) { + ByteChanged?.Invoke((int)index, value, _bytes[(int)index]); + _bytes[(int)index] = value; + OnChanged(EventArgs.Empty); + } + } + + public void WriteBytes(long index, byte[] values) + { + _partialPos = -1; + BytesChanged?.Invoke((int)index, values); + for(int i = 0; i < values.Length && index + i < _bytes.Length; i++) { + _bytes[(int)index + i] = values[i]; + } + } + + long _partialPos = -1; + byte _partialValue = 0; + public void PartialWriteByte(long index, byte value) + { + //Wait for a full byte to be written + _partialPos = index; + _partialValue = value; + } + + public void CommitWriteByte() + { + if(_partialPos >= 0) { + WriteByte(_partialPos, _partialValue); + _partialPos = -1; + } + } + + public void DeleteBytes(long index, long length) { } - public override bool SupportsInsertBytes() + public void InsertBytes(long index, byte[] bs) + { + } + + /// + /// Gets the length of the bytes in the byte collection. + /// + public long Length + { + get + { + return _bytes.Length; + } + } + + /// + /// Returns true + /// + public virtual bool SupportsWriteByte() + { + return true; + } + + /// + /// Returns true + /// + public virtual bool SupportsInsertBytes() { return false; } - public override bool SupportsDeleteBytes() + /// + /// Returns true + /// + public virtual bool SupportsDeleteBytes() { return false; } + #endregion + } } diff --git a/UI/Forms/frmMain.cs b/UI/Forms/frmMain.cs index 5a35d1d..0078d60 100644 --- a/UI/Forms/frmMain.cs +++ b/UI/Forms/frmMain.cs @@ -97,6 +97,8 @@ namespace Mesen.GUI.Forms ConfigManager.ApplyChanges(); DebugApi.ResumeExecution(); + DebugWindowManager.CloseAll(); + EmuApi.Stop(); EmuApi.Release(); }