📄 arm9es.cpp
字号:
/**************************************************************************
* DSemu - The Next Generation *
* Portable ARM9ES core: Plugin implementation [arm9es.cpp] *
* Copyright Imran Nazar, 2005; released under the BSD public licence. *
**************************************************************************/
#include <string>
#include <utility>
#include "arm9es.h"
#include "armdasm.h"
#include "plgmmu32.h"
#include "plggui.h"
#include "datadefs.h"
#include "log.h"
#include "err.h"
#include "font5x7.h"
#include "arm-cpnull.h"
#include "arm-cpsys.h"
// Interrupt vectors at top of address space, not bottom
#define ARM_HIGH_VECTORS
//---Static private class members------------------------------------------
// Every plugin has an INFO structure attached, with info about the plugin.
PLUGININFO ARM9ES::pInfo={
PLUGIN_TYPE_CPU,
0x00010001,
"Portable ARM9ES core",
"DSemu-ng"
};
ARM9ES::REGS ARM9ES::reg;
std::map<u32, int> ARM9ES::bkpts;
std::string ARM9ES::pluginName;
FILE *ARM9ES::dumpfile;
MMU32Plugin *ARM9ES::MMU;
GUIPlugin *ARM9ES::GUI;
u32 *ARM9ES::dbgbuffer = NULL;
int ARM9ES::dbgwinID = 0;
ARMDasm ARM9ES::dasm(rdWhelper);
ARMCopro *ARM9ES::copro[16];
const char *ARM9ES::modeStrings[7] = {
"USR", "FIQ", "IRQ", "SVC", "ABT", "UND", "SYS"
};
const int ARM9ES::modeToCpsrLUT[7] = {
CPSR_MUSR, CPSR_MFIQ, CPSR_MIRQ, CPSR_MSVC,
CPSR_MABT, CPSR_MUND, CPSR_MSYS
};
const int ARM9ES::modeFromCpsrLUT[16] = {
MODE_USR, MODE_FIQ, MODE_IRQ, MODE_SVC,
-1, -1, -1, MODE_ABT,
-1, -1, -1, MODE_UND,
-1, -1, -1, MODE_SYS,
};
//---Implementation--------------------------------------------------------
// Initialise plugin
// Parameters: name - FQPN of plugin as listed in INI file
// req - Pointer to PluginRequest API function
// unreq - Pointer to PluginUnrequest API function
ARM9ES::ARM9ES(std::string name, REQPTR req, UNREQPTR unreq)
{
pName = std::string(name);
pClass = pName.substr(0, pName.find(".")+1);
pRequest = req;
pUnrequest = unreq;
pluginName = pName;
dbgbuffer = new u32[456*128];
copro[0] = new ARMcpNULL();
copro[15] = new ARMcpSys();
for(int i=1;i<=14;i++) copro[i]=copro[0];
MMU = (MMU32Plugin*) pRequest(pClass+"mmu");
GUI = (GUIPlugin*) pRequest("UI");
dbgwinID = GUI->subwinCreate(456, 128, "ARM9 debugger", dbgbuffer);
#ifdef ARM9ES_DEBUG
dumpfile = fopen("dsemu-trace.bin","wb");
#endif
MMU->setCPU(this);
// Simple check: Is this a 32-bit MMU? Our CPU's 32-bit after all
if((MMU->getCaps() & PLGMMU_CAPS_SIZEMASK) != PLGMMU_CAPS_32B)
{
pUnrequest(pClass+"mmu", 1); MMU = NULL;
throw Exception(ERR_CPU_INIT, pName,
pClass+"mmu isn't 32-bit.");
}
Logger::log(pName) << "Initialised.";
}
// Plugin cleanup
ARM9ES::~ARM9ES()
{
if(dbgbuffer) { delete dbgbuffer; dbgbuffer = NULL; }
if(copro[0]) delete copro[0];
if(copro[15]) delete copro[15];
for(int i=0;i<=15;i++) copro[i]=NULL;
pUnrequest("UI",0); GUI = NULL;
pUnrequest(pClass+"mmu", 1); MMU = NULL;
#ifdef ARM9ES_DEBUG
fclose(dumpfile);
#endif
Logger::log(pName) << "Shutdown after " << reg.clkcount << " cycles.";
}
// Reset CPU state
void ARM9ES::reset()
{
reg.r0 =0; reg.r1 =0; reg.r2 =0; reg.r3 =0;
reg.r4 =0; reg.r5 =0; reg.r6 =0; reg.r7 =0;
reg.r8 =0; reg.r9 =0; reg.r10=0; reg.r11=0;
reg.r12=0; reg.r13=0; reg.r14=0;
#ifdef ARM_HIGH_VECTORS
reg.r15=0xFFFF0000; // Reset vector
#else
reg.r15=0x00000000; // Reset vector
#endif
for(int i=0; i<7; i++) reg.spsr[i]=0;
reg.r8fiq=0; reg.r9fiq=0; reg.r10fiq=0; reg.r11fiq=0;
reg.r12fiq=0; reg.r13fiq=0; reg.r14fiq=0;
reg.r13irq=0; reg.r14irq=0;
reg.r13abt=0; reg.r14abt=0;
reg.r13svc=0; reg.r14svc=0;
reg.r13und=0; reg.r14und=0;
reg.curmode = MODE_SYS;
reg.cpsr = CPSR_MSYS;
// BUGBUG: Hack to set up DS initial state on reset
reg.r13 = 0x03007F00;
reg.r13irq = 0x03007FA0;
reg.r13svc = 0x03007FE0;
reg.cpsr |= CPSR_F;
// ENDBUG
reg.r[0x0]=reg.r0 ; reg.r[0x1]=reg.r1 ; reg.r[0x2]=reg.r2 ; reg.r[0x3]=reg.r3 ;
reg.r[0x4]=reg.r4 ; reg.r[0x5]=reg.r5 ; reg.r[0x6]=reg.r6 ; reg.r[0x7]=reg.r7 ;
reg.r[0x8]=reg.r8 ; reg.r[0x9]=reg.r9 ; reg.r[0xA]=reg.r10; reg.r[0xB]=reg.r11;
reg.r[0xC]=reg.r12; reg.r[0xD]=reg.r13; reg.r[0xE]=reg.r14; reg.r[0xF]=reg.r15;
for(int i=0; i<8; i++) reg.flags[i]=0;
reg.clkcount = 0;
MMU->reset();
memset(dbgbuffer, 0, 456*128*4);
status(3,0);
#ifdef ARM9ES_DEBUG
reg.r[15]+=4; fwrite(reg.r, 4, 17, dumpfile); reg.r[15]-=4;
#endif
Logger::log(pName) << "Reset.";
}
// Provide status information (fill the debugger framebuffer)
void ARM9ES::status(int mode=3, int opt2=0)
{
char str[512]; int a; int xdim=456, ydim=128;
u32 r15=reg.r[15],r15orig=r15; static u32 r15old;
static u32 dbgoldr[16],rchanged[16];
static int dbgoldf[6],fchanged[6];
u32 op=0; u32 col; u16 oph=0;
int offset=0;
if(dbgbuffer)
{
Font5x7 prn(dbgbuffer, xdim, ydim);
cpsrUpdate();
if((mode==3 && reg.flags[FLAG_T]) || (mode==2))
r15-=(16-offset*2);
else
r15-=(32-offset*4);
for(a=0;a<16;a++)
{
if(r15==r15orig) col=0x00FF8080; else col=0x00FFFFFF;
if(bkpts.find(r15) != bkpts.end()) col=0x0000FFFF;
if((r15&0x0F000000)==(r15orig&0x0F000000)) op=MMU->rdW(r15);
switch(mode)
{
case 1:
if((r15&0x0F000000)==(r15orig&0x0F000000))
sprintf(str,"%08X: %08X | %s",r15,op,dasm.disasm(op,r15).c_str());
else sprintf(str,"%08X",r15);
r15+=4;
break;
case 2:
if((r15&0x0F000000)==(r15orig&0x0F000000))
{
if(r15&2) oph=op>>16; else oph=op&65535;
sprintf(str,"%08X: %04X | %s",r15,oph,dasm.tdisasm((u32)oph,r15).c_str());
}
else sprintf(str,"%08X",r15);
r15+=2; break;
case 3:
switch(reg.flags[FLAG_T])
{
case 0:
if((r15&0x0F000000)==(r15orig&0x0F000000))
sprintf(str,"%08X: %08X | %s",r15,op,dasm.disasm(op,r15).c_str());
else sprintf(str,"%08X",r15);
r15+=4; break;
case 1:
if((r15&0x0F000000)==(r15orig&0x0F000000))
{
if(r15&2) oph=op>>16; else oph=op&65535;
sprintf(str,"%08X: %04X | %s",r15,oph,dasm.tdisasm(oph,r15).c_str());
}
else sprintf(str,"%08X",r15);
r15+=2; break;
}
}
prn.print(str,0,a*8,col);
}
for(a=0;a<=15;a++)
{
sprintf(str,"r%02d: %08X",a,reg.r[a]);
if(r15old!=r15orig)
{
if(reg.r[a]!=dbgoldr[a]) { dbgoldr[a]=reg.r[a]; rchanged[a]=1; }
else rchanged[a]=0;
}
if(rchanged[a]) prn.print(str,56*6,a*8,0x000000FF);
else prn.print(str,56*6,a*8,0x00FFFFFF);
}
sprintf(str,"%s",modeStrings[reg.curmode]);
prn.print(str, 72*6, 56 ,0x00FFFFFF);
a=(reg.cpsr&CPSR_N)>>31; sprintf(str,"N: %d",a);
if(r15old!=r15orig)
if(a!=dbgoldf[0]) { dbgoldf[0]=a; fchanged[0]=1; } else fchanged[0]=0;
if(fchanged[0]) prn.print(str,72*6,0,0x000000FF);
else prn.print(str,72*6,0,0x00FFFFFF);
a=(reg.cpsr&CPSR_Z)>>30; sprintf(str,"Z: %d",a);
if(r15old!=r15orig)
if(a!=dbgoldf[1]) { dbgoldf[1]=a; fchanged[1]=1; } else fchanged[1]=0;
if(fchanged[1]) prn.print(str,72*6,8,0x000000FF);
else prn.print(str,72*6,8,0x00FFFFFF);
a=(reg.cpsr&CPSR_C)>>29; sprintf(str,"C: %d",a);
if(r15old!=r15orig)
if(a!=dbgoldf[2]) { dbgoldf[2]=a; fchanged[2]=1; } else fchanged[2]=0;
if(fchanged[2]) prn.print(str,72*6,16,0x000000FF);
else prn.print(str,72*6,16,0x00FFFFFF);
a=(reg.cpsr&CPSR_V)>>28; sprintf(str,"V: %d",a);
if(r15old!=r15orig)
if(a!=dbgoldf[3]) { dbgoldf[3]=a; fchanged[3]=1; } else fchanged[3]=0;
if(fchanged[3]) prn.print(str,72*6,24,0x000000FF);
else prn.print(str,72*6,24,0x00FFFFFF);
a=(reg.cpsr&CPSR_Q)>>27; sprintf(str,"Q: %d",a);
if(r15old!=r15orig)
if(a!=dbgoldf[4]) { dbgoldf[4]=a; fchanged[4]=1; } else fchanged[4]=0;
if(fchanged[4]) prn.print(str,72*6,32,0x000000FF);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -