#include "../copyright" #ifndef _sa1_h_ #define _sa1_h_ #include "memmap.h" #include "cpuexec.h" #include 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