fix HLE BitUnPack and clarify historical crc16 bugs.

This commit is contained in:
zeromus 2013-08-12 06:08:57 +00:00
parent b18f284799
commit a850bc64d3
1 changed files with 95 additions and 89 deletions

View File

@ -858,7 +858,8 @@ TEMPLATE static u32 BitUnPack()
case 4:
case 8:
break;
default: return (0); // error
default:
return (0); // error
}
dataSize = _MMU_read08<PROCNUM>(header+3);
switch (dataSize)
@ -870,12 +871,12 @@ TEMPLATE static u32 BitUnPack()
case 16:
case 32:
break;
default: return (0); // error
default:
return (0); // error
}
revbits = 8 - bits;
// u32 value = 0;
base = _MMU_read08<PROCNUM>(header+4);
base = _MMU_read32<PROCNUM>(header+4);
addBase = (base & 0x80000000) ? 1 : 0;
base &= 0x7fffffff;
@ -894,21 +895,27 @@ TEMPLATE static u32 BitUnPack()
while(1) {
if(bitcount >= 8)
break;
d = b & mask;
temp = d >> bitcount;
if(!temp && addBase) {
temp = b & mask;
if(temp)
temp += base;
}
else if(addBase)
temp += base;
//you might think you should do this. but you would be wrong!
//this is meant for palette adjusting things, i.e. 16col data to 256col data in colors 240..255. In that case theres no modulo normally.
//Users expecting modulo have done something wrong anyway.
//temp &= (1<<bits)-1;
data |= temp << bitwritecount;
bitwritecount += dataSize;
if(bitwritecount >= 32) {
_MMU_write08<PROCNUM>(dest, data);
_MMU_write32<PROCNUM>(dest, data);
dest += 4;
data = 0;
bitwritecount = 0;
}
mask <<= bits;
bitcount += bits;
b >>= bits;
}
}
return 1;
@ -1029,41 +1036,40 @@ TEMPLATE static u32 getVolumeTab()
}
//TEMPLATE static u32 getCRC16_old_and_broken(u32 crc, u32 datap, u32 size)
//{
// unsigned int i,j;
//
// const u16 val[] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 };
// for(i = 0; i < size; i++)
// {
// crc = crc ^ _MMU_read08<PROCNUM>(datap + i);
//
// for(j = 0; j < 8; j++) {
// int do_bit = 0;
//
// if ( crc & 0x1)
// do_bit = 1;
//
// crc = crc >> 1;
//
// if ( do_bit) {
// crc = crc ^ (val[j] << (7-j));
// }
// }
// }
// return crc;
//}
TEMPLATE static u32 getCRC16_old_and_broken(u32 crc, u32 datap, u32 size)
{
unsigned int i,j;
const u16 val[] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 };
for(i = 0; i < size; i++)
{
crc = crc ^ _MMU_read08<PROCNUM>(datap + i);
for(j = 0; j < 8; j++) {
int do_bit = 0;
if ( crc & 0x1)
do_bit = 1;
crc = crc >> 1;
if ( do_bit) {
crc = crc ^ (val[j] << (7-j));
}
}
}
return crc;
}
TEMPLATE static u32 getCRC16()
{
//gbatek is wrong.. for ARM9, at least.
//someone should check how the ARM7 version works.
//dawn of sorrow uses this to checksum its save data;
//if this implementation is wrong, then it won't match what the real bios returns,
//and savefiles created with a bios will be invalid when loaded with non-bios (and vice-versa)
//u32 old = getCRC16_old<PROCNUM>(cpu->R[0],cpu->R[1],cpu->R[2]);
//and savefiles created with a bios will be invalid when loaded with non-bios (and vice-versa).
//Once upon a time, desmume was doing this wrongly; this was due to its mis-use of high bits of the input CRC.
//Additionally, that implementation was not handling odd sizes and addresses correctly (but this was discovered independently)
//The following call is left here so we can A/B test with the old version. Glad I left it, because we keep coming back to this code.
//u32 old = getCRC16_old_and_broken<PROCNUM>(cpu->R[0],cpu->R[1],cpu->R[2]);
u16 crc = (u16)cpu->R[0];
u32 datap = cpu->R[1];
@ -1091,7 +1097,7 @@ TEMPLATE static u32 getCRC16()
cpu->R[0] = crc;
//R3 contains the last processed halfword
//this is significant -- WHY?
//this is significant -- why? Can we get a test case? Supposedly there is one..
cpu->R[3] = currVal;
return 1;