/[pcsx2_0.9.7]/branch/debug/0.X/0.9.X/0.9.7/ramdump-lateset/pcsx2/ps2/BiosTools.cpp
ViewVC logotype

Contents of /branch/debug/0.X/0.9.X/0.9.7/ramdump-lateset/pcsx2/ps2/BiosTools.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 330 - (show annotations) (download)
Tue Dec 28 04:24:23 2010 UTC (9 years, 9 months ago) by william
File size: 9142 byte(s)
merged upstream r4154-r4160
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #include "PrecompiledHeader.h"
17 #include "Common.h"
18 #include "BiosTools.h"
19
20 #include "Utilities/pxStreams.h"
21 #include "wx/ffile.h"
22
23
24 // FIXME: Temporary hack until we remove dependence on Pcsx2App.
25 #include "AppConfig.h"
26 #include "wx/mstream.h"
27 #include "wx/wfstream.h"
28
29 #define DIRENTRY_SIZE 16
30
31 // --------------------------------------------------------------------------------------
32 // romdir structure (packing required!)
33 // --------------------------------------------------------------------------------------
34 //
35 #if defined(_MSC_VER)
36 # pragma pack(1)
37 #endif
38
39 struct romdir
40 {
41 char fileName[10];
42 u16 extInfoSize;
43 u32 fileSize;
44 } __packed; // +16
45
46 #ifdef _MSC_VER
47 # pragma pack()
48 #endif
49
50 C_ASSERT( sizeof(romdir) == DIRENTRY_SIZE );
51
52 u32 BiosVersion;
53 u32 BiosChecksum;
54 wxString BiosDescription;
55
56
57 // --------------------------------------------------------------------------------------
58 // Exception::BiosLoadFailed (implementations)
59 // --------------------------------------------------------------------------------------
60 Exception::BiosLoadFailed::BiosLoadFailed( const wxString& filename )
61 {
62 StreamName = filename;
63 }
64
65 // This method throws a BadStream exception if the bios information chould not be obtained.
66 // (indicating that the file is invalid, incomplete, corrupted, or plain naughty).
67 static void LoadBiosVersion( pxInputStream& fp, u32& version, wxString& description, wxString& zoneStr )
68 {
69 uint i;
70 romdir rd;
71
72 for (i=0; i<512*1024; i++)
73 {
74 fp.Read( rd );
75 if (strncmp( rd.fileName, "RESET", 5 ) == 0)
76 break; /* found romdir */
77 }
78
79 if (i == 512*1024)
80 {
81 throw Exception::BadStream( fp.GetStreamName() )
82 .SetDiagMsg(L"BIOS version check failed: 'RESET' tag could not be found.")
83 .SetUserMsg(_("The selected BIOS file is not a valid PS2 BIOS. Please re-configure."));
84 }
85
86 uint fileOffset = 0;
87
88 while(strlen(rd.fileName) > 0)
89 {
90 if (strcmp(rd.fileName, "ROMVER") == 0)
91 {
92 char romver[14+1]; // ascii version loaded from disk.
93
94 wxFileOffset filetablepos = fp.Tell();
95 fp.Seek( fileOffset );
96 fp.Read( &romver, 14 );
97 fp.Seek( filetablepos ); //go back
98
99 romver[14] = 0;
100
101 const char zonefail[2] = { romver[4], '\0' }; // the default "zone" (unknown code)
102 const char* zone = zonefail;
103
104 switch(romver[4])
105 {
106 case 'T': zone = "T10K"; break;
107 case 'X': zone = "Test"; break;
108 case 'J': zone = "Japan"; break;
109 case 'A': zone = "USA"; break;
110 case 'E': zone = "Europe"; break;
111 case 'H': zone = "HK"; break;
112 case 'P': zone = "Free"; break;
113 case 'C': zone = "China"; break;
114 }
115
116 char vermaj[3] = { romver[0], romver[1], 0 };
117 char vermin[3] = { romver[2], romver[3], 0 };
118
119 FastFormatUnicode result;
120 result.Write( "%-7s v%s.%s(%c%c/%c%c/%c%c%c%c) %s",
121 zone,
122 vermaj, vermin,
123 romver[12], romver[13], // day
124 romver[10], romver[11], // month
125 romver[6], romver[7], romver[8], romver[9], // year!
126 (romver[5]=='C') ? "Console" : (romver[5]=='D') ? "Devel" : ""
127 );
128
129 version = strtol(vermaj, (char**)NULL, 0) << 8;
130 version|= strtol(vermin, (char**)NULL, 0);
131
132 Console.WriteLn(L"Bios Found: %s", result.c_str());
133
134 description = result.c_str();
135 zoneStr = fromUTF8(zone);
136 }
137
138 if ((rd.fileSize % 0x10) == 0)
139 fileOffset += rd.fileSize;
140 else
141 fileOffset += (rd.fileSize + 0x10) & 0xfffffff0;
142
143 fp.Read( rd );
144 }
145
146 fileOffset -= ((rd.fileSize + 0x10) & 0xfffffff0) - rd.fileSize;
147
148 if (description.IsEmpty())
149 throw Exception::BadStream( fp.GetStreamName() )
150 .SetDiagMsg(L"BIOS version check failed: 'ROMDIR' tag could not be found.")
151 .SetUserMsg(_("The selected BIOS file is not a valid PS2 BIOS. Please re-configure."));
152
153 wxFileOffset fileSize = fp.Length();
154 if (fileSize < (int)fileOffset)
155 {
156 description += pxsFmt( L" %d%%", ((fileSize*100) / (int)fileOffset) );
157 // we force users to have correct bioses,
158 // not that lame scph10000 of 513KB ;-)
159 }
160 }
161
162 static void LoadBiosVersion( pxInputStream& fp, u32& version, wxString& description )
163 {
164 wxString zoneStr;
165 LoadBiosVersion( fp,version, description, zoneStr );
166 }
167
168 template< size_t _size >
169 void ChecksumIt( u32& result, const u8 (&srcdata)[_size] )
170 {
171 pxAssume( (_size & 3) == 0 );
172 for( size_t i=0; i<_size/4; ++i )
173 result ^= ((u32*)srcdata)[i];
174 }
175
176 // Attempts to load a BIOS rom sub-component, by trying multiple combinations of base
177 // filename and extension. The bios specified in the user's configuration is used as
178 // the base.
179 //
180 // Parameters:
181 // ext - extension of the sub-component to load. Valid options are rom1, rom2, AND erom.
182 //
183 template< size_t _size >
184 static void LoadExtraRom( const wxChar* ext, u8 (&dest)[_size] )
185 {
186 wxString Bios1;
187 s64 filesize;
188
189 // Try first a basic extension concatenation (normally results in something like name.bin.rom1)
190 const wxString Bios( g_Conf->FullpathToBios() );
191 Bios1.Printf( L"%s.%s", Bios.c_str(), ext);
192
193 try
194 {
195 if( (filesize=Path::GetFileSize( Bios1 ) ) <= 0 )
196 {
197 // Try the name properly extensioned next (name.rom1)
198 Bios1 = Path::ReplaceExtension( Bios, ext );
199 if( (filesize=Path::GetFileSize( Bios1 ) ) <= 0 )
200 {
201 Console.WriteLn( Color_Gray, L"BIOS %s module not found, skipping...", ext );
202 return;
203 }
204 }
205
206 wxFile fp( Bios1 );
207 fp.Read( dest, std::min<s64>( _size, filesize ) );
208
209 // Checksum for ROM1, ROM2, EROM? Rama says no, Gigaherz says yes. I'm not sure either way. --air
210 //ChecksumIt( BiosChecksum, dest );
211 }
212 catch (Exception::BadStream& ex)
213 {
214 // If any of the secondary roms fail,its a non-critical error.
215 // Log it, but don't make a big stink. 99% of games and stuff will
216 // still work fine.
217
218 Console.Warning(L"BIOS Warning: %s could not be read (permission denied?)", ext);
219 Console.Indent().WriteLn(L"Details: %s", ex.FormatDiagnosticMessage().c_str());
220 Console.Indent().WriteLn(L"File size: %llu", filesize);
221 }
222 }
223
224 // Loads the configured bios rom file into PS2 memory. PS2 memory must be allocated prior to
225 // this method being called.
226 //
227 // Remarks:
228 // This function does not fail if rom1, rom2, or erom files are missing, since none are
229 // explicitly required for most emulation tasks.
230 //
231 // Exceptions:
232 // BadStream - Thrown if the primary bios file (usually .bin) is not found, corrupted, etc.
233 //
234 void LoadBIOS()
235 {
236 pxAssertDev( eeMem->ROM != NULL, "PS2 system memory has not been initialized yet." );
237
238 try
239 {
240 wxString Bios( g_Conf->FullpathToBios() );
241 if( !g_Conf->BaseFilenames.Bios.IsOk() || g_Conf->BaseFilenames.Bios.IsDir() )
242 throw Exception::FileNotFound( Bios )
243 .SetDiagMsg(L"BIOS has not been configured, or the configuration has been corrupted.")
244 .SetUserMsg(_("The PS2 BIOS could not be loaded. The BIOS has not been configured, or the configuration has been corrupted. Please re-configure."));
245
246 s64 filesize = Path::GetFileSize( Bios );
247 if( filesize <= 0 )
248 {
249 throw Exception::FileNotFound( Bios )
250 .SetDiagMsg(L"Configured BIOS file does not exist, or has a file size of zero.")
251 .SetUserMsg(_("The configured BIOS file does not exist. Please re-configure."));
252 }
253
254 BiosChecksum = 0;
255
256 wxString biosZone;
257 wxFFile fp( Bios );
258 fp.Read( eeMem->ROM, std::min<s64>( Ps2MemSize::Rom, filesize ) );
259
260 ChecksumIt( BiosChecksum, eeMem->ROM );
261
262 pxInputStream memfp( Bios, new wxMemoryInputStream( eeMem->ROM, sizeof(eeMem->ROM) ) );
263 LoadBiosVersion( memfp, BiosVersion, BiosDescription, biosZone );
264
265 Console.SetTitle( pxsFmt( L"Running BIOS (%s v%u.%u)",
266 biosZone.c_str(), BiosVersion >> 8, BiosVersion & 0xff
267 ));
268
269 //injectIRX("host.irx"); //not fully tested; still buggy
270
271 LoadExtraRom( L"rom1", eeMem->ROM1 );
272 LoadExtraRom( L"rom2", eeMem->ROM2 );
273 LoadExtraRom( L"erom", eeMem->EROM );
274 }
275 catch (Exception::BadStream& ex)
276 {
277 // Rethrow as a Bios Load Failure, so that the user interface handling the exceptions
278 // can respond to it appropriately.
279 throw Exception::BiosLoadFailed( ex.StreamName )
280 .SetDiagMsg( ex.DiagMsg() )
281 .SetUserMsg( ex.UserMsg() );
282 }
283 }
284
285 bool IsBIOS(const wxString& filename, wxString& description)
286 {
287 wxFileName Bios( g_Conf->Folders.Bios + filename );
288 pxInputStream inway( filename, new wxFFileInputStream( filename ) );
289
290 if (!inway.IsOk()) return false;
291 if (inway.Length() < 512*1024) return false;
292
293 try {
294 u32 version;
295 LoadBiosVersion( inway, version, description );
296 return true;
297 } catch( Exception::BadStream& ) { }
298
299 return false; // fail quietly
300 }

  ViewVC Help
Powered by ViewVC 1.1.22