Some improvements of FP and DMA
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4334 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
b9422c7ed9
commit
b4e12ad5c9
|
@ -105,7 +105,6 @@ void fcmpu(UGeckoInstruction _inst)
|
|||
}
|
||||
|
||||
// Apply current rounding mode
|
||||
// need to investigate this instruction.
|
||||
void fctiwx(UGeckoInstruction _inst)
|
||||
{
|
||||
const double b = rPS0(_inst.FB);
|
||||
|
@ -133,7 +132,7 @@ void fctiwx(UGeckoInstruction _inst)
|
|||
{
|
||||
double t = b + 0.5;
|
||||
i = (s32)t;
|
||||
if (t - i < 0) i--;
|
||||
if (t - i < 0 || (t - i == 0 && b > 0)) i--;
|
||||
break;
|
||||
}
|
||||
case 1: // zero
|
||||
|
@ -161,19 +160,15 @@ void fctiwx(UGeckoInstruction _inst)
|
|||
FPSCR.FR = fabs(di) > fabs(b);
|
||||
}
|
||||
}
|
||||
|
||||
//FPRF undefined
|
||||
|
||||
riPS0(_inst.FD) = (u64)value; // zero extend
|
||||
// based on HW tests
|
||||
// FPRF is not affected
|
||||
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
|
||||
if (value == 0 && ( (*(u64*)&b) & DOUBLE_SIGN ))
|
||||
riPS0(_inst.FD) |= 0x100000000ull;
|
||||
if (_inst.Rc)
|
||||
Helper_UpdateCR1(rPS0(_inst.FD));
|
||||
}
|
||||
|
||||
/*
|
||||
In the float -> int direction, floating point input values larger than the largest
|
||||
representable int result in 0x80000000 (a very negative number) rather than the
|
||||
largest representable int on PowerPC. */
|
||||
|
||||
// Always round toward zero
|
||||
void fctiwzx(UGeckoInstruction _inst)
|
||||
{
|
||||
|
@ -209,8 +204,11 @@ void fctiwzx(UGeckoInstruction _inst)
|
|||
}
|
||||
value = (u32)i;
|
||||
}
|
||||
|
||||
riPS0(_inst.FD) = (u64)value;
|
||||
// based on HW tests
|
||||
// FPRF is not affected
|
||||
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
|
||||
if (value == 0 && ( (*(u64*)&b) & DOUBLE_SIGN ))
|
||||
riPS0(_inst.FD) |= 0x100000000ull;
|
||||
if (_inst.Rc)
|
||||
Helper_UpdateCR1(rPS0(_inst.FD));
|
||||
}
|
||||
|
|
|
@ -315,19 +315,18 @@ void dcbtst(UGeckoInstruction _inst)
|
|||
_assert_msg_(POWERPC,0,"dcbtst - Not implemented");
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
// dcbz
|
||||
// TODO(ector) check docs
|
||||
void dcbz(UGeckoInstruction _inst)
|
||||
{
|
||||
// !!! after the dcbz follows a dcbf... dont clear the memory in this case !!!
|
||||
// 0x81330c2c
|
||||
u32 NextOpcode = Memory::Read_U32(PC+4);
|
||||
// LinesPrower: why? does it break something?
|
||||
// according to docs dcbz->dcbf should clear the memory immediately!
|
||||
// However, dcbz->dcbi won't clear anything, but that's completely senseless
|
||||
/* u32 NextOpcode = Memory::Read_U32(PC+4);
|
||||
if (NextOpcode == 0x7C0400AC)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}*/
|
||||
// HACK but works... we think
|
||||
Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32);
|
||||
}
|
||||
|
|
|
@ -473,18 +473,8 @@ void ps_cmpo1(UGeckoInstruction _inst)
|
|||
// TODO(ector) check docs
|
||||
void dcbz_l(UGeckoInstruction _inst)
|
||||
{
|
||||
// This is supposed to allocate a cache line in the locked cache. Not entirely sure how
|
||||
// this is visible to the rest of the world. For now, we ignore it.
|
||||
/*
|
||||
addr_t ea = Helper_Get_EA(_inst);
|
||||
|
||||
u32 blockStart = ea & (~(CACHEBLOCKSIZE-1));
|
||||
u32 blockEnd = blockStart + CACHEBLOCKSIZE;
|
||||
|
||||
//FAKE: clear memory instead of clearing the cache block
|
||||
for (int i=blockStart; i<blockEnd; i+=4)
|
||||
Memory::Write_U32(0,i);
|
||||
*/
|
||||
Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -323,6 +323,9 @@ void mtspr(UGeckoInstruction _inst)
|
|||
UReg_HID2 old_hid2;
|
||||
old_hid2.Hex = oldValue;
|
||||
|
||||
//if (HID2.LCE && !old_hid2.LCE)
|
||||
// PanicAlert("Locked cache enabled!");
|
||||
|
||||
if (HID2.PSE == 0)
|
||||
PanicAlert("WARNING: PSE in HID2 isnt set");
|
||||
|
||||
|
@ -363,6 +366,7 @@ void mtspr(UGeckoInstruction _inst)
|
|||
u32 dwMemAddress = DMAU.MEM_ADDR << 5;
|
||||
u32 dwCacheAddress = DMAL.LC_ADDR << 5;
|
||||
u32 iLength = ((DMAU.DMA_LEN_U << 2) | DMAL.DMA_LEN_L);
|
||||
//INFO_LOG(POWERPC, "DMA: mem = %x, cache = %x, len = %u, LD = %d, PC=%x", dwMemAddress, dwCacheAddress, iLength, (int)DMAL.DMA_LD, PC);
|
||||
if (iLength == 0)
|
||||
iLength = 128;
|
||||
if (DMAL.DMA_LD)
|
||||
|
@ -370,6 +374,7 @@ void mtspr(UGeckoInstruction _inst)
|
|||
else
|
||||
Memory::DMA_LCToMemory(dwMemAddress, dwCacheAddress, iLength);
|
||||
}
|
||||
DMAL.DMA_T = 0;
|
||||
break;
|
||||
|
||||
case SPR_DEC:
|
||||
|
|
Loading…
Reference in New Issue