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:
LinesPrower 2009-09-27 14:19:38 +00:00
parent b9422c7ed9
commit b4e12ad5c9
4 changed files with 23 additions and 31 deletions

View File

@ -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));
} }

View File

@ -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);
} }

View File

@ -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

View File

@ -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: