| 46 |
#define DEBUG 0 |
#define DEBUG 0 |
| 47 |
#include "debug.h" |
#include "debug.h" |
| 48 |
|
|
| 49 |
|
// Emulation time statistics |
| 50 |
|
#define EMUL_TIME_STATS 1 |
| 51 |
|
|
| 52 |
|
#if EMUL_TIME_STATS |
| 53 |
|
static clock_t emul_start_time; |
| 54 |
|
static uint32 interrupt_count = 0; |
| 55 |
|
static clock_t interrupt_time = 0; |
| 56 |
|
static uint32 exec68k_count = 0; |
| 57 |
|
static clock_t exec68k_time = 0; |
| 58 |
|
static uint32 native_exec_count = 0; |
| 59 |
|
static clock_t native_exec_time = 0; |
| 60 |
|
static uint32 macos_exec_count = 0; |
| 61 |
|
static clock_t macos_exec_time = 0; |
| 62 |
|
#endif |
| 63 |
|
|
| 64 |
static void enter_mon(void) |
static void enter_mon(void) |
| 65 |
{ |
{ |
| 66 |
// Start up mon in real-mode |
// Start up mon in real-mode |
| 239 |
// Handle MacOS interrupt |
// Handle MacOS interrupt |
| 240 |
void sheepshaver_cpu::interrupt(uint32 entry) |
void sheepshaver_cpu::interrupt(uint32 entry) |
| 241 |
{ |
{ |
| 242 |
|
#if EMUL_TIME_STATS |
| 243 |
|
interrupt_count++; |
| 244 |
|
const clock_t interrupt_start = clock(); |
| 245 |
|
#endif |
| 246 |
|
|
| 247 |
#if !MULTICORE_CPU |
#if !MULTICORE_CPU |
| 248 |
// Save program counters and branch registers |
// Save program counters and branch registers |
| 249 |
uint32 saved_pc = pc(); |
uint32 saved_pc = pc(); |
| 297 |
ctr()= saved_ctr; |
ctr()= saved_ctr; |
| 298 |
gpr(1) = saved_sp; |
gpr(1) = saved_sp; |
| 299 |
#endif |
#endif |
| 300 |
|
|
| 301 |
|
#if EMUL_TIME_STATS |
| 302 |
|
interrupt_time += (clock() - interrupt_start); |
| 303 |
|
#endif |
| 304 |
} |
} |
| 305 |
|
|
| 306 |
// Execute 68k routine |
// Execute 68k routine |
| 307 |
void sheepshaver_cpu::execute_68k(uint32 entry, M68kRegisters *r) |
void sheepshaver_cpu::execute_68k(uint32 entry, M68kRegisters *r) |
| 308 |
{ |
{ |
| 309 |
|
#if EMUL_TIME_STATS |
| 310 |
|
exec68k_count++; |
| 311 |
|
const clock_t exec68k_start = clock(); |
| 312 |
|
#endif |
| 313 |
|
|
| 314 |
#if SAFE_EXEC_68K |
#if SAFE_EXEC_68K |
| 315 |
if (ReadMacInt32(XLM_RUN_MODE) != MODE_EMUL_OP) |
if (ReadMacInt32(XLM_RUN_MODE) != MODE_EMUL_OP) |
| 316 |
printf("FATAL: Execute68k() not called from EMUL_OP mode\n"); |
printf("FATAL: Execute68k() not called from EMUL_OP mode\n"); |
| 393 |
lr() = saved_lr; |
lr() = saved_lr; |
| 394 |
ctr()= saved_ctr; |
ctr()= saved_ctr; |
| 395 |
set_cr(saved_cr); |
set_cr(saved_cr); |
| 396 |
|
|
| 397 |
|
#if EMUL_TIME_STATS |
| 398 |
|
exec68k_time += (clock() - exec68k_start); |
| 399 |
|
#endif |
| 400 |
} |
} |
| 401 |
|
|
| 402 |
// Call MacOS PPC code |
// Call MacOS PPC code |
| 403 |
uint32 sheepshaver_cpu::execute_macos_code(uint32 tvect, int nargs, uint32 const *args) |
uint32 sheepshaver_cpu::execute_macos_code(uint32 tvect, int nargs, uint32 const *args) |
| 404 |
{ |
{ |
| 405 |
|
#if EMUL_TIME_STATS |
| 406 |
|
macos_exec_count++; |
| 407 |
|
const clock_t macos_exec_start = clock(); |
| 408 |
|
#endif |
| 409 |
|
|
| 410 |
// Save program counters and branch registers |
// Save program counters and branch registers |
| 411 |
uint32 saved_pc = pc(); |
uint32 saved_pc = pc(); |
| 412 |
uint32 saved_lr = lr(); |
uint32 saved_lr = lr(); |
| 445 |
lr() = saved_lr; |
lr() = saved_lr; |
| 446 |
ctr()= saved_ctr; |
ctr()= saved_ctr; |
| 447 |
|
|
| 448 |
|
#if EMUL_TIME_STATS |
| 449 |
|
macos_exec_time += (clock() - macos_exec_start); |
| 450 |
|
#endif |
| 451 |
|
|
| 452 |
return retval; |
return retval; |
| 453 |
} |
} |
| 454 |
|
|
| 592 |
mon_add_command("regs", dump_registers, "regs Dump PowerPC registers\n"); |
mon_add_command("regs", dump_registers, "regs Dump PowerPC registers\n"); |
| 593 |
mon_add_command("log", dump_log, "log Dump PowerPC emulation log\n"); |
mon_add_command("log", dump_log, "log Dump PowerPC emulation log\n"); |
| 594 |
#endif |
#endif |
| 595 |
|
|
| 596 |
|
#if EMUL_TIME_STATS |
| 597 |
|
emul_start_time = clock(); |
| 598 |
|
#endif |
| 599 |
} |
} |
| 600 |
|
|
| 601 |
/* |
/* |
| 604 |
|
|
| 605 |
void exit_emul_ppc(void) |
void exit_emul_ppc(void) |
| 606 |
{ |
{ |
| 607 |
|
#if EMUL_TIME_STATS |
| 608 |
|
clock_t emul_end_time = clock(); |
| 609 |
|
|
| 610 |
|
printf("### Statistics for SheepShaver emulation parts\n"); |
| 611 |
|
const clock_t emul_time = emul_end_time - emul_start_time; |
| 612 |
|
printf("Total emulation time : %.1f sec\n", double(emul_time) / double(CLOCKS_PER_SEC)); |
| 613 |
|
printf("Total interrupt count: %d (%2.1f Hz)\n", interrupt_count, |
| 614 |
|
(double(interrupt_count) * CLOCKS_PER_SEC) / double(emul_time)); |
| 615 |
|
|
| 616 |
|
#define PRINT_STATS(LABEL, VAR_PREFIX) do { \ |
| 617 |
|
printf("Total " LABEL " count : %d\n", VAR_PREFIX##_count); \ |
| 618 |
|
printf("Total " LABEL " time : %.1f sec (%.1f%%)\n", \ |
| 619 |
|
double(VAR_PREFIX##_time) / double(CLOCKS_PER_SEC), \ |
| 620 |
|
100.0 * double(VAR_PREFIX##_time) / double(emul_time)); \ |
| 621 |
|
} while (0) |
| 622 |
|
|
| 623 |
|
PRINT_STATS("Execute68k[Trap] execution", exec68k); |
| 624 |
|
PRINT_STATS("NativeOp execution", native_exec); |
| 625 |
|
PRINT_STATS("MacOS routine execution", macos_exec); |
| 626 |
|
|
| 627 |
|
#undef PRINT_STATS |
| 628 |
|
printf("\n"); |
| 629 |
|
#endif |
| 630 |
|
|
| 631 |
delete main_cpu; |
delete main_cpu; |
| 632 |
#if MULTICORE_CPU |
#if MULTICORE_CPU |
| 633 |
delete interrupt_cpu; |
delete interrupt_cpu; |
| 797 |
|
|
| 798 |
static void NativeOp(int selector) |
static void NativeOp(int selector) |
| 799 |
{ |
{ |
| 800 |
|
#if EMUL_TIME_STATS |
| 801 |
|
native_exec_count++; |
| 802 |
|
const clock_t native_exec_start = clock(); |
| 803 |
|
#endif |
| 804 |
|
|
| 805 |
switch (selector) { |
switch (selector) { |
| 806 |
case NATIVE_PATCH_NAME_REGISTRY: |
case NATIVE_PATCH_NAME_REGISTRY: |
| 807 |
DoPatchNameRegistry(); |
DoPatchNameRegistry(); |
| 865 |
QuitEmulator(); |
QuitEmulator(); |
| 866 |
break; |
break; |
| 867 |
} |
} |
| 868 |
|
|
| 869 |
|
#if EMUL_TIME_STATS |
| 870 |
|
native_exec_time += (clock() - native_exec_start); |
| 871 |
|
#endif |
| 872 |
} |
} |
| 873 |
|
|
| 874 |
/* |
/* |