| 1 |
/* |
/* |
| 2 |
* emul_op.cpp - 68k opcodes for ROM patches |
* emul_op.cpp - 68k opcodes for ROM patches |
| 3 |
* |
* |
| 4 |
* Basilisk II (C) 1997-1999 Christian Bauer |
* Basilisk II (C) 1997-2004 Christian Bauer |
| 5 |
* |
* |
| 6 |
* This program is free software; you can redistribute it and/or modify |
* 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 |
* it under the terms of the GNU General Public License as published by |
| 42 |
#include "extfs.h" |
#include "extfs.h" |
| 43 |
#include "emul_op.h" |
#include "emul_op.h" |
| 44 |
|
|
| 45 |
|
#ifdef ENABLE_MON |
| 46 |
|
#include "mon.h" |
| 47 |
|
#endif |
| 48 |
|
|
| 49 |
#define DEBUG 0 |
#define DEBUG 0 |
| 50 |
#include "debug.h" |
#include "debug.h" |
| 51 |
|
|
| 60 |
switch (opcode) { |
switch (opcode) { |
| 61 |
case M68K_EMUL_BREAK: { // Breakpoint |
case M68K_EMUL_BREAK: { // Breakpoint |
| 62 |
printf("*** Breakpoint\n"); |
printf("*** Breakpoint\n"); |
| 63 |
printf("d0 %08lx d1 %08lx d2 %08lx d3 %08lx\n" |
printf("d0 %08x d1 %08x d2 %08x d3 %08x\n" |
| 64 |
"d4 %08lx d5 %08lx d6 %08lx d7 %08lx\n" |
"d4 %08x d5 %08x d6 %08x d7 %08x\n" |
| 65 |
"a0 %08lx a1 %08lx a2 %08lx a3 %08lx\n" |
"a0 %08x a1 %08x a2 %08x a3 %08x\n" |
| 66 |
"a4 %08lx a5 %08lx a6 %08lx a7 %08lx\n" |
"a4 %08x a5 %08x a6 %08x a7 %08x\n" |
| 67 |
"sr %04x\n", |
"sr %04x\n", |
| 68 |
r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7], |
r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7], |
| 69 |
r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7], |
r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7], |
| 70 |
r->sr); |
r->sr); |
| 71 |
|
VideoQuitFullScreen(); |
| 72 |
|
#ifdef ENABLE_MON |
| 73 |
|
char *arg[4] = {"mon", "-m", "-r", NULL}; |
| 74 |
|
mon(3, arg); |
| 75 |
|
#endif |
| 76 |
QuitEmulator(); |
QuitEmulator(); |
| 77 |
break; |
break; |
| 78 |
} |
} |
| 85 |
D(bug("*** RESET ***\n")); |
D(bug("*** RESET ***\n")); |
| 86 |
TimerReset(); |
TimerReset(); |
| 87 |
EtherReset(); |
EtherReset(); |
| 88 |
|
AudioReset(); |
| 89 |
|
|
| 90 |
// Create BootGlobs at top of memory |
// Create BootGlobs at top of memory |
| 91 |
memset((void *)(RAMBaseHost + RAMSize - 4096), 0, 4096); |
Mac_memset(RAMBaseMac + RAMSize - 4096, 0, 4096); |
| 92 |
uint32 boot_globs = RAMBaseMac + RAMSize - 0x1c; |
uint32 boot_globs = RAMBaseMac + RAMSize - 0x1c; |
| 93 |
WriteMacInt32(boot_globs + 0x00, RAMBaseMac); // First RAM bank |
WriteMacInt32(boot_globs + 0x00, RAMBaseMac); // First RAM bank |
| 94 |
WriteMacInt32(boot_globs + 0x04, RAMSize); |
WriteMacInt32(boot_globs + 0x04, RAMSize); |
| 197 |
break; |
break; |
| 198 |
|
|
| 199 |
case M68K_EMUL_OP_FIX_BOOTSTACK: // Set boot stack to 3/4 of RAM (7.5) |
case M68K_EMUL_OP_FIX_BOOTSTACK: // Set boot stack to 3/4 of RAM (7.5) |
|
D(bug("Fix boot stack\n")); |
|
| 200 |
r->a[1] = RAMBaseMac + RAMSize * 3 / 4; |
r->a[1] = RAMBaseMac + RAMSize * 3 / 4; |
| 201 |
|
D(bug("Fix boot stack %08x\n", r->a[1])); |
| 202 |
break; |
break; |
| 203 |
|
|
| 204 |
case M68K_EMUL_OP_FIX_MEMSIZE: { // Set correct logical and physical memory size |
case M68K_EMUL_OP_FIX_MEMSIZE: { // Set correct logical and physical memory size |
| 240 |
r.a[0] = PutScrapPatch; |
r.a[0] = PutScrapPatch; |
| 241 |
Execute68kTrap(0xa647, &r); // SetToolTrap() |
Execute68kTrap(0xa647, &r); // SetToolTrap() |
| 242 |
|
|
| 243 |
|
// Install GetScrap() patch |
| 244 |
|
if (GetScrapPatch) { |
| 245 |
|
r.d[0] = 0xa9fd; |
| 246 |
|
r.a[0] = GetScrapPatch; |
| 247 |
|
Execute68kTrap(0xa647, &r); // SetToolTrap() |
| 248 |
|
} |
| 249 |
|
|
| 250 |
// Setup fake ASC registers |
// Setup fake ASC registers |
| 251 |
if (ROMVersion == ROM_VERSION_32) { |
if (ROMVersion == ROM_VERSION_32) { |
| 252 |
r.d[0] = 0x1000; |
r.d[0] = 0x1000; |
| 356 |
EtherReadPacket((uint8 **)&r->a[0], r->a[3], r->d[3], r->d[1]); |
EtherReadPacket((uint8 **)&r->a[0], r->a[3], r->d[3], r->d[1]); |
| 357 |
break; |
break; |
| 358 |
|
|
| 359 |
|
case M68K_EMUL_OP_SOUNDIN_OPEN: // Sound input driver functions |
| 360 |
|
r->d[0] = SoundInOpen(r->a[0], r->a[1]); |
| 361 |
|
break; |
| 362 |
|
|
| 363 |
|
case M68K_EMUL_OP_SOUNDIN_PRIME: |
| 364 |
|
r->d[0] = SoundInPrime(r->a[0], r->a[1]); |
| 365 |
|
break; |
| 366 |
|
|
| 367 |
|
case M68K_EMUL_OP_SOUNDIN_CONTROL: |
| 368 |
|
r->d[0] = SoundInControl(r->a[0], r->a[1]); |
| 369 |
|
break; |
| 370 |
|
|
| 371 |
|
case M68K_EMUL_OP_SOUNDIN_STATUS: |
| 372 |
|
r->d[0] = SoundInStatus(r->a[0], r->a[1]); |
| 373 |
|
break; |
| 374 |
|
|
| 375 |
|
case M68K_EMUL_OP_SOUNDIN_CLOSE: |
| 376 |
|
r->d[0] = SoundInClose(r->a[0], r->a[1]); |
| 377 |
|
break; |
| 378 |
|
|
| 379 |
case M68K_EMUL_OP_SCSI_DISPATCH: { // SCSIDispatch() replacement |
case M68K_EMUL_OP_SCSI_DISPATCH: { // SCSIDispatch() replacement |
| 380 |
uint32 ret = ReadMacInt32(r->a[7]); // Get return address |
uint32 ret = ReadMacInt32(r->a[7]); // Get return address |
| 381 |
uint16 sel = ReadMacInt16(r->a[7] + 4); // Get selector |
uint16 sel = ReadMacInt16(r->a[7] + 4); // Get selector |
| 439 |
break; |
break; |
| 440 |
} |
} |
| 441 |
|
|
|
case M68K_EMUL_OP_MEMORY_DISPATCH: { // MemoryDispatch() replacement routine |
|
|
int16 sel = r->d[0]; |
|
|
D(bug("MemoryDispatch(%d)\n", sel)); |
|
|
switch (sel) { |
|
|
case -6: // GetLogicalRAMSize |
|
|
r->d[0] = RAMSize; |
|
|
break; |
|
|
case -3: |
|
|
r->d[0] = 0x1000; |
|
|
break; |
|
|
case 0: // HoldMemory |
|
|
case 1: // UnholdMemory |
|
|
case 2: // LockMemory |
|
|
case 3: // UnlockMemory |
|
|
case 4: // LockMemoryContiguous |
|
|
case 6: // ProtectMemory |
|
|
case 7: // UnprotectMemory |
|
|
r->d[0] = 0; |
|
|
break; |
|
|
default: |
|
|
printf("FATAL: MemoryDispatch(%d): illegal selector\n", sel); |
|
|
r->d[0] = (uint32)-502; |
|
|
break; |
|
|
} |
|
|
break; |
|
|
} |
|
|
|
|
| 442 |
case M68K_EMUL_OP_IRQ: // Level 1 interrupt |
case M68K_EMUL_OP_IRQ: // Level 1 interrupt |
| 443 |
r->d[0] = 0; |
r->d[0] = 0; |
| 444 |
|
|
| 445 |
if (InterruptFlags & INTFLAG_60HZ) { |
if (InterruptFlags & INTFLAG_60HZ) { |
| 446 |
ClearInterruptFlag(INTFLAG_60HZ); |
ClearInterruptFlag(INTFLAG_60HZ); |
| 447 |
|
|
| 448 |
|
// Increment Ticks variable |
| 449 |
|
WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1); |
| 450 |
|
|
| 451 |
if (HasMacStarted()) { |
if (HasMacStarted()) { |
| 452 |
|
|
| 453 |
// Mac has started, execute all 60Hz interrupt functions |
// Mac has started, execute all 60Hz interrupt functions |
|
ADBInterrupt(); |
|
| 454 |
TimerInterrupt(); |
TimerInterrupt(); |
| 455 |
VideoInterrupt(); |
VideoInterrupt(); |
|
SonyInterrupt(); |
|
|
DiskInterrupt(); |
|
|
CDROMInterrupt(); |
|
| 456 |
|
|
| 457 |
// Call DoVBLTask(0) |
// Call DoVBLTask(0) |
| 458 |
if (ROMVersion == ROM_VERSION_32) { |
if (ROMVersion == ROM_VERSION_32) { |
| 464 |
r->d[0] = 1; // Flag: 68k interrupt routine executes VBLTasks etc. |
r->d[0] = 1; // Flag: 68k interrupt routine executes VBLTasks etc. |
| 465 |
} |
} |
| 466 |
} |
} |
| 467 |
|
|
| 468 |
|
if (InterruptFlags & INTFLAG_1HZ) { |
| 469 |
|
ClearInterruptFlag(INTFLAG_1HZ); |
| 470 |
|
if (HasMacStarted()) { |
| 471 |
|
SonyInterrupt(); |
| 472 |
|
DiskInterrupt(); |
| 473 |
|
CDROMInterrupt(); |
| 474 |
|
} |
| 475 |
|
} |
| 476 |
|
|
| 477 |
if (InterruptFlags & INTFLAG_SERIAL) { |
if (InterruptFlags & INTFLAG_SERIAL) { |
| 478 |
ClearInterruptFlag(INTFLAG_SERIAL); |
ClearInterruptFlag(INTFLAG_SERIAL); |
| 479 |
SerialInterrupt(); |
SerialInterrupt(); |
| 480 |
} |
} |
| 481 |
|
|
| 482 |
if (InterruptFlags & INTFLAG_ETHER) { |
if (InterruptFlags & INTFLAG_ETHER) { |
| 483 |
ClearInterruptFlag(INTFLAG_ETHER); |
ClearInterruptFlag(INTFLAG_ETHER); |
| 484 |
EtherInterrupt(); |
EtherInterrupt(); |
| 485 |
} |
} |
| 486 |
|
|
| 487 |
if (InterruptFlags & INTFLAG_AUDIO) { |
if (InterruptFlags & INTFLAG_AUDIO) { |
| 488 |
ClearInterruptFlag(INTFLAG_AUDIO); |
ClearInterruptFlag(INTFLAG_AUDIO); |
| 489 |
AudioInterrupt(); |
AudioInterrupt(); |
| 490 |
} |
} |
| 491 |
|
|
| 492 |
|
if (InterruptFlags & INTFLAG_ADB) { |
| 493 |
|
ClearInterruptFlag(INTFLAG_ADB); |
| 494 |
|
if (HasMacStarted()) |
| 495 |
|
ADBInterrupt(); |
| 496 |
|
} |
| 497 |
|
|
| 498 |
|
if (InterruptFlags & INTFLAG_NMI) { |
| 499 |
|
ClearInterruptFlag(INTFLAG_NMI); |
| 500 |
|
if (HasMacStarted()) |
| 501 |
|
TriggerNMI(); |
| 502 |
|
} |
| 503 |
break; |
break; |
| 504 |
|
|
| 505 |
case M68K_EMUL_OP_PUT_SCRAP: { // PutScrap() patch |
case M68K_EMUL_OP_PUT_SCRAP: { // PutScrap() patch |
| 510 |
break; |
break; |
| 511 |
} |
} |
| 512 |
|
|
| 513 |
|
case M68K_EMUL_OP_GET_SCRAP: { // GetScrap() patch |
| 514 |
|
void **scrap_handle = (void **)Mac2HostAddr(ReadMacInt32(r->a[7] + 4)); |
| 515 |
|
uint32 type = ReadMacInt32(r->a[7] + 8); |
| 516 |
|
int32 length = ReadMacInt32(r->a[7] + 12); |
| 517 |
|
GetScrap(scrap_handle, type, length); |
| 518 |
|
break; |
| 519 |
|
} |
| 520 |
|
|
| 521 |
case M68K_EMUL_OP_CHECKLOAD: { // vCheckLoad() patch (resource loader) |
case M68K_EMUL_OP_CHECKLOAD: { // vCheckLoad() patch (resource loader) |
| 522 |
uint32 type = r->d[1]; |
uint32 type = r->d[1]; |
| 523 |
int16 id = ReadMacInt16(r->a[2]); |
int16 id = ReadMacInt16(r->a[2]); |
| 546 |
break; |
break; |
| 547 |
#endif |
#endif |
| 548 |
|
|
| 549 |
|
case M68K_EMUL_OP_BLOCK_MOVE: // BlockMove() cache flushing |
| 550 |
|
FlushCodeCache(Mac2HostAddr(r->a[0]), r->a[1]); |
| 551 |
|
break; |
| 552 |
|
|
| 553 |
|
case M68K_EMUL_OP_DEBUGUTIL: |
| 554 |
|
// printf("DebugUtil d0=%08lx a5=%08lx\n", r->d[0], r->a[5]); |
| 555 |
|
r->d[0] = DebugUtil(r->d[0]); |
| 556 |
|
break; |
| 557 |
|
|
| 558 |
default: |
default: |
| 559 |
printf("FATAL: EMUL_OP called with bogus opcode %08x\n", opcode); |
printf("FATAL: EMUL_OP called with bogus opcode %08x\n", opcode); |
| 560 |
printf("d0 %08lx d1 %08lx d2 %08lx d3 %08lx\n" |
printf("d0 %08x d1 %08x d2 %08x d3 %08x\n" |
| 561 |
"d4 %08lx d5 %08lx d6 %08lx d7 %08lx\n" |
"d4 %08x d5 %08x d6 %08x d7 %08x\n" |
| 562 |
"a0 %08lx a1 %08lx a2 %08lx a3 %08lx\n" |
"a0 %08x a1 %08x a2 %08x a3 %08x\n" |
| 563 |
"a4 %08lx a5 %08lx a6 %08lx a7 %08lx\n" |
"a4 %08x a5 %08x a6 %08x a7 %08x\n" |
| 564 |
"sr %04x\n", |
"sr %04x\n", |
| 565 |
r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7], |
r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7], |
| 566 |
r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7], |
r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7], |
| 567 |
r->sr); |
r->sr); |
| 568 |
|
#ifdef ENABLE_MON |
| 569 |
|
char *arg[4] = {"mon", "-m", "-r", NULL}; |
| 570 |
|
mon(3, arg); |
| 571 |
|
#endif |
| 572 |
QuitEmulator(); |
QuitEmulator(); |
| 573 |
break; |
break; |
| 574 |
} |
} |