⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debug.cpp

📁 一个gba的模拟器源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>

#include "Debug.h"
#include "Pal.h"
#define NOTYPEREDEF
#include "gotodialog.h"
#include "Value.h"
//#include "Entry.h"
//#include "Data.h"
#include "Search.h"
//#include "Log.h"
//#include "EditLog.h"
//#include "AddLog.h"
#include "rom.h"
#include "z80.h"
#include "z80dasm.h"
#include "TileView.h"
#include "MapView.h"

#define GETBYTE(x) (getmem_direct(x)&0xff)
#define GETWORD(x) ((getmem_direct(x)|(getmem_direct(x+1)<<8))&0xffff)
#define GETDWORD(x) (GETWORD(x)|(GETWORD(x+2)<<16))

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TDebugWnd *DebugWnd;
int debug=0;
int run=1;
int debugStartPC,debugStartMem;
int debugCheckEnable;
int debugEnforceAddr=0;
int debugFirstInstrucLen;
int debugCodeBreakCount,debugCodeBreak[256];
int debugDataBreakCount,debugDataBreakType[256];
int debugDataBreakLow[256],debugDataBreakHigh[256];
int debugDataBreak;
int debugProgBreak,debugProgBreakOfs,debugProgLen;
int debugBeginStepOver,debugEndStepOver;
int debugStepOver,debugStepGoal;
int debugStepA7;
int debugForceUpdate;
int debugLogEnable;
int debugLogCount;
int debugLogClass[256];
int debugLogType[256];
int debugLogLow[256];
int debugLogHigh[256];
int debugLogCheck[256];
int debugLogLast[256];
int debugLogState[256];
int debugLogAny[256];
int debugLogLinkSend,debugLogLinkRecv;
int debugException=0;
int debugRunToCursor=0;
int debugCursorAddr;
int exceptBPCount,exceptBP[48];
int endStepOver=0,ignoreStack=0;
//extern int readmem24(int a);
//extern int readmem24_word(int a);
//extern int readmem24_dword(int a);
//extern int writemem24(int a,int v);
//extern int writemem24_word(int a,int v);
//extern int writemem24_dword(int a,int v);
//extern void UseDebugReadFuncs();
//extern void RestoreReadFuncs();
extern void PauseStart();
extern void PauseEnd();
//extern Z80_Regs R;
volatile extern int emuRunning;
extern int lcdClk;
extern int enableDebugWarnings;

static char tmpStr[64];

//---------------------------------------------------------------------------
__fastcall TDebugWnd::TDebugWnd(TComponent* Owner)
    : TForm(Owner)
{
    debugStartMem=0;
    debugProgBreak=0;
    debugCodeBreakCount=0;
    debugDataBreakCount=0;
    debugDataBreak=0;
    debugStepOver=0;
    debugBeginStepOver=0;
    debugForceUpdate=1;
    debugLogEnable=0;
    debugLogCount=0;
    debugLogLinkSend=0;
    debugLogLinkRecv=0;
}

