drc: avoid excessive recursion in hle mode
[pcsx_rearmed.git] / libpcsxcore / r3000a.h
CommitLineData
ef79bbde
P
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
24extern "C" {
25#endif
26
27#include "psxcommon.h"
ef79bbde 28
905b7c25 29enum R3000Aexception {
30 R3000E_Int = 0, // Interrupt
31 R3000E_AdEL = 4, // Address error (on load/I-fetch)
32 R3000E_AdES = 5, // Address error (on store)
33 R3000E_IBE = 6, // Bus error (instruction fetch)
bc7c5acb 34 R3000E_DBE = 7, // Bus error (data load/store)
905b7c25 35 R3000E_Syscall = 8, // syscall instruction
36 R3000E_Bp = 9, // Breakpoint - a break instruction
37 R3000E_RI = 10, // reserved instruction
38 R3000E_CpU = 11, // Co-Processor unusable
39 R3000E_Ov = 12 // arithmetic overflow
40};
41
980f7a58 42enum R3000Anote {
943a507a 43 R3000ACPU_NOTIFY_CACHE_ISOLATED = 0,
44 R3000ACPU_NOTIFY_CACHE_UNISOLATED = 1,
1da9b9ae 45 R3000ACPU_NOTIFY_BEFORE_SAVE, // data arg - hle if non-null
980f7a58 46 R3000ACPU_NOTIFY_AFTER_LOAD,
943a507a 47};
943a507a 48
da65071f 49enum blockExecCaller {
50 EXEC_CALLER_BOOT,
51 EXEC_CALLER_HLE,
52};
53
ef79bbde
P
54typedef struct {
55 int (*Init)();
56 void (*Reset)();
da65071f 57 void (*Execute)();
58 void (*ExecuteBlock)(enum blockExecCaller caller); /* executes up to a jump */
ef79bbde 59 void (*Clear)(u32 Addr, u32 Size);
980f7a58 60 void (*Notify)(enum R3000Anote note, void *data);
32631e6a 61 void (*ApplyConfig)();
ef79bbde
P
62 void (*Shutdown)();
63} R3000Acpu;
64
65extern R3000Acpu *psxCpu;
66extern R3000Acpu psxInt;
ef79bbde 67extern R3000Acpu psxRec;
ef79bbde
P
68
69typedef union {
04bd10b1 70#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
ef79bbde
P
71 struct { u8 h3, h2, h, l; } b;
72 struct { s8 h3, h2, h, l; } sb;
73 struct { u16 h, l; } w;
74 struct { s16 h, l; } sw;
75#else
76 struct { u8 l, h, h2, h3; } b;
77 struct { u16 l, h; } w;
78 struct { s8 l, h, h2, h3; } sb;
79 struct { s16 l, h; } sw;
80#endif
81} PAIR;
82
83typedef union {
84 struct {
85 u32 r0, at, v0, v1, a0, a1, a2, a3,
86 t0, t1, t2, t3, t4, t5, t6, t7,
87 s0, s1, s2, s3, s4, s5, s6, s7,
14b3bd95 88 t8, t9, k0, k1, gp, sp, fp, ra, lo, hi;
ef79bbde
P
89 } n;
90 u32 r[34]; /* Lo, Hi in r[32] and r[33] */
91 PAIR p[34];
92} psxGPRRegs;
93
6d75addf 94typedef union psxCP0Regs_ {
ef79bbde 95 struct {
bc7c5acb 96 u32 Reserved0, Reserved1, Reserved2, BPC,
97 Reserved4, BDA, Target, DCIC,
98 BadVAddr, BDAM, Reserved10, BPCM,
99 SR, Cause, EPC, PRid,
100 Reserved16[16];
ef79bbde
P
101 } n;
102 u32 r[32];
103 PAIR p[32];
104} psxCP0Regs;
105
106typedef struct {
107 short x, y;
108} SVector2D;
109
110typedef struct {
111 short z, pad;
112} SVector2Dz;
113
114typedef struct {
115 short x, y, z, pad;
116} SVector3D;
117
118typedef struct {
119 short x, y, z, pad;
120} LVector3D;
121
122typedef struct {
123 unsigned char r, g, b, c;
124} CBGR;
125
126typedef struct {
127 short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad;
128} SMatrix3D;
129
130typedef union {
131 struct {
132 SVector3D v0, v1, v2;
133 CBGR rgb;
134 s32 otz;
135 s32 ir0, ir1, ir2, ir3;
136 SVector2D sxy0, sxy1, sxy2, sxyp;
137 SVector2Dz sz0, sz1, sz2, sz3;
138 CBGR rgb0, rgb1, rgb2;
139 s32 reserved;
140 s32 mac0, mac1, mac2, mac3;
141 u32 irgb, orgb;
142 s32 lzcs, lzcr;
143 } n;
144 u32 r[32];
145 PAIR p[32];
146} psxCP2Data;
147
148typedef union {
149 struct {
150 SMatrix3D rMatrix;
151 s32 trX, trY, trZ;
152 SMatrix3D lMatrix;
153 s32 rbk, gbk, bbk;
154 SMatrix3D cMatrix;
155 s32 rfc, gfc, bfc;
156 s32 ofx, ofy;
157 s32 h;
158 s32 dqa, dqb;
159 s32 zsf3, zsf4;
160 s32 flag;
161 } n;
162 u32 r[32];
163 PAIR p[32];
164} psxCP2Ctrl;
165
d28b54b1 166enum {
167 PSXINT_SIO = 0,
168 PSXINT_CDR,
169 PSXINT_CDREAD,
170 PSXINT_GPUDMA,
171 PSXINT_MDECOUTDMA,
172 PSXINT_SPUDMA,
528ad661 173 PSXINT_GPUBUSY,
174 PSXINT_MDECINDMA,
57a757ce 175 PSXINT_GPUOTCDMA,
9f8b032d 176 PSXINT_CDRDMA,
d28b54b1 177 PSXINT_NEWDRC_CHECK,
5b8c000f 178 PSXINT_RCNT,
9f8b032d 179 PSXINT_CDRLID,
11d23573 180 PSXINT_IRQ10,
2b30c129 181 PSXINT_SPU_UPDATE,
d28b54b1 182 PSXINT_COUNT
183};
184
bc7c5acb 185enum R3000Abdt {
186 // corresponds to bits 31,30 of Cause reg
187 R3000A_BRANCH_TAKEN = 3,
188 R3000A_BRANCH_NOT_TAKEN = 2,
189 // none or tells that there was an exception in DS back to doBranch
190 R3000A_BRANCH_NONE_OR_EXCEPTION = 0,
191};
192
eac38522 193typedef struct psxCP2Regs {
194 psxCP2Data CP2D; /* Cop2 data registers */
195 psxCP2Ctrl CP2C; /* Cop2 control registers */
196} psxCP2Regs;
197
ef79bbde 198typedef struct {
6d75addf 199 // note: some cores like lightrec don't keep their data here,
200 // so use R3000ACPU_NOTIFY_BEFORE_SAVE to sync
ef79bbde
P
201 psxGPRRegs GPR; /* General Purpose Registers */
202 psxCP0Regs CP0; /* Coprocessor0 Registers */
eac38522 203 union {
204 struct {
205 psxCP2Data CP2D; /* Cop2 data registers */
206 psxCP2Ctrl CP2C; /* Cop2 control registers */
207 };
208 psxCP2Regs CP2;
209 };
6d75addf 210 u32 pc; /* Program counter */
211 u32 code; /* The instruction */
ef79bbde
P
212 u32 cycle;
213 u32 interrupt;
d28b54b1 214 struct { u32 sCycle, cycle; } intCycle[32];
81dbbf4c 215 u32 gteBusyCycle;
32631e6a 216 u32 muldivBusyCycle;
bc7c5acb 217 u32 subCycle; /* interpreter cycle counting */
d5aeda23 218 u32 subCycleStep;
679d5ee3 219 u32 biuReg;
bc7c5acb 220 u8 branching; /* interp. R3000A_BRANCH_TAKEN / not, 0 if not branch */
221 u8 dloadSel; /* interp. delay load state */
f9ae4f29 222 u8 dloadReg[2];
223 u32 dloadVal[2];
de74f599 224 u32 biosBranchCheck;
65722e04 225 u32 cpuInRecursion;
226 u32 reserved[2];
81dbbf4c 227 // warning: changing anything in psxRegisters requires update of all
d5aeda23 228 // asm in libpcsxcore/new_dynarec/
ef79bbde
P
229} psxRegisters;
230
231extern psxRegisters psxRegs;
232
d28b54b1 233/* new_dynarec stuff */
234extern u32 event_cycles[PSXINT_COUNT];
235extern u32 next_interupt;
236
03f55e6b 237void new_dyna_freeze(void *f, int mode);
52082bc1 238
df717ca9 239#define new_dyna_set_event_abs(e, abs) { \
240 u32 abs_ = abs; \
241 s32 di_ = next_interupt - abs_; \
d28b54b1 242 event_cycles[e] = abs_; \
df717ca9 243 if (di_ > 0) { \
244 /*printf("%u: next_interupt %u -> %u\n", psxRegs.cycle, next_interupt, abs_);*/ \
d28b54b1 245 next_interupt = abs_; \
246 } \
247}
248
df717ca9 249#define new_dyna_set_event(e, c) \
250 new_dyna_set_event_abs(e, psxRegs.cycle + (c))
251
ef79bbde
P
252int psxInit();
253void psxReset();
254void psxShutdown();
bc7c5acb 255void psxException(u32 code, enum R3000Abdt bdt, psxCP0Regs *cp0);
ef79bbde
P
256void psxBranchTest();
257void psxExecuteBios();
ef79bbde
P
258void psxJumpTest();
259
11d23573 260void irq10Interrupt();
261void psxScheduleIrq10(int irq_count, int x_cycles, int y);
262
ef79bbde
P
263#ifdef __cplusplus
264}
265#endif
266#endif