Apollo64/source/R4K Debugger.cpp

557 lines
No EOL
22 KiB
C++

/**************************************************************************
* *
* Copyright (C) 2000, Eclipse Productions *
* *
* Offical Source code of the Apollo Project. DO NOT DISTRIBUTE! Any *
* unauthorized distribution of these files in any way, shape, or form *
* is a direct infringement on the copyrights entitled to Eclipse *
* Productions and you will be prosecuted to the fullest extent of *
* the law. Have a nice day... ^_^ *
* *
*************************************************************************/
/**************************************************************************
*
* Revision History:
* Date: Comment:
* -----------------------------------------------------------------------
* 06-20-00 Initial Version (Andrew)
*
**************************************************************************/
/**************************************************************************
*
* Notes:
*
*
**************************************************************************/
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h> // For status window
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <math.h>
#include "WinMain.h"
#include "EmuMain.h"
#include "CpuMain.h"
#include "resource.h"
#define RD() ((opcode & 0xffff) >> 11)
#define RT() ((opcode >> 16) & 0x1f)
#define RS() ((opcode >> 21) & 0x1f)
#define SA() ((opcode >> 6) & 0x1f)
#undef opcode
void Fetch( char* buffer, unsigned int opcode, unsigned int location, char fmt );
HWND DebuggerHwnd = NULL;
u32 DebuggerLocation = 0x80000040;
s_sop dop;
/*
void (*r4300i[0x40])() = {
opSPECIAL, opREGIMM, opJ, opJAL, opBEQ, opBNE, opBLEZ, opBGTZ,
opADDI, opADDIU, opSLTI, opSLTIU, opANDI, opORI, opXORI, opLUI,
opCOP0, opCOP1, opCOP2, opNI, opBEQL, opBNEL, opBLEZL,opBGTZL,
opDADDI, opDADDIU, opLDL, opLDR, opNI, opNI, opNI, opNI,
opLB, opLH, opLWL, opLW, opLBU, opLHU, opLWR, opLWU,
opSB, opSH, opSWL, opSW, opSDL, opSDR, opSWR, opCACHE,
opLL, opLWC1, opLWC2, opNI, opLLD, opLDC1, opLDC2, opLD,
opSC, opSWC1, opSWC2, opNI, opSCD, opSDC1, opSDC2, opSD
};
void (*special[0x40])() = {
opSLL, opNI, opSRL, opSRA, opSLLV, opNI, opSRLV, opSRAV,
opJR, opJALR, opNI, opNI, opSYSCALL, opBREAK, opNI, opSYNC,
opMFHI, opMTHI, opMFLO, opMTLO, opDSLLV, opNI, opDSRLV, opDSRAV,
opMULT, opMULTU, opDIV, opDIVU, opDMULT, opDMULTU, opDDIV, opDDIVU,
opADD, opADDU, opSUB, opSUBU, opAND, opOR, opXOR, opNOR,
opNI, opNI, opSLT, opSLTU, opDADD, opDADDU, opDSUB, opDSUBU,
opTGE, opTGEU, opTLT, opTLTU, opTEQ, opNI, opTNE, opNI,
opDSLL, opNI, opDSRL, opDSRA, opDSLL32, opNI, opDSRL32, opDSRA32
};
void (*regimm[0x20])() = {
opBLTZ, opBGEZ, opBLTZL, opBGEZL, opNI, opNI, opNI, opNI,
opTGEI, opTGEIU, opTLTI, opTLTIU, opTEQI, opNI, opTNEI, opNI,
opBLTZAL, opBGEZAL, opBLTZALL, opBGEZALL, opNI, opNI, opNI, opNI,
opNI, opNI, opNI, opNI, opNI, opNI, opNI, opNI,
};
*/
char *r4kreg[0x20] = {
"R0", "AT", "V0", "V1", "A0", "A1", "A2", "A3", "T0", "T1", "T2",
"T3", "T4", "T5", "T6", "T7", "S0", "S1", "S2", "S3", "S4", "S5",
"S6", "S7", "T8", "T9", "K0", "K1", "GP", "SP", "S8", "RA"
};
char *mmuregs[0x20] = {
"Index", "Random", "EntryLo0", "EntryLo1", "Context", "PageMask", "Wired",
"RESERVED", "BadVAddr", "Count", "EntryHi", "Compare", "Status", "Cause",
"ExceptPC", "PRevID", "Config", "LLAddr", "WatchLo", "WatchHi", "XContext", "RESERVED",
"RESERVED", "RESERVED", "RESERVED", "RESERVED", "PErr", "CacheErr", "TagLo",
"TagHi", "ErrorEPC", "RESERVED"
};
void COP0Lookup (char *out) {
switch (dop.rs) {
case 0x00: sprintf (out, "MFC0 %s, %s", r4kreg[dop.rt], mmuregs[dop.rd]); break;
case 0x04: sprintf (out, "MTC0 %s, %s", r4kreg[dop.rt], mmuregs[dop.rd]); break;
case 0x10: // Special
switch (dop.func) {
case 0x01: sprintf (out, "TLBR"); break;
case 0x02: sprintf (out, "TLBWI"); break;
case 0x06: sprintf (out, "TLBWR"); break;
case 0x08: sprintf (out, "TLBP"); break;
case 0x18: sprintf (out, "ERET"); break;
default: sprintf (out, "UKNWN %08X", ((u32 *)&dop)[0]);
} break;
default: sprintf (out, "CUKNWN %08X", ((u32 *)&dop)[0]);
}
}
void COP1Lookup () {
}
void REGIMMLookup (char *out, u32 addy) {
switch (dop.rt) {
case 0x00: sprintf (out, "BLTZ %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x01: sprintf (out, "BGEZ %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x02: sprintf (out, "BLTZL %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x03: sprintf (out, "BGEZL %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x08: sprintf (out, "TGEI %s, 0x%08X", r4kreg[dop.rs], (((u16 *)&dop)[0]<<2)); break;
case 0x09: sprintf (out, "TGEIU %s, 0x%08X", r4kreg[dop.rs], (((u16 *)&dop)[0]<<2)); break;
case 0x0A: sprintf (out, "TLTI %s, 0x%08X", r4kreg[dop.rs], (((u16 *)&dop)[0]<<2)); break;
case 0x0B: sprintf (out, "TLTIU %s, 0x%08X", r4kreg[dop.rs], (((u16 *)&dop)[0]<<2)); break;
case 0x0C: sprintf (out, "TEQI %s, 0x%08X", r4kreg[dop.rs], (((u16 *)&dop)[0]<<2)); break;
case 0x0E: sprintf (out, "TNEI %s, 0x%08X", r4kreg[dop.rs], (((u16 *)&dop)[0]<<2)); break;
case 0x10: sprintf (out, "BLTZAL %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x11: if (dop.rs) sprintf (out, "BGEZAL %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2));
else sprintf (out, "BAL 0x%08X", addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x12: sprintf (out, "BLTZALL %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x13: sprintf (out, "BGEZALL %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2)); break;
default:
sprintf (out, "***REGIMM %08X***", dop.rt); break;
}
}
/*
void (*special[0x40])() = {
opSLL, opNI, opSRL, opSRA, opSLLV, opNI, opSRLV, opSRAV,
opJR, opJALR, opNI, opNI, opSYSCALL, opBREAK, opNI, opSYNC,
opMFHI, opMTHI, opMFLO, opMTLO, opDSLLV, opNI, opDSRLV, opDSRAV,
opMULT, opMULTU, opDIV, opDIVU, opDMULT, opDMULTU, opDDIV, opDDIVU,
opADD, opADDU, opSUB, opSUBU, opAND, opOR, opXOR, opNOR,
opNI, opNI, opSLT, opSLTU, opDADD, opDADDU, opDSUB, opDSUBU,
opTGE, opTGEU, opTLT, opTLTU, opTEQ, opNI, opTNE, opNI,
opDSLL, opNI, opDSRL, opDSRA, opDSLL32, opNI, opDSRL32, opDSRA32
};
*/
void SPECIALLookup (char *out) {
switch (dop.func) {
case 0x00: if (((u32*)&dop)[0] == 0) sprintf (out, "NOP");
else sprintf (out, "SLL %s, %s, 0x%X", r4kreg[dop.rd], r4kreg[dop.rt], dop.sa); break;
case 0x01: sprintf (out, "Unknown %08X", ((u32 *)&dop)[0]); break;
case 0x02: sprintf (out, "SRL %s, %s, 0x%X", r4kreg[dop.rd], r4kreg[dop.rt], dop.sa); break;
case 0x03: sprintf (out, "SRA %s, %s, 0x%X", r4kreg[dop.rd], r4kreg[dop.rt], dop.sa); break;
case 0x04: sprintf (out, "SLLV %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rt], r4kreg[dop.rs]); break;
case 0x06: sprintf (out, "SRLV %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rt], r4kreg[dop.rs]); break;
case 0x07: sprintf (out, "SRAV %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rt], r4kreg[dop.rs]); break;
case 0x08: sprintf (out, "JR %s", r4kreg[dop.rs]); break;
case 0x09: if (dop.rd == 31) sprintf (out, "JALR %s", r4kreg[dop.rs]);
else sprintf (out, "JALR %s, %s", r4kreg[dop.rd], r4kreg[dop.rs]); break;
case 0x0C: sprintf (out, "SYSCALL ????"); break;
case 0x0D: sprintf (out, "BREAK ????"); break;
case 0x0F: sprintf (out, "SYNC ????"); break;
case 0x10: sprintf (out, "MFHI %s", r4kreg[dop.rd]); break;
case 0x11: sprintf (out, "MTHI %s", r4kreg[dop.rd]); break;
case 0x12: sprintf (out, "MFLO %s", r4kreg[dop.rd]); break;
case 0x13: sprintf (out, "MTLO %s", r4kreg[dop.rd]); break;
case 0x18: sprintf (out, "MULT %s, %s", r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x19: sprintf (out, "MULTU %s, %s", r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x1A: sprintf (out, "DIV %s, %s", r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x1B: sprintf (out, "DIVU %s, %s", r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x1C: sprintf (out, "DMULT %s, %s", r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x1F: sprintf (out, "DDIVU %s, %s", r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x20: sprintf (out, "ADD %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x21: sprintf (out, "ADDU %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x22: sprintf (out, "SUB %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x23: sprintf (out, "SUBU %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x24: sprintf (out, "AND %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x25: sprintf (out, "OR %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x26: sprintf (out, "XOR %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x2A: sprintf (out, "SLT %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x2B: sprintf (out, "SLTU %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x2D: sprintf (out, "DADDU %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x38: sprintf (out, "DSLL %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x3C: sprintf (out, "DSLL32 %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
case 0x3F: sprintf (out, "DSRA32 %s, %s, %s", r4kreg[dop.rd], r4kreg[dop.rs], r4kreg[dop.rt]); break;
default: sprintf (out, "***SPECIAL %08X***", dop.func);
}
}
/*
A4000898 r4300 00000014
A40004E8 r4300 00000015
A40009D0 r4300 00000024
A400098C r4300 00000028
A40003F8 r4300 0000002F*/
//bool FindHLEFunc(u32 addy, char *func);
void OpcodeLookup (DWORD addy, char *out) {
char func[100];
if (TLBLUT[addy >> 12] == 0xFFFFFFFF) {
strcpy (out, "TLB Miss");
return;
}
if (TLBLUT[addy >> 12] == 0xFFFFFFFE) {
strcpy (out, "TLB Invalid");
return;
}
((u32*)&dop)[0] = vr32(addy);
switch (dop.op) {
case 0x00: SPECIALLookup (out); break;
case 0x01: REGIMMLookup (out, addy); break;
case 0x02: sprintf (out, "J %08X", ((addy+4) & 0xf0000000) + (((((u32 *)&dop)[0] << 2) & 0x0fffffff))); break;
case 0x03: //if (FindHLEFunc(((addy+4) & 0xf0000000) + (((((u32 *)&dop)[0] << 2) & 0x0fffffff)), func) == false)
sprintf (out, "JAL %08X", ((addy+4) & 0xf0000000) + (((((u32 *)&dop)[0] << 2) & 0x0fffffff)));
//else
// sprintf (out, "JAL %s(%08X)", func, ((addy+4) & 0xf0000000) + (((((u32 *)&dop)[0] << 2) & 0x0fffffff)));
//break;
case 0x04: if (dop.rt) sprintf (out, "BEQ %s, %s, 0x%08X", r4kreg[dop.rs], r4kreg[dop.rt], addy+4+(((s16 *)&dop)[0]<<2));
else if (dop.rs) sprintf (out, "BEQZ %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2));
else sprintf (out, "B 0x%08X", addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x05: if (dop.rt) sprintf (out, "BNE %s, %s, 0x%08X", r4kreg[dop.rs], r4kreg[dop.rt], addy+4+(((s16 *)&dop)[0]<<2));
else sprintf (out, "BNEZ %s, %08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x06: sprintf (out, "BLEZ %s, %s, 0x%08X", r4kreg[dop.rs], r4kreg[dop.rt], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x07: sprintf (out, "BGTZ %s, %s, 0x%08X", r4kreg[dop.rs], r4kreg[dop.rt], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x08: sprintf (out, "ADDI %s, %s, 0x%04X", r4kreg[dop.rt], r4kreg[dop.rs], ((u16 *)&dop)[0]); break;
case 0x09: sprintf (out, "ADDIU %s, %s, 0x%04X", r4kreg[dop.rt], r4kreg[dop.rs], ((u16 *)&dop)[0]); break;
case 0x0A: sprintf (out, "SLTI %s, %s, 0x%04X", r4kreg[dop.rt], r4kreg[dop.rs], ((u16 *)&dop)[0]); break;
case 0x0B: sprintf (out, "SLTIU %s, %s, 0x%04X", r4kreg[dop.rt], r4kreg[dop.rs], ((u16 *)&dop)[0]); break;
case 0x0C: sprintf (out, "ANDI %s, %s, 0x%04X", r4kreg[dop.rt], r4kreg[dop.rs], ((u16 *)&dop)[0]); break;
case 0x0D: sprintf (out, "ORI %s, %s, 0x%04X", r4kreg[dop.rt], r4kreg[dop.rs], ((u16 *)&dop)[0]); break;
case 0x0E: sprintf (out, "XORI %s, %s, 0x%04X", r4kreg[dop.rt], r4kreg[dop.rs], ((u16 *)&dop)[0]); break;
case 0x0F: sprintf (out, "LUI %s, 0x%04X", r4kreg[dop.rt], ((u16 *)&dop)[0]); break;
case 0x10: COP0Lookup (out); break;
case 0x11: sprintf (out, "COP1 %08X", dop.rs); break;
case 0x14: if (dop.rt) sprintf (out, "BEQL %s, %s, 0x%08X", r4kreg[dop.rs], r4kreg[dop.rt], addy+4+(((s16 *)&dop)[0]<<2));
else sprintf (out, "BEQZL %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x15: if (dop.rt) sprintf (out, "BNEL %s, %s, 0x%08X", r4kreg[dop.rs], r4kreg[dop.rt], addy+4+(((s16 *)&dop)[0]<<2));
else sprintf (out, "BNEZL %s, 0x%08X", r4kreg[dop.rs], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x16: sprintf (out, "BLEZL %s, %s, 0x%08X", r4kreg[dop.rs], r4kreg[dop.rt], addy+4+(((s16 *)&dop)[0]<<2)); break;
case 0x20: sprintf (out, "LB %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
case 0x21: sprintf (out, "LH %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
// 22 - LWL
case 0x23: sprintf (out, "LW %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
case 0x24: sprintf (out, "LBU %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
case 0x25: sprintf (out, "LHU %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
// 26 - LWR
case 0x27: sprintf (out, "LWU %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
case 0x28: sprintf (out, "SB %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
case 0x29: sprintf (out, "SH %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
// 2A - SWL
case 0x2B: sprintf (out, "SW %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
// 2C - SDL
// 2D - SDR
// 2E - SWR
case 0x2F: sprintf (out, "CACHE %X, 0x%04X(%s)", dop.rt, ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
// 30 - LL
case 0x31: sprintf (out, "LWC1 COP1[%i], 0x%04X(%s)", dop.rt, ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
// 32 - LWC2
// 34 - LLD
// 35 - LDC1
// 36 - LDC2
// 37 - LD
case 0x37: sprintf (out, "LD %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
// 38 - SC
// 39 - SWC1
// 3A - SWC2
// 3C - SCD
// 3D - SDC1
// 3E - SDC2
// 3F - SD
case 0x3F: sprintf (out, "SD %s, 0x%04X(%s)", r4kreg[dop.rt], ((u16 *)&dop)[0], r4kreg[dop.rs]); break;
default:
sprintf (out, "***r4300 %08X***", dop.op);
}
}
void DisassembleRange (u32 Start, u32 End) {
FILE *disasm = fopen ("d:\\disasm.txt", "wt");
char buffer[0x100];
char tbuff[50];
u32 pcx = Start;
u32 tmp;
while (pcx != End) {
OpcodeLookup(pcx, buffer);
/*tmp = strlen (buffer);
memset (tbuff, 32, 35-tmp);
tbuff[35-tmp] = 0;
strcat (buffer, tbuff);
*/
fprintf (disasm, "%08X %s %08X\n", pcx, buffer, vr32(pcx));
pcx += 4;
}
fclose (disasm);
}
/*
bool InitializeDebugger(void) {
if (DebuggerHwnd!=0) return false;
DebuggerHwnd = CreateDialog(GhInst,MAKEINTRESOURCE(IDD_DEBUGME),
GhWnd,(DLGPROC)Debugger);
ShowWindow(DebuggerHwnd,SW_SHOW);
return (DebuggerHwnd !=0);
}
#define TYPER4K 0
#define TYPEMMU 1
#define TYPEFPU 2
#define TYPERSP 3
#define TYPEMI 4
#define TYPEPI 5
#define TYPESP 6
#define TYPEDP 7
#define TYPEAI 8
#define TYPERAM 9
#define TYPERI 10
#define TYPEVI 11
#define TYPESI 12
#define R4KCPU 0
#define RSPCPU 1
char *lpszREGTYPES[13] = {"R4K", "MMU", "FPU", "RSP", "MI", "PI", "SP",
"DP", "AI", "RAM", "RI", "VI", "SI"};
*/
char *R4KRegNames[0x20] = {
"R0", "AT", "V0", "V1", "A0", "A1", "A2", "A3", "T0", "T1", "T2",
"T3", "T4", "T5", "T6", "T7", "S0", "S1", "S2", "S3", "S4", "S5",
"S6", "S7", "T8", "T9", "K0", "K1", "GP", "SP", "S8", "RA"
};
/*
static int iCurrentCPU = 0;
static int iCurrentREG = 0;
void UpdateRegisters (HWND hWnd, int REGType) {
LVCOLUMN lvColumn;
char buffer [20];
int x;
LVITEM lvItem;
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGS),LVM_DELETEALLITEMS, 0, 0);
ZeroMemory (&lvColumn, sizeof(LVCOLUMN));
ZeroMemory (&lvItem, sizeof(LVITEM));
lvItem.mask = LVIF_TEXT;
switch (REGType) {
case TYPER4K:
strcpy (buffer, "r4k Regs");
for (x=0x1F; x >= 0; x--) {
char buff[0x12];
lvItem.iSubItem = 0;
lvItem.pszText = r4kreg[x];
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGS),LVM_INSERTITEM, 0, (LPARAM)&lvItem);
sprintf (buff, "%08X", (CpuRegs[x]>>32));
sprintf (buff+8, " %08X", CpuRegs[x]);
lvItem.pszText = buff;
lvItem.iSubItem = 1;
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGS),LVM_SETITEM, 0, (LPARAM)&lvItem);
}
break;
case TYPEMMU:
strcpy (buffer, "MMU Registers");
break;
case TYPEFPU:
strcpy (buffer, "FPU Registers");
break;
case TYPERSP:
strcpy (buffer, "SP Registers");
break;
case TYPEMI:
strcpy (buffer, "MI Registers");
break;
case TYPEPI:
strcpy (buffer, "PI Registers");
break;
case TYPESP:
strcpy (buffer, "SP Registers");
break;
case TYPEDP:
strcpy (buffer, "DP Registers");
break;
case TYPEAI:
strcpy (buffer, "AI Registers");
break;
case TYPERAM:
strcpy (buffer, "RDRAM Registers");
break;
case TYPERI:
strcpy (buffer, "RI Registers");
break;
case TYPEVI:
strcpy (buffer, "VI Registers");
break;
case TYPESI:
strcpy (buffer, "SI Registers");
break;
default:
return;
}
lvColumn.mask = LVCF_TEXT;
lvColumn.pszText = buffer;
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGS),LVM_SETCOLUMN, 0, (LPARAM)&lvColumn);
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGS),LVM_SETCOLUMNWIDTH, 0, MAKELPARAM(LVSCW_AUTOSIZE_USEHEADER,0));
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGS),LVM_SETCOLUMNWIDTH, 1, MAKELPARAM(LVSCW_AUTOSIZE_USEHEADER,0));
}
u32 bpoints[0x20];
u32 topaddy;
const u32 MAXLIST = 0x26;
void UpdateCPU (HWND hWnd, int CPUType, DWORD addy) {
char buffer[0x100];
long tabstop = 70;
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_DISASM), LB_SETTABSTOPS, 1, (long)&tabstop);
topaddy = addy; // Address on the top of the list
//bpoints[0] =addy+0x30;
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_DISASM), LB_RESETCONTENT, 0, 0);
if (CPUType == R4KCPU) {
for (int x = 0; x < MAXLIST; x++) {
sprintf (buffer, "%08X ", addy+(x*4));
OpcodeLookup(addy+(x*4), buffer+0x9);
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_DISASM), LB_INSERTSTRING, x, (long)buffer);
SetDlgItemText (hWnd, IDC_DEBUG_ITEML1+x, "");
SetDlgItemText (hWnd, IDC_DEBUG_ITEMR1+x, "");
for (int z = 0; z < 0x10; z++) {
if (bpoints[z] == addy+(x*4)) {
SetDlgItemText (hWnd, IDC_DEBUG_ITEMR1+x, "<B");
break;
}
}
}
} else {
for (int x = 0; x < MAXLIST; x++) {
sprintf (buffer, "", addy+(x*4));
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_DISASM), LB_INSERTSTRING, x, (long)buffer);
SetDlgItemText (hWnd, IDC_DEBUG_ITEML1+x, "");
SetDlgItemText (hWnd, IDC_DEBUG_ITEMR1+x, "");
}
}
}
//IDC_DEBUG_SCRBAR
BOOL CALLBACK Debugger( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) {
int MenuId,i;
TCITEM index;
LVCOLUMN lvColumn;
char buffer[0x20];
static DWORD daddy;
switch(message)
{
case WM_INITDIALOG: {
index.pszText = "R4K";
index.cchTextMax = 3;
index.mask = TCIF_TEXT;
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_CPUSEL),TCM_INSERTITEM,0,(LPARAM)&index);
index.pszText = "RSP";
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_CPUSEL),TCM_INSERTITEM,1,(LPARAM)&index);
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_CPUSEL),TCM_SETITEMSIZE,0,(LPARAM)0x40);
for (int x = 0; x < 13; x++) {
index.cchTextMax = 2;
index.mask = TCIF_TEXT;
index.pszText = lpszREGTYPES[x];
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGSEL),TCM_INSERTITEM,x,(LPARAM)&index);
}
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGSEL),TCM_SETITEMSIZE,0,(LPARAM)0x30);
lvColumn.mask = LVCF_TEXT | LVCF_WIDTH;
lvColumn.cx = 0x80;
lvColumn.pszText = "Register";
lvColumn.cchTextMax = 16;
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGS),LVM_INSERTCOLUMN, 0, (LPARAM)&lvColumn);
lvColumn.pszText = "Register Value";
lvColumn.cx = 0x100;
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGS),LVM_INSERTCOLUMN, 1, (LPARAM)&lvColumn);
SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGS),LVM_SETEXTENDEDLISTVIEWSTYLE,
LVS_EX_FULLROWSELECT|LVS_EX_ONECLICKACTIVATE,
LVS_EX_FULLROWSELECT|LVS_EX_ONECLICKACTIVATE);
iCurrentCPU = R4KCPU;
iCurrentREG = 0;
UpdateRegisters (hWnd, iCurrentREG);
memset (bpoints, -1, 0x20*4);
daddy = pc;
UpdateCPU (hWnd, iCurrentCPU, daddy);
return TRUE;
}
break;
case WM_COMMAND:
MenuId = LOWORD(wParam);
switch (MenuId) {
case IDOK:
EndDialog(DebuggerHwnd,0);
DebuggerHwnd = 0;
return TRUE;
break;
case IDC_DEBUG_DISASM: {
if (HIWORD(wParam) == LBN_SELCHANGE) {
char lpBuff[0x40];
int selection=0;
selection = SendMessage(GetDlgItem(hWnd,IDC_DEBUG_DISASM), LB_GETCURSEL, 0, 0);
sprintf (lpBuff, "0x%08X", topaddy+selection*4);
SetDlgItemText (hWnd, IDC_DEBUG_COPYBOX, lpBuff);
} else if (HIWORD(wParam) == LBN_DBLCLK) {
char lpBuff[0x40];
int selection=0;
selection = SendMessage(GetDlgItem(hWnd,IDC_DEBUG_DISASM), LB_GETCURSEL, 0, 0);
for (int x=0; x<0x20; x++)
if (bpoints[x] == topaddy+selection*4) {
bpoints[x] = 0xFFFFFFFF;
x = 0x30;
break;
}
if (x != 0x30)
for (x=0; x<0x20; x++)
if (bpoints[x] == 0xFFFFFFFF) {
bpoints[x] = topaddy+selection*4;
break;
}
UpdateCPU (hWnd, iCurrentCPU, topaddy);
}
}
break;
}
break;
case WM_NOTIFY: {
int idCtrl = wParam;
NMHDR *nmHeader = (NMHDR *)lParam;
switch (nmHeader->idFrom){//idCtrl) {
case IDC_DEBUG_REGSEL:
if ((nmHeader->code == TCN_SELCHANGE)&&(nmHeader->idFrom == IDC_DEBUG_REGSEL))
UpdateRegisters (hWnd, iCurrentREG = SendMessage(GetDlgItem(hWnd,IDC_DEBUG_REGSEL),TCM_GETCURSEL,0,0));
break;
case IDC_DEBUG_CPUSEL:
if ((nmHeader->code == TCN_SELCHANGE)&&(nmHeader->idFrom == IDC_DEBUG_CPUSEL))
UpdateCPU (hWnd, iCurrentCPU= SendMessage(GetDlgItem(hWnd,IDC_DEBUG_CPUSEL),TCM_GETCURSEL,0,0), pc);
break;
}
break;
}
}
return FALSE;
}
*/