drc: small debug improvement
[pcsx_rearmed.git] / libpcsxcore / mdec.c
CommitLineData
ef79bbde
P
1/***************************************************************************
2 * Copyright (C) 2010 Gabriele Gorla *
3 * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
19 ***************************************************************************/
20
21#include "mdec.h"
22
23#define DSIZE 8
24#define DSIZE2 (DSIZE * DSIZE)
25
26#define SCALE(x, n) ((x) >> (n))
27#define SCALER(x, n) (((x) + ((1 << (n)) >> 1)) >> (n))
28
29#define AAN_CONST_BITS 12
30#define AAN_PRESCALE_BITS 16
31
32#define AAN_CONST_SIZE 24
33#define AAN_CONST_SCALE (AAN_CONST_SIZE - AAN_CONST_BITS)
34
35#define AAN_PRESCALE_SIZE 20
36#define AAN_PRESCALE_SCALE (AAN_PRESCALE_SIZE-AAN_PRESCALE_BITS)
37#define AAN_EXTRA 12
38
39#define FIX_1_082392200 SCALER(18159528, AAN_CONST_SCALE) // B6
40#define FIX_1_414213562 SCALER(23726566, AAN_CONST_SCALE) // A4
41#define FIX_1_847759065 SCALER(31000253, AAN_CONST_SCALE) // A2
42#define FIX_2_613125930 SCALER(43840978, AAN_CONST_SCALE) // B2
43
44#define MULS(var, const) (SCALE((var) * (const), AAN_CONST_BITS))
45
46#define RLE_RUN(a) ((a) >> 10)
47#define RLE_VAL(a) (((int)(a) << (sizeof(int) * 8 - 10)) >> (sizeof(int) * 8 - 10))
48
49#if 0
50static void printmatrixu8(u8 *m) {
51 int i;
52 for(i = 0; i < DSIZE2; i++) {
53 printf("%3d ",m[i]);
54 if((i+1) % 8 == 0) printf("\n");
55 }
56}
57#endif
58
59static inline void fillcol(int *blk, int val) {
60 blk[0 * DSIZE] = blk[1 * DSIZE] = blk[2 * DSIZE] = blk[3 * DSIZE]
61 = blk[4 * DSIZE] = blk[5 * DSIZE] = blk[6 * DSIZE] = blk[7 * DSIZE] = val;
62}
63
64static inline void fillrow(int *blk, int val) {
65 blk[0] = blk[1] = blk[2] = blk[3]
66 = blk[4] = blk[5] = blk[6] = blk[7] = val;
67}
68
69void idct(int *block,int used_col) {
70 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
71 int z5, z10, z11, z12, z13;
72 int *ptr;
73 int i;
74
75 // the block has only the DC coefficient
76 if (used_col == -1) {
77 int v = block[0];
78 for (i = 0; i < DSIZE2; i++) block[i] = v;
79 return;
80 }
81
82 // last_col keeps track of the highest column with non zero coefficients
83 ptr = block;
84 for (i = 0; i < DSIZE; i++, ptr++) {
85 if ((used_col & (1 << i)) == 0) {
86 // the column is empty or has only the DC coefficient
87 if (ptr[DSIZE * 0]) {
88 fillcol(ptr, ptr[0]);
89 used_col |= (1 << i);
90 }
91 continue;
92 }
93
94 // further optimization could be made by keeping track of
95 // last_row in rl2blk
96 z10 = ptr[DSIZE * 0] + ptr[DSIZE * 4]; // s04
97 z11 = ptr[DSIZE * 0] - ptr[DSIZE * 4]; // d04
98 z13 = ptr[DSIZE * 2] + ptr[DSIZE * 6]; // s26
99 z12 = MULS(ptr[DSIZE * 2] - ptr[DSIZE * 6], FIX_1_414213562) - z13;
100 //^^^^ d26=d26*2*A4-s26
101
102 tmp0 = z10 + z13; // os07 = s04 + s26
103 tmp3 = z10 - z13; // os34 = s04 - s26
104 tmp1 = z11 + z12; // os16 = d04 + d26
105 tmp2 = z11 - z12; // os25 = d04 - d26
106
107 z13 = ptr[DSIZE * 3] + ptr[DSIZE * 5]; //s53
108 z10 = ptr[DSIZE * 3] - ptr[DSIZE * 5]; //-d53
109 z11 = ptr[DSIZE * 1] + ptr[DSIZE * 7]; //s17
110 z12 = ptr[DSIZE * 1] - ptr[DSIZE * 7]; //d17
111
112 tmp7 = z11 + z13; // od07 = s17 + s53
113
114 z5 = (z12 - z10) * (FIX_1_847759065);
115 tmp6 = SCALE(z10*(FIX_2_613125930) + z5, AAN_CONST_BITS) - tmp7;
116 tmp5 = MULS(z11 - z13, FIX_1_414213562) - tmp6;
117 tmp4 = SCALE(z12*(FIX_1_082392200) - z5, AAN_CONST_BITS) + tmp5;
118
119 // path #1
120 //z5 = (z12 - z10)* FIX_1_847759065;
121 // tmp0 = (d17 + d53) * 2*A2
122
123 //tmp6 = DESCALE(z10*FIX_2_613125930 + z5, CONST_BITS) - tmp7;
124 // od16 = (d53*-2*B2 + tmp0) - od07
125
126 //tmp4 = DESCALE(z12*FIX_1_082392200 - z5, CONST_BITS) + tmp5;
127 // od34 = (d17*2*B6 - tmp0) + od25
128
129 // path #2
130
131 // od34 = d17*2*(B6-A2) - d53*2*A2
132 // od16 = d53*2*(A2-B2) + d17*2*A2
133
134 // end
135
136 // tmp5 = MULS(z11 - z13, FIX_1_414213562) - tmp6;
137 // od25 = (s17 - s53)*2*A4 - od16
138
139 ptr[DSIZE * 0] = (tmp0 + tmp7); // os07 + od07
140 ptr[DSIZE * 7] = (tmp0 - tmp7); // os07 - od07
141 ptr[DSIZE * 1] = (tmp1 + tmp6); // os16 + od16
142 ptr[DSIZE * 6] = (tmp1 - tmp6); // os16 - od16
143 ptr[DSIZE * 2] = (tmp2 + tmp5); // os25 + od25
144 ptr[DSIZE * 5] = (tmp2 - tmp5); // os25 - od25
145 ptr[DSIZE * 4] = (tmp3 + tmp4); // os34 + od34
146 ptr[DSIZE * 3] = (tmp3 - tmp4); // os34 - od34
147 }
148
149 ptr = block;
150 if (used_col == 1) {
151 for (i = 0; i < DSIZE; i++)
152 fillrow(block + DSIZE * i, block[DSIZE * i]);
153 } else {
154 for (i = 0; i < DSIZE; i++, ptr += DSIZE) {
155 z10 = ptr[0] + ptr[4];
156 z11 = ptr[0] - ptr[4];
157 z13 = ptr[2] + ptr[6];
158 z12 = MULS(ptr[2] - ptr[6], FIX_1_414213562) - z13;
159
160 tmp0 = z10 + z13;
161 tmp3 = z10 - z13;
162 tmp1 = z11 + z12;
163 tmp2 = z11 - z12;
164
165 z13 = ptr[3] + ptr[5];
166 z10 = ptr[3] - ptr[5];
167 z11 = ptr[1] + ptr[7];
168 z12 = ptr[1] - ptr[7];
169
170 tmp7 = z11 + z13;
171 z5 = (z12 - z10) * FIX_1_847759065;
172 tmp6 = SCALE(z10 * FIX_2_613125930 + z5, AAN_CONST_BITS) - tmp7;
173 tmp5 = MULS(z11 - z13, FIX_1_414213562) - tmp6;
174 tmp4 = SCALE(z12 * FIX_1_082392200 - z5, AAN_CONST_BITS) + tmp5;
175
176 ptr[0] = tmp0 + tmp7;
177
178 ptr[7] = tmp0 - tmp7;
179 ptr[1] = tmp1 + tmp6;
180 ptr[6] = tmp1 - tmp6;
181 ptr[2] = tmp2 + tmp5;
182 ptr[5] = tmp2 - tmp5;
183 ptr[4] = tmp3 + tmp4;
184 ptr[3] = tmp3 - tmp4;
185 }
186 }
187}
188
189// mdec0: command register
190#define MDEC0_STP 0x02000000
191#define MDEC0_RGB24 0x08000000
192#define MDEC0_SIZE_MASK 0xFFFF
193
194// mdec1: status register
195#define MDEC1_BUSY 0x20000000
196#define MDEC1_DREQ 0x18000000
197#define MDEC1_FIFO 0xc0000000
198#define MDEC1_RGB24 0x02000000
199#define MDEC1_STP 0x00800000
200#define MDEC1_RESET 0x80000000
201
202struct {
203 u32 reg0;
204 u32 reg1;
205 unsigned short *rl;
206 int rlsize;
207} mdec;
208
209static int iq_y[DSIZE2], iq_uv[DSIZE2];
210
211static int zscan[DSIZE2] = {
212 0 , 1 , 8 , 16, 9 , 2 , 3 , 10,
213 17, 24, 32, 25, 18, 11, 4 , 5 ,
214 12, 19, 26, 33, 40, 48, 41, 34,
215 27, 20, 13, 6 , 7 , 14, 21, 28,
216 35, 42, 49, 56, 57, 50, 43, 36,
217 29, 22, 15, 23, 30, 37, 44, 51,
218 58, 59, 52, 45, 38, 31, 39, 46,
219 53, 60, 61, 54, 47, 55, 62, 63
220};
221
222static int aanscales[DSIZE2] = {
223 1048576, 1454417, 1370031, 1232995, 1048576, 823861, 567485, 289301,
224 1454417, 2017334, 1900287, 1710213, 1454417, 1142728, 787125, 401273,
225 1370031, 1900287, 1790031, 1610986, 1370031, 1076426, 741455, 377991,
226 1232995, 1710213, 1610986, 1449849, 1232995, 968758, 667292, 340183,
227 1048576, 1454417, 1370031, 1232995, 1048576, 823861, 567485, 289301,
228 823861, 1142728, 1076426, 968758, 823861, 647303, 445870, 227303,
229 567485, 787125, 741455, 667292, 567485, 445870, 307121, 156569,
230 289301, 401273, 377991, 340183, 289301, 227303, 156569, 79818
231};
232
233static void iqtab_init(int *iqtab, unsigned char *iq_y) {
234 int i;
235
236 for (i = 0; i < DSIZE2; i++) {
237 iqtab[i] = (iq_y[i] * SCALER(aanscales[zscan[i]], AAN_PRESCALE_SCALE));
238 }
239}
240
241#define MDEC_END_OF_DATA 0xfe00
242
243unsigned short *rl2blk(int *blk, unsigned short *mdec_rl) {
244 int i, k, q_scale, rl, used_col;
245 int *iqtab;
246
247 memset(blk, 0, 6 * DSIZE2 * sizeof(int));
248 iqtab = iq_uv;
249 for (i = 0; i < 6; i++) {
250 // decode blocks (Cr,Cb,Y1,Y2,Y3,Y4)
251 if (i == 2) iqtab = iq_y;
252
253 rl = SWAP16(*mdec_rl); mdec_rl++;
254 q_scale = RLE_RUN(rl);
255 blk[0] = SCALER(iqtab[0] * RLE_VAL(rl), AAN_EXTRA - 3);
256 for (k = 0, used_col = 0;;) {
257 rl = SWAP16(*mdec_rl); mdec_rl++;
258 if (rl == MDEC_END_OF_DATA) break;
259 k += RLE_RUN(rl) + 1; // skip zero-coefficients
260
261 if (k > 63) {
262 // printf("run lenght exceeded 64 enties\n");
263 break;
264 }
265
266 // zigzag transformation
267 blk[zscan[k]] = SCALER(RLE_VAL(rl) * iqtab[k] * q_scale, AAN_EXTRA);
268 // keep track of used columns to speed up the idtc
269 used_col |= (zscan[k] > 7) ? 1 << (zscan[k] & 7) : 0;
270 }
271
272 if (k == 0) used_col = -1;
273 // used_col is -1 for blocks with only the DC coefficient
274 // any other value is a bitmask of the columns that have
275 // at least one non zero cofficient in the rows 1-7
276 // single coefficients in row 0 are treted specially
277 // in the idtc function
278 idct(blk, used_col);
279 blk += DSIZE2;
280 }
281 return mdec_rl;
282}
283
284// full scale (JPEG)
285// Y/Cb/Cr[0...255] -> R/G/B[0...255]
286// R = 1.000 * (Y) + 1.400 * (Cr - 128)
287// G = 1.000 * (Y) - 0.343 * (Cb - 128) - 0.711 (Cr - 128)
288// B = 1.000 * (Y) + 1.765 * (Cb - 128)
289#define MULR(a) ((1434 * (a)))
290#define MULB(a) ((1807 * (a)))
291#define MULG2(a, b) ((-351 * (a) - 728 * (b)))
292#define MULY(a) ((a) << 10)
293
294#define MAKERGB15(r, g, b, a) (SWAP16(a | ((b) << 10) | ((g) << 5) | (r)))
295#define SCALE8(c) SCALER(c, 20)
296#define SCALE5(c) SCALER(c, 23)
297
298#define CLAMP5(c) ( ((c) < -16) ? 0 : (((c) > (31 - 16)) ? 31 : ((c) + 16)) )
299#define CLAMP8(c) ( ((c) < -128) ? 0 : (((c) > (255 - 128)) ? 255 : ((c) + 128)) )
300
301#define CLAMP_SCALE8(a) (CLAMP8(SCALE8(a)))
302#define CLAMP_SCALE5(a) (CLAMP5(SCALE5(a)))
303
304static inline void putlinebw15(unsigned short *image, int *Yblk) {
305 int i;
306 int A = (mdec.reg0 & MDEC0_STP) ? 0x8000 : 0;
307
308 for (i = 0; i < 8; i++, Yblk++) {
309 int Y = *Yblk;
310 // missing rounding
311 image[i] = SWAP16((CLAMP5(Y >> 3) * 0x421) | A);
312 }
313}
314
315static void putquadrgb15(unsigned short *image, int *Yblk, int Cr, int Cb) {
316 int Y, R, G, B;
317 int A = (mdec.reg0 & MDEC0_STP) ? 0x8000 : 0;
318 R = MULR(Cr);
319 G = MULG2(Cb, Cr);
320 B = MULB(Cb);
321
322 // added transparency
323 Y = MULY(Yblk[0]);
324 image[0] = MAKERGB15(CLAMP_SCALE5(Y + R), CLAMP_SCALE5(Y + G), CLAMP_SCALE5(Y + B), A);
325 Y = MULY(Yblk[1]);
326 image[1] = MAKERGB15(CLAMP_SCALE5(Y + R), CLAMP_SCALE5(Y + G), CLAMP_SCALE5(Y + B), A);
327 Y = MULY(Yblk[8]);
328 image[16] = MAKERGB15(CLAMP_SCALE5(Y + R), CLAMP_SCALE5(Y + G), CLAMP_SCALE5(Y + B), A);
329 Y = MULY(Yblk[9]);
330 image[17] = MAKERGB15(CLAMP_SCALE5(Y + R), CLAMP_SCALE5(Y + G), CLAMP_SCALE5(Y + B), A);
331}
332
333static void yuv2rgb15(int *blk, unsigned short *image) {
334 int x, y;
335 int *Yblk = blk + DSIZE2 * 2;
336 int *Crblk = blk;
337 int *Cbblk = blk + DSIZE2;
338
339 if (!Config.Mdec) {
340 for (y = 0; y < 16; y += 2, Crblk += 4, Cbblk += 4, Yblk += 8, image += 24) {
341 if (y == 8) Yblk += DSIZE2;
342 for (x = 0; x < 4; x++, image += 2, Crblk++, Cbblk++, Yblk += 2) {
343 putquadrgb15(image, Yblk, *Crblk, *Cbblk);
344 putquadrgb15(image + 8, Yblk + DSIZE2, *(Crblk + 4), *(Cbblk + 4));
345 }
346 }
347 } else {
348 for (y = 0; y < 16; y++, Yblk += 8, image += 16) {
349 if (y == 8) Yblk += DSIZE2;
350 putlinebw15(image, Yblk);
351 putlinebw15(image + 8, Yblk + DSIZE2);
352 }
353 }
354}
355
356static inline void putlinebw24(unsigned char *image, int *Yblk) {
357 int i;
358 unsigned char Y;
359 for (i = 0; i < 8 * 3; i += 3, Yblk++) {
360 Y = CLAMP8(*Yblk);
361 image[i + 0] = Y;
362 image[i + 1] = Y;
363 image[i + 2] = Y;
364 }
365}
366
367static void putquadrgb24(unsigned char *image, int *Yblk, int Cr, int Cb) {
368 int Y, R, G, B;
369
370 R = MULR(Cr);
371 G = MULG2(Cb,Cr);
372 B = MULB(Cb);
373
374 Y = MULY(Yblk[0]);
375 image[0 * 3 + 0] = CLAMP_SCALE8(Y + R);
376 image[0 * 3 + 1] = CLAMP_SCALE8(Y + G);
377 image[0 * 3 + 2] = CLAMP_SCALE8(Y + B);
378 Y = MULY(Yblk[1]);
379 image[1 * 3 + 0] = CLAMP_SCALE8(Y + R);
380 image[1 * 3 + 1] = CLAMP_SCALE8(Y + G);
381 image[1 * 3 + 2] = CLAMP_SCALE8(Y + B);
382 Y = MULY(Yblk[8]);
383 image[16 * 3 + 0] = CLAMP_SCALE8(Y + R);
384 image[16 * 3 + 1] = CLAMP_SCALE8(Y + G);
385 image[16 * 3 + 2] = CLAMP_SCALE8(Y + B);
386 Y = MULY(Yblk[9]);
387 image[17 * 3 + 0] = CLAMP_SCALE8(Y + R);
388 image[17 * 3 + 1] = CLAMP_SCALE8(Y + G);
389 image[17 * 3 + 2] = CLAMP_SCALE8(Y + B);
390}
391
392static void yuv2rgb24(int *blk, unsigned char *image) {
393 int x, y;
394 int *Yblk = blk + DSIZE2 * 2;
395 int *Crblk = blk;
396 int *Cbblk = blk + DSIZE2;
397
398 if (!Config.Mdec) {
399 for (y = 0; y < 16; y += 2, Crblk += 4, Cbblk += 4, Yblk += 8, image += 24 * 3) {
400 if (y == 8) Yblk += DSIZE2;
401 for (x = 0; x < 4; x++, image += 6, Crblk++, Cbblk++, Yblk += 2) {
402 putquadrgb24(image, Yblk, *Crblk, *Cbblk);
403 putquadrgb24(image + 8 * 3, Yblk + DSIZE2, *(Crblk + 4), *(Cbblk + 4));
404 }
405 }
406 } else {
407 for (y = 0; y < 16; y++, Yblk += 8, image += 16 * 3) {
408 if (y == 8) Yblk += DSIZE2;
409 putlinebw24(image, Yblk);
410 putlinebw24(image + 8 * 3, Yblk + DSIZE2);
411 }
412 }
413}
414
415void mdecInit(void) {
416 mdec.rl = (u16 *)&psxM[0x100000];
417 mdec.reg0 = 0;
418 mdec.reg1 = 0;
419}
420
421// command register
422void mdecWrite0(u32 data) {
423#ifdef CDR_LOG
424 CDR_LOG("mdec0 write %08x\n", data);
425#endif
426 mdec.reg0 = data;
427}
428
429u32 mdecRead0(void) {
430#ifdef CDR_LOG
431 CDR_LOG("mdec0 read %08x\n", mdec.reg0);
432#endif
433 // mame is returning 0
434 return mdec.reg0;
435}
436
437// status register
438void mdecWrite1(u32 data) {
439#ifdef CDR_LOG
440 CDR_LOG("mdec1 write %08x\n", data);
441#endif
442 if (data & MDEC1_RESET) { // mdec reset
443 mdec.reg0 = 0;
444 mdec.reg1 = 0;
445 }
446}
447
448u32 mdecRead1(void) {
449 u32 v = mdec.reg1;
450 v |= (mdec.reg0 & MDEC0_STP) ? MDEC1_STP : 0;
451 v |= (mdec.reg0 & MDEC0_RGB24) ? MDEC1_RGB24 : 0;
452#ifdef CDR_LOG
453 CDR_LOG("mdec1 read %08x\n", v);
454#endif
455 return v;
456}
457
458void psxDma0(u32 adr, u32 bcr, u32 chcr) {
459 int cmd = mdec.reg0;
460 int size;
461
462#ifdef CDR_LOG
463 CDR_LOG("DMA0 %08x %08x %08x\n", adr, bcr, chcr);
464#endif
465
466 if (chcr != 0x01000201) {
467 // printf("chcr != 0x01000201\n");
468 return;
469 }
470
471 size = (bcr >> 16) * (bcr & 0xffff);
472
473 switch (cmd >> 28) {
474 case 0x3: // decode
475 mdec.rl = (u16 *)PSXM(adr);
476 mdec.rlsize = mdec.reg0 & MDEC0_SIZE_MASK;
477 break;
478
479 case 0x4: // quantization table upload
480 {
481 u8 *p = (u8 *)PSXM(adr);
482 // printf("uploading new quantization table\n");
483 // printmatrixu8(p);
484 // printmatrixu8(p + 64);
485 iqtab_init(iq_y, p);
486 iqtab_init(iq_uv, p + 64);
487 }
488 break;
489
490 case 0x6: // cosine table
491 // printf("mdec cosine table\n");
492 break;
493
494 default:
495 // printf("mdec unknown command\n");
496 break;
497 }
498
499 HW_DMA0_CHCR &= SWAP32(~0x01000000);
500 DMA_INTERRUPT(0);
501}
502
503void psxDma1(u32 adr, u32 bcr, u32 chcr) {
504 int blk[DSIZE2 * 6];
505 unsigned short *image;
506 int size;
507
508#ifdef CDR_LOG
509 CDR_LOG("DMA1 %08x %08x %08x (cmd = %08x)\n", adr, bcr, chcr, mdec.reg0);
510#endif
511
512 if (chcr != 0x01000200) return;
513
514 size = (bcr >> 16) * (bcr & 0xffff);
515
516 image = (u16 *)PSXM(adr);
517
518 if (mdec.reg0 & MDEC0_RGB24) { // 15-b decoding
519 // MDECOUTDMA_INT(((size * (1000000 / 9000)) / 4) /** 4*/);
520 MDECOUTDMA_INT(size / 4);
521 size = size / ((16 * 16) / 2);
522 for (; size > 0; size--, image += (16 * 16)) {
523 mdec.rl = rl2blk(blk, mdec.rl);
524 yuv2rgb15(blk, image);
525 }
526 } else { // 24-b decoding
527 // MDECOUTDMA_INT(((size * (1000000 / 9000)) / 4) /** 4*/);
528 MDECOUTDMA_INT(size / 4);
529 size = size / ((24 * 16) / 2);
530 for (; size > 0; size--, image += (24 * 16)) {
531 mdec.rl = rl2blk(blk, mdec.rl);
532 yuv2rgb24(blk, (u8 *)image);
533 }
534 }
535
536 mdec.reg1 |= MDEC1_BUSY;
537}
538
539void mdec1Interrupt() {
540#ifdef CDR_LOG
541 CDR_LOG("mdec1Interrupt\n");
542#endif
543 if (HW_DMA1_CHCR & SWAP32(0x01000000)) {
544 // Set a fixed value totaly arbitrarie another sound value is
545 // PSXCLK / 60 or PSXCLK / 50 since the bug happened at end of frame.
546 // PSXCLK / 1000 seems good for FF9. (for FF9 need < ~28000)
547 // CAUTION: commented interrupt-handling may lead to problems, keep an eye ;-)
548 MDECOUTDMA_INT(PSXCLK / 1000 * BIAS);
549// psxRegs.interrupt |= 0x02000000;
550// psxRegs.intCycle[5 + 24 + 1] *= 8;
551// psxRegs.intCycle[5 + 24] = psxRegs.cycle;
552 HW_DMA1_CHCR &= SWAP32(~0x01000000);
553 DMA_INTERRUPT(1);
554 } else {
555 mdec.reg1 &= ~MDEC1_BUSY;
556 }
557}
558
559int mdecFreeze(gzFile f, int Mode) {
560 gzfreeze(&mdec, sizeof(mdec));
561 gzfreeze(iq_y, sizeof(iq_y));
562 gzfreeze(iq_uv, sizeof(iq_uv));
563
564 return 0;
565}