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
// 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
if (_inst.Rc)
// 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));
}

View File

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

View File

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

View File

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