mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-25 07:21:14 +01:00
beginning to take a look at the wonderful world of exceptions. try to implement tw/twi
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2738 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
813b864a5e
commit
32b983ef83
@ -46,7 +46,7 @@ union UGeckoInstruction
|
||||
{
|
||||
signed SIMM_16 : 16;
|
||||
unsigned : 5;
|
||||
unsigned : 5;
|
||||
unsigned TO : 5;
|
||||
unsigned OPCD_2 : 6;
|
||||
};
|
||||
struct
|
||||
@ -152,7 +152,7 @@ union UGeckoInstruction
|
||||
|
||||
struct
|
||||
{ unsigned : 10;
|
||||
unsigned OE : 1;
|
||||
unsigned OE : 1;
|
||||
unsigned SPR : 10;
|
||||
unsigned : 11;
|
||||
};
|
||||
@ -604,6 +604,7 @@ enum
|
||||
#define EXCEPTION_ISI 0x00000010
|
||||
#define EXCEPTION_ALIGNMENT 0x00000020
|
||||
#define EXCEPTION_FPU_UNAVAILABLE 0x00000040
|
||||
#define EXCEPTION_PROGRAM 0x00000080
|
||||
|
||||
inline s32 SignExt16(s16 x) {return (s32)(s16)x;}
|
||||
inline s32 SignExt26(u32 x) {return x & 0x2000000 ? (s32)x | 0xFC000000 : (s32)(x);}
|
||||
|
@ -113,7 +113,7 @@ void CompiledBlock(UGeckoInstruction _inst)
|
||||
|
||||
void rfi(UGeckoInstruction _inst)
|
||||
{
|
||||
//Bits SRR1[0,5-9,16<EFBFBD>23, 25<32>27, 30<33>31] are placed into the corresponding bits of the MSR.
|
||||
//Bits SRR1[0,5-9,16-23, 25-27, 30-31] are placed into the corresponding bits of the MSR.
|
||||
//MSR[13] is set to 0.
|
||||
const int mask = 0x87C0FF73;
|
||||
MSR = (MSR & ~mask) | (SRR1 & mask);
|
||||
|
@ -165,11 +165,22 @@ void subfic(UGeckoInstruction _inst)
|
||||
|
||||
void twi(UGeckoInstruction _inst)
|
||||
{
|
||||
bool bFirst = true;
|
||||
if (bFirst)
|
||||
PanicAlert("twi - Instruction unimplemented");
|
||||
s32 a = m_GPR[_inst.RA];
|
||||
s32 b = _inst.SIMM_16;
|
||||
s32 TO = _inst.TO;
|
||||
|
||||
bFirst = false;
|
||||
ERROR_LOG(GEKKO, "twi rA %x SIMM %x TO %0x", a, b, TO);
|
||||
|
||||
if ( ((a < b) && (TO & 0x10))
|
||||
|| ((a > b) && (TO & 0x08))
|
||||
|| ((a ==b) && (TO & 0x04))
|
||||
|| (((u32)a <(u32)b) && (TO & 0x02))
|
||||
|| (((u32)a >(u32)b) && (TO & 0x01)))
|
||||
{
|
||||
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM;
|
||||
PowerPC::CheckExceptions();
|
||||
m_EndBlock = true; // Dunno about this
|
||||
}
|
||||
}
|
||||
|
||||
void xori(UGeckoInstruction _inst)
|
||||
@ -382,10 +393,22 @@ void srwx(UGeckoInstruction _inst)
|
||||
|
||||
void tw(UGeckoInstruction _inst)
|
||||
{
|
||||
static bool bFirst = true;
|
||||
if (bFirst)
|
||||
PanicAlert("tw - Instruction unimplemented");
|
||||
bFirst = false;
|
||||
s32 a = m_GPR[_inst.RA];
|
||||
s32 b = m_GPR[_inst.RB];
|
||||
s32 TO = _inst.TO;
|
||||
|
||||
ERROR_LOG(GEKKO, "tw rA %0x rB %0x TO %0x", a, b, TO);
|
||||
|
||||
if ( ((a < b) && (TO & 0x10))
|
||||
|| ((a > b) && (TO & 0x08))
|
||||
|| ((a ==b) && (TO & 0x04))
|
||||
|| (((u32)a <(u32)b) && (TO & 0x02))
|
||||
|| (((u32)a >(u32)b) && (TO & 0x01)))
|
||||
{
|
||||
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM;
|
||||
PowerPC::CheckExceptions();
|
||||
m_EndBlock = true; // Dunno about this
|
||||
}
|
||||
}
|
||||
|
||||
void xorx(UGeckoInstruction _inst)
|
||||
|
@ -213,62 +213,12 @@ void CheckExceptions()
|
||||
// gcemu uses the mask 0x87C0FFFF instead of 0x0780FF77
|
||||
// Investigate!
|
||||
|
||||
if (ppcState.Exceptions & EXCEPTION_FPU_UNAVAILABLE)
|
||||
{
|
||||
//This happens a lot - Gamecube OS uses deferred FPU context switching
|
||||
SRR0 = PC; // re-execute the instruction
|
||||
SRR1 = MSR & 0x0780FF77;
|
||||
NPC = 0x80000800;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_FPU_UNAVAILABLE");
|
||||
ppcState.Exceptions &= ~EXCEPTION_FPU_UNAVAILABLE;
|
||||
SRR1 |= 0x02; //recoverable
|
||||
}
|
||||
else if (ppcState.Exceptions & EXCEPTION_SYSCALL)
|
||||
{
|
||||
SRR0 = NPC; // execute next instruction when we come back from handler
|
||||
SRR1 = MSR & 0x0780FF77;
|
||||
NPC = 0x80000C00;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_SYSCALL (PC=%08x)", PC);
|
||||
ppcState.Exceptions &= ~EXCEPTION_SYSCALL;
|
||||
SRR1 |= 0x02; //recoverable
|
||||
}
|
||||
else if (ppcState.Exceptions & EXCEPTION_DSI)
|
||||
{
|
||||
SRR0 = PC; // re-execute the instruction
|
||||
SRR1 = MSR & 0x0780FF77;
|
||||
NPC = 0x80000300;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_DSI");
|
||||
ppcState.Exceptions &= ~EXCEPTION_DSI;
|
||||
//SRR1 |= 0x02; //make recoverable ?
|
||||
}
|
||||
else if (ppcState.Exceptions & EXCEPTION_ISI)
|
||||
{
|
||||
SRR0 = PC;
|
||||
SRR1 = (MSR & 0x0780FF77) | 0x40000000;
|
||||
NPC = 0x80000400;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_ISI");
|
||||
ppcState.Exceptions &= ~EXCEPTION_ISI;
|
||||
//SRR1 |= 0x02; //make recoverable ?
|
||||
}
|
||||
else if (ppcState.Exceptions & EXCEPTION_ALIGNMENT)
|
||||
{
|
||||
//This never happens ATM
|
||||
SRR0 = NPC;
|
||||
SRR1 = MSR & 0x0780FF77;
|
||||
NPC = 0x80000600;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_ALIGNMENT");
|
||||
ppcState.Exceptions &= ~EXCEPTION_ALIGNMENT;
|
||||
//SRR1 |= 0x02; //make recoverable ?
|
||||
}
|
||||
|
||||
// EXTERNAL INTTERUPT
|
||||
else if (MSR & 0x0008000)
|
||||
if (MSR & 0x0008000)
|
||||
{
|
||||
// EXCEPTION_SYSRESET (hard)
|
||||
// EXCEPTION_MACHINE_CHECK
|
||||
// EXCEPTION_SYSRESET (soft)
|
||||
if (ppcState.Exceptions & EXCEPTION_EXTERNAL_INT)
|
||||
{
|
||||
// Pokemon gets this "too early", it hasn't a handler yet
|
||||
@ -277,12 +227,13 @@ void CheckExceptions()
|
||||
SRR0 = NPC;
|
||||
NPC = 0x80000500;
|
||||
SRR1 = (MSR & 0x0780FF77);
|
||||
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_EXTERNAL_INT");
|
||||
|
||||
SRR1 |= 0x02; //set it to recoverable
|
||||
_dbg_assert_msg_(GEKKO, (SRR1 & 0x02) != 0, "GEKKO", "EXTERNAL_INT unrecoverable???"); // unrecoverable exception !?!
|
||||
}
|
||||
// EXCEPTION_PERF_MONITOR
|
||||
else if (ppcState.Exceptions & EXCEPTION_DECREMENTER)
|
||||
{
|
||||
SRR0 = NPC;
|
||||
@ -300,6 +251,73 @@ void CheckExceptions()
|
||||
ERROR_LOG(GEKKO, "Unknown EXTERNAL INTERRUPT exception: Exceptions == %08x", ppcState.Exceptions);
|
||||
}
|
||||
}
|
||||
else if (ppcState.Exceptions & EXCEPTION_ISI)
|
||||
{
|
||||
SRR0 = PC;
|
||||
SRR1 = (MSR & 0x0780FF77) | 0x40000000;
|
||||
NPC = 0x80000400;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_ISI");
|
||||
ppcState.Exceptions &= ~EXCEPTION_ISI;
|
||||
//SRR1 |= 0x02; //make recoverable ?
|
||||
}
|
||||
// EXCEPTION_ADDR_BREAKPOINT
|
||||
else if (ppcState.Exceptions & EXCEPTION_PROGRAM)
|
||||
{
|
||||
SRR0 = NPC; // execute next instruction when we come back from handler
|
||||
SRR1 = MSR & 0x0780FF77;
|
||||
NPC = 0x80000700;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_PROGRAM (PC=%08x)", PC);
|
||||
ppcState.Exceptions &= ~EXCEPTION_PROGRAM;
|
||||
SRR1 |= 0x02; //recoverable
|
||||
}
|
||||
else if (ppcState.Exceptions & EXCEPTION_SYSCALL)
|
||||
{
|
||||
SRR0 = NPC; // execute next instruction when we come back from handler
|
||||
SRR1 = MSR & 0x0780FF77;
|
||||
NPC = 0x80000C00;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_SYSCALL (PC=%08x)", PC);
|
||||
ppcState.Exceptions &= ~EXCEPTION_SYSCALL;
|
||||
SRR1 |= 0x02; //recoverable
|
||||
}
|
||||
else if (ppcState.Exceptions & EXCEPTION_FPU_UNAVAILABLE)
|
||||
{
|
||||
//This happens a lot - Gamecube OS uses deferred FPU context switching
|
||||
SRR0 = PC; // re-execute the instruction
|
||||
SRR1 = MSR & 0x0780FF77;
|
||||
NPC = 0x80000800;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_FPU_UNAVAILABLE");
|
||||
ppcState.Exceptions &= ~EXCEPTION_FPU_UNAVAILABLE;
|
||||
SRR1 |= 0x02; //recoverable
|
||||
}
|
||||
// EXCEPTION_PROGRAM (floating point)
|
||||
else if (ppcState.Exceptions & EXCEPTION_DSI)
|
||||
{
|
||||
SRR0 = PC; // re-execute the instruction
|
||||
SRR1 = MSR & 0x0780FF77;
|
||||
NPC = 0x80000300;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_DSI");
|
||||
ppcState.Exceptions &= ~EXCEPTION_DSI;
|
||||
//SRR1 |= 0x02; //make recoverable ?
|
||||
}
|
||||
else if (ppcState.Exceptions & EXCEPTION_ALIGNMENT)
|
||||
{
|
||||
// Alignment exceptions have priorities
|
||||
//This never happens ATM
|
||||
SRR0 = NPC;
|
||||
SRR1 = MSR & 0x0780FF77;
|
||||
NPC = 0x80000600;
|
||||
|
||||
INFO_LOG(GEKKO, "EXCEPTION_ALIGNMENT");
|
||||
ppcState.Exceptions &= ~EXCEPTION_ALIGNMENT;
|
||||
//SRR1 |= 0x02; //make recoverable ?
|
||||
}
|
||||
// Other DSI exceptions
|
||||
// EXCEPTION_TRACE
|
||||
MSR &= ~0x0008000; // clear EE-bit so interrupts aren't possible anymore
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user