1 |
|
/* |
2 |
|
* sheepshaver_glue.cpp - Glue Kheperix CPU to SheepShaver CPU engine interface |
3 |
|
* |
4 |
< |
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig |
4 |
> |
* SheepShaver (C) 1997-2004 Christian Bauer and Marc Hellwig |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
73 |
|
#endif |
74 |
|
} |
75 |
|
|
76 |
+ |
// From main_*.cpp |
77 |
+ |
extern uintptr SignalStackBase(); |
78 |
+ |
|
79 |
|
// PowerPC EmulOp to exit from emulation looop |
80 |
|
const uint32 POWERPC_EXEC_RETURN = POWERPC_EMUL_OP | 1; |
81 |
|
|
127 |
|
// Constructor |
128 |
|
sheepshaver_cpu(); |
129 |
|
|
130 |
< |
// Condition Register accessors |
130 |
> |
// CR & XER accessors |
131 |
|
uint32 get_cr() const { return cr().get(); } |
132 |
|
void set_cr(uint32 v) { cr().set(v); } |
133 |
+ |
uint32 get_xer() const { return xer().get(); } |
134 |
+ |
void set_xer(uint32 v) { xer().set(v); } |
135 |
|
|
136 |
|
// Execute 68k routine |
137 |
|
void execute_68k(uint32 entry, M68kRegisters *r); |
243 |
|
for (int i = 0; i < 7; i++) |
244 |
|
r68.a[i] = gpr(16 + i); |
245 |
|
r68.a[7] = gpr(1); |
246 |
+ |
uint32 saved_cr = get_cr() & CR_field<2>::mask(); |
247 |
+ |
uint32 saved_xer = get_xer(); |
248 |
|
EmulOp(&r68, gpr(24), EMUL_OP_field::extract(opcode) - 3); |
249 |
+ |
set_cr(saved_cr); |
250 |
+ |
set_xer(saved_xer); |
251 |
|
for (int i = 0; i < 8; i++) |
252 |
|
gpr(8 + i) = r68.d[i]; |
253 |
|
for (int i = 0; i < 7; i++) |
277 |
|
#endif |
278 |
|
|
279 |
|
// Initialize stack pointer to SheepShaver alternate stack base |
280 |
< |
SheepArray<64> stack_area; |
272 |
< |
gpr(1) = stack_area.addr(); |
280 |
> |
gpr(1) = SignalStackBase() - 64; |
281 |
|
|
282 |
|
// Build trampoline to return from interrupt |
283 |
|
SheepVar32 trampoline = POWERPC_EXEC_RETURN; |
629 |
|
// Initialize main CPU emulator |
630 |
|
main_cpu = new sheepshaver_cpu(); |
631 |
|
main_cpu->set_register(powerpc_registers::GPR(3), any_register((uint32)ROM_BASE + 0x30d000)); |
632 |
+ |
main_cpu->set_register(powerpc_registers::GPR(4), any_register(KernelDataAddr + 0x1000)); |
633 |
|
WriteMacInt32(XLM_RUN_MODE, MODE_68K); |
634 |
|
|
635 |
|
#if MULTICORE_CPU |
694 |
|
void emul_ppc(uint32 entry) |
695 |
|
{ |
696 |
|
current_cpu = main_cpu; |
697 |
< |
#if DEBUG |
697 |
> |
#if 0 |
698 |
|
current_cpu->start_log(); |
699 |
|
#endif |
700 |
|
// start emulation loop and enable code translation or caching |
793 |
|
if (InterruptFlags & INTFLAG_VIA) { |
794 |
|
ClearInterruptFlag(INTFLAG_VIA); |
795 |
|
ADBInterrupt(); |
796 |
< |
ExecutePPC(VideoVBL); |
796 |
> |
ExecuteNative(NATIVE_VIDEO_VBL); |
797 |
|
} |
798 |
|
} |
799 |
|
#endif |
917 |
|
} |
918 |
|
|
919 |
|
/* |
911 |
– |
* Execute native subroutine (LR must contain return address) |
912 |
– |
*/ |
913 |
– |
|
914 |
– |
void ExecuteNative(int selector) |
915 |
– |
{ |
916 |
– |
SheepRoutineDescriptor desc(0, NativeTVECT(selector)); |
917 |
– |
M68kRegisters r; |
918 |
– |
Execute68k(desc.addr(), &r); |
919 |
– |
} |
920 |
– |
|
921 |
– |
/* |
920 |
|
* Execute 68k subroutine (must be ended with EXEC_RETURN) |
921 |
|
* This must only be called by the emul_thread when in EMUL_OP mode |
922 |
|
* r->a[7] is unused, the routine runs on the caller's stack |