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