initial hle support for lightrec
[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"
28#include "psxmem.h"
29#include "psxcounters.h"
30#include "psxbios.h"
31
905b7c25 32enum 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)
bc7c5acb 37 R3000E_DBE = 7, // Bus error (data load/store)
905b7c25 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
980f7a58 45enum R3000Anote {
943a507a 46 R3000ACPU_NOTIFY_CACHE_ISOLATED = 0,
47 R3000ACPU_NOTIFY_CACHE_UNISOLATED = 1,
1da9b9ae 48 R3000ACPU_NOTIFY_BEFORE_SAVE, // data arg - hle if non-null
980f7a58 49 R3000ACPU_NOTIFY_AFTER_LOAD,
943a507a 50};
943a507a 51
da65071f 52enum blockExecCaller {
53 EXEC_CALLER_BOOT,
54 EXEC_CALLER_HLE,
55};
56
ef79bbde
P
57typedef struct {
58 int (*Init)();
59 void (*Reset)();
da65071f 60 void (*Execute)();
61 void (*ExecuteBlock)(enum blockExecCaller caller); /* executes up to a jump */
ef79bbde 62 void (*Clear)(u32 Addr, u32 Size);
980f7a58 63 void (*Notify)(enum R3000Anote note, void *data);
32631e6a 64 void (*ApplyConfig)();
ef79bbde
P
65 void (*Shutdown)();
66} R3000Acpu;
67
68extern R3000Acpu *psxCpu;
69extern R3000Acpu psxInt;
ef79bbde 70extern R3000Acpu psxRec;
ef79bbde
P
71
72typedef union {
04bd10b1 73#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
ef79bbde
P
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
86typedef 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,
14b3bd95 91 t8, t9, k0, k1, gp, sp, fp, ra, lo, hi;
ef79bbde
P
92 } n;
93 u32 r[34]; /* Lo, Hi in r[32] and r[33] */
94 PAIR p[34];
95} psxGPRRegs;
96
6d75addf 97typedef union psxCP0Regs_ {
ef79bbde 98 struct {
bc7c5acb 99 u32 Reserved0, Reserved1, Reserved2, BPC,
100 Reserved4, BDA, Target, DCIC,
101 BadVAddr, BDAM, Reserved10, BPCM,
102 SR, Cause, EPC, PRid,
103 Reserved16[16];
ef79bbde
P
104 } n;
105 u32 r[32];
106 PAIR p[32];
107} psxCP0Regs;
108
109typedef struct {
110 short x, y;
111} SVector2D;
112
113typedef struct {
114 short z, pad;
115} SVector2Dz;
116
117typedef struct {
118 short x, y, z, pad;
119} SVector3D;
120
121typedef struct {
122 short x, y, z, pad;
123} LVector3D;
124
125typedef struct {
126 unsigned char r, g, b, c;
127} CBGR;
128
129typedef struct {
130 short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad;
131} SMatrix3D;
132
133typedef union {
134 struct {
135 SVector3D v0, v1, v2;
136 CBGR rgb;
137 s32 otz;
138 s32 ir0, ir1, ir2, ir3;
139 SVector2D sxy0, sxy1, sxy2, sxyp;
140 SVector2Dz sz0, sz1, sz2, sz3;
141 CBGR rgb0, rgb1, rgb2;
142 s32 reserved;
143 s32 mac0, mac1, mac2, mac3;
144 u32 irgb, orgb;
145 s32 lzcs, lzcr;
146 } n;
147 u32 r[32];
148 PAIR p[32];
149} psxCP2Data;
150
151typedef union {
152 struct {
153 SMatrix3D rMatrix;
154 s32 trX, trY, trZ;
155 SMatrix3D lMatrix;
156 s32 rbk, gbk, bbk;
157 SMatrix3D cMatrix;
158 s32 rfc, gfc, bfc;
159 s32 ofx, ofy;
160 s32 h;
161 s32 dqa, dqb;
162 s32 zsf3, zsf4;
163 s32 flag;
164 } n;
165 u32 r[32];
166 PAIR p[32];
167} psxCP2Ctrl;
168
d28b54b1 169enum {
170 PSXINT_SIO = 0,
171 PSXINT_CDR,
172 PSXINT_CDREAD,
173 PSXINT_GPUDMA,
174 PSXINT_MDECOUTDMA,
175 PSXINT_SPUDMA,
528ad661 176 PSXINT_GPUBUSY,
177 PSXINT_MDECINDMA,
57a757ce 178 PSXINT_GPUOTCDMA,
9f8b032d 179 PSXINT_CDRDMA,
d28b54b1 180 PSXINT_NEWDRC_CHECK,
5b8c000f 181 PSXINT_RCNT,
9f8b032d 182 PSXINT_CDRLID,
d9a02493 183 PSXINT_CDRPLAY_OLD, /* unused */
2b30c129 184 PSXINT_SPU_UPDATE,
d28b54b1 185 PSXINT_COUNT
186};
187
bc7c5acb 188enum R3000Abdt {
189 // corresponds to bits 31,30 of Cause reg
190 R3000A_BRANCH_TAKEN = 3,
191 R3000A_BRANCH_NOT_TAKEN = 2,
192 // none or tells that there was an exception in DS back to doBranch
193 R3000A_BRANCH_NONE_OR_EXCEPTION = 0,
194};
195
eac38522 196typedef struct psxCP2Regs {
197 psxCP2Data CP2D; /* Cop2 data registers */
198 psxCP2Ctrl CP2C; /* Cop2 control registers */
199} psxCP2Regs;
200
ef79bbde 201typedef struct {
6d75addf 202 // note: some cores like lightrec don't keep their data here,
203 // so use R3000ACPU_NOTIFY_BEFORE_SAVE to sync
ef79bbde
P
204 psxGPRRegs GPR; /* General Purpose Registers */
205 psxCP0Regs CP0; /* Coprocessor0 Registers */
eac38522 206 union {
207 struct {
208 psxCP2Data CP2D; /* Cop2 data registers */
209 psxCP2Ctrl CP2C; /* Cop2 control registers */
210 };
211 psxCP2Regs CP2;
212 };
6d75addf 213 u32 pc; /* Program counter */
214 u32 code; /* The instruction */
ef79bbde
P
215 u32 cycle;
216 u32 interrupt;
d28b54b1 217 struct { u32 sCycle, cycle; } intCycle[32];
81dbbf4c 218 u32 gteBusyCycle;
32631e6a 219 u32 muldivBusyCycle;
bc7c5acb 220 u32 subCycle; /* interpreter cycle counting */
d5aeda23 221 u32 subCycleStep;
679d5ee3 222 u32 biuReg;
bc7c5acb 223 u8 branching; /* interp. R3000A_BRANCH_TAKEN / not, 0 if not branch */
224 u8 dloadSel; /* interp. delay load state */
f9ae4f29 225 u8 dloadReg[2];
226 u32 dloadVal[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
260#ifdef __cplusplus
261}
262#endif
263#endif