mirror of
https://github.com/libretro/snes9x2005.git
synced 2024-11-27 02:20:24 +00:00
131 lines
3.5 KiB
C
131 lines
3.5 KiB
C
#include "../copyright"
|
|
|
|
#ifndef _sa1_h_
|
|
#define _sa1_h_
|
|
|
|
#include "memmap.h"
|
|
#include "cpuexec.h"
|
|
#include <retro_inline.h>
|
|
|
|
typedef struct
|
|
{
|
|
uint8_t PB;
|
|
uint8_t DB;
|
|
pair P;
|
|
pair A;
|
|
pair D;
|
|
pair S;
|
|
pair X;
|
|
pair Y;
|
|
uint16_t PC;
|
|
} SSA1Registers;
|
|
|
|
typedef struct
|
|
{
|
|
SOpcodes* S9xOpcodes;
|
|
uint8_t _Carry;
|
|
uint8_t _Zero;
|
|
uint8_t _Negative;
|
|
uint8_t _Overflow;
|
|
bool CPUExecuting;
|
|
uint32_t ShiftedPB;
|
|
uint32_t ShiftedDB;
|
|
uint32_t Flags;
|
|
bool Executing;
|
|
bool NMIActive;
|
|
uint8_t IRQActive;
|
|
bool WaitingForInterrupt;
|
|
bool Waiting;
|
|
uint8_t* PC;
|
|
uint8_t* PCBase;
|
|
uint8_t* BWRAM;
|
|
uint8_t* PCAtOpcodeStart;
|
|
uint8_t* WaitAddress;
|
|
uint32_t WaitCounter;
|
|
uint8_t* WaitByteAddress1;
|
|
uint8_t* WaitByteAddress2;
|
|
uint8_t* Map [MEMMAP_NUM_BLOCKS];
|
|
uint8_t* WriteMap [MEMMAP_NUM_BLOCKS];
|
|
int16_t op1;
|
|
int16_t op2;
|
|
int arithmetic_op; /* For savestate compatibility can't change to int32_t */
|
|
int64_t sum;
|
|
bool overflow;
|
|
uint8_t VirtualBitmapFormat;
|
|
uint8_t in_char_dma;
|
|
uint8_t variable_bit_pos;
|
|
SSA1Registers Registers;
|
|
} SSA1;
|
|
|
|
#define SA1CheckZero() (SA1._Zero == 0)
|
|
#define SA1CheckCarry() (SA1._Carry)
|
|
#define SA1CheckIRQ() (SA1.Registers.PL & IRQ)
|
|
#define SA1CheckDecimal() (SA1.Registers.PL & Decimal)
|
|
#define SA1CheckIndex() (SA1.Registers.PL & IndexFlag)
|
|
#define SA1CheckMemory() (SA1.Registers.PL & MemoryFlag)
|
|
#define SA1CheckOverflow() (SA1._Overflow)
|
|
#define SA1CheckNegative() (SA1._Negative & 0x80)
|
|
#define SA1CheckEmulation() (SA1.Registers.P.W & Emulation)
|
|
|
|
#define SA1ClearFlags(f) (SA1.Registers.P.W &= ~(f))
|
|
#define SA1SetFlags(f) (SA1.Registers.P.W |= (f))
|
|
#define SA1CheckFlag(f) (SA1.Registers.PL & (f))
|
|
|
|
uint8_t S9xSA1GetByte(uint32_t);
|
|
uint16_t S9xSA1GetWord(uint32_t);
|
|
void S9xSA1SetByte(uint8_t, uint32_t);
|
|
void S9xSA1SetWord(uint16_t, uint32_t);
|
|
void S9xSA1SetPCBase(uint32_t);
|
|
uint8_t S9xGetSA1(uint32_t);
|
|
void S9xSetSA1(uint8_t, uint32_t);
|
|
|
|
extern SOpcodes S9xSA1OpcodesE1 [256];
|
|
extern SOpcodes S9xSA1OpcodesM1X1 [256];
|
|
extern SOpcodes S9xSA1OpcodesM1X0 [256];
|
|
extern SOpcodes S9xSA1OpcodesM0X1 [256];
|
|
extern SOpcodes S9xSA1OpcodesM0X0 [256];
|
|
extern SSA1 SA1;
|
|
|
|
void S9xSA1MainLoop(void);
|
|
void S9xSA1Init(void);
|
|
void S9xFixSA1AfterSnapshotLoad(void);
|
|
|
|
#define SNES_IRQ_SOURCE (1 << 7)
|
|
#define TIMER_IRQ_SOURCE (1 << 6)
|
|
#define DMA_IRQ_SOURCE (1 << 5)
|
|
|
|
static INLINE void S9xSA1UnpackStatus(void)
|
|
{
|
|
SA1._Zero = (SA1.Registers.PL & Zero) == 0;
|
|
SA1._Negative = (SA1.Registers.PL & Negative);
|
|
SA1._Carry = (SA1.Registers.PL & Carry);
|
|
SA1._Overflow = (SA1.Registers.PL & Overflow) >> 6;
|
|
}
|
|
|
|
static INLINE void S9xSA1PackStatus(void)
|
|
{
|
|
SA1.Registers.PL &= ~(Zero | Negative | Carry | Overflow);
|
|
SA1.Registers.PL |= SA1._Carry | ((SA1._Zero == 0) << 1) | (SA1._Negative & 0x80) | (SA1._Overflow << 6);
|
|
}
|
|
|
|
static INLINE void S9xSA1FixCycles(void)
|
|
{
|
|
if (SA1CheckEmulation())
|
|
SA1.S9xOpcodes = S9xSA1OpcodesE1;
|
|
else if (SA1CheckMemory())
|
|
{
|
|
if (SA1CheckIndex())
|
|
SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
|
|
else
|
|
SA1.S9xOpcodes = S9xSA1OpcodesM1X0;
|
|
}
|
|
else
|
|
{
|
|
if (SA1CheckIndex())
|
|
SA1.S9xOpcodes = S9xSA1OpcodesM0X1;
|
|
else
|
|
SA1.S9xOpcodes = S9xSA1OpcodesM0X0;
|
|
}
|
|
}
|
|
#endif
|