1 | /*****************************************************************************\ |
---|---|
2 | Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. |
3 | This file is licensed under the Snes9x License. |
4 | For further information, consult the LICENSE file in the root directory. |
5 | \*****************************************************************************/ |
6 | |
7 | #ifndef _SA1_H_ |
8 | #define _SA1_H_ |
9 | |
10 | struct SSA1Registers |
11 | { |
12 | uint8 DB; |
13 | pair P; |
14 | pair A; |
15 | pair D; |
16 | pair S; |
17 | pair X; |
18 | pair Y; |
19 | PC_t PC; |
20 | }; |
21 | |
22 | struct SSA1 |
23 | { |
24 | struct SOpcodes *S9xOpcodes; |
25 | uint8 *S9xOpLengths; |
26 | uint8 _Carry; |
27 | uint8 _Zero; |
28 | uint8 _Negative; |
29 | uint8 _Overflow; |
30 | uint32 ShiftedPB; |
31 | uint32 ShiftedDB; |
32 | |
33 | uint32 Flags; |
34 | int32 Cycles; |
35 | int32 PrevCycles; |
36 | uint8 *PCBase; |
37 | bool8 WaitingForInterrupt; |
38 | |
39 | uint8 *Map[MEMMAP_NUM_BLOCKS]; |
40 | uint8 *WriteMap[MEMMAP_NUM_BLOCKS]; |
41 | uint8 *BWRAM; |
42 | |
43 | bool8 in_char_dma; |
44 | bool8 TimerIRQLastState; |
45 | uint16 HTimerIRQPos; |
46 | uint16 VTimerIRQPos; |
47 | int16 HCounter; |
48 | int16 VCounter; |
49 | int16 PrevHCounter; |
50 | int32 MemSpeed; |
51 | int32 MemSpeedx2; |
52 | int32 arithmetic_op; |
53 | uint16 op1; |
54 | uint16 op2; |
55 | uint64 sum; |
56 | bool8 overflow; |
57 | uint8 VirtualBitmapFormat; |
58 | uint8 variable_bit_pos; |
59 | }; |
60 | |
61 | #define SA1CheckCarry() (SA1._Carry) |
62 | #define SA1CheckZero() (SA1._Zero == 0) |
63 | #define SA1CheckIRQ() (SA1Registers.PL & IRQ) |
64 | #define SA1CheckDecimal() (SA1Registers.PL & Decimal) |
65 | #define SA1CheckIndex() (SA1Registers.PL & IndexFlag) |
66 | #define SA1CheckMemory() (SA1Registers.PL & MemoryFlag) |
67 | #define SA1CheckOverflow() (SA1._Overflow) |
68 | #define SA1CheckNegative() (SA1._Negative & 0x80) |
69 | #define SA1CheckEmulation() (SA1Registers.P.W & Emulation) |
70 | |
71 | #define SA1SetFlags(f) (SA1Registers.P.W |= (f)) |
72 | #define SA1ClearFlags(f) (SA1Registers.P.W &= ~(f)) |
73 | #define SA1CheckFlag(f) (SA1Registers.PL & (f)) |
74 | |
75 | extern struct SSA1Registers SA1Registers; |
76 | extern struct SSA1 SA1; |
77 | extern uint8 SA1OpenBus; |
78 | extern struct SOpcodes S9xSA1OpcodesM1X1[256]; |
79 | extern struct SOpcodes S9xSA1OpcodesM1X0[256]; |
80 | extern struct SOpcodes S9xSA1OpcodesM0X1[256]; |
81 | extern struct SOpcodes S9xSA1OpcodesM0X0[256]; |
82 | extern uint8 S9xOpLengthsM1X1[256]; |
83 | extern uint8 S9xOpLengthsM1X0[256]; |
84 | extern uint8 S9xOpLengthsM0X1[256]; |
85 | extern uint8 S9xOpLengthsM0X0[256]; |
86 | |
87 | uint8 S9xSA1GetByte (uint32); |
88 | void S9xSA1SetByte (uint8, uint32); |
89 | uint16 S9xSA1GetWord (uint32, enum s9xwrap_t w = WRAP_NONE); |
90 | void S9xSA1SetWord (uint16, uint32, enum s9xwrap_t w = WRAP_NONE, enum s9xwriteorder_t o = WRITE_01); |
91 | void S9xSA1SetPCBase (uint32); |
92 | uint8 S9xGetSA1 (uint32); |
93 | void S9xSetSA1 (uint8, uint32); |
94 | void S9xSA1Init (void); |
95 | void S9xSA1MainLoop (void); |
96 | void S9xSA1PostLoadState (void); |
97 | |
98 | static inline void S9xSA1UnpackStatus (void) |
99 | { |
100 | SA1._Zero = (SA1Registers.PL & Zero) == 0; |
101 | SA1._Negative = (SA1Registers.PL & Negative); |
102 | SA1._Carry = (SA1Registers.PL & Carry); |
103 | SA1._Overflow = (SA1Registers.PL & Overflow) >> 6; |
104 | } |
105 | |
106 | static inline void S9xSA1PackStatus (void) |
107 | { |
108 | SA1Registers.PL &= ~(Zero | Negative | Carry | Overflow); |
109 | SA1Registers.PL |= SA1._Carry | ((SA1._Zero == 0) << 1) | (SA1._Negative & 0x80) | (SA1._Overflow << 6); |
110 | } |
111 | |
112 | static inline void S9xSA1FixCycles (void) |
113 | { |
114 | if (SA1CheckEmulation()) |
115 | { |
116 | SA1.S9xOpcodes = S9xSA1OpcodesM1X1; |
117 | SA1.S9xOpLengths = S9xOpLengthsM1X1; |
118 | } |
119 | else |
120 | if (SA1CheckMemory()) |
121 | { |
122 | if (SA1CheckIndex()) |
123 | { |
124 | SA1.S9xOpcodes = S9xSA1OpcodesM1X1; |
125 | SA1.S9xOpLengths = S9xOpLengthsM1X1; |
126 | } |
127 | else |
128 | { |
129 | SA1.S9xOpcodes = S9xSA1OpcodesM1X0; |
130 | SA1.S9xOpLengths = S9xOpLengthsM1X0; |
131 | } |
132 | } |
133 | else |
134 | { |
135 | if (SA1CheckIndex()) |
136 | { |
137 | SA1.S9xOpcodes = S9xSA1OpcodesM0X1; |
138 | SA1.S9xOpLengths = S9xOpLengthsM0X1; |
139 | } |
140 | else |
141 | { |
142 | SA1.S9xOpcodes = S9xSA1OpcodesM0X0; |
143 | SA1.S9xOpLengths = S9xOpLengthsM0X0; |
144 | } |
145 | } |
146 | } |
147 | |
148 | #endif |
149 |