psxinterpreter: rework load delays
[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 R3000Aexception {
33         R3000E_Int = 0,      // Interrupt
34         R3000E_AdEL = 4,     // Address error (on load/I-fetch)
35         R3000E_AdES = 5,     // Address error (on store)
36         R3000E_IBE = 6,      // Bus error (instruction fetch)
37         R3000E_DBE = 7,      // Bus error (data load)
38         R3000E_Syscall = 8,  // syscall instruction
39         R3000E_Bp = 9,       // Breakpoint - a break instruction
40         R3000E_RI = 10,      // reserved instruction
41         R3000E_CpU = 11,     // Co-Processor unusable
42         R3000E_Ov = 12       // arithmetic overflow
43 };
44
45 enum R3000Anote {
46         R3000ACPU_NOTIFY_CACHE_ISOLATED = 0,
47         R3000ACPU_NOTIFY_CACHE_UNISOLATED = 1,
48         R3000ACPU_NOTIFY_BEFORE_SAVE,
49         R3000ACPU_NOTIFY_AFTER_LOAD,
50 };
51
52 enum blockExecCaller {
53         EXEC_CALLER_BOOT,
54         EXEC_CALLER_HLE,
55 };
56
57 typedef struct {
58         int  (*Init)();
59         void (*Reset)();
60         void (*Execute)();
61         void (*ExecuteBlock)(enum blockExecCaller caller); /* executes up to a jump */
62         void (*Clear)(u32 Addr, u32 Size);
63         void (*Notify)(enum R3000Anote note, void *data);
64         void (*ApplyConfig)();
65         void (*Shutdown)();
66 } R3000Acpu;
67
68 extern R3000Acpu *psxCpu;
69 extern R3000Acpu psxInt;
70 extern R3000Acpu psxRec;
71
72 typedef union {
73 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
74         struct { u8 h3, h2, h, l; } b;
75         struct { s8 h3, h2, h, l; } sb;
76         struct { u16 h, l; } w;
77         struct { s16 h, l; } sw;
78 #else
79         struct { u8 l, h, h2, h3; } b;
80         struct { u16 l, h; } w;
81         struct { s8 l, h, h2, h3; } sb;
82         struct { s16 l, h; } sw;
83 #endif
84 } PAIR;
85
86 typedef union {
87         struct {
88                 u32   r0, at, v0, v1, a0, a1, a2, a3,
89                                                 t0, t1, t2, t3, t4, t5, t6, t7,
90                                                 s0, s1, s2, s3, s4, s5, s6, s7,
91                                                 t8, t9, k0, k1, gp, sp, s8, ra, lo, hi;
92         } n;
93         u32 r[34]; /* Lo, Hi in r[32] and r[33] */
94         PAIR p[34];
95 } psxGPRRegs;
96
97 typedef union psxCP0Regs_ {
98         struct {
99                 u32     Index,     Random,    EntryLo0,  EntryLo1,
100                                                 Context,   PageMask,  Wired,     Reserved0,
101                                                 BadVAddr,  Count,     EntryHi,   Compare,
102                                                 Status,    Cause,     EPC,       PRid,
103                                                 Config,    LLAddr,    WatchLO,   WatchHI,
104                                                 XContext,  Reserved1, Reserved2, Reserved3,
105                                                 Reserved4, Reserved5, ECC,       CacheErr,
106                                                 TagLo,     TagHi,     ErrorEPC,  Reserved6;
107         } n;
108         u32 r[32];
109         PAIR p[32];
110 } psxCP0Regs;
111
112 typedef struct {
113         short x, y;
114 } SVector2D;
115
116 typedef struct {
117         short z, pad;
118 } SVector2Dz;
119
120 typedef struct {
121         short x, y, z, pad;
122 } SVector3D;
123
124 typedef struct {
125         short x, y, z, pad;
126 } LVector3D;
127
128 typedef struct {
129         unsigned char r, g, b, c;
130 } CBGR;
131
132 typedef struct {
133         short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad;
134 } SMatrix3D;
135
136 typedef union {
137         struct {
138                 SVector3D     v0, v1, v2;
139                 CBGR          rgb;
140                 s32          otz;
141                 s32          ir0, ir1, ir2, ir3;
142                 SVector2D     sxy0, sxy1, sxy2, sxyp;
143                 SVector2Dz    sz0, sz1, sz2, sz3;
144                 CBGR          rgb0, rgb1, rgb2;
145                 s32          reserved;
146                 s32          mac0, mac1, mac2, mac3;
147                 u32 irgb, orgb;
148                 s32          lzcs, lzcr;
149         } n;
150         u32 r[32];
151         PAIR p[32];
152 } psxCP2Data;
153
154 typedef union {
155         struct {
156                 SMatrix3D rMatrix;
157                 s32      trX, trY, trZ;
158                 SMatrix3D lMatrix;
159                 s32      rbk, gbk, bbk;
160                 SMatrix3D cMatrix;
161                 s32      rfc, gfc, bfc;
162                 s32      ofx, ofy;
163                 s32      h;
164                 s32      dqa, dqb;
165                 s32      zsf3, zsf4;
166                 s32      flag;
167         } n;
168         u32 r[32];
169         PAIR p[32];
170 } psxCP2Ctrl;
171
172 enum {
173         PSXINT_SIO = 0,
174         PSXINT_CDR,
175         PSXINT_CDREAD,
176         PSXINT_GPUDMA,
177         PSXINT_MDECOUTDMA,
178         PSXINT_SPUDMA,
179         PSXINT_GPUBUSY,
180         PSXINT_MDECINDMA,
181         PSXINT_GPUOTCDMA,
182         PSXINT_CDRDMA,
183         PSXINT_NEWDRC_CHECK,
184         PSXINT_RCNT,
185         PSXINT_CDRLID,
186         PSXINT_CDRPLAY_OLD,     /* unused */
187         PSXINT_SPU_UPDATE,
188         PSXINT_COUNT
189 };
190
191 typedef struct psxCP2Regs {
192         psxCP2Data CP2D;        /* Cop2 data registers */
193         psxCP2Ctrl CP2C;        /* Cop2 control registers */
194 } psxCP2Regs;
195
196 typedef struct {
197         // note: some cores like lightrec don't keep their data here,
198         // so use R3000ACPU_NOTIFY_BEFORE_SAVE to sync
199         psxGPRRegs GPR;         /* General Purpose Registers */
200         psxCP0Regs CP0;         /* Coprocessor0 Registers */
201         union {
202                 struct {
203                         psxCP2Data CP2D;        /* Cop2 data registers */
204                         psxCP2Ctrl CP2C;        /* Cop2 control registers */
205                 };
206                 psxCP2Regs CP2;
207         };
208         u32 pc;                         /* Program counter */
209         u32 code;                       /* The instruction */
210         u32 cycle;
211         u32 interrupt;
212         struct { u32 sCycle, cycle; } intCycle[32];
213         u32 gteBusyCycle;
214         u32 muldivBusyCycle;
215         u32 subCycle;           /* interpreter cycle counting */
216         u32 subCycleStep;
217         u32 biuReg;
218         u8  reserved;
219         u8  dloadSel;
220         u8  dloadReg[2];
221         u32 dloadVal[2];
222         // warning: changing anything in psxRegisters requires update of all
223         // asm in libpcsxcore/new_dynarec/
224 } psxRegisters;
225
226 extern psxRegisters psxRegs;
227
228 /* new_dynarec stuff */
229 extern u32 event_cycles[PSXINT_COUNT];
230 extern u32 next_interupt;
231
232 void new_dyna_freeze(void *f, int mode);
233
234 #define new_dyna_set_event_abs(e, abs) { \
235         u32 abs_ = abs; \
236         s32 di_ = next_interupt - abs_; \
237         event_cycles[e] = abs_; \
238         if (di_ > 0) { \
239                 /*printf("%u: next_interupt %u -> %u\n", psxRegs.cycle, next_interupt, abs_);*/ \
240                 next_interupt = abs_; \
241         } \
242 }
243
244 #define new_dyna_set_event(e, c) \
245         new_dyna_set_event_abs(e, psxRegs.cycle + (c))
246
247 int  psxInit();
248 void psxReset();
249 void psxShutdown();
250 void psxException(u32 code, u32 bd, psxCP0Regs *cp0);
251 void psxBranchTest();
252 void psxExecuteBios();
253 void psxJumpTest();
254
255 #ifdef __cplusplus
256 }
257 #endif
258 #endif