df7882ce78b60dfbf387e555f308a43914e16f77
[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         EXEC_CALLER_OTHER,
53 };
54
55 struct psxRegisters;
56
57 typedef struct {
58         int  (*Init)();
59         void (*Reset)();
60         void (*Execute)(struct psxRegisters *regs);
61         /* executes up to a jump */
62         void (*ExecuteBlock)(struct psxRegisters *regs, enum blockExecCaller caller);
63         void (*Clear)(u32 Addr, u32 Size);
64         void (*Notify)(enum R3000Anote note, void *data);
65         void (*ApplyConfig)();
66         void (*Shutdown)();
67 } R3000Acpu;
68
69 extern R3000Acpu *psxCpu;
70 extern R3000Acpu psxInt;
71 extern R3000Acpu psxRec;
72
73 typedef union {
74 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
75         struct { u8 h3, h2, h, l; } b;
76         struct { s8 h3, h2, h, l; } sb;
77         struct { u16 h, l; } w;
78         struct { s16 h, l; } sw;
79 #else
80         struct { u8 l, h, h2, h3; } b;
81         struct { u16 l, h; } w;
82         struct { s8 l, h, h2, h3; } sb;
83         struct { s16 l, h; } sw;
84 #endif
85 } PAIR;
86
87 typedef union {
88         struct {
89                 u32   r0, at, v0, v1, a0, a1, a2, a3,
90                                                 t0, t1, t2, t3, t4, t5, t6, t7,
91                                                 s0, s1, s2, s3, s4, s5, s6, s7,
92                                                 t8, t9, k0, k1, gp, sp, fp, ra, lo, hi;
93         } n;
94         u32 r[34]; /* Lo, Hi in r[32] and r[33] */
95         PAIR p[34];
96 } psxGPRRegs;
97
98 typedef union psxCP0Regs_ {
99         struct {
100                 u32 Reserved0, Reserved1, Reserved2,  BPC,
101                     Reserved4, BDA,       Target,     DCIC,
102                     BadVAddr,  BDAM,      Reserved10, BPCM,
103                     SR,        Cause,     EPC,        PRid,
104                     Reserved16[16];
105         } n;
106         u32 r[32];
107         PAIR p[32];
108 } psxCP0Regs;
109
110 typedef struct {
111         short x, y;
112 } SVector2D;
113
114 typedef struct {
115         short z, pad;
116 } SVector2Dz;
117
118 typedef struct {
119         short x, y, z, pad;
120 } SVector3D;
121
122 typedef struct {
123         short x, y, z, pad;
124 } LVector3D;
125
126 typedef struct {
127         unsigned char r, g, b, c;
128 } CBGR;
129
130 typedef struct {
131         short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad;
132 } SMatrix3D;
133
134 typedef union {
135         struct {
136                 SVector3D     v0, v1, v2;
137                 CBGR          rgb;
138                 s32          otz;
139                 s32          ir0, ir1, ir2, ir3;
140                 SVector2D     sxy0, sxy1, sxy2, sxyp;
141                 SVector2Dz    sz0, sz1, sz2, sz3;
142                 CBGR          rgb0, rgb1, rgb2;
143                 s32          reserved;
144                 s32          mac0, mac1, mac2, mac3;
145                 u32 irgb, orgb;
146                 s32          lzcs, lzcr;
147         } n;
148         u32 r[32];
149         PAIR p[32];
150 } psxCP2Data;
151
152 typedef union {
153         struct {
154                 SMatrix3D rMatrix;
155                 s32      trX, trY, trZ;
156                 SMatrix3D lMatrix;
157                 s32      rbk, gbk, bbk;
158                 SMatrix3D cMatrix;
159                 s32      rfc, gfc, bfc;
160                 s32      ofx, ofy;
161                 s32      h;
162                 s32      dqa, dqb;
163                 s32      zsf3, zsf4;
164                 s32      flag;
165         } n;
166         u32 r[32];
167         PAIR p[32];
168 } psxCP2Ctrl;
169
170 enum R3000Abdt {
171         // corresponds to bits 31,30 of Cause reg
172         R3000A_BRANCH_TAKEN = 3,
173         R3000A_BRANCH_NOT_TAKEN = 2,
174         // none or tells that there was an exception in DS back to doBranch
175         R3000A_BRANCH_NONE_OR_EXCEPTION = 0,
176 };
177
178 typedef struct psxCP2Regs {
179         psxCP2Data CP2D;        /* Cop2 data registers */
180         psxCP2Ctrl CP2C;        /* Cop2 control registers */
181 } psxCP2Regs;
182
183 typedef struct psxRegisters {
184         // note: some cores like lightrec don't keep their data here,
185         // so use R3000ACPU_NOTIFY_BEFORE_SAVE to sync
186         psxGPRRegs GPR;         /* General Purpose Registers */
187         psxCP0Regs CP0;         /* Coprocessor0 Registers */
188         union {
189                 struct {
190                         psxCP2Data CP2D;        /* Cop2 data registers */
191                         psxCP2Ctrl CP2C;        /* Cop2 control registers */
192                 };
193                 psxCP2Regs CP2;
194         };
195         u32 pc;                         /* Program counter */
196         u32 code;                       /* The instruction */
197         u32 cycle;
198         u32 interrupt;
199         struct { u32 sCycle, cycle; } intCycle[20];
200         u32 event_cycles[20];
201         u32 psxNextCounter;
202         u32 psxNextsCounter;
203         u32 next_interupt;  /* cycle */
204         u32 unused;
205         u32 gteBusyCycle;
206         u32 muldivBusyCycle;
207         u32 subCycle;       /* interpreter cycle counting */
208         u32 subCycleStep;
209         u32 biuReg;
210         u8  stop;
211         u8  branchSeen;     /* interp. */
212         u8  branching;      /* interp. R3000A_BRANCH_TAKEN / not, 0 if not branch */
213         u8  dloadSel;       /* interp. delay load state */
214         u8  dloadReg[2];
215         u8  unused2[2];
216         u32 dloadVal[2];
217         u32 biosBranchCheck;
218         u32 cpuInRecursion;
219         u32 gpuIdleAfter;
220         u32 unused3[2];
221         // warning: changing anything in psxRegisters requires update of all
222         // asm in libpcsxcore/new_dynarec/ and may break savestates
223 } psxRegisters;
224
225 extern psxRegisters psxRegs;
226
227 /* new_dynarec stuff */
228 void ndrc_freeze(void *f, int mode);
229 void ndrc_clear_full(void);
230
231 int  psxInit();
232 void psxReset();
233 void psxShutdown();
234 void psxException(u32 code, enum R3000Abdt bdt, psxCP0Regs *cp0);
235 void psxBranchTest();
236 void psxExecuteBios();
237 int  psxExecuteBiosEnded(void);
238 void psxJumpTest();
239
240 void irq10Interrupt();
241 void psxScheduleIrq10(int irq_count, int x_cycles, int y);
242
243 #ifdef __cplusplus
244 }
245 #endif
246 #endif