00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00190 #include "StdAfx.h"
00191 #include "System.h"
00192 #include "Flash.h"
00193 #include "DPR.h"
00194
00195 #include "lockstep.h"
00196
00197 #if defined(HAVE_SDL)
00198 #include "SDL.h"
00199 #endif
00200
00202 const char* path[] ={
00203 #if defined(_WIN32)
00204 ".\\es40.cfg",
00205 "c:\\es40.cfg",
00206 "c:\\windows\\es40.cfg",
00207 #elif defined(__VMS)
00208 "[]ES40.CFG",
00209 #else
00210 "./es40.cfg",
00211 "/etc/es40.cfg",
00212 "/usr/etc/es40.cfg",
00213 "/usr/local/etc/es40.cfg",
00214 #endif
00215 0
00216 };
00217
00218 #ifdef DEBUG_BACKTRACE
00219 #ifdef __GNUG__
00220 #include <execinfo.h>
00221 #include <signal.h>
00222 #define HAS_BACKTRACE
00223
00224 #define BTCOUNT 100
00225 void* btbuffer[BTCOUNT];
00226
00227 void segv_handler(int signum)
00228 {
00229 int nptrs = backtrace(btbuffer, BTCOUNT);
00230 char ** strings;
00231
00232 printf("%%SYS-F-SEGFAULT: The Alpha Simulator has Segfaulted.\n");
00233 printf("-SYS-F-SEGFAULT: Backtrace follows.\n");
00234
00235 printf("backtrace() returned %d addresses.\n", nptrs);
00236 strings = backtrace_symbols(btbuffer, nptrs);
00237 if(strings == NULL)
00238 {
00239 perror("backtrace_symbols");
00240 exit(1);
00241 }
00242
00243 for(int i = 0; i < nptrs; i++)
00244 {
00245 printf("%3d %s\n", nptrs - i, strings[i]);
00246 }
00247
00248 free(strings);
00249 if(signum == SIGSEGV)
00250 _exit(1);
00251 }
00252
00253 #else
00254 #warning "Your compiler isn't configured to support backtraces."
00255 #endif // __GNUG__
00256 #endif
00257
00269 int main (int argc, char*argv[])
00270 {
00271 printf("\n\n");
00272 printf(" **======================================================================**\n");
00273 printf(" || ES40 emulator ||\n");
00274 printf(" || Version " VERSION " ||\n");
00275 printf(" || ||\n");
00276 printf(" || Copyright (C) 2007-2008 by the ES40 Emulator Project ||\n");
00277 printf(" || Website: http://sourceforge.net/projects/es40 ||\n");
00278 printf(" || E-mail : camiel@camicom.com ||\n");
00279 printf(" || ||\n");
00280 printf(" || This program is free software; you can redistribute it and/or ||\n");
00281 printf(" || modify it under the terms of the GNU General Public License ||\n");
00282 printf(" || as published by the Free Software Foundation; either version 2 ||\n");
00283 printf(" || of the License, or (at your option) any later version. ||\n");
00284 printf(" **======================================================================**\n");
00285 printf("\n\n");
00286
00287 const char* filename = 0;
00288 FILE* f;
00289
00290 #ifdef HAS_BACKTRACE
00291 signal(SIGSEGV, &segv_handler);
00292 signal(SIGUSR1, &segv_handler);
00293 #endif
00294 try
00295 {
00296 #if defined(IDB) && (defined(LS_MASTER) || defined(LS_SLAVE))
00297 lockstep_init();
00298 #endif
00299 #if defined(IDB)
00300 if((argc == 2 || argc == 3) && argv[1][0] != '@')
00301 #else
00302 if(argc == 2)
00303 #endif
00304 {
00305 filename = argv[1];
00306 }
00307 else
00308 {
00309 for(int i = 0; path[i]; i++)
00310 {
00311 filename = path[i];
00312 f = fopen(path[i], "r");
00313 if(f != NULL)
00314 {
00315 fclose(f);
00316 filename = path[i];
00317 break;
00318 }
00319 }
00320 if(filename == NULL)
00321 FAILURE(FileNotFound, "configuration file");
00322 }
00323 char* ch1;
00324 size_t ll1;
00325 f = fopen(filename, "rb");
00326 fseek(f, 0, SEEK_END);
00327 ll1 = ftell(f);
00328 ch1 = (char*) calloc(ll1, 1);
00329 fseek(f, 0, SEEK_SET);
00330 ll1 = fread(ch1, 1, ll1, f);
00331 CConfigurator* c = new CConfigurator(0, 0, 0, ch1, ll1);
00332 fclose(f);
00333 free(ch1);
00334
00335 if(!theSystem)
00336 FAILURE(Configuration, "no system initialized");
00337
00338 #if defined(IDB)
00339 trc = new CTraceEngine(theSystem);
00340 #endif
00341 theSystem->LoadROM();
00342
00343 #if defined(PROFILE)
00344 {
00345 u64 p_i;
00346 for(p_i = PROFILE_FROM; p_i < PROFILE_TO; p_i += (4 * PROFILE_BUCKSIZE))
00347 PROFILE_BUCKET(p_i) = 0;
00348 profiled_insts = 0;
00349 }
00350 #endif
00351 #if defined(IDB)
00352 if(argc > 1 && argc < 4 && argv[argc - 1][0] == '@')
00353 trc->run_script(argv[argc - 1] + 1);
00354 else
00355 trc->run_script(NULL);
00356 #else
00357 theSystem->Run();
00358 #endif
00359 }
00360 catch(CGracefulException & e)
00361 {
00362 printf("Exiting gracefully: %s\n", e.displayText().c_str());
00363
00364 theSystem->stop_threads();
00365
00366
00367 theSROM->SaveStateF();
00368 theDPR->SaveStateF();
00369
00370 #if defined(PROFILE)
00371 {
00372 FILE* p_fp;
00373 u64 p_max = 0;
00374 u64 p_i;
00375 int p_j;
00376
00377 printf("Writing profile to profile.txt");
00378
00379 p_fp = fopen("profile.txt", "w");
00380 for(p_i = PROFILE_FROM; p_i < PROFILE_TO; p_i += (4 * PROFILE_BUCKSIZE))
00381 {
00382 if(PROFILE_BUCKET(p_i) > p_max)
00383 p_max = PROFILE_BUCKET(p_i);
00384 }
00385 fprintf
00386 (
00387 p_fp, "p_max = %10"LL "d; %10"LL "d profiled instructions.\n\n", p_max,
00388 profiled_insts
00389 );
00390 for(p_i = PROFILE_FROM; p_i < PROFILE_TO; p_i += (4 * PROFILE_BUCKSIZE))
00391 {
00392 if(PROFILE_BUCKET(p_i))
00393 {
00394 fprintf(p_fp, "%016"LL "x: %10"LL "d ", p_i, PROFILE_BUCKET(p_i));
00395 for(p_j = 0; p_j < (((float) PROFILE_BUCKET(p_i) / (float) p_max) * 100);
00396 p_j++)
00397 fprintf(p_fp, "*");
00398 fprintf(p_fp, "\n");
00399 }
00400 }
00401 fclose(p_fp);
00402 }
00403 #endif
00404 delete theSystem;
00405 }
00406 catch(Poco::Exception & e)
00407 {
00408 printf("Emulator Failure: %s\n", e.displayText().c_str());
00409 if(theSystem)
00410 {
00411 theSystem->stop_threads();
00412 delete theSystem;
00413 }
00414 }
00415 return 0;
00416 }