| 273 |
gpr(1) = SheepStack1Base - 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[] = { htonl(POWERPC_EMUL_OP | 1) }; |
| 277 |
|
|
| 278 |
// Prepare registers for nanokernel interrupt routine |
// Prepare registers for nanokernel interrupt routine |
| 279 |
kernel_data->v[0x004 >> 2] = gpr(1); |
kernel_data->v[0x004 >> 2] = htonl(gpr(1)); |
| 280 |
kernel_data->v[0x018 >> 2] = gpr(6); |
kernel_data->v[0x018 >> 2] = htonl(gpr(6)); |
| 281 |
|
|
| 282 |
gpr(6) = kernel_data->v[0x65c >> 2]; |
gpr(6) = ntohl(kernel_data->v[0x65c >> 2]); |
| 283 |
assert(gpr(6) != 0); |
assert(gpr(6) != 0); |
| 284 |
WriteMacInt32(gpr(6) + 0x13c, gpr(7)); |
WriteMacInt32(gpr(6) + 0x13c, gpr(7)); |
| 285 |
WriteMacInt32(gpr(6) + 0x144, gpr(8)); |
WriteMacInt32(gpr(6) + 0x144, gpr(8)); |
| 290 |
WriteMacInt32(gpr(6) + 0x16c, gpr(13)); |
WriteMacInt32(gpr(6) + 0x16c, gpr(13)); |
| 291 |
|
|
| 292 |
gpr(1) = KernelDataAddr; |
gpr(1) = KernelDataAddr; |
| 293 |
gpr(7) = kernel_data->v[0x660 >> 2]; |
gpr(7) = ntohl(kernel_data->v[0x660 >> 2]); |
| 294 |
gpr(8) = 0; |
gpr(8) = 0; |
| 295 |
gpr(10) = (uint32)trampoline; |
gpr(10) = (uint32)trampoline; |
| 296 |
gpr(12) = (uint32)trampoline; |
gpr(12) = (uint32)trampoline; |
| 335 |
WriteMacInt32(gpr(1), sp); |
WriteMacInt32(gpr(1), sp); |
| 336 |
|
|
| 337 |
// Save PowerPC registers |
// Save PowerPC registers |
| 338 |
memcpy(Mac2HostAddr(gpr(1)+56), &gpr(13), sizeof(uint32)*(32-13)); |
for (int i = 13; i < 32; i++) |
| 339 |
|
WriteMacInt32(gpr(1) + 56 + i*4, gpr(i)); |
| 340 |
#if SAVE_FP_EXEC_68K |
#if SAVE_FP_EXEC_68K |
| 341 |
memcpy(Mac2HostAddr(gpr(1)+56+19*4), &fpr(14), sizeof(double)*(32-14)); |
memcpy(Mac2HostAddr(gpr(1)+56+19*4), &fpr(14), sizeof(double)*(32-14)); |
| 342 |
#endif |
#endif |
| 352 |
gpr(25) = ReadMacInt32(XLM_68K_R25); // MSB of SR |
gpr(25) = ReadMacInt32(XLM_68K_R25); // MSB of SR |
| 353 |
gpr(26) = 0; |
gpr(26) = 0; |
| 354 |
gpr(28) = 0; // VBR |
gpr(28) = 0; // VBR |
| 355 |
gpr(29) = kernel_data->ed.v[0x74 >> 2]; // Pointer to opcode table |
gpr(29) = ntohl(kernel_data->ed.v[0x74 >> 2]); // Pointer to opcode table |
| 356 |
gpr(30) = kernel_data->ed.v[0x78 >> 2]; // Address of emulator |
gpr(30) = ntohl(kernel_data->ed.v[0x78 >> 2]); // Address of emulator |
| 357 |
gpr(31) = KernelDataAddr + 0x1000; |
gpr(31) = KernelDataAddr + 0x1000; |
| 358 |
|
|
| 359 |
// Push return address (points to EXEC_RETURN opcode) on stack |
// Push return address (points to EXEC_RETURN opcode) on stack |
| 385 |
r->a[i] = gpr(16 + i); |
r->a[i] = gpr(16 + i); |
| 386 |
|
|
| 387 |
// Restore PowerPC registers |
// Restore PowerPC registers |
| 388 |
memcpy(&gpr(13), Mac2HostAddr(gpr(1)+56), sizeof(uint32)*(32-13)); |
for (int i = 13; i < 32; i++) |
| 389 |
|
gpr(i) = ReadMacInt32(gpr(1) + 56 + i*4); |
| 390 |
#if SAVE_FP_EXEC_68K |
#if SAVE_FP_EXEC_68K |
| 391 |
memcpy(&fpr(14), Mac2HostAddr(gpr(1)+56+19*4), sizeof(double)*(32-14)); |
memcpy(&fpr(14), Mac2HostAddr(gpr(1)+56+19*4), sizeof(double)*(32-14)); |
| 392 |
#endif |
#endif |
| 409 |
uint32 saved_ctr= ctr(); |
uint32 saved_ctr= ctr(); |
| 410 |
|
|
| 411 |
// Build trampoline with EXEC_RETURN |
// Build trampoline with EXEC_RETURN |
| 412 |
uint32 trampoline[] = { POWERPC_EMUL_OP | 1 }; |
uint32 trampoline[] = { htonl(POWERPC_EMUL_OP | 1) }; |
| 413 |
lr() = (uint32)trampoline; |
lr() = (uint32)trampoline; |
| 414 |
|
|
| 415 |
gpr(1) -= 64; // Create stack frame |
gpr(1) -= 64; // Create stack frame |
| 451 |
uint32 saved_lr = lr(); |
uint32 saved_lr = lr(); |
| 452 |
uint32 saved_ctr= ctr(); |
uint32 saved_ctr= ctr(); |
| 453 |
|
|
| 454 |
const uint32 trampoline[] = { POWERPC_EMUL_OP | 1 }; |
const uint32 trampoline[] = { htonl(POWERPC_EMUL_OP | 1) }; |
| 455 |
|
|
| 456 |
lr() = (uint32)trampoline; |
lr() = (uint32)trampoline; |
| 457 |
ctr()= entry; |
ctr()= entry; |
| 463 |
} |
} |
| 464 |
|
|
| 465 |
// Resource Manager thunk |
// Resource Manager thunk |
| 466 |
extern "C" void check_load_invoc(uint32 type, int16 id, uint16 **h); |
extern "C" void check_load_invoc(uint32 type, int16 id, uint32 h); |
| 467 |
|
|
| 468 |
inline void sheepshaver_cpu::get_resource(uint32 old_get_resource) |
inline void sheepshaver_cpu::get_resource(uint32 old_get_resource) |
| 469 |
{ |
{ |
| 475 |
|
|
| 476 |
// Call old routine |
// Call old routine |
| 477 |
execute_ppc(old_get_resource); |
execute_ppc(old_get_resource); |
|
uint16 **handle = (uint16 **)gpr(3); |
|
| 478 |
|
|
| 479 |
// Call CheckLoad() |
// Call CheckLoad() |
| 480 |
|
uint32 handle = gpr(3); |
| 481 |
check_load_invoc(type, id, handle); |
check_load_invoc(type, id, handle); |
| 482 |
gpr(3) = (uint32)handle; |
gpr(3) = handle; |
| 483 |
|
|
| 484 |
// Cleanup stack |
// Cleanup stack |
| 485 |
gpr(1) += 56; |
gpr(1) += 56; |
| 831 |
|
|
| 832 |
void Execute68kTrap(uint16 trap, M68kRegisters *r) |
void Execute68kTrap(uint16 trap, M68kRegisters *r) |
| 833 |
{ |
{ |
| 834 |
uint16 proc[2] = {trap, M68K_RTS}; |
uint16 proc[2]; |
| 835 |
|
proc[0] = htons(trap); |
| 836 |
|
proc[1] = htons(M68K_RTS); |
| 837 |
Execute68k((uint32)proc, r); |
Execute68k((uint32)proc, r); |
| 838 |
} |
} |
| 839 |
|
|