[Debugger] Rewrite memory viewer

replace the list control with a custom hex editor control
add ability to select/copy/paste/delete multiple bytes
add byte group size option
make window resizable
fix DPI-related issues
speed up auto-refresh
remove option to disable auto-refresh (new control's cpu usage is insignificant)
move the dump and search buttons into the context menu
change colors of breakpoints to match the command window's
highlight CPU read and write targets while stepping
move address info into a status bar
allow window to open before MMU is initialized
add shortcut keys for various actions
add "follow pointer" feature
add "safe mode" feature
add copy gameshark code feature
add copy with row/group addresses feature
add tabs feature
add jump menu for hardware regions
fix cartridge ROM addresses not being viewable
allow writes to cartridge ROM
use thread-safe functions for reading/writing memory
This commit is contained in:
shygoo 2019-11-30 11:48:46 -06:00
parent 7254a80aed
commit 5c2aa06f7c
16 changed files with 3799 additions and 959 deletions

View File

@ -350,7 +350,6 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory)
AddHandler(Debugger_WriteBPExists, new CSettingTypeTempBool(false));
AddHandler(Debugger_ReadBPExists, new CSettingTypeTempBool(false));
AddHandler(Debugger_WaitingForStep, new CSettingTypeTempBool(false));
AddHandler(Debugger_AutoRefreshMemoryView, new CSettingTypeApplication("Debugger", "Auto Refresh Memory View", true));
AddHandler(Debugger_CPULoggingEnabled, new CSettingTypeApplication("Debugger", "Enable CPU Logging", false));
AddHandler(Debugger_CPULogBufferSize, new CSettingTypeApplication("Debugger", "CPU Log Buffer Size", (uint32_t)1024));
AddHandler(Debugger_ExceptionBreakpoints, new CSettingTypeApplication("Debugger", "Exception Breakpoints", (uint32_t)0));

View File

@ -260,7 +260,6 @@ enum SettingID
Debugger_WriteBPExists,
Debugger_ReadBPExists,
Debugger_WaitingForStep,
Debugger_AutoRefreshMemoryView,
Debugger_CPULoggingEnabled,
Debugger_CPULogBufferSize,
Debugger_ExceptionBreakpoints,

View File

@ -99,6 +99,7 @@
<ClCompile Include="UserInterface\Debugger\Debugger-TLB.cpp" />
<ClCompile Include="UserInterface\Debugger\Debugger-ViewMemory.cpp" />
<ClCompile Include="UserInterface\Debugger\Debugger.cpp" />
<ClCompile Include="UserInterface\Debugger\DebugMMU.cpp" />
<ClCompile Include="UserInterface\Debugger\DMALog.cpp" />
<ClCompile Include="UserInterface\Debugger\MemoryScanner.cpp" />
<ClCompile Include="UserInterface\Debugger\ScriptHook.cpp" />
@ -131,6 +132,7 @@
<ClCompile Include="UserInterface\SupportEnterCode.cpp" />
<ClCompile Include="UserInterface\SupportWindow.cpp" />
<ClCompile Include="UserInterface\WTLControls\EditNumber32.cpp" />
<ClCompile Include="UserInterface\WTLControls\HexEditCtrl.cpp" />
<ClCompile Include="UserInterface\WTLControls\ModifiedEditBox.cpp" />
<ClCompile Include="UserInterface\WTLControls\PartialGroupBox.cpp" />
</ItemGroup>
@ -166,6 +168,7 @@
<ClInclude Include="UserInterface\Debugger\Debugger-ViewMemory.h" />
<ClInclude Include="UserInterface\Debugger\debugger.h" />
<ClInclude Include="UserInterface\Debugger\DebuggerUI.h" />
<ClInclude Include="UserInterface\Debugger\DebugMMU.h" />
<ClInclude Include="UserInterface\Debugger\DMALog.h" />
<ClInclude Include="UserInterface\Debugger\MemoryScanner.h" />
<ClInclude Include="UserInterface\Debugger\OpInfo.h" />
@ -201,6 +204,7 @@
<ClInclude Include="UserInterface\SupportEnterCode.h" />
<ClInclude Include="UserInterface\SupportWindow.h" />
<ClInclude Include="UserInterface\WTLControls\EditNumber32.h" />
<ClInclude Include="UserInterface\WTLControls\HexEditCtrl.h" />
<ClInclude Include="UserInterface\WTLControls\ModifiedCheckBox.h" />
<ClInclude Include="UserInterface\WTLControls\ModifiedComboBox.h" />
<ClInclude Include="UserInterface\WTLControls\ModifiedEditBox.h" />

View File

@ -237,6 +237,12 @@
<ClCompile Include="UserInterface\Settings\SettingsPage-DiskDrive.cpp">
<Filter>Source Files\User Interface Source\Settings Source</Filter>
</ClCompile>
<ClCompile Include="UserInterface\WTLControls\HexEditCtrl.cpp">
<Filter>Source Files\User Interface Source\WTL Controls Source</Filter>
</ClCompile>
<ClCompile Include="UserInterface\Debugger\DebugMMU.cpp">
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="UserInterface\resource.h">
@ -455,6 +461,12 @@
<ClInclude Include="UserInterface\Settings\SettingsPage-DiskDrive.h">
<Filter>Header Files\User Interface Headers\Settings Header</Filter>
</ClInclude>
<ClInclude Include="UserInterface\WTLControls\HexEditCtrl.h">
<Filter>Header Files\User Interface Headers\WTL Controls Headers</Filter>
</ClInclude>
<ClInclude Include="UserInterface\Debugger\DebugMMU.h">
<Filter>Header Files\User Interface Headers\Debugger Headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="res\divider.cur">

View File

@ -0,0 +1,304 @@
#include <stdafx.h>
#include "DebugMMU.h"
#include <Common/MemoryManagement.h>
uint32_t* CDebugMMU::PAddrWordPtr(uint32_t paddr)
{
if (g_MMU == NULL)
{
return NULL;
}
paddr = paddr & ~3;
// RDRAM & DMEM/IMEM
if ((paddr < g_MMU->RdramSize()) ||
(paddr >= 0x04000000 && paddr <= 0x04001FFF))
{
return (uint32_t*)(g_MMU->Rdram() + paddr);
}
// 64DD buffer
if (paddr >= 0x05000000 && paddr <= 0x050004FF)
{
// todo
return NULL;
}
// Cartridge Domain 1 (Address 1) (64DD IPL ROM)
if (paddr >= 0x06000000 && paddr <= 0x06FFFFFF)
{
uint32_t iplRomOffset = paddr - 0x06000000;
if (g_DDRom != NULL && iplRomOffset < g_DDRom->GetRomSize())
{
return (uint32_t*)(g_MMU->Rdram() + paddr);
}
return NULL;
}
// Cartridge Domain 2 (Address 2) (SRAM/FlashRAM)
if (paddr >= 0x08000000 && paddr < 0x08FFFFFF)
{
// stored in a file
return NULL;
}
// Cartridge ROM
if (paddr >= 0x10000000 && paddr <= 0x15FFFFFF)
{
uint32_t cartRomOffset = paddr - 0x10000000;
if (g_Rom != NULL && cartRomOffset < g_Rom->GetRomSize())
{
return (uint32_t*)(g_Rom->GetRomAddress() + cartRomOffset);
}
return false;
}
// PIF ROM
if (paddr >= 0x1FC00000 && paddr <= 0x1FC007BF)
{
return NULL;
}
// PIF RAM
if (paddr >= 0x1FC007C0 && paddr <= 0x1FC007FF)
{
uint32_t pifRamOffset = paddr - 0x1FC007C0;
return (uint32_t*)(g_MMU->PifRam() + pifRamOffset);
}
switch (paddr)
{
case 0x03F00000: return &g_Reg->RDRAM_CONFIG_REG;
case 0x03F00004: return &g_Reg->RDRAM_DEVICE_ID_REG;
case 0x03F00008: return &g_Reg->RDRAM_DELAY_REG;
case 0x03F0000C: return &g_Reg->RDRAM_MODE_REG;
case 0x03F00010: return &g_Reg->RDRAM_REF_INTERVAL_REG;
case 0x03F00014: return &g_Reg->RDRAM_REF_ROW_REG;
case 0x03F00018: return &g_Reg->RDRAM_RAS_INTERVAL_REG;
case 0x03F0001C: return &g_Reg->RDRAM_MIN_INTERVAL_REG;
case 0x03F00020: return &g_Reg->RDRAM_ADDR_SELECT_REG;
case 0x03F00024: return &g_Reg->RDRAM_DEVICE_MANUF_REG;
case 0x04040010: return &g_Reg->SP_STATUS_REG;
case 0x04040014: return &g_Reg->SP_DMA_FULL_REG;
case 0x04040018: return &g_Reg->SP_DMA_BUSY_REG;
case 0x0404001C: return &g_Reg->SP_SEMAPHORE_REG;
case 0x04080000: return &g_Reg->SP_PC_REG;
case 0x0410000C: return &g_Reg->DPC_STATUS_REG;
case 0x04100010: return &g_Reg->DPC_CLOCK_REG;
case 0x04100014: return &g_Reg->DPC_BUFBUSY_REG;
case 0x04100018: return &g_Reg->DPC_PIPEBUSY_REG;
case 0x0410001C: return &g_Reg->DPC_TMEM_REG;
case 0x04300000: return &g_Reg->MI_MODE_REG;
case 0x04300004: return &g_Reg->MI_VERSION_REG;
case 0x04300008: return &g_Reg->MI_INTR_REG;
case 0x0430000C: return &g_Reg->MI_INTR_MASK_REG;
case 0x04400000: return &g_Reg->VI_STATUS_REG;
case 0x04400004: return &g_Reg->VI_ORIGIN_REG;
case 0x04400008: return &g_Reg->VI_WIDTH_REG;
case 0x0440000C: return &g_Reg->VI_INTR_REG;
case 0x04400010: return &g_Reg->VI_V_CURRENT_LINE_REG;
case 0x04400014: return &g_Reg->VI_BURST_REG;
case 0x04400018: return &g_Reg->VI_V_SYNC_REG;
case 0x0440001C: return &g_Reg->VI_H_SYNC_REG;
case 0x04400020: return &g_Reg->VI_LEAP_REG;
case 0x04400024: return &g_Reg->VI_H_START_REG;
case 0x04400028: return &g_Reg->VI_V_START_REG;
case 0x0440002C: return &g_Reg->VI_V_BURST_REG;
case 0x04400030: return &g_Reg->VI_X_SCALE_REG;
case 0x04400034: return &g_Reg->VI_Y_SCALE_REG;
case 0x04600000: return &g_Reg->PI_DRAM_ADDR_REG;
case 0x04600004: return &g_Reg->PI_CART_ADDR_REG;
case 0x04600008: return &g_Reg->PI_RD_LEN_REG;
case 0x0460000C: return &g_Reg->PI_WR_LEN_REG;
case 0x04600010: return &g_Reg->PI_STATUS_REG;
case 0x04600014: return &g_Reg->PI_DOMAIN1_REG;
case 0x04600018: return &g_Reg->PI_BSD_DOM1_PWD_REG;
case 0x0460001C: return &g_Reg->PI_BSD_DOM1_PGS_REG;
case 0x04600020: return &g_Reg->PI_BSD_DOM1_RLS_REG;
case 0x04600024: return &g_Reg->PI_DOMAIN2_REG;
case 0x04600028: return &g_Reg->PI_BSD_DOM2_PWD_REG;
case 0x0460002C: return &g_Reg->PI_BSD_DOM2_PGS_REG;
case 0x04600030: return &g_Reg->PI_BSD_DOM2_RLS_REG;
case 0x04700000: return &g_Reg->RI_MODE_REG;
case 0x04700004: return &g_Reg->RI_CONFIG_REG;
case 0x04700008: return &g_Reg->RI_CURRENT_LOAD_REG;
case 0x0470000C: return &g_Reg->RI_SELECT_REG;
case 0x04700010: return &g_Reg->RI_REFRESH_REG;
case 0x04700014: return &g_Reg->RI_LATENCY_REG;
case 0x04700018: return &g_Reg->RI_RERROR_REG;
case 0x0470001C: return &g_Reg->RI_WERROR_REG;
case 0x04800018: return &g_Reg->SI_STATUS_REG;
case 0x05000500: return &g_Reg->ASIC_DATA;
case 0x05000504: return &g_Reg->ASIC_MISC_REG;
case 0x05000508: return &g_Reg->ASIC_STATUS;
case 0x0500050C: return &g_Reg->ASIC_CUR_TK;
case 0x05000510: return &g_Reg->ASIC_BM_STATUS;
case 0x05000514: return &g_Reg->ASIC_ERR_SECTOR;
case 0x05000518: return &g_Reg->ASIC_SEQ_STATUS;
case 0x0500051C: return &g_Reg->ASIC_CUR_SECTOR;
case 0x05000520: return &g_Reg->ASIC_HARD_RESET;
case 0x05000524: return &g_Reg->ASIC_C1_S0;
case 0x05000528: return &g_Reg->ASIC_HOST_SECBYTE;
case 0x0500052C: return &g_Reg->ASIC_C1_S2;
case 0x05000530: return &g_Reg->ASIC_SEC_BYTE;
case 0x05000534: return &g_Reg->ASIC_C1_S4;
case 0x05000538: return &g_Reg->ASIC_C1_S6;
case 0x0500053C: return &g_Reg->ASIC_CUR_ADDR;
case 0x05000540: return &g_Reg->ASIC_ID_REG;
case 0x05000544: return &g_Reg->ASIC_TEST_REG;
case 0x05000548: return &g_Reg->ASIC_TEST_PIN_SEL;
}
return NULL;
}
bool CDebugMMU::DebugLW_PAddr(uint32_t paddr, uint32_t& value)
{
if (g_MMU == NULL)
{
return false;
}
uint32_t* ptr = PAddrWordPtr(paddr);
if (ptr != NULL)
{
value = *ptr;
return true;
}
if (paddr >= 0x08000000 && paddr < 0x08FFFFFF) // Cartridge Domain 2 (Address 2)
{
uint32_t saveOffset = paddr & 0x000FFFFF;
if (g_System->m_SaveUsing == SaveChip_Sram && saveOffset <= 0x7FFF) // sram
{
uint8_t tmp[4] = "";
CSram *sram = g_MMU->GetSram();
sram->DmaFromSram(tmp, paddr - 0x08000000, 4);
value = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0];
return true;
}
else if (g_System->m_SaveUsing == SaveChip_FlashRam && saveOffset == 0) // flash ram status
{
CFlashram* flashRam = g_MMU->GetFlashram();
value = flashRam->ReadFromFlashStatus(0x08000000);
return true;
}
}
if (paddr == 0x04500004)
{
if (g_System->bFixedAudio())
{
value = g_Audio->GetLength();
}
else
{
CAudioPlugin* audioPlg = g_Plugins->Audio();
value = (audioPlg->AiReadLength != NULL) ? audioPlg->AiReadLength() : 0;
}
return true;
}
if (paddr == 0x0450000C)
{
value = g_System->bFixedAudio() ? g_Audio->GetStatus() : g_Reg->AI_STATUS_REG;
return true;
}
return false;
}
bool CDebugMMU::DebugLW_VAddr(uint32_t vaddr, uint32_t& value)
{
if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB)
{
if (g_MMU == NULL)
{
return false;
}
return g_MMU->LW_VAddr(vaddr, value);
}
uint32_t paddr = vaddr & 0x1FFFFFFF;
return DebugLW_PAddr(paddr, value);
}
bool CDebugMMU::DebugLB_PAddr(uint32_t vaddr, uint8_t& value)
{
uint32_t word;
if (!DebugLW_PAddr(vaddr & ~3, word))
{
return false;
}
value = (word >> (24 - (vaddr & 3) * 8)) & 0xFF;
return true;
}
bool CDebugMMU::DebugLB_VAddr(uint32_t vaddr, uint8_t& value)
{
uint32_t word;
if (!DebugLW_VAddr(vaddr & ~3, word))
{
return false;
}
value = (word >> (24 - (vaddr & 3) * 8)) & 0xFF;
return true;
}
bool CDebugMMU::DebugSB_PAddr(uint32_t paddr, uint8_t value)
{
bool bWriteToRom = false;
if (paddr >= 0x10000000 && paddr <= 0x1FBFFFFF)
{
uint32_t romOffset = paddr - 0x10000000;
if (romOffset > g_Rom->GetRomSize())
{
return false;
}
bWriteToRom = true;
}
int nbyte = 3 - (paddr & 3);
uint8_t* ptr = (uint8_t*)PAddrWordPtr(paddr & ~3);
if (ptr == NULL)
{
return false;
}
if (bWriteToRom)
{
ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READWRITE);
}
ptr[nbyte] = value;
if (bWriteToRom)
{
ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READONLY);
}
return true;
}
bool CDebugMMU::DebugSB_VAddr(uint32_t vaddr, uint8_t value)
{
if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB)
{
if (g_MMU == NULL)
{
return false;
}
return g_MMU->SB_VAddr(vaddr, value);
}
uint32_t paddr = vaddr & 0x1FFFFFFF;
return DebugSB_PAddr(paddr, value);
}

