| 71 |
// Interrupts in native mode? |
// Interrupts in native mode? |
| 72 |
#define INTERRUPTS_IN_NATIVE_MODE 1 |
#define INTERRUPTS_IN_NATIVE_MODE 1 |
| 73 |
|
|
|
// 68k Emulator Data |
|
|
struct EmulatorData { |
|
|
uint32 v[0x400]; |
|
|
}; |
|
|
|
|
|
// Kernel Data |
|
|
struct KernelData { |
|
|
uint32 v[0x400]; |
|
|
EmulatorData ed; |
|
|
}; |
|
|
|
|
| 74 |
// Pointer to Kernel Data |
// Pointer to Kernel Data |
| 75 |
static KernelData * const kernel_data = (KernelData *)0x68ffe000; |
static KernelData * const kernel_data = (KernelData *)KERNEL_DATA_BASE; |
| 76 |
|
|
| 77 |
|
|
| 78 |
/** |
/** |
| 113 |
void get_resource(uint32 old_get_resource); |
void get_resource(uint32 old_get_resource); |
| 114 |
|
|
| 115 |
// Handle MacOS interrupt |
// Handle MacOS interrupt |
| 116 |
void interrupt(uint32 entry, sheepshaver_cpu *cpu); |
void interrupt(uint32 entry); |
| 117 |
|
|
| 118 |
// spcflags for interrupts handling |
// spcflags for interrupts handling |
| 119 |
static uint32 spcflags; |
static uint32 spcflags; |
| 221 |
static inline void execute(powerpc_cpu *) { } |
static inline void execute(powerpc_cpu *) { } |
| 222 |
}; |
}; |
| 223 |
|
|
|
static void HandleInterrupt(void); |
|
|
|
|
| 224 |
struct execute_spcflags_check { |
struct execute_spcflags_check { |
| 225 |
static inline void execute(powerpc_cpu *cpu) { |
static inline void execute(powerpc_cpu *cpu) { |
| 226 |
|
#if !ASYNC_IRQ |
| 227 |
if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) { |
if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) { |
| 228 |
if (SPCFLAGS_TEST( SPCFLAG_ENTER_MON )) { |
if (SPCFLAGS_TEST( SPCFLAG_ENTER_MON )) { |
| 229 |
SPCFLAGS_CLEAR( SPCFLAG_ENTER_MON ); |
SPCFLAGS_CLEAR( SPCFLAG_ENTER_MON ); |
| 238 |
SPCFLAGS_SET( SPCFLAG_DOINT ); |
SPCFLAGS_SET( SPCFLAG_DOINT ); |
| 239 |
} |
} |
| 240 |
} |
} |
| 241 |
|
#endif |
| 242 |
} |
} |
| 243 |
}; |
}; |
| 244 |
|
|
| 259 |
} |
} |
| 260 |
|
|
| 261 |
// Handle MacOS interrupt |
// Handle MacOS interrupt |
| 262 |
void sheepshaver_cpu::interrupt(uint32 entry, sheepshaver_cpu *cpu) |
void sheepshaver_cpu::interrupt(uint32 entry) |
| 263 |
{ |
{ |
| 264 |
#if MULTICORE_CPU |
#if !MULTICORE_CPU |
|
// Initialize stack pointer from previous CPU running |
|
|
gpr(1) = cpu->gpr(1); |
|
|
#else |
|
| 265 |
// Save program counters and branch registers |
// Save program counters and branch registers |
| 266 |
uint32 saved_pc = pc(); |
uint32 saved_pc = pc(); |
| 267 |
uint32 saved_lr = lr(); |
uint32 saved_lr = lr(); |
| 268 |
uint32 saved_ctr= ctr(); |
uint32 saved_ctr= ctr(); |
| 269 |
|
uint32 saved_sp = gpr(1); |
| 270 |
#endif |
#endif |
| 271 |
|
|
| 272 |
// Create stack frame |
// Initialize stack pointer to SheepShaver alternate stack base |
| 273 |
gpr(1) -= 64; |
gpr(1) = SheepStack1Base - 64; |
| 274 |
|
|
| 275 |
// Build trampoline to return from interrupt |
// Build trampoline to return from interrupt |
| 276 |
uint32 trampoline[] = { POWERPC_EMUL_OP | 1 }; |
uint32 trampoline[] = { POWERPC_EMUL_OP | 1 }; |
| 307 |
// Enter nanokernel |
// Enter nanokernel |
| 308 |
execute(entry); |
execute(entry); |
| 309 |
|
|
|
// Cleanup stack |
|
|
gpr(1) += 64; |
|
|
|
|
| 310 |
#if !MULTICORE_CPU |
#if !MULTICORE_CPU |
| 311 |
// Restore program counters and branch registers |
// Restore program counters and branch registers |
| 312 |
pc() = saved_pc; |
pc() = saved_pc; |
| 313 |
lr() = saved_lr; |
lr() = saved_lr; |
| 314 |
ctr()= saved_ctr; |
ctr()= saved_ctr; |
| 315 |
|
gpr(1) = saved_sp; |
| 316 |
#endif |
#endif |
| 317 |
} |
} |
| 318 |
|
|
| 598 |
extern int atomic_and(int *var, int v); |
extern int atomic_and(int *var, int v); |
| 599 |
extern int atomic_or(int *var, int v); |
extern int atomic_or(int *var, int v); |
| 600 |
|
|
| 601 |
|
#if !ASYNC_IRQ |
| 602 |
void TriggerInterrupt(void) |
void TriggerInterrupt(void) |
| 603 |
{ |
{ |
| 604 |
#if 0 |
#if 0 |
| 607 |
SPCFLAGS_SET( SPCFLAG_INT ); |
SPCFLAGS_SET( SPCFLAG_INT ); |
| 608 |
#endif |
#endif |
| 609 |
} |
} |
| 610 |
|
#endif |
| 611 |
|
|
| 612 |
static void HandleInterrupt(void) |
void HandleInterrupt(void) |
| 613 |
{ |
{ |
| 614 |
// Do nothing if interrupts are disabled |
// Do nothing if interrupts are disabled |
| 615 |
if (int32(ReadMacInt32(XLM_IRQ_NEST)) > 0) |
if (int32(ReadMacInt32(XLM_IRQ_NEST)) > 0) |
| 646 |
DisableInterrupt(); |
DisableInterrupt(); |
| 647 |
cpu_push(interrupt_cpu); |
cpu_push(interrupt_cpu); |
| 648 |
if (ROMType == ROMTYPE_NEWWORLD) |
if (ROMType == ROMTYPE_NEWWORLD) |
| 649 |
current_cpu->interrupt(ROM_BASE + 0x312b1c, main_cpu); |
current_cpu->interrupt(ROM_BASE + 0x312b1c); |
| 650 |
else |
else |
| 651 |
current_cpu->interrupt(ROM_BASE + 0x312a3c, main_cpu); |
current_cpu->interrupt(ROM_BASE + 0x312a3c); |
| 652 |
cpu_pop(); |
cpu_pop(); |
| 653 |
} |
} |
| 654 |
break; |
break; |