~random-stuff/random-stuff/snes9x-OLD

1 by OV2
Initial 1.52 import
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),
87 by OV2
Update copyright in all files
20
21
  (c) Copyright 2002 - 2011  zones (kasumitokoduck@yahoo.com)
1 by OV2
Initial 1.52 import
22
23
  (c) Copyright 2006 - 2007  nitsuja
24
290 by Brandon Wright
Update some copyrights, bump version number.
25
  (c) Copyright 2009 - 2016  BearOso,
1 by OV2
Initial 1.52 import
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
295 by Brandon Wright
Add byuu copyright for his S-SMP
121
  S-SMP emulator code used in 1.54+
122
  (c) Copyright 2016         byuu
123
1 by OV2
Initial 1.52 import
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
290 by Brandon Wright
Update some copyrights, bump version number.
137
  (c) Copyright 2004 - 2016  BearOso
1 by OV2
Initial 1.52 import
138
139
  Win32 GUI code
140
  (c) Copyright 2003 - 2006  blip,
141
                             funkyass,
142
                             Matthew Kendora,
143
                             Nach,
144
                             nitsuja
298 by Brandon Wright
Bump OV2 Windows port copyright.
145
  (c) Copyright 2009 - 2016  OV2
1 by OV2
Initial 1.52 import
146
147
  Mac OS GUI code
148
  (c) Copyright 1998 - 2001  John Stiles
87 by OV2
Update copyright in all files
149
  (c) Copyright 2001 - 2011  zones
1 by OV2
Initial 1.52 import
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
// Dreamer Nom wrote:
182
// Large thanks to John Weidman for all his initial research
183
// Thanks to Seph3 for his modem notes
184
185
186
#include "snes9x.h"
187
#include "memmap.h"
188
#include "display.h"
189
190
//#define BSX_DEBUG
191
192
#define BIOS_SIZE	0x100000
193
#define FLASH_SIZE	0x200000
194
#define PSRAM_SIZE	0x80000
195
196
#define Map			Memory.Map
197
#define BlockIsRAM	Memory.BlockIsRAM
198
#define BlockIsROM	Memory.BlockIsROM
199
#define RAM			Memory.RAM
200
#define SRAM		Memory.SRAM
201
#define PSRAM		Memory.BSRAM
202
#define BIOSROM		Memory.BIOSROM
203
#define MAP_BSX		Memory.MAP_BSX
204
#define MAP_CPU		Memory.MAP_CPU
205
#define MAP_PPU		Memory.MAP_PPU
206
#define MAP_NONE	Memory.MAP_NONE
207
208
#define BSXPPUBASE	0x2180
209
210
struct SBSX_RTC
211
{
212
	int	hours;
213
	int	minutes;
214
	int	seconds;
215
	int	ticks;
216
};
217
218
static struct SBSX_RTC	BSX_RTC;
219
220
// flash card vendor information
221
static const uint8	flashcard[20] =
222
{
223
	0x4D, 0x00, 0x50, 0x00,	// vendor id
224
	0x00, 0x00,				// ?
225
	0x2B, 0x00,				// 2MB Flash (1MB = 0x2A)
226
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00
228
};
229
230
static const uint8	init2192[32] =	// FIXME
231
{
232
	00, 00, 00, 00, 00,		// unknown
233
	01, 01, 00, 00, 00,
234
	00,						// seconds (?)
235
	00,						// minutes
236
	00,						// hours
237
	10, 10, 10, 10, 10,		// unknown
238
	10, 10, 10, 10, 10,		// dummy
239
	00, 00, 00, 00, 00, 00, 00, 00, 00
240
};
241
242
static bool8	FlashMode;
243
static uint32	FlashSize;
244
static uint8	*MapROM, *FlashROM;
245
246
static void BSX_Map_SNES (void);
247
static void BSX_Map_LoROM (void);
248
static void BSX_Map_HiROM (void);
249
static void BSX_Map_MMC (void);
250
static void BSX_Map_FlashIO (void);
251
static void BSX_Map_SRAM (void);
252
static void BSX_Map_PSRAM (void);
253
static void BSX_Map_BIOS (void);
254
static void BSX_Map_RAM (void);
255
static void BSX_Map_Dirty (void);
256
static void BSX_Map (void);
257
static void BSX_Set_Bypass_FlashIO (uint16, uint8);
258
static uint8 BSX_Get_Bypass_FlashIO (uint16);
259
static bool8 BSX_LoadBIOS (void);
260
static void map_psram_mirror_sub (uint32);
261
static int is_bsx (unsigned char *);
262
263
264
static void BSX_Map_SNES (void)
265
{
266
	// These maps will be partially overwritten
267
268
	int	c;
269
270
	// Banks 00->3F and 80->BF
271
	for (c = 0; c < 0x400; c += 16)
272
	{
273
		Map[c + 0] = Map[c + 0x800] = RAM;
274
		Map[c + 1] = Map[c + 0x801] = RAM;
275
		BlockIsRAM[c + 0] = BlockIsRAM[c + 0x800] = TRUE;
276
		BlockIsRAM[c + 1] = BlockIsRAM[c + 0x801] = TRUE;
277
278
		Map[c + 2] = Map[c + 0x802] = (uint8 *) MAP_PPU;
279
		Map[c + 3] = Map[c + 0x803] = (uint8 *) MAP_PPU;
280
		Map[c + 4] = Map[c + 0x804] = (uint8 *) MAP_CPU;
281
		Map[c + 5] = Map[c + 0x805] = (uint8 *) MAP_CPU;
282
		Map[c + 6] = Map[c + 0x806] = (uint8 *) MAP_NONE;
283
		Map[c + 7] = Map[c + 0x807] = (uint8 *) MAP_NONE;
284
	}
285
}
286
287
static void BSX_Map_LoROM (void)
288
{
289
	// These maps will be partially overwritten
290
291
	int	i, c;
292
293
	// Banks 00->3F and 80->BF
294
	for (c = 0; c < 0x400; c += 16)
295
	{
296
		for (i = c + 8; i < c + 16; i++)
297
		{
298
			Map[i] = Map[i + 0x800] = &MapROM[(c << 11) % FlashSize] - 0x8000;
299
			BlockIsRAM[i] = BlockIsRAM[i + 0x800] = BSX.write_enable;
300
			BlockIsROM[i] = BlockIsROM[i + 0x800] = !BSX.write_enable;
301
		}
302
	}
303
304
	// Banks 40->7F and C0->FF
305
	for (c = 0; c < 0x400; c += 16)
306
	{
307
		for (i = c; i < c + 8; i++)
308
			Map[i + 0x400] = Map[i + 0xC00] = &MapROM[(c << 11) % FlashSize];
309
310
		for (i = c + 8; i < c + 16; i++)
311
			Map[i + 0x400] = Map[i + 0xC00] = &MapROM[(c << 11) % FlashSize] - 0x8000;
312
313
		for (i = c; i < c + 16; i++)
314
		{
315
			BlockIsRAM[i + 0x400] = BlockIsRAM[i + 0xC00] = BSX.write_enable;
316
			BlockIsROM[i + 0x400] = BlockIsROM[i + 0xC00] = !BSX.write_enable;
317
		}
318
	}
319
}
320
321
static void BSX_Map_HiROM (void)
322
{
323
	// These maps will be partially overwritten
324
325
	int	i, c;
326
327
	// Banks 00->3F and 80->BF
328
	for (c = 0; c < 0x400; c += 16)
329
	{
330
		for (i = c + 8; i < c + 16; i++)
331
		{
332
			Map[i] = Map[i + 0x800] = &MapROM[(c << 12) % FlashSize];
333
			BlockIsRAM[i] = BlockIsRAM[i + 0x800] = BSX.write_enable;
334
			BlockIsROM[i] = BlockIsROM[i + 0x800] = !BSX.write_enable;
335
		}
336
	}
337
338
	// Banks 40->7F and C0->FF
339
	for (c = 0; c < 0x400; c += 16)
340
	{
341
		for (i = c; i < c + 16; i++)
342
		{
343
			Map[i + 0x400] = Map[i + 0xC00] = &MapROM[(c << 12) % FlashSize];
344
			BlockIsRAM[i + 0x400] = BlockIsRAM[i + 0xC00] = BSX.write_enable;
345
			BlockIsROM[i + 0x400] = BlockIsROM[i + 0xC00] = !BSX.write_enable;
346
		}
347
	}
348
}
349
350
static void BSX_Map_MMC (void)
351
{
352
	int	c;
353
354
	// Banks 01->0E:5000-5FFF
355
	for (c = 0x010; c < 0x0F0; c += 16)
356
	{
357
		Map[c + 5] = (uint8 *) MAP_BSX;
358
		BlockIsRAM[c + 5] = BlockIsROM[c + 5] = FALSE;
359
	}
360
}
361
362
static void BSX_Map_FlashIO (void)
363
{
364
	if (BSX.MMC[0x0C] || BSX.MMC[0x0D])
365
	{
366
		// Bank C0:0000, 2AAA, 5555, FF00-FF1F
288 by Brandon Wright
Fix some possible problems from cppcheck. Everything else looks fine.
367
		for (int c = 0; c < 16; c++)
1 by OV2
Initial 1.52 import
368
		{
369
			Map[c + 0xC00] = (uint8 *) MAP_BSX;
370
			BlockIsRAM[c + 0xC00] = TRUE;
371
			BlockIsROM[c + 0xC00] = FALSE;
372
		}
373
	}
374
}
375
376
static void BSX_Map_SRAM (void)
377
{
378
	int	c;
379
380
	// Banks 10->17:5000-5FFF
381
	for (c = 0x100; c < 0x180; c += 16)
382
	{
383
		Map[c + 5] = (uint8 *) SRAM + ((c & 0x70) << 8) - 0x5000;
384
		BlockIsRAM[c + 5] = TRUE;
385
		BlockIsROM[c + 5] = FALSE;
386
	}
387
}
388
389
static void map_psram_mirror_sub (uint32 bank)
390
{
391
	int	i, c;
392
393
	bank <<= 4;
394
395
	if (BSX.MMC[0x02])
396
	{
397
		for (c = 0; c < 0x100; c += 16)
398
		{
399
			for (i = c; i < c + 16; i++)
400
			{
401
				Map[i + bank] = &PSRAM[(c << 12) % PSRAM_SIZE];
402
				BlockIsRAM[i + bank] = TRUE;
403
				BlockIsROM[i + bank] = FALSE;
404
			}
405
		}
406
	}
407
	else
408
	{
409
		for (c = 0; c < 0x100; c += 16)
410
		{
411
			for (i = c; i < c + 8; i++)
412
				Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE];
413
414
			for (i = c + 8; i < c + 16; i++)
415
				Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE] - 0x8000;
416
417
			for (i = c; i < c + 16; i++)
418
			{
419
				BlockIsRAM[i + bank] = TRUE;
420
				BlockIsROM[i + bank] = FALSE;
421
			}
422
		}
