1 |
william |
31 |
/* PCSX2 - PS2 Emulator for PCs |
2 |
|
|
* Copyright (C) 2002-2010 PCSX2 Dev Team |
3 |
|
|
* |
4 |
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms |
5 |
|
|
* of the GNU Lesser General Public License as published by the Free Software Found- |
6 |
|
|
* ation, either version 3 of the License, or (at your option) any later version. |
7 |
|
|
* |
8 |
|
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
9 |
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
10 |
|
|
* PURPOSE. See the GNU General Public License for more details. |
11 |
|
|
* |
12 |
|
|
* You should have received a copy of the GNU General Public License along with PCSX2. |
13 |
|
|
* If not, see <http://www.gnu.org/licenses/>. |
14 |
|
|
*/ |
15 |
|
|
|
16 |
|
|
#ifndef __R3000A_H__ |
17 |
|
|
#define __R3000A_H__ |
18 |
|
|
|
19 |
|
|
#include <stdio.h> |
20 |
|
|
|
21 |
|
|
union GPRRegs { |
22 |
|
|
struct { |
23 |
|
|
u32 r0, at, v0, v1, a0, a1, a2, a3, |
24 |
|
|
t0, t1, t2, t3, t4, t5, t6, t7, |
25 |
|
|
s0, s1, s2, s3, s4, s5, s6, s7, |
26 |
|
|
t8, t9, k0, k1, gp, sp, s8, ra, hi, lo; // hi needs to be at index 32! don't change |
27 |
|
|
} n; |
28 |
|
|
u32 r[34]; /* Lo, Hi in r[33] and r[32] */ |
29 |
|
|
}; |
30 |
|
|
|
31 |
|
|
union CP0Regs { |
32 |
|
|
struct { |
33 |
|
|
u32 Index, Random, EntryLo0, EntryLo1, |
34 |
|
|
Context, PageMask, Wired, Reserved0, |
35 |
|
|
BadVAddr, Count, EntryHi, Compare, |
36 |
|
|
Status, Cause, EPC, PRid, |
37 |
|
|
Config, LLAddr, WatchLO, WatchHI, |
38 |
|
|
XContext, Reserved1, Reserved2, Reserved3, |
39 |
|
|
Reserved4, Reserved5, ECC, CacheErr, |
40 |
|
|
TagLo, TagHi, ErrorEPC, Reserved6; |
41 |
|
|
} n; |
42 |
|
|
u32 r[32]; |
43 |
|
|
}; |
44 |
|
|
|
45 |
|
|
struct SVector2D { |
46 |
|
|
short x, y; |
47 |
|
|
}; |
48 |
|
|
|
49 |
|
|
struct SVector2Dz { |
50 |
|
|
short z, pad; |
51 |
|
|
}; |
52 |
|
|
|
53 |
|
|
struct SVector3D { |
54 |
|
|
short x, y, z, pad; |
55 |
|
|
}; |
56 |
|
|
|
57 |
|
|
struct LVector3D { |
58 |
|
|
short x, y, z, pad; |
59 |
|
|
}; |
60 |
|
|
|
61 |
|
|
struct CBGR { |
62 |
|
|
unsigned char r, g, b, c; |
63 |
|
|
}; |
64 |
|
|
|
65 |
|
|
struct SMatrix3D { |
66 |
|
|
short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad; |
67 |
|
|
}; |
68 |
|
|
|
69 |
|
|
union CP2Data { |
70 |
|
|
struct { |
71 |
|
|
SVector3D v0, v1, v2; |
72 |
|
|
CBGR rgb; |
73 |
|
|
s32 otz; |
74 |
|
|
s32 ir0, ir1, ir2, ir3; |
75 |
|
|
SVector2D sxy0, sxy1, sxy2, sxyp; |
76 |
|
|
SVector2Dz sz0, sz1, sz2, sz3; |
77 |
|
|
CBGR rgb0, rgb1, rgb2; |
78 |
|
|
s32 reserved; |
79 |
|
|
s32 mac0, mac1, mac2, mac3; |
80 |
|
|
u32 irgb, orgb; |
81 |
|
|
s32 lzcs, lzcr; |
82 |
|
|
} n; |
83 |
|
|
u32 r[32]; |
84 |
|
|
}; |
85 |
|
|
|
86 |
|
|
union CP2Ctrl { |
87 |
|
|
struct { |
88 |
|
|
SMatrix3D rMatrix; |
89 |
|
|
s32 trX, trY, trZ; |
90 |
|
|
SMatrix3D lMatrix; |
91 |
|
|
s32 rbk, gbk, bbk; |
92 |
|
|
SMatrix3D cMatrix; |
93 |
|
|
s32 rfc, gfc, bfc; |
94 |
|
|
s32 ofx, ofy; |
95 |
|
|
s32 h; |
96 |
|
|
s32 dqa, dqb; |
97 |
|
|
s32 zsf3, zsf4; |
98 |
|
|
s32 flag; |
99 |
|
|
} n; |
100 |
|
|
u32 r[32]; |
101 |
|
|
}; |
102 |
|
|
|
103 |
|
|
struct psxRegisters { |
104 |
|
|
GPRRegs GPR; /* General Purpose Registers */ |
105 |
|
|
CP0Regs CP0; /* Coprocessor0 Registers */ |
106 |
|
|
CP2Data CP2D; /* Cop2 data registers */ |
107 |
|
|
CP2Ctrl CP2C; /* Cop2 control registers */ |
108 |
|
|
u32 pc; /* Program counter */ |
109 |
|
|
u32 code; /* The instruction */ |
110 |
|
|
u32 cycle; |
111 |
|
|
u32 interrupt; |
112 |
|
|
u32 sCycle[32]; // start cycle for signaled ints |
113 |
|
|
s32 eCycle[32]; // cycle delta for signaled ints (sCycle + eCycle == branch cycle) |
114 |
|
|
//u32 _msflag[32]; |
115 |
|
|
//u32 _smflag[32]; |
116 |
|
|
}; |
117 |
|
|
|
118 |
|
|
extern __aligned16 psxRegisters psxRegs; |
119 |
|
|
|
120 |
|
|
extern u32 g_psxNextBranchCycle; |
121 |
|
|
extern s32 psxBreak; // used when the IOP execution is broken and control returned to the EE |
122 |
|
|
extern s32 psxCycleEE; // tracks IOP's current sych status with the EE |
123 |
|
|
|
124 |
|
|
#ifndef _PC_ |
125 |
|
|
|
126 |
|
|
#define _i32(x) (s32)x //R3000A |
127 |
|
|
#define _u32(x) (u32)x //R3000A |
128 |
|
|
|
129 |
|
|
#define _i16(x) (s16)x // Not used |
130 |
|
|
#define _u16(x) (u16)x // Not used |
131 |
|
|
|
132 |
|
|
#define _i8(x) (s8)x // Not used |
133 |
|
|
#define _u8(x) (u8)x //R3000A - once |
134 |
|
|
|
135 |
|
|
/**** R3000A Instruction Macros ****/ |
136 |
|
|
#define _PC_ psxRegs.pc // The next PC to be executed |
137 |
|
|
|
138 |
|
|
#define _Funct_ ((psxRegs.code ) & 0x3F) // The funct part of the instruction register |
139 |
|
|
#define _Rd_ ((psxRegs.code >> 11) & 0x1F) // The rd part of the instruction register |
140 |
|
|
#define _Rt_ ((psxRegs.code >> 16) & 0x1F) // The rt part of the instruction register |
141 |
|
|
#define _Rs_ ((psxRegs.code >> 21) & 0x1F) // The rs part of the instruction register |
142 |
|
|
#define _Sa_ ((psxRegs.code >> 6) & 0x1F) // The sa part of the instruction register |
143 |
|
|
#define _Im_ ((u16)psxRegs.code) // The immediate part of the instruction register |
144 |
|
|
#define _Target_ (psxRegs.code & 0x03ffffff) // The target part of the instruction register |
145 |
|
|
|
146 |
|
|
#define _Imm_ ((short)psxRegs.code) // sign-extended immediate |
147 |
|
|
#define _ImmU_ (psxRegs.code&0xffff) // zero-extended immediate |
148 |
|
|
|
149 |
|
|
#define _rRs_ psxRegs.GPR.r[_Rs_] // Rs register |
150 |
|
|
#define _rRt_ psxRegs.GPR.r[_Rt_] // Rt register |
151 |
|
|
#define _rRd_ psxRegs.GPR.r[_Rd_] // Rd register |
152 |
|
|
#define _rSa_ psxRegs.GPR.r[_Sa_] // Sa register |
153 |
|
|
#define _rFs_ psxRegs.CP0.r[_Rd_] // Fs register |
154 |
|
|
|
155 |
|
|
#define _c2dRs_ psxRegs.CP2D.r[_Rs_] // Rs cop2 data register |
156 |
|
|
#define _c2dRt_ psxRegs.CP2D.r[_Rt_] // Rt cop2 data register |
157 |
|
|
#define _c2dRd_ psxRegs.CP2D.r[_Rd_] // Rd cop2 data register |
158 |
|
|
#define _c2dSa_ psxRegs.CP2D.r[_Sa_] // Sa cop2 data register |
159 |
|
|
|
160 |
|
|
#define _rHi_ psxRegs.GPR.n.hi // The HI register |
161 |
|
|
#define _rLo_ psxRegs.GPR.n.lo // The LO register |
162 |
|
|
|
163 |
|
|
#define _JumpTarget_ ((_Target_ << 2) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction |
164 |
|
|
#define _BranchTarget_ (((s32)(s16)_Imm_ * 4) + _PC_) // Calculates the target during a branch instruction |
165 |
|
|
|
166 |
|
|
#define _SetLink(x) psxRegs.GPR.r[x] = _PC_ + 4; // Sets the return address in the link register |
167 |
|
|
|
168 |
|
|
extern s32 EEsCycle; |
169 |
|
|
extern u32 EEoCycle; |
170 |
|
|
|
171 |
|
|
#endif |
172 |
|
|
|
173 |
|
|
extern s32 psxNextCounter; |
174 |
|
|
extern u32 psxNextsCounter; |
175 |
|
|
extern bool iopBranchAction; |
176 |
|
|
extern bool iopEventTestIsActive; |
177 |
|
|
|
178 |
|
|
// Branching status used when throwing exceptions. |
179 |
|
|
extern bool iopIsDelaySlot; |
180 |
|
|
|
181 |
|
|
//////////////////////////////////////////////////////////////////// |
182 |
|
|
// R3000A Public Interface / API |
183 |
|
|
|
184 |
|
|
struct R3000Acpu { |
185 |
|
|
void (*Allocate)(); |
186 |
|
|
void (*Reset)(); |
187 |
|
|
void (*Execute)(); |
188 |
|
|
s32 (*ExecuteBlock)( s32 eeCycles ); // executes the given number of EE cycles. |
189 |
|
|
void (*Clear)(u32 Addr, u32 Size); |
190 |
|
|
void (*Shutdown)(); |
191 |
|
|
}; |
192 |
|
|
|
193 |
|
|
extern R3000Acpu *psxCpu; |
194 |
|
|
extern R3000Acpu psxInt; |
195 |
|
|
extern R3000Acpu psxRec; |
196 |
|
|
|
197 |
|
|
extern void psxReset(); |
198 |
|
|
extern void __fastcall psxException(u32 code, u32 step); |
199 |
|
|
extern void psxBranchTest(); |
200 |
|
|
extern void psxMemReset(); |
201 |
|
|
|
202 |
|
|
// Subsets |
203 |
|
|
extern void (*psxBSC[64])(); |
204 |
|
|
extern void (*psxSPC[64])(); |
205 |
|
|
extern void (*psxREG[32])(); |
206 |
|
|
extern void (*psxCP0[32])(); |
207 |
|
|
extern void (*psxCP2[64])(); |
208 |
|
|
extern void (*psxCP2BSC[32])(); |
209 |
|
|
|
210 |
|
|
#endif /* __R3000A_H__ */ |