drc: handle regs-not-in-psxRegs case better
[pcsx_rearmed.git] / libpcsxcore / r3000a.h
1 /***************************************************************************
2  *   Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team              *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA.           *
18  ***************************************************************************/
19
20 #ifndef __R3000A_H__
21 #define __R3000A_H__
22
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26
27 #include "psxcommon.h"
28 #include "psxmem.h"
29 #include "psxcounters.h"
30 #include "psxbios.h"
31
32 enum R3000Anote {
33         R3000ACPU_NOTIFY_CACHE_ISOLATED = 0,
34         R3000ACPU_NOTIFY_CACHE_UNISOLATED = 1,
35         R3000ACPU_NOTIFY_BEFORE_SAVE,
36         R3000ACPU_NOTIFY_AFTER_LOAD,
37 };
38
39 typedef struct {
40         int  (*Init)();
41         void (*Reset)();
42         void (*Execute)();              /* executes up to a break */
43         void (*ExecuteBlock)(); /* executes up to a jump */
44         void (*Clear)(u32 Addr, u32 Size);
45         void (*Notify)(enum R3000Anote note, void *data);
46         void (*ApplyConfig)();
47         void (*Shutdown)();
48 } R3000Acpu;
49
50 extern R3000Acpu *psxCpu;
51 extern R3000Acpu psxInt;
52 extern R3000Acpu psxRec;
53
54 typedef union {
55 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
56         struct { u8 h3, h2, h, l; } b;
57         struct { s8 h3, h2, h, l; } sb;
58         struct { u16 h, l; } w;
59         struct { s16 h, l; } sw;
60 #else
61         struct { u8 l, h, h2, h3; } b;
62         struct { u16 l, h; } w;
63         struct { s8 l, h, h2, h3; } sb;
64         struct { s16 l, h; } sw;
65 #endif
66 } PAIR;
67
68 typedef union {
69         struct {
70                 u32   r0, at, v0, v1, a0, a1, a2, a3,
71                                                 t0, t1, t2, t3, t4, t5, t6, t7,
72                                                 s0, s1, s2, s3, s4, s5, s6, s7,
73                                                 t8, t9, k0, k1, gp, sp, s8, ra, lo, hi;
74         } n;
75         u32 r[34]; /* Lo, Hi in r[32] and r[33] */
76         PAIR p[34];
77 } psxGPRRegs;
78
79 typedef union psxCP0Regs_ {
80         struct {
81                 u32     Index,     Random,    EntryLo0,  EntryLo1,
82                                                 Context,   PageMask,  Wired,     Reserved0,
83                                                 BadVAddr,  Count,     EntryHi,   Compare,
84                                                 Status,    Cause,     EPC,       PRid,
85                                                 Config,    LLAddr,    WatchLO,   WatchHI,
86                                                 XContext,  Reserved1, Reserved2, Reserved3,
87                                                 Reserved4, Reserved5, ECC,       CacheErr,
88                                                 TagLo,     TagHi,     ErrorEPC,  Reserved6;
89         } n;
90         u32 r[32];
91         PAIR p[32];
92 } psxCP0Regs;
93
94 typedef struct {
95         short x, y;
96 } SVector2D;
97
98 typedef struct {
99         short z, pad;
100 } SVector2Dz;
101
102 typedef struct {
103         short x, y, z, pad;
104 } SVector3D;
105
106 typedef struct {
107         short x, y, z, pad;
108 } LVector3D;
109
110 typedef struct {
111         unsigned char r, g, b, c;
112 } CBGR;
113
114 typedef struct {
115         short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad;
116 } SMatrix3D;
117
118 typedef union {
119         struct {
120                 SVector3D     v0, v1, v2;
121                 CBGR          rgb;
122                 s32          otz;
123                 s32          ir0, ir1, ir2, ir3;
124                 SVector2D     sxy0, sxy1, sxy2, sxyp;
125                 SVector2Dz    sz0, sz1, sz2, sz3;
126                 CBGR          rgb0, rgb1, rgb2;
127                 s32          reserved;
128                 s32          mac0, mac1, mac2, mac3;
129                 u32 irgb, orgb;
130                 s32          lzcs, lzcr;
131         } n;
132         u32 r[32];
133         PAIR p[32];
134 } psxCP2Data;
135
136 typedef union {
137         struct {
138                 SMatrix3D rMatrix;
139                 s32      trX, trY, trZ;
140                 SMatrix3D lMatrix;
141                 s32      rbk, gbk, bbk;
142                 SMatrix3D cMatrix;
143                 s32      rfc, gfc, bfc;
144                 s32      ofx, ofy;
145                 s32      h;
146                 s32      dqa, dqb;
147                 s32      zsf3, zsf4;
148                 s32      flag;
149         } n;
150         u32 r[32];
151         PAIR p[32];
152 } psxCP2Ctrl;
153
154 enum {
155         PSXINT_SIO = 0,
156         PSXINT_CDR,
157         PSXINT_CDREAD,
158         PSXINT_GPUDMA,
159         PSXINT_MDECOUTDMA,
160         PSXINT_SPUDMA,
161         PSXINT_GPUBUSY,
162         PSXINT_MDECINDMA,
163         PSXINT_GPUOTCDMA,
164         PSXINT_CDRDMA,
165         PSXINT_NEWDRC_CHECK,
166         PSXINT_RCNT,
167         PSXINT_CDRLID,
168         PSXINT_CDRPLAY_OLD,     /* unused */
169         PSXINT_SPU_UPDATE,
170         PSXINT_COUNT
171 };
172
173 typedef struct psxCP2Regs {
174         psxCP2Data CP2D;        /* Cop2 data registers */
175         psxCP2Ctrl CP2C;        /* Cop2 control registers */
176 } psxCP2Regs;
177
178 typedef struct {
179         // note: some cores like lightrec don't keep their data here,
180         // so use R3000ACPU_NOTIFY_BEFORE_SAVE to sync
181         psxGPRRegs GPR;         /* General Purpose Registers */
182         psxCP0Regs CP0;         /* Coprocessor0 Registers */
183         union {
184                 struct {
185                         psxCP2Data CP2D;        /* Cop2 data registers */
186                         psxCP2Ctrl CP2C;        /* Cop2 control registers */
187                 };
188                 psxCP2Regs CP2;
189         };
190         u32 pc;                         /* Program counter */
191         u32 code;                       /* The instruction */
192         u32 cycle;
193         u32 interrupt;
194         struct { u32 sCycle, cycle; } intCycle[32];
195         u32 gteBusyCycle;
196         u32 muldivBusyCycle;
197         u32 subCycle;           /* interpreter cycle counting */
198         u32 subCycleStep;
199         u32 biuReg;
200         u32 reserved[3];
201         // warning: changing anything in psxRegisters requires update of all
202         // asm in libpcsxcore/new_dynarec/
203 } psxRegisters;
204
205 extern psxRegisters psxRegs;
206
207 /* new_dynarec stuff */
208 extern u32 event_cycles[PSXINT_COUNT];
209 extern u32 next_interupt;
210
211 void new_dyna_freeze(void *f, int mode);
212
213 #define new_dyna_set_event_abs(e, abs) { \
214         u32 abs_ = abs; \
215         s32 di_ = next_interupt - abs_; \
216         event_cycles[e] = abs_; \
217         if (di_ > 0) { \
218                 /*printf("%u: next_interupt %u -> %u\n", psxRegs.cycle, next_interupt, abs_);*/ \
219                 next_interupt = abs_; \
220         } \
221 }
222
223 #define new_dyna_set_event(e, c) \
224         new_dyna_set_event_abs(e, psxRegs.cycle + (c))
225
226 int  psxInit();
227 void psxReset();
228 void psxShutdown();
229 void psxException(u32 code, u32 bd, psxCP0Regs *cp0);
230 void psxBranchTest();
231 void psxExecuteBios();
232 void psxJumpTest();
233
234 #ifdef __cplusplus
235 }
236 #endif
237 #endif