423
	}
424
}
425
426
static void BSX_Map_PSRAM (void)
427
{
428
	int	c;
429
430
	// Banks 70->77:0000-FFFF
431
	// FIXME: could be toggled by $03
432
	for (c = 0; c < 0x80; c++)
433
	{
434
		Map[c + 0x700] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE];
435
		BlockIsRAM[c + 0x700] = TRUE;
436
		BlockIsROM[c + 0x700] = FALSE;
437
	}
438
439
	// Banks 20->3F:6000-7FFF mirrors 70->77:6000-7FFF
440
	for (c = 0x200; c < 0x400; c += 16)
441
	{
442
		Map[c + 6] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE];
443
		Map[c + 7] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE];
444
		BlockIsRAM[c + 6] = TRUE;
445
		BlockIsRAM[c + 7] = TRUE;
446
		BlockIsROM[c + 6] = FALSE;
447
		BlockIsROM[c + 7] = FALSE;
448
	}
449
450
	if (!BSX.MMC[0x05])
451
		// Banks 40->4F:0000-FFFF mirrors 70->77:0000-7FFF
452
		map_psram_mirror_sub(0x40);
453
454
	if (!BSX.MMC[0x06])
455
		// Banks 50->5F:0000-FFFF mirrors 70->77:0000-7FFF
456
		map_psram_mirror_sub(0x50);
457
458
	// FIXME
459
	if (!BSX.MMC[0x03])
460
		// Banks 60->6F:0000-FFFF mirrors 70->77:0000-7FFF (?)
461
		map_psram_mirror_sub(0x60);
462
}
463
464
static void BSX_Map_BIOS (void)
465
{
466
	int	i,c;
467
468
	// Banks 00->1F:8000-FFFF
469
	if (BSX.MMC[0x07])
470
	{
471
		for (c = 0; c < 0x200; c += 16)
472
		{
473
			for (i = c + 8; i < c + 16; i++)
474
			{
475
				Map[i] = &BIOSROM[(c << 11) % BIOS_SIZE] - 0x8000;
476
				BlockIsRAM[i] = FALSE;
477
				BlockIsROM[i] = TRUE;
478
			}
479
		}
480
	}
481
482
	// Banks 80->9F:8000-FFFF
483
	if (BSX.MMC[0x08])
484
	{
485
		for (c = 0; c < 0x200; c += 16)
486
		{
487
			for (i = c + 8; i < c + 16; i++)
488
			{
489
				Map[i + 0x800] = &BIOSROM[(c << 11) % BIOS_SIZE] - 0x8000;
490
				BlockIsRAM[i + 0x800] = FALSE;
491
				BlockIsROM[i + 0x800] = TRUE;
492
			}
493
		}
494
	}
495
}
496
497
static void BSX_Map_RAM (void)
498
{
499
	int	c;
500
501
	// Banks 7E->7F
502
	for (c = 0; c < 16; c++)
503
	{
504
		Map[c + 0x7E0] = RAM;
505
		Map[c + 0x7F0] = RAM + 0x10000;
506
		BlockIsRAM[c + 0x7E0] = TRUE;
507
		BlockIsRAM[c + 0x7F0] = TRUE;
508
		BlockIsROM[c + 0x7E0] = FALSE;
509
		BlockIsROM[c + 0x7F0] = FALSE;
510
	}
511
}
512
513
static void BSX_Map_Dirty (void)
514
{
515
	// for the quick bank change
516
517
	int i, c;
518
519
	// Banks 00->1F and 80->9F:8000-FFFF
520
	if (BSX.MMC[0x02])
521
	{
522
		for (c = 0; c < 0x200; c += 16)
523
		{
524
			for (i = c + 8; i < c + 16; i++)
525
			{
526
				Map[i] = Map[i + 0x800] = &MapROM[(c << 12) % FlashSize];
527
				BlockIsRAM[i] = BlockIsRAM[i + 0x800] = BSX.write_enable;
528
				BlockIsROM[i] = BlockIsROM[i + 0x800] = !BSX.write_enable;
529
			}
530
		}
531
	}
532
	else
533
	{
534
		for (c = 0; c < 0x200; c += 16)
535
		{
536
			for (i = c + 8; i < c + 16; i++)
537
			{
538
				Map[i] = Map[i + 0x800] = &MapROM[(c << 11) % FlashSize] - 0x8000;
539
				BlockIsRAM[i] = BlockIsRAM[i + 0x800] = BSX.write_enable;
540
				BlockIsROM[i] = BlockIsROM[i + 0x800] = !BSX.write_enable;
541
			}
542
		}
543
	}
544
}
545
546
static void BSX_Map (void)
547
{
548
#ifdef BSX_DEBUG
549
	printf("BS: Remapping\n");
550
	for (int i = 0; i < 32; i++)
551
		printf("BS: MMC %02X: %d\n", i, BSX.MMC[i]);
552
#endif
553
554
	memcpy(BSX.prevMMC, BSX.MMC, sizeof(BSX.MMC));
555
556
	// Do a quick bank change
557
	if (BSX.dirty2 && !BSX.dirty)
558
	{
559
		BSX_Map_Dirty();
560
		BSX_Map_BIOS();
561
562
		BSX.dirty2 = FALSE;
563
564
		Memory.map_WriteProtectROM();
565
		return;
566
	}
567
568
	if (BSX.MMC[0x01])
569
	{
570
		MapROM = PSRAM;
571
		FlashSize = PSRAM_SIZE;
572
	}
573
	else
574
	{
575
		MapROM = FlashROM;
576
		FlashSize = FLASH_SIZE;
577
	}
578
579
	BSX_Map_SNES();
580
581
	if (BSX.MMC[0x02])
582
		BSX_Map_HiROM();
583
	else
584
		BSX_Map_LoROM();
585
586
	BSX_Map_PSRAM();
587
	BSX_Map_SRAM();
588
	BSX_Map_RAM();
589
590
	BSX_Map_BIOS();
591
	BSX_Map_FlashIO();
592
	BSX_Map_MMC();
593
594
	// Monitor new register changes
595
	BSX.dirty  = FALSE;
596
	BSX.dirty2 = FALSE;
597
598
	Memory.map_WriteProtectROM();
599
}
600
601
static uint8 BSX_Get_Bypass_FlashIO (uint16 offset)
602
{
603
	if (BSX.MMC[0x02])
604
		return (MapROM[offset]);
605
	else
606
	{
607
		if (offset < 0x8000)
608
			return (MapROM[offset]);
609
		else
610
			return (MapROM[offset - 0x8000]);
611
	}
612
}
613
614
static void BSX_Set_Bypass_FlashIO (uint16 offset, uint8 byte)
615
{
616
	if (BSX.MMC[0x02])
617
		MapROM[offset] = byte;
618
	else
619
	{
620
		if (offset < 0x8000)
621
			MapROM[offset] = byte;
622
		else
623
			MapROM[offset - 0x8000] = byte;
624
	}
625
}
626
627
uint8 S9xGetBSX (uint32 address)
628
{
629
	uint8	bank = (address >> 16) & 0xFF;
630
	uint16	offset = address & 0xFFFF;
631
	uint8	t = 0;
632
633
	// MMC
634
	if ((bank >= 0x01 && bank <= 0x0E) && (offset == 0x5000))
635
		return (BSX.MMC[bank]);
636
637
	// Flash IO
638
	if (bank == 0xC0)
639
	{
640
		// default: read-through mode
641
		t = BSX_Get_Bypass_FlashIO(offset);
642
643
		// note: may be more registers, purposes unknown
644
		switch (offset)
645
		{
646
			case 0x0002:
647
				if (BSX.flash_enable)
648
					t = 0x80; // status register?
649
				break;
650
651
			case 0x5555:
652
				if (BSX.flash_enable)
653
					t = 0x80; // ???
654
				break;
655
656
			case 0xFF00:
657
			case 0xFF02:
658
			case 0xFF04:
659
			case 0xFF06:
660
			case 0xFF08:
661
			case 0xFF0A:
662
			case 0xFF0C:
663
			case 0xFF0E:
664
			case 0xFF10:
665
			case 0xFF12:
666
				// return flash vendor information
667
				if (BSX.read_enable)
668
					t = flashcard[offset - 0xFF00];
669
				break;
670
		}
671
	}
672
673
	return (t);
674
}
675
676
void S9xSetBSX (uint8 byte, uint32 address)
677
{
678
	uint8	bank = (address >> 16) & 0xFF;
679
	uint16	offset = address & 0xFFFF;
680
681
	// MMC
682
	if ((bank >= 0x01 && bank <= 0x0E) && (offset == 0x5000))
683
	{
684
		switch (bank)
685
		{
686
			case 0x01:
687
			case 0x02:
688
			case 0x03:
689
			case 0x04:
690
			case 0x05:
691
			case 0x06:
692
			case 0x09:
693
			case 0x0A:
694
			case 0x0B:
695
			case 0x0C:
696
			case 0x0D:
697
				if (BSX.MMC[bank] != byte)
698
				{
699
					BSX.MMC[bank] = byte;
700
					BSX.dirty = TRUE;
701
				}
702
				break;
703
704
			case 0x07:
705
			case 0x08:
706
				if (BSX.MMC[bank] != byte)
707
				{
708
					BSX.MMC[bank] = byte;
709
					BSX.dirty2 = TRUE;
710
				}
711
				break;
712
713
			case 0x0E:
714
				BSX.MMC[bank] = byte;
715
				if (byte && (BSX.dirty || BSX.dirty2))
716
					BSX_Map();
717
				break;
718
		}
719
	}
720
721
	// Flash IO
722
	if (bank == 0xC0)
723
	{
724
		BSX.old_write = BSX.new_write;
725
		BSX.new_write = address;
726
727
		// ???: double writes to the desired address will bypass
728
		// flash registers
729
		if (BSX.old_write == BSX.new_write && BSX.write_enable)
730
		{
731
			BSX_Set_Bypass_FlashIO(offset, byte);
732
			return;
733
		}
734
735
		// flash command handling
736
		// note: incomplete
737
		switch (offset)
738
		{
739
			case 0x0000:
740
				BSX.flash_command <<= 8;
741
				BSX.flash_command |= byte;
742
				if ((BSX.flash_command & 0xFFFF) == 0x38D0)
743
				{
744
					// retrieve information about the flash card
745
					BSX.flash_enable = TRUE;
746
					BSX.read_enable  = TRUE;
747
				}
748
				break;
749
750
			case 0x2AAA:
751
				BSX.flash_command <<= 8;
752
				BSX.flash_command |= byte;
753
				break;
754
755
			case 0x5555:
756
				BSX.flash_command <<= 8;
757
				BSX.flash_command |= byte;
758
759
				switch (BSX.flash_command & 0xFFFFFF)
760
				{
761
					case 0xAA55F0:
762
						// turn off flash i/o
763
						BSX.flash_enable = FALSE;
764
						BSX.write_enable = FALSE;
765
						BSX.read_enable  = FALSE;
766
						break;
767
768
					case 0xAA55A0:
769
						// enable writing to flash
770
						BSX.old_write = 0;
771
						BSX.new_write = 0;
772
						BSX.flash_enable = TRUE;
773
						BSX.write_enable = TRUE;
774
						BSX_Map();
775
						break;
776
777
					case 0xAA5570:
778
						// turn on write-protection
779
						BSX.write_enable = FALSE;
780
						BSX_Map();
781
						break;
782
783
					case 0xAA5580:
784
					case 0xAA5510:
785
						// ???
786
						break;
787
788
				}
789
790
				break;
791
		}
792
	}
793
}
794
795
uint8 S9xGetBSXPPU (uint16 address)
796
{
797
	uint8	t;
798
799
	// known read registers
800
	switch (address)
801
	{
802
		// Test register low? (r/w)
803
		case 0x2188:
804
			t = BSX.PPU[0x2188 - BSXPPUBASE];
805
			break;
806
807
		// Test register high? (r/w)
808
		case 0x2189:
809
			t = BSX.PPU[0x2189 - BSXPPUBASE];
810
			break;
811
812
		case 0x218A:
813
			t = BSX.PPU[0x218A - BSXPPUBASE];
814
			break;
815
816
		case 0x218C:
817
			t = BSX.PPU[0x218C - BSXPPUBASE];
818
			break;
819
820
		// Transmission number low? (r/w)
821
		case 0x218E:
822
			t = BSX.PPU[0x218E - BSXPPUBASE];
823
			break;
824
825
		// Transmission number high? (r/w)
826
		case 0x218F:
827
			t = BSX.PPU[0x218F - BSXPPUBASE];
828
			break;
829
830
		// Status register? (r)
831
		case 0x2190:
832
			t = BSX.PPU[0x2190 - BSXPPUBASE];
833
			break;
834
835
		// Data register? (r/w)
836
		case 0x2192:
288 by Brandon Wright
Fix some possible problems from cppcheck. Everything else looks fine.
837
			// t = BSX.PPU[0x2192 - BSXPPUBASE];
1 by OV2
Initial 1.52 import
838
839
			// test
840
			t = BSX.test2192[BSX.out_index++];
841
			if (BSX.out_index == 32)
842
				BSX.out_index = 0;
843
844
			BSX_RTC.ticks++;
845
			if (BSX_RTC.ticks >= 1000)
846
			{
847
				BSX_RTC.ticks = 0;
848
				BSX_RTC.seconds++;
849
			}
850
			if (BSX_RTC.seconds >= 60)
851
			{
852
				BSX_RTC.seconds = 0;
853
				BSX_RTC.minutes++;
854
			}
855
			if (BSX_RTC.minutes >= 60)
856
			{
857
				BSX_RTC.minutes = 0;
858
				BSX_RTC.hours++;
859
			}
860
			if (BSX_RTC.hours >= 24)
861
				BSX_RTC.hours = 0;
862
863
			BSX.test2192[10] = BSX_RTC.seconds;
864
			BSX.test2192[11] = BSX_RTC.minutes;
865
			BSX.test2192[12] = BSX_RTC.hours;
866
867
			break;
868
869
		// Transmission status? (r/w)
870
		case 0x2193:
871
			// Data ready when bits 2/3 clear?
872
			t = BSX.PPU[0x2193 - BSXPPUBASE] & ~0x0C;
873
			break;
874
875
		// Reset? (r/w)
876
		case 0x2194:
877
			t = BSX.PPU[0x2194 - BSXPPUBASE];
878
			break;
879
880
		// Unknown (r)
881
		case 0x2196:
882
			t = BSX.PPU[0x2196 - BSXPPUBASE];
883
			break;
884
885
		// Unknown (r/w)
886
		case 0x2197:
887
			t = BSX.PPU[0x2197 - BSXPPUBASE];
888
			break;
889
890
		// Modem protocol? (r/w)
891
		case 0x2199:
892
			t = BSX.PPU[0x2199 - BSXPPUBASE];
893
			break;
894
895
		default:
896
			t = OpenBus;
897
			break;
898
	}
899
900
	return (t);
901
}
902
903
void S9xSetBSXPPU (uint8 byte, uint16 address)
904
{
905
	// known write registers
906
	switch (address)
907
	{
908
		// Test register low? (r/w)
909
		case 0x2188:
910
			BSX.PPU[0x2188 - BSXPPUBASE] = byte;
911
			break;
912
913
		// Test register high? (r/w)
914
		case 0x2189:
915
			BSX.PPU[0x2189 - BSXPPUBASE] = byte;
916
			break;
917
918
		case 0x218A:
919
			BSX.PPU[0x218A - BSXPPUBASE] = byte;
920
			break;
921
922
		case 0x218B:
923
			BSX.PPU[0x218B - BSXPPUBASE] = byte;
924
			break;
925
926
		case 0x218C:
927
			BSX.PPU[0x218C - BSXPPUBASE] = byte;
928
			break;
929
930
		// Transmission number low? (r/w)
931
		case 0x218E:
932
			BSX.PPU[0x218E - BSXPPUBASE] = byte;
933
			break;
934
935
		// Transmission number high? (r/w)
936
		case 0x218F:
937
			BSX.PPU[0x218F - BSXPPUBASE] = byte;
938
939
			// ?
940
			BSX.PPU[0x218E - BSXPPUBASE] >>= 1;
941
			BSX.PPU[0x218E - BSXPPUBASE] = BSX.PPU[0x218F - BSXPPUBASE] - BSX.PPU[0x218E - BSXPPUBASE];
942
			BSX.PPU[0x218F - BSXPPUBASE] >>= 1;
943
944
			BSX.PPU[0x2190 - BSXPPUBASE] = 0x80; // ?
945
			break;
946
947
		// Strobe assert? (w)
948
		case 0x2191:
949
			BSX.PPU[0x2191 - BSXPPUBASE] = byte;
950
			BSX.out_index = 0;
951
			break;
952
953
		// Data register? (r/w)
954
		case 0x2192:
955
			BSX.PPU[0x2192 - BSXPPUBASE] = 0x01; // ?
956
			BSX.PPU[0x2190 - BSXPPUBASE] = 0x80; // ?
957
			break;
958
959
		// Transmission status? (r/w)
960
		case 0x2193:
961
			BSX.PPU[0x2193 - BSXPPUBASE] = byte;
962
			break;
963
964
		// Reset? (r/w)
965
		case 0x2194:
966
			BSX.PPU[0x2194 - BSXPPUBASE] = byte;
967
			break;
968
969
		// Unknown (r/w)
970
		case 0x2197:
971
			BSX.PPU[0x2197 - BSXPPUBASE] = byte;
972
			break;
973
974
		// Modem protocol? (r/w)
975
		case 0x2199:
976
			// Lots of modem strings written here when
977
			// connection is lost or no uplink established
978
			BSX.PPU[0x2199 - BSXPPUBASE] = byte;
979
			break;
980
	}
981
}
982
983
uint8 * S9xGetBasePointerBSX (uint32 address)
984
{
985
	return (MapROM);
986
}
987
988
static bool8 BSX_LoadBIOS (void)
989
{
990
	FILE	*fp;
991
	char	path[PATH_MAX + 1], name[PATH_MAX + 1];
992
	bool8	r = FALSE;
993
994
	strcpy(path, S9xGetDirectory(BIOS_DIR));
995
	strcat(path, SLASH_STR);
996
	strcpy(name, path);
997
	strcat(name, "BS-X.bin");
998
999
	fp = fopen(name, "rb");
1000
	if (!fp)
1001
	{
1002
		strcpy(name, path);
1003
		strcat(name, "BS-X.bios");
1004
		fp = fopen(name, "rb");
1005
	}
1006
1007
	if (fp)
1008
	{
1009
		size_t	size;
1010
1011
		size = fread((void *) BIOSROM, 1, BIOS_SIZE, fp);
1012
		fclose(fp);
1013
		if (size == BIOS_SIZE)
1014
			r = TRUE;
1015
	}
1016
1017
#ifdef BSX_DEBUG
1018
	if (r)
1019
		printf("BS: BIOS found.\n");
1020
	else
1021
		printf("BS: BIOS not found!\n");
1022
#endif
1023
1024
	return (r);
1025
}
1026
162.1.5 by OV2
Add bsx loading to libsnes
1027
static bool8 is_BSX_BIOS (const uint8 *data, uint32 size)
1028
{
1029
	if (size == BIOS_SIZE && strncmp((char *) (data + 0x7FC0), "Satellaview BS-X     ", 21) == 0)
1030
		return (TRUE);
1031
	else
1032
		return (FALSE);
1033
}
1034
1 by OV2
Initial 1.52 import
1035
void S9xInitBSX (void)
1036
{
1037
	Settings.BS = FALSE;
1038
162.1.5 by OV2
Add bsx loading to libsnes
1039
    if (is_BSX_BIOS(Memory.ROM,Memory.CalculatedSize))
1 by OV2
Initial 1.52 import
1040
	{
1041
		// BS-X itself
1042
1043
		Settings.BS = TRUE;
1044
		Settings.BSXItself = TRUE;
1045
1046
		Memory.LoROM = TRUE;
1047
		Memory.HiROM = FALSE;
1048
1049
		memmove(BIOSROM, Memory.ROM, BIOS_SIZE);
1050
1051
		FlashMode = FALSE;
1052
		FlashSize = FLASH_SIZE;
1053
1054
		BSX.bootup = TRUE;
1055
	}
1056
	else
1057
	{
1058
		Settings.BSXItself = FALSE;
1059
1060
		int	r1, r2;
1061
1062
		r1 = (is_bsx(Memory.ROM + 0x7FC0) == 1);
1063
		r2 = (is_bsx(Memory.ROM + 0xFFC0) == 1);
1064
		Settings.BS = (r1 | r2) ? TRUE : FALSE;
1065
1066
		if (Settings.BS)
1067
		{
1068
			// BS games
1069
1070
			Memory.LoROM = r1 ? TRUE : FALSE;
1071
			Memory.HiROM = r2 ? TRUE : FALSE;
1072
1073
			uint8	*header = r1 ? Memory.ROM + 0x7FC0 : Memory.ROM + 0xFFC0;
1074
1075
			FlashMode = (header[0x18] & 0xEF) == 0x20 ? FALSE : TRUE;
1076
			FlashSize = (header[0x19] & 0x20) ? PSRAM_SIZE : FLASH_SIZE;
1077
1078
#ifdef BSX_DEBUG
1079
			for (int i = 0; i <= 0x1F; i++)
1080
				printf("BS: ROM Header %02X: %02X\n", i, header[i]);
1081
			printf("BS: FlashMode: %d, FlashSize: %x\n", FlashMode, FlashSize);
1082
#endif
1083
1084
			BSX.bootup = Settings.BSXBootup;
1085
162.1.5 by OV2
Add bsx loading to libsnes
1086
			if (!BSX_LoadBIOS() && !is_BSX_BIOS(BIOSROM,BIOS_SIZE))
1 by OV2
Initial 1.52 import
1087
			{
1088
				BSX.bootup = FALSE;
1089
				memset(BIOSROM, 0, BIOS_SIZE);
1090
			}
1091
		}
1092
	}
1093
1094
	if (Settings.BS)
1095
	{
1096
		MapROM = NULL;
1097
		FlashROM = Memory.ROM;
1098
1099
		time_t		t;
1100
		struct tm	*tmr;
1101
1102
		time(&t);
1103
		tmr = localtime(&t);
1104
1105
		BSX_RTC.ticks = 0;
1106
		memcpy(BSX.test2192, init2192, sizeof(init2192));
1107
		BSX.test2192[10] = BSX_RTC.seconds = tmr->tm_sec;
1108
		BSX.test2192[11] = BSX_RTC.minutes = tmr->tm_min;
1109
		BSX.test2192[12] = BSX_RTC.hours   = tmr->tm_hour;
1110
#ifdef BSX_DEBUG
1111
		printf("BS: Current Time: %02d:%02d:%02d\n",  BSX_RTC.hours, BSX_RTC.minutes, BSX_RTC.seconds);
1112
#endif
1113
		SNESGameFixes.SRAMInitialValue = 0x00;
1114
	}
1115
}
1116
1117
void S9xResetBSX (void)
1118
{
1119
	if (Settings.BSXItself)
1120
		memset(Memory.ROM, 0, FLASH_SIZE);
1121
1122
	memset(BSX.PPU, 0, sizeof(BSX.PPU));
1123
	memset(BSX.MMC, 0, sizeof(BSX.MMC));
1124
	memset(BSX.prevMMC, 0, sizeof(BSX.prevMMC));
1125
1126
	BSX.dirty         = FALSE;
1127
	BSX.dirty2        = FALSE;
1128
	BSX.flash_enable  = FALSE;
1129
	BSX.write_enable  = FALSE;
1130
	BSX.read_enable   = FALSE;
1131
	BSX.flash_command = 0;
1132
	BSX.old_write     = 0;
1133
	BSX.new_write     = 0;
1134
1135
	BSX.out_index = 0;
1136
	memset(BSX.output, 0, sizeof(BSX.output));
1137
1138
	// starting from the bios
1139
	if (BSX.bootup)
1140
		BSX.MMC[0x07] = BSX.MMC[0x08] = 0x80;
1141
	else
1142
	{
1143
		BSX.MMC[0x02] = FlashMode ? 0x80: 0;
1144
1145
		// per bios: run from psram or flash card
1146
		if (FlashSize == PSRAM_SIZE)
1147
		{
1148
			memcpy(PSRAM, FlashROM, PSRAM_SIZE);
1149
1150
			BSX.MMC[0x01] = 0x80;
1151
			BSX.MMC[0x03] = 0x80;
1152
			BSX.MMC[0x04] = 0x80;
1153
			BSX.MMC[0x0C] = 0x80;
1154
			BSX.MMC[0x0D] = 0x80;
1155
		}
1156
		else
1157
		{
1158
			BSX.MMC[0x03] = 0x80;
1159
			BSX.MMC[0x05] = 0x80;
1160
			BSX.MMC[0x06] = 0x80;
1161
		}
1162
1163
		BSX.MMC[0x0E] = 0x80;
1164
	}
1165
1166
	BSX_Map();
1167
}
1168
1169
void S9xBSXPostLoadState (void)
1170
{
1171
	uint8	temp[16];
1172
	bool8	pd1, pd2;
1173
1174
	pd1 = BSX.dirty;
1175
	pd2 = BSX.dirty2;
1176
	memcpy(temp, BSX.MMC, sizeof(BSX.MMC));
1177
1178
	memcpy(BSX.MMC, BSX.prevMMC, sizeof(BSX.MMC));
1179
	BSX_Map();
1180
1181
	memcpy(BSX.MMC, temp, sizeof(BSX.MMC));
1182
	BSX.dirty  = pd1;
1183
	BSX.dirty2 = pd2;
1184
}
1185
1186
static bool valid_normal_bank (unsigned char bankbyte)
1187
{
1188
	switch (bankbyte)
1189
	{
1190
		case 32: case 33: case 48: case 49:
1191
			return (true);
1192
			break;
1193
	}
1194
1195
	return (false);
1196
}
1197
1198
static int is_bsx (unsigned char *p)
1199
{
1200
	if ((p[26] == 0x33 || p[26] == 0xFF) && (!p[21] || (p[21] & 131) == 128) && valid_normal_bank(p[24]))
1201
	{
1202
		unsigned char	m = p[22];
1203
1204
		if (!m && !p[23])
1205
			return (2);
1206
1207
		if ((m == 0xFF && p[23] == 0xFF) || (!(m & 0xF) && ((m >> 4) - 1 < 12)))
1208
			return (1);
1209
	}
1210
1211
	return (0);
1212
}