pureikyubu/SRC/Debugger/console.cpp
ogamespec ab8396e2b3 cpuview switched to new disasm
- Fixed rlw instructions (Rc bit)
2020-04-23 23:54:14 +03:00

224 lines
4.9 KiB
C++

// console init code.
//
// recommended console font size is 6x9.
#include "pch.h"
// all console important variables are here
CONControl con;
// ---------------------------------------------------------------------------
static BOOL CALLBACK WndEnumProc(HWND hWnd, LPARAM lpParam)
{
TCHAR szClassName[1024];
DWORD dwPid = 0;
ZeroMemory(szClassName, sizeof(szClassName));
if(!GetClassName(hWnd, szClassName, sizeof(szClassName))) return TRUE;
if(lstrcmp(szClassName, TEXT("tty")) != 0) return TRUE;
GetWindowThreadProcessId(hWnd, &dwPid);
if(dwPid == GetCurrentProcessId())
{
*(HWND*)lpParam = hWnd;
return FALSE;
}
return TRUE;
}
static HWND MyGetConsoleWindow(void)
{
HWND hwnd = NULL;
EnumWindows((WNDENUMPROC)WndEnumProc, (LPARAM)&hwnd);
return hwnd;
}
void con_open()
{
DWORD flags;
COORD coord;
SMALL_RECT rect;
RECT wndrect;
if(con.active) return;
// clear internal structures
memset(&roll, 0, sizeof(ROLLControl));
memset(&wind, 0, sizeof(WINDControl));
memset(con.buf, 0, sizeof(con.buf));
cmd_init_handlers();
// prepare console structures
con_set_autoscroll(TRUE);
roll.rollpos = con_wraproll(0, -1);
con_memorize_cpu_regs();
wind.full = 0;
wind.visible |= CON_UPDATE_ALL;
wind.focus = WCONSOLE;
wind.regs_h = 17;
wind.data_h = 8;
wind.disa_h = 28;
wind.disa_sub_h = 0;
con_recalc_wnds();
con.data = 0x80000000;
con.text = Gekko::Gekko->regs.pc;
con_set_disa_cur(con.text);
strcpy_s (con.logfile, sizeof(con.logfile), CON_LOG_FILE);
// create console
AllocConsole();
con.hwnd = MyGetConsoleWindow();
// get input/ouput handles
con.input = GetStdHandle(STD_INPUT_HANDLE);
assert(con.input != INVALID_HANDLE_VALUE);
con.output = GetStdHandle(STD_OUTPUT_HANDLE);
assert(con.output != INVALID_HANDLE_VALUE);
// setup console window
GetConsoleCursorInfo(con.output, &con.curinfo);
GetConsoleMode(con.input, &flags);
flags &= ~ENABLE_MOUSE_INPUT;
SetConsoleMode(con.input, flags);
rect.Top = rect.Left = 0;
rect.Right = CON_WIDTH - 1;
rect.Bottom = CON_HEIGHT - 1;
coord.X = CON_WIDTH;
coord.Y = CON_HEIGHT;
SetConsoleWindowInfo(con.output, TRUE, &rect);
SetConsoleScreenBufferSize(con.output, coord);
// change window layout
if(con.hwnd)
while(1)
{
GetWindowRect(con.hwnd, &wndrect);
if(wndrect.right >= GetSystemMetrics(SM_CXSCREEN)) break;
SetWindowPos(
con.hwnd,
HWND_TOP,
GetSystemMetrics(SM_CXSCREEN) - (wndrect.right - wndrect.left),
0, 0, 0, SWP_NOSIZE);
}
SetConsoleTitleA("Dolwin Debug Console");
con.active = TRUE;
con.update |= CON_UPDATE_ALL;
DBReport("Debugger is running. Type help for quick reference.\n");
con_refresh();
}
void con_close()
{
if(!con.active) return;
con.cmds.clear();
// clear NOP history
if(con.nopHist)
{
free(con.nopHist);
con.nopHist = NULL;
con.nopNum = 0;
}
// close console
// Don't touch console handles, they can be used by Visual Studio or by other parasites.
FreeConsole();
// close log file
if(con.logf)
{
fclose(con.logf);
con.logf = NULL;
}
con.active = FALSE;
}
static void dummy(const char* text, ...) {}
static void dummy2(DbgChannel chan, const char* text, ...) {}
void con_start()
{
uint32_t main = SYMAddress("main");
if(main) con_set_disa_cur(main);
else con_set_disa_cur(Gekko::Gekko->regs.pc);
con.update = CON_UPDATE_ALL;
con_refresh();
while (!con.exitPending)
{
con_read_input(1);
con_refresh();
Sleep(10);
}
con_close();
DBHalt = dummy;
DBReport = dummy;
DBReport2 = dummy2;
con.exitPending = false;
}
void con_break(const char *reason)
{
if(reason) con_print(ConColor::GREEN, "\ndebugger breaks%s. press F5 to continue.\n", reason);
if (Gekko::Gekko) Gekko::Gekko->Suspend();
con_set_disa_cur(Gekko::Gekko->regs.pc);
}
void con_command(std::vector<std::string>& args, int lnum)
{
// Poke Jdi
if (Debug::Hub.CommandExists(args))
{
Json::Value * output = Debug::Hub.Execute(args);
if (output != nullptr)
{
delete output;
}
return;
}
// Legacy commands (will be migrated to Jdi afterwards)
auto it = con.cmds.find(args[0]);
if (it != con.cmds.end())
{
it->second(args);
}
else
{
if (lnum) con_print(ConColor::NORM, "unknown script command in line %i, see \'help\'", lnum);
else con_print(ConColor::NORM, "unknown command, try \'help\'");
}
}
// execution
// step into instruction
void con_step_into()
{
if (Gekko::Gekko)
{
Gekko::Gekko->Step();
con.text = Gekko::Gekko->regs.pc - 4 * wind.disa_h / 2 + 4;
con.update |= CON_UPDATE_ALL;
}
}