view src/win32/MemoryViewerDlg.cpp @ 6:458a4f18f3cd

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