drc: starting arm64 support
[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
528ad661 23/* memory speed is 1 byte per MDEC_BIAS psx clock
24 * That mean (PSXCLK / MDEC_BIAS) B/s
25 * MDEC_BIAS = 2.0 => ~16MB/s
26 * MDEC_BIAS = 3.0 => ~11MB/s
27 * and so on ...
28 * I guess I have 50 images in 50Hz ... (could be 25 images ?)
29 * 320x240x24@50Hz => 11.52 MB/s
30 * 320x240x24@60Hz => 13.824 MB/s
31 * 320x240x16@50Hz => 7.68 MB/s
32 * 320x240x16@60Hz => 9.216 MB/s
33 * so 2.0 to 4.0 should be fine.
34 */
1ffdacd5 35
36/* Was set to 2 before but it would cause issues in R-types and Vandal Hearts videos.
37 * Setting it to 6 as dmitrysmagin did fix those... except for Galerians.
38 * Galerians needs this to be set to 10 (!!) before it looks properly.
39 * I've tried this with a few other games (including R-Types) and so far, this
40 * has not backfired.
41 * */
42#define MDEC_BIAS 10
528ad661 43
ef79bbde
P
44#define DSIZE 8
45#define DSIZE2 (DSIZE * DSIZE)
46
47#define SCALE(x, n) ((x) >> (n))
48#define SCALER(x, n) (((x) + ((1 << (n)) >> 1)) >> (n))
49
50#define AAN_CONST_BITS 12
51#define AAN_PRESCALE_BITS 16
52
53#define AAN_CONST_SIZE 24
54#define AAN_CONST_SCALE (AAN_CONST_SIZE - AAN_CONST_BITS)
55
56#define AAN_PRESCALE_SIZE 20
57#define AAN_PRESCALE_SCALE (AAN_PRESCALE_SIZE-AAN_PRESCALE_BITS)
58#define AAN_EXTRA 12
59
60#define FIX_1_082392200 SCALER(18159528, AAN_CONST_SCALE) // B6
61#define FIX_1_414213562 SCALER(23726566, AAN_CONST_SCALE) // A4
62#define FIX_1_847759065 SCALER(31000253, AAN_CONST_SCALE) // A2
63#define FIX_2_613125930 SCALER(43840978, AAN_CONST_SCALE) // B2
64
65#define MULS(var, const) (SCALE((var) * (const), AAN_CONST_BITS))
66
67#define RLE_RUN(a) ((a) >> 10)
68#define RLE_VAL(a) (((int)(a) << (sizeof(int) * 8 - 10)) >> (sizeof(int) * 8 - 10))
69
70#if 0
71static void printmatrixu8(u8 *m) {
72 int i;
73 for(i = 0; i < DSIZE2; i++) {
74 printf("%3d ",m[i]);
75 if((i+1) % 8 == 0) printf("\n");
76 }
77}
78#endif
79
80static inline void fillcol(int *blk, int val) {
81 blk[0 * DSIZE] = blk[1 * DSIZE] = blk[2 * DSIZE] = blk[3 * DSIZE]
82 = blk[4 * DSIZE] = blk[5 * DSIZE] = blk[6 * DSIZE] = blk[7 * DSIZE] = val;
83}
84
85static inline void fillrow(int *blk, int val) {
86 blk[0] = blk[1] = blk[2] = blk[3]
87 = blk[4] = blk[5] = blk[6] = blk[7] = val;
88}
89
528ad661 90static void idct(int *block,int used_col) {
ef79bbde
P
91 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
92 int z5, z10, z11, z12, z13;
93 int *ptr;
94 int i;
95
96 // the block has only the DC coefficient
97 if (used_col == -1) {
98 int v = block[0];
99 for (i = 0; i < DSIZE2; i++) block[i] = v;
100 return;
101 }
102
103 // last_col keeps track of the highest column with non zero coefficients
104 ptr = block;
105 for (i = 0; i < DSIZE; i++, ptr++) {
106 if ((used_col & (1 << i)) == 0) {
107 // the column is empty or has only the DC coefficient
108 if (ptr[DSIZE * 0]) {
109 fillcol(ptr, ptr[0]);
110 used_col |= (1 << i);
111 }
112 continue;
113 }
114
115 // further optimization could be made by keeping track of
116 // last_row in rl2blk
117 z10 = ptr[DSIZE * 0] + ptr[DSIZE * 4]; // s04
118 z11 = ptr[DSIZE * 0] - ptr[DSIZE * 4]; // d04
119 z13 = ptr[DSIZE * 2] + ptr[DSIZE * 6]; // s26
120 z12 = MULS(ptr[DSIZE * 2] - ptr[DSIZE * 6], FIX_1_414213562) - z13;
121 //^^^^ d26=d26*2*A4-s26
122
123 tmp0 = z10 + z13; // os07 = s04 + s26
124 tmp3 = z10 - z13; // os34 = s04 - s26
125 tmp1 = z11 + z12; // os16 = d04 + d26
126 tmp2 = z11 - z12; // os25 = d04 - d26
127
128 z13 = ptr[DSIZE * 3] + ptr[DSIZE * 5]; //s53
129 z10 = ptr[DSIZE * 3] - ptr[DSIZE * 5]; //-d53
130 z11 = ptr[DSIZE * 1] + ptr[DSIZE * 7]; //s17
131 z12 = ptr[DSIZE * 1] - ptr[DSIZE * 7]; //d17
132
133 tmp7 = z11 + z13; // od07 = s17 + s53
134
135 z5 = (z12 - z10) * (FIX_1_847759065);
136 tmp6 = SCALE(z10*(FIX_2_613125930) + z5, AAN_CONST_BITS) - tmp7;
137 tmp5 = MULS(z11 - z13, FIX_1_414213562) - tmp6;
138 tmp4 = SCALE(z12*(FIX_1_082392200) - z5, AAN_CONST_BITS) + tmp5;
139
140 // path #1
141 //z5 = (z12 - z10)* FIX_1_847759065;
142 // tmp0 = (d17 + d53) * 2*A2
143
144 //tmp6 = DESCALE(z10*FIX_2_613125930 + z5, CONST_BITS) - tmp7;
145 // od16 = (d53*-2*B2 + tmp0) - od07
146
147 //tmp4 = DESCALE(z12*FIX_1_082392200 - z5, CONST_BITS) + tmp5;
148 // od34 = (d17*2*B6 - tmp0) + od25
149
150 // path #2
151
152 // od34 = d17*2*(B6-A2) - d53*2*A2
153 // od16 = d53*2*(A2-B2) + d17*2*A2
154
155 // end
156
157 // tmp5 = MULS(z11 - z13, FIX_1_414213562) - tmp6;
158 // od25 = (s17 - s53)*2*A4 - od16
159
160 ptr[DSIZE * 0] = (tmp0 + tmp7); // os07 + od07
161 ptr[DSIZE * 7] = (tmp0 - tmp7); // os07 - od07
162 ptr[DSIZE * 1] = (tmp1 + tmp6); // os16 + od16
163 ptr[DSIZE * 6] = (tmp1 - tmp6); // os16 - od16
164 ptr[DSIZE * 2] = (tmp2 + tmp5); // os25 + od25
165 ptr[DSIZE * 5] = (tmp2 - tmp5); // os25 - od25
166 ptr[DSIZE * 4] = (tmp3 + tmp4); // os34 + od34
167 ptr[DSIZE * 3] = (tmp3 - tmp4); // os34 - od34
168 }
169
170 ptr = block;
171 if (used_col == 1) {
172 for (i = 0; i < DSIZE; i++)
173 fillrow(block + DSIZE * i, block[DSIZE * i]);
174 } else {
175 for (i = 0; i < DSIZE; i++, ptr += DSIZE) {
176 z10 = ptr[0] + ptr[4];
177 z11 = ptr[0] - ptr[4];
178 z13 = ptr[2] + ptr[6];
179 z12 = MULS(ptr[2] - ptr[6], FIX_1_414213562) - z13;
180
181 tmp0 = z10 + z13;
182 tmp3 = z10 - z13;
183 tmp1 = z11 + z12;
184 tmp2 = z11 - z12;
185
186 z13 = ptr[3] + ptr[5];
187 z10 = ptr[3] - ptr[5];
188 z11 = ptr[1] + ptr[7];
189 z12 = ptr[1] - ptr[7];
190
191 tmp7 = z11 + z13;
192 z5 = (z12 - z10) * FIX_1_847759065;
193 tmp6 = SCALE(z10 * FIX_2_613125930 + z5, AAN_CONST_BITS) - tmp7;
194 tmp5 = MULS(z11 - z13, FIX_1_414213562) - tmp6;
195 tmp4 = SCALE(z12 * FIX_1_082392200 - z5, AAN_CONST_BITS) + tmp5;
196
197 ptr[0] = tmp0 + tmp7;
198
199 ptr[7] = tmp0 - tmp7;
200 ptr[1] = tmp1 + tmp6;
201 ptr[6] = tmp1 - tmp6;
202 ptr[2] = tmp2 + tmp5;
203 ptr[5] = tmp2 - tmp5;
204 ptr[4] = tmp3 + tmp4;
205 ptr[3] = tmp3 - tmp4;
206 }
207 }
208}
209
210// mdec0: command register
211#define MDEC0_STP 0x02000000
212#define MDEC0_RGB24 0x08000000
528ad661 213#define MDEC0_SIZE_MASK 0x0000FFFF
ef79bbde
P
214
215// mdec1: status register
216#define MDEC1_BUSY 0x20000000
217#define MDEC1_DREQ 0x18000000
218#define MDEC1_FIFO 0xc0000000
219#define MDEC1_RGB24 0x02000000
220#define MDEC1_STP 0x00800000
221#define MDEC1_RESET 0x80000000
222
528ad661 223struct _pending_dma1 {
224 u32 adr;
225 u32 bcr;
226 u32 chcr;
227};
228
c62b43c9 229static struct {
528ad661 230 u32 reg0;
231 u32 reg1;
232 u16 * rl;
233 u16 * rl_end;
234 u8 * block_buffer_pos;
235 u8 block_buffer[16*16*3];
236 struct _pending_dma1 pending_dma1;
ef79bbde
P
237} mdec;
238
239static int iq_y[DSIZE2], iq_uv[DSIZE2];
240
241static int zscan[DSIZE2] = {
242 0 , 1 , 8 , 16, 9 , 2 , 3 , 10,
243 17, 24, 32, 25, 18, 11, 4 , 5 ,
244 12, 19, 26, 33, 40, 48, 41, 34,
245 27, 20, 13, 6 , 7 , 14, 21, 28,
246 35, 42, 49, 56, 57, 50, 43, 36,
247 29, 22, 15, 23, 30, 37, 44, 51,
248 58, 59, 52, 45, 38, 31, 39, 46,
249 53, 60, 61, 54, 47, 55, 62, 63
250};
251
252static int aanscales[DSIZE2] = {
253 1048576, 1454417, 1370031, 1232995, 1048576, 823861, 567485, 289301,
254 1454417, 2017334, 1900287, 1710213, 1454417, 1142728, 787125, 401273,
255 1370031, 1900287, 1790031, 1610986, 1370031, 1076426, 741455, 377991,
256 1232995, 1710213, 1610986, 1449849, 1232995, 968758, 667292, 340183,
257 1048576, 1454417, 1370031, 1232995, 1048576, 823861, 567485, 289301,
258 823861, 1142728, 1076426, 968758, 823861, 647303, 445870, 227303,
259 567485, 787125, 741455, 667292, 567485, 445870, 307121, 156569,
260 289301, 401273, 377991, 340183, 289301, 227303, 156569, 79818
261};
262
263static void iqtab_init(int *iqtab, unsigned char *iq_y) {
264 int i;
265
266 for (i = 0; i < DSIZE2; i++) {
267 iqtab[i] = (iq_y[i] * SCALER(aanscales[zscan[i]], AAN_PRESCALE_SCALE));
268 }
269}
270
271#define MDEC_END_OF_DATA 0xfe00
272
528ad661 273static unsigned short *rl2blk(int *blk, unsigned short *mdec_rl) {
ef79bbde
P
274 int i, k, q_scale, rl, used_col;
275 int *iqtab;
276
277 memset(blk, 0, 6 * DSIZE2 * sizeof(int));
278 iqtab = iq_uv;
279 for (i = 0; i < 6; i++) {
280 // decode blocks (Cr,Cb,Y1,Y2,Y3,Y4)
281 if (i == 2) iqtab = iq_y;
282
283 rl = SWAP16(*mdec_rl); mdec_rl++;
284 q_scale = RLE_RUN(rl);
285 blk[0] = SCALER(iqtab[0] * RLE_VAL(rl), AAN_EXTRA - 3);
286 for (k = 0, used_col = 0;;) {
287 rl = SWAP16(*mdec_rl); mdec_rl++;
288 if (rl == MDEC_END_OF_DATA) break;
289 k += RLE_RUN(rl) + 1; // skip zero-coefficients
290
291 if (k > 63) {
292 // printf("run lenght exceeded 64 enties\n");
293 break;
294 }
295
296 // zigzag transformation
297 blk[zscan[k]] = SCALER(RLE_VAL(rl) * iqtab[k] * q_scale, AAN_EXTRA);
298 // keep track of used columns to speed up the idtc
299 used_col |= (zscan[k] > 7) ? 1 << (zscan[k] & 7) : 0;
300 }
301
302 if (k == 0) used_col = -1;
303 // used_col is -1 for blocks with only the DC coefficient
304 // any other value is a bitmask of the columns that have
305 // at least one non zero cofficient in the rows 1-7
306 // single coefficients in row 0 are treted specially
307 // in the idtc function
308 idct(blk, used_col);
309 blk += DSIZE2;
310 }
311 return mdec_rl;
312}
313
314// full scale (JPEG)
315// Y/Cb/Cr[0...255] -> R/G/B[0...255]
316// R = 1.000 * (Y) + 1.400 * (Cr - 128)
317// G = 1.000 * (Y) - 0.343 * (Cb - 128) - 0.711 (Cr - 128)
318// B = 1.000 * (Y) + 1.765 * (Cb - 128)
319#define MULR(a) ((1434 * (a)))
320#define MULB(a) ((1807 * (a)))
321#define MULG2(a, b) ((-351 * (a) - 728 * (b)))
322#define MULY(a) ((a) << 10)
323
324#define MAKERGB15(r, g, b, a) (SWAP16(a | ((b) << 10) | ((g) << 5) | (r)))
325#define SCALE8(c) SCALER(c, 20)
326#define SCALE5(c) SCALER(c, 23)
327
328#define CLAMP5(c) ( ((c) < -16) ? 0 : (((c) > (31 - 16)) ? 31 : ((c) + 16)) )
329#define CLAMP8(c) ( ((c) < -128) ? 0 : (((c) > (255 - 128)) ? 255 : ((c) + 128)) )
330
331#define CLAMP_SCALE8(a) (CLAMP8(SCALE8(a)))
332#define CLAMP_SCALE5(a) (CLAMP5(SCALE5(a)))
333
528ad661 334static inline void putlinebw15(u16 *image, int *Yblk) {
ef79bbde
P
335 int i;
336 int A = (mdec.reg0 & MDEC0_STP) ? 0x8000 : 0;
337
338 for (i = 0; i < 8; i++, Yblk++) {
339 int Y = *Yblk;
340 // missing rounding
341 image[i] = SWAP16((CLAMP5(Y >> 3) * 0x421) | A);
342 }
343}
344
528ad661 345static inline void putquadrgb15(u16 *image, int *Yblk, int Cr, int Cb) {
ef79bbde
P
346 int Y, R, G, B;
347 int A = (mdec.reg0 & MDEC0_STP) ? 0x8000 : 0;
348 R = MULR(Cr);
349 G = MULG2(Cb, Cr);
350 B = MULB(Cb);
351
352 // added transparency
353 Y = MULY(Yblk[0]);
354 image[0] = MAKERGB15(CLAMP_SCALE5(Y + R), CLAMP_SCALE5(Y + G), CLAMP_SCALE5(Y + B), A);
355 Y = MULY(Yblk[1]);
356 image[1] = MAKERGB15(CLAMP_SCALE5(Y + R), CLAMP_SCALE5(Y + G), CLAMP_SCALE5(Y + B), A);
357 Y = MULY(Yblk[8]);
358 image[16] = MAKERGB15(CLAMP_SCALE5(Y + R), CLAMP_SCALE5(Y + G), CLAMP_SCALE5(Y + B), A);
359 Y = MULY(Yblk[9]);
360 image[17] = MAKERGB15(CLAMP_SCALE5(Y + R), CLAMP_SCALE5(Y + G), CLAMP_SCALE5(Y + B), A);
361}
362
528ad661 363static inline void yuv2rgb15(int *blk, unsigned short *image) {
ef79bbde
P
364 int x, y;
365 int *Yblk = blk + DSIZE2 * 2;
366 int *Crblk = blk;
367 int *Cbblk = blk + DSIZE2;
368
369 if (!Config.Mdec) {
370 for (y = 0; y < 16; y += 2, Crblk += 4, Cbblk += 4, Yblk += 8, image += 24) {
371 if (y == 8) Yblk += DSIZE2;
372 for (x = 0; x < 4; x++, image += 2, Crblk++, Cbblk++, Yblk += 2) {
373 putquadrgb15(image, Yblk, *Crblk, *Cbblk);
374 putquadrgb15(image + 8, Yblk + DSIZE2, *(Crblk + 4), *(Cbblk + 4));
375 }
376 }
377 } else {
378 for (y = 0; y < 16; y++, Yblk += 8, image += 16) {
379 if (y == 8) Yblk += DSIZE2;
380 putlinebw15(image, Yblk);
381 putlinebw15(image + 8, Yblk + DSIZE2);
382 }
383 }
384}
385
528ad661 386static inline void putlinebw24(u8 * image, int *Yblk) {
ef79bbde
P
387 int i;
388 unsigned char Y;
389 for (i = 0; i < 8 * 3; i += 3, Yblk++) {
390 Y = CLAMP8(*Yblk);
391 image[i + 0] = Y;
392 image[i + 1] = Y;
393 image[i + 2] = Y;
394 }
395}
396
528ad661 397static inline void putquadrgb24(u8 * image, int *Yblk, int Cr, int Cb) {
ef79bbde
P
398 int Y, R, G, B;
399
400 R = MULR(Cr);
401 G = MULG2(Cb,Cr);
402 B = MULB(Cb);
403
404 Y = MULY(Yblk[0]);
405 image[0 * 3 + 0] = CLAMP_SCALE8(Y + R);
406 image[0 * 3 + 1] = CLAMP_SCALE8(Y + G);
407 image[0 * 3 + 2] = CLAMP_SCALE8(Y + B);
408 Y = MULY(Yblk[1]);
409 image[1 * 3 + 0] = CLAMP_SCALE8(Y + R);
410 image[1 * 3 + 1] = CLAMP_SCALE8(Y + G);
411 image[1 * 3 + 2] = CLAMP_SCALE8(Y + B);
412 Y = MULY(Yblk[8]);
413 image[16 * 3 + 0] = CLAMP_SCALE8(Y + R);
414 image[16 * 3 + 1] = CLAMP_SCALE8(Y + G);
415 image[16 * 3 + 2] = CLAMP_SCALE8(Y + B);
416 Y = MULY(Yblk[9]);
417 image[17 * 3 + 0] = CLAMP_SCALE8(Y + R);
418 image[17 * 3 + 1] = CLAMP_SCALE8(Y + G);
419 image[17 * 3 + 2] = CLAMP_SCALE8(Y + B);
420}
421
528ad661 422static void yuv2rgb24(int *blk, u8 *image) {
ef79bbde
P
423 int x, y;
424 int *Yblk = blk + DSIZE2 * 2;
425 int *Crblk = blk;
426 int *Cbblk = blk + DSIZE2;
427
428 if (!Config.Mdec) {
528ad661 429 for (y = 0; y < 16; y += 2, Crblk += 4, Cbblk += 4, Yblk += 8, image += 8 * 3 * 3) {
ef79bbde
P
430 if (y == 8) Yblk += DSIZE2;
431 for (x = 0; x < 4; x++, image += 6, Crblk++, Cbblk++, Yblk += 2) {
432 putquadrgb24(image, Yblk, *Crblk, *Cbblk);
433 putquadrgb24(image + 8 * 3, Yblk + DSIZE2, *(Crblk + 4), *(Cbblk + 4));
434 }
435 }
436 } else {
437 for (y = 0; y < 16; y++, Yblk += 8, image += 16 * 3) {
438 if (y == 8) Yblk += DSIZE2;
439 putlinebw24(image, Yblk);
440 putlinebw24(image + 8 * 3, Yblk + DSIZE2);
441 }
442 }
443}
444
445void mdecInit(void) {
c62b43c9 446 memset(&mdec, 0, sizeof(mdec));
447 memset(iq_y, 0, sizeof(iq_y));
448 memset(iq_uv, 0, sizeof(iq_uv));
ef79bbde 449 mdec.rl = (u16 *)&psxM[0x100000];
ef79bbde
P
450}
451
452// command register
453void mdecWrite0(u32 data) {
ef79bbde
P
454 mdec.reg0 = data;
455}
456
457u32 mdecRead0(void) {
ef79bbde
P
458 return mdec.reg0;
459}
460
461// status register
462void mdecWrite1(u32 data) {
ef79bbde
P
463 if (data & MDEC1_RESET) { // mdec reset
464 mdec.reg0 = 0;
465 mdec.reg1 = 0;
528ad661 466 mdec.pending_dma1.adr = 0;
467 mdec.block_buffer_pos = 0;
ef79bbde
P
468 }
469}
470
471u32 mdecRead1(void) {
472 u32 v = mdec.reg1;
ef79bbde
P
473 return v;
474}
475
476void psxDma0(u32 adr, u32 bcr, u32 chcr) {
477 int cmd = mdec.reg0;
478 int size;
ef79bbde
P
479
480 if (chcr != 0x01000201) {
ef79bbde
P
481 return;
482 }
483
528ad661 484 /* mdec is STP till dma0 is released */
485 mdec.reg1 |= MDEC1_STP;
486
ef79bbde
P
487 size = (bcr >> 16) * (bcr & 0xffff);
488
489 switch (cmd >> 28) {
490 case 0x3: // decode
528ad661 491 mdec.rl = (u16 *) PSXM(adr);
492 /* now the mdec is busy till all data are decoded */
493 mdec.reg1 |= MDEC1_BUSY;
494 /* detect the end of decoding */
495 mdec.rl_end = mdec.rl + (size * 2);
496
497 /* sanity check */
498 if(mdec.rl_end <= mdec.rl) {
499 MDECINDMA_INT( size / 4 );
500 return;
501 }
502
503 /* process the pending dma1 */
504 if(mdec.pending_dma1.adr){
505 psxDma1(mdec.pending_dma1.adr, mdec.pending_dma1.bcr, mdec.pending_dma1.chcr);
506 }
507 mdec.pending_dma1.adr = 0;
508 return;
509
ef79bbde
P
510
511 case 0x4: // quantization table upload
512 {
513 u8 *p = (u8 *)PSXM(adr);
514 // printf("uploading new quantization table\n");
515 // printmatrixu8(p);
516 // printmatrixu8(p + 64);
517 iqtab_init(iq_y, p);
518 iqtab_init(iq_uv, p + 64);
519 }
528ad661 520
521 MDECINDMA_INT( size / 4 );
522 return;
ef79bbde
P
523
524 case 0x6: // cosine table
525 // printf("mdec cosine table\n");
528ad661 526
527 MDECINDMA_INT( size / 4 );
528 return;
ef79bbde
P
529
530 default:
531 // printf("mdec unknown command\n");
532 break;
533 }
534
535 HW_DMA0_CHCR &= SWAP32(~0x01000000);
536 DMA_INTERRUPT(0);
537}
538
528ad661 539void mdec0Interrupt()
540{
ad418c19 541 if (HW_DMA0_CHCR & SWAP32(0x01000000))
542 {
543 HW_DMA0_CHCR &= SWAP32(~0x01000000);
544 DMA_INTERRUPT(0);
545 }
528ad661 546}
547
548#define SIZE_OF_24B_BLOCK (16*16*3)
549#define SIZE_OF_16B_BLOCK (16*16*2)
550
ef79bbde
P
551void psxDma1(u32 adr, u32 bcr, u32 chcr) {
552 int blk[DSIZE2 * 6];
528ad661 553 u8 * image;
ef79bbde 554 int size;
fc4803bd 555 u32 words;
ef79bbde
P
556
557 if (chcr != 0x01000200) return;
558
fc4803bd 559 words = (bcr >> 16) * (bcr & 0xffff);
528ad661 560 /* size in byte */
fc4803bd 561 size = words * 4;
528ad661 562
563 if (!(mdec.reg1 & MDEC1_BUSY)) {
564 /* add to pending */
565 mdec.pending_dma1.adr = adr;
566 mdec.pending_dma1.bcr = bcr;
567 mdec.pending_dma1.chcr = chcr;
568 /* do not free the dma */
569 } else {
ef79bbde 570
528ad661 571 image = (u8 *)PSXM(adr);
572
573 if (mdec.reg0 & MDEC0_RGB24) {
574 /* 16 bits decoding
575 * block are 16 px * 16 px, each px are 2 byte
576 */
577
578 /* there is some partial block pending ? */
579 if(mdec.block_buffer_pos != 0) {
580 int n = mdec.block_buffer - mdec.block_buffer_pos + SIZE_OF_16B_BLOCK;
581 /* TODO: check if partial block do not larger than size */
582 memcpy(image, mdec.block_buffer_pos, n);
583 image += n;
584 size -= n;
585 mdec.block_buffer_pos = 0;
586 }
ef79bbde 587
528ad661 588 while(size >= SIZE_OF_16B_BLOCK) {
ef79bbde 589 mdec.rl = rl2blk(blk, mdec.rl);
528ad661 590 yuv2rgb15(blk, (u16 *)image);
591 image += SIZE_OF_16B_BLOCK;
592 size -= SIZE_OF_16B_BLOCK;
ef79bbde 593 }
528ad661 594
595 if(size != 0) {
ef79bbde 596 mdec.rl = rl2blk(blk, mdec.rl);
528ad661 597 yuv2rgb15(blk, (u16 *)mdec.block_buffer);
598 memcpy(image, mdec.block_buffer, size);
599 mdec.block_buffer_pos = mdec.block_buffer + size;
600 }
601
602 } else {
603 /* 24 bits decoding
604 * block are 16 px * 16 px, each px are 3 byte
605 */
606
607 /* there is some partial block pending ? */
608 if(mdec.block_buffer_pos != 0) {
609 int n = mdec.block_buffer - mdec.block_buffer_pos + SIZE_OF_24B_BLOCK;
610 /* TODO: check if partial block do not larger than size */
611 memcpy(image, mdec.block_buffer_pos, n);
612 image += n;
613 size -= n;
614 mdec.block_buffer_pos = 0;
615 }
616
617 while(size >= SIZE_OF_24B_BLOCK) {
618 mdec.rl = rl2blk(blk, mdec.rl);
619 yuv2rgb24(blk, image);
620 image += SIZE_OF_24B_BLOCK;
621 size -= SIZE_OF_24B_BLOCK;
ef79bbde 622 }
ef79bbde 623
528ad661 624 if(size != 0) {
625 mdec.rl = rl2blk(blk, mdec.rl);
626 yuv2rgb24(blk, mdec.block_buffer);
627 memcpy(image, mdec.block_buffer, size);
628 mdec.block_buffer_pos = mdec.block_buffer + size;
629 }
630 }
631
632 /* define the power of mdec */
fc4803bd 633 MDECOUTDMA_INT(words * MDEC_BIAS);
528ad661 634 }
ef79bbde
P
635}
636
637void mdec1Interrupt() {
528ad661 638 /* Author : gschwind
639 *
640 * in that case we have done all decoding stuff
641 * Note that : each block end with 0xfe00 flags
642 * the list of blocks end with the same 0xfe00 flags
643 * data loock like :
644 *
645 * data block ...
646 * 0xfe00
647 * data block ...
648 * 0xfe00
649 * a lost of block ..
650 *
651 * 0xfe00
652 * the last block
653 * 0xfe00
654 * 0xfe00
655 *
656 * OR
657 *
658 * if the 0xfe00 is not present the data size is important.
659 *
660 */
661
ad418c19 662 /* MDEC_END_OF_DATA avoids read outside memory */
663 if (mdec.rl >= mdec.rl_end || SWAP16(*(mdec.rl)) == MDEC_END_OF_DATA) {
664 mdec.reg1 &= ~(MDEC1_STP|MDEC1_BUSY);
665 if (HW_DMA0_CHCR & SWAP32(0x01000000))
666 {
667 HW_DMA0_CHCR &= SWAP32(~0x01000000);
668 DMA_INTERRUPT(0);
669 }
ef79bbde 670 }
528ad661 671
ad418c19 672 if (HW_DMA1_CHCR & SWAP32(0x01000000))
673 {
674 HW_DMA1_CHCR &= SWAP32(~0x01000000);
675 DMA_INTERRUPT(1);
676 }
ef79bbde
P
677}
678
496d88d4 679int mdecFreeze(void *f, int Mode) {
8e1040b6 680 u8 *base = (u8 *)&psxM[0x100000];
681 u32 v;
682
683 gzfreeze(&mdec.reg0, sizeof(mdec.reg0));
684 gzfreeze(&mdec.reg1, sizeof(mdec.reg1));
685
686 // old code used to save raw pointers..
687 v = (u8 *)mdec.rl - base;
688 gzfreeze(&v, sizeof(v));
689 mdec.rl = (u16 *)(base + (v & 0xffffe));
690 v = (u8 *)mdec.rl_end - base;
691 gzfreeze(&v, sizeof(v));
692 mdec.rl_end = (u16 *)(base + (v & 0xffffe));
693
694 v = 0;
695 if (mdec.block_buffer_pos)
696 v = mdec.block_buffer_pos - base;
697 gzfreeze(&v, sizeof(v));
698 mdec.block_buffer_pos = 0;
699 if (v)
700 mdec.block_buffer_pos = base + (v & 0xfffff);
701
702 gzfreeze(&mdec.block_buffer, sizeof(mdec.block_buffer));
703 gzfreeze(&mdec.pending_dma1, sizeof(mdec.pending_dma1));
ef79bbde
P
704 gzfreeze(iq_y, sizeof(iq_y));
705 gzfreeze(iq_uv, sizeof(iq_uv));
706
707 return 0;
708}