drc: implement cycle reload on read
[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
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)
34 R3000E_DBE = 7, // Bus error (data load/store)
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
42enum R3000Anote {
43 R3000ACPU_NOTIFY_CACHE_ISOLATED = 0,
44 R3000ACPU_NOTIFY_CACHE_UNISOLATED = 1,
45 R3000ACPU_NOTIFY_BEFORE_SAVE, // data arg - hle if non-null
46 R3000ACPU_NOTIFY_AFTER_LOAD,
47};
48
49enum blockExecCaller {
50 EXEC_CALLER_BOOT,
51 EXEC_CALLER_HLE,
52};
53
54typedef struct {
55 int (*Init)();
56 void (*Reset)();
57 void (*Execute)();
58 void (*ExecuteBlock)(enum blockExecCaller caller); /* executes up to a jump */
59 void (*Clear)(u32 Addr, u32 Size);
60 void (*Notify)(enum R3000Anote note, void *data);
61 void (*ApplyConfig)();
62 void (*Shutdown)();
63} R3000Acpu;
64
65extern R3000Acpu *psxCpu;
66extern R3000Acpu psxInt;
67extern R3000Acpu psxRec;
68
69typedef union {
70#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
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,
88 t8, t9, k0, k1, gp, sp, fp, ra, lo, hi;
89 } n;
90 u32 r[34]; /* Lo, Hi in r[32] and r[33] */
91 PAIR p[34];
92} psxGPRRegs;
93
94typedef union psxCP0Regs_ {
95 struct {
96 u32 Reserved0, Reserved1, Reserved2, BPC,
97 Reserved4, BDA, Target, DCIC,
98 BadVAddr, BDAM, Reserved10, BPCM,
99 SR, Cause, EPC, PRid,
100 Reserved16[16];
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
166enum R3000Abdt {
167 // corresponds to bits 31,30 of Cause reg
168 R3000A_BRANCH_TAKEN = 3,
169 R3000A_BRANCH_NOT_TAKEN = 2,
170 // none or tells that there was an exception in DS back to doBranch
171 R3000A_BRANCH_NONE_OR_EXCEPTION = 0,
172};
173
174typedef struct psxCP2Regs {
175 psxCP2Data CP2D; /* Cop2 data registers */
176 psxCP2Ctrl CP2C; /* Cop2 control registers */
177} psxCP2Regs;
178
179typedef struct {
180 // note: some cores like lightrec don't keep their data here,
181 // so use R3000ACPU_NOTIFY_BEFORE_SAVE to sync
182 psxGPRRegs GPR; /* General Purpose Registers */
183 psxCP0Regs CP0; /* Coprocessor0 Registers */
184 union {
185 struct {
186 psxCP2Data CP2D; /* Cop2 data registers */
187 psxCP2Ctrl CP2C; /* Cop2 control registers */
188 };
189 psxCP2Regs CP2;
190 };
191 u32 pc; /* Program counter */
192 u32 code; /* The instruction */
193 u32 cycle;
194 u32 interrupt;
195 struct { u32 sCycle, cycle; } intCycle[32];
196 u32 gteBusyCycle;
197 u32 muldivBusyCycle;
198 u32 subCycle; /* interpreter cycle counting */
199 u32 subCycleStep;
200 u32 biuReg;
201 u8 branching; /* interp. R3000A_BRANCH_TAKEN / not, 0 if not branch */
202 u8 dloadSel; /* interp. delay load state */
203 u8 dloadReg[2];
204 u32 dloadVal[2];
205 u32 biosBranchCheck;
206 u32 cpuInRecursion;
207 u32 reserved[2];
208 // warning: changing anything in psxRegisters requires update of all
209 // asm in libpcsxcore/new_dynarec/
210} psxRegisters;
211
212extern psxRegisters psxRegs;
213
214/* new_dynarec stuff */
215void new_dyna_freeze(void *f, int mode);
216
217int psxInit();
218void psxReset();
219void psxShutdown();
220void psxException(u32 code, enum R3000Abdt bdt, psxCP0Regs *cp0);
221void psxBranchTest();
222void psxExecuteBios();
223void psxJumpTest();
224
225void irq10Interrupt();
226void psxScheduleIrq10(int irq_count, int x_cycles, int y);
227
228#ifdef __cplusplus
229}
230#endif
231#endif