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.
51 static int S9xCompareSDD1IndexEntries (const void *p1, const void *p2)
53 return (*(uint32 *) p1 - *(uint32 *) p2);
56 static int S9xGetSDD1Dir(char * packdir)
58 char dir[_MAX_DIR + 1];
59 char drive[_MAX_DRIVE + 1];
60 char name[_MAX_FNAME + 1];
61 char ext[_MAX_EXT + 1];
63 PathSplit(S9xGetFilename(FILE_ROM), drive, dir, name, ext);
65 if (strncmp(Memory.ROMName, "Star Ocean", 10) == 0) {
66 PathMake(packdir, drive, dir, "socnsdd1", 0);
68 } else if(strncmp(Memory.ROMName, "STREET FIGHTER ALPHA2", 21) == 0) {
69 PathMake(packdir, drive, dir, "sfa2sdd1", 0);
72 S9xMessage(S9X_WARNING, S9X_ROM_INFO,
73 "WARNING: No default SDD1 pack for this ROM");
78 void S9xLoadSDD1Data ()
80 char packdir[_MAX_PATH + 1];
82 // Unload any previous pack
83 Settings.SDD1Pack = FALSE;
84 Memory.FreeSDD1Data();
86 if (!S9xGetSDD1Dir(packdir)) {
87 printf("SDD1: Didn't found pack for this ROM\n");
91 printf("SDD1: Searching for pack in %s\n", packdir);
92 Settings.SDD1Pack=TRUE;
94 char index[_MAX_PATH + 1];
95 char data[_MAX_PATH + 1];
96 char patch[_MAX_PATH + 1];
97 DIR *dir = opendir(packdir);
106 while ((d = readdir (dir))) {
107 if (strcasecmp (d->d_name, "SDD1GFX.IDX") == 0) {
108 strcpy(index, packdir);
110 strcat(index, d->d_name);
111 } else if (strcasecmp (d->d_name, "SDD1GFX.DAT") == 0) {
112 strcpy(data, packdir);
114 strcat(data, d->d_name);
115 } else if (strcasecmp (d->d_name, "SDD1GFX.PAT") == 0) {
116 strcpy(patch, packdir);
118 strcat(patch, d->d_name);
124 if (strlen (index) && strlen (data)) {
125 FILE *fs = fopen (index, "rb");
129 // Index is stored as a sequence of entries, each entry being
130 // 12 bytes consisting of:
131 // 4 byte key: (24bit address & 0xfffff * 16) | translated block
135 fseek (fs, 0, SEEK_END);
138 Memory.SDD1Index = (uint8 *) malloc (len);
139 fread (Memory.SDD1Index, 1, len, fs);
141 Memory.SDD1Entries = len / 12;
143 fprintf(stderr, "Failed to read SDD1 index file %s\n", index);
146 printf("SDD1: index: %s\n", PathBasename(index));
148 if (!(fs = fopen (data, "rb"))) {
149 fprintf(stderr, "Failed to read SDD1 data file %s\n", data);
150 free ((char *) Memory.SDD1Index);
151 Memory.SDD1Index = NULL;
152 Memory.SDD1Entries = 0;
155 fseek (fs, 0, SEEK_END);
158 Memory.SDD1Data = (uint8 *) malloc (len);
159 fread (Memory.SDD1Data, 1, len, fs);
162 printf("SDD1: data pack: %s\n", PathBasename(data));
164 if (strlen (patch) > 0 && (fs = fopen (patch, "rb"))) {
169 // Swap the byte order of the 32-bit value triplets on
170 // MSBFirst machines.
171 uint8 *ptr = Memory.SDD1Index;
172 for (int i = 0; i < Memory.SDD1Entries; i++, ptr += 12) {
173 SWAP_DWORD ((*(uint32 *) (ptr + 0)));
174 SWAP_DWORD ((*(uint32 *) (ptr + 4)));
175 SWAP_DWORD ((*(uint32 *) (ptr + 8)));
179 qsort(Memory.SDD1Index, Memory.SDD1Entries, 12,
180 S9xCompareSDD1IndexEntries);
181 printf("SDD1: Pack loaded succesfully\n");
183 fprintf(stderr, "SDD1: SDD1 data pack not found in '%s'\n",
185 fprintf(stderr, "SDD1: Check if sdd1gfx files exist\n");
186 printf("SDD1: Failed to load pack\n");
190 void S9xSetSDD1MemoryMap (uint32 bank, uint32 value)
192 bank = 0xc00 + bank * 0x100;
193 value = value * 1024 * 1024;
197 for (c = 0; c < 0x100; c += 16)
199 uint8 *block = &Memory.ROM [value + (c << 12)];
202 for (i = c; i < c + 16; i++)
203 Memory.Map [i + bank] = block;
209 memset (&Memory.FillRAM [0x4800], 0, 4);
210 for (int i = 0; i < 4; i++)
212 Memory.FillRAM [0x4804 + i] = i;
213 S9xSetSDD1MemoryMap (i, i);
217 void S9xSDD1PostLoadState ()
219 for (int i = 0; i < 4; i++)
220 S9xSetSDD1MemoryMap (i, Memory.FillRAM [0x4804 + i]);
224 static int S9xCompareSDD1LoggedDataEntries (const void *p1, const void *p2)
226 static int _cdecl S9xCompareSDD1LoggedDataEntries (const void *p1, const void *p2)
229 uint8 *b1 = (uint8 *) p1;
230 uint8 *b2 = (uint8 *) p2;
231 uint32 a1 = (*b1 << 16) + (*(b1 + 1) << 8) + *(b1 + 2);
232 uint32 a2 = (*b2 << 16) + (*(b2 + 1) << 8) + *(b2 + 2);
237 void S9xSDD1SaveLoggedData ()
239 if (Memory.SDD1LoggedDataCount != Memory.SDD1LoggedDataCountPrev)
241 qsort (Memory.SDD1LoggedData, Memory.SDD1LoggedDataCount, 8,
242 S9xCompareSDD1LoggedDataEntries);
244 const char * sdd1_dat_file = S9xGetFilename(FILE_SDD1_DAT);
245 FILE *fs = fopen (sdd1_dat_file, "wb");
249 fwrite (Memory.SDD1LoggedData, 8,
250 Memory.SDD1LoggedDataCount, fs);
253 chown (sdd1_dat_file, getuid (), getgid ());
256 Memory.SDD1LoggedDataCountPrev = Memory.SDD1LoggedDataCount;
260 void S9xSDD1LoadLoggedData ()
262 FILE *fs = fopen (S9xGetFilename(FILE_SDD1_DAT), "rb");
264 Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = 0;
268 int c = fread (Memory.SDD1LoggedData, 8,
269 MEMMAP_MAX_SDD1_LOGGED_ENTRIES, fs);
272 Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = c;