expand debug options

This commit is contained in:
Wengier 2021-05-03 14:51:51 -04:00
parent 83c73fa51d
commit e8ccd10263
4 changed files with 80 additions and 38 deletions

View File

@ -5966,6 +5966,7 @@ public:
WriteOut("Generates a non-maskable interrupt (NMI).\n\nNMITEST\n\nNote: This is a debugging tool to test if the interrupt handler works properly.\n");
return;
}
WriteOut("Generating a non-maskable interrupt (NMI)...\n");
CPU_Raise_NMI();
}
};
@ -6644,13 +6645,14 @@ static void SETCOLOR_ProgramStart(Program * * make) {
#endif
#if C_DEBUG
extern Bitu int2fdbg_hook_callback;
class INT2FDBG : public Program {
public:
void Run(void);
private:
void PrintUsage() {
constexpr const char *msg =
"Hooks INT 2Fh for debugging purposes.\n\nINT2FDBG [option]\n /I Installs hook\n\nIt will hook INT 2Fh at the top of the call chain for debugging information.\n";
"Hooks INT 2Fh for debugging purposes.\n\nINT2FDBG [option]\n /I Installs hook\n\nIt will hook INT 2Fh at the top of the call chain for debugging information.\n\nType INT2FDBG without a parameter to show the current hook status.\n";
WriteOut(msg);
}
};
@ -6660,6 +6662,14 @@ void INT2FDBG::Run()
// Hack To allow long commandlines
ChangeToLongCmd();
if (!cmd->GetCount()) {
if (int2fdbg_hook_callback == 0)
WriteOut("INT 2Fh hook has not been set.\n");
else
WriteOut("INT 2Fh hook has already been set.\n");
return;
}
// Usage
if (!cmd->GetCount() || cmd->FindExist("-?", false) || cmd->FindExist("/?", false)) {
PrintUsage();

View File

@ -720,6 +720,8 @@ static const char *def_menu_help_debug[] =
"save_logas",
"--",
"debug_blankrefreshtest",
"debug_generatenmi",
"debug_int2fhook",
"debug_pageflip",
"debug_retracepoll",
"--",

View File

@ -11213,6 +11213,9 @@ bool refreshtest_menu_callback(DOSBoxMenu * const xmenu, DOSBoxMenu::item * cons
BlankDisplay();
#if defined(USE_TTF)
if (TTF_using()) resetFontSize();
#endif
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
mainMenu.setRedraw();
GFX_DrawSDLMenu(mainMenu,mainMenu.display_list);
@ -11221,6 +11224,32 @@ bool refreshtest_menu_callback(DOSBoxMenu * const xmenu, DOSBoxMenu::item * cons
return true;
}
bool generatenmi_menu_callback(DOSBoxMenu * const xmenu, DOSBoxMenu::item * const menuitem) {
(void)menuitem;
(void)xmenu;
CPU_Raise_NMI();
return true;
}
Bitu int2fdbg_hook_callback = 0;
bool int2fhook_menu_callback(DOSBoxMenu * const xmenu, DOSBoxMenu::item * const menuitem) {
(void)menuitem;
(void)xmenu;
#if C_DEBUG
if (int2fdbg_hook_callback == 0) {
void Int2fhook();
Int2fhook();
systemmessagebox("Success", "The INT 2Fh hook has been successfully set.", "ok","info", 1);
} else
systemmessagebox("Warning", "The INT 2Fh hook was already set up.", "ok","warning", 1);
#endif
return true;
}
bool showdetails_menu_callback(DOSBoxMenu * const xmenu, DOSBoxMenu::item * const menuitem) {
(void)xmenu;//UNUSED
(void)menuitem;//UNUSED
@ -13210,6 +13239,8 @@ int main(int argc, char* argv[]) SDL_MAIN_NOEXCEPT {
{
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"debug_blankrefreshtest").set_text("Refresh test (blank display)").set_callback_function(refreshtest_menu_callback);
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"debug_generatenmi").set_text("Generate NMI interrupt").set_callback_function(generatenmi_menu_callback);
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"debug_int2fhook").set_text("Hook INT 2Fh calls").set_callback_function(int2fhook_menu_callback);
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"debug_logint21").set_text("Log INT 21h calls").
set_callback_function(dos_debug_menu_callback);
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"debug_logfileio").set_text("Log file I/O").

View File

@ -271,8 +271,7 @@ __do_command_begin:
}
#if C_DEBUG
Bitu int2fdbg_hook_callback = 0;
extern Bitu int2fdbg_hook_callback;
static Bitu INT2FDBG_Handler(void) {
if (reg_ax == 0x1605) { /* Windows init broadcast */
int patience = 500;
@ -347,6 +346,35 @@ static Bitu INT2FDBG_Handler(void) {
return CBRET_NONE;
}
void Int2fhook() {
uint32_t old_int2Fh;
PhysPt w;
int2fdbg_hook_callback = CALLBACK_Allocate();
CALLBACK_Setup(int2fdbg_hook_callback,&INT2FDBG_Handler,CB_IRET,"INT 2Fh DBG callback");
/* record old vector, set our new vector */
old_int2Fh = RealGetVec(0x2f);
w = CALLBACK_PhysPointer(int2fdbg_hook_callback);
RealSetVec(0x2f,CALLBACK_RealPointer(int2fdbg_hook_callback));
/* overwrite the callback with code to chain the call down, then invoke our callback on the way back up: */
/* first, chain to the previous INT 15h handler */
phys_writeb(w++,(uint8_t)0x9C); //PUSHF
phys_writeb(w++,(uint8_t)0x9A); //CALL FAR <address>
phys_writew(w,(uint16_t)(old_int2Fh&0xFFFF)); w += 2; //offset
phys_writew(w,(uint16_t)((old_int2Fh>>16)&0xFFFF)); w += 2; //seg
/* then, having returned from it, invoke our callback */
phys_writeb(w++,(uint8_t)0xFE); //GRP 4
phys_writeb(w++,(uint8_t)0x38); //Extra Callback instruction
phys_writew(w,(uint16_t)int2fdbg_hook_callback); w += 2; //The immediate word
/* return */
phys_writeb(w++,(uint8_t)0xCF); //IRET
}
/* NTS: I know I could just modify the DOS kernel's INT 2Fh code to receive the init call,
* the problem is that at that point, the registers do not yet contain anything interesting.
* all the interesting results of the call are added by TSRs on the way back UP the call
@ -360,41 +388,12 @@ void DOS_Shell::CMD_INT2FDBG(char * args) {
/* TODO: Allow /U to remove INT 2Fh hook */
if (ScanCMDBool(args,"I")) {
if (int2fdbg_hook_callback == 0) {
uint32_t old_int2Fh;
PhysPt w;
int2fdbg_hook_callback = CALLBACK_Allocate();
CALLBACK_Setup(int2fdbg_hook_callback,&INT2FDBG_Handler,CB_IRET,"INT 2Fh DBG callback");
/* record old vector, set our new vector */
old_int2Fh = RealGetVec(0x2f);
w = CALLBACK_PhysPointer(int2fdbg_hook_callback);
RealSetVec(0x2f,CALLBACK_RealPointer(int2fdbg_hook_callback));
/* overwrite the callback with code to chain the call down, then invoke our callback on the way back up: */
/* first, chain to the previous INT 15h handler */
phys_writeb(w++,(uint8_t)0x9C); //PUSHF
phys_writeb(w++,(uint8_t)0x9A); //CALL FAR <address>
phys_writew(w,(uint16_t)(old_int2Fh&0xFFFF)); w += 2; //offset
phys_writew(w,(uint16_t)((old_int2Fh>>16)&0xFFFF)); w += 2; //seg
/* then, having returned from it, invoke our callback */
phys_writeb(w++,(uint8_t)0xFE); //GRP 4
phys_writeb(w++,(uint8_t)0x38); //Extra Callback instruction
phys_writew(w,(uint16_t)int2fdbg_hook_callback); w += 2; //The immediate word
/* return */
phys_writeb(w++,(uint8_t)0xCF); //IRET
Int2fhook();
LOG_MSG("INT 2Fh debugging hook set\n");
WriteOut("INT 2Fh hook set\n");
}
else {
WriteOut("INT 2Fh hook already setup\n");
}
}
else if (*args)
WriteOut("INT 2Fh hook has been set.\n");
} else
WriteOut("INT 2Fh hook was already set up.\n");
} else if (*args)
WriteOut("Invalid parameter - %s\n", args);
}
#endif
@ -3969,7 +3968,7 @@ void DOS_Shell::CMD_COUNTRY(char * args) {
}
#if defined(USE_TTF)
int setTTFCodePage();
int setTTFCodePage(void);
void toSetCodePage(DOS_Shell *shell, int newCP) {
if (newCP == 437 || newCP == 808 || newCP == 850 || newCP == 852 || newCP == 853 || newCP == 855 || newCP == 857 || newCP == 858 || (newCP >= 860 && newCP <= 866) || newCP == 869 || newCP == 872 || newCP == 874) {
dos.loaded_codepage = newCP;