View File

@ -0,0 +1,15 @@
#pragma once
#include <stdafx.h>
class CDebugMMU
{
private:
uint32_t* PAddrWordPtr(uint32_t paddr);
public:
bool DebugLW_PAddr(uint32_t paddr, uint32_t& value);
bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value);
bool DebugLB_PAddr(uint32_t paddr, uint8_t& value);
bool DebugLB_VAddr(uint32_t vaddr, uint8_t& value);
bool DebugSB_PAddr(uint32_t paddr, uint8_t value);
bool DebugSB_VAddr(uint32_t vaddr, uint8_t value);
};

File diff suppressed because it is too large Load Diff

View File

@ -11,9 +11,78 @@
#pragma once
#include "Debugger-AddSymbol.h"
#include <UserInterface/WTLControls/HexEditCtrl.h>
#include <Project64/UserInterface/WTLControls/TooltipDialog.h>
typedef struct
{
NMHDR nmh;
int nItem;
} NMMTRCLICK;
enum
{
MTCN_RCLICK
};
class CMemTabCtrl :
public CWindowImpl<CMemTabCtrl, CTabCtrl>
{
private:
int m_nItemRClick;
public:
CMemTabCtrl() :
m_nItemRClick(-1)
{
}
BOOL Attach(HWND hWndNew)
{
return SubclassWindow(hWndNew);
}
private:
void OnLButtonDblClk(UINT /*nFlags*/, CPoint /*point*/)
{
NMHDR nmh = { m_hWnd, (UINT_PTR)::GetDlgCtrlID(m_hWnd), NM_DBLCLK };
::SendMessage(::GetParent(m_hWnd), WM_NOTIFY, NM_DBLCLK, (LPARAM)&nmh);
}
void OnRButtonDown(UINT /*nFlags*/, CPoint point)
{
TCHITTESTINFO ht = { point, 0};
int nItem = ::SendMessage(m_hWnd, TCM_HITTEST, 0, (LPARAM)&ht);
if (nItem != -1)
{
m_nItemRClick = nItem;
}
}
void OnRButtonUp(UINT /*nFlags*/, CPoint point)
{
TCHITTESTINFO ht = { point, 0 };
int nItem = ::SendMessage(m_hWnd, TCM_HITTEST, 0, (LPARAM)&ht);
if (nItem != -1 && nItem == m_nItemRClick)
{
NMMTRCLICK nmrc = { { m_hWnd, (UINT_PTR)::GetDlgCtrlID(m_hWnd), MTCN_RCLICK }, nItem };
::SendMessage(::GetParent(m_hWnd), WM_NOTIFY, MTCN_RCLICK, (LPARAM)&nmrc);
}
m_nItemRClick = -1;
}
BEGIN_MSG_MAP_EX(CMemTabCtrl)
MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
MSG_WM_RBUTTONDOWN(OnRButtonDown)
MSG_WM_RBUTTONUP(OnRButtonUp)
MSG_WM_RBUTTONDBLCLK(OnRButtonDown)
END_MSG_MAP()
};
class CDebugMemoryView :
public CDebugDialog < CDebugMemoryView >
public CDebugDialog<CDebugMemoryView>,
public CDialogResize<CDebugMemoryView>,
public CToolTipDialog<CDebugMemoryView>
{
public:
enum { IDD = IDD_Debugger_Memory };
@ -21,74 +90,201 @@ public:
CDebugMemoryView(CDebuggerUI * debugger);
virtual ~CDebugMemoryView(void);
void ShowAddress(DWORD Address, bool VAddr);
void ShowAddress(uint32_t address, bool bVirtual);
private:
enum
{
WM_SHOWADDRESS = WM_USER + 1
};
enum
{
COLOR_DEFAULT = RGB(0, 0, 0),
COLOR_READONLY = RGB(0, 100, 0),
BKCOLOR_DEFAULT = RGB(255, 255, 255),
COLOR_CHANGED = RGB(255, 0, 0),
BKCOLOR_HOT = RGB(240, 240, 240),
BKCOLOR_LOCKED = RGB(100, 100, 0),
COLOR_BP = RGB(255, 255, 255),
BKCOLOR_RWBP = RGB(100, 0, 100),
BKCOLOR_RBP = RGB(0, 0, 100),
BKCOLOR_WBP = RGB(100, 0, 0),
BKCOLOR_CPUREAD = RGB(200, 200, 255),
BKCOLOR_CPUWRITE = RGB(255, 200, 200),
BKCOLOR_SYMBOL0 = RGB(208, 240, 208),
BKCOLOR_SYMBOL1 = RGB(176, 208, 176),
BKCOLOR_SAFEEDIT = RGB(255, 230, 255),
COLOR_SAFEEDIT = RGB(255, 0, 255)
};
enum
{
MEMSB_HOTADDR,
MEMSB_BLOCK,
MEMSB_BLOCKLEN,
MEMSB_DMAINFO,
MEMSB_SAFEMODE,
MEMSB_NUM_PANES
};
enum
{
MEMSB_HOTADDR_W = 160,
MEMSB_BLOCK_W = 120 + MEMSB_HOTADDR_W,
MEMSB_BLOCKLEN_W = 60 + MEMSB_BLOCK_W,
MEMSB_DMAINFO_W = 60 + MEMSB_BLOCKLEN_W,
MEMSB_SAFEMODE_W = -1
};
enum edit_type_t
{
SE_FILL,
//SE_DATA
};
typedef struct
{
edit_type_t type;
uint32_t startAddress;
uint32_t endAddress;
uint8_t value;
//uint8_t* data;
} edit_t;
typedef struct
{
uint32_t vaddr;
uint32_t paddr;
uint32_t size;
const char* caption;
} jump_item_t;
typedef struct
{
uint32_t address;
bool bVirtual;
int numBytesPerGroup;
} tab_info_t;
static jump_item_t JumpItems[];
static int GetJumpItemIndex(uint32_t address, bool bVirtual);
CHexEditCtrl m_HexEditCtrl;
CEditNumber32 m_MemAddr;
CAddSymbolDlg m_AddSymbolDlg;
CButton m_VirtualCheckbox;
CMemTabCtrl m_TabCtrl;
CStatusBarCtrl m_StatusBar;
CComboBox m_CmbJump;
std::vector<tab_info_t> m_TabData;
CBreakpoints* m_Breakpoints;
int m_WriteTargetColorStride;
int m_ReadTargetColorStride;
int m_SymbolColorStride;
int m_SymbolColorPhase;
uint32_t m_ContextMenuAddress;
uint32_t m_HotAddress;
bool m_bIgnoreAddressInput;
bool m_bVirtualMemory;
bool m_bSafeEditMode;
std::vector<edit_t> m_SafeEditQueue;
bool GetByte(uint32_t address, uint8_t* value);
bool SetByte(uint32_t address, uint8_t value);
void SetupJumpMenu(bool bVirtual);
bool GetSafeEditValue(uint32_t address, uint8_t* value);
void ApplySafeEdits(void);
void CopyTextToClipboard(const char* text);
void CopyBytesToClipboard(uint32_t startAddress, uint32_t endAddress, bool bHex, bool bIncludeAddresses = false, bool bRowAddresses = false);
void CopyGameSharkCodeToClipboard(uint32_t startAddress, uint32_t endAddress);
void FillRange(uint32_t startAddress, uint32_t endAddress, uint8_t value);
void FollowPointer(bool bContextMenuAddress = true);
void JumpToSelection(void);
int AddTab(uint32_t address, bool bVirtual, int numBytesPerGroup);
int InsertTab(int nItem, uint32_t address, bool bVirtual, int numBytesPerGroup);
void DeleteTab(int index);
void UpdateCurrentTab(uint32_t address);
void OpenNewTab(uint32_t address, bool bVirtual, int numBytesPerGroup, bool bInsert = false, bool bOpenExisting = false);
void OpenDuplicateTab(void);
void CloseTab(int nItem);
void CloseCurrentTab(void);
void TabSelChanged(void);
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnShowAddress(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
void OnAddrChanged(UINT Code, int id, HWND ctl);
void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar);
void OnExitSizeMove(void);
LRESULT OnDestroy(void);
LRESULT OnHxGetByteInfo(LPNMHDR lpNMHDR);
LRESULT OnHxSetNibble(LPNMHDR lpNMHDR);
LRESULT OnHxSetByte(LPNMHDR lpNMHDR);
LRESULT OnHxRightClick(LPNMHDR lpNMHDR);
LRESULT OnHxEnterPressed(LPNMHDR lpNMHDR);
LRESULT OnHxRedrawStarted(LPNMHDR lpNMHDR);
LRESULT OnHxBaseAddrChanged(LPNMHDR lpNMHDR);
LRESULT OnHxHotAddrChanged(LPNMHDR lpNMHDR);
LRESULT OnHxCopy(LPNMHDR lpNMHDR);
LRESULT OnHxPaste(LPNMHDR lpNMHDR);
LRESULT OnHxCtrlKeyPressed(LPNMHDR lpNMHDR);
LRESULT OnHxFillRange(LPNMHDR lpNMHDR);
LRESULT OnHxInsertModeChanged(LPNMHDR lpNMHDR);
LRESULT OnHxSelectionChanged(LPNMHDR lpNMHDR);
LRESULT OnHxGroupSizeChanged(LPNMHDR lpNMHDR);
LRESULT OnTabSelChange(LPNMHDR lpNMHDR);
LRESULT OnTabDblClick(LPNMHDR lpNMHDR);
LRESULT OnTabRClick(LPNMHDR lpNMHDR);
LRESULT OnStatusBarClick(LPNMHDR lpNMHDR);
void OnJumpComboSelChange(UINT uNotifyCode, int nID, CWindow wndCtl);
BEGIN_MSG_MAP_EX(CDebugMemoryView)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_SHOWADDRESS, OnShowAddress)
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
COMMAND_HANDLER_EX(IDC_ADDR_EDIT, EN_CHANGE, OnAddrChanged)
NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_MODIFIED, OnMemoryModified)
NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_RIGHTCLICK, OnMemoryRightClicked)
NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_HOTITEMCHANGED, OnHotItemChanged)
MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
MSG_WM_EXITSIZEMOVE(OnExitSizeMove)
MSG_WM_DESTROY(OnDestroy)
MSG_WM_VSCROLL(OnVScroll)
COMMAND_HANDLER_EX(IDC_CMB_JUMP, CBN_SELCHANGE, OnJumpComboSelChange)
NOTIFY_HANDLER_EX(IDC_STATUSBAR, NM_CLICK, OnStatusBarClick)
NOTIFY_HANDLER_EX(IDC_MEMTABS, NM_DBLCLK, OnTabDblClick)
NOTIFY_HANDLER_EX(IDC_MEMTABS, TCN_SELCHANGE, OnTabSelChange)
NOTIFY_HANDLER_EX(IDC_MEMTABS, MTCN_RCLICK, OnTabRClick)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_GETBYTEINFO, OnHxGetByteInfo)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_SETNIBBLE, OnHxSetNibble)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_SETBYTE, OnHxSetByte)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_RCLICK, OnHxRightClick)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_HOTADDRCHANGED, OnHxHotAddrChanged)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_REDRAWSTARTED, OnHxRedrawStarted)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_BASEADDRCHANGED, OnHxBaseAddrChanged)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_HOTADDRCHANGED, OnHxHotAddrChanged)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_PASTE, OnHxPaste)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_CTRLKEYPRESSED, OnHxCtrlKeyPressed)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_FILLRANGE, OnHxFillRange)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_COPY, OnHxCopy)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_INSERTMODECHANGED, OnHxInsertModeChanged)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_ENTERPRESSED, OnHxEnterPressed)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_SELCHANGED, OnHxSelectionChanged)
NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_GROUPSIZECHANGED, OnHxGroupSizeChanged)
CHAIN_MSG_MAP(CDialogResize<CDebugMemoryView>)
END_MSG_MAP()
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled);
void OnAddrChanged(UINT Code, int id, HWND ctl);
void OnVScroll(int request, short Pos, HWND ctrl);
void OnExitSizeMove(void);
LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnMemoryModified(LPNMHDR lpNMHDR);
LRESULT OnMemoryRightClicked(LPNMHDR lpNMHDR);
LRESULT OnHotItemChanged(LPNMHDR lpNMHDR);
LRESULT OnDestroy(void);
BEGIN_DLGRESIZE_MAP(CDebugMemoryView)
DLGRESIZE_CONTROL(IDC_CMB_JUMP, DLSZ_MOVE_X)
DLGRESIZE_CONTROL(IDC_STATUSBAR, DLSZ_SIZE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(IDC_HEXEDIT, DLSZ_SIZE_X | DLSZ_SIZE_Y)
DLGRESIZE_CONTROL(IDC_MEMTABS, DLSZ_SIZE_X)
DLGRESIZE_CONTROL(IDC_SCRL_BAR, DLSZ_MOVE_X | DLSZ_SIZE_Y)
END_DLGRESIZE_MAP()
void Insert_MemoryLineDump(int LineNumber);
void RefreshMemory(bool ResetCompare);
BEGIN_TOOLTIP_MAP()
TOOLTIP(IDC_SYMBOLS_BTN, "Symbols...")
TOOLTIP(IDC_CHK_VADDR, "Checked = Use virtual address space (CPU), Unchecked = Use physical address space (RCP)")
END_TOOLTIP_MAP()
};
HANDLE m_AutoRefreshThread;
static DWORD WINAPI AutoRefreshProc(void* _self);
void SelectColors(uint32_t address, bool changed, COLORREF& bgColor, COLORREF& fgColor, COLORREF& fgHiColor);
bool GetItemOffset(LPNMHDR lpNMHDR, uint32_t &offset);
bool GetItemAddress(LPNMHDR lpNMHDR, uint32_t &address);
void CopyNumber(uint32_t address, int numBytes);
enum { MemoryToDisplay = 0x100 };
static CDebugMemoryView* _this;
static HHOOK hWinMessageHook;
static LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);
void InterceptMouseWheel(WPARAM wParam, LPARAM lParam);
CEditNumber32 m_MemAddr;
CListCtrl * m_MemoryList;
CAddSymbolDlg m_AddSymbolDlg;
CStatic m_SymInfo;
CStatic m_DMAInfo;
bool m_bAutoRefreshEnabled;
CBreakpoints* m_Breakpoints;
int m_SymbolColorStride;
int m_SymbolColorPhase;
DWORD m_CtxMenuAddr;
DWORD m_DataStartLoc;
bool m_DataVAddrr;
BYTE m_CurrentData[MemoryToDisplay];
bool m_DataValid[MemoryToDisplay];
DWORD m_CompareStartLoc;
bool m_CompareVAddrr;
BYTE m_CompareData[MemoryToDisplay];
bool m_CompareValid[MemoryToDisplay];
};

View File

@ -233,10 +233,6 @@ void CDebuggerUI::OpenMemoryDump()
void CDebuggerUI::OpenMemoryWindow(void)
{
if (g_MMU == NULL)
{
return;
}
if (m_MemoryView == NULL)
{
m_MemoryView = new CDebugMemoryView(this);
@ -462,192 +458,6 @@ CCPULog* CDebuggerUI::CPULog()
return m_CPULog;
}
// thread safe LW_PAddr
// does not trigger application breakpoint if paddr is invalid
bool CDebuggerUI::DebugLW_PAddr(uint32_t paddr, uint32_t& value)
{
if (g_MMU == NULL)
{
return false;
}
if ((paddr < g_MMU->RdramSize()) || // RDRAM
(paddr >= 0x04000000 && paddr <= 0x04001FFF)) // DMEM/IMEM
{
value = *(uint32_t*)(g_MMU->Rdram() + paddr);
return true;
}
else if (paddr >= 0x05000000 && paddr <= 0x050004FF) // 64DD buffer
{
// todo
return false;
}
else if (paddr >= 0x06000000 && paddr <= 0x06FFFFFF) // Cartridge Domain 1 (Address 1) (64DD IPL ROM)
{
uint32_t iplRomOffset = paddr - 0x06000000;
if (g_DDRom != NULL && iplRomOffset < g_DDRom->GetRomSize())
{
value = *(uint32_t*)(g_MMU->Rdram() + paddr);
return true;
}
}
else if (paddr >= 0x08000000 && paddr < 0x08FFFFFF) // Cartridge Domain 2 (Address 2)
{
uint32_t saveOffset = paddr & 0x000FFFFF;
if (g_System->m_SaveUsing == SaveChip_Sram && saveOffset <= 0x7FFF) // sram
{
uint8_t tmp[4] = "";
CSram *sram = g_MMU->GetSram();
sram->DmaFromSram(tmp, paddr - 0x08000000, 4);
value = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0];
return true;
}
else if (g_System->m_SaveUsing == SaveChip_FlashRam && saveOffset == 0) // flash ram status
{
CFlashram* flashRam = g_MMU->GetFlashram();
value = flashRam->ReadFromFlashStatus(0x08000000);
return true;
}
}
else if (paddr >= 0x10000000 && paddr <= 0x15FFFFFF) // Cartridge ROM
{
uint32_t cartRomOffset = paddr - 0x10000000;
if (g_Rom != NULL && paddr < g_Rom->GetRomSize())
{
value = *(uint32_t*)(g_Rom->GetRomAddress() + cartRomOffset);
return true;
}
}
else if (paddr >= 0x1FC00000 && paddr <= 0x1FC007BF) // PIF ROM
{
return false;
}
else if (paddr >= 0x1FC007C0 && paddr <= 0x1FC007FF) // PIF RAM
{
uint32_t pifRamOffset = paddr - 0x1FC007C0;
value = *(uint32_t*)(g_MMU->PifRam() + pifRamOffset);
return true;
}
// note: write-only registers are excluded
switch (paddr)
{
case 0x03F00000: value = g_Reg->RDRAM_CONFIG_REG; return true;
case 0x03F00004: value = g_Reg->RDRAM_DEVICE_ID_REG; return true;
case 0x03F00008: value = g_Reg->RDRAM_DELAY_REG; return true;
case 0x03F0000C: value = g_Reg->RDRAM_MODE_REG; return true;
case 0x03F00010: value = g_Reg->RDRAM_REF_INTERVAL_REG; return true;
case 0x03F00014: value = g_Reg->RDRAM_REF_ROW_REG; return true;
case 0x03F00018: value = g_Reg->RDRAM_RAS_INTERVAL_REG; return true;
case 0x03F0001C: value = g_Reg->RDRAM_MIN_INTERVAL_REG; return true;
case 0x03F00020: value = g_Reg->RDRAM_ADDR_SELECT_REG; return true;
case 0x03F00024: value = g_Reg->RDRAM_DEVICE_MANUF_REG; return true;
case 0x04040010: value = g_Reg->SP_STATUS_REG; return true;
case 0x04040014: value = g_Reg->SP_DMA_FULL_REG; return true;
case 0x04040018: value = g_Reg->SP_DMA_BUSY_REG; return true;
case 0x0404001C: value = g_Reg->SP_SEMAPHORE_REG; return true;
case 0x04080000: value = g_Reg->SP_PC_REG; return true;
case 0x0410000C: value = g_Reg->DPC_STATUS_REG; return true;
case 0x04100010: value = g_Reg->DPC_CLOCK_REG; return true;
case 0x04100014: value = g_Reg->DPC_BUFBUSY_REG; return true;
case 0x04100018: value = g_Reg->DPC_PIPEBUSY_REG; return true;
case 0x0410001C: value = g_Reg->DPC_TMEM_REG; return true;
case 0x04300000: value = g_Reg->MI_MODE_REG; return true;
case 0x04300004: value = g_Reg->MI_VERSION_REG; return true;
case 0x04300008: value = g_Reg->MI_INTR_REG; return true;
case 0x0430000C: value = g_Reg->MI_INTR_MASK_REG; return true;
case 0x04400000: value = g_Reg->VI_STATUS_REG; return true;
case 0x04400004: value = g_Reg->VI_ORIGIN_REG; return true;
case 0x04400008: value = g_Reg->VI_WIDTH_REG; return true;
case 0x0440000C: value = g_Reg->VI_INTR_REG; return true;
case 0x04400010: value = g_Reg->VI_V_CURRENT_LINE_REG; return true;
case 0x04400014: value = g_Reg->VI_BURST_REG; return true;
case 0x04400018: value = g_Reg->VI_V_SYNC_REG; return true;
case 0x0440001C: value = g_Reg->VI_H_SYNC_REG; return true;
case 0x04400020: value = g_Reg->VI_LEAP_REG; return true;
case 0x04400024: value = g_Reg->VI_H_START_REG; return true;
case 0x04400028: value = g_Reg->VI_V_START_REG; return true;
case 0x0440002C: value = g_Reg->VI_V_BURST_REG; return true;
case 0x04400030: value = g_Reg->VI_X_SCALE_REG; return true;
case 0x04400034: value = g_Reg->VI_Y_SCALE_REG; return true;
case 0x04600000: value = g_Reg->PI_DRAM_ADDR_REG; return true;
case 0x04600004: value = g_Reg->PI_CART_ADDR_REG; return true;
case 0x04600008: value = g_Reg->PI_RD_LEN_REG; return true;
case 0x0460000C: value = g_Reg->PI_WR_LEN_REG; return true;
case 0x04600010: value = g_Reg->PI_STATUS_REG; return true;
case 0x04600014: value = g_Reg->PI_DOMAIN1_REG; return true;
case 0x04600018: value = g_Reg->PI_BSD_DOM1_PWD_REG; return true;
case 0x0460001C: value = g_Reg->PI_BSD_DOM1_PGS_REG; return true;
case 0x04600020: value = g_Reg->PI_BSD_DOM1_RLS_REG; return true;
case 0x04600024: value = g_Reg->PI_DOMAIN2_REG; return true;
case 0x04600028: value = g_Reg->PI_BSD_DOM2_PWD_REG; return true;
case 0x0460002C: value = g_Reg->PI_BSD_DOM2_PGS_REG; return true;
case 0x04600030: value = g_Reg->PI_BSD_DOM2_RLS_REG; return true;
case 0x04700000: value = g_Reg->RI_MODE_REG; return true;
case 0x04700004: value = g_Reg->RI_CONFIG_REG; return true;
case 0x04700008: value = g_Reg->RI_CURRENT_LOAD_REG; return true;
case 0x0470000C: value = g_Reg->RI_SELECT_REG; return true;
case 0x04700010: value = g_Reg->RI_REFRESH_REG; return true;
case 0x04700014: value = g_Reg->RI_LATENCY_REG; return true;
case 0x04700018: value = g_Reg->RI_RERROR_REG; return true;
case 0x0470001C: value = g_Reg->RI_WERROR_REG; return true;
case 0x04800018: value = g_Reg->SI_STATUS_REG; return true;
case 0x05000500: value = g_Reg->ASIC_DATA; return true;
case 0x05000504: value = g_Reg->ASIC_MISC_REG; return true;
case 0x05000508: value = g_Reg->ASIC_STATUS; return true;
case 0x0500050C: value = g_Reg->ASIC_CUR_TK; return true;
case 0x05000510: value = g_Reg->ASIC_BM_STATUS; return true;
case 0x05000514: value = g_Reg->ASIC_ERR_SECTOR; return true;
case 0x05000518: value = g_Reg->ASIC_SEQ_STATUS; return true;
case 0x0500051C: value = g_Reg->ASIC_CUR_SECTOR; return true;
case 0x05000520: value = g_Reg->ASIC_HARD_RESET; return true;
case 0x05000524: value = g_Reg->ASIC_C1_S0; return true;
case 0x05000528: value = g_Reg->ASIC_HOST_SECBYTE; return true;
case 0x0500052C: value = g_Reg->ASIC_C1_S2; return true;
case 0x05000530: value = g_Reg->ASIC_SEC_BYTE; return true;
case 0x05000534: value = g_Reg->ASIC_C1_S4; return true;
case 0x05000538: value = g_Reg->ASIC_C1_S6; return true;
case 0x0500053C: value = g_Reg->ASIC_CUR_ADDR; return true;
case 0x05000540: value = g_Reg->ASIC_ID_REG; return true;
case 0x05000544: value = g_Reg->ASIC_TEST_REG; return true;
case 0x05000548: value = g_Reg->ASIC_TEST_PIN_SEL; return true;
case 0x04500004:
if (g_System->bFixedAudio())
{
value = g_Audio->GetLength();
}
else
{
CAudioPlugin* audioPlg = g_Plugins->Audio();
value = (audioPlg->AiReadLength != NULL) ? audioPlg->AiReadLength() : 0;
}
return true;
case 0x0450000C:
value = g_System->bFixedAudio() ? g_Audio->GetStatus() : g_Reg->AI_STATUS_REG;
return true;
}
return false;
}
bool CDebuggerUI::DebugLW_VAddr(uint32_t vaddr, uint32_t& value)
{
if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB)
{
if (g_MMU == NULL)
{
return false;
}
return g_MMU->LW_VAddr(vaddr, value);
}
uint32_t paddr = vaddr & 0x1FFFFFFF;
return DebugLW_PAddr(paddr, value);
}
// CDebugger implementation
void CDebuggerUI::TLBChanged()