//---------------------------------------------------------------------------
void __fastcall TDebugWnd::Update()
{
    char str[256],str2[256];
    int useOldPC=0;

    if (!romLoaded) return;
//    PauseStart();
    if ((!run)&&debugStepOver)
        debugStepOver=0;
    if ((!run)&&debugDataBreak)
    {
        debugDataBreak=0;
        useOldPC=1;
    }
    int chg,i,j,k,max;
//    sprintf(str,"AF=%4.4X",R.AF.D); AF->Caption=str; AF->Update();
//    sprintf(str,"BC=%4.4X",R.BC.D); BC->Caption=str; BC->Update();
//    sprintf(str,"DE=%4.4X",R.DE.D); DE->Caption=str; DE->Update();
//    sprintf(str,"HL=%4.4X",R.HL.D); HL->Caption=str; HL->Update();
//    sprintf(str,"SP=%4.4X",R.SP.D); SP->Caption=str; SP->Update();
    #ifdef C_CORE
        sprintf(str,"AF=%4.4X",regAF); AF->Caption=str; AF->Update();
    #else
        int z=regAF&0x40?0x80:0;
        int n=nFlag?0x40:0;
        int h=regAF&0x10?0x20:0;
        int c=regAF&1?0x10:0;
        sprintf(str,"AF=%4.4X",(regAF&0xff00)|z|n|h|c); AF->Caption=str; AF->Update();
    #endif
    sprintf(str,"BC=%4.4X",regBC); BC->Caption=str; BC->Update();
    sprintf(str,"DE=%4.4X",regDE); DE->Caption=str; DE->Update();
    sprintf(str,"HL=%4.4X",regHL); HL->Caption=str; HL->Update();
    sprintf(str,"SP=%4.4X",regSP); SP->Caption=str; SP->Update();
//        MakeSR();
//    sprintf(str,"PC=%4.4X",R.PC.D); PC->Caption=str; PC->Update();
    sprintf(str,"PC=%4.4X",regPC); PC->Caption=str; PC->Update();
//    sprintf(str,"IME=%X",R.IFF1?1:0); IME->Caption=str; IME->Update();
    sprintf(str,"IME=%X",imeFlag); IME->Caption=str; IME->Update();
    sprintf(str,"ROM PG=%3.3X",romPage); ROMPg->Caption=str; ROMPg->Update();
    sprintf(str,"RAM PG=%X",ramPage); RAMPg->Caption=str; RAMPg->Update();
    sprintf(str,"RAM ENABLE=%X",ramEnable&1); RAMEnable->Caption=str; RAMEnable->Update();
    sprintf(str,"CPU SPEED=%s",(clkMult==1)?"SLOW":"FAST"); CPU->Caption=str; CPU->Update();
    sprintf(str,"VBLANK INT=%s",(hiRam[0xff]&1)?"ENABLED":"DISABLED"); VBlank->Caption=str; VBlank->Update();
    sprintf(str,"LCDC INT=  %s",(hiRam[0xff]&2)?"ENABLED":"DISABLED"); LCDC->Caption=str; LCDC->Update();
    sprintf(str,"TIMER INT= %s",(hiRam[0xff]&4)?"ENABLED":"DISABLED"); Timer->Caption=str; Timer->Update();
    sprintf(str,"SERIAL INT=%s",(hiRam[0xff]&8)?"ENABLED":"DISABLED"); Serial->Caption=str; Serial->Update();
    sprintf(str,"BUTTON INT=%s",(hiRam[0xff]&16)?"ENABLED":"DISABLED"); Button->Caption=str; Button->Update();
    sprintf(str,"LY=%2.2X",lcdY); LY->Caption=str; LY->Update();
    sprintf(str,"LYC=%2.2X",hiRam[0x45]&0xff); LYC->Caption=str; LYC->Update();
    sprintf(str,"LCD MODE=%s",(lcdMode==0)?"HBLANK":(lcdMode==1)?"VBLANK":(lcdMode==2)?"OAM SRCH":"TRANSFER"); LCDMode->Caption=str; LCDMode->Update();
//    sprintf(str,"%4.4d CLK UNTIL %s",(lcdMode==0)?(203*clkMult)-lcdClk:(lcdMode==1)?((153-lcdY)*(456*clkMult))+((456*clkMult)-lcdClk):(lcdMode==2)?(83*clkMult)-lcdClk:(175*clkMult)-lcdClk,(lcdMode==0)?"OAM SRCH":(lcdMode==1)?"OAM SRCH":(lcdMode==2)?"TRANSFER":(lcdY>=143)?"VBLANK":"HBLANK"); LCDClk->Caption=str; LCDClk->Update();
    sprintf(str,"%4.4d CLK UNTIL %s",lcdClk,(lcdMode==0)?"OAM SRCH":(lcdMode==1)?"OAM SRCH":(lcdMode==2)?"TRANSFER":(lcdY>=143)?"VBLANK":"HBLANK"); LCDClk->Caption=str; LCDClk->Update();
    int updateCode=1;
    int pc=regPC;//R.PC.D;
    if ((Code->Items->Count)&&(!debugEnforceAddr))
    {
        for (i=0,j=-1,k=-1;i<15;i++)
        {
            int addr;
            if (Code->Items->Strings[i].c_str()[0]!='@')
            {
                sscanf(Code->Items->Strings[i].c_str(),"%x",&addr);
                if (addr==pc)
                {
                    j=i;
                    if (!useOldPC) k=i;
                }
                if ((useOldPC)&&(addr==debugStartPC))
                    k=i;
            }
        }
        if ((j!=-1)&&(k==-1)) k=j;
        if (j!=-1)
        {
            if (j>=11)
            {
                if (Code->Items->Strings[j-10].c_str()[0]!='@')
                {
                    sscanf(Code->Items->Strings[j-10].c_str(),
                        "%x",&debugStartPC);
                }
                else
                {
                    sscanf(Code->Items->Strings[j-9].c_str(),
                        "%x",&debugStartPC);
                }
            }
            else
            {
                if (Code->Items->Strings[0].c_str()[0]!='@')
                {
                    sscanf(Code->Items->Strings[0].c_str(),
                        "%x",&debugStartPC);
                }
                else
                {
                    sscanf(Code->Items->Strings[1].c_str(),
                        "%x",&debugStartPC);
                }
                if (!debugForceUpdate)
                    updateCode=0;
                for (i=0;i<15;i++)
                {
                    if (i==j)
                    {
                        strcpy(str,Code->Items->Strings[i].c_str());
                        str[4]='-'; str[5]='>';
                        Code->Items->Strings[i]=str;
                    }
                    else
                    {
                        strcpy(str,Code->Items->Strings[i].c_str());
                        if (str[0]!='@')
                        {
                            str[4]=':'; str[5]=' ';
                            Code->Items->Strings[i]=str;
                        }
                    }
                }
                Code->ItemIndex=k;
            }
        }
    }
    debugEnforceAddr=0;
    if (updateCode)
    {
        unsigned short buf[256];
        for (i=0;i<256;i++)
            buf[i]=GETWORD(debugStartPC+(i<<1));
        Code->Clear();
        int first=1;
        for (i=0,j=0,k=-1;i<15;i++)
        {
            int oj=j;
//            if (IsROMAddr(debugStartPC+j))
//            {
//                sprintf(str2,"@%s:",ROMAddrName(
//                    debugStartPC+j));
//                Code->Items->Add(str2);
//                i++; if (i>=15) break;
//            }
            j+=DasmZ80(str,debugStartPC+j);
            if (first)
            {
                debugFirstInstrucLen=j;
                first=0;
            }
            if ((debugStartPC+oj)!=pc)
                sprintf(str2,"%4.4X: %s",(debugStartPC+oj)&0xffffff,str);
            else
            {
                sprintf(str2,"%4.4X->%s",(debugStartPC+oj)&0xffffff,str);
                k=i;
            }
            Code->Items->Add(str2);
        }
        Code->ItemIndex=k;
    }
    Code->Update();
    Stack->Clear();
    for (i=0;i<16;i++)
    {
//        sprintf(str,"%4.4X: %4.4X",R.SP.D+(i*2),GETWORD(
//            R.SP.D+(i*2)));
        sprintf(str,"%4.4X: %4.4X",regSP+(i*2),GETWORD(
            regSP+(i*2)));
        Stack->Items->Add(str);
    }
    Stack->Update();
    UpdateMem();
    if (PalView->Visible) PalView->DoUpdate();
    if (TileWnd->Visible) TileWnd->DoUpdate();
    debugForceUpdate=0;
//    PauseEnd();
}

