home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / win32 / Disassemble.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-13  |  7.3 KB  |  350 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. // Disassemble.cpp : implementation file
  20. //
  21.  
  22. #include "stdafx.h"
  23. #include "vba.h"
  24. #include "Disassemble.h"
  25.  
  26. #include "../System.h"
  27. #include "../armdis.h"
  28. #include "../GBA.h"
  29. #include "../Globals.h"
  30.  
  31. #ifdef _DEBUG
  32. #define new DEBUG_NEW
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36.  
  37. extern int emulating;
  38.  
  39. extern void CPUUpdateCPSR();
  40.  
  41.  
  42. /////////////////////////////////////////////////////////////////////////////
  43. // Disassemble dialog
  44.  
  45.  
  46. Disassemble::Disassemble(CWnd* pParent /*=NULL*/)
  47.   : ResizeDlg(Disassemble::IDD, pParent)
  48. {
  49.   //{{AFX_DATA_INIT(Disassemble)
  50.   m_c = FALSE;
  51.   m_f = FALSE;
  52.   m_i = FALSE;
  53.   m_n = FALSE;
  54.   m_t = FALSE;
  55.   m_v = FALSE;
  56.   m_z = FALSE;
  57.   mode = -1;
  58.   //}}AFX_DATA_INIT
  59.   mode = 0;
  60.   address = 0;
  61.   autoUpdate = false;
  62.   count = 1;
  63. }
  64.  
  65.  
  66. void Disassemble::DoDataExchange(CDataExchange* pDX)
  67. {
  68.   CDialog::DoDataExchange(pDX);
  69.   //{{AFX_DATA_MAP(Disassemble)
  70.   DDX_Control(pDX, IDC_ADDRESS, m_address);
  71.   DDX_Control(pDX, IDC_DISASSEMBLE, m_list);
  72.   DDX_Check(pDX, IDC_C, m_c);
  73.   DDX_Check(pDX, IDC_F, m_f);
  74.   DDX_Check(pDX, IDC_I, m_i);
  75.   DDX_Check(pDX, IDC_N, m_n);
  76.   DDX_Check(pDX, IDC_T, m_t);
  77.   DDX_Check(pDX, IDC_V, m_v);
  78.   DDX_Check(pDX, IDC_Z, m_z);
  79.   DDX_Radio(pDX, IDC_AUTOMATIC, mode);
  80.   //}}AFX_DATA_MAP
  81. }
  82.  
  83.  
  84. BEGIN_MESSAGE_MAP(Disassemble, CDialog)
  85.   //{{AFX_MSG_MAP(Disassemble)
  86.   ON_BN_CLICKED(IDC_AUTO_UPDATE, OnAutoUpdate)
  87.   ON_BN_CLICKED(IDC_AUTOMATIC, OnAutomatic)
  88.   ON_BN_CLICKED(IDC_ARM, OnArm)
  89.   ON_BN_CLICKED(IDC_CLOSE, OnClose)
  90.   ON_BN_CLICKED(IDC_GO, OnGo)
  91.   ON_BN_CLICKED(IDC_GOPC, OnGopc)
  92.   ON_BN_CLICKED(IDC_NEXT, OnNext)
  93.   ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
  94.   ON_BN_CLICKED(IDC_THUMB, OnThumb)
  95.   ON_WM_VSCROLL()
  96.   //}}AFX_MSG_MAP
  97.   END_MESSAGE_MAP()
  98.  
  99.   /////////////////////////////////////////////////////////////////////////////
  100. // Disassemble message handlers
  101.  
  102. void Disassemble::OnAutoUpdate() 
  103. {
  104.   autoUpdate = !autoUpdate;
  105.   if(autoUpdate) {
  106.     theApp.winAddUpdateListener(this);
  107.   } else {
  108.     theApp.winRemoveUpdateListener(this);    
  109.   }  
  110. }
  111.  
  112. void Disassemble::OnAutomatic() 
  113. {
  114.   mode = 0;
  115.   refresh();
  116. }
  117.  
  118. void Disassemble::OnArm() 
  119. {
  120.   mode = 1;
  121.   refresh();
  122. }
  123.  
  124. void Disassemble::OnClose() 
  125. {
  126.   theApp.winRemoveUpdateListener(this);
  127.   
  128.   DestroyWindow();
  129. }
  130.  
  131. void Disassemble::OnGo() 
  132. {
  133.   CString buffer;
  134.   m_address.GetWindowText(buffer);
  135.   sscanf(buffer, "%x", &address);
  136.   refresh();
  137. }
  138.  
  139. void Disassemble::OnGopc() 
  140. {
  141.   if(armState)
  142.     address = armNextPC - 16;
  143.   else
  144.     address = armNextPC - 8;
  145.  
  146.   refresh();
  147. }
  148.  
  149. void Disassemble::OnNext() 
  150. {
  151.   CPULoop(1);
  152.   if(armState) {
  153.     u32 total = address+count*4;
  154.     if(armNextPC >= address && armNextPC < total) {
  155.     } else {
  156.       OnGopc();
  157.     }
  158.   } else {
  159.     u32 total = address+count*2;
  160.     if(armNextPC >= address && armNextPC < total) {
  161.     } else {
  162.       OnGopc();
  163.     }
  164.   }
  165.   refresh();
  166. }
  167.  
  168. void Disassemble::OnRefresh() 
  169. {
  170.   refresh();
  171. }
  172.  
  173. void Disassemble::OnThumb() 
  174. {
  175.   mode = 2;
  176.   refresh();
  177. }
  178.  
  179. BOOL Disassemble::OnInitDialog() 
  180. {
  181.   CDialog::OnInitDialog();
  182.   
  183.   DIALOG_SIZER_START( sz )
  184.     DIALOG_SIZER_ENTRY( IDC_DISASSEMBLE, DS_SizeY)
  185.     DIALOG_SIZER_ENTRY( IDC_REFRESH, DS_MoveY)
  186.     DIALOG_SIZER_ENTRY( IDC_CLOSE, DS_MoveY)
  187.     DIALOG_SIZER_ENTRY( IDC_NEXT,  DS_MoveY)
  188.     DIALOG_SIZER_ENTRY( IDC_AUTO_UPDATE, DS_MoveY)
  189.     DIALOG_SIZER_ENTRY( IDC_GOPC, DS_MoveY)
  190.     DIALOG_SIZER_ENTRY( IDC_VSCROLL, DS_SizeY)
  191.     DIALOG_SIZER_END()
  192.     SetData(sz,
  193.             TRUE,
  194.             HKEY_CURRENT_USER,
  195.             "Software\\Emulators\\VisualBoyAdvance\\Viewer\\DisassembleView",
  196.             NULL);
  197.  
  198.   SCROLLINFO si;
  199.   ZeroMemory(&si, sizeof(si));
  200.   si.cbSize = sizeof(si);
  201.   si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
  202.   si.nMin = 0;
  203.   si.nMax = 100;
  204.   si.nPos = 50;
  205.   si.nPage = 0;
  206.   GetDlgItem(IDC_VSCROLL)->SetScrollInfo(SB_CTL, &si, TRUE);
  207.   
  208.   CFont *font = CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT));
  209.   
  210.   m_list.SetFont(font, FALSE);
  211.   for(int i = 0; i < 17; i++)
  212.     GetDlgItem(IDC_R0+i)->SetFont(font, FALSE);
  213.  
  214.   GetDlgItem(IDC_MODE)->SetFont(font, FALSE);
  215.   
  216.  
  217.   m_address.LimitText(8);
  218.   refresh();
  219.   
  220.   return TRUE;  // return TRUE unless you set the focus to a control
  221.                 // EXCEPTION: OCX Property Pages should return FALSE
  222. }
  223.  
  224. void Disassemble::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
  225. {
  226.   switch(nSBCode) {
  227.   case SB_LINEDOWN:
  228.     if(mode == 0) {
  229.       if(armState)
  230.         address += 4;
  231.       else
  232.         address += 2;
  233.     } else if(mode == 1)
  234.       address += 4;
  235.     else
  236.       address += 2;
  237.     break;
  238.   case SB_LINEUP:
  239.     if(mode == 0) {
  240.       if(armState)
  241.         address -= 4;
  242.       else
  243.         address -= 2;
  244.     } else if(mode == 1)
  245.       address -= 4;
  246.     else
  247.       address -= 2;
  248.     break;
  249.   case SB_PAGEDOWN:
  250.     if(mode == 0) {
  251.       if(armState)
  252.         address += count*4;
  253.       else
  254.         address += count*2;
  255.     } else if(mode == 1)
  256.       address += count*4;
  257.     else
  258.       address += count*2;
  259.     break;
  260.   case SB_PAGEUP:
  261.     if(mode == 0) {
  262.       if(armState)
  263.         address -= count*4;
  264.       else
  265.         address -= count*2;
  266.     } else if(mode == 1)
  267.       address -= count*4;
  268.     else
  269.       address -= count*2;
  270.     break;
  271.   }
  272.   refresh();
  273.   
  274.   CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
  275. }
  276.  
  277. void Disassemble::refresh()
  278. {
  279.   if(rom == NULL)
  280.     return;
  281.   
  282.   bool arm = armState;
  283.   
  284.   if(mode != 0) {
  285.     if(mode == 1)
  286.       arm = true;
  287.     else
  288.       arm = false;
  289.   }
  290.   
  291.   int h = m_list.GetItemHeight(0);
  292.   RECT r;
  293.   m_list.GetClientRect(&r);
  294.   count = (r.bottom - r.top+1)/h;
  295.  
  296.   m_list.ResetContent();
  297.   if(!emulating && theApp.cartridgeType == 0)
  298.     return;
  299.   
  300.   char buffer[80];
  301.   u32 addr = address;
  302.   int i;
  303.   int sel = -1;
  304.   for(i = 0; i < count; i++) {
  305.     if(addr == armNextPC)
  306.       sel = i;
  307.     if(arm) {
  308.       addr += disArm(addr, buffer, 3);
  309.     } else {
  310.       addr += disThumb(addr, buffer, 3);
  311.     }
  312.     m_list.InsertString(-1, buffer);
  313.   }
  314.  
  315.   if(sel != -1)
  316.     m_list.SetCurSel(sel);
  317.  
  318.   CPUUpdateCPSR();
  319.   
  320.   for(i = 0; i < 17; i++) {
  321.     sprintf(buffer, "%08x", reg[i].I);
  322.     GetDlgItem(IDC_R0+i)->SetWindowText(buffer);
  323.   }
  324.  
  325.   m_n = (reg[16].I & 0x80000000) != 0;
  326.   m_z = (reg[16].I & 0x40000000) != 0;
  327.   m_c = (reg[16].I & 0x20000000) != 0;
  328.   m_v = (reg[16].I & 0x10000000) != 0;
  329.   m_i = (reg[16].I & 0x80) != 0;
  330.   m_f = (reg[16].I & 0x40) != 0;
  331.   m_t = (reg[16].I & 0x20) != 0;
  332.  
  333.   UpdateData(FALSE);
  334.  
  335.   int v = reg[16].I & 0x1f;
  336.   sprintf(buffer, "%02x", v);
  337.   GetDlgItem(IDC_MODE)->SetWindowText(buffer);
  338. }
  339.  
  340. void Disassemble::update()
  341. {
  342.   OnGopc();
  343.   refresh();
  344. }
  345.  
  346. void Disassemble::PostNcDestroy() 
  347. {
  348.   delete this;
  349. }
  350.