#include "arm7.h"
#include "arm7i.h"
#define PC_ADJUSTMENT (-4)
#include "arm7memil.c"
#define SHL(w, k) (((UINT32)(w)) << (k))
#define SHR(w, k) (((UINT32)(w)) >> (k))
#define SAR(w, k) (((INT32)(w)) >> (k))
#define ROR(w, k) (SHR (w, k) | SHL (w, 32 - (k)))
#define RBOD(w, i) (ROR (w, (i) * 8))
#define NEG(i) ((i) & (1 << 31))
#define POS(i) (~(i) & (1 << 31))
#define ADDCARRY(a, b, c) \
((NEG (a) & NEG (b)) |\
(NEG (a) & POS (c)) |\
(NEG (b) & POS (c))) ? 1 : 0;
#define ADDOVERFLOW(a, b, c) \
((NEG (a) & NEG (b) & POS (c)) |\
(POS (a) & POS (b) & NEG (c))) ? 1 : 0;
#define SUBCARRY(a, b, c) \
((NEG (a) & POS (b)) |\
(NEG (a) & POS (c)) |\
(POS (b) & POS (c))) ? 1 : 0;
#define SUBOVERFLOW(a, b, c)\
((NEG (a) & POS (b) & POS (c)) |\
(POS (a) & NEG (b) & NEG (c))) ? 1 : 0;
static int R_WEQ (void);
static int R_WNE (void);
static int R_WCS (void);
static int R_WCC (void);
static int R_WMI (void);
static int R_WPL (void);
static int R_WVS (void);
static int R_WVC (void);
static int R_WHI (void);
static int R_WLS (void);
static int R_WGE (void);
static int R_WLT (void);
static int R_WGT (void);
static int R_WLE (void);
static int R_WAL (void);
static int R_Wxx (void);
static UINT32 WyliczPrzes (void);
static UINT32 LSL_x (UINT32 w, int i);
static UINT32 LSR_x (UINT32 w, int i);
static UINT32 ASR_x (UINT32 w, int i);
static UINT32 ROR_x (UINT32 w, int i);
static UINT32 RRX_1 (UINT32 w);
static void R_G00x (void);
static void R_MUL_MLA (void);
static void R_SWP (void);
static void R_PSR (void);
static void R_DP (void);
static void R_WynikDP (ARM7_REG w);
static void R_FlagiDP (ARM7_REG w);
static void R_SDT (void);
static void R_Und ();
static void R_BDT ();
static void R_LDM (int Rn, UINT32 adres);
static void R_STM (int Rn, UINT32 adres);
static void R_B_BL (void);
static void R_G110 (void);
static void R_G111 (void);
#ifdef ARM7_THUMB
static void R_HSDT ();
#endif
static int (*s_tabWar [16]) (void) = {R_WEQ, R_WNE, R_WCS, R_WCC, R_WMI, R_WPL,
R_WVS, R_WVC, R_WHI, R_WLS, R_WGE, R_WLT, R_WGT, R_WLE, R_WAL, R_Wxx};
static void (*s_tabGrup [8]) (void) = {R_G00x, R_G00x, R_SDT, R_SDT, R_BDT,
R_B_BL, R_G110, R_G111};
static int s_tabAL [16] = {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE};
static int s_cykle;
int ARM7i_Step ()
{
ARM7.kod = arm7_read_32 (ARM7.Rx [ARM7_PC] & ~3);
ARM7.Rx [ARM7_PC] += 4;
s_cykle = 2;
if (s_tabWar [(ARM7.kod >> 28) & 15] ())
s_tabGrup [(ARM7.kod >> 25) & 7] ();
return s_cykle;
}
int R_WEQ ()
{
return ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_Z;
}
int R_WNE ()
{
return !(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_Z);
}
int R_WCS ()
{
return ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C;
}
int R_WCC ()
{
return !(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C);
}
int R_WMI ()
{
return ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_N;
}
int R_WPL ()
{
return !(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_N);
}
int R_WVS ()
{
return ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_V;
}
int R_WVC ()
{
return !(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_V);
}
int R_WHI ()
{
return (ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C) &&\
!(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_Z);
}
int R_WLS ()
{
return !(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C) ||\
(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_Z);
}
int R_WGE ()
{
return (ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_N) &&\
(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_V) || !(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_N) &&\
!(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_V);
}
int R_WLT ()
{
return !(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_N) &&\
(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_V) || (ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_N) &&\
!(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_V);
}
int R_WGT ()
{
return !(ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_Z) && R_WGE ();
}
int R_WLE ()
{
return (ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_Z) || R_WLT ();
}
int R_WAL ()
{
return TRUE;
}
int R_Wxx ()
{
return FALSE;
}
UINT32 WyliczPrzes ()
{
int Rm, Rs, i;
UINT32 w;
Rm = ARM7.kod & 15;
if (ARM7.kod & (1 << 4))
{
s_cykle++;
if (Rm != ARM7_PC)
w = ARM7.Rx [Rm];
else
w = (ARM7.Rx [ARM7_PC] & ~3) + 12 + PC_ADJUSTMENT;
Rs = (ARM7.kod >> 8) & 15;
i = (UINT8)ARM7.Rx [Rs];
if (i == 0)
{
ARM7.carry = (ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C) ? 1 : 0;
return w;
}
switch ((ARM7.kod >> 5) & 3)
{
case 0:
w = LSL_x (w, i);
break;
case 1:
w = LSR_x (w, i);
break;
case 2:
w = ASR_x (w, i);
break;
case 3:
w = ROR_x (w, i);
break;
}
}
else
{
if (Rm != ARM7_PC)
w = ARM7.Rx [Rm];
else
w = (ARM7.Rx [ARM7_PC] & ~3) + 8 + PC_ADJUSTMENT;
i = (ARM7.kod >> 7) & 31;
switch ((ARM7.kod >> 5) & 3)
{
case 0:
w = LSL_x (w, i);
break;
case 1:
if (i > 0)
w = LSR_x (w, i);
else
w = LSR_x (w, 32);
break;
case 2:
if (i > 0)
w = ASR_x (w, i);
else
w = ASR_x (w, 32);
break;
case 3:
if (i > 0)
w = ROR_x (w, i);
else
w = RRX_1 (w);
break;
}
}
return w;
}
UINT32 LSL_x (UINT32 w, int i)
{
if (i == 0)
{
ARM7.carry = (ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C) ? 1 : 0;
return w;
}
if (i == 32)
{
ARM7.carry = w & 1;
return 0;
}
if (i > 32)
{
ARM7.carry = 0;
return 0;
}
ARM7.carry = (w & (1 << (32 - i))) ? 1 : 0;
w = SHL (w, i);
return w;
}
UINT32 LSR_x (UINT32 w, int i)
{
if (i == 32)
{
ARM7.carry = (w & (1 << 31)) ? 1 : 0;
return 0;
}
if (i > 32)
{
ARM7.carry = 0;
return 0;
}
ARM7.carry = (w & (1 << (i - 1))) ? 1 : 0;
w = SHR (w, i);
return w;
}
UINT32 ASR_x (UINT32 w, int i)
{
if (i >= 32)
{
if (w & (1 << 31))
{
ARM7.carry = 1;
return ~0;
}
ARM7.carry = 0;
return 0;
}
ARM7.carry = (w & (1 << (i - 1))) ? 1 : 0;
w = SAR (w, i);
return w;
}
UINT32 ROR_x (UINT32 w, int i)
{
i &= 0x1f;
if (i == 0)
{
ARM7.carry = (w & (1 << 31)) ? 1 : 0;
return w;
}
ARM7.carry = (w & (1 << (i-1))) ? 1 : 0;
w = ROR (w, i);
return w;
}
UINT32 RRX_1 (UINT32 w)
{
ARM7.carry = w & 1;
return (w >> 1) | ((ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C) << 2);
}
void R_G00x ()
{
#ifdef ARM7_THUMB
if ((ARM7.kod & 0x0ffffff0) == 0x012fff10) {
#ifdef ARM7_THUMB
int Rn = ARM7.Rx[ARM7.kod & 0xf];
if (Rn & 1)
{
ARM7_SetCPSR(ARM7.Rx[ARM7_CPSR] | ARM7_CPSR_T);
}
ARM7.Rx[ARM7_PC] = Rn & ~1;
#endif
}
else if ((ARM7.kod & 0x0fb00ff0) == 0x01000090)
R_SWP ();
else if ((ARM7.kod & 0x0fc000f0) == 0x00000090)
R_MUL_MLA ();
else if ((ARM7.kod & 0x0e400f90) == 0x00000090)
R_HSDT ();
else if ((ARM7.kod & 0x0f8000f0) == 0x00800090)
{
}
else if ((ARM7.kod & 0x0e400090) == 0x00400090)
R_HSDT ();
else
{
if ((ARM7.kod & 0x01900000) == 0x01000000)
R_PSR ();
else
R_DP ();
}
#else
if ((ARM7.kod & 0x03b00090) == 0x01000090)
R_SWP ();
else if ((ARM7.kod & 0x03c00090) == 0x00000090)
R_MUL_MLA ();
else
{
if ((ARM7.kod & 0x01900000) == 0x01000000)
R_PSR ();
else
R_DP ();
}
#endif
}
void R_SWP ()
{
int Rn, Rd, Rm;
UINT32 adres, w;
#define BIT_B (ARM7.kod & (1 << 21))
s_cykle += 4;
Rn = (ARM7.kod >> 16) & 15;
Rd = (ARM7.kod >> 12) & 15;
Rm = ARM7.kod & 15;
adres = ARM7.Rx [Rn];
if (BIT_B)
{
w = arm7_read_8 (adres);
arm7_write_8 (adres, (UINT8)ARM7.Rx [Rm]);
}
else
{
w = RBOD (arm7_read_32 (adres & ~3), adres & 3);
arm7_write_32 (adres & ~3, ARM7.Rx [Rm]);
}
ARM7.Rx [Rd] = w;
#undef BIT_B
}
void R_MUL_MLA ()
{
int Rm, Rs, Rn, Rd;
UINT32 wynik;
#define BIT_A (ARM7.kod & (1 << 21))
#define BIT_S (ARM7.kod & (1 << 20))
s_cykle += 2;
Rd = (ARM7.kod >> 16) & 15,
Rs = (ARM7.kod >> 8) & 15,
Rm = ARM7.kod & 15;
wynik = ARM7.Rx [Rm] * ARM7.Rx [Rs];
if (BIT_A)
{
Rn = (ARM7.kod >> 12) & 15;
wynik += ARM7.Rx [Rn];
}
ARM7.Rx [Rd] = wynik;
if (BIT_S)
{
ARM7.Rx [ARM7_CPSR] &= ~(ARM7_CPSR_N | ARM7_CPSR_Z);
if (wynik == 0)
ARM7.Rx [ARM7_CPSR] |= ARM7_CPSR_Z;
ARM7.Rx [ARM7_CPSR] |= wynik & 0x80000000;
}
#undef BIT_S
#undef BIT_A
}
void R_PSR ()
{
int Rd, Rm;
UINT32 w, arg;
#define BIT_I (ARM7.kod & (1 << 25))
#define BIT_P (ARM7.kod & (1 << 22))
if (ARM7.kod & (1 << 21))
{
Rm = ARM7.kod & 15;
if (BIT_I)
arg = ROR (ARM7.kod & 0xff, ((ARM7.kod >> 8) & 0xf) * 2);
else
arg = ARM7.Rx [Rm];
if (BIT_P)
{
w = ARM7.Rx [ARM7_SPSR];
if (ARM7_CPSR_M (ARM7.Rx [ARM7_CPSR]) > ARM7_CPSR_M_usr &&\
ARM7_CPSR_M (ARM7.Rx [ARM7_CPSR]) < ARM7_CPSR_M_sys)
{
if (ARM7.kod & (1 << 16))
w = (w & 0xffffff00) | (arg & 0x000000ff);
if (ARM7.kod & (1 << 17))
w = (w & 0xffff00ff) | (arg & 0x0000ff00);
if (ARM7.kod & (1 << 18))
w = (w & 0xff00ffff) | (arg & 0x00ff0000);
if (ARM7.kod & (1 << 19))
w = (w & 0x00ffffff) | (arg & 0xf0000000);
}
w |= 0x10;
ARM7.Rx [ARM7_SPSR] = w;
}
else
{
w = ARM7.Rx [ARM7_CPSR];
if (ARM7_CPSR_M (ARM7.Rx [ARM7_CPSR]) != ARM7_CPSR_M_usr)
{
if (ARM7.kod & (1 << 16))
w = (w & 0xffffff00) | (arg & 0x000000ff);
if (ARM7.kod & (1 << 17))
w = (w & 0xffff00ff) | (arg & 0x0000ff00);
if (ARM7.kod & (1 << 18))
w = (w & 0xff00ffff) | (arg & 0x00ff0000);
}
if (ARM7.kod & (1 << 19))
w = (w & 0x00ffffff) | (arg & 0xf0000000);
w |= 0x10;
ARM7_SetCPSR (w);
}
}
else
{
Rd = (ARM7.kod >> 12) & 15;
if (BIT_P)
ARM7.Rx [Rd] = ARM7.Rx [ARM7_SPSR];
else
ARM7.Rx [Rd] = ARM7.Rx [ARM7_CPSR];
}
#undef BIT_P
#undef BIT_I
}
void R_DP ()
{
int Rn;
ARM7_REG arg1, arg2, w;
#define BIT_I (ARM7.kod & (1 << 25))
Rn = (ARM7.kod >> 16) & 15;
if (BIT_I)
{
if (Rn != ARM7_PC)
arg1 = ARM7.Rx [Rn];
else
arg1 = (ARM7.Rx [ARM7_PC] & ~3) + 8 + PC_ADJUSTMENT;
arg2 = ROR (ARM7.kod & 0xff, ((ARM7.kod >> 8) & 0xf) * 2);
ARM7.carry = (ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C) ? 1 : 0;
}
else
{
if (Rn != ARM7_PC)
arg1 = ARM7.Rx [Rn];
else
if (ARM7.kod & (1 << 4))
arg1 = (ARM7.Rx [ARM7_PC] & ~3) + 12 + PC_ADJUSTMENT;
else
arg1 = (ARM7.Rx [ARM7_PC] & ~3) + 8 + PC_ADJUSTMENT;
arg2 = WyliczPrzes ();
}
switch ((ARM7.kod >> 21) & 15)
{
case 0:
R_WynikDP (arg1 & arg2);
break;
case 1:
R_WynikDP (arg1 ^ arg2);
break;
case 2:
w = arg1 - arg2;
ARM7.carry = SUBCARRY (arg1, arg2, w);
ARM7.overflow = SUBOVERFLOW (arg1, arg2, w);
R_WynikDP (w);
break;
case 3:
w = arg2 - arg1;
ARM7.carry = SUBCARRY (arg2, arg1, w);
ARM7.overflow = SUBOVERFLOW (arg2, arg1, w);
R_WynikDP (w);
break;
case 4:
w = arg1 + arg2;
ARM7.carry = ADDCARRY (arg1, arg2, w);
ARM7.overflow = ADDOVERFLOW (arg1, arg2, w);
R_WynikDP (w);
break;
case 5:
w = arg1 + arg2 + ((ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C) ? 1 : 0);
ARM7.carry = ADDCARRY (arg1, arg2, w);
ARM7.overflow = ADDOVERFLOW (arg1, arg2, w);
R_WynikDP (w);
break;
case 6:
w = arg1 - arg2 - ((ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C) ? 0 : 1);
ARM7.carry = SUBCARRY (arg1, arg2, w);
ARM7.overflow = SUBOVERFLOW (arg1, arg2, w);
R_WynikDP (w);
break;
case 7:
w = arg2 - arg1 - ((ARM7.Rx [ARM7_CPSR] & ARM7_CPSR_C) ? 0 : 1);
ARM7.carry = SUBCARRY (arg2, arg1, w);
ARM7.overflow = SUBOVERFLOW (arg2, arg1, w);
R_WynikDP (w);
break;
case 8:
R_FlagiDP (arg1 & arg2);
break;
case 9:
R_FlagiDP (arg1 ^ arg2);
break;
case 10:
w = arg1 - arg2;
ARM7.carry = SUBCARRY (arg1, arg2, w);
ARM7.overflow = SUBOVERFLOW (arg1, arg2, w);
R_FlagiDP (w);
break;
case 11:
w = arg1 + arg2;
ARM7.carry = ADDCARRY (arg1, arg2, w);
ARM7.overflow = ADDOVERFLOW (arg1, arg2, w);
R_FlagiDP (w);
break;
case 12:
R_WynikDP (arg1 | arg2);
break;
case 13:
R_WynikDP (arg2);
break;
case 14:
R_WynikDP (arg1 & ~arg2);
break;
case 15:
R_WynikDP (~arg2);
break;
}
#undef BIT_I
}
void R_WynikDP (ARM7_REG w)
{
int Rd;
#define BIT_S (ARM7.kod & (1 << 20))
Rd = (ARM7.kod >> 12) & 15;
ARM7.Rx [Rd] = w;
if (BIT_S)
{
if (Rd == ARM7_PC)
{
s_cykle += 4;
ARM7_SetCPSR (ARM7.Rx [ARM7_SPSR]);
}
else
R_FlagiDP (w);
}
#undef BIT_S
}
void R_FlagiDP (ARM7_REG w)
{
if (s_tabAL [(ARM7.kod >> 21) & 15])
{
ARM7.Rx [ARM7_CPSR] &= ~(ARM7_CPSR_N | ARM7_CPSR_Z | ARM7_CPSR_C |\
ARM7_CPSR_V);
ARM7.Rx [ARM7_CPSR] |= ARM7.overflow << 28;
}
else
ARM7.Rx [ARM7_CPSR] &= ~(ARM7_CPSR_N | ARM7_CPSR_Z | ARM7_CPSR_C);
ARM7.Rx [ARM7_CPSR] |= ARM7.carry << 29;
if (w == 0)
ARM7.Rx [ARM7_CPSR] |= ARM7_CPSR_Z;
ARM7.Rx [ARM7_CPSR] |= w & 0x80000000;
}
void R_SDT (void)
{
int Rn, Rd, offset;
UINT32 adres, w = 0;
#define BIT_I (ARM7.kod & (1 << 25))
#define BIT_P (ARM7.kod & (1 << 24))
#define BIT_U (ARM7.kod & (1 << 23))
#define BIT_B (ARM7.kod & (1 << 22))
#define BIT_W (ARM7.kod & (1 << 21))
#define BIT_L (ARM7.kod & (1 << 20))
if (BIT_I && (ARM7.kod & (1 << 4)))
{
R_Und ();
return;
}
Rn = (ARM7.kod >> 16) & 15,
Rd = (ARM7.kod >> 12) & 15;
if (Rn != ARM7_PC)
adres = ARM7.Rx [Rn];
else
adres = ARM7.Rx [ARM7_PC] & ~3;
if (!BIT_L)
if (Rd != ARM7_PC)
w = ARM7.Rx [Rd];
else
w = (ARM7.Rx [ARM7_PC] & ~3) + 12 + PC_ADJUSTMENT;
if (BIT_I)
offset = WyliczPrzes ();
else
offset = ARM7.kod & 0xfff;
if (!BIT_U)
offset = -offset;
if (BIT_P)
{
adres += offset;
if (BIT_W)
ARM7.Rx [Rn] = adres;
}
else
ARM7.Rx [Rn] += offset;
if (Rn == ARM7_PC)
adres += 8 + PC_ADJUSTMENT;
if (BIT_L)
{
s_cykle += 3;
if (BIT_B)
ARM7.Rx [Rd] = arm7_read_8 (adres);
else
ARM7.Rx [Rd] = RBOD (arm7_read_32 (adres & ~3), adres & 3);
}
else
{
s_cykle += 2;
if (BIT_B)
arm7_write_8 (adres, (UINT8)w);
else
arm7_write_32 (adres & ~3, w);
}
#undef BIT_L
#undef BIT_W
#undef BIT_B
#undef BIT_U
#undef BIT_P
#undef BIT_I
}
void R_Und ()
{
UINT32 sr = ARM7.Rx [ARM7_CPSR];
ARM7_SetCPSR (ARM7_CPSR_MX (sr, ARM7_CPSR_M_und) | ARM7_CPSR_I);
ARM7.Rx [ARM7_SPSR] = sr;
ARM7.Rx [ARM7_LR] = ARM7.Rx [ARM7_PC] + 4;
ARM7.Rx [ARM7_PC] = 0x00000004;
}
#define BIT_U (ARM7.kod & (1 << 23))
#define BIT_S (ARM7.kod & (1 << 22))
void R_BDT ()
{
int Rn, usr = FALSE;
UINT32 adres;
ARM7_REG cpsr = 0;
#define BIT_L (ARM7.kod & (1 << 20))
Rn = (ARM7.kod >> 16) & 15;
adres = ARM7.Rx [Rn];
if (BIT_S)
if (!BIT_L || !(ARM7.kod & (1 << ARM7_PC)))
usr = TRUE;
if (usr)
{
cpsr = ARM7.Rx [ARM7_CPSR];
ARM7_SetCPSR (ARM7_CPSR_MX (cpsr, ARM7_CPSR_M_usr));
}
if (BIT_L)
R_LDM (Rn, adres);
else
R_STM (Rn, adres);
if (usr)
ARM7_SetCPSR (cpsr);
#undef BIT_L
}
#define BIT_P (ARM7.kod & (1 << 24))
#define BIT_W (ARM7.kod & (1 << 21))
void R_LDM (int Rn, UINT32 adres)
{
int i, n, sp;
for (i = 0, n = 0; i < 16; i++)
if (ARM7.kod & (1 << i))
n++;
s_cykle += n * 2 + 1;
n <<= 2;
sp = BIT_P;
if (!BIT_U)
{
n = -n;
adres += n;
sp = !sp;
}
if (BIT_W)
ARM7.Rx [Rn] += n;
if (sp)
for (i = 0; i < 16; i++)
{
if (!(ARM7.kod & (1 << i)))
continue;
adres += 4;
ARM7.Rx [i] = arm7_read_32 (adres);
}
else
for (i = 0; i < 16; i++)
{
if (!(ARM7.kod & (1 << i)))
continue;
ARM7.Rx [i] = arm7_read_32 (adres);
adres += 4;
}
if ((ARM7.kod & (1 << ARM7_PC)) && BIT_S)
ARM7_SetCPSR (ARM7.Rx [ARM7_SPSR]);
}
void R_STM (int Rn, UINT32 adres)
{
int i, n, p, sp;
for (i = 0, n = 0, p = -1; i < 16; i++)
if (ARM7.kod & (1 << i))
{
n++;
if (p < 0)
p = i;
}
s_cykle += n * 2;
n <<= 2;
sp = BIT_P;
if (!BIT_U)
{
n = -n;
adres += n;
sp = !sp;
}
if (BIT_W && Rn != p)
ARM7.Rx [Rn] += n;
if (sp)
for (i = 0; i < 15; i++)
{
if (!(ARM7.kod & (1 << i)))
continue;
adres += 4;
arm7_write_32 (adres, ARM7.Rx [i]);
}
else
for (i = 0; i < 15; i++)
{
if (!(ARM7.kod & (1 << i)))
continue;
arm7_write_32 (adres, ARM7.Rx [i]);
adres += 4;
}
if (ARM7.kod & (1 << ARM7_PC))
{
if (sp)
{
adres += 4;
arm7_write_32 (adres, (ARM7.Rx [ARM7_PC] & ~3) + 12 + PC_ADJUSTMENT);
}
else
{
arm7_write_32 (adres, (ARM7.Rx [ARM7_PC] & ~3) + 12 + PC_ADJUSTMENT);
adres += 4;
}
}
if (BIT_W && Rn == p)
ARM7.Rx [Rn] += n;
}
#undef BIT_W
#undef BIT_P
#undef BIT_S
#undef BIT_U
void R_B_BL ()
{
INT32 offset;
#define BIT_L (ARM7.kod & (1 << 24))
s_cykle += 4;
offset = (ARM7.kod & 0x00ffffff) << 2;
if (offset & 0x02000000)
offset |= 0xfc000000;
offset += 8 + PC_ADJUSTMENT;
if (BIT_L)
ARM7.Rx [ARM7_LR] = (ARM7.Rx [ARM7_PC] & ~3) + 4 + PC_ADJUSTMENT;
ARM7.Rx [ARM7_PC] += offset;
#undef BIT_L
}
void R_G110 ()
{
}
void R_G111 ()
{
if ((ARM7.kod & 0xf0000000) == 0xe0000000)
{
}
else
{
UINT32 sr = ARM7.Rx [ARM7_CPSR];
ARM7_SetCPSR (ARM7_CPSR_MX (sr, ARM7_CPSR_M_svc) | ARM7_CPSR_I);
ARM7.Rx [ARM7_SPSR] = sr;
ARM7.Rx [ARM7_LR] = ARM7.Rx [ARM7_PC];
ARM7.Rx [ARM7_PC] = 0x00000008;
}
}
#ifdef ARM7_THUMB
void R_HSDT ()
{
int Rm, Rd, Rn, offset;
uint32_t adres, w;
#define BIT_P (ARM7.kod & (1 << 24))
#define BIT_U (ARM7.kod & (1 << 23))
#define BIT_W (ARM7.kod & (1 << 21))
#define BIT_L (ARM7.kod & (1 << 20))
#define BIT_S (ARM7.kod & (1 << 6))
#define BIT_H (ARM7.kod & (1 << 5))
Rn = (ARM7.kod >> 16) & 15;
Rd = (ARM7.kod >> 12) & 15;
if (Rn != ARM7_PC)
adres = ARM7.Rx [Rn];
else
adres = ARM7.Rx [ARM7_PC] & ~3;
if (!BIT_L)
if (Rd != ARM7_PC)
w = ARM7.Rx [Rd];
else
w = (ARM7.Rx [ARM7_PC] & ~3) + 12 + POPRAWKA_PC;
if (1 << 22)
offset = ((ARM7.kod >> 4) & 0xf0) | (ARM7.kod & 15);
else
{
Rm = ARM7.kod & 15;
offset = ARM7.Rx [Rm];
}
if (!BIT_U)
offset = -offset;
if (BIT_P)
{
adres += offset;
if (BIT_W)
ARM7.Rx [Rn] = adres;
}
else
ARM7.Rx [Rn] += offset;
if (Rn == ARM7_PC)
adres += 8 + POPRAWKA_PC;
if (BIT_L)
{
s_cykle += 3;
if (BIT_S)
{
if (BIT_H)
ARM7.Rx [Rd] = (INT32)(INT16)arm7_read_16 (adres);
else
ARM7.Rx [Rd] = (INT32)(INT8)arm7_read_8 (adres);
}
else
ARM7.Rx [Rd] = arm7_read_16 (adres);
}
else
{
s_cykle += 2;
if (BIT_H)
arm7_write_16 (adres, (UINT16)w);
else
arm7_write_8 (adres, (UINT8)w);
}
#undef BIT_H
#undef BIT_S
#undef BIT_L
#undef BIT_W
#undef BIT_U
#undef BIT_P
}
#endif