void __fastcall TDebugWnd::UpdateMem()
{
    if (!romLoaded) return;
    int i,j;
    char str[32];
    TListBox *memCol[8]={MemCol0,MemCol1,MemCol2,MemCol3,
        MemCol4,MemCol5,MemCol6,MemCol7};
//    PauseStart();
    MemAddr->Clear(); MemCol0->Clear(); MemCol1->Clear();
    MemCol2->Clear(); MemCol3->Clear(); MemCol4->Clear();
    MemCol5->Clear(); MemCol6->Clear(); MemCol7->Clear();
    MemText->Clear();
    for (i=0;i<0x30;)
    {
        sprintf(str,"%6.6X",(debugStartMem+i)&0xffffff);
        MemAddr->Items->Add(str);
        for (j=0;j<8;j++)
        {
            sprintf(str,"%2.2X",getmem_direct(debugStartMem+i+j));
            memCol[j]->Items->Add(str);
        }
        str[8]=0;
        for (j=0;j<8;j++,i++)
        {
            int c=getmem_direct(debugStartMem+i)&0xff;
            if ((c>=32)&&(c<128))
                str[j]=c;
            else
                str[j]='.';
        }
        MemText->Items->Add(str);
    }
    MemAddr->Repaint(); MemCol0->Repaint(); MemCol1->Repaint();
    MemCol2->Repaint(); MemCol3->Repaint(); MemCol4->Repaint();
    MemCol5->Repaint(); MemCol6->Repaint(); MemCol7->Repaint();
    MemText->Repaint();
//    PauseEnd();
}

