psxinterpreter: rework branching in ds
[pcsx_rearmed.git] / libpcsxcore / r3000a.h
... / ...
CommitLineData
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
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)
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
45enum 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
52enum blockExecCaller {
53 EXEC_CALLER_BOOT,
54 EXEC_CALLER_HLE,
55};
56
57typedef 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
68extern R3000Acpu *psxCpu;
69extern R3000Acpu psxInt;
70extern R3000Acpu psxRec;
71
72typedef 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
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,
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
97typedef 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
112typedef struct {
113 short x, y;
114} SVector2D;
115
116typedef struct {
117 short z, pad;
118} SVector2Dz;
119
120typedef struct {
121 short x, y, z, pad;
122} SVector3D;
123
124typedef struct {
125 short x, y, z, pad;
126} LVector3D;
127
128typedef struct {
129 unsigned char r, g, b, c;
130} CBGR;
131
132typedef struct {
133 short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad;
134} SMatrix3D;
135
136typedef 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
154typedef 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
172enum {
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
191typedef struct psxCP2Regs {
192 psxCP2Data CP2D; /* Cop2 data registers */
193 psxCP2Ctrl CP2C; /* Cop2 control registers */
194} psxCP2Regs;
195
196typedef 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 u32 reserved[3];
219 // warning: changing anything in psxRegisters requires update of all
220 // asm in libpcsxcore/new_dynarec/
221} psxRegisters;
222
223extern psxRegisters psxRegs;
224
225/* new_dynarec stuff */
226extern u32 event_cycles[PSXINT_COUNT];
227extern u32 next_interupt;
228
229void new_dyna_freeze(void *f, int mode);
230
231#define new_dyna_set_event_abs(e, abs) { \
232 u32 abs_ = abs; \
233 s32 di_ = next_interupt - abs_; \
234 event_cycles[e] = abs_; \
235 if (di_ > 0) { \
236 /*printf("%u: next_interupt %u -> %u\n", psxRegs.cycle, next_interupt, abs_);*/ \
237 next_interupt = abs_; \
238 } \
239}
240
241#define new_dyna_set_event(e, c) \
242 new_dyna_set_event_abs(e, psxRegs.cycle + (c))
243
244int psxInit();
245void psxReset();
246void psxShutdown();
247void psxException(u32 code, u32 bd, psxCP0Regs *cp0);
248void psxBranchTest();
249void psxExecuteBios();
250void psxJumpTest();
251
252#ifdef __cplusplus
253}
254#endif
255#endif