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
|
// Apply current rounding mode
|
||||||
// need to investigate this instruction.
|
|
||||||
void fctiwx(UGeckoInstruction _inst)
|
void fctiwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
const double b = rPS0(_inst.FB);
|
const double b = rPS0(_inst.FB);
|
||||||
|
@ -133,7 +132,7 @@ void fctiwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double t = b + 0.5;
|
double t = b + 0.5;
|
||||||
i = (s32)t;
|
i = (s32)t;
|
||||||
if (t - i < 0) i--;
|
if (t - i < 0 || (t - i == 0 && b > 0)) i--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: // zero
|
case 1: // zero
|
||||||
|
@ -161,19 +160,15 @@ void fctiwx(UGeckoInstruction _inst)
|
||||||
FPSCR.FR = fabs(di) > fabs(b);
|
FPSCR.FR = fabs(di) > fabs(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// based on HW tests
|
||||||
//FPRF undefined
|
// FPRF is not affected
|
||||||
|
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
|
||||||
riPS0(_inst.FD) = (u64)value; // zero extend
|
if (value == 0 && ( (*(u64*)&b) & DOUBLE_SIGN ))
|
||||||
|
riPS0(_inst.FD) |= 0x100000000ull;
|
||||||
if (_inst.Rc)
|
if (_inst.Rc)
|
||||||
Helper_UpdateCR1(rPS0(_inst.FD));
|
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
|
// Always round toward zero
|
||||||
void fctiwzx(UGeckoInstruction _inst)
|
void fctiwzx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
|
@ -209,8 +204,11 @@ void fctiwzx(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
value = (u32)i;
|
value = (u32)i;
|
||||||
}
|
}
|
||||||
|
// based on HW tests
|
||||||
riPS0(_inst.FD) = (u64)value;
|
// FPRF is not affected
|
||||||
|
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
|
||||||
|
if (value == 0 && ( (*(u64*)&b) & DOUBLE_SIGN ))
|
||||||
|
riPS0(_inst.FD) |= 0x100000000ull;
|
||||||
if (_inst.Rc)
|
if (_inst.Rc)
|
||||||
Helper_UpdateCR1(rPS0(_inst.FD));
|
Helper_UpdateCR1(rPS0(_inst.FD));
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,19 +315,18 @@ void dcbtst(UGeckoInstruction _inst)
|
||||||
_assert_msg_(POWERPC,0,"dcbtst - Not implemented");
|
_assert_msg_(POWERPC,0,"dcbtst - Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
// __________________________________________________________________________________________________
|
|
||||||
// dcbz
|
|
||||||
// TODO(ector) check docs
|
|
||||||
void dcbz(UGeckoInstruction _inst)
|
void dcbz(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
// !!! after the dcbz follows a dcbf... dont clear the memory in this case !!!
|
// !!! after the dcbz follows a dcbf... dont clear the memory in this case !!!
|
||||||
// 0x81330c2c
|
// 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)
|
if (NextOpcode == 0x7C0400AC)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// HACK but works... we think
|
// HACK but works... we think
|
||||||
Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32);
|
Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32);
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,18 +473,8 @@ void ps_cmpo1(UGeckoInstruction _inst)
|
||||||
// TODO(ector) check docs
|
// TODO(ector) check docs
|
||||||
void dcbz_l(UGeckoInstruction _inst)
|
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
|
//FAKE: clear memory instead of clearing the cache block
|
||||||
for (int i=blockStart; i<blockEnd; i+=4)
|
Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32);
|
||||||
Memory::Write_U32(0,i);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -323,6 +323,9 @@ void mtspr(UGeckoInstruction _inst)
|
||||||
UReg_HID2 old_hid2;
|
UReg_HID2 old_hid2;
|
||||||
old_hid2.Hex = oldValue;
|
old_hid2.Hex = oldValue;
|
||||||
|
|
||||||
|
//if (HID2.LCE && !old_hid2.LCE)
|
||||||
|
// PanicAlert("Locked cache enabled!");
|
||||||
|
|
||||||
if (HID2.PSE == 0)
|
if (HID2.PSE == 0)
|
||||||
PanicAlert("WARNING: PSE in HID2 isnt set");
|
PanicAlert("WARNING: PSE in HID2 isnt set");
|
||||||
|
|
||||||
|
@ -363,6 +366,7 @@ void mtspr(UGeckoInstruction _inst)
|
||||||
u32 dwMemAddress = DMAU.MEM_ADDR << 5;
|
u32 dwMemAddress = DMAU.MEM_ADDR << 5;
|
||||||
u32 dwCacheAddress = DMAL.LC_ADDR << 5;
|
u32 dwCacheAddress = DMAL.LC_ADDR << 5;
|
||||||
u32 iLength = ((DMAU.DMA_LEN_U << 2) | DMAL.DMA_LEN_L);
|
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)
|
if (iLength == 0)
|
||||||
iLength = 128;
|
iLength = 128;
|
||||||
if (DMAL.DMA_LD)
|
if (DMAL.DMA_LD)
|
||||||
|
@ -370,6 +374,7 @@ void mtspr(UGeckoInstruction _inst)
|
||||||
else
|
else
|
||||||
Memory::DMA_LCToMemory(dwMemAddress, dwCacheAddress, iLength);
|
Memory::DMA_LCToMemory(dwMemAddress, dwCacheAddress, iLength);
|
||||||
}
|
}
|
||||||
|
DMAL.DMA_T = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPR_DEC:
|
case SPR_DEC:
|
||||||
|
|
Loading…
Reference in New Issue