Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "armdefs.h"
+#include "armemu.h"
#include "ansidecl.h"
extern unsigned ARMul_CoProInit (ARMul_State * state);
int reg = BITS (16, 19) & 7;
MMUReg[reg] = value;
+
if (reg == 1)
{
+ ARMword p,d,l,b;
+
+ p = state->prog32Sig;
+ d = state->data32Sig;
+ l = state->lateabtSig;
+ b = state->bigendSig;
+
state->prog32Sig = value >> 4 & 1;
state->data32Sig = value >> 5 & 1;
state->lateabtSig = value >> 6 & 1;
state->bigendSig = value >> 7 & 1;
- state->Emulate = TRUE; /* force ARMulator to notice these now ! */
+
+ if (p != state->prog32Sig
+ || d != state->data32Sig
+ || l != state->lateabtSig
+ || b != state->bigendSig)
+ state->Emulate = CHANGEMODE; /* Force ARMulator to notice these now. */
}
- return (ARMul_DONE);
+
+ return ARMul_DONE;
}
{
if (reg < 8)
MMUReg[reg] = value;
+
if (reg == 1)
{
+ ARMword p,d,l,b;
+
+ p = state->prog32Sig;
+ d = state->data32Sig;
+ l = state->lateabtSig;
+ b = state->bigendSig;
+
state->prog32Sig = value >> 4 & 1;
state->data32Sig = value >> 5 & 1;
state->lateabtSig = value >> 6 & 1;
state->bigendSig = value >> 7 & 1;
- state->Emulate = TRUE; /* force ARMulator to notice these now ! */
+
+
+ if (p != state->prog32Sig
+ || d != state->data32Sig
+ || l != state->lateabtSig
+ || b != state->bigendSig)
+ state->Emulate = CHANGEMODE; /* Force ARMulator to notice these now. */
}
- return (TRUE);
+
+ return TRUE;
}
ARMword ARMul_SwitchMode (ARMul_State * state, ARMword oldmode,
ARMword newmode);
-static ARMword ModeToBank (ARMul_State * state, ARMword mode);
+static ARMword ModeToBank (ARMword mode);
unsigned ARMul_NthReg (ARMword instr, unsigned number);
{
mode &= MODEBITS;
if (mode != state->Mode)
- return (state->RegBank[ModeToBank (state, (ARMword) mode)][reg]);
+ return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
else
return (state->Reg[reg]);
}
{
mode &= MODEBITS;
if (mode != state->Mode)
- state->RegBank[ModeToBank (state, (ARMword) mode)][reg] = value;
+ state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
else
state->Reg[reg] = value;
}
ARMword
ARMul_GetSPSR (ARMul_State * state, ARMword mode)
{
- ARMword bank = ModeToBank (state, mode & MODEBITS);
- if (bank == USERBANK || bank == DUMMYBANK)
- return (CPSR);
- else
- return (state->Spsr[bank]);
+ ARMword bank = ModeToBank (mode & MODEBITS);
+
+ if (! BANK_CAN_ACCESS_SPSR (bank))
+ return CPSR;
+
+ return state->Spsr[bank];
}
/***************************************************************************\
void
ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
{
- ARMword bank = ModeToBank (state, mode & MODEBITS);
- if (bank != USERBANK && bank != DUMMYBANK)
+ ARMword bank = ModeToBank (mode & MODEBITS);
+
+ if (BANK_CAN_ACCESS_SPSR (bank))
state->Spsr[bank] = value;
}
void
ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
{
- if (state->Bank != USERBANK && state->Bank != DUMMYBANK)
+ if (BANK_CAN_ACCESS_SPSR (state->Bank))
{
if (BITS (16, 19) == 9)
SETPSR (state->Spsr[state->Bank], rhs);
if (state->prog32Sig == LOW)
state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
+
oldmode = state->Mode;
+
if (state->Mode != (state->Cpsr & MODEBITS))
{
state->Mode =
ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS);
+
state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
}
else
state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
}
-
}
/***************************************************************************\
ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
{
unsigned i;
-
- oldmode = ModeToBank (state, oldmode);
- state->Bank = ModeToBank (state, newmode);
- if (oldmode != state->Bank)
+ ARMword oldbank;
+ ARMword newbank;
+
+ oldbank = ModeToBank (oldmode);
+ newbank = state->Bank = ModeToBank (newmode);
+
+ if (oldbank != newbank)
{ /* really need to do it */
- switch (oldmode)
+ switch (oldbank)
{ /* save away the old registers */
+ case SYSTEMBANK:
+ /* The System mode uses the USER bank. */
+ oldbank = USERBANK;
+ /* Fall through. */
case USERBANK:
case IRQBANK:
case SVCBANK:
case ABORTBANK:
case UNDEFBANK:
- if (state->Bank == FIQBANK)
+ if (newbank == FIQBANK)
for (i = 8; i < 13; i++)
state->RegBank[USERBANK][i] = state->Reg[i];
- state->RegBank[oldmode][13] = state->Reg[13];
- state->RegBank[oldmode][14] = state->Reg[14];
+ state->RegBank[oldbank][13] = state->Reg[13];
+ state->RegBank[oldbank][14] = state->Reg[14];
break;
case FIQBANK:
for (i = 8; i < 15; i++)
for (i = 8; i < 15; i++)
state->RegBank[DUMMYBANK][i] = 0;
break;
-
+ default:
+ abort ();
}
- switch (state->Bank)
+
+ switch (newbank)
{ /* restore the new registers */
+ case SYSTEMBANK:
+ newbank = USERBANK;
+ /* Fall through. */
case USERBANK:
case IRQBANK:
case SVCBANK:
case ABORTBANK:
case UNDEFBANK:
- if (oldmode == FIQBANK)
+ if (oldbank == FIQBANK)
for (i = 8; i < 13; i++)
state->Reg[i] = state->RegBank[USERBANK][i];
- state->Reg[13] = state->RegBank[state->Bank][13];
- state->Reg[14] = state->RegBank[state->Bank][14];
+ state->Reg[13] = state->RegBank[newbank][13];
+ state->Reg[14] = state->RegBank[newbank][14];
break;
case FIQBANK:
for (i = 8; i < 15; i++)
for (i = 8; i < 15; i++)
state->Reg[i] = 0;
break;
+ default:
+ abort ();
} /* switch */
} /* if */
- return (newmode);
+
+ return newmode;
}
/***************************************************************************\
\***************************************************************************/
static ARMword
-ModeToBank (ARMul_State * state ATTRIBUTE_UNUSED, ARMword mode)
+ModeToBank (ARMword mode)
{
- static ARMword bankofmode[] = { USERBANK, FIQBANK, IRQBANK, SVCBANK,
+ static ARMword bankofmode[] =
+ {
+ USERBANK, FIQBANK, IRQBANK, SVCBANK,
DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
- USERBANK, FIQBANK, IRQBANK, SVCBANK,
+ USERBANK, FIQBANK, IRQBANK, SVCBANK,
DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
- DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK
+ DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
+ DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
};
- if (mode > UNDEF32MODE)
- return (DUMMYBANK);
- else
- return (bankofmode[mode]);
+ if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
+ return DUMMYBANK;
+
+ return bankofmode[mode];
}
/***************************************************************************\
unsigned cpab;
cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
+
while (cpab == ARMul_BUSY)
{
ARMul_Icycles (state, 1, 0);
+
if (IntPending (state))
{
cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
else
cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source);
}
+
if (cpab == ARMul_CANT)
ARMul_Abort (state, ARMul_UndefinedInstrV);
else