#include "arm7.h"
#include "arm7i.h"
#ifdef ARM7_THUMB
#include "arm7thumb.h"
#endif
#define RX_BANK(t,r) (ARM7.Rx_bank [t][r - 8])
static void Reset (void);
struct sARM7 ARM7;
static const int s_tabTryb [32] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, ARM7_MODE_usr, ARM7_MODE_fiq, ARM7_MODE_irq,
ARM7_MODE_svc, -1, -1, -1, ARM7_MODE_abt, -1, -1, -1, ARM7_MODE_und,
-1, -1, -1, ARM7_MODE_sys};
void ARM7_Init ()
{
ARM7.fiq = 0;
ARM7.irq = 0;
ARM7.carry = 0;
ARM7.overflow = 0;
ARM7.flagi = FALSE;
ARM7.cykle = 0;
ARM7_HardReset ();
}
void ARM7_HardReset ()
{
ARM7.Rx [ARM7_CPSR] = ARM7_CPSR_I | ARM7_CPSR_F | ARM7_CPSR_M_svc;
Reset ();
}
void ARM7_SoftReset ()
{
Reset ();
}
void ARM7_SetCPSR (ARM7_REG sr)
{
int stary, nowy;
stary = s_tabTryb [ARM7_CPSR_M (ARM7.Rx [ARM7_CPSR])];
nowy = s_tabTryb [ARM7_CPSR_M (sr)];
if (nowy != stary)
{
RX_BANK (stary, ARM7_SP) = ARM7.Rx [ARM7_SP],
RX_BANK (stary, ARM7_LR) = ARM7.Rx [ARM7_LR],
RX_BANK (stary, ARM7_SPSR) = ARM7.Rx [ARM7_SPSR];
if (stary == ARM7_MODE_fiq)
{
RX_BANK (ARM7_MODE_fiq, 8) = ARM7.Rx [8],
RX_BANK (ARM7_MODE_fiq, 9) = ARM7.Rx [9],
RX_BANK (ARM7_MODE_fiq, 10) = ARM7.Rx [10],
RX_BANK (ARM7_MODE_fiq, 11) = ARM7.Rx [11],
RX_BANK (ARM7_MODE_fiq, 12) = ARM7.Rx [12];
ARM7.Rx [8] = RX_BANK (ARM7_MODE_usr, 8),
ARM7.Rx [9] = RX_BANK (ARM7_MODE_usr, 9),
ARM7.Rx [10] = RX_BANK (ARM7_MODE_usr, 10),
ARM7.Rx [11] = RX_BANK (ARM7_MODE_usr, 11),
ARM7.Rx [12] = RX_BANK (ARM7_MODE_usr, 12);
}
ARM7.Rx [ARM7_SP] = RX_BANK (nowy, ARM7_SP),
ARM7.Rx [ARM7_LR] = RX_BANK (nowy, ARM7_LR),
ARM7.Rx [ARM7_SPSR] = RX_BANK (nowy, ARM7_SPSR);
if (nowy == ARM7_MODE_fiq)
{
RX_BANK (ARM7_MODE_usr, 8) = ARM7.Rx [8],
RX_BANK (ARM7_MODE_usr, 9) = ARM7.Rx [9],
RX_BANK (ARM7_MODE_usr, 10) = ARM7.Rx [10],
RX_BANK (ARM7_MODE_usr, 11) = ARM7.Rx [11],
RX_BANK (ARM7_MODE_usr, 12) = ARM7.Rx [12];
ARM7.Rx [8] = RX_BANK (ARM7_MODE_fiq, 8),
ARM7.Rx [9] = RX_BANK (ARM7_MODE_fiq, 9),
ARM7.Rx [10] = RX_BANK (ARM7_MODE_fiq, 10),
ARM7.Rx [11] = RX_BANK (ARM7_MODE_fiq, 11),
ARM7.Rx [12] = RX_BANK (ARM7_MODE_fiq, 12);
}
}
ARM7.Rx [ARM7_CPSR] = sr;
if (ARM7.fiq)
ARM7.flagi |= ARM7_FL_FIQ;
#ifndef ARM7_DREAMCAST
if (ARM7.irq)
ARM7.flagi |= ARM7_FL_IRQ;
#endif
}
void ARM7_SetFIQ (int stan)
{
stan = stan ? TRUE : FALSE;
if (stan ^ ARM7.fiq)
{
ARM7.fiq = stan;
if (ARM7.fiq)
ARM7.flagi |= ARM7_FL_FIQ;
}
}
void ARM7_SetIRQ (int stan)
{
stan = stan ? TRUE : FALSE;
if (stan ^ ARM7.irq)
{
ARM7.irq = stan;
if (ARM7.irq)
ARM7.flagi |= ARM7_FL_IRQ;
}
}
void ARM7_CheckIRQ ()
{
UINT32 sr = ARM7.Rx [ARM7_CPSR];
ARM7.flagi &= ~(ARM7_FL_FIQ | ARM7_FL_IRQ);
if (ARM7.fiq)
{
if (!(sr & ARM7_CPSR_F))
{
ARM7_SetCPSR (ARM7_CPSR_MX (sr, ARM7_CPSR_M_fiq) | ARM7_CPSR_F | ARM7_CPSR_I);
ARM7.Rx [ARM7_SPSR] = sr;
ARM7.Rx [ARM7_LR] = ARM7.Rx [ARM7_PC] + 4;
ARM7.Rx [ARM7_PC] = 0x0000001c;
}
}
#ifndef ARM7_DREAMCAST
if (ARM7.irq)
{
if (!(sr & ARM7_CPSR_I))
{
ARM7_SetCPSR (ARM7_CPSR_MX (sr, ARM7_CPSR_M_irq) | ARM7_CPSR_I);
ARM7.Rx [ARM7_SPSR] = sr;
ARM7.Rx [ARM7_LR] = ARM7.Rx [ARM7_PC] + 4;
ARM7.Rx [ARM7_PC] = 0x00000018;
ARM7.irq = 0;
}
}
#endif
}
void ARM7_Step ()
{
#ifdef ARM7_THUMB
if (ARM7.Rx[ARM7_CPSR] & ARM7_CPSR_T)
{
ARM7i_Thumb_Step();
}
else
#endif
{
ARM7i_Step ();
}
ARM7_CheckIRQ ();
}
int ARM7_Execute (int n)
{
ARM7.cykle = 0;
while (ARM7.cykle < n)
{
ARM7_CheckIRQ ();
while (!ARM7.flagi && ARM7.cykle < n)
ARM7.cykle += ARM7i_Step ();
}
return ARM7.cykle;
}
void Reset (void)
{
ARM7.carry = 0;
ARM7.overflow = 0;
if (s_tabTryb [ARM7_CPSR_M (ARM7.Rx [ARM7_CPSR])] < 0)
ARM7.Rx [ARM7_CPSR] = ARM7_CPSR_I | ARM7_CPSR_F | ARM7_CPSR_M_svc;
RX_BANK (ARM7_MODE_svc, ARM7_LR) = ARM7.Rx [ARM7_PC];
RX_BANK (ARM7_MODE_svc, ARM7_SPSR) = ARM7.Rx [ARM7_CPSR];
ARM7_SetCPSR (ARM7_CPSR_I | ARM7_CPSR_F | ARM7_CPSR_M_svc);
ARM7.Rx [ARM7_PC] = 0x00000000;
}