drc: implement cycle reload on read
[pcsx_rearmed.git] / libpcsxcore / r3000a.h
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
24 extern "C" {
25 #endif
26
27 #include "psxcommon.h"
28
29 enum 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
42 enum 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
49 enum blockExecCaller {
50         EXEC_CALLER_BOOT,
51         EXEC_CALLER_HLE,
52 };
53
54 typedef 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
65 extern R3000Acpu *psxCpu;
66 extern R3000Acpu psxInt;
67 extern R3000Acpu psxRec;
68
69 typedef 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
83 typedef 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
94 typedef 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
106 typedef struct {
107         short x, y;
108 } SVector2D;
109
110 typedef struct {
111         short z, pad;
112 } SVector2Dz;
113
114 typedef struct {
115         short x, y, z, pad;
116 } SVector3D;
117
118 typedef struct {
119         short x, y, z, pad;
120 } LVector3D;
121
122 typedef struct {
123         unsigned char r, g, b, c;
124 } CBGR;
125
126 typedef struct {
127         short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad;
128 } SMatrix3D;
129
130 typedef 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
148 typedef 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
166 enum 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
174 typedef struct psxCP2Regs {
175         psxCP2Data CP2D;        /* Cop2 data registers */
176         psxCP2Ctrl CP2C;        /* Cop2 control registers */
177 } psxCP2Regs;
178
179 typedef 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
212 extern psxRegisters psxRegs;
213
214 /* new_dynarec stuff */
215 void new_dyna_freeze(void *f, int mode);
216
217 int  psxInit();
218 void psxReset();
219 void psxShutdown();
220 void psxException(u32 code, enum R3000Abdt bdt, psxCP0Regs *cp0);
221 void psxBranchTest();
222 void psxExecuteBios();
223 void psxJumpTest();
224
225 void irq10Interrupt();
226 void psxScheduleIrq10(int irq_count, int x_cycles, int y);
227
228 #ifdef __cplusplus
229 }
230 #endif
231 #endif