void __fastcall TDebugWnd::FormCloseQuery(TObject *Sender, bool &CanClose)
{
    debugStepOver=0;
    debug=0; run=1;
    CanClose=false;
    Hide();
    debugForceUpdate=1;
    debugException=0;
}
//---------------------------------------------------------------------------

//void DoOneInstruction();

void __fastcall TDebugWnd::Step1Click(TObject *Sender)
{
    #ifdef DEMO
    MessageBox(NULL,"This feature is disabled in the demo version.","VGBC",MB_OK|MB_TASKMODAL);
    return;
    #else
    debugException=0;
//    PauseStart();
    run=1;
    OneInstruction();
    run=0;
    debugStartPC=regPC;//R.PC.D;
    Update();
//    PauseEnd();
    #endif
}
//---------------------------------------------------------------------------


void __fastcall TDebugWnd::Run1Click(TObject *Sender)
{
    debugException=0;
    debugStepOver=0;
    debug=0; run=1;
    Hide();
    debugForceUpdate=1;
}
//---------------------------------------------------------------------------


void __fastcall TDebugWnd::CodeKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
    if (!romLoaded) return;
    if (Key==VK_PRIOR)
    {
        debugStartPC--;
        debugEnforceAddr=1;
        Update();
        Application->ProcessMessages();
    }
    else if (Key==VK_NEXT)
    {
        debugStartPC+=debugFirstInstrucLen;
        debugEnforceAddr=1;
        Update();
        Application->ProcessMessages();
    }
    else if (Key==VK_UP)
    {
        if (Code->ItemIndex==0)
        {
            debugStartPC--;
            debugEnforceAddr=1;
            Update();
            Application->ProcessMessages();
            Code->ItemIndex=0;
        }
    }
    else if (Key==VK_DOWN)
    {
        if (Code->ItemIndex==14)
        {
            debugStartPC+=debugFirstInstrucLen;
            debugEnforceAddr=1;
            Update();
            Application->ProcessMessages();
            Code->ItemIndex=14;
        }
    }
    else if (Key=='G')
        Gotoaddress1Click(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TDebugWnd::Gotoaddress1Click(TObject *Sender)
{
    if (!romLoaded) return;
    #ifdef DEMO
    MessageBox(NULL,"This feature is disabled in the demo version.","VGBC",MB_OK|MB_TASKMODAL);
    return;
    #else
    GoToDlg->Address->Text="";
    if (GoToDlg->ShowModal()==1)
    {
        sscanf(GoToDlg->Address->Text.c_str(),"%x",&debugStartPC);
        debugEnforceAddr=1;
        Update();
    }
    #endif
}
//---------------------------------------------------------------------------

void __fastcall TDebugWnd::SetPC1Click(TObject *Sender)
{
    if (!romLoaded) return;
    #ifdef DEMO
    MessageBox(NULL,"This feature is disabled in the demo version.","VGBC",MB_OK|MB_TASKMODAL);
    return;
    #else
    debugException=0;
    if (Code->ItemIndex==-1) return;
    sscanf(Code->Items->Strings[Code->ItemIndex].c_str(),
        "%x",&regPC);//R.PC.D);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -