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.
50 static int S9xCompareSDD1IndexEntries (const void *p1, const void *p2)
52 return (*(uint32 *) p1 - *(uint32 *) p2);
55 static int S9xGetSDD1Dir(char * packdir)
57 char dir[_MAX_DIR + 1];
58 char drive[_MAX_DRIVE + 1];
59 char name[_MAX_FNAME + 1];
60 char ext[_MAX_EXT + 1];
62 PathSplit(S9xGetFilename(FILE_ROM), drive, dir, name, ext);
64 if (strncmp(Memory.ROMName, "Star Ocean", 10) == 0) {
65 PathMake(packdir, drive, dir, "socnsdd1", 0);
67 } else if(strncmp(Memory.ROMName, "STREET FIGHTER ALPHA2", 21) == 0) {
68 PathMake(packdir, drive, dir, "sfa2sdd1", 0);
71 S9xMessage(S9X_WARNING, S9X_ROM_INFO,
72 "WARNING: No default SDD1 pack for this ROM");
77 void S9xLoadSDD1Data ()
79 char packdir[_MAX_PATH + 1];
81 // Unload any previous pack
82 Settings.SDD1Pack = FALSE;
83 Memory.FreeSDD1Data();
85 if (!S9xGetSDD1Dir(packdir)) {
86 printf("SDD1: Didn't found pack for this ROM\n");
90 printf("SDD1: Searching for pack in %s\n", packdir);
91 Settings.SDD1Pack=TRUE;
93 char index[_MAX_PATH + 1];
94 char data[_MAX_PATH + 1];
95 char patch[_MAX_PATH + 1];
96 DIR *dir = opendir(packdir);
105 while ((d = readdir (dir))) {
106 if (strcasecmp (d->d_name, "SDD1GFX.IDX") == 0) {
107 strcpy(index, packdir);
109 strcat(index, d->d_name);
110 } else if (strcasecmp (d->d_name, "SDD1GFX.DAT") == 0) {
111 strcpy(data, packdir);
113 strcat(data, d->d_name);
114 } else if (strcasecmp (d->d_name, "SDD1GFX.PAT") == 0) {
115 strcpy(patch, packdir);
117 strcat(patch, d->d_name);
123 if (strlen (index) && strlen (data)) {
124 FILE *fs = fopen (index, "rb");
128 // Index is stored as a sequence of entries, each entry being
129 // 12 bytes consisting of:
130 // 4 byte key: (24bit address & 0xfffff * 16) | translated block
134 fseek (fs, 0, SEEK_END);
137 Memory.SDD1Index = (uint8 *) malloc (len);
138 if (fread (Memory.SDD1Index, 1, len, fs) < len) {
139 fprintf(stderr, "Failed to fully read SDD1 index file %s\n",
143 Memory.SDD1Entries = len / 12;
145 fprintf(stderr, "Failed to read SDD1 index file %s\n", index);
148 printf("SDD1: index: %s\n", PathBasename(index));
150 if (!(fs = fopen (data, "rb"))) {
151 fprintf(stderr, "Failed to read SDD1 data file %s\n", data);
152 free ((char *) Memory.SDD1Index);
153 Memory.SDD1Index = NULL;
154 Memory.SDD1Entries = 0;
157 fseek (fs, 0, SEEK_END);
160 Memory.SDD1Data = (uint8 *) malloc (len);
161 if (fread (Memory.SDD1Data, 1, len, fs) < len) {
162 fprintf(stderr, "Failed to fully read SDD1 data file %s\n",
167 printf("SDD1: data pack: %s\n", PathBasename(data));
169 if (strlen (patch) > 0 && (fs = fopen (patch, "rb"))) {
174 // Swap the byte order of the 32-bit value triplets on
175 // MSBFirst machines.
176 uint8 *ptr = Memory.SDD1Index;
177 for (int i = 0; i < Memory.SDD1Entries; i++, ptr += 12) {
178 SWAP_DWORD ((*(uint32 *) (ptr + 0)));
179 SWAP_DWORD ((*(uint32 *) (ptr + 4)));
180 SWAP_DWORD ((*(uint32 *) (ptr + 8)));
184 qsort(Memory.SDD1Index, Memory.SDD1Entries, 12,
185 S9xCompareSDD1IndexEntries);
186 printf("SDD1: Pack loaded succesfully\n");
188 fprintf(stderr, "SDD1: SDD1 data pack not found in '%s'\n",
190 fprintf(stderr, "SDD1: Check if sdd1gfx files exist\n");
191 printf("SDD1: Failed to load pack\n");
195 void S9xSetSDD1MemoryMap (uint32 bank, uint32 value)
197 bank = 0xc00 + bank * 0x100;
198 value = value * 1024 * 1024;
202 for (c = 0; c < 0x100; c += 16)
204 uint8 *block = &Memory.ROM [value + (c << 12)];
207 for (i = c; i < c + 16; i++)
208 Memory.Map [i + bank] = block;
214 memset (&Memory.FillRAM [0x4800], 0, 4);
215 for (int i = 0; i < 4; i++)
217 Memory.FillRAM [0x4804 + i] = i;
218 S9xSetSDD1MemoryMap (i, i);
222 void S9xSDD1PostLoadState ()
224 for (int i = 0; i < 4; i++)
225 S9xSetSDD1MemoryMap (i, Memory.FillRAM [0x4804 + i]);
229 static int S9xCompareSDD1LoggedDataEntries (const void *p1, const void *p2)
231 static int _cdecl S9xCompareSDD1LoggedDataEntries (const void *p1, const void *p2)
234 uint8 *b1 = (uint8 *) p1;
235 uint8 *b2 = (uint8 *) p2;
236 uint32 a1 = (*b1 << 16) + (*(b1 + 1) << 8) + *(b1 + 2);
237 uint32 a2 = (*b2 << 16) + (*(b2 + 1) << 8) + *(b2 + 2);
242 void S9xSDD1SaveLoggedData ()
244 if (Memory.SDD1LoggedDataCount != Memory.SDD1LoggedDataCountPrev)
246 qsort (Memory.SDD1LoggedData, Memory.SDD1LoggedDataCount, 8,
247 S9xCompareSDD1LoggedDataEntries);
249 const char * sdd1_dat_file = S9xGetFilename(FILE_SDD1_DAT);
250 FILE *fs = fopen(sdd1_dat_file, "wb");
254 size_t c = fwrite(Memory.SDD1LoggedData, 8,
255 Memory.SDD1LoggedDataCount, fs);
256 if (c < Memory.SDD1LoggedDataCount) {
257 fprintf(stderr, "Failed to write sdd1 log data\n");
261 Memory.SDD1LoggedDataCountPrev = Memory.SDD1LoggedDataCount;
265 void S9xSDD1LoadLoggedData ()
267 FILE *fs = fopen (S9xGetFilename(FILE_SDD1_DAT), "rb");
269 Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = 0;
273 size_t c = fread (Memory.SDD1LoggedData, 8,
274 MEMMAP_MAX_SDD1_LOGGED_ENTRIES, fs);
277 Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = c;