aboutsummaryrefslogtreecommitdiff
path: root/source/sa1.h
blob: 84ec94acde7135ec4b5a0995e003382cfe460e2c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "../copyright"

#ifndef _sa1_h_
#define _sa1_h_

#include "memmap.h"
#include "cpuexec.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;
   int64_t   sum;
   bool   overflow;
   uint8_t   VirtualBitmapFormat;
   bool   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 S9xSA1OpcodesM1X1 [256];
extern SOpcodes S9xSA1OpcodesM1X0 [256];
extern SOpcodes S9xSA1OpcodesM0X1 [256];
extern SOpcodes S9xSA1OpcodesM0X0 [256];
extern SSA1 SA1;

void S9xSA1MainLoop();
void S9xSA1Init();
void S9xFixSA1AfterSnapshotLoad();

#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 = S9xSA1OpcodesM1X1;
   else if (SA1CheckMemory())
   {
      if (SA1CheckIndex())
         SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
      else
         SA1.S9xOpcodes = S9xSA1OpcodesM1X0;
   }
   else
   {
      if (SA1CheckIndex())
         SA1.S9xOpcodes = S9xSA1OpcodesM0X1;
      else
         SA1.S9xOpcodes = S9xSA1OpcodesM0X0;
   }
}
#endif