annotate src/win32/MemoryViewerDlg.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
rev   line source
rlm@1 1 // MemoryViewerDlg.cpp : implementation file
rlm@1 2 //
rlm@1 3
rlm@1 4 #include "stdafx.h"
rlm@1 5 #include "resource.h"
rlm@1 6 #include "MemoryViewerDlg.h"
rlm@1 7 #include "FileDlg.h"
rlm@1 8 #include "MemoryViewerAddressSize.h"
rlm@1 9 #include "Reg.h"
rlm@1 10 #include "WinResUtil.h"
rlm@1 11 #include "VBA.h"
rlm@1 12
rlm@1 13 #include "../gba/GBAGlobals.h"
rlm@1 14
rlm@1 15 #define CPUReadByteQuick(addr) \
rlm@1 16 ::map[(addr)>>24].address[(addr) & ::map[(addr)>>24].mask]
rlm@1 17 #define CPUWriteByteQuick(addr, b) \
rlm@1 18 ::map[(addr)>>24].address[(addr) & ::map[(addr)>>24].mask] = (b)
rlm@1 19 #define CPUReadHalfWordQuick(addr) \
rlm@1 20 *((u16 *)&::map[(addr)>>24].address[(addr) & ::map[(addr)>>24].mask])
rlm@1 21 #define CPUWriteHalfWordQuick(addr, b) \
rlm@1 22 *((u16 *)&::map[(addr)>>24].address[(addr) & ::map[(addr)>>24].mask]) = (b)
rlm@1 23 #define CPUReadMemoryQuick(addr) \
rlm@1 24 *((u32 *)&::map[(addr)>>24].address[(addr) & ::map[(addr)>>24].mask])
rlm@1 25 #define CPUWriteMemoryQuick(addr, b) \
rlm@1 26 *((u32 *)&::map[(addr)>>24].address[(addr) & ::map[(addr)>>24].mask]) = (b)
rlm@1 27
rlm@1 28 /////////////////////////////////////////////////////////////////////////////
rlm@1 29 // GBAMemoryViewer control
rlm@1 30
rlm@1 31 GBAMemoryViewer::GBAMemoryViewer()
rlm@1 32 : MemoryViewer()
rlm@1 33 {
rlm@1 34 setAddressSize(0);
rlm@1 35 }
rlm@1 36
rlm@1 37 void GBAMemoryViewer::readData(u32 address, int len, u8 *data)
rlm@1 38 {
rlm@1 39 if (emulating && rom != NULL)
rlm@1 40 {
rlm@1 41 for (int i = 0; i < len; i++)
rlm@1 42 {
rlm@1 43 *data++ = CPUReadByteQuick(address);
rlm@1 44 address++;
rlm@1 45 }
rlm@1 46 }
rlm@1 47 else
rlm@1 48 {
rlm@1 49 for (int i = 0; i < len; i++)
rlm@1 50 {
rlm@1 51 *data++ = 0;
rlm@1 52 address++;
rlm@1 53 }
rlm@1 54 }
rlm@1 55 }
rlm@1 56
rlm@1 57 void GBAMemoryViewer::editData(u32 address, int size, int mask, u32 value)
rlm@1 58 {
rlm@1 59 u32 oldValue;
rlm@1 60
rlm@1 61 switch (size)
rlm@1 62 {
rlm@1 63 case 8:
rlm@1 64 oldValue = (CPUReadByteQuick(address) & mask) | value;
rlm@1 65 CPUWriteByteQuick(address, oldValue);
rlm@1 66 break;
rlm@1 67 case 16:
rlm@1 68 oldValue = (CPUReadHalfWordQuick(address) & mask) | value;
rlm@1 69 CPUWriteHalfWordQuick(address, oldValue);
rlm@1 70 break;
rlm@1 71 case 32:
rlm@1 72 oldValue = (CPUReadMemoryQuick(address) & mask) | value;
rlm@1 73 CPUWriteMemoryQuick(address, oldValue);
rlm@1 74 break;
rlm@1 75 }
rlm@1 76 }
rlm@1 77
rlm@1 78 /////////////////////////////////////////////////////////////////////////////
rlm@1 79 // MemoryViewerDlg dialog
rlm@1 80
rlm@1 81 MemoryViewerDlg::MemoryViewerDlg(CWnd*pParent /*=NULL*/)
rlm@1 82 : ResizeDlg(MemoryViewerDlg::IDD, pParent)
rlm@1 83 {
rlm@1 84 //{{AFX_DATA_INIT(MemoryViewerDlg)
rlm@1 85 m_size = -1;
rlm@1 86 //}}AFX_DATA_INIT
rlm@1 87 }
rlm@1 88
rlm@1 89 void MemoryViewerDlg::DoDataExchange(CDataExchange*pDX)
rlm@1 90 {
rlm@1 91 CDialog::DoDataExchange(pDX);
rlm@1 92 //{{AFX_DATA_MAP(MemoryViewerDlg)
rlm@1 93 DDX_Control(pDX, IDC_CURRENT_ADDRESS, m_current);
rlm@1 94 DDX_Control(pDX, IDC_ADDRESS, m_address);
rlm@1 95 DDX_Control(pDX, IDC_ADDRESSES, m_addresses);
rlm@1 96 DDX_Check(pDX, IDC_AUTO_UPDATE, autoUpdate);
rlm@1 97 DDX_Check(pDX, IDC_DECIMAL_DISPLAY, decimalDisplay);
rlm@1 98 DDX_Check(pDX, IDC_ALIGN, align);
rlm@1 99 DDX_Radio(pDX, IDC_8_BIT, m_size);
rlm@1 100 //}}AFX_DATA_MAP
rlm@1 101 DDX_Control(pDX, IDC_VIEWER, m_viewer);
rlm@1 102 }
rlm@1 103
rlm@1 104 BEGIN_MESSAGE_MAP(MemoryViewerDlg, CDialog)
rlm@1 105 //{{AFX_MSG_MAP(MemoryViewerDlg)
rlm@1 106 ON_BN_CLICKED(IDC_CLOSE, OnClose)
rlm@1 107 ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
rlm@1 108 ON_BN_CLICKED(IDC_8_BIT, On8Bit)
rlm@1 109 ON_BN_CLICKED(IDC_16_BIT, On16Bit)
rlm@1 110 ON_BN_CLICKED(IDC_32_BIT, On32Bit)
rlm@1 111 ON_BN_CLICKED(IDC_AUTO_UPDATE, OnAutoUpdate)
rlm@1 112 ON_BN_CLICKED(IDC_DECIMAL_DISPLAY, OnDecimalDisplay)
rlm@1 113 ON_BN_CLICKED(IDC_ALIGN, OnAlign)
rlm@1 114 ON_BN_CLICKED(IDC_GO, OnGo)
rlm@1 115 ON_CBN_SELCHANGE(IDC_ADDRESSES, OnSelchangeAddresses)
rlm@1 116 ON_BN_CLICKED(IDC_SAVE, OnSave)
rlm@1 117 ON_BN_CLICKED(IDC_LOAD, OnLoad)
rlm@1 118 //}}AFX_MSG_MAP
rlm@1 119 END_MESSAGE_MAP()
rlm@1 120
rlm@1 121 /////////////////////////////////////////////////////////////////////////////
rlm@1 122 // MemoryViewerDlg message handlers
rlm@1 123
rlm@1 124 BOOL MemoryViewerDlg::OnInitDialog()
rlm@1 125 {
rlm@1 126 CDialog::OnInitDialog();
rlm@1 127
rlm@1 128 DIALOG_SIZER_START(sz)
rlm@1 129 DIALOG_SIZER_ENTRY(IDC_VIEWER, DS_SizeX | DS_SizeY)
rlm@1 130 DIALOG_SIZER_ENTRY(IDC_REFRESH, DS_MoveY)
rlm@1 131 DIALOG_SIZER_ENTRY(IDC_CLOSE, DS_MoveY)
rlm@1 132 DIALOG_SIZER_ENTRY(IDC_LOAD, DS_MoveY)
rlm@1 133 DIALOG_SIZER_ENTRY(IDC_SAVE, DS_MoveY)
rlm@1 134 DIALOG_SIZER_ENTRY(IDC_AUTO_UPDATE, DS_MoveY)
rlm@1 135 DIALOG_SIZER_ENTRY(IDC_DECIMAL_DISPLAY, DS_MoveY)
rlm@1 136 DIALOG_SIZER_ENTRY(IDC_ALIGN, DS_MoveY)
rlm@1 137 DIALOG_SIZER_ENTRY(IDC_CURRENT_ADDRESS_LABEL, DS_MoveY | DS_MoveX)
rlm@1 138 DIALOG_SIZER_ENTRY(IDC_CURRENT_ADDRESS, DS_MoveY | DS_MoveX)
rlm@1 139 DIALOG_SIZER_END()
rlm@1 140 SetData(sz,
rlm@1 141 TRUE,
rlm@1 142 HKEY_CURRENT_USER,
rlm@1 143 "Software\\Emulators\\VisualBoyAdvance\\Viewer\\GBDisassembleView",
rlm@1 144 NULL);
rlm@1 145
rlm@1 146 autoUpdate = regQueryDwordValue("memViewerAutoUpdate", 1);
rlm@1 147 if (autoUpdate)
rlm@1 148 {
rlm@1 149 theApp.winAddUpdateListener(this);
rlm@1 150 }
rlm@1 151 else
rlm@1 152 {
rlm@1 153 theApp.winRemoveUpdateListener(this);
rlm@1 154 }
rlm@1 155
rlm@1 156 decimalDisplay = regQueryDwordValue("memViewerDecimalDisplay", 0);
rlm@1 157 m_viewer.setDecimal(decimalDisplay ? true : false);
rlm@1 158 align = regQueryDwordValue("memViewerAlign", 0);
rlm@1 159
rlm@1 160 m_viewer.setDialog(this);
rlm@1 161 m_viewer.ShowScrollBar(SB_VERT, TRUE);
rlm@1 162 m_viewer.EnableScrollBar(SB_VERT, ESB_ENABLE_BOTH);
rlm@1 163
rlm@1 164 LPCTSTR s[] = {
rlm@1 165 "0x00000000 - BIOS",
rlm@1 166 "0x02000000 - WRAM",
rlm@1 167 "0x03000000 - IRAM",
rlm@1 168 "0x04000000 - I/O",
rlm@1 169 "0x05000000 - PALETTE",
rlm@1 170 "0x06000000 - VRAM",
rlm@1 171 "0x07000000 - OAM",
rlm@1 172 "0x08000000 - ROM"
rlm@1 173 };
rlm@1 174
rlm@1 175 for (int i = 0; i < 8; i++)
rlm@1 176 m_addresses.AddString(s[i]);
rlm@1 177
rlm@1 178 m_addresses.SetCurSel(0);
rlm@1 179
rlm@1 180 RECT cbSize;
rlm@1 181 int Height;
rlm@1 182
rlm@1 183 m_addresses.GetClientRect(&cbSize);
rlm@1 184 Height = m_addresses.GetItemHeight(-1);
rlm@1 185 Height += m_addresses.GetItemHeight(0) * (9);
rlm@1 186
rlm@1 187 // Note: The use of SM_CYEDGE assumes that we're using Windows '95
rlm@1 188 // Now add on the height of the border of the edit box
rlm@1 189 Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges
rlm@1 190
rlm@1 191 // The height of the border of the drop-down box
rlm@1 192 Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges
rlm@1 193
rlm@1 194 // now set the size of the window
rlm@1 195 m_addresses.SetWindowPos(NULL,
rlm@1 196 0, 0,
rlm@1 197 cbSize.right, Height,
rlm@1 198 SWP_NOMOVE | SWP_NOZORDER);
rlm@1 199
rlm@1 200 m_address.LimitText(8);
rlm@1 201
rlm@1 202 m_size = regQueryDwordValue("memViewerDataSize", 1);
rlm@1 203 if (m_size < 0 || m_size > 2)
rlm@1 204 m_size = 0;
rlm@1 205 m_viewer.setSize(m_size);
rlm@1 206 UpdateData(FALSE);
rlm@1 207
rlm@1 208 m_current.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)));
rlm@1 209
rlm@1 210 return TRUE; // return TRUE unless you set the focus to a control
rlm@1 211 // EXCEPTION: OCX Property Pages should return FALSE
rlm@1 212 }
rlm@1 213
rlm@1 214 void MemoryViewerDlg::OnClose()
rlm@1 215 {
rlm@1 216 theApp.winRemoveUpdateListener(this);
rlm@1 217
rlm@1 218 DestroyWindow();
rlm@1 219 }
rlm@1 220
rlm@1 221 void MemoryViewerDlg::OnRefresh()
rlm@1 222 {
rlm@1 223 m_viewer.Invalidate();
rlm@1 224 }
rlm@1 225
rlm@1 226 void MemoryViewerDlg::update()
rlm@1 227 {
rlm@1 228 OnRefresh();
rlm@1 229 }
rlm@1 230
rlm@1 231 void MemoryViewerDlg::On8Bit()
rlm@1 232 {
rlm@1 233 m_viewer.setSize(0);
rlm@1 234 regSetDwordValue("memViewerDataSize", 0);
rlm@1 235 }
rlm@1 236
rlm@1 237 void MemoryViewerDlg::On16Bit()
rlm@1 238 {
rlm@1 239 m_viewer.setSize(1);
rlm@1 240 regSetDwordValue("memViewerDataSize", 1);
rlm@1 241 }
rlm@1 242
rlm@1 243 void MemoryViewerDlg::On32Bit()
rlm@1 244 {
rlm@1 245 m_viewer.setSize(2);
rlm@1 246 regSetDwordValue("memViewerDataSize", 2);
rlm@1 247 }
rlm@1 248
rlm@1 249 void MemoryViewerDlg::OnAutoUpdate()
rlm@1 250 {
rlm@1 251 autoUpdate = !autoUpdate;
rlm@1 252 if (autoUpdate)
rlm@1 253 {
rlm@1 254 theApp.winAddUpdateListener(this);
rlm@1 255 }
rlm@1 256 else
rlm@1 257 {
rlm@1 258 theApp.winRemoveUpdateListener(this);
rlm@1 259 }
rlm@1 260 regSetDwordValue("memViewerAutoUpdate", autoUpdate);
rlm@1 261 }
rlm@1 262
rlm@1 263 void MemoryViewerDlg::OnDecimalDisplay()
rlm@1 264 {
rlm@1 265 decimalDisplay = !decimalDisplay;
rlm@1 266 m_viewer.setDecimal(decimalDisplay ? true : false);
rlm@1 267 regSetDwordValue("memViewerDecimalDisplay", decimalDisplay);
rlm@1 268 }
rlm@1 269
rlm@1 270 void MemoryViewerDlg::OnAlign()
rlm@1 271 {
rlm@1 272 align = !align;
rlm@1 273 regSetDwordValue("memViewerAlign", align);
rlm@1 274 }
rlm@1 275
rlm@1 276 void MemoryViewerDlg::OnGo()
rlm@1 277 {
rlm@1 278 CString buffer;
rlm@1 279
rlm@1 280 m_address.GetWindowText(buffer);
rlm@1 281
rlm@1 282 u32 address;
rlm@1 283 sscanf(buffer, "%x", &address);
rlm@1 284 if (align)
rlm@1 285 address &= ~0xF;
rlm@1 286 else
rlm@1 287 {
rlm@1 288 if (m_viewer.getSize() == 1)
rlm@1 289 address &= ~1;
rlm@1 290 else if (m_viewer.getSize() == 2)
rlm@1 291 address &= ~3;
rlm@1 292 }
rlm@1 293 m_viewer.setAddress(address);
rlm@1 294 }
rlm@1 295
rlm@1 296 void MemoryViewerDlg::OnSelchangeAddresses()
rlm@1 297 {
rlm@1 298 int cur = m_addresses.GetCurSel();
rlm@1 299
rlm@1 300 switch (cur)
rlm@1 301 {
rlm@1 302 case 0:
rlm@1 303 m_viewer.setAddress(0);
rlm@1 304 break;
rlm@1 305 case 1:
rlm@1 306 m_viewer.setAddress(0x2000000);
rlm@1 307 break;
rlm@1 308 case 2:
rlm@1 309 m_viewer.setAddress(0x3000000);
rlm@1 310 break;
rlm@1 311 case 3:
rlm@1 312 m_viewer.setAddress(0x4000000);
rlm@1 313 break;
rlm@1 314 case 4:
rlm@1 315 m_viewer.setAddress(0x5000000);
rlm@1 316 break;
rlm@1 317 case 5:
rlm@1 318 m_viewer.setAddress(0x6000000);
rlm@1 319 break;
rlm@1 320 case 6:
rlm@1 321 m_viewer.setAddress(0x7000000);
rlm@1 322 break;
rlm@1 323 case 7:
rlm@1 324 m_viewer.setAddress(0x8000000);
rlm@1 325 break;
rlm@1 326 }
rlm@1 327 }
rlm@1 328
rlm@1 329 void MemoryViewerDlg::setCurrentAddress(u32 address)
rlm@1 330 {
rlm@1 331 CString buffer;
rlm@1 332
rlm@1 333 buffer.Format("0x%08X", address);
rlm@1 334 m_current.SetWindowText(buffer);
rlm@1 335 }
rlm@1 336
rlm@1 337 void MemoryViewerDlg::OnSave()
rlm@1 338 {
rlm@1 339 MemoryViewerAddressSize dlg;
rlm@1 340 CString buffer;
rlm@1 341
rlm@1 342 dlg.setAddress(m_viewer.getCurrentAddress());
rlm@1 343
rlm@1 344 LPCTSTR exts[] = { ".dmp", NULL };
rlm@1 345
rlm@1 346 if (dlg.DoModal() == IDOK)
rlm@1 347 {
rlm@1 348 CString filter = winResLoadFilter(IDS_FILTER_DUMP);
rlm@1 349 CString title = winResLoadString(IDS_SELECT_DUMP_FILE);
rlm@1 350
rlm@1 351 FileDlg file(this,
rlm@1 352 buffer,
rlm@1 353 filter,
rlm@1 354 0,
rlm@1 355 "DMP",
rlm@1 356 exts,
rlm@1 357 "",
rlm@1 358 title,
rlm@1 359 true);
rlm@1 360 if (file.DoModal() == IDOK)
rlm@1 361 {
rlm@1 362 buffer = file.GetPathName();
rlm@1 363
rlm@1 364 FILE *f = fopen(buffer, "wb");
rlm@1 365
rlm@1 366 if (f == NULL)
rlm@1 367 {
rlm@1 368 systemMessage(IDS_ERROR_CREATING_FILE, buffer);
rlm@1 369 return;
rlm@1 370 }
rlm@1 371
rlm@1 372 int size = dlg.getSize();
rlm@1 373 u32 addr = dlg.getAddress();
rlm@1 374
rlm@1 375 for (int i = 0; i < size; i++)
rlm@1 376 {
rlm@1 377 fputc(CPUReadByteQuick(addr), f);
rlm@1 378 addr++;
rlm@1 379 }
rlm@1 380
rlm@1 381 fclose(f);
rlm@1 382 }
rlm@1 383 }
rlm@1 384 }
rlm@1 385
rlm@1 386 void MemoryViewerDlg::OnLoad()
rlm@1 387 {
rlm@1 388 CString buffer;
rlm@1 389 LPCTSTR exts[] = { ".dmp", NULL };
rlm@1 390
rlm@1 391 CString filter = winResLoadFilter(IDS_FILTER_DUMP);
rlm@1 392 CString title = winResLoadString(IDS_SELECT_DUMP_FILE);
rlm@1 393
rlm@1 394 FileDlg file(this,
rlm@1 395 buffer,
rlm@1 396 filter,
rlm@1 397 0,
rlm@1 398 "DMP",
rlm@1 399 exts,
rlm@1 400 "",
rlm@1 401 title,
rlm@1 402 false);
rlm@1 403
rlm@1 404 if (file.DoModal() == IDOK)
rlm@1 405 {
rlm@1 406 buffer = file.GetPathName();
rlm@1 407 FILE *f = fopen(buffer, "rb");
rlm@1 408 if (f == NULL)
rlm@1 409 {
rlm@1 410 systemMessage(IDS_CANNOT_OPEN_FILE,
rlm@1 411 "Cannot open file %s",
rlm@1 412 buffer);
rlm@1 413 return;
rlm@1 414 }
rlm@1 415
rlm@1 416 MemoryViewerAddressSize dlg;
rlm@1 417
rlm@1 418 fseek(f, 0, SEEK_END);
rlm@1 419 int size = ftell(f);
rlm@1 420
rlm@1 421 fseek(f, 0, SEEK_SET);
rlm@1 422
rlm@1 423 dlg.setAddress(m_viewer.getCurrentAddress());
rlm@1 424 dlg.setSize(size);
rlm@1 425
rlm@1 426 if (dlg.DoModal() == IDOK)
rlm@1 427 {
rlm@1 428 int size = dlg.getSize();
rlm@1 429 u32 addr = dlg.getAddress();
rlm@1 430
rlm@1 431 for (int i = 0; i < size; i++)
rlm@1 432 {
rlm@1 433 int c = fgetc(f);
rlm@1 434 if (c == -1)
rlm@1 435 break;
rlm@1 436 CPUWriteByteQuick(addr, c);
rlm@1 437 addr++;
rlm@1 438 }
rlm@1 439 OnRefresh();
rlm@1 440 }
rlm@1 441 fclose(f);
rlm@1 442 }
rlm@1 443 }
rlm@1 444
rlm@1 445 void MemoryViewerDlg::PostNcDestroy()
rlm@1 446 {
rlm@1 447 delete this;
rlm@1 448 }
rlm@1 449