1 /***********************************************************************************
2   Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 
4   (c) Copyright 1996 - 2002  Gary Henderson (gary.henderson@ntlworld.com),
5                              Jerremy Koot (jkoot@snes9x.com)
6 
7   (c) Copyright 2002 - 2004  Matthew Kendora
8 
9   (c) Copyright 2002 - 2005  Peter Bortas (peter@bortas.org)
10 
11   (c) Copyright 2004 - 2005  Joel Yliluoma (http://iki.fi/bisqwit/)
12 
13   (c) Copyright 2001 - 2006  John Weidman (jweidman@slip.net)
14 
15   (c) Copyright 2002 - 2006  funkyass (funkyass@spam.shaw.ca),
16                              Kris Bleakley (codeviolation@hotmail.com)
17 
18   (c) Copyright 2002 - 2010  Brad Jorsch (anomie@users.sourceforge.net),
19                              Nach (n-a-c-h@users.sourceforge.net),
20 
21   (c) Copyright 2002 - 2011  zones (kasumitokoduck@yahoo.com)
22 
23   (c) Copyright 2006 - 2007  nitsuja
24 
25   (c) Copyright 2009 - 2016  BearOso,
26                              OV2
27 
28 
29   BS-X C emulator code
30   (c) Copyright 2005 - 2006  Dreamer Nom,
31                              zones
32 
33   C4 x86 assembler and some C emulation code
34   (c) Copyright 2000 - 2003  _Demo_ (_demo_@zsnes.com),
35                              Nach,
36                              zsKnight (zsknight@zsnes.com)
37 
38   C4 C++ code
39   (c) Copyright 2003 - 2006  Brad Jorsch,
40                              Nach
41 
42   DSP-1 emulator code
43   (c) Copyright 1998 - 2006  _Demo_,
44                              Andreas Naive (andreasnaive@gmail.com),
45                              Gary Henderson,
46                              Ivar (ivar@snes9x.com),
47                              John Weidman,
48                              Kris Bleakley,
49                              Matthew Kendora,
50                              Nach,
51                              neviksti (neviksti@hotmail.com)
52 
53   DSP-2 emulator code
54   (c) Copyright 2003         John Weidman,
55                              Kris Bleakley,
56                              Lord Nightmare (lord_nightmare@users.sourceforge.net),
57                              Matthew Kendora,
58                              neviksti
59 
60   DSP-3 emulator code
61   (c) Copyright 2003 - 2006  John Weidman,
62                              Kris Bleakley,
63                              Lancer,
64                              z80 gaiden
65 
66   DSP-4 emulator code
67   (c) Copyright 2004 - 2006  Dreamer Nom,
68                              John Weidman,
69                              Kris Bleakley,
70                              Nach,
71                              z80 gaiden
72 
73   OBC1 emulator code
74   (c) Copyright 2001 - 2004  zsKnight,
75                              pagefault (pagefault@zsnes.com),
76                              Kris Bleakley
77                              Ported from x86 assembler to C by sanmaiwashi
78 
79   SPC7110 and RTC C++ emulator code used in 1.39-1.51
80   (c) Copyright 2002         Matthew Kendora with research by
81                              zsKnight,
82                              John Weidman,
83                              Dark Force
84 
85   SPC7110 and RTC C++ emulator code used in 1.52+
86   (c) Copyright 2009         byuu,
87                              neviksti
88 
89   S-DD1 C emulator code
90   (c) Copyright 2003         Brad Jorsch with research by
91                              Andreas Naive,
92                              John Weidman
93 
94   S-RTC C emulator code
95   (c) Copyright 2001 - 2006  byuu,
96                              John Weidman
97 
98   ST010 C++ emulator code
99   (c) Copyright 2003         Feather,
100                              John Weidman,
101                              Kris Bleakley,
102                              Matthew Kendora
103 
104   Super FX x86 assembler emulator code
105   (c) Copyright 1998 - 2003  _Demo_,
106                              pagefault,
107                              zsKnight
108 
109   Super FX C emulator code
110   (c) Copyright 1997 - 1999  Ivar,
111                              Gary Henderson,
112                              John Weidman
113 
114   Sound emulator code used in 1.5-1.51
115   (c) Copyright 1998 - 2003  Brad Martin
116   (c) Copyright 1998 - 2006  Charles Bilyue'
117 
118   Sound emulator code used in 1.52+
119   (c) Copyright 2004 - 2007  Shay Green (gblargg@gmail.com)
120 
121   S-SMP emulator code used in 1.54+
122   (c) Copyright 2016         byuu
123 
124   SH assembler code partly based on x86 assembler code
125   (c) Copyright 2002 - 2004  Marcus Comstedt (marcus@mc.pp.se)
126 
127   2xSaI filter
128   (c) Copyright 1999 - 2001  Derek Liauw Kie Fa
129 
130   HQ2x, HQ3x, HQ4x filters
131   (c) Copyright 2003         Maxim Stepin (maxim@hiend3d.com)
132 
133   NTSC filter
134   (c) Copyright 2006 - 2007  Shay Green
135 
136   GTK+ GUI code
137   (c) Copyright 2004 - 2016  BearOso
138 
139   Win32 GUI code
140   (c) Copyright 2003 - 2006  blip,
141                              funkyass,
142                              Matthew Kendora,
143                              Nach,
144                              nitsuja
145   (c) Copyright 2009 - 2016  OV2
146 
147   Mac OS GUI code
148   (c) Copyright 1998 - 2001  John Stiles
149   (c) Copyright 2001 - 2011  zones
150 
151 
152   Specific ports contains the works of other authors. See headers in
153   individual files.
154 
155 
156   Snes9x homepage: http://www.snes9x.com/
157 
158   Permission to use, copy, modify and/or distribute Snes9x in both binary
159   and source form, for non-commercial purposes, is hereby granted without
160   fee, providing that this license information and copyright notice appear
161   with all copies and any derived work.
162 
163   This software is provided 'as-is', without any express or implied
164   warranty. In no event shall the authors be held liable for any damages
165   arising from the use of this software or it's derivatives.
166 
167   Snes9x is freeware for PERSONAL USE only. Commercial users should
168   seek permission of the copyright holders first. Commercial use includes,
169   but is not limited to, charging money for Snes9x or software derived from
170   Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
171   using Snes9x as a promotion for your commercial product.
172 
173   The copyright holders request that bug fixes and improvements to the code
174   should be forwarded to them so everyone can benefit from the modifications
175   in future versions.
176 
177   Super NES and Super Nintendo Entertainment System are trademarks of
178   Nintendo Co., Limited and its subsidiary companies.
179  ***********************************************************************************/
180 
181 
182 #include "snes9x.h"
183 #include "memmap.h"
184 
185 static void DSP2_Op01 (void);
186 static void DSP2_Op03 (void);
187 static void DSP2_Op05 (void);
188 static void DSP2_Op06 (void);
189 static void DSP2_Op09 (void);
190 static void DSP2_Op0D (void);
191 
192 
193 // convert bitmap to bitplane tile
DSP2_Op01(void)194 static void DSP2_Op01 (void)
195 {
196 	// Op01 size is always 32 bytes input and output
197 	// The hardware does strange things if you vary the size
198 
199 	uint8	c0, c1, c2, c3;
200 	uint8	*p1  = DSP2.parameters;
201 	uint8	*p2a = DSP2.output;
202 	uint8	*p2b = DSP2.output + 16; // halfway
203 
204 	// Process 8 blocks of 4 bytes each
205 
206 	for (int j = 0; j < 8; j++)
207 	{
208 		c0 = *p1++;
209 		c1 = *p1++;
210 		c2 = *p1++;
211 		c3 = *p1++;
212 
213 		*p2a++ = (c0 & 0x10) << 3 |
214 				 (c0 & 0x01) << 6 |
215 				 (c1 & 0x10) << 1 |
216 				 (c1 & 0x01) << 4 |
217 				 (c2 & 0x10) >> 1 |
218 				 (c2 & 0x01) << 2 |
219 				 (c3 & 0x10) >> 3 |
220 				 (c3 & 0x01);
221 
222 		*p2a++ = (c0 & 0x20) << 2 |
223 				 (c0 & 0x02) << 5 |
224 				 (c1 & 0x20)      |
225 				 (c1 & 0x02) << 3 |
226 				 (c2 & 0x20) >> 2 |
227 				 (c2 & 0x02) << 1 |
228 				 (c3 & 0x20) >> 4 |
229 				 (c3 & 0x02) >> 1;
230 
231 		*p2b++ = (c0 & 0x40) << 1 |
232 				 (c0 & 0x04) << 4 |
233 				 (c1 & 0x40) >> 1 |
234 				 (c1 & 0x04) << 2 |
235 				 (c2 & 0x40) >> 3 |
236 				 (c2 & 0x04)      |
237 				 (c3 & 0x40) >> 5 |
238 				 (c3 & 0x04) >> 2;
239 
240 		*p2b++ = (c0 & 0x80)      |
241 				 (c0 & 0x08) << 3 |
242 				 (c1 & 0x80) >> 2 |
243 				 (c1 & 0x08) << 1 |
244 				 (c2 & 0x80) >> 4 |
245 				 (c2 & 0x08) >> 1 |
246 				 (c3 & 0x80) >> 6 |
247 				 (c3 & 0x08) >> 3;
248 	}
249 }
250 
251 // set transparent color
DSP2_Op03(void)252 static void DSP2_Op03 (void)
253 {
254 	DSP2.Op05Transparent = DSP2.parameters[0];
255 }
256 
257 // replace bitmap using transparent color
DSP2_Op05(void)258 static void DSP2_Op05 (void)
259 {
260 	// Overlay bitmap with transparency.
261 	// Input:
262 	//
263 	//   Bitmap 1:  i[0] <=> i[size-1]
264 	//   Bitmap 2:  i[size] <=> i[2*size-1]
265 	//
266 	// Output:
267 	//
268 	//   Bitmap 3:  o[0] <=> o[size-1]
269 	//
270 	// Processing:
271 	//
272 	//   Process all 4-bit pixels (nibbles) in the bitmap
273 	//
274 	//   if ( BM2_pixel == transparent_color )
275 	//      pixelout = BM1_pixel
276 	//   else
277 	//      pixelout = BM2_pixel
278 
279 	// The max size bitmap is limited to 255 because the size parameter is a byte
280 	// I think size=0 is an error.  The behavior of the chip on size=0 is to
281 	// return the last value written to DR if you read DR on Op05 with
282 	// size = 0.  I don't think it's worth implementing this quirk unless it's
283 	// proven necessary.
284 
285 	uint8	color;
286 	uint8	c1, c2;
287 	uint8	*p1 = DSP2.parameters;
288 	uint8	*p2 = DSP2.parameters + DSP2.Op05Len;
289 	uint8	*p3 = DSP2.output;
290 
291 	color = DSP2.Op05Transparent & 0x0f;
292 
293 	for (int32 n = 0; n < DSP2.Op05Len; n++)
294 	{
295 		c1 = *p1++;
296 		c2 = *p2++;
297 		*p3++ = (((c2 >> 4) == color) ? c1 & 0xf0: c2 & 0xf0) | (((c2 & 0x0f) == color) ? c1 & 0x0f: c2 & 0x0f);
298 	}
299 }
300 
301 // reverse bitmap
DSP2_Op06(void)302 static void DSP2_Op06 (void)
303 {
304 	// Input:
305 	//    size
306 	//    bitmap
307 
308 	for (int32 i = 0, j = DSP2.Op06Len - 1; i < DSP2.Op06Len; i++, j--)
309 		DSP2.output[j] = (DSP2.parameters[i] << 4) | (DSP2.parameters[i] >> 4);
310 }
311 
312 // multiply
DSP2_Op09(void)313 static void DSP2_Op09 (void)
314 {
315 	DSP2.Op09Word1 = DSP2.parameters[0] | (DSP2.parameters[1] << 8);
316 	DSP2.Op09Word2 = DSP2.parameters[2] | (DSP2.parameters[3] << 8);
317 
318 	uint32	temp = DSP2.Op09Word1 * DSP2.Op09Word2;
319 	DSP2.output[0] =  temp        & 0xFF;
320 	DSP2.output[1] = (temp >>  8) & 0xFF;
321 	DSP2.output[2] = (temp >> 16) & 0xFF;
322 	DSP2.output[3] = (temp >> 24) & 0xFF;
323 }
324 
325 // scale bitmap
DSP2_Op0D(void)326 static void DSP2_Op0D (void)
327 {
328 	// Bit accurate hardware algorithm - uses fixed point math
329 	// This should match the DSP2 Op0D output exactly
330 	// I wouldn't recommend using this unless you're doing hardware debug.
331 	// In some situations it has small visual artifacts that
332 	// are not readily apparent on a TV screen but show up clearly
333 	// on a monitor.  Use Overload's scaling instead.
334 	// This is for hardware verification testing.
335 	//
336 	// One note:  the HW can do odd byte scaling but since we divide
337 	// by two to get the count of bytes this won't work well for
338 	// odd byte scaling (in any of the current algorithm implementations).
339 	// So far I haven't seen Dungeon Master use it.
340 	// If it does we can adjust the parameters and code to work with it
341 
342 	uint32	multiplier; // Any size int >= 32-bits
343 	uint32	pixloc;	    // match size of multiplier
344 	uint8	pixelarray[512];
345 
346 	if (DSP2.Op0DInLen <= DSP2.Op0DOutLen)
347 		multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1
348 	else
349 		multiplier = (DSP2.Op0DInLen << 17) / ((DSP2.Op0DOutLen << 1) + 1);
350 
351 	pixloc = 0;
352 
353 	for (int32 i = 0; i < DSP2.Op0DOutLen * 2; i++)
354 	{
355 		int32	j = pixloc >> 16;
356 
357 		if (j & 1)
358 			pixelarray[i] =  DSP2.parameters[j >> 1] & 0x0f;
359 		else
360 			pixelarray[i] = (DSP2.parameters[j >> 1] & 0xf0) >> 4;
361 
362 		pixloc += multiplier;
363 	}
364 
365 	for (int32 i = 0; i < DSP2.Op0DOutLen; i++)
366 		DSP2.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1];
367 }
368 
369 /*
370 static void DSP2_Op0D (void)
371 {
372 	// Overload's algorithm - use this unless doing hardware testing
373 
374 	// One note:  the HW can do odd byte scaling but since we divide
375 	// by two to get the count of bytes this won't work well for
376 	// odd byte scaling (in any of the current algorithm implementations).
377 	// So far I haven't seen Dungeon Master use it.
378 	// If it does we can adjust the parameters and code to work with it
379 
380 	int32	pixel_offset;
381 	uint8	pixelarray[512];
382 
383 	for (int32 i = 0; i < DSP2.Op0DOutLen * 2; i++)
384 	{
385 		pixel_offset = (i * DSP2.Op0DInLen) / DSP2.Op0DOutLen;
386 
387 		if ((pixel_offset & 1) == 0)
388 			pixelarray[i] = DSP2.parameters[pixel_offset >> 1] >> 4;
389 		else
390 			pixelarray[i] = DSP2.parameters[pixel_offset >> 1] & 0x0f;
391 	}
392 
393 	for (int32 i = 0; i < DSP2.Op0DOutLen; i++)
394 		DSP2.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1];
395 }
396 */
397 
DSP2SetByte(uint8 byte,uint16 address)398 void DSP2SetByte (uint8 byte, uint16 address)
399 {
400 	if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000))
401 	{
402 		if (DSP2.waiting4command)
403 		{
404 			DSP2.command         = byte;
405 			DSP2.in_index        = 0;
406 			DSP2.waiting4command = FALSE;
407 
408 			switch (byte)
409 			{
410 				case 0x01: DSP2.in_count = 32; break;
411 				case 0x03: DSP2.in_count =  1; break;
412 				case 0x05: DSP2.in_count =  1; break;
413 				case 0x06: DSP2.in_count =  1; break;
414 				case 0x09: DSP2.in_count =  4; break;
415 				case 0x0D: DSP2.in_count =  2; break;
416 				default:
417 				#ifdef DEBUGGER
418 					//printf("Op%02X\n", byte);
419 				#endif
420 				case 0x0f: DSP2.in_count =  0; break;
421 			}
422 		}
423 		else
424 		{
425 			DSP2.parameters[DSP2.in_index] = byte;
426 			DSP2.in_index++;
427 		}
428 
429 		if (DSP2.in_count == DSP2.in_index)
430 		{
431 			DSP2.waiting4command = TRUE;
432 			DSP2.out_index       = 0;
433 
434 			switch (DSP2.command)
435 			{
436 				case 0x01:
437 					DSP2.out_count = 32;
438 					DSP2_Op01();
439 					break;
440 
441 				case 0x03:
442 					DSP2_Op03();
443 					break;
444 
445 				case 0x05:
446 					if (DSP2.Op05HasLen)
447 					{
448 						DSP2.Op05HasLen = FALSE;
449 						DSP2.out_count  = DSP2.Op05Len;
450 						DSP2_Op05();
451 					}
452 					else
453 					{
454 						DSP2.Op05Len    = DSP2.parameters[0];
455 						DSP2.in_index   = 0;
456 						DSP2.in_count   = 2 * DSP2.Op05Len;
457 						DSP2.Op05HasLen = TRUE;
458 						if (byte)
459 							DSP2.waiting4command = FALSE;
460 					}
461 
462 					break;
463 
464 				case 0x06:
465 					if (DSP2.Op06HasLen)
466 					{
467 						DSP2.Op06HasLen = FALSE;
468 						DSP2.out_count  = DSP2.Op06Len;
469 						DSP2_Op06();
470 					}
471 					else
472 					{
473 						DSP2.Op06Len    = DSP2.parameters[0];
474 						DSP2.in_index   = 0;
475 						DSP2.in_count   = DSP2.Op06Len;
476 						DSP2.Op06HasLen = TRUE;
477 						if (byte)
478 							DSP2.waiting4command = FALSE;
479 					}
480 
481 					break;
482 
483 				case 0x09:
484 					DSP2.out_count = 4;
485 					DSP2_Op09();
486 					break;
487 
488 				case 0x0D:
489 					if (DSP2.Op0DHasLen)
490 					{
491 						DSP2.Op0DHasLen = FALSE;
492 						DSP2.out_count  = DSP2.Op0DOutLen;
493 						DSP2_Op0D();
494 					}
495 					else
496 					{
497 						DSP2.Op0DInLen  = DSP2.parameters[0];
498 						DSP2.Op0DOutLen = DSP2.parameters[1];
499 						DSP2.in_index   = 0;
500 						DSP2.in_count   = (DSP2.Op0DInLen + 1) >> 1;
501 						DSP2.Op0DHasLen = TRUE;
502 						if (byte)
503 							DSP2.waiting4command = FALSE;
504 					}
505 
506 					break;
507 
508 				case 0x0f:
509 				default:
510 					break;
511 			}
512 		}
513 	}
514 }
515 
DSP2GetByte(uint16 address)516 uint8 DSP2GetByte (uint16 address)
517 {
518 	uint8	t;
519 
520 	if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000))
521 	{
522 		if (DSP2.out_count)
523 		{
524 			t = (uint8) DSP2.output[DSP2.out_index];
525 			DSP2.out_index++;
526 			if (DSP2.out_count == DSP2.out_index)
527 				DSP2.out_count = 0;
528 		}
529 		else
530 			t = 0xff;
531 	}
532 	else
533 		t = 0x80;
534 
535 	return (t);
536 }
537