diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 356ccea8..5b165de5 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -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 histBuff; +static list::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; iFindCommand(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; xGetAdr(),&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); diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index fc9f1ca3..936086c7 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -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"); }