/[pcsx2_0.9.7]/trunk/pcsx2/IPU/IPU.h
ViewVC logotype

Contents of /trunk/pcsx2/IPU/IPU.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 273 - (show annotations) (download)
Fri Nov 12 01:10:22 2010 UTC (9 years, 7 months ago) by william
File MIME type: text/plain
File size: 6369 byte(s)
Auto Commited Import of: pcsx2-0.9.7-DEBUG (upstream: v0.9.7.4013 local: v0.9.7.197-latest) in ./trunk
1 /* 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 #pragma once
17
18 #include "IPU_Fifo.h"
19
20 #define ipumsk( src ) ( (src) & 0xff )
21 #define ipucase( src ) case ipumsk(src)
22
23 #define IPU_INT_TO( cycles ) if(!(cpuRegs.interrupt & (1<<4))) CPU_INT( DMAC_TO_IPU, cycles )
24 #define IPU_INT_FROM( cycles ) CPU_INT( DMAC_FROM_IPU, cycles )
25
26 #define IPU_FORCEINLINE __fi
27
28 //
29 // Bitfield Structures
30 //
31
32 struct tIPU_CMD
33 {
34 u32 DATA;
35 u32 BUSY;
36
37 void SetBusy(bool busy=true)
38 {
39 BUSY = busy ? 0x80000000 : 0;
40 }
41 };
42
43 union tIPU_CTRL {
44 struct {
45 u32 IFC : 4; // Input FIFO counter
46 u32 OFC : 4; // Output FIFO counter
47 u32 CBP : 6; // Coded block pattern
48 u32 ECD : 1; // Error code pattern
49 u32 SCD : 1; // Start code detected
50 u32 IDP : 2; // Intra DC precision
51 u32 resv0 : 2;
52 u32 AS : 1; // Alternate scan
53 u32 IVF : 1; // Intra VLC format
54 u32 QST : 1; // Q scale step
55 u32 MP1 : 1; // MPEG1 bit stream
56 u32 PCT : 3; // Picture Type
57 u32 resv1 : 3;
58 u32 RST : 1; // Reset
59 u32 BUSY : 1; // Busy
60 };
61 u32 _u32;
62
63 tIPU_CTRL( u32 val ) { _u32 = val; }
64
65 // CTRL = the first 16 bits of ctrl [0x8000ffff], + value for the next 16 bits,
66 // minus the reserved bits. (18-19; 27-29) [0x47f30000]
67 void write(u32 value) { _u32 = (value & 0x47f30000) | (_u32 & 0x8000ffff); }
68
69 bool test(u32 flags) const { return !!(_u32 & flags); }
70 void set_flags(u32 flags) { _u32 |= flags; }
71 void clear_flags(u32 flags) { _u32 &= ~flags; }
72 void reset() { _u32 = 0; }
73 };
74
75 struct __aligned16 tIPU_BP {
76 __aligned16 u128 internal_qwc[2];
77
78 u32 BP; // Bit stream point (0 to 128*2)
79 u32 IFC; // Input FIFO counter (8QWC) (0 to 8)
80 u32 FP; // internal FIFO (2QWC) fill status (0 to 2)
81
82 __fi void Align()
83 {
84 BP = (BP + 7) & ~7;
85 Advance(0);
86 }
87
88 __fi void Advance(uint bits)
89 {
90 BP += bits;
91 pxAssume( BP <= 256 );
92
93 if (BP >= 128)
94 {
95 BP -= 128;
96
97 if (FP == 2)
98 {
99 // when BP is over 128 it means we're reading data from the second quadword. Shift that one
100 // to the front and load the new quadword into the second QWC (its a manualized ringbuffer!)
101
102 CopyQWC(&internal_qwc[0], &internal_qwc[1]);
103 FP = 1;
104 }
105 else
106 {
107 // if FP == 1 then the buffer has been completely drained.
108 // if FP == 0 then an already-drained buffer is being advanced, and we need to drop a
109 // quadword from the IPU FIFO.
110
111 if (!FP)
112 ipu_fifo.in.read(&internal_qwc[0]);
113
114 FP = 0;
115 }
116 }
117 }
118
119 __fi bool FillBuffer(u32 bits)
120 {
121 while (FP < 2)
122 {
123 if (ipu_fifo.in.read(&internal_qwc[FP]) == 0)
124 {
125 // Here we *try* to fill the entire internal QWC buffer; however that may not necessarily
126 // be possible -- so if the fill fails we'll only return 0 if we don't have enough
127 // remaining bits in the FIFO to fill the request.
128
129 return ((FP!=0) && (BP + bits) <= 128);
130 }
131
132 ++FP;
133 }
134
135 return true;
136 }
137
138 wxString desc() const
139 {
140 return wxsFormat(L"Ipu BP: bp = 0x%x, IFC = 0x%x, FP = 0x%x.", BP, IFC, FP);
141 }
142 };
143
144 union tIPU_CMD_IDEC
145 {
146 struct
147 {
148 u32 FB : 6;
149 u32 UN2 :10;
150 u32 QSC : 5;
151 u32 UN1 : 3;
152 u32 DTD : 1;
153 u32 SGN : 1;
154 u32 DTE : 1;
155 u32 OFM : 1;
156 u32 cmd : 4;
157 };
158
159 u32 _u32;
160
161 tIPU_CMD_IDEC( u32 val ) { _u32 = val; }
162
163 bool test(u32 flags) const { return !!(_u32 & flags); }
164 void set_flags(u32 flags) { _u32 |= flags; }
165 void clear_flags(u32 flags) { _u32 &= ~flags; }
166 void reset() { _u32 = 0; }
167 void log() const;
168 };
169
170 union tIPU_CMD_BDEC
171 {
172 struct
173 {
174 u32 FB : 6;
175 u32 UN2 :10;
176 u32 QSC : 5;
177 u32 UN1 : 4;
178 u32 DT : 1;
179 u32 DCR : 1;
180 u32 MBI : 1;
181 u32 cmd : 4;
182 };
183 u32 _u32;
184
185 tIPU_CMD_BDEC( u32 val ) { _u32 = val; }
186
187 bool test(u32 flags) const { return !!(_u32 & flags); }
188 void set_flags(u32 flags) { _u32 |= flags; }
189 void clear_flags(u32 flags) { _u32 &= ~flags; }
190 void reset() { _u32 = 0; }
191 void log(int s_bdec) const;
192 };
193
194 union tIPU_CMD_CSC
195 {
196 struct
197 {
198 u32 MBC :11;
199 u32 UN2 :15;
200 u32 DTE : 1;
201 u32 OFM : 1;
202 u32 cmd : 4;
203 };
204 u32 _u32;
205
206 tIPU_CMD_CSC( u32 val ){ _u32 = val; }
207
208 bool test(u32 flags) const { return !!(_u32 & flags); }
209 void set_flags(u32 flags) { _u32 |= flags; }
210 void clear_flags(u32 flags) { _u32 &= ~flags; }
211 void reset() { _u32 = 0; }
212 void log_from_YCbCr() const;
213 void log_from_RGB32() const;
214 };
215
216 enum SCE_IPU
217 {
218 SCE_IPU_BCLR = 0x0
219 , SCE_IPU_IDEC
220 , SCE_IPU_BDEC
221 , SCE_IPU_VDEC
222 , SCE_IPU_FDEC
223 , SCE_IPU_SETIQ
224 , SCE_IPU_SETVQ
225 , SCE_IPU_CSC
226 , SCE_IPU_PACK
227 , SCE_IPU_SETTH
228 };
229
230 struct IPUregisters {
231 tIPU_CMD cmd;
232 u32 dummy0[2];
233
234 tIPU_CTRL ctrl;
235 u32 dummy1[3];
236
237 u32 ipubp;
238 u32 dummy2[3];
239
240 u32 top;
241 u32 topbusy;
242 u32 dummy3[2];
243
244 void SetTopBusy()
245 {
246 topbusy = 0x80000000;
247 }
248
249 void SetDataBusy()
250 {
251 cmd.BUSY = 0x80000000;
252 topbusy = 0x80000000;
253 }
254
255 };
256
257 union tIPU_cmd
258 {
259 struct
260 {
261 int index;
262 int pos[6];
263 union {
264 struct {
265 u32 OPTION : 28;
266 u32 CMD : 4;
267 };
268 u32 current;
269 };
270 };
271
272 u128 _u128[2];
273
274 void clear();
275 wxString desc() const
276 {
277 return pxsFmt(L"Ipu cmd: index = 0x%x, current = 0x%x, pos[0] = 0x%x, pos[1] = 0x%x",
278 index, current, pos[0], pos[1]);
279 }
280 };
281
282 static IPUregisters& ipuRegs = (IPUregisters&)eeHw[0x2000];
283
284 extern __aligned16 tIPU_cmd ipu_cmd;
285 extern int coded_block_pattern;
286
287 extern int ipuInit();
288 extern void ipuReset();
289
290 extern u32 ipuRead32(u32 mem);
291 extern u64 ipuRead64(u32 mem);
292 extern bool ipuWrite32(u32 mem,u32 value);
293 extern bool ipuWrite64(u32 mem,u64 value);
294
295 extern void IPUCMD_WRITE(u32 val);
296 extern void ipuSoftReset();
297 extern void IPUProcessInterrupt();
298
299 extern u8 getBits128(u8 *address, bool advance);
300 extern u8 getBits64(u8 *address, bool advance);
301 extern u8 getBits32(u8 *address, bool advance);
302 extern u8 getBits16(u8 *address, bool advance);
303 extern u8 getBits8(u8 *address, bool advance);
304

  ViewVC Help
Powered by ViewVC 1.1.22