Add history to debugger and cleanup. Patch 2991413 from etillite
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3613
This commit is contained in:
parent
6976225474
commit
b441536ff4
2 changed files with 151 additions and 72 deletions
|
@ -76,6 +76,7 @@ static void DrawVariables(void);
|
|||
char* AnalyzeInstruction(char* inst, bool saveSelector);
|
||||
Bit32u GetHexValue(char* str, char*& hex);
|
||||
|
||||
#if 0
|
||||
class DebugPageHandler : public PageHandler {
|
||||
public:
|
||||
Bitu readb(PhysPt /*addr*/) {
|
||||
|
@ -90,10 +91,8 @@ public:
|
|||
}
|
||||
void writed(PhysPt /*addr*/,Bitu /*val*/) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
class DEBUG;
|
||||
|
@ -123,7 +122,6 @@ static char curSelectorName[3] = { 0,0,0 };
|
|||
static Segment oldsegs[6];
|
||||
static Bitu oldflags,oldcpucpl;
|
||||
DBGBlock dbg;
|
||||
static Bitu input_count;
|
||||
Bitu cycle_count;
|
||||
static bool debugging;
|
||||
|
||||
|
@ -136,23 +134,34 @@ static void SetColor(Bitu test) {
|
|||
}
|
||||
}
|
||||
|
||||
#define MAXCMDLEN 254
|
||||
struct SCodeViewData {
|
||||
int cursorPos;
|
||||
int cursorPos;
|
||||
Bit16u firstInstSize;
|
||||
Bit16u useCS;
|
||||
Bit32u useEIPlast, useEIPmid;
|
||||
Bit32u useEIP;
|
||||
Bit16u useCS;
|
||||
Bit32u useEIPlast, useEIPmid;
|
||||
Bit32u useEIP;
|
||||
Bit16u cursorSeg;
|
||||
Bit32u cursorOfs;
|
||||
bool inputMode;
|
||||
char inputStr[255];
|
||||
char prevInputStr[255];
|
||||
|
||||
Bit32u cursorOfs;
|
||||
bool ovrMode;
|
||||
char inputStr[MAXCMDLEN+1];
|
||||
char suspInputStr[MAXCMDLEN+1];
|
||||
int inputPos;
|
||||
} codeViewData;
|
||||
|
||||
static Bit16u dataSeg;
|
||||
static Bit32u dataOfs;
|
||||
static bool showExtend = true;
|
||||
static Bit16u dataSeg;
|
||||
static Bit32u dataOfs;
|
||||
static bool showExtend = true;
|
||||
|
||||
static void ClearInputLine(void) {
|
||||
codeViewData.inputStr[0] = 0;
|
||||
codeViewData.inputPos = 0;
|
||||
}
|
||||
|
||||
// History stuff
|
||||
#define MAX_HIST_BUFFER 50
|
||||
static list<string> histBuff;
|
||||
static list<string>::iterator histBuffPos = histBuff.end();
|
||||
|
||||
/***********/
|
||||
/* Helpers */
|
||||
|
@ -775,6 +784,8 @@ static void DrawCode(void) {
|
|||
wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREEN_BLACK));
|
||||
if (codeViewData.cursorPos==-1) {
|
||||
codeViewData.cursorPos = i; // Set Cursor
|
||||
}
|
||||
if (i == codeViewData.cursorPos) {
|
||||
codeViewData.cursorSeg = SegValue(cs);
|
||||
codeViewData.cursorOfs = disEIP;
|
||||
}
|
||||
|
@ -837,12 +848,18 @@ static void DrawCode(void) {
|
|||
|
||||
wattrset(dbg.win_code,0);
|
||||
if (!debugging) {
|
||||
mvwprintw(dbg.win_code,10,0,"(Running)",codeViewData.inputStr);
|
||||
} else {
|
||||
if(!*codeViewData.inputStr) { //Clear old commands
|
||||
mvwprintw(dbg.win_code,10,0," ");
|
||||
}
|
||||
mvwprintw(dbg.win_code,10,0,"-> %s_ ",codeViewData.inputStr);
|
||||
mvwprintw(dbg.win_code,10,0,"%s","(Running)");
|
||||
wclrtoeol(dbg.win_code);
|
||||
} else {
|
||||
//TODO long lines
|
||||
char* dispPtr = codeViewData.inputStr;
|
||||
char* curPtr = &codeViewData.inputStr[codeViewData.inputPos];
|
||||
mvwprintw(dbg.win_code,10,0,"%c-> %s%c",
|
||||
(codeViewData.ovrMode?'O':'I'),dispPtr,(*curPtr?' ':'_'));
|
||||
wclrtoeol(dbg.win_code); // not correct in pdcurses if full line
|
||||
if (*curPtr) {
|
||||
mvwchgat(dbg.win_code,10,(curPtr-dispPtr+4),1,0,(PAIR_BLACK_GREY),NULL);
|
||||
}
|
||||
}
|
||||
|
||||
wrefresh(dbg.win_code);
|
||||
|
@ -1121,6 +1138,7 @@ bool ParseCommand(char* str) {
|
|||
DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X\n",codeSeg,codeOfs);
|
||||
codeViewData.useCS = codeSeg;
|
||||
codeViewData.useEIP = codeOfs;
|
||||
codeViewData.cursorPos = 0;
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -1226,6 +1244,7 @@ bool ParseCommand(char* str) {
|
|||
DEBUG_ShowMsg("DEBUG: Set code overview to interrupt handler %X\n",intNr);
|
||||
codeViewData.useCS = mem_readw(intNr*4+2);
|
||||
codeViewData.useEIP = mem_readw(intNr*4);
|
||||
codeViewData.cursorPos = 0;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -1259,7 +1278,8 @@ bool ParseCommand(char* str) {
|
|||
if (command == "HELP" || command == "?") {
|
||||
DEBUG_ShowMsg("Debugger commands (enter all values in hex or as register):\n");
|
||||
DEBUG_ShowMsg("--------------------------------------------------------------------------\n");
|
||||
DEBUG_ShowMsg("F3/F6 - Re-enter previous command.\n");
|
||||
DEBUG_ShowMsg("F3/F6 - Previous command in history.\n");
|
||||
DEBUG_ShowMsg("F4/F7 - Next command in history.\n");
|
||||
DEBUG_ShowMsg("F5 - Run.\n");
|
||||
DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n");
|
||||
DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n");
|
||||
|
@ -1476,12 +1496,12 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) {
|
|||
if (jmp) {
|
||||
pos = strchr(instu,'$');
|
||||
if (pos) {
|
||||
pos = strchr(instu,'+');
|
||||
if (pos) {
|
||||
strcpy(result,"(down)");
|
||||
} else {
|
||||
strcpy(result,"(up)");
|
||||
}
|
||||
pos = strchr(instu,'+');
|
||||
if (pos) {
|
||||
strcpy(result,"(down)");
|
||||
} else {
|
||||
strcpy(result,"(up)");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sprintf(result,"(no jmp)");
|
||||
|
@ -1497,6 +1517,11 @@ Bit32u DEBUG_CheckKeys(void) {
|
|||
if (key>0) {
|
||||
#if defined(WIN32) && defined(__PDCURSES__)
|
||||
switch (key) {
|
||||
case PADENTER: key=0x0A; break;
|
||||
case PADSLASH: key='/'; break;
|
||||
case PADSTAR: key='*'; break;
|
||||
case PADMINUS: key='-'; break;
|
||||
case PADPLUS: key='+'; break;
|
||||
case ALT_D:
|
||||
if (ungetch('D') != ERR) key=27;
|
||||
break;
|
||||
|
@ -1518,7 +1543,7 @@ Bit32u DEBUG_CheckKeys(void) {
|
|||
case 27: // escape (a bit slow): Clears line. and processes alt commands.
|
||||
key=getch();
|
||||
if(key < 0) { //Purely escape Clear line
|
||||
codeViewData.inputStr[0] = 0;
|
||||
ClearInputLine();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1584,23 +1609,54 @@ Bit32u DEBUG_CheckKeys(void) {
|
|||
case KEY_END: // End: scroll log page down
|
||||
DEBUG_RefreshPage(1);
|
||||
break;
|
||||
case KEY_F(6): // Re-enter previous command (f1-f4 generate rubbish at my place)
|
||||
case KEY_F(3): // Re-enter previous command
|
||||
// copy prevInputStr back into inputStr
|
||||
safe_strncpy(codeViewData.inputStr, codeViewData.prevInputStr, sizeof(codeViewData.inputStr));
|
||||
case KEY_IC: // Insert: toggle insert/overwrite
|
||||
codeViewData.ovrMode = !codeViewData.ovrMode;
|
||||
break;
|
||||
case KEY_LEFT: // move to the left in command line
|
||||
if (codeViewData.inputPos > 0) codeViewData.inputPos--;
|
||||
break;
|
||||
case KEY_RIGHT: // move to the right in command line
|
||||
if (codeViewData.inputStr[codeViewData.inputPos]) codeViewData.inputPos++;
|
||||
break;
|
||||
case KEY_F(6): // previous command (f1-f4 generate rubbish at my place)
|
||||
case KEY_F(3): // previous command
|
||||
if (histBuffPos == histBuff.begin()) break;
|
||||
if (histBuffPos == histBuff.end()) {
|
||||
// copy inputStr to suspInputStr so we can restore it
|
||||
safe_strncpy(codeViewData.suspInputStr, codeViewData.inputStr, sizeof(codeViewData.suspInputStr));
|
||||
}
|
||||
safe_strncpy(codeViewData.inputStr,(*--histBuffPos).c_str(),sizeof(codeViewData.inputStr));
|
||||
codeViewData.inputPos = strlen(codeViewData.inputStr);
|
||||
break;
|
||||
case KEY_F(7): // next command (f1-f4 generate rubbish at my place)
|
||||
case KEY_F(4): // next command
|
||||
if (histBuffPos == histBuff.end()) break;
|
||||
if (++histBuffPos != histBuff.end()) {
|
||||
safe_strncpy(codeViewData.inputStr,(*histBuffPos).c_str(),sizeof(codeViewData.inputStr));
|
||||
} else {
|
||||
// copy suspInputStr back into inputStr
|
||||
safe_strncpy(codeViewData.inputStr, codeViewData.suspInputStr, sizeof(codeViewData.inputStr));
|
||||
}
|
||||
codeViewData.inputPos = strlen(codeViewData.inputStr);
|
||||
break;
|
||||
case KEY_F(5): // Run Program
|
||||
debugging=false;
|
||||
CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true);
|
||||
ignoreAddressOnce = SegPhys(cs)+reg_eip;
|
||||
DOSBOX_SetNormalLoop();
|
||||
break;
|
||||
case KEY_F(9): // Set/Remove TBreakpoint
|
||||
case KEY_F(9): // Set/Remove Breakpoint
|
||||
{ PhysPt ptr = GetAddress(codeViewData.cursorSeg,codeViewData.cursorOfs);
|
||||
if (CBreakpoint::IsBreakpoint(ptr)) CBreakpoint::DeleteBreakpoint(ptr);
|
||||
else CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false);
|
||||
if (CBreakpoint::IsBreakpoint(ptr)) {
|
||||
CBreakpoint::DeleteBreakpoint(ptr);
|
||||
DEBUG_ShowMsg("DEBUG: Breakpoint deletion success.\n");
|
||||
}
|
||||
else {
|
||||
CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false);
|
||||
DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X\n",codeViewData.cursorSeg,codeViewData.cursorOfs);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case KEY_F(10): // Step over inst
|
||||
if (StepOver()) return 0;
|
||||
else {
|
||||
|
@ -1621,28 +1677,54 @@ Bit32u DEBUG_CheckKeys(void) {
|
|||
CBreakpoint::ignoreOnce = 0;
|
||||
break;
|
||||
case 0x0A: //Parse typed Command
|
||||
codeViewData.inputMode = true;
|
||||
codeViewData.inputStr[MAXCMDLEN] = '\0';
|
||||
if(ParseCommand(codeViewData.inputStr)) {
|
||||
// copy inputStr to prevInputStr so we can restore it if the user hits F3
|
||||
safe_strncpy(codeViewData.prevInputStr, codeViewData.inputStr, sizeof(codeViewData.prevInputStr));
|
||||
// clear input line ready for next command
|
||||
codeViewData.inputStr[0] = 0;
|
||||
char* cmd = ltrim(codeViewData.inputStr);
|
||||
if (histBuff.empty() || *--histBuff.end()!=cmd)
|
||||
histBuff.push_back(cmd);
|
||||
if (histBuff.size() > MAX_HIST_BUFFER) histBuff.pop_front();
|
||||
histBuffPos = histBuff.end();
|
||||
ClearInputLine();
|
||||
} else {
|
||||
codeViewData.inputPos = strlen(codeViewData.inputStr);
|
||||
}
|
||||
break;
|
||||
case KEY_BACKSPACE: //backspace (linux)
|
||||
case 0x7f: // backspace in some terminal emulators (linux)
|
||||
case 0x08: // delete
|
||||
if (codeViewData.inputPos == 0) break;
|
||||
codeViewData.inputPos--;
|
||||
// fallthrough
|
||||
case KEY_DC: // delete character
|
||||
if ((codeViewData.inputPos<0) || (codeViewData.inputPos>=MAXCMDLEN)) break;
|
||||
if (codeViewData.inputStr[codeViewData.inputPos] != 0) {
|
||||
codeViewData.inputStr[MAXCMDLEN] = '\0';
|
||||
for(char* p=&codeViewData.inputStr[codeViewData.inputPos];(*p=*(p+1));p++) {}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ((key>=32) && (key<127)) {
|
||||
if ((codeViewData.inputPos<0) || (codeViewData.inputPos>=MAXCMDLEN)) break;
|
||||
codeViewData.inputStr[MAXCMDLEN] = '\0';
|
||||
if (codeViewData.inputStr[codeViewData.inputPos] == 0) {
|
||||
codeViewData.inputStr[codeViewData.inputPos++] = char(key);
|
||||
codeViewData.inputStr[codeViewData.inputPos] = '\0';
|
||||
} else if (!codeViewData.ovrMode) {
|
||||
int len = (int) strlen(codeViewData.inputStr);
|
||||
if (len < MAXCMDLEN) {
|
||||
for(len++;len>codeViewData.inputPos;len--)
|
||||
codeViewData.inputStr[len]=codeViewData.inputStr[len-1];
|
||||
codeViewData.inputStr[codeViewData.inputPos++] = char(key);
|
||||
}
|
||||
} else {
|
||||
codeViewData.inputStr[codeViewData.inputPos++] = char(key);
|
||||
}
|
||||
} else if (key==killchar()) {
|
||||
ClearInputLine();
|
||||
}
|
||||
break;
|
||||
case 0x107: //backspace (linux)
|
||||
case 0x7f: //backspace in some terminal emulators (linux)
|
||||
case 0x08: // delete
|
||||
if (strlen(codeViewData.inputStr)>0) codeViewData.inputStr[strlen(codeViewData.inputStr)-1] = 0;
|
||||
break;
|
||||
default : if ((key>=32) && (key<=128) && (strlen(codeViewData.inputStr)<253)) {
|
||||
Bit32u len = strlen(codeViewData.inputStr);
|
||||
codeViewData.inputStr[len] = char(key);
|
||||
codeViewData.inputStr[len+1] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
if (ret<0) return ret;
|
||||
if (ret<0) return ret;
|
||||
if (ret>0) {
|
||||
ret=(*CallBack_Handlers[ret])();
|
||||
if (ret) {
|
||||
|
@ -1902,7 +1984,7 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, ofstream& out) {
|
|||
char ibytes[200]=""; char tmpc[200];
|
||||
for (Bitu i=0; i<size; i++) {
|
||||
Bit8u value;
|
||||
if (mem_readb_checked(start+i,&value)) sprintf(tmpc,"?? ",value);
|
||||
if (mem_readb_checked(start+i,&value)) sprintf(tmpc,"%s","?? ");
|
||||
else sprintf(tmpc,"%02X ",value);
|
||||
strcat(ibytes,tmpc);
|
||||
}
|
||||
|
@ -1958,7 +2040,6 @@ public:
|
|||
safe_strncpy(filename,temp_line.c_str(),128);
|
||||
// Read commandline
|
||||
Bit16u i =2;
|
||||
bool ok = false;
|
||||
args[0] = 0;
|
||||
for (;cmd->FindCommand(i++,temp_line)==true;) {
|
||||
strncat(args,temp_line.c_str(),256);
|
||||
|
@ -2027,8 +2108,7 @@ void DEBUG_SetupConsole(void) {
|
|||
#endif
|
||||
memset((void *)&dbg,0,sizeof(dbg));
|
||||
debugging=false;
|
||||
dbg.active_win=3;
|
||||
input_count=0;
|
||||
// dbg.active_win=3;
|
||||
/* Start the Debug Gui */
|
||||
DBGUI_StartUp();
|
||||
}
|
||||
|
@ -2037,6 +2117,7 @@ static void DEBUG_ShutDown(Section * /*sec*/) {
|
|||
CBreakpoint::DeleteAll();
|
||||
CDebugVar::DeleteAll();
|
||||
curs_set(old_cursor_state);
|
||||
endwin();
|
||||
#ifndef WIN32
|
||||
tcsetattr(0, TCSANOW,&consolesettings);
|
||||
// printf("\e[0m\e[2J"); //Seems to destroy scrolling
|
||||
|
@ -2049,11 +2130,11 @@ Bitu debugCallback;
|
|||
|
||||
void DEBUG_Init(Section* sec) {
|
||||
|
||||
MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n");
|
||||
// MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n");
|
||||
DEBUG_DrawScreen();
|
||||
/* Add some keyhandlers */
|
||||
MAPPER_AddHandler(DEBUG_Enable,MK_pause,MMOD2,"debugger","Debugger");
|
||||
/* Clear the TBreakpoint list */
|
||||
/* Reset code overview and input line */
|
||||
memset((void*)&codeViewData,0,sizeof(codeViewData));
|
||||
/* setup debug.com */
|
||||
PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart);
|
||||
|
@ -2154,7 +2235,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) {
|
|||
sprintf(buffer,"%04X:%04X ",seg,ofs1);
|
||||
for (Bit16u x=0; x<16; x++) {
|
||||
Bit8u value;
|
||||
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"?? ",value);
|
||||
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? ");
|
||||
else sprintf(temp,"%02X ",value);
|
||||
strcat(buffer,temp);
|
||||
}
|
||||
|
@ -2167,7 +2248,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) {
|
|||
sprintf(buffer,"%04X:%04X ",seg,ofs1);
|
||||
for (Bit16u x=0; x<num; x++) {
|
||||
Bit8u value;
|
||||
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"?? ",value);
|
||||
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? ");
|
||||
else sprintf(temp,"%02X ",value);
|
||||
strcat(buffer,temp);
|
||||
}
|
||||
|
@ -2229,7 +2310,7 @@ static void DrawVariables(void) {
|
|||
|
||||
Bit16u value;
|
||||
if (mem_readw_checked(dv->GetAdr(),&value))
|
||||
snprintf(buffer,DEBUG_VAR_BUF_LEN, "??????", value);
|
||||
snprintf(buffer,DEBUG_VAR_BUF_LEN, "%s", "??????");
|
||||
else
|
||||
snprintf(buffer,DEBUG_VAR_BUF_LEN, "0x%04x", value);
|
||||
|
||||
|
@ -2248,8 +2329,6 @@ static void DrawVariables(void) {
|
|||
|
||||
const Bit32u LOGCPUMAX = 20000;
|
||||
|
||||
static Bit16u logCpuCS [LOGCPUMAX];
|
||||
static Bit32u logCpuEIP[LOGCPUMAX];
|
||||
static Bit32u logCount = 0;
|
||||
|
||||
struct TLogInst {
|
||||
|
@ -2287,7 +2366,7 @@ void DEBUG_HeavyLogInstruction(void) {
|
|||
|
||||
PhysPt start = GetAddress(SegValue(cs),reg_eip);
|
||||
char dline[200];
|
||||
Bitu size = DasmI386(dline, start, reg_eip, cpu.code.big);
|
||||
DasmI386(dline, start, reg_eip, cpu.code.big);
|
||||
char* res = empty;
|
||||
if (showExtend) {
|
||||
res = AnalyzeInstruction(dline,false);
|
||||
|
|
|
@ -154,7 +154,7 @@ static void DrawBars(void) {
|
|||
/* Show the Variable Overview bar */
|
||||
mvaddstr(dbg.win_var->_begy-1,0, "---(Variable Overview )---");
|
||||
/* Show the Output OverView */
|
||||
mvaddstr(dbg.win_out->_begy-1,0, "---(OutPut/Input Scroll: home/end )---");
|
||||
mvaddstr(dbg.win_out->_begy-1,0, "---(Output Scroll: home/end )---");
|
||||
attrset(0);
|
||||
}
|
||||
|
||||
|
@ -178,8 +178,8 @@ static void MakeSubWindows(void) {
|
|||
dbg.win_var=subwin(dbg.win_main,4,win_main_maxx,outy,0);
|
||||
outy+=5;
|
||||
/* The Output Window */
|
||||
dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy-1,win_main_maxx,outy,0);
|
||||
dbg.input_y=win_main_maxy-1;
|
||||
dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy,win_main_maxx,outy,0);
|
||||
// dbg.input_y=win_main_maxy-1;
|
||||
scrollok(dbg.win_out,TRUE);
|
||||
DrawBars();
|
||||
Draw_RegisterLayout();
|
||||
|
@ -257,7 +257,7 @@ void LOG_StartUp(void) {
|
|||
Prop_bool* Pbool = sect->Add_bool(buf,Property::Changeable::Always,true);
|
||||
Pbool->Set_help("Enable/Disable logging of this type.");
|
||||
}
|
||||
MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n");
|
||||
// MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue