Fixed bugs in LDL/LDR instructions; fixing various TLB Miss errors in assorted games (namely ones that worked in the old VM builds). The instructions were not sign-extending values into the upper 32 bits of the target register. (LDR in particular has odd rules for sign extension)

Some minor cleanups / correctness fixes to the IPU's register Read/Write functions.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@600 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-02-25 16:51:05 +00:00
parent 795152e7e1
commit c46ef87c89
3 changed files with 122 additions and 62 deletions

View File

@ -236,11 +236,17 @@ bool ipuCanFreeze()
__forceinline u32 ipuRead32(u32 mem)
{
// Note: It's assumed that mem's input value is always in the 0x10002000 page
// of memory (if not, it's probably bad code).
jASSUME( ( mem & ~0xff ) == 0x10002000 );
mem &= 0xff; // ipu repeats every 0x100
IPUProcessInterrupt();
switch (mem){
case 0x10002010: // IPU_CTRL
switch( mem )
{
case 0x10: // IPU_CTRL
ipuRegs->ctrl.IFC = g_BP.IFC;
//ipuRegs->ctrl.OFC = min(g_nIPU0Data, 8); // check if transfering to ipu0
ipuRegs->ctrl.CBP = coded_block_pattern;
@ -250,7 +256,7 @@ __forceinline u32 ipuRead32(u32 mem)
return ipuRegs->ctrl._u32;
case 0x10002020: // IPU_BP
case 0x20: // IPU_BP
ipuRegs->ipubp = g_BP.BP & 0x7f;
ipuRegs->ipubp |= g_BP.IFC<<8;
@ -260,23 +266,22 @@ __forceinline u32 ipuRead32(u32 mem)
return ipuRegs->ipubp;
}
return *(u32*)(((u8*)ipuRegs)+(mem&0xff)); // ipu repeats every 0x100
return *(u32*)(((u8*)ipuRegs)+mem);
}
__forceinline u64 ipuRead64(u32 mem)
{
// Note: It's assumed that mem's input value is always in the 0x10002000 page
// of memory (if not, it's probably bad code).
jASSUME( ( mem & ~0xff ) == 0x10002000 );
mem &= 0xff; // ipu repeats every 0x100
IPUProcessInterrupt();
#ifdef PCSX2_DEVBUILD
if( mem == 0x10002010 ) {
Console::Notice("reading 64bit IPU ctrl");
}
if( mem == 0x10002020 ) {
Console::Notice("reading 64bit IPU top");
}
#endif
switch (mem){
case 0x10002000: // IPU_CMD
switch( mem )
{
case 0x00: // IPU_CMD
//if(!ipuRegs->cmd.BUSY){
if( ipuRegs->cmd.DATA&0xffffff )
@ -284,6 +289,14 @@ __forceinline u64 ipuRead64(u32 mem)
//return *(u64*)&ipuRegs->cmd;
break;
case 0x10:
DevCon::Notice("reading 64bit IPU ctrl");
break;
case 0x20:
DevCon::Notice("reading 64bit IPU top");
break;
case 0x10002030: // IPU_TOP
IPU_LOG("Ipu read64: IPU_TOP=%x, bp = %d\n",ipuRegs->top,g_BP.BP);
@ -293,9 +306,8 @@ __forceinline u64 ipuRead64(u32 mem)
default:
IPU_LOG("Ipu read64: Unknown=%x\n", mem);
break;
}
return *(u64*)(((u8*)ipuRegs)+(mem&0xff));
return *(u64*)(((u8*)ipuRegs)+mem);
}
void ipuSoftReset()
@ -332,8 +344,13 @@ void ipuSoftReset()
g_nCmdPos[0] = 0; g_nCmdPos[1] = 0;
}
__forceinline void ipuWrite32(u32 mem,u32 value)
__forceinline void ipuWrite32(u32 mem, u32 value)
{
// Note: It's assumed that mem's input value is always in the 0x10002000 page
// of memory (if not, it's probably bad code).
jASSUME( ( mem & ~0xfff ) == 0x10002000 );
IPUProcessInterrupt();
switch (mem){
@ -356,13 +373,18 @@ __forceinline void ipuWrite32(u32 mem,u32 value)
break;
default:
IPU_LOG("Ipu write32: Unknown=%x\n", mem);
*(u32*)((u8*)ipuRegs + (mem&0xfff)) = value;
*(u32*)((u8*)ipuRegs + mem) = value;
break;
}
}
__forceinline void ipuWrite64(u32 mem, u64 value)
{
// Note: It's assumed that mem's input value is always in the 0x10002000 page
// of memory (if not, it's probably bad code).
jASSUME( ( mem & ~0xfff ) == 0x10002000 );
IPUProcessInterrupt();
switch (mem){
@ -373,7 +395,7 @@ __forceinline void ipuWrite64(u32 mem, u64 value)
default:
IPU_LOG("Ipu write64: Unknown=%x\n", mem);
*(u64*)((u8*)ipuRegs + (mem&0xfff)) = value;
*(u64*)((u8*)ipuRegs + mem) = value;
break;
}
}

View File

@ -315,8 +315,11 @@ void LWU() {
}
}
u32 LWL_MASK[4] = { 0xffffff, 0xffff, 0xff, 0 };
u32 LWL_SHIFT[4] = { 24, 16, 8, 0 };
static const s32 LWL_MASK[4] = { 0xffffff, 0x0000ffff, 0x000000ff, 0x00000000 };
static const s32 LWR_MASK[4] = { 0x000000, 0xff000000, 0xffff0000, 0xffffff00 };
static const u8 LWL_SHIFT[4] = { 24, 16, 8, 0 };
static const u8 LWR_SHIFT[4] = { 0, 8, 16, 24 };
void LWL() {
s32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
@ -325,11 +328,14 @@ void LWL() {
if (!_Rt_) return;
memRead32(addr & ~3, &mem);
cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UL[0] & LWL_MASK[shift]) |
// Reassignment note: ensure the compiler does sign extension into 64 bits, by using (s32).
cpuRegs.GPR.r[_Rt_].UD[0] = (s32)(cpuRegs.GPR.r[_Rt_].SL[0] & LWL_MASK[shift]) |
(mem << LWL_SHIFT[shift]);
/*
Mem = 1234. Reg = abcd
(result is always sign extended into the upper 32 bits of the Rt)
0 4bcd (mem << 24) | (reg & 0x00ffffff)
1 34cd (mem << 16) | (reg & 0x0000ffff)
@ -338,23 +344,35 @@ void LWL() {
*/
}
u32 LWR_MASK[4] = { 0, 0xff000000, 0xffff0000, 0xffffff00 };
u32 LWR_SHIFT[4] = { 0, 8, 16, 24 };
void LWR() {
s32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 3;
u32 mem;
if (!_Rt_) return;
memRead32(addr & ~3, &mem);
cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UL[0] & LWR_MASK[shift]) |
(mem >> LWR_SHIFT[shift]);
u32 mem;
memRead32(addr & ~3, &mem);
mem = (cpuRegs.GPR.r[_Rt_].SL[0] & LWR_MASK[shift]) |
(mem >> LWR_SHIFT[shift]);
if( shift == 0 )
{
// This special case requires sign extension into the full 64 bit dest.
cpuRegs.GPR.r[_Rt_].SD[0] = (s32)mem;
}
else
{
// This case can simply set the lower 32 bits of the target register. Upper
// 32 bits are always preserved.
cpuRegs.GPR.r[_Rt_].UL[0] = mem;
}
/*
Mem = 1234. Reg = abcd
0 1234 (mem ) | (reg & 0x00000000)
0 1234 (mem ) | (reg & 0x00000000) [sign extend into upper 32 bits!]
1 a123 (mem >> 8) | (reg & 0xff000000)
2 ab12 (mem >> 16) | (reg & 0xffff0000)
3 abc1 (mem >> 24) | (reg & 0xffffff00)
@ -373,9 +391,18 @@ void LD() {
}
}
u64 LDL_MASK[8] = { 0x00ffffffffffffffLL, 0x0000ffffffffffffLL, 0x000000ffffffffffLL, 0x00000000ffffffffLL,
0x0000000000ffffffLL, 0x000000000000ffffLL, 0x00000000000000ffLL, 0x0000000000000000LL };
u32 LDL_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 };
static const u64 LDL_MASK[8] =
{ 0x00ffffffffffffffLL, 0x0000ffffffffffffLL, 0x000000ffffffffffLL, 0x00000000ffffffffLL,
0x0000000000ffffffLL, 0x000000000000ffffLL, 0x00000000000000ffLL, 0x0000000000000000LL
};
static const u64 LDR_MASK[8] =
{ 0x0000000000000000LL, 0xff00000000000000LL, 0xffff000000000000LL, 0xffffff0000000000LL,
0xffffffff00000000LL, 0xffffffffff000000LL, 0xffffffffffff0000LL, 0xffffffffffffff00LL
};
static const u8 LDR_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
static const u8 LDL_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 };
void LDL() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
@ -388,10 +415,6 @@ void LDL() {
(mem << LDL_SHIFT[shift]);
}
u64 LDR_MASK[8] = { 0x0000000000000000LL, 0xff00000000000000LL, 0xffff000000000000LL, 0xffffff0000000000LL,
0xffffffff00000000LL, 0xffffffffff000000LL, 0xffffffffffff0000LL, 0xffffffffffffff00LL };
u32 LDR_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
void LDR() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 7;
@ -438,8 +461,11 @@ void SW(){
memWrite32(addr, cpuRegs.GPR.r[_Rt_].UL[0]);
}
u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0x00000000 };
u32 SWL_SHIFT[4] = { 24, 16, 8, 0 };
static const u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0x00000000 };
static const u32 SWR_MASK[4] = { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
static const u8 SWR_SHIFT[4] = { 0, 8, 16, 24 };
static const u8 SWL_SHIFT[4] = { 24, 16, 8, 0 };
void SWL() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
@ -448,8 +474,10 @@ void SWL() {
memRead32(addr & ~3, &mem);
memWrite32(addr & ~3, (cpuRegs.GPR.r[_Rt_].UL[0] >> SWL_SHIFT[shift]) |
( mem & SWL_MASK[shift]) );
memWrite32( addr & ~3,
(cpuRegs.GPR.r[_Rt_].UL[0] >> SWL_SHIFT[shift]) |
(mem & SWL_MASK[shift])
);
/*
Mem = 1234. Reg = abcd
@ -460,9 +488,6 @@ void SWL() {
*/
}
u32 SWR_MASK[4] = { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
u32 SWR_SHIFT[4] = { 0, 8, 16, 24 };
void SWR() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 3;
@ -470,8 +495,10 @@ void SWR() {
memRead32(addr & ~3, &mem);
memWrite32(addr & ~3, (cpuRegs.GPR.r[_Rt_].UL[0] << SWR_SHIFT[shift]) |
( mem & SWR_MASK[shift]) );
memWrite32( addr & ~3,
(cpuRegs.GPR.r[_Rt_].UL[0] << SWR_SHIFT[shift]) |
(mem & SWR_MASK[shift])
);
/*
Mem = 1234. Reg = abcd
@ -490,9 +517,17 @@ void SD() {
memWrite64(addr,&cpuRegs.GPR.r[_Rt_].UD[0]);
}
u64 SDL_MASK[8] = { 0xffffffffffffff00LL, 0xffffffffffff0000LL, 0xffffffffff000000LL, 0xffffffff00000000LL,
0xffffff0000000000LL, 0xffff000000000000LL, 0xff00000000000000LL, 0x0000000000000000LL };
u32 SDL_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 };
static const u64 SDL_MASK[8] =
{ 0xffffffffffffff00LL, 0xffffffffffff0000LL, 0xffffffffff000000LL, 0xffffffff00000000LL,
0xffffff0000000000LL, 0xffff000000000000LL, 0xff00000000000000LL, 0x0000000000000000LL
};
static const u64 SDR_MASK[8] =
{ 0x0000000000000000LL, 0x00000000000000ffLL, 0x000000000000ffffLL, 0x0000000000ffffffLL,
0x00000000ffffffffLL, 0x000000ffffffffffLL, 0x0000ffffffffffffLL, 0x00ffffffffffffffLL
};
static const u8 SDL_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 };
static const u8 SDR_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
void SDL() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
@ -500,14 +535,11 @@ void SDL() {
u64 mem;
memRead64(addr & ~7, &mem);
mem =(cpuRegs.GPR.r[_Rt_].UD[0] >> SDL_SHIFT[shift]) |
( mem & SDL_MASK[shift]);
mem = (cpuRegs.GPR.r[_Rt_].UD[0] >> SDL_SHIFT[shift]) |
(mem & SDL_MASK[shift]);
memWrite64(addr & ~7, &mem);
}
u64 SDR_MASK[8] = { 0x0000000000000000LL, 0x00000000000000ffLL, 0x000000000000ffffLL, 0x0000000000ffffffLL,
0x00000000ffffffffLL, 0x000000ffffffffffLL, 0x0000ffffffffffffLL, 0x00ffffffffffffffLL };
u32 SDR_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
void SDR() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
@ -515,8 +547,8 @@ void SDR() {
u64 mem;
memRead64(addr & ~7, &mem);
mem=(cpuRegs.GPR.r[_Rt_].UD[0] << SDR_SHIFT[shift]) |
( mem & SDR_MASK[shift]);
mem = (cpuRegs.GPR.r[_Rt_].UD[0] << SDR_SHIFT[shift]) |
(mem & SDR_MASK[shift]);
memWrite64(addr & ~7, &mem );
}

View File

@ -1,10 +1,16 @@
; DEV9null.def : Declares the module parameters for the DLL.
; DEV9null.def : Declares the module parameters for the DLL.
LIBRARY "DEV9null"
DESCRIPTION 'DEV9null Driver'
EXPORTS
; Explicit exports can go here
;DESCRIPTION 'DEV9null Driver'
EXPORTS
; Explicit exports can go here
PS2EgetLibType @2
PS2EgetLibName @3
PS2EgetLibVersion2 @4