psxinterpreter: rework branching in ds
[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)
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
980f7a58 45enum R3000Anote {
943a507a 46 R3000ACPU_NOTIFY_CACHE_ISOLATED = 0,
47 R3000ACPU_NOTIFY_CACHE_UNISOLATED = 1,
980f7a58 48 R3000ACPU_NOTIFY_BEFORE_SAVE,
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,
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
6d75addf 97typedef union psxCP0Regs_ {
ef79bbde
P
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
d28b54b1 172enum {
173 PSXINT_SIO = 0,
174 PSXINT_CDR,
175 PSXINT_CDREAD,
176 PSXINT_GPUDMA,
177 PSXINT_MDECOUTDMA,
178 PSXINT_SPUDMA,
528ad661 179 PSXINT_GPUBUSY,
180 PSXINT_MDECINDMA,
57a757ce 181 PSXINT_GPUOTCDMA,
9f8b032d 182 PSXINT_CDRDMA,
d28b54b1 183 PSXINT_NEWDRC_CHECK,
5b8c000f 184 PSXINT_RCNT,
9f8b032d 185 PSXINT_CDRLID,
d9a02493 186 PSXINT_CDRPLAY_OLD, /* unused */
2b30c129 187 PSXINT_SPU_UPDATE,
d28b54b1 188 PSXINT_COUNT
189};
190
eac38522 191typedef struct psxCP2Regs {
192 psxCP2Data CP2D; /* Cop2 data registers */
193 psxCP2Ctrl CP2C; /* Cop2 control registers */
194} psxCP2Regs;
195
ef79bbde 196typedef struct {
6d75addf 197 // note: some cores like lightrec don't keep their data here,
198 // so use R3000ACPU_NOTIFY_BEFORE_SAVE to sync
ef79bbde
P
199 psxGPRRegs GPR; /* General Purpose Registers */
200 psxCP0Regs CP0; /* Coprocessor0 Registers */
eac38522 201 union {
202 struct {
203 psxCP2Data CP2D; /* Cop2 data registers */
204 psxCP2Ctrl CP2C; /* Cop2 control registers */
205 };
206 psxCP2Regs CP2;
207 };
6d75addf 208 u32 pc; /* Program counter */
209 u32 code; /* The instruction */
ef79bbde
P
210 u32 cycle;
211 u32 interrupt;
d28b54b1 212 struct { u32 sCycle, cycle; } intCycle[32];
81dbbf4c 213 u32 gteBusyCycle;
32631e6a 214 u32 muldivBusyCycle;
d5aeda23 215 u32 subCycle; /* interpreter cycle counting */
216 u32 subCycleStep;
679d5ee3 217 u32 biuReg;
218 u32 reserved[3];
81dbbf4c 219 // warning: changing anything in psxRegisters requires update of all
d5aeda23 220 // asm in libpcsxcore/new_dynarec/
ef79bbde
P
221} psxRegisters;
222
223extern psxRegisters psxRegs;
224
d28b54b1 225/* new_dynarec stuff */
226extern u32 event_cycles[PSXINT_COUNT];
227extern u32 next_interupt;
228
03f55e6b 229void new_dyna_freeze(void *f, int mode);
52082bc1 230
df717ca9 231#define new_dyna_set_event_abs(e, abs) { \
232 u32 abs_ = abs; \
233 s32 di_ = next_interupt - abs_; \
d28b54b1 234 event_cycles[e] = abs_; \
df717ca9 235 if (di_ > 0) { \
236 /*printf("%u: next_interupt %u -> %u\n", psxRegs.cycle, next_interupt, abs_);*/ \
d28b54b1 237 next_interupt = abs_; \
238 } \
239}
240
df717ca9 241#define new_dyna_set_event(e, c) \
242 new_dyna_set_event_abs(e, psxRegs.cycle + (c))
243
ef79bbde
P
244int psxInit();
245void psxReset();
246void psxShutdown();
6d75addf 247void psxException(u32 code, u32 bd, psxCP0Regs *cp0);
ef79bbde
P
248void psxBranchTest();
249void psxExecuteBios();
ef79bbde
P
250void psxJumpTest();
251
252#ifdef __cplusplus
253}
254#endif
255#endif