414 lines
11 KiB
C++
414 lines
11 KiB
C++
#include "Debugger UI.h"
|
|
|
|
CDebugMemoryView::CDebugMemoryView(CMipsMemory * MMU, CDebugger * debugger) :
|
|
CDebugDialog<CDebugMemoryView>(MMU,debugger),
|
|
m_MemoryList(NULL)
|
|
{
|
|
if (m_MemoryList== NULL)
|
|
{
|
|
m_MemoryList = new CListCtrl;
|
|
m_MemoryList->RegisterClass();
|
|
}
|
|
}
|
|
|
|
CDebugMemoryView::~CDebugMemoryView()
|
|
{
|
|
}
|
|
|
|
LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
|
{
|
|
m_DataStartLoc = -1;
|
|
m_CompareStartLoc = -1;
|
|
memset(m_CompareData,0,sizeof(m_CompareData));
|
|
memset(m_CompareValid,0,sizeof(m_CompareValid));
|
|
|
|
HWND hScrlBar = GetDlgItem(IDC_SCRL_BAR);
|
|
if (hScrlBar) {
|
|
SCROLLINFO si;
|
|
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
|
|
si.nMin = 0;
|
|
si.nMax = 0xFFFF;
|
|
si.nPos = 0x8000;
|
|
si.nPage = 100;
|
|
::SetScrollInfo(hScrlBar,SB_CTL,&si,TRUE);
|
|
}
|
|
|
|
m_MemAddr.Attach(GetDlgItem(IDC_ADDR_EDIT));
|
|
m_MemAddr.SetDisplayType(CEditNumber::DisplayHex);
|
|
m_MemAddr.SetValue(0x80000000,true,true);
|
|
|
|
SendDlgItemMessage( IDC_CHK_VADDR, BM_SETCHECK, BST_CHECKED,0);
|
|
|
|
if (m_MemoryList== NULL)
|
|
{
|
|
m_MemoryList = new CListCtrl;
|
|
m_MemoryList->RegisterClass();
|
|
}
|
|
m_MemoryList->SubclassWindow( GetDlgItem( IDC_MEM_DETAILS ) );
|
|
m_MemoryList->ShowHeader(false);
|
|
m_MemoryList->SetSortEnabled(FALSE);
|
|
m_MemoryList->AddColumn( _T( "Address" ), 90 );
|
|
m_MemoryList->AddColumn( _T( "1" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "2" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "3" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "4" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "-" ), 10 );
|
|
m_MemoryList->AddColumn( _T( "5" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "6" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "7" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "8" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "-" ), 10 );
|
|
m_MemoryList->AddColumn( _T( "9" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "10" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "11" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "12" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "-" ), 10 );
|
|
m_MemoryList->AddColumn( _T( "13" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "14" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "15" ), 20 );
|
|
m_MemoryList->AddColumn( _T( "16" ), 35 );
|
|
m_MemoryList->AddColumn( _T( "Memory Ascii" ), 140 );
|
|
::SetWindowLongPtr(m_MemoryList->m_hWnd, GWL_EXSTYLE, WS_EX_CLIENTEDGE);
|
|
RefreshMemory(false);
|
|
WindowCreated();
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT CDebugMemoryView::OnDestroy ( void )
|
|
{
|
|
if (m_MemoryList)
|
|
{
|
|
m_MemoryList->UnsubclassWindow();
|
|
delete m_MemoryList;
|
|
m_MemoryList = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CDebugMemoryView::OnClicked (WORD wNotifyCode, WORD wID, HWND , BOOL& bHandled)
|
|
{
|
|
switch(wID)
|
|
{
|
|
case IDC_REFRSH_MEM:
|
|
RefreshMemory(true);
|
|
break;
|
|
case IDC_CHK_VADDR:
|
|
RefreshMemory(false);
|
|
break;
|
|
case IDC_DUMP_MEM:
|
|
m_Debugger->Debug_ShowMemoryDump();
|
|
break;
|
|
case IDC_SEARCH_MEM:
|
|
m_Debugger->Debug_ShowMemorySearch();
|
|
break;
|
|
case IDCANCEL:
|
|
EndDialog(0);
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
LRESULT CDebugMemoryView::OnMemoryModified ( LPNMHDR lpNMHDR )
|
|
{
|
|
CListNotify *pListNotify = reinterpret_cast<CListNotify *>( lpNMHDR );
|
|
int LineNumber = pListNotify->m_nItem;
|
|
int Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 1));
|
|
if (pListNotify->m_nSubItem >= 6 && pListNotify->m_nSubItem < 10)
|
|
{
|
|
Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 2));
|
|
}
|
|
if (pListNotify->m_nSubItem >= 11 && pListNotify->m_nSubItem < 15)
|
|
{
|
|
Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 3));
|
|
}
|
|
if (pListNotify->m_nSubItem >= 16 && pListNotify->m_nSubItem < 20)
|
|
{
|
|
Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 4));
|
|
}
|
|
|
|
LPCSTR strValue = m_MemoryList->GetItemText(pListNotify->m_nItem,pListNotify->m_nSubItem);
|
|
int Finish = strlen(strValue);
|
|
if (Finish > 8) { Finish = 8; }
|
|
DWORD Value = 0;
|
|
for (int i = 0; i < Finish; i++)
|
|
{
|
|
Value = (Value << 4);
|
|
if (strValue[i] <= '9' && strValue[i] >= '0')
|
|
{
|
|
Value |= strValue[i] - '0';
|
|
}
|
|
else if (strValue[i] <= 'f' && strValue[i] >= 'a')
|
|
{
|
|
Value |= strValue[i] - 'a' + 10;
|
|
}
|
|
else if (strValue[i] <= 'F' && strValue[i] >= 'A')
|
|
{
|
|
Value |= strValue[i] - 'A' + 10;
|
|
}
|
|
}
|
|
|
|
if (m_CurrentData[Pos] == Value)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (m_CompareStartLoc != m_DataStartLoc ||
|
|
m_CompareVAddrr != m_DataVAddrr)
|
|
{
|
|
// copy current data for change comparison
|
|
m_CompareStartLoc = m_DataStartLoc;
|
|
m_CompareVAddrr = m_DataVAddrr;
|
|
memcpy(m_CompareData,m_CurrentData,sizeof(m_CurrentData));
|
|
memcpy(m_CompareValid,m_DataValid,sizeof(m_CompareValid));
|
|
}
|
|
|
|
m_CompareData[Pos] = m_CurrentData[Pos];
|
|
m_CurrentData[Pos] = Value;
|
|
|
|
//sb
|
|
if ( m_DataVAddrr )
|
|
{
|
|
if (!m_MMU->Store64(m_DataStartLoc+ Pos,Value,_8Bit))
|
|
{
|
|
WriteTraceF(TraceError,"CDebugMemoryView::OnMemoryModified - failed to store at %X",m_DataStartLoc + Pos);
|
|
}
|
|
} else {
|
|
if (!m_MMU->StorePhysical64(m_DataStartLoc+ Pos,Value,_8Bit))
|
|
{
|
|
WriteTraceF(TraceError,"CDebugMemoryView::OnMemoryModified - failed to store at %X",m_DataStartLoc + Pos);
|
|
}
|
|
}
|
|
Insert_MemoryLineDump(LineNumber);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CDebugMemoryView::ShowAddress(DWORD Address, bool VAddr)
|
|
{
|
|
if (m_hWnd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SendDlgItemMessage( IDC_CHK_VADDR, BM_SETCHECK, VAddr ? BST_CHECKED : BST_UNCHECKED,0);
|
|
m_MemAddr.SetValue(Address,true,true);
|
|
RefreshMemory (true);
|
|
}
|
|
|
|
void CDebugMemoryView::Insert_MemoryLineDump ( int LineNumber )
|
|
{
|
|
if (m_MemoryList == NULL || m_MemoryList->GetColumnCount() == 0)
|
|
{
|
|
return;
|
|
}
|
|
char Output[20], Hex[60], Ascii[20], AsciiAddOn[15];
|
|
sprintf(Output,"0x%08X",m_DataStartLoc + (LineNumber << 4));
|
|
if (m_MemoryList->GetItemCount() <= LineNumber)
|
|
{
|
|
HFONT hFont = (HFONT)GetStockObject(ANSI_FIXED_FONT);
|
|
m_MemoryList->AddItemAt( LineNumber, Output);
|
|
for (int i = 0; i < m_MemoryList->GetColumnCount(); i++)
|
|
{
|
|
m_MemoryList->SetItemFont( LineNumber, i, hFont );
|
|
if (i == 5 || i == 10 || i == 15)
|
|
{
|
|
m_MemoryList->SetItemText(LineNumber,i,"-");
|
|
}
|
|
}
|
|
} else {
|
|
if ( strcmp( Output, m_MemoryList->GetItemText(LineNumber, 0) ) != 0 )
|
|
{
|
|
m_MemoryList->SetItemText(LineNumber,0,Output);
|
|
}
|
|
}
|
|
|
|
Hex[0] = 0;
|
|
Ascii[0] = 0;
|
|
int CompareStartPos = m_DataStartLoc - m_CompareStartLoc;
|
|
|
|
for (int i = 0, col = 1; i < 0x10; i ++, col ++)
|
|
{
|
|
int Pos = ((LineNumber << 4) + i);
|
|
if (m_DataValid[Pos])
|
|
{
|
|
int ComparePos = CompareStartPos + Pos;
|
|
bool Changed = false;
|
|
|
|
if (ComparePos >= 0 && ComparePos < MemoryToDisplay &&
|
|
m_DataVAddrr == m_CompareVAddrr &&
|
|
m_DataValid[ComparePos] &&
|
|
m_CurrentData[Pos] != m_CompareData[ComparePos])
|
|
{
|
|
Changed = true;
|
|
}
|
|
sprintf(Hex,"%02X",m_CurrentData[Pos]);
|
|
m_MemoryList->SetItemText(LineNumber,col,Hex);
|
|
m_MemoryList->SetItemFormat( LineNumber,col, ITEM_FORMAT_EDIT, ITEM_FLAGS_EDIT_HEX );
|
|
m_MemoryList->SetItemMaxEditLen( LineNumber,col , 2);
|
|
m_MemoryList->SetItemColours( LineNumber, col, GetSysColor( COLOR_WINDOW ),
|
|
Changed ? RGB( 255, 0, 0 ) : GetSysColor( COLOR_WINDOWTEXT ) );
|
|
m_MemoryList->SetItemHighlightColours( LineNumber, col,
|
|
Changed ? RGB( 255, 0, 0 ) : GetSysColor( COLOR_HIGHLIGHTTEXT ) );
|
|
sprintf(AsciiAddOn,"%c",m_CurrentData[((LineNumber << 4) + i)]);
|
|
strcat(Ascii,AsciiAddOn);
|
|
} else {
|
|
m_MemoryList->SetItemText(LineNumber,col,"**");
|
|
m_MemoryList->SetItemFormat( LineNumber,col, ITEM_FORMAT_NONE, ITEM_FLAGS_NONE );
|
|
m_MemoryList->SetItemColours( LineNumber, col, GetSysColor( COLOR_WINDOW ), GetSysColor( COLOR_WINDOWTEXT ) );
|
|
strcat(Ascii,"*");
|
|
}
|
|
if (i != 0xF)
|
|
{
|
|
if ((i & 3) == 3)
|
|
{
|
|
col += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( strcmp( Ascii, m_MemoryList->GetItemText(LineNumber, 20) ) != 0 )
|
|
{
|
|
m_MemoryList->SetItemText(LineNumber,20,Ascii);
|
|
}
|
|
}
|
|
|
|
void CDebugMemoryView::OnAddrChanged( UINT Code, int id, HWND ctl )
|
|
{
|
|
RefreshMemory(false);
|
|
}
|
|
|
|
void CDebugMemoryView::OnVScroll(int request, short Pos, HWND ctrl )
|
|
{
|
|
if (ctrl != GetDlgItem(IDC_SCRL_BAR))
|
|
{
|
|
return;
|
|
}
|
|
DWORD Location = m_MemAddr.GetValue();
|
|
switch (request)
|
|
{
|
|
case SB_LINEDOWN:
|
|
m_MemAddr.SetValue(Location < 0xFFFFFFEF ? Location + 0x10 : 0xFFFFFFFF,true,true);
|
|
break;
|
|
case SB_LINEUP:
|
|
m_MemAddr.SetValue(Location > 0x10 ? Location - 0x10 : 0,true,true);
|
|
break;
|
|
case SB_PAGEDOWN:
|
|
m_MemAddr.SetValue(Location < 0xFFFFFEFF ? Location + 0x100 : 0xFFFFFFFF,true,true);
|
|
break;
|
|
case SB_PAGEUP:
|
|
m_MemAddr.SetValue(Location > 0x100 ? Location - 0x100 : 0,true,true);
|
|
break;
|
|
case SB_THUMBPOSITION:
|
|
m_MemAddr.SetValue((DWORD)Pos << 0x10,true,true);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CDebugMemoryView::RefreshMemory ( bool ResetCompare )
|
|
{
|
|
DWORD NewAddress = m_MemAddr.GetValue();
|
|
if (NewAddress != m_DataStartLoc)
|
|
{
|
|
HWND hScrlBar = GetDlgItem(IDC_SCRL_BAR);
|
|
if (hScrlBar)
|
|
{
|
|
SCROLLINFO si;
|
|
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_POS;
|
|
si.nPos = NewAddress >> 0x10;
|
|
::SetScrollInfo(hScrlBar,SB_CTL,&si,TRUE);
|
|
}
|
|
}
|
|
|
|
if (ResetCompare)
|
|
{
|
|
// copy current data for change comparison
|
|
m_CompareStartLoc = m_DataStartLoc;
|
|
m_CompareVAddrr = m_DataVAddrr;
|
|
memcpy(m_CompareData,m_CurrentData,sizeof(m_CurrentData));
|
|
memcpy(m_CompareValid,m_DataValid,sizeof(m_CompareValid));
|
|
}
|
|
|
|
m_DataStartLoc = m_MemAddr.GetValue();
|
|
if (m_DataStartLoc > 0xFFFFFF00) { m_DataStartLoc = 0xFFFFFF00; }
|
|
int WritePos = 0;
|
|
|
|
m_DataVAddrr = (SendDlgItemMessage( IDC_CHK_VADDR, BM_GETCHECK, 0,0) & BST_CHECKED) != 0;
|
|
|
|
if ((m_DataStartLoc & 3) != 0)
|
|
{
|
|
MIPS_WORD word;
|
|
bool ValidData = true;
|
|
|
|
if ( m_DataVAddrr )
|
|
{
|
|
if (!m_MMU->Load32(m_DataStartLoc & ~3, word.UW,_32Bit,false))
|
|
{
|
|
ValidData = false;
|
|
}
|
|
} else {
|
|
if (!m_MMU->LoadPhysical32(m_DataStartLoc & ~3, word.UW, _32Bit,false))
|
|
{
|
|
ValidData = false;
|
|
}
|
|
}
|
|
|
|
int Offset = (m_DataStartLoc & 3);
|
|
for (int i = 0; i < (4 - Offset); i++)
|
|
{
|
|
if (WritePos >= MemoryToDisplay)
|
|
{
|
|
break;
|
|
}
|
|
m_DataValid[WritePos + i] = ValidData;
|
|
if (ValidData)
|
|
{
|
|
m_CurrentData[WritePos + i] = word.UB[3 - (i + Offset)];
|
|
}
|
|
}
|
|
WritePos = 4 - Offset;
|
|
|
|
}
|
|
|
|
for (int Pos = ((m_DataStartLoc + 3) & ~3); Pos < (m_DataStartLoc + MemoryToDisplay); WritePos += 4, Pos += 4)
|
|
{
|
|
MIPS_WORD word;
|
|
bool ValidData = true;
|
|
|
|
if ( m_DataVAddrr )
|
|
{
|
|
if (!m_MMU->Load32(Pos, word.UW,_32Bit,false))
|
|
{
|
|
ValidData = false;
|
|
}
|
|
} else {
|
|
if (!m_MMU->LoadPhysical32(Pos, word.UW, _32Bit,false))
|
|
{
|
|
ValidData = false;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
if ((WritePos + i)>= MemoryToDisplay)
|
|
{
|
|
break;
|
|
}
|
|
m_DataValid[WritePos + i] = ValidData;
|
|
if (ValidData)
|
|
{
|
|
m_CurrentData[WritePos + i] = word.UB[3 - i];
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int count = 0 ; count < 16;count ++ ){
|
|
Insert_MemoryLineDump ( count );
|
|
}
|
|
}
|