View File

@ -989,9 +989,9 @@ bool CMemoryScanner::NextScan()
int CMemoryScanner::HexDigitVal(char c)
{
if (c >= '0' && c < '9') return (c - '0');
if (c >= 'A' && c < 'F') return (c - 'A') + 0x0A;
if (c >= 'a' && c < 'f') return (c - 'a') + 0x0A;
if (c >= '0' && c <= '9') return (c - '0');
if (c >= 'A' && c <= 'F') return (c - 'A') + 0x0A;
if (c >= 'a' && c <= 'f') return (c - 'a') + 0x0A;
return 0;
}

View File

@ -12,6 +12,7 @@
#include <Project64-core/Debugger.h>
#include <Common/SyncEvent.h>
#include <Project64-core/Settings/DebugSettings.h>
#include "DebugMMU.h"
class CDumpMemory;
class CDebugMemoryView;
@ -33,7 +34,8 @@ class CScriptSystem;
class CDebuggerUI :
public CDebugger,
public CDebugSettings
public CDebugSettings,
public CDebugMMU
{
public:
CDebuggerUI();
@ -88,8 +90,8 @@ public:
static void GameNameChanged(CDebuggerUI * _this);
static void SteppingOpsChanged(CDebuggerUI * _this);
bool DebugLW_PAddr(uint32_t vaddr, uint32_t& value);
bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value);
//bool DebugLW_PAddr(uint32_t vaddr, uint32_t& value);
//bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value);
protected:
void TLBChanged(void);

