2 * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
4 * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5 * Jerremy Koot (jkoot@snes9x.com)
7 * Super FX C emulator code
8 * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
10 * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
12 * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
13 * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
14 * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
16 * DOS port code contains the works of other authors. See headers in
19 * Snes9x homepage: http://www.snes9x.com
21 * Permission to use, copy, modify and distribute Snes9x in both binary and
22 * source form, for non-commercial purposes, is hereby granted without fee,
23 * providing that this license information and copyright notice appear with
24 * all copies and any derived work.
26 * This software is provided 'as-is', without any express or implied
27 * warranty. In no event shall the authors be held liable for any damages
28 * arising from the use of this software.
30 * Snes9x is freeware for PERSONAL USE only. Commercial users should
31 * seek permission of the copyright holders first. Commercial use includes
32 * charging money for Snes9x or software derived from Snes9x.
34 * The copyright holders request that bug fixes and improvements to the code
35 * should be forwarded to them so everyone can benefit from the modifications
38 * Super NES and Super Nintendo Entertainment System are trademarks of
39 * Nintendo Co., Limited and its subsidiary companies.
47 EXTERN_C void _2xSaILine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width,
48 uint8 *dstPtr, uint32 dstPitch);
49 EXTERN_C void _2xSaISuperEagleLine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width,
50 uint8 *dstPtr, uint32 dstPitch);
51 EXTERN_C int Init_2xSaIMMX (uint32 BitFormat);
56 static uint32 colorMask = 0xF7DEF7DE;
57 static uint32 lowPixelMask = 0x08210821;
58 static uint32 qcolorMask = 0xE79CE79C;
59 static uint32 qlowpixelMask = 0x18631863;
62 int Init_2xSaI(uint32 BitFormat)
66 colorMask = 0xF7DEF7DE;
67 lowPixelMask = 0x08210821;
68 qcolorMask = 0xE79CE79C;
69 qlowpixelMask = 0x18631863;
74 colorMask = 0x7BDE7BDE;
75 lowPixelMask = 0x04210421;
76 qcolorMask = 0x739C739C;
77 qlowpixelMask = 0x0C630C63;
84 Init_2xSaIMMX(BitFormat);
89 STATIC inline int GetResult1(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E)
94 if (A == C) x+=1; else if (B == C) y+=1;
95 if (A == D) x+=1; else if (B == D) y+=1;
101 STATIC inline int GetResult2(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E)
106 if (A == C) x+=1; else if (B == C) y+=1;
107 if (A == D) x+=1; else if (B == D) y+=1;
114 STATIC inline int GetResult(uint32 A, uint32 B, uint32 C, uint32 D)
119 if (A == C) x+=1; else if (B == C) y+=1;
120 if (A == D) x+=1; else if (B == D) y+=1;
127 STATIC inline uint32 INTERPOLATE(uint32 A, uint32 B)
131 return ( ((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask) );
137 STATIC inline uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D)
139 register uint32 x = ((A & qcolorMask) >> 2) +
140 ((B & qcolorMask) >> 2) +
141 ((C & qcolorMask) >> 2) +
142 ((D & qcolorMask) >> 2);
143 register uint32 y = (A & qlowpixelMask) +
144 (B & qlowpixelMask) +
145 (C & qlowpixelMask) +
147 y = (y>>2) & qlowpixelMask;
156 void Super2xSaI(uint8 *srcPtr, uint32 srcPitch,
158 uint8 *dstPtr, uint32 dstPitch, int width, int height)
163 #ifdef MMX_BLA //no MMX version yet
164 if (cpu_mmx && width != 512)
166 for (; height; height--)
168 bP = (uint16 *) srcPtr;
169 xP = (uint16 *) deltaPtr;
170 dP = (uint32 *) dstPtr;
171 _2xSaISuperEagleLine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *) dP, dstPitch);
172 dstPtr += dstPitch << 1;
174 deltaPtr += srcPitch;
180 uint32 Nextline = srcPitch >> 1;
182 for (; height; height--)
184 bP = (uint16 *) srcPtr;
185 dP = (uint32 *) dstPtr;
186 for (uint32 finish = width; finish; finish -= 1 )
188 uint32 color4, color5, color6;
189 uint32 color1, color2, color3;
190 uint32 colorA0, colorA1, colorA2, colorA3,
191 colorB0, colorB1, colorB2, colorB3,
193 uint32 product1a, product1b,
194 product2a, product2b;
196 //--------------------------------------- B1 B2
201 colorB0 = *(bP- Nextline - 1);
202 colorB1 = *(bP- Nextline);
203 colorB2 = *(bP- Nextline + 1);
204 colorB3 = *(bP- Nextline + 2);
211 color1 = *(bP + Nextline - 1);
212 color2 = *(bP + Nextline);
213 color3 = *(bP + Nextline + 1);
214 colorS1 = *(bP + Nextline + 2);
216 colorA0 = *(bP + Nextline + Nextline - 1);
217 colorA1 = *(bP + Nextline + Nextline);
218 colorA2 = *(bP + Nextline + Nextline + 1);
219 colorA3 = *(bP + Nextline + Nextline + 2);
222 //--------------------------------------
223 if (color2 == color6 && color5 != color3)
225 product2b = product1b = color2;
228 if (color5 == color3 && color2 != color6)
230 product2b = product1b = color5;
233 if (color5 == color3 && color2 == color6 && color5 != color6)
237 r += GetResult (color6, color5, color1, colorA1);
238 r += GetResult (color6, color5, color4, colorB1);
239 r += GetResult (color6, color5, colorA2, colorS1);
240 r += GetResult (color6, color5, colorB2, colorS2);
243 product2b = product1b = color6;
246 product2b = product1b = color5;
249 product2b = product1b = INTERPOLATE (color5, color6);
257 if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
258 product2b = Q_INTERPOLATE (color3, color3, color3, color2);
260 if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
261 product2b = Q_INTERPOLATE (color2, color2, color2, color3);
264 product2b = INTERPOLATE (color2, color3);
267 if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
268 product1b = Q_INTERPOLATE (color6, color6, color6, color5);
270 if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
271 product1b = Q_INTERPOLATE (color6, color5, color5, color5);
274 product1b = INTERPOLATE (color5, color6);
278 if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
279 product2a = INTERPOLATE (color2, color5);
281 if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
282 product2a = INTERPOLATE(color2, color5);
288 if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
289 product1a = INTERPOLATE (color2, color5);
291 if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
292 product1a = INTERPOLATE(color2, color5);
298 product1a = product1a | (product1b << 16);
299 product2a = product2a | (product2b << 16);
302 *(dP+(dstPitch>>2)) = product2a;
306 }//end of for ( finish= width etc..)
308 dstPtr += dstPitch << 1;
310 deltaPtr += srcPitch;
311 }; //endof: for (height; height; height--)
322 /*ONLY use with 640x480x16 or higher resolutions*/
323 /*Only use this if 2*width * 2*height fits on the current screen*/
324 void SuperEagle(uint8 *srcPtr, uint32 srcPitch,
326 uint8 *dstPtr, uint32 dstPitch, int width, int height)
335 if (mmx_cpu && width != 512)
337 for (; height; height--)
339 bP = (uint16 *) srcPtr;
340 xP = (uint16 *) deltaPtr;
341 dP = (uint32 *) dstPtr;
342 _2xSaISuperEagleLine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch);
343 dstPtr += dstPitch << 1;
345 deltaPtr += srcPitch;
351 uint32 Nextline = srcPitch >> 1;
353 for (; height; height--)
355 bP = (uint16 *) srcPtr;
356 dP = (uint32 *) dstPtr;
357 for (uint32 finish = width; finish; finish -= 1 )
360 uint32 color4, color5, color6;
361 uint32 color1, color2, color3;
362 uint32 colorA0, colorA1, colorA2, colorA3,
363 colorB0, colorB1, colorB2, colorB3,
365 uint32 product1a, product1b,
366 product2a, product2b;
368 colorB0 = *(bP- Nextline - 1);
369 colorB1 = *(bP- Nextline);
370 colorB2 = *(bP- Nextline + 1);
371 colorB3 = *(bP- Nextline + 2);
378 color1 = *(bP + Nextline - 1);
379 color2 = *(bP + Nextline);
380 color3 = *(bP + Nextline + 1);
381 colorS1 = *(bP + Nextline + 2);
383 colorA0 = *(bP + Nextline + Nextline - 1);
384 colorA1 = *(bP + Nextline + Nextline);
385 colorA2 = *(bP + Nextline + Nextline + 1);
386 colorA3 = *(bP + Nextline + Nextline + 2);
389 //--------------------------------------
390 if (color2 == color6 && color5 != color3)
392 product1b = product2a = color2;
393 if ((color1 == color2 && color6 == colorS2) ||
394 (color2 == colorA1 && color6 == colorB2))
396 product1a = INTERPOLATE (color2, color5);
397 product1a = INTERPOLATE (color2, product1a);
398 product2b = INTERPOLATE (color2, color3);
399 product2b = INTERPOLATE (color2, product2b);
400 // product1a = color2;
401 // product2b = color2;
405 product1a = INTERPOLATE (color5, color6);
406 product2b = INTERPOLATE (color2, color3);
410 if (color5 == color3 && color2 != color6)
412 product2b = product1a = color5;
413 if ((colorB1 == color5 && color3 == colorA2) ||
414 (color4 == color5 && color3 == colorS1))
416 product1b = INTERPOLATE (color5, color6);
417 product1b = INTERPOLATE (color5, product1b);
418 product2a = INTERPOLATE (color5, color2);
419 product2a = INTERPOLATE (color5, product2a);
420 // product1b = color5;
421 // product2a = color5;
425 product1b = INTERPOLATE (color5, color6);
426 product2a = INTERPOLATE (color2, color3);
430 if (color5 == color3 && color2 == color6 && color5 != color6)
434 r += GetResult (color6, color5, color1, colorA1);
435 r += GetResult (color6, color5, color4, colorB1);
436 r += GetResult (color6, color5, colorA2, colorS1);
437 r += GetResult (color6, color5, colorB2, colorS2);
441 product1b = product2a = color2;
442 product1a = product2b = INTERPOLATE (color5, color6);
447 product2b = product1a = color5;
448 product1b = product2a = INTERPOLATE (color5, color6);
452 product2b = product1a = color5;
453 product1b = product2a = color2;
459 if ((color2 == color5) || (color3 == color6))
469 product1b = product1a = INTERPOLATE (color5, color6);
470 product1a = INTERPOLATE (color5, product1a);
471 product1b = INTERPOLATE (color6, product1b);
473 product2a = product2b = INTERPOLATE (color2, color3);
474 product2a = INTERPOLATE (color2, product2a);
475 product2b = INTERPOLATE (color3, product2b);
480 product1a = product1a | (product1b << 16);
481 product2a = product2a | (product2b << 16);
484 *(dP+(dstPitch>>2)) = product2a;
488 }//end of for ( finish= width etc..)
490 dstPtr += dstPitch << 1;
492 deltaPtr += srcPitch;
493 }; //endof: for (height; height; height--)
501 /*ONLY use with 640x480x16 or higher resolutions*/
502 /*Only use this if 2*width * 2*height fits on the current screen*/
503 void _2xSaI(uint8 *srcPtr, uint32 srcPitch,
505 uint8 *dstPtr, uint32 dstPitch, int width, int height)
514 if (mmx_cpu && width != 512)
516 for (; height; height--)
519 bP = (uint16 *) srcPtr;
520 xP = (uint16 *) deltaPtr;
521 dP = (uint32 *) dstPtr;
522 _2xSaILine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch);
523 dstPtr += dstPitch << 1;
525 deltaPtr += srcPitch;
531 uint32 Nextline = srcPitch >> 1;
533 for (; height; height--)
535 bP = (uint16 *) srcPtr;
536 dP = (uint32 *) dstPtr;
537 for (uint32 finish = width; finish; finish -= 1 )
541 register uint32 colorA, colorB;
542 uint32 colorC, colorD,
543 colorE, colorF, colorG, colorH,
544 colorI, colorJ, colorK, colorL,
545 colorM, colorN, colorO, colorP;
546 uint32 product, product1, product2;
549 //---------------------------------------
550 // Map of the pixels: I|E F|J
554 colorI = *(bP- Nextline - 1);
555 colorE = *(bP- Nextline);
556 colorF = *(bP- Nextline + 1);
557 colorJ = *(bP- Nextline + 2);
564 colorH = *(bP + Nextline - 1);
565 colorC = *(bP + Nextline);
566 colorD = *(bP + Nextline + 1);
567 colorL = *(bP + Nextline + 2);
569 colorM = *(bP + Nextline + Nextline - 1);
570 colorN = *(bP + Nextline + Nextline);
571 colorO = *(bP + Nextline + Nextline + 1);
572 colorP = *(bP + Nextline + Nextline + 2);
574 if ((colorA == colorD) && (colorB != colorC))
576 if ( ((colorA == colorE) && (colorB == colorL)) ||
577 ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) )
583 product = INTERPOLATE(colorA, colorB);
586 if (((colorA == colorG) && (colorC == colorO)) ||
587 ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) )
593 product1 = INTERPOLATE(colorA, colorC);
598 if ((colorB == colorC) && (colorA != colorD))
600 if (((colorB == colorF) && (colorA == colorH)) ||
601 ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) )
607 product = INTERPOLATE(colorA, colorB);
610 if (((colorC == colorH) && (colorA == colorF)) ||
611 ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) )
617 product1 = INTERPOLATE(colorA, colorC);
622 if ((colorA == colorD) && (colorB == colorC))
624 if (colorA == colorB)
633 product1 = INTERPOLATE(colorA, colorC);
634 product = INTERPOLATE(colorA, colorB);
636 r += GetResult1 (colorA, colorB, colorG, colorE, colorI);
637 r += GetResult2 (colorB, colorA, colorK, colorF, colorJ);
638 r += GetResult2 (colorB, colorA, colorH, colorN, colorM);
639 r += GetResult1 (colorA, colorB, colorL, colorO, colorP);
648 product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD);
654 product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD);
656 if ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ))
661 if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
667 product = INTERPOLATE(colorA, colorB);
670 if ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM))
675 if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI))
681 product1 = INTERPOLATE(colorA, colorC);
684 product = colorA | (product << 16);
685 product1 = product1 | (product2 << 16);
687 *(dP+(dstPitch>>2)) = product1;
691 }//end of for ( finish= width etc..)
693 dstPtr += dstPitch << 1;
695 deltaPtr += srcPitch;
696 }; //endof: for (height; height; height--)