mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
228 lines
6.1 KiB
C++
228 lines
6.1 KiB
C++
// cpu view (disassembly)
|
|
#include "pch.h"
|
|
|
|
static int con_disa_line(int line, uint32_t opcode, uint32_t addr)
|
|
{
|
|
int bg, fg, bgcur, bgbp;
|
|
char *symbol;
|
|
int addend = 1;
|
|
|
|
bgcur = (addr == con.disa_cursor) ? (8) : (0);
|
|
bgbp = (Gekko::Gekko->IsBreakpoint(addr)) ? (4) : (0);
|
|
bg = (addr == Gekko::Gekko->regs.pc) ? (1) : (0);
|
|
bg = bg ^ bgcur ^ bgbp;
|
|
fg = 7;
|
|
con_attr(fg, bg);
|
|
|
|
con_clear_line(line, con.attr);
|
|
|
|
symbol = SYMName(addr);
|
|
if(symbol)
|
|
{
|
|
con_printf_at(0, line, "\x1%c%s\n", ConColor::GREEN, symbol);
|
|
line++;
|
|
addend++;
|
|
|
|
con_clear_line(line, con.attr);
|
|
}
|
|
|
|
if(opcode == 1 /* no memory */)
|
|
{
|
|
con_printf_at( 0, line, "\x1%c%08X ", ConColor::NORM, addr);
|
|
con_printf_at(10, line, "\x1%c%08X ", ConColor::CYAN, 0);
|
|
con_printf_at(20, line, "\x1%c???", ConColor::NORM);
|
|
return addend;
|
|
}
|
|
|
|
Gekko::AnalyzeInfo info = { 0 };
|
|
|
|
Gekko::Analyzer::Analyze(addr, opcode, &info);
|
|
|
|
std::string text = Gekko::GekkoDisasm::Disasm(addr, &info);
|
|
|
|
if(info.flow && info.Imm.Address != 0)
|
|
{
|
|
const char* dir;
|
|
|
|
if (info.Imm.Address > addr) dir = " \x19";
|
|
else if (info.Imm.Address < addr) dir = " \x18";
|
|
else dir = " \x1b";
|
|
|
|
con_printf_at(0, line, "\x1%c%s\x1%c%s",
|
|
ConColor::GREEN, text.c_str(), ConColor::CYAN, dir);
|
|
|
|
symbol = SYMName(info.Imm.Address);
|
|
if(symbol)
|
|
{
|
|
con_printf_at(47, line, "\x1%c ; %s", ConColor::BROWN, symbol);
|
|
}
|
|
}
|
|
|
|
else con_printf_at(0, line, "\x1%c%s", ConColor::NORM, text.c_str());
|
|
|
|
if (text[0] == 'r' && text[1] == 'l')
|
|
{
|
|
int mb = info.paramBits[3];
|
|
int me = info.paramBits[4];
|
|
uint32_t mask = ((uint32_t)-1 >> mb) ^ ((me >= 31) ? 0 : ((uint32_t)-1) >> (me + 1));
|
|
|
|
con_printf_at (60, line, "\x1%cmask:0x%08X", ConColor::NORM, mask);
|
|
}
|
|
|
|
return addend;
|
|
}
|
|
|
|
void con_update_disa_window()
|
|
{
|
|
uint32_t pa = Gekko::BadAddress;
|
|
if (Gekko::Gekko)
|
|
{
|
|
int WIMG;
|
|
pa = Gekko::Gekko->EffectiveToPhysical(con.disa_cursor, Gekko::MmuAccess::Execute, WIMG);
|
|
}
|
|
|
|
con_attr(0, 3);
|
|
con_fill_line(wind.disa_y, 0xc4);
|
|
if(wind.focus == WDISA) con_printf_at(0, wind.disa_y, "\x1%c\x1f", ConColor::WHITE);
|
|
con_attr(0, 3);
|
|
con_print_at(2, wind.disa_y, "F3");
|
|
con_printf_at(
|
|
6, wind.disa_y,
|
|
" cursor:%08X phys:%08X pc:%08X",
|
|
pa, Gekko::Gekko->regs.pc);
|
|
con_attr(7, 0);
|
|
|
|
uint32_t op, addr = con.text & ~3;
|
|
wind.disa_sub_h = 0;
|
|
|
|
for(int line=wind.disa_y+1; line<wind.disa_y+wind.disa_h; line++, addr+=4)
|
|
{
|
|
op = 0;
|
|
|
|
if (Gekko::Gekko)
|
|
{
|
|
int WIMG;
|
|
pa = Gekko::Gekko->EffectiveToPhysical(addr, Gekko::MmuAccess::Execute, WIMG);
|
|
if (pa != Gekko::BadAddress)
|
|
{
|
|
MIReadWord(pa, &op);
|
|
}
|
|
}
|
|
|
|
int n = con_disa_line(line, op, addr);
|
|
if(n > 1) wind.disa_sub_h += n - 1;
|
|
line += n - 1;
|
|
}
|
|
}
|
|
|
|
static BOOL disa_cur_visible()
|
|
{
|
|
DWORD limit;
|
|
limit = con.text + (wind.disa_h - 1) * 4;
|
|
return ((con.disa_cursor < limit) && (con.disa_cursor >= con.text));
|
|
}
|
|
|
|
static void disa_goto(uint32_t addr)
|
|
{
|
|
if(wind.disa_nav_last < 256)
|
|
{
|
|
wind.disa_nav_hist[++wind.disa_nav_last] = con.disa_cursor;
|
|
con.text = addr - 4 * wind.disa_h / 2 + 4;
|
|
con.disa_cursor = addr;
|
|
con.update |= CON_UPDATE_DISA;
|
|
}
|
|
}
|
|
|
|
static void disa_return()
|
|
{
|
|
if(wind.disa_nav_last > 0)
|
|
{
|
|
con.disa_cursor = con.text = wind.disa_nav_hist[wind.disa_nav_last--];
|
|
con.text -= 4 * wind.disa_h / 2;
|
|
con.update |= CON_UPDATE_DISA;
|
|
}
|
|
}
|
|
|
|
static void disa_navigate()
|
|
{
|
|
uint32_t op = 0, addr = con.disa_cursor;
|
|
|
|
uint32_t pa = Gekko::BadAddress;
|
|
if (Gekko::Gekko)
|
|
{
|
|
int WIMG;
|
|
pa = Gekko::Gekko->EffectiveToPhysical(addr, Gekko::MmuAccess::Execute, WIMG);
|
|
}
|
|
if (pa != Gekko::BadAddress)
|
|
{
|
|
MIReadWord(pa, &op);
|
|
}
|
|
if(op == 0) return;
|
|
|
|
Gekko::AnalyzeInfo info = { 0 };
|
|
|
|
Gekko::Analyzer::Analyze(addr, op, &info);
|
|
|
|
std::string text = Gekko::GekkoDisasm::Disasm(addr, &info);
|
|
|
|
if(info.flow && info.Imm.Address != 0) disa_goto(info.Imm.Address);
|
|
}
|
|
|
|
void con_disa_key(char ascii, int vkey, int ctrl)
|
|
{
|
|
UNREFERENCED_PARAMETER(ascii);
|
|
UNREFERENCED_PARAMETER(ctrl);
|
|
|
|
switch(vkey)
|
|
{
|
|
case VK_HOME:
|
|
con_set_disa_cur(con.disa_cursor);
|
|
break;
|
|
case VK_END:
|
|
break;
|
|
case VK_UP:
|
|
if(con.disa_cursor < con.text)
|
|
{
|
|
con.disa_cursor = con.text;
|
|
break;
|
|
}
|
|
if(con.disa_cursor >= (con.text + 4 * wind.disa_h - 4))
|
|
{
|
|
con.disa_cursor = con.text + 4 * wind.disa_h - 8;
|
|
break;
|
|
}
|
|
con.disa_cursor -= 4;
|
|
if(con.disa_cursor < con.text) con.text -= 4;
|
|
break;
|
|
case VK_DOWN:
|
|
if(con.disa_cursor < con.text)
|
|
{
|
|
con.disa_cursor = con.text;
|
|
break;
|
|
}
|
|
if(con.disa_cursor >= (con.text + 4 * (wind.disa_h - wind.disa_sub_h) - 4))
|
|
{
|
|
con.disa_cursor = con.text + 4 * (wind.disa_h - wind.disa_sub_h) - 8;
|
|
break;
|
|
}
|
|
con.disa_cursor += 4;
|
|
if(con.disa_cursor >= (con.text + ((wind.disa_h - wind.disa_sub_h) - 1) * 4)) con.text += 4;
|
|
break;
|
|
case VK_PRIOR:
|
|
con.text -= 4 * wind.disa_h - 4;
|
|
if(!disa_cur_visible()) con.disa_cursor = con.text;
|
|
break;
|
|
case VK_NEXT:
|
|
con.text += 4 * (wind.disa_h - wind.disa_sub_h) - 4;
|
|
if(!disa_cur_visible()) con.disa_cursor = con.text + ((wind.disa_h - wind.disa_sub_h) - 2) * 4;
|
|
break;
|
|
case VK_RETURN:
|
|
disa_navigate(); // browse functions
|
|
break;
|
|
case VK_ESCAPE:
|
|
disa_return();
|
|
break;
|
|
}
|
|
|
|
con.update |= CON_UPDATE_DISA;
|
|
}
|