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