arm: implemented Transfers to User Bank in LDM/STM and fixed flags corruption in branch opcodes.

This commit is contained in:
Sandro Ronco 2016-10-28 21:37:42 +02:00
parent fc5fc6d4c2
commit 6184bba010

View File

@ -588,11 +588,11 @@ void arm_cpu_device::HandleBranch( uint32_t insn )
/* Sign-extend the 24-bit offset in our calculations */
if (off & 0x2000000u)
{
R15 -= ((~(off | 0xfc000000u)) + 1) - 8;
R15 = ((R15 - (((~(off | 0xfc000000u)) + 1) - 8)) & ADDRESS_MASK) | (R15 & ~ADDRESS_MASK);
}
else
{
R15 += off + 8;
R15 = ((R15 + (off + 8)) & ADDRESS_MASK) | (R15 & ~ADDRESS_MASK);
}
m_icount -= 2 * S_CYCLE + N_CYCLE;
}
@ -1122,6 +1122,15 @@ void arm_cpu_device::HandleMemBlock( uint32_t insn )
/* Incrementing */
if (!(insn & INSN_BDT_P)) rbp = rbp + (- 4);
// S Flag Set, but R15 not in list = Transfers to User Bank
if ((insn & INSN_BDT_S) && !(insn & 0x8000))
{
int curmode = MODE;
R15 = R15 & ~MODE_MASK;
result = loadInc( insn & 0xffff, rbp, insn&INSN_BDT_S );
R15 = R15 | curmode;
}
else
result = loadInc( insn & 0xffff, rbp, insn&INSN_BDT_S );
if (insn & 0x8000)
@ -1163,6 +1172,15 @@ void arm_cpu_device::HandleMemBlock( uint32_t insn )
rbp = rbp - (- 4);
}
// S Flag Set, but R15 not in list = Transfers to User Bank
if ((insn & INSN_BDT_S) && !(insn & 0x8000))
{
int curmode = MODE;
R15 = R15 & ~MODE_MASK;
result = loadDec( insn&0xffff, rbp, insn&INSN_BDT_S, &deferredR15, &defer );
R15 = R15 | curmode;
}
else
result = loadDec( insn&0xffff, rbp, insn&INSN_BDT_S, &deferredR15, &defer );
if (insn & INSN_BDT_W)
@ -1210,7 +1228,18 @@ void arm_cpu_device::HandleMemBlock( uint32_t insn )
{
rbp = rbp + (- 4);
}
// S bit set = Transfers to User Bank
if (insn & INSN_BDT_S)
{
int curmode = MODE;
R15 = R15 & ~MODE_MASK;
result = storeInc( insn&0xffff, rbp );
R15 = R15 | curmode;
}
else
result = storeInc( insn&0xffff, rbp );
if( insn & INSN_BDT_W )
{
SetRegister(rb,GetRegister(rb)+result*4);
@ -1223,7 +1252,18 @@ void arm_cpu_device::HandleMemBlock( uint32_t insn )
{
rbp = rbp - (- 4);
}
// S bit set = Transfers to User Bank
if (insn & INSN_BDT_S)
{
int curmode = MODE;
R15 = R15 & ~MODE_MASK;
result = storeDec( insn&0xffff, rbp );
R15 = R15 | curmode;
}
else
result = storeDec( insn&0xffff, rbp );
if( insn & INSN_BDT_W )
{
SetRegister(rb,GetRegister(rb)-result*4);