rlm@1: // Disassemble.cpp : implementation file rlm@1: // rlm@1: rlm@1: #include "stdafx.h" rlm@1: #include "resource.h" rlm@1: #include "Disassemble.h" rlm@1: #include "VBA.h" rlm@1: rlm@1: #include "../gba/armdis.h" rlm@1: #include "../gba/GBA.h" rlm@1: #include "../gba/GBAGlobals.h" rlm@1: rlm@1: extern void CPUUpdateCPSR(); rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // Disassemble dialog rlm@1: rlm@1: Disassemble::Disassemble(CWnd*pParent /*=NULL*/) rlm@1: : ResizeDlg(Disassemble::IDD, pParent) rlm@1: { rlm@1: //{{AFX_DATA_INIT(Disassemble) rlm@1: m_c = FALSE; rlm@1: m_f = FALSE; rlm@1: m_i = FALSE; rlm@1: m_n = FALSE; rlm@1: m_t = FALSE; rlm@1: m_v = FALSE; rlm@1: m_z = FALSE; rlm@1: //}}AFX_DATA_INIT rlm@1: autoUpdate = false; rlm@1: address = 0; rlm@1: count = 1; rlm@1: mode = 0; rlm@1: } rlm@1: rlm@1: void Disassemble::DoDataExchange(CDataExchange*pDX) rlm@1: { rlm@1: CDialog::DoDataExchange(pDX); rlm@1: //{{AFX_DATA_MAP(Disassemble) rlm@1: DDX_Control(pDX, IDC_ADDRESS, m_address); rlm@1: DDX_Control(pDX, IDC_DISASSEMBLE, m_list); rlm@1: DDX_Check(pDX, IDC_C, m_c); rlm@1: DDX_Check(pDX, IDC_F, m_f); rlm@1: DDX_Check(pDX, IDC_I, m_i); rlm@1: DDX_Check(pDX, IDC_N, m_n); rlm@1: DDX_Check(pDX, IDC_T, m_t); rlm@1: DDX_Check(pDX, IDC_V, m_v); rlm@1: DDX_Check(pDX, IDC_Z, m_z); rlm@1: DDX_Radio(pDX, IDC_AUTOMATIC, mode); rlm@1: //}}AFX_DATA_MAP rlm@1: } rlm@1: rlm@1: BEGIN_MESSAGE_MAP(Disassemble, CDialog) rlm@1: //{{AFX_MSG_MAP(Disassemble) rlm@1: ON_BN_CLICKED(IDC_AUTO_UPDATE, OnAutoUpdate) rlm@1: ON_BN_CLICKED(IDC_AUTOMATIC, OnAutomatic) rlm@1: ON_BN_CLICKED(IDC_ARM, OnArm) rlm@1: ON_BN_CLICKED(IDC_CLOSE, OnClose) rlm@1: ON_BN_CLICKED(IDC_GO, OnGo) rlm@1: ON_BN_CLICKED(IDC_GOPC, OnGopc) rlm@1: ON_BN_CLICKED(IDC_NEXT, OnNext) rlm@1: ON_BN_CLICKED(IDC_REFRESH, OnRefresh) rlm@1: ON_BN_CLICKED(IDC_THUMB, OnThumb) rlm@1: ON_WM_VSCROLL() rlm@1: //}}AFX_MSG_MAP rlm@1: END_MESSAGE_MAP() rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // Disassemble message handlers rlm@1: rlm@1: void Disassemble::OnAutoUpdate() rlm@1: { rlm@1: autoUpdate = !autoUpdate; rlm@1: if (autoUpdate) rlm@1: { rlm@1: theApp.winAddUpdateListener(this); rlm@1: } rlm@1: else rlm@1: { rlm@1: theApp.winRemoveUpdateListener(this); rlm@1: } rlm@1: } rlm@1: rlm@1: void Disassemble::OnAutomatic() rlm@1: { rlm@1: mode = 0; rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: void Disassemble::OnArm() rlm@1: { rlm@1: mode = 1; rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: void Disassemble::OnClose() rlm@1: { rlm@1: theApp.winRemoveUpdateListener(this); rlm@1: rlm@1: DestroyWindow(); rlm@1: } rlm@1: rlm@1: void Disassemble::OnGo() rlm@1: { rlm@1: CString buffer; rlm@1: m_address.GetWindowText(buffer); rlm@1: sscanf(buffer, "%x", &address); rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: void Disassemble::OnGopc() rlm@1: { rlm@1: if (armState) rlm@1: address = armNextPC - 16; rlm@1: else rlm@1: address = armNextPC - 8; rlm@1: rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: void Disassemble::OnNext() rlm@1: { rlm@1: CPULoop(1); rlm@1: if (armState) rlm@1: { rlm@1: u32 total = address+count*4; rlm@1: if (armNextPC >= address && armNextPC < total) rlm@1: {} rlm@1: else rlm@1: { rlm@1: OnGopc(); rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: u32 total = address+count*2; rlm@1: if (armNextPC >= address && armNextPC < total) rlm@1: {} rlm@1: else rlm@1: { rlm@1: OnGopc(); rlm@1: } rlm@1: } rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: void Disassemble::OnRefresh() rlm@1: { rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: void Disassemble::OnThumb() rlm@1: { rlm@1: mode = 2; rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: BOOL Disassemble::OnInitDialog() rlm@1: { rlm@1: CDialog::OnInitDialog(); rlm@1: rlm@1: DIALOG_SIZER_START(sz) rlm@1: DIALOG_SIZER_ENTRY(IDC_DISASSEMBLE, DS_SizeY) rlm@1: DIALOG_SIZER_ENTRY(IDC_REFRESH, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_CLOSE, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_NEXT, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_AUTO_UPDATE, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_GOPC, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_VSCROLL, DS_SizeY) rlm@1: DIALOG_SIZER_END() rlm@1: SetData(sz, rlm@1: TRUE, rlm@1: HKEY_CURRENT_USER, rlm@1: "Software\\Emulators\\VisualBoyAdvance\\Viewer\\DisassembleView", rlm@1: NULL); rlm@1: rlm@1: SCROLLINFO si; rlm@1: ZeroMemory(&si, sizeof(si)); rlm@1: si.cbSize = sizeof(si); rlm@1: si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; rlm@1: si.nMin = 0; rlm@1: si.nMax = 100; rlm@1: si.nPos = 50; rlm@1: si.nPage = 0; rlm@1: GetDlgItem(IDC_VSCROLL)->SetScrollInfo(SB_CTL, &si, TRUE); rlm@1: rlm@1: CFont *font = CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)); rlm@1: m_list.SetFont(font, FALSE); rlm@1: for (int i = 0; i < 17; i++) rlm@1: GetDlgItem(IDC_R0+i)->SetFont(font, FALSE); rlm@1: rlm@1: GetDlgItem(IDC_MODE)->SetFont(font, FALSE); rlm@1: rlm@1: m_address.LimitText(8); rlm@1: refresh(); rlm@1: rlm@1: return TRUE; // return TRUE unless you set the focus to a control rlm@1: // EXCEPTION: OCX Property Pages should return FALSE rlm@1: } rlm@1: rlm@1: void Disassemble::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar*pScrollBar) rlm@1: { rlm@1: switch (nSBCode) rlm@1: { rlm@1: case SB_LINEDOWN: rlm@1: if (mode == 0) rlm@1: { rlm@1: if (armState) rlm@1: address += 4; rlm@1: else rlm@1: address += 2; rlm@1: } rlm@1: else if (mode == 1) rlm@1: address += 4; rlm@1: else rlm@1: address += 2; rlm@1: break; rlm@1: case SB_LINEUP: rlm@1: if (mode == 0) rlm@1: { rlm@1: if (armState) rlm@1: address -= 4; rlm@1: else rlm@1: address -= 2; rlm@1: } rlm@1: else if (mode == 1) rlm@1: address -= 4; rlm@1: else rlm@1: address -= 2; rlm@1: break; rlm@1: case SB_PAGEDOWN: rlm@1: if (mode == 0) rlm@1: { rlm@1: if (armState) rlm@1: address += count*4; rlm@1: else rlm@1: address += count*2; rlm@1: } rlm@1: else if (mode == 1) rlm@1: address += count*4; rlm@1: else rlm@1: address += count*2; rlm@1: break; rlm@1: case SB_PAGEUP: rlm@1: if (mode == 0) rlm@1: { rlm@1: if (armState) rlm@1: address -= count*4; rlm@1: else rlm@1: address -= count*2; rlm@1: } rlm@1: else if (mode == 1) rlm@1: address -= count*4; rlm@1: else rlm@1: address -= count*2; rlm@1: break; rlm@1: } rlm@1: refresh(); rlm@1: rlm@1: CDialog::OnVScroll(nSBCode, nPos, pScrollBar); rlm@1: } rlm@1: rlm@1: void Disassemble::refresh() rlm@1: { rlm@1: if (rom == NULL) rlm@1: return; rlm@1: rlm@1: bool8 arm = armState; rlm@1: rlm@1: if (mode != 0) rlm@1: { rlm@1: if (mode == 1) rlm@1: arm = true; rlm@1: else rlm@1: arm = false; rlm@1: } rlm@1: rlm@1: int h = m_list.GetItemHeight(0); rlm@1: RECT r; rlm@1: m_list.GetClientRect(&r); rlm@1: count = (r.bottom - r.top+1)/h; rlm@1: rlm@1: m_list.ResetContent(); rlm@1: if (!systemIsEmulating() && systemCartridgeType == 0) rlm@1: return; rlm@1: rlm@1: char buffer[80]; rlm@1: u32 addr = address; rlm@1: int i; rlm@1: int sel = -1; rlm@1: for (i = 0; i < count; i++) rlm@1: { rlm@1: if (addr == armNextPC) rlm@1: sel = i; rlm@1: if (arm) rlm@1: { rlm@1: addr += disArm(addr, buffer, 3); rlm@1: } rlm@1: else rlm@1: { rlm@1: addr += disThumb(addr, buffer, 3); rlm@1: } rlm@1: m_list.InsertString(-1, buffer); rlm@1: } rlm@1: rlm@1: if (sel != -1) rlm@1: m_list.SetCurSel(sel); rlm@1: rlm@1: CPUUpdateCPSR(); rlm@1: rlm@1: for (i = 0; i < 17; i++) rlm@1: { rlm@1: sprintf(buffer, "%08x", reg[i].I); rlm@1: GetDlgItem(IDC_R0+i)->SetWindowText(buffer); rlm@1: } rlm@1: rlm@1: m_n = (reg[16].I & 0x80000000) != 0; rlm@1: m_z = (reg[16].I & 0x40000000) != 0; rlm@1: m_c = (reg[16].I & 0x20000000) != 0; rlm@1: m_v = (reg[16].I & 0x10000000) != 0; rlm@1: m_i = (reg[16].I & 0x80) != 0; rlm@1: m_f = (reg[16].I & 0x40) != 0; rlm@1: m_t = (reg[16].I & 0x20) != 0; rlm@1: rlm@1: UpdateData(FALSE); rlm@1: rlm@1: int v = reg[16].I & 0x1f; rlm@1: sprintf(buffer, "%02x", v); rlm@1: GetDlgItem(IDC_MODE)->SetWindowText(buffer); rlm@1: } rlm@1: rlm@1: void Disassemble::update() rlm@1: { rlm@1: OnGopc(); rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: void Disassemble::PostNcDestroy() rlm@1: { rlm@1: delete this; rlm@1: } rlm@1: