📄 debug.cpp
字号:
//---------------------------------------------------------------------------
#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",®PC);//R.PC.D);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -