#pragma once
#include "GBAinline.h"
int armExecute();
int thumbExecute();
#ifdef __GNUC__
# ifndef __APPLE__
# define INSN_REGPARM __attribute__((regparm(1)))
# else
# define INSN_REGPARM /*nothing*/
# endif
# define LIKELY(x) __builtin_expect(!!(x), 1)
# define UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
# define INSN_REGPARM /*nothing*/
# define LIKELY(x) (x)
# define UNLIKELY(x) (x)
#endif
inline void UPDATE_REG(uint32_t address, uint16_t value) { WRITE16LE(&ioMem[address], value); }
extern uint32_t cpuPrefetch[2];
inline void ARM_PREFETCH()
{
cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC);
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4);
}
inline void THUMB_PREFETCH()
{
cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC);
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC + 2);
}
inline void ARM_PREFETCH_NEXT() { cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4); }
inline void THUMB_PREFETCH_NEXT() { cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC + 2); }
extern int SWITicks;
extern bool busPrefetch;
extern bool busPrefetchEnable;
extern uint32_t busPrefetchCount;
extern uint8_t memoryWait[16];
extern uint8_t memoryWait32[16];
extern uint8_t memoryWaitSeq[16];
extern uint8_t memoryWaitSeq32[16];
extern uint8_t cpuBitsSet[256];
void CPUSwitchMode(int mode, bool saveState, bool breakLoop = true);
void CPUUpdateCPSR();
void CPUUpdateFlags(bool breakLoop = true);
void CPUUndefinedException();
void CPUSoftwareInterrupt(int comment);
// Waitstates when accessing data
inline int dataTicksAccess16(uint32_t address) // DATA 8/16bits NON SEQ
{
int addr = (address >> 24) & 15;
int value = memoryWait[addr];
if (addr >= 0x08 || addr < 0x02)
{
busPrefetchCount = 0;
busPrefetch = false;
}
else if (busPrefetch)
{
int waitState = value;
if (!waitState)
waitState = 1;
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
}
return value;
}
inline int dataTicksAccess32(uint32_t address) // DATA 32bits NON SEQ
{
int addr = (address >> 24) & 15;
int value = memoryWait32[addr];
if (addr >= 0x08 || addr < 0x02)
{
busPrefetchCount = 0;
busPrefetch = false;
}
else if (busPrefetch)
{
int waitState = value;
if (!waitState)
waitState = 1;
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
}
return value;
}
inline int dataTicksAccessSeq32(uint32_t address) // DATA 32bits SEQ
{
int addr = (address >> 24) & 15;
int value = memoryWaitSeq32[addr];
if (addr >= 0x08 || addr < 0x02)
{
busPrefetchCount = 0;
busPrefetch = false;
}
else if (busPrefetch)
{
int waitState = value;
if (!waitState)
waitState = 1;
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
}
return value;
}
// Waitstates when executing opcode
inline int codeTicksAccess16(uint32_t address) // THUMB NON SEQ
{
int addr = (address >> 24) & 15;
if (addr >= 0x08 && addr <= 0x0D)
{
if (busPrefetchCount & 0x1)
{
if (busPrefetchCount & 0x2)
{
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | (busPrefetchCount & 0xFFFFFF00);
return 0;
}
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
return memoryWaitSeq[addr] - 1;
}
else
{
busPrefetchCount = 0;
return memoryWait[addr];
}
}
else
{
busPrefetchCount = 0;
return memoryWait[addr];
}
}
inline int codeTicksAccess32(uint32_t address) // ARM NON SEQ
{
int addr = (address >> 24) & 15;
if (addr >= 0x08 && addr <= 0x0D)
{
if (busPrefetchCount & 0x1)
{
if (busPrefetchCount & 0x2)
{
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | (busPrefetchCount & 0xFFFFFF00);
return 0;
}
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
return memoryWaitSeq[addr] - 1;
}
else
{
busPrefetchCount = 0;
return memoryWait32[addr];
}
}
else
{
busPrefetchCount = 0;
return memoryWait32[addr];
}
}
inline int codeTicksAccessSeq16(uint32_t address) // THUMB SEQ
{
int addr = (address >> 24) & 15;
if (addr >= 0x08 && addr <= 0x0D)
{
if (busPrefetchCount & 0x1)
{
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
return 0;
}
else if (busPrefetchCount > 0xFF)
{
busPrefetchCount = 0;
return memoryWait[addr];
}
else
return memoryWaitSeq[addr];
}
else
{
busPrefetchCount = 0;
return memoryWaitSeq[addr];
}
}
inline int codeTicksAccessSeq32(uint32_t address) // ARM SEQ
{
int addr = (address >> 24) & 15;
if (addr >= 0x08 && addr <= 0x0D)
{
if (busPrefetchCount & 0x1)
{
if (busPrefetchCount & 0x2)
{
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | (busPrefetchCount & 0xFFFFFF00);
return 0;
}
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
return memoryWaitSeq[addr];
}
else if (busPrefetchCount > 0xFF)
{
busPrefetchCount = 0;
return memoryWait32[addr];
}
else
return memoryWaitSeq32[addr];
}
else
return memoryWaitSeq32[addr];
}