Merge f6b73decc7
into 7ac2eb2d71
This commit is contained in:
commit
2b6db0d0ac
|
@ -400,11 +400,7 @@ void A_LDM(ARM* cpu)
|
||||||
|
|
||||||
if (!(cpu->CurInstr & (1<<23)))
|
if (!(cpu->CurInstr & (1<<23)))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; i++)
|
base -= 4 * __builtin_popcount(cpu->CurInstr & 0xFFFF);
|
||||||
{
|
|
||||||
if (cpu->CurInstr & (1<<i))
|
|
||||||
base -= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu->CurInstr & (1<<21))
|
if (cpu->CurInstr & (1<<21))
|
||||||
{
|
{
|
||||||
|
@ -418,17 +414,18 @@ void A_LDM(ARM* cpu)
|
||||||
if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15)))
|
if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15)))
|
||||||
cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10, true);
|
cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10, true);
|
||||||
|
|
||||||
for (int i = 0; i < 15; i++)
|
u16 reglist = cpu->CurInstr & 0x7FFF;
|
||||||
{
|
while (reglist)
|
||||||
if (cpu->CurInstr & (1<<i))
|
|
||||||
{
|
{
|
||||||
|
int i = __builtin_ctz(reglist);
|
||||||
|
reglist ^= 1<<i;
|
||||||
|
|
||||||
if (preinc) base += 4;
|
if (preinc) base += 4;
|
||||||
if (first) cpu->DataRead32 (base, &cpu->R[i]);
|
if (first) cpu->DataRead32 (base, &cpu->R[i]);
|
||||||
else cpu->DataRead32S(base, &cpu->R[i]);
|
else cpu->DataRead32S(base, &cpu->R[i]);
|
||||||
first = false;
|
first = false;
|
||||||
if (!preinc) base += 4;
|
if (!preinc) base += 4;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu->CurInstr & (1<<15))
|
if (cpu->CurInstr & (1<<15))
|
||||||
{
|
{
|
||||||
|
@ -479,11 +476,7 @@ void A_STM(ARM* cpu)
|
||||||
|
|
||||||
if (!(cpu->CurInstr & (1<<23)))
|
if (!(cpu->CurInstr & (1<<23)))
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < 16; i++)
|
base -= 4 * __builtin_popcount(cpu->CurInstr & 0xFFFF);
|
||||||
{
|
|
||||||
if (cpu->CurInstr & (1<<i))
|
|
||||||
base -= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu->CurInstr & (1<<21))
|
if (cpu->CurInstr & (1<<21))
|
||||||
cpu->R[baseid] = base;
|
cpu->R[baseid] = base;
|
||||||
|
@ -503,10 +496,12 @@ void A_STM(ARM* cpu)
|
||||||
cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10, true);
|
cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < 16; i++)
|
u16 reglist = cpu->CurInstr & 0xFFFF;
|
||||||
{
|
while (reglist)
|
||||||
if (cpu->CurInstr & (1<<i))
|
|
||||||
{
|
{
|
||||||
|
int i = __builtin_ctz(reglist);
|
||||||
|
reglist ^= 1<<i;
|
||||||
|
|
||||||
if (preinc) base += 4;
|
if (preinc) base += 4;
|
||||||
|
|
||||||
if (i == baseid && !isbanked)
|
if (i == baseid && !isbanked)
|
||||||
|
@ -523,7 +518,6 @@ void A_STM(ARM* cpu)
|
||||||
|
|
||||||
if (!preinc) base += 4;
|
if (!preinc) base += 4;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu->CurInstr & (1<<22))
|
if (cpu->CurInstr & (1<<22))
|
||||||
cpu->UpdateMode((cpu->CPSR&~0x1F)|0x10, cpu->CPSR, true);
|
cpu->UpdateMode((cpu->CPSR&~0x1F)|0x10, cpu->CPSR, true);
|
||||||
|
@ -700,32 +694,24 @@ void T_LDR_SPREL(ARM* cpu)
|
||||||
|
|
||||||
void T_PUSH(ARM* cpu)
|
void T_PUSH(ARM* cpu)
|
||||||
{
|
{
|
||||||
int nregs = 0;
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
if (cpu->CurInstr & (1<<i))
|
|
||||||
nregs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu->CurInstr & (1<<8))
|
|
||||||
nregs++;
|
|
||||||
|
|
||||||
u32 base = cpu->R[13];
|
u32 base = cpu->R[13];
|
||||||
base -= (nregs<<2);
|
base -= 4 * __builtin_popcount(cpu->CurInstr & 0x1FF);
|
||||||
|
|
||||||
cpu->R[13] = base;
|
cpu->R[13] = base;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
u8 reglist = cpu->CurInstr & 0xFF;
|
||||||
{
|
while (reglist)
|
||||||
if (cpu->CurInstr & (1<<i))
|
|
||||||
{
|
{
|
||||||
|
int i = __builtin_ctz(reglist);
|
||||||
|
reglist ^= 1<<i;
|
||||||
|
|
||||||
if (first) cpu->DataWrite32 (base, cpu->R[i]);
|
if (first) cpu->DataWrite32 (base, cpu->R[i]);
|
||||||
else cpu->DataWrite32S(base, cpu->R[i]);
|
else cpu->DataWrite32S(base, cpu->R[i]);
|
||||||
first = false;
|
first = false;
|
||||||
base += 4;
|
base += 4;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu->CurInstr & (1<<8))
|
if (cpu->CurInstr & (1<<8))
|
||||||
{
|
{
|
||||||
|
@ -741,16 +727,17 @@ void T_POP(ARM* cpu)
|
||||||
u32 base = cpu->R[13];
|
u32 base = cpu->R[13];
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
u8 reglist = cpu->CurInstr & 0xFF;
|
||||||
{
|
while (reglist)
|
||||||
if (cpu->CurInstr & (1<<i))
|
|
||||||
{
|
{
|
||||||
|
int i = __builtin_ctz(reglist);
|
||||||
|
reglist ^= 1<<i;
|
||||||
|
|
||||||
if (first) cpu->DataRead32 (base, &cpu->R[i]);
|
if (first) cpu->DataRead32 (base, &cpu->R[i]);
|
||||||
else cpu->DataRead32S(base, &cpu->R[i]);
|
else cpu->DataRead32S(base, &cpu->R[i]);
|
||||||
first = false;
|
first = false;
|
||||||
base += 4;
|
base += 4;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu->CurInstr & (1<<8))
|
if (cpu->CurInstr & (1<<8))
|
||||||
{
|
{
|
||||||
|
@ -771,16 +758,17 @@ void T_STMIA(ARM* cpu)
|
||||||
u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7];
|
u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7];
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
u8 reglist = cpu->CurInstr & 0xFF;
|
||||||
{
|
while (reglist)
|
||||||
if (cpu->CurInstr & (1<<i))
|
|
||||||
{
|
{
|
||||||
|
int i = __builtin_ctz(reglist);
|
||||||
|
reglist ^= 1<<i;
|
||||||
|
|
||||||
if (first) cpu->DataWrite32 (base, cpu->R[i]);
|
if (first) cpu->DataWrite32 (base, cpu->R[i]);
|
||||||
else cpu->DataWrite32S(base, cpu->R[i]);
|
else cpu->DataWrite32S(base, cpu->R[i]);
|
||||||
first = false;
|
first = false;
|
||||||
base += 4;
|
base += 4;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: check "Rb included in Rlist" case
|
// TODO: check "Rb included in Rlist" case
|
||||||
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
|
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
|
||||||
|
@ -792,16 +780,17 @@ void T_LDMIA(ARM* cpu)
|
||||||
u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7];
|
u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7];
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
u8 reglist = cpu->CurInstr & 0xFF;
|
||||||
{
|
while (reglist)
|
||||||
if (cpu->CurInstr & (1<<i))
|
|
||||||
{
|
{
|
||||||
|
int i = __builtin_ctz(reglist);
|
||||||
|
reglist ^= 1<<i;
|
||||||
|
|
||||||
if (first) cpu->DataRead32 (base, &cpu->R[i]);
|
if (first) cpu->DataRead32 (base, &cpu->R[i]);
|
||||||
else cpu->DataRead32S(base, &cpu->R[i]);
|
else cpu->DataRead32S(base, &cpu->R[i]);
|
||||||
first = false;
|
first = false;
|
||||||
base += 4;
|
base += 4;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!(cpu->CurInstr & (1<<((cpu->CurInstr >> 8) & 0x7))))
|
if (!(cpu->CurInstr & (1<<((cpu->CurInstr >> 8) & 0x7))))
|
||||||
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
|
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
|
||||||
|
|
|
@ -143,6 +143,8 @@ void SoftRenderer::TextureLookup(const GPU& gpu, u32 texparam, u32 texpal, s16 s
|
||||||
u32 vramaddr = (texparam & 0xFFFF) << 3;
|
u32 vramaddr = (texparam & 0xFFFF) << 3;
|
||||||
|
|
||||||
s32 width = 8 << ((texparam >> 20) & 0x7);
|
s32 width = 8 << ((texparam >> 20) & 0x7);
|
||||||
|
// since width is always a multple of 8 (thus a multiple of 2) we can replace all multiplications by width with a bitshift
|
||||||
|
s32 widthshift = 3 + ((texparam >> 20) & 0x7);
|
||||||
s32 height = 8 << ((texparam >> 23) & 0x7);
|
s32 height = 8 << ((texparam >> 23) & 0x7);
|
||||||
|
|
||||||
s >>= 4;
|
s >>= 4;
|
||||||
|
@ -192,7 +194,7 @@ void SoftRenderer::TextureLookup(const GPU& gpu, u32 texparam, u32 texpal, s16 s
|
||||||
{
|
{
|
||||||
case 1: // A3I5
|
case 1: // A3I5
|
||||||
{
|
{
|
||||||
vramaddr += ((t * width) + s);
|
vramaddr += ((t << widthshift) + s);
|
||||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||||
|
|
||||||
texpal <<= 4;
|
texpal <<= 4;
|
||||||
|
@ -203,7 +205,7 @@ void SoftRenderer::TextureLookup(const GPU& gpu, u32 texparam, u32 texpal, s16 s
|
||||||
|
|
||||||
case 2: // 4-color
|
case 2: // 4-color
|
||||||
{
|
{
|
||||||
vramaddr += (((t * width) + s) >> 2);
|
vramaddr += (((t << widthshift) + s) >> 2);
|
||||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||||
pixel >>= ((s & 0x3) << 1);
|
pixel >>= ((s & 0x3) << 1);
|
||||||
pixel &= 0x3;
|
pixel &= 0x3;
|
||||||
|
@ -216,7 +218,7 @@ void SoftRenderer::TextureLookup(const GPU& gpu, u32 texparam, u32 texpal, s16 s
|
||||||
|
|
||||||
case 3: // 16-color
|
case 3: // 16-color
|
||||||
{
|
{
|
||||||
vramaddr += (((t * width) + s) >> 1);
|
vramaddr += (((t << widthshift) + s) >> 1);
|
||||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||||
if (s & 0x1) pixel >>= 4;
|
if (s & 0x1) pixel >>= 4;
|
||||||
else pixel &= 0xF;
|
else pixel &= 0xF;
|
||||||
|
@ -229,7 +231,7 @@ void SoftRenderer::TextureLookup(const GPU& gpu, u32 texparam, u32 texpal, s16 s
|
||||||
|
|
||||||
case 4: // 256-color
|
case 4: // 256-color
|
||||||
{
|
{
|
||||||
vramaddr += ((t * width) + s);
|
vramaddr += ((t << widthshift) + s);
|
||||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||||
|
|
||||||
texpal <<= 4;
|
texpal <<= 4;
|
||||||
|
@ -240,7 +242,7 @@ void SoftRenderer::TextureLookup(const GPU& gpu, u32 texparam, u32 texpal, s16 s
|
||||||
|
|
||||||
case 5: // compressed
|
case 5: // compressed
|
||||||
{
|
{
|
||||||
vramaddr += ((t & 0x3FC) * (width>>2)) + (s & 0x3FC);
|
vramaddr += ((t & 0x3FC) << (widthshift-2)) + (s & 0x3FC);
|
||||||
vramaddr += (t & 0x3);
|
vramaddr += (t & 0x3);
|
||||||
vramaddr &= 0x7FFFF; // address used for all calcs wraps around after slot 3
|
vramaddr &= 0x7FFFF; // address used for all calcs wraps around after slot 3
|
||||||
|
|
||||||
|
@ -352,7 +354,7 @@ void SoftRenderer::TextureLookup(const GPU& gpu, u32 texparam, u32 texpal, s16 s
|
||||||
|
|
||||||
case 6: // A5I3
|
case 6: // A5I3
|
||||||
{
|
{
|
||||||
vramaddr += ((t * width) + s);
|
vramaddr += ((t << widthshift) + s);
|
||||||
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
u8 pixel = ReadVRAM_Texture<u8>(vramaddr, gpu);
|
||||||
|
|
||||||
texpal <<= 4;
|
texpal <<= 4;
|
||||||
|
@ -363,7 +365,7 @@ void SoftRenderer::TextureLookup(const GPU& gpu, u32 texparam, u32 texpal, s16 s
|
||||||
|
|
||||||
case 7: // direct color
|
case 7: // direct color
|
||||||
{
|
{
|
||||||
vramaddr += (((t * width) + s) << 1);
|
vramaddr += (((t << widthshift) + s) << 1);
|
||||||
*color = ReadVRAM_Texture<u16>(vramaddr, gpu);
|
*color = ReadVRAM_Texture<u16>(vramaddr, gpu);
|
||||||
*alpha = (*color & 0x8000) ? 31 : 0;
|
*alpha = (*color & 0x8000) ? 31 : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,15 +101,15 @@ private:
|
||||||
|
|
||||||
if ((w0 & 0x1) && !(w1 & 0x1))
|
if ((w0 & 0x1) && !(w1 & 0x1))
|
||||||
{
|
{
|
||||||
this->w0n = w0 - 1;
|
this->w0n = w0 - 1 >> 1;
|
||||||
this->w0d = w0 + 1;
|
this->w0d = w0 + 1 >> 1;
|
||||||
this->w1d = w1;
|
this->w1d = w1 >> 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->w0n = w0 & 0xFFFE;
|
this->w0n = w0 >> 1;
|
||||||
this->w0d = w0 & 0xFFFE;
|
this->w0d = w0 >> 1;
|
||||||
this->w1d = w1 & 0xFFFE;
|
this->w1d = w1 >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->shift = 9;
|
this->shift = 9;
|
||||||
|
@ -138,7 +138,7 @@ private:
|
||||||
// this seems to be a proper division on hardware :/
|
// this seems to be a proper division on hardware :/
|
||||||
// I haven't been able to find cases that produce imperfect output
|
// I haven't been able to find cases that produce imperfect output
|
||||||
if (den == 0) yfactor = 0;
|
if (den == 0) yfactor = 0;
|
||||||
else yfactor = (s32)(num / den);
|
else yfactor = ((u32)num / den);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue