43 |
|
#include <stdio.h> |
44 |
|
#include <stdlib.h> |
45 |
|
|
46 |
+ |
#ifdef USE_SDL_VIDEO |
47 |
+ |
#include <SDL_events.h> |
48 |
+ |
#endif |
49 |
+ |
|
50 |
|
#if ENABLE_MON |
51 |
|
#include "mon.h" |
52 |
|
#include "mon_disass.h" |
56 |
|
#include "debug.h" |
57 |
|
|
58 |
|
// Emulation time statistics |
59 |
< |
#define EMUL_TIME_STATS 1 |
59 |
> |
#ifndef EMUL_TIME_STATS |
60 |
> |
#define EMUL_TIME_STATS 0 |
61 |
> |
#endif |
62 |
|
|
63 |
|
#if EMUL_TIME_STATS |
64 |
|
static clock_t emul_start_time; |
65 |
< |
static uint32 interrupt_count = 0; |
65 |
> |
static uint32 interrupt_count = 0, ppc_interrupt_count = 0; |
66 |
|
static clock_t interrupt_time = 0; |
67 |
|
static uint32 exec68k_count = 0; |
68 |
|
static clock_t exec68k_time = 0; |
450 |
|
status = COMPILE_CODE_OK; |
451 |
|
break; |
452 |
|
#endif |
447 |
– |
case NATIVE_DISABLE_INTERRUPT: |
448 |
– |
dg.gen_invoke(DisableInterrupt); |
449 |
– |
status = COMPILE_CODE_OK; |
450 |
– |
break; |
451 |
– |
case NATIVE_ENABLE_INTERRUPT: |
452 |
– |
dg.gen_invoke(EnableInterrupt); |
453 |
– |
status = COMPILE_CODE_OK; |
454 |
– |
break; |
453 |
|
case NATIVE_BITBLT: |
454 |
|
dg.gen_load_T0_GPR(3); |
455 |
|
dg.gen_invoke_T0((void (*)(uint32))NQD_bitblt); |
594 |
|
void sheepshaver_cpu::interrupt(uint32 entry) |
595 |
|
{ |
596 |
|
#if EMUL_TIME_STATS |
597 |
< |
interrupt_count++; |
597 |
> |
ppc_interrupt_count++; |
598 |
|
const clock_t interrupt_start = clock(); |
599 |
|
#endif |
600 |
|
|
986 |
|
printf("Total emulation time : %.1f sec\n", double(emul_time) / double(CLOCKS_PER_SEC)); |
987 |
|
printf("Total interrupt count: %d (%2.1f Hz)\n", interrupt_count, |
988 |
|
(double(interrupt_count) * CLOCKS_PER_SEC) / double(emul_time)); |
989 |
+ |
printf("Total ppc interrupt count: %d (%2.1f %%)\n", ppc_interrupt_count, |
990 |
+ |
(double(ppc_interrupt_count) * 100.0) / double(interrupt_count)); |
991 |
|
|
992 |
|
#define PRINT_STATS(LABEL, VAR_PREFIX) do { \ |
993 |
|
printf("Total " LABEL " count : %d\n", VAR_PREFIX##_count); \ |
1063 |
|
|
1064 |
|
void sheepshaver_cpu::handle_interrupt(void) |
1065 |
|
{ |
1066 |
< |
// Do nothing if interrupts are disabled |
1067 |
< |
if (*(int32 *)XLM_IRQ_NEST > 0) |
1068 |
< |
return; |
1066 |
> |
#ifdef USE_SDL_VIDEO |
1067 |
> |
// We must fill in the events queue in the same thread that did call SDL_SetVideoMode() |
1068 |
> |
SDL_PumpEvents(); |
1069 |
> |
#endif |
1070 |
|
|
1071 |
< |
// Do nothing if there is no interrupt pending |
1072 |
< |
if (InterruptFlags == 0) |
1071 |
> |
// Do nothing if interrupts are disabled |
1072 |
> |
if (int32(ReadMacInt32(XLM_IRQ_NEST)) > 0) |
1073 |
|
return; |
1074 |
|
|
1075 |
|
// Current interrupt nest level |
1076 |
|
static int interrupt_depth = 0; |
1077 |
|
++interrupt_depth; |
1078 |
+ |
#if EMUL_TIME_STATS |
1079 |
+ |
interrupt_count++; |
1080 |
+ |
#endif |
1081 |
|
|
1082 |
|
// Disable MacOS stack sniffer |
1083 |
|
WriteMacInt32(0x110, 0); |
1117 |
|
// 68k emulator active, within EMUL_OP routine, execute 68k interrupt routine directly when interrupt level is 0 |
1118 |
|
if ((ReadMacInt32(XLM_68K_R25) & 7) == 0) { |
1119 |
|
interrupt_context ctx(this, "68k mode"); |
1120 |
+ |
#if EMUL_TIME_STATS |
1121 |
+ |
const clock_t interrupt_start = clock(); |
1122 |
+ |
#endif |
1123 |
|
#if 1 |
1124 |
|
// Execute full 68k interrupt routine |
1125 |
|
M68kRegisters r; |
1145 |
|
} |
1146 |
|
} |
1147 |
|
#endif |
1148 |
+ |
#if EMUL_TIME_STATS |
1149 |
+ |
interrupt_time += (clock() - interrupt_start); |
1150 |
+ |
#endif |
1151 |
|
} |
1152 |
|
break; |
1153 |
|
#endif |
1267 |
|
get_resource_callbacks[selector - NATIVE_GET_RESOURCE](); |
1268 |
|
break; |
1269 |
|
} |
1260 |
– |
case NATIVE_DISABLE_INTERRUPT: |
1261 |
– |
DisableInterrupt(); |
1262 |
– |
break; |
1263 |
– |
case NATIVE_ENABLE_INTERRUPT: |
1264 |
– |
EnableInterrupt(); |
1265 |
– |
break; |
1270 |
|
case NATIVE_MAKE_EXECUTABLE: |
1271 |
|
MakeExecutable(0, (void *)gpr(4), gpr(5)); |
1272 |
|
break; |