View File

@ -1252,7 +1252,6 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugR4300Menu, L"&R4300i");
DebugMenu.push_back(Item);
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugMemoryMenu, L"Memory");
Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item);
DebugMenu.push_back(MENU_ITEM(SPLITER));
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugProfileMenu, L"Profile");

View File

@ -509,24 +509,19 @@ BEGIN
COMBOBOX IDC_LANG_SEL,105,77,112,120,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_Debugger_Memory DIALOGEX 0, 0, 435, 204
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
IDD_Debugger_Memory DIALOGEX 0, 0, 321, 199
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Memory"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
EDITTEXT IDC_ADDR_EDIT,35,5,49,12,ES_AUTOHSCROLL
LTEXT "Address:",IDC_STATIC,4,6,29,11
CONTROL "Is VAddr?",IDC_CHK_VADDR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,111,7,46,8
PUSHBUTTON "Dump",IDC_DUMP_MEM,319,4,54,13
PUSHBUTTON "Search",IDC_SEARCH_MEM,377,4,54,13
SCROLLBAR IDC_SCRL_BAR,421,23,11,154,SBS_VERT
PUSHBUTTON "Refresh",IDC_REFRSH_MEM,161,4,54,13
CONTROL "Mem Details",IDC_MEM_DETAILS,"ListCtrl",WS_TABSTOP,4,23,416,154
PUSHBUTTON "...",IDC_SYMBOLS_BTN,86,4,21,13
LTEXT "",IDC_SYM_INFO,8,198,418,8
LTEXT "",IDC_DMA_INFO,8,208,415,8
GROUPBOX "",IDC_STATIC,4,190,428,30
CONTROL "Auto",IDC_CHK_AUTOREFRESH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,220,7,31,8
EDITTEXT IDC_ADDR_EDIT,5,20,49,12,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_SYMBOLS_BTN,58,20,21,13
CONTROL "Virtual",IDC_CHK_VADDR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,83,20,40,13
CONTROL "HexEdit",IDC_HEXEDIT,"HexEditCtrl",WS_TABSTOP,0,36,310,147
SCROLLBAR IDC_SCRL_BAR,310,36,11,147,SBS_VERT
CONTROL "",IDC_MEMTABS,"SysTabControl32",TCS_FOCUSNEVER,0,3,319,13
COMBOBOX IDC_CMB_JUMP,194,20,123,12,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_STATUSBAR,"msctls_statusbar32",WS_TABSTOP,0,188,321,11
END
IDD_Debugger_Search DIALOGEX 0, 0, 357, 257
@ -1597,8 +1592,7 @@ BEGIN
IDD_Debugger_Memory, DIALOG
BEGIN
RIGHTMARGIN, 431
BOTTOMMARGIN, 203
BOTTOMMARGIN, 196
END
IDD_Debugger_Search, DIALOG
@ -1954,23 +1948,39 @@ IDR_MEM_BP_POPUP MENU
BEGIN
POPUP "PopupMenu"
BEGIN
MENUITEM "Toggle read breakpoint", ID_POPUPMENU_TOGGLERBP
MENUITEM "Toggle write breakpoint", ID_POPUPMENU_TOGGLEWBP
MENUITEM "Clear all breakpoints", ID_POPUPMENU_CLEARALLBPS
MENUITEM "Read breakpoint\tCtrl+R", ID_POPUPMENU_TOGGLERBP
MENUITEM "Write breakpoint\tCtrl+W", ID_POPUPMENU_TOGGLEWBP
MENUITEM "Lock value\tCtrl+E", ID_POPUPMENU_TOGGLELOCK
MENUITEM SEPARATOR
MENUITEM "Toggle lock", ID_POPUPMENU_TOGGLELOCK
MENUITEM "Clear locks", ID_POPUPMENU_CLEARLOCKS
MENUITEM "Clear breakpoints\tCtrl+Q", ID_POPUPMENU_CLEARALLBPS
MENUITEM "Clear locks\tCtrl+Q", ID_POPUPMENU_CLEARLOCKS
MENUITEM SEPARATOR
MENUITEM "View disassembly...", ID_POPUPMENU_VIEWDISASM
MENUITEM "Jump here\tCtrl+G", ID_POPUPMENU_JUMPHERE
MENUITEM "Follow pointer\tCtrl+Space", ID_POPUPMENU_FOLLOWPOINTER
MENUITEM SEPARATOR
POPUP "Byte group size"
BEGIN
MENUITEM "1\tCtrl+1", ID_POPUPMENU_BYTEGROUPSIZE_1
MENUITEM "2\tCtrl+2", ID_POPUPMENU_BYTEGROUPSIZE_2
MENUITEM "4\tCtrl+4", ID_POPUPMENU_BYTEGROUPSIZE_4
MENUITEM "8\tCtrl+8", ID_POPUPMENU_BYTEGROUPSIZE_8
END
MENUITEM "Safe mode\tINS", ID_POPUPMENU_SAFEMODE
MENUITEM SEPARATOR
MENUITEM "Add symbol...", ID_POPUPMENU_ADDSYMBOL
MENUITEM "View disassembly...", ID_POPUPMENU_VIEWDISASM
MENUITEM "Dump...\tCtrl+S", ID_POPUPMENU_DUMP
MENUITEM "Search...\tCtrl+F", ID_POPUPMENU_SEARCH
MENUITEM SEPARATOR
POPUP "Copy"
POPUP "Copy special"
BEGIN
MENUITEM "Word", ID_POPUPMENU_COPY_WORD
MENUITEM "Halfword", ID_POPUPMENU_COPY_HALFWORD
MENUITEM "Byte", ID_POPUPMENU_COPY_BYTE
MENUITEM "Data with group addresses", ID_POPUPMENU_COPYDATAWITHGROUPADDRESSES
MENUITEM "Data with row addresses", ID_POPUPMENU_COPYDATAWITHROWADDRESSES
MENUITEM "GameShark code", ID_POPUPMENU_COPYGAMESHARKCODE
END
MENUITEM "Copy\tCtrl+C", ID_POPUPMENU_COPY
MENUITEM "Paste\tCtrl+V", ID_POPUPMENU_PASTE
MENUITEM "Zero-fill\tDEL", ID_POPUPMENU_ZEROFILL
END
END

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,309 @@
#pragma once
#include <stdafx.h>
enum
{
HXN_REDRAWSTARTED,
HXN_GETBYTEINFO,
HXN_SETBYTE,
HXN_SETNIBBLE,
HXN_FILLRANGE,
HXN_RCLICK,
HXN_INSERTMODECHANGED,
HXN_HOTADDRCHANGED,
HXN_BASEADDRCHANGED,
HXN_GROUPSIZECHANGED,
HXN_SELCHANGED,
HXN_CTRLKEYPRESSED,
HXN_ENTERPRESSED,
HXN_COPY,
HXN_PASTE,
};
enum HXCOLUMN
{
HX_COL_NONE = -1,
HX_COL_ADDRESS,
HX_COL_HEXDATA,
HX_COL_ASCII
};
typedef struct HXBYTEINFO_S
{
bool bHidden;
bool bValid;
uint8_t value;
COLORREF color;
COLORREF bkColor;
bool operator==(const HXBYTEINFO_S& b) const
{
return memcmp(this, &b, sizeof(HXBYTEINFO_S)) == 0;
}
bool operator!=(const HXBYTEINFO_S& b) const
{
return memcmp(this, &b, sizeof(HXBYTEINFO_S)) != 0;
}
} HXBYTEINFO;
template<>
struct std::hash<HXBYTEINFO>
{
std::size_t operator()(const HXBYTEINFO& k) const
{
return (size_t)(k.bValid * 0xFFFFFFFF) ^ (k.value * 0x1010101) ^ k.color ^ k.bkColor;
}
};
typedef struct
{
NMHDR nmh;
uint32_t address;
size_t numBytes;
bool bIgnoreDiff;
HXBYTEINFO* oldBytes;
HXBYTEINFO* newBytes;
} NMHXGETBYTEINFO;
typedef struct
{
NMHDR nmh;
bool bInsert;
uint32_t address;
uint8_t value;
} NMHXSETBYTE;
typedef struct
{
NMHDR nmh;
bool bInsert;
uint32_t address;
bool bLoNibble;
uint8_t value;
} NMHXSETNIBBLE;
typedef struct
{
NMHDR nmh;
bool bInsert;
uint32_t startAddress;
uint32_t endAddress;
uint8_t value;
} NMHXFILLRANGE;
typedef struct
{
NMHDR nmh;
uint32_t address;
uint32_t length;
uint8_t* data;
} NMHXSETBYTES;
typedef struct
{
NMHDR nmh;
uint32_t address;
} NMHXRCLICK;
typedef struct
{
NMHDR nmh;
uint32_t address;
HXCOLUMN column;
} NMHXPASTE;
typedef struct
{
NMHDR nmh;
int nChar;
} NMHXCTRLKEYPRESSED;
class CHexEditCtrl :
public CWindowImpl<CHexEditCtrl>
{
public:
CHexEditCtrl(void);
~CHexEditCtrl(void);
DECLARE_WND_CLASS(_T("HexEditCtrl"))
BOOL Attach(HWND hWnd);
HWND Detach(void);
static char ByteAscii(uint8_t value);
static uint8_t HexCharValue(char c);
static int CALLBACK HaveFontCb(CONST LOGFONTA *lplf, CONST TEXTMETRICA *lptm, DWORD FontType, LPARAM lParam);
static bool HaveFont(HDC hdc, const char* name);
void Draw(void);
void Copy(void);
void Paste(bool bAdvanceCaret = true);
void SetBaseAddress(uint32_t address);
void SetByteGroupSize(int nBytes);
uint32_t GetBaseAddress(void);
uint32_t GetCaretAddress(void);
uint32_t GetHotAddress(void);
int GetNumBytesPerGroup(void);
int GetNumBytesPerRow(void);
int GetNumVisibleBytes(void);
bool GetSelectionRange(uint32_t* startAddress, uint32_t* endAddress);
HXCOLUMN GetFocusedColumn(void);
bool GetInsertMode(void);
private:
enum HXCELLSIDE
{
HX_LEFT,
HX_RIGHT
};
enum
{
TIMER_ID_AUTO_REFRESH,
TIMER_ID_DRAG_SCROLL
};
enum
{
BKCOLOR_DEFAULT = RGB(255, 255, 255),
BKCOLOR_ADDR = RGB(220, 220, 220),
COLOR_ADDR = RGB(40, 40, 40),
BKCOLOR_SEL_FOCUSED = RGB(51, 153, 255),
COLOR_SEL_FOCUSED = RGB(255, 255, 255),
BKCOLOR_SEL_UNFOCUSED = RGB(200, 200, 200),
COLOR_SEL_UNFOCUSED = RGB(0, 0, 0),
BKCOLOR_HOT = RGB(140, 140, 140)
};
typedef struct
{
HXCOLUMN column;
uint32_t asciiAddress;
HXCELLSIDE asciiCellSide;
uint32_t hexAddress;
HXCELLSIDE hexCellSide;
} HXHITTEST;
typedef struct
{
CRect rcHex;
CRect rcAscii;
} HXRECTPAIR;
uint32_t m_BaseAddress;
uint32_t m_DrawnBaseAddress;
uint32_t m_SelStartAddress;
HXCELLSIDE m_SelStartCellSide;
uint32_t m_SelEndAddress;
HXCELLSIDE m_SelEndCellSide;
uint32_t m_RealSelStartAddress;
uint32_t m_RealSelEndAddress;
bool m_bHaveRealSel;
bool m_bInsertMode;
bool m_bHaveCaret;
bool m_bCaretVisible;
uint32_t m_CaretAddress;
bool m_bCaretLoNibble;
bool m_bShowHotAddress;
uint32_t m_HotAddress;
HXCOLUMN m_FocusedColumn;
HFONT m_Font;
HBITMAP m_BackBMP;
HDC m_BackDC;
HCURSOR m_hCursorIBeam;
HCURSOR m_hCursorDefault;
int m_DragScrollDelta;
bool m_bDblClicked;
bool m_bLButtonDown;
bool m_bMouseDragging;
bool m_bLayoutChanged;
int m_CharWidth;
int m_CharHeight;
CRect m_AddressColumnRect;
CRect m_HexDataColumnRect;
CRect m_AsciiColumnRect;
int m_NumBytesPerGroup;
int m_NumByteGroupsPerRow;
int m_NumBytesPerRow;
int m_NumVisibleRows;
int m_NumVisibleBytes;
HXBYTEINFO* m_NewBytes;
HXBYTEINFO* m_OldBytes;
static COLORREF BlendColor(COLORREF c1, COLORREF c2);
static uint32_t SatAdd32(uint32_t a, uint32_t b);
static uint32_t SatAdd32(uint32_t a, int b);
void DrawAddressColumn(void);
void DrawHeader(void);
void Text(int x, int y, const char *text, COLORREF bg, COLORREF fg, CRect* rcOut);
bool IsSelected(uint32_t address);
int GetSelDirection(void);
void CancelSelection(void);
void SelectAllVisible(void);
void UpdateRealSelection(void);
uint32_t LineAddress(uint32_t address);
void GetHexCellPos(int index, CRect* rc);
void GetAsciiCellPos(int index, CRect* rc);
void HitTest(int x, int y, HXHITTEST* pht);
void ShowCaret(void);
void HideCaret(void);
void CaretIncrementNibble(void);
void CaretDecrementNibble(void);
bool UpdateCaretUI(bool bEnsureVisible, bool bTop = false);
void EnsureCaretAddressVisible(bool bTop = false);
bool IsCaretAddressVisible(void);
void UpdateLayoutInfo(void);
void ReallocByteBuffers(void);
LRESULT Notify(UINT code);
LRESULT NotifyGetByteInfo(uint32_t address, size_t numBytes, bool bIgnoreDiff, HXBYTEINFO* oldBytes, HXBYTEINFO* newBytes);
LRESULT NotifySetByte(uint32_t address, uint8_t value);
LRESULT NotifySetNibble(uint32_t address, bool bLoNibble, uint8_t value);
LRESULT NotifyFillRange(uint32_t startAddress, uint32_t endAddress, uint8_t value);
LRESULT NotifyCtrlKeyPressed(int nChar);
LRESULT NotifyPaste(uint32_t address);
LRESULT NotifyRightClick(uint32_t address);
void OnLButtonDown(UINT nFlags, CPoint point);
void OnLButtonDblClk(UINT nFlags, CPoint point);
void OnLButtonUp(UINT nFlags, CPoint point);
void OnRButtonDown(UINT nFlags, CPoint point);
void OnRButtonUp(UINT nFlags, CPoint point);
void OnMouseMove(UINT nFlags, CPoint point);
BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
void OnSetFocus(CWindow wndOld);
void OnKillFocus(CWindow wndFocus);
void OnTimer(UINT_PTR nIDEvent);
UINT OnGetDlgCode(LPMSG lpMsg);
void OnPaint(CDCHandle dc);
BOOL OnSetCursor(CWindow wnd, UINT nHitTest, UINT message);
void OnWindowPosChanged(LPWINDOWPOS lpWndPos);
BEGIN_MSG_MAP_EX(CHexEditCtrl)
MSG_WM_RBUTTONDOWN(OnRButtonDown)
MSG_WM_LBUTTONDOWN(OnLButtonDown)
MSG_WM_LBUTTONUP(OnLButtonUp)
MSG_WM_RBUTTONUP(OnRButtonUp)
MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
MSG_WM_MOUSEMOVE(OnMouseMove)
MSG_WM_MOUSEWHEEL(OnMouseWheel)
MSG_WM_KEYDOWN(OnKeyDown)
MSG_WM_CHAR(OnChar)
MSG_WM_SETFOCUS(OnSetFocus)
MSG_WM_KILLFOCUS(OnKillFocus)
MSG_WM_TIMER(OnTimer)
MSG_WM_GETDLGCODE(OnGetDlgCode)
MSG_WM_PAINT(OnPaint)
MSG_WM_SETCURSOR(OnSetCursor)
MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged)
END_MSG_MAP()
};

View File

@ -91,10 +91,8 @@
#define RSP_ABOUT 1006
#define IDC_ASSIGN 1006
#define IDC_BTN_CHOOSE_FILE 1006
#define IDC_DUMP_MEM 1006
#define IDC_INFO_FILENAME 1007
#define IDC_BTN_RDRAM 1007
#define IDC_REFRSH_MEM 1007
#define IDC_INFO_ROMNAME 1008
#define IDC_RESET_PAGE 1008
#define IDC_INFO_CARTID 1009
@ -194,7 +192,6 @@
#define IDC_DIRECT_READ 1057
#define IDC_DMA_READ 1058
#define IDC_CONT_PAK 1059
#define IDC_SEARCH_MEM 1059
#define IDC_BTN_ROM 1061
#define IDC_TEXTURE_OTHER 1062
#define IDC_TEXTURE_DIR 1063
@ -202,7 +199,6 @@
#define IDC_TEXTURE_DEFAULT 1064
#define IDC_LST_RESULTS 1064
#define IDC_SELECT_TEXTURE_DIR 1065
#define IDC_MEM_DETAILS 1065
#define IDC_PLUGIN_OTHER 1066
#define IDC_PLUGIN_DIR 1067
#define IDC_PLUGIN_DEFAULT 1068
@ -508,9 +504,7 @@
#define IDC_COP0_17_EDIT 1332
#define IDC_COP0_18_EDIT 1333
#define IDC_FILTER_STATIC 1339
#define IDC_SYM_INFO 1348
#define IDC_BLOCK_INFO 1350
#define IDC_DMA_INFO 1351
#define IDC_BACK_BTN 1352
#define IDC_FORWARD_BTN 1353
#define IDC_PC_EDIT 1354
@ -604,7 +598,6 @@
#define IDC_DD44_EDIT 1443
#define IDC_DD48_EDIT 1444
#define IDC_ROM_FIXEDAUDIO 1445
#define IDC_CHK_AUTOREFRESH 1446
#define IDC_SHOW_FILE_EXTENSIONS 1447
#define IDC_ENHANCEMENTLIST 1450
#define IDC_OVERCLOCK 1451
@ -718,6 +711,10 @@
#define IDC_CHK_FP_CO 1566
#define IDC_CHK_FP_CU 1567
#define IDC_CHK_FP_CI 1568
#define IDC_HEXEDIT 1569
#define IDC_MEMTABS 1571
#define IDC_STATUSBAR 1572
#define IDC_CMB_JUMP 1573
#define ID_POPUPMENU_PLAYGAMEWITHDISK 40008
#define ID_POPUPMENU_ADDSYMBOL 40013
#define ID_POPUPMENU_VIEWDISASM 40017
@ -757,9 +754,21 @@
#define ID_RESULTS_ADDALLTOWATCHLIST 40080
#define ID_WATCHLIST_CHANGE_ADDRESS 40082
#define ID_WATCHLIST_CHANGE_ADDRESSBY 40084
#define ID_POPUPMENU_COPY_WORD 40089
#define ID_POPUPMENU_COPY_HALFWORD 40090
#define ID_POPUPMENU_COPY_BYTE 40091
#define ID_POPUPMENU_PASTE 40092
#define ID_POPUPMENU_COPY 40093
#define ID_POPUPMENU_FOLLOWPOINTER 40095
#define ID_POPUPMENU_ZEROFILL 40097
#define ID_POPUPMENU_BYTEGROUPSIZE_1 40103
#define ID_POPUPMENU_BYTEGROUPSIZE_2 40104
#define ID_POPUPMENU_BYTEGROUPSIZE_4 40105
#define ID_POPUPMENU_BYTEGROUPSIZE_8 40106
#define ID_POPUPMENU_SAFEMODE 40107
#define ID_POPUPMENU_DUMP 40108
#define ID_POPUPMENU_SEARCH 40109
#define ID_POPUPMENU_JUMPHERE 40113
#define ID_POPUPMENU_COPYGAMESHARKCODE 40118
#define ID_POPUPMENU_COPYDATAWITHROWADDRESSES 40119
#define ID_POPUPMENU_COPYDATAWITHGROUPADDRESSES 40120
#define ID_POPUPMENU_ROMDIRECTORY 40137
#define ID_POPUPMENU_REFRESHROMLIST 40138
#define ID_POPUPMENU_PLAYGAME 40152
@ -777,8 +786,8 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 219
#define _APS_NEXT_COMMAND_VALUE 40092
#define _APS_NEXT_CONTROL_VALUE 1569
#define _APS_NEXT_COMMAND_VALUE 40121
#define _APS_NEXT_CONTROL_VALUE 1574
#define _APS_NEXT_SYMED_VALUE 102
#endif
#endif