home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / win32 / MemoryViewerDlg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-13  |  10.1 KB  |  425 lines

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