Enable Apple DR emulator from NewWorld ROMs only.

This commit is contained in:
gbeauche 2004-05-31 09:04:44 +00:00
parent d048916fda
commit 7bc86b27ee
9 changed files with 88 additions and 19 deletions

View File

@ -117,6 +117,7 @@ const char KERNEL_AREA2_NAME[] = "Macintosh Kernel Data 2";
const char RAM_AREA_NAME[] = "Macintosh RAM"; const char RAM_AREA_NAME[] = "Macintosh RAM";
const char ROM_AREA_NAME[] = "Macintosh ROM"; const char ROM_AREA_NAME[] = "Macintosh ROM";
const char DR_CACHE_AREA_NAME[] = "Macintosh DR Cache"; const char DR_CACHE_AREA_NAME[] = "Macintosh DR Cache";
const char DR_EMULATOR_AREA_NAME[] = "Macintosh DR Emulator";
const char SHEEP_AREA_NAME[] = "SheepShaver Virtual Stack"; const char SHEEP_AREA_NAME[] = "SheepShaver Virtual Stack";
const uint32 SIG_STACK_SIZE = 8192; // Size of signal stack const uint32 SIG_STACK_SIZE = 8192; // Size of signal stack
@ -142,7 +143,7 @@ public:
// Initialize other variables // Initialize other variables
sheep_fd = -1; sheep_fd = -1;
emulator_data = NULL; emulator_data = NULL;
kernel_area = kernel_area2 = rom_area = ram_area = dr_cache_area = -1; kernel_area = kernel_area2 = rom_area = ram_area = dr_cache_area = dr_emulator_area = -1;
emul_thread = nvram_thread = tick_thread = -1; emul_thread = nvram_thread = tick_thread = -1;
ReadyForSignals = false; ReadyForSignals = false;
AllowQuitting = true; AllowQuitting = true;
@ -190,6 +191,7 @@ private:
area_id rom_area; // ROM area ID area_id rom_area; // ROM area ID
area_id ram_area; // RAM area ID area_id ram_area; // RAM area ID
area_id dr_cache_area; // DR Cache area ID area_id dr_cache_area; // DR Cache area ID
area_id dr_emulator_area; // DR Emulator area ID
struct sigaction sigusr1_action; // Interrupt signal (of emulator thread) struct sigaction sigusr1_action; // Interrupt signal (of emulator thread)
struct sigaction sigsegv_action; // Data access exception signal (of emulator thread) struct sigaction sigsegv_action; // Data access exception signal (of emulator thread)
@ -213,6 +215,7 @@ uint32 RAMSize; // Size of Mac RAM
uint32 KernelDataAddr; // Address of Kernel Data uint32 KernelDataAddr; // Address of Kernel Data
uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM
uint32 DRCacheAddr; // Address of DR Cache uint32 DRCacheAddr; // Address of DR Cache
uint32 DREmulatorAddr; // Address of DR Emulator
uint32 PVR; // Theoretical PVR uint32 PVR; // Theoretical PVR
int64 CPUClockSpeed; // Processor clock speed (Hz) int64 CPUClockSpeed; // Processor clock speed (Hz)
int64 BusClockSpeed; // Bus clock speed (Hz) int64 BusClockSpeed; // Bus clock speed (Hz)
@ -313,6 +316,9 @@ void SheepShaver::ReadyToRun(void)
area_id old_dr_cache_area = find_area(DR_CACHE_AREA_NAME); area_id old_dr_cache_area = find_area(DR_CACHE_AREA_NAME);
if (old_dr_cache_area > 0) if (old_dr_cache_area > 0)
delete_area(old_dr_cache_area); delete_area(old_dr_cache_area);
area_id old_dr_emulator_area = find_area(DR_EMULATOR_AREA_NAME);
if (old_dr_emulator_area > 0)
delete_area(old_dr_emulator_area);
// Read preferences // Read preferences
int argc = 0; int argc = 0;
@ -403,7 +409,7 @@ void SheepShaver::StartEmulator(void)
// Create area for SheepShaver data // Create area for SheepShaver data
if (!SheepMem::Init()) { if (!SheepMem::Init()) {
sprintf(str, GetString(STR_NO_SHEEP_MEM_AREA_ERR)); sprintf(str, GetString(STR_NO_SHEEP_MEM_AREA_ERR), strerror(SheepMemArea), SheepMemArea);
ErrorAlert(str); ErrorAlert(str);
PostMessage(B_QUIT_REQUESTED); PostMessage(B_QUIT_REQUESTED);
return; return;
@ -458,6 +464,17 @@ void SheepShaver::StartEmulator(void)
} }
D(bug("DR Cache area %ld at %p\n", dr_cache_area, DRCacheAddr)); D(bug("DR Cache area %ld at %p\n", dr_cache_area, DRCacheAddr));
// Create area for DR Emulator
DREmulatorAddr = DR_EMULATOR_BASE;
dr_emulator_area = create_area(DR_EMULATOR_AREA_NAME, (void **)&DREmulatorAddr, B_EXACT_ADDRESS, DR_EMULATOR_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
if (dr_emulator_area < 0) {
sprintf(str, GetString(STR_NO_KERNEL_DATA_ERR), strerror(dr_emulator_area), dr_emulator_area);
ErrorAlert(str);
PostMessage(B_QUIT_REQUESTED);
return;
}
D(bug("DR Emulator area %ld at %p\n", dr_emulator_area, DREmulatorAddr));
// Load NVRAM // Load NVRAM
XPRAMInit(); XPRAMInit();
@ -683,6 +700,10 @@ void SheepShaver::Quit(void)
// Delete SheepShaver globals // Delete SheepShaver globals
SheepMem::Exit(); SheepMem::Exit();
// Delete DR Emulator area
if (dr_emulator_area >= 0)
delete_area(dr_emulator_area);
// Delete DR Cache area // Delete DR Cache area
if (dr_cache_area >= 0) if (dr_cache_area >= 0)
delete_area(dr_cache_area); delete_area(dr_cache_area);

View File

@ -40,6 +40,9 @@ user_string_def platform_strings[] = {
{STR_NET_CONFIG_MODIFY_WARN, "To enable Ethernet networking for SheepShaver, your network configuration has to be modified and the network restarted. Do you want this to be done now (selecting \"Cancel\" will disable Ethernet under SheepShaver)?."}, {STR_NET_CONFIG_MODIFY_WARN, "To enable Ethernet networking for SheepShaver, your network configuration has to be modified and the network restarted. Do you want this to be done now (selecting \"Cancel\" will disable Ethernet under SheepShaver)?."},
{STR_NET_ADDON_INIT_FAILED, "SheepShaver net server add-on found\nbut there seems to be no network hardware.\nPlease check your network preferences."}, {STR_NET_ADDON_INIT_FAILED, "SheepShaver net server add-on found\nbut there seems to be no network hardware.\nPlease check your network preferences."},
{STR_NET_ADDON_CLONE_FAILED, "Cloning of the network transfer area failed."}, {STR_NET_ADDON_CLONE_FAILED, "Cloning of the network transfer area failed."},
{STR_NO_SHEEP_MEM_AREA_ERR, "Cannot create SheepShaver Globals area: %s (%08x)."},
{STR_NO_DR_CACHE_AREA_ERR, "Cannot create DR Cache area: %s (%08x)."},
{STR_NO_DR_EMULATOR_AREA_ERR, "Cannot create DR Emulator area: %s (%08x)."},
{-1, NULL} // End marker {-1, NULL} // End marker
}; };

View File

@ -29,7 +29,9 @@ enum {
STR_NET_CONFIG_MODIFY_WARN, STR_NET_CONFIG_MODIFY_WARN,
STR_NET_ADDON_INIT_FAILED, STR_NET_ADDON_INIT_FAILED,
STR_NET_ADDON_CLONE_FAILED, STR_NET_ADDON_CLONE_FAILED,
STR_NO_SHEEP_MEM_AREA_ERR STR_NO_SHEEP_MEM_AREA_ERR,
STR_NO_DR_CACHE_AREA_ERR,
STR_NO_DR_EMULATOR_AREA_ERR
}; };
#endif #endif

View File

@ -265,6 +265,7 @@ uint32 RAMBase; // Base address of Mac RAM
uint32 RAMSize; // Size of Mac RAM uint32 RAMSize; // Size of Mac RAM
uint32 KernelDataAddr; // Address of Kernel Data uint32 KernelDataAddr; // Address of Kernel Data
uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM
uint32 DRCacheAddr; // Address of DR Cache
uint32 PVR; // Theoretical PVR uint32 PVR; // Theoretical PVR
int64 CPUClockSpeed; // Processor clock speed (Hz) int64 CPUClockSpeed; // Processor clock speed (Hz)
int64 BusClockSpeed; // Bus clock speed (Hz) int64 BusClockSpeed; // Bus clock speed (Hz)
@ -282,6 +283,8 @@ static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped
static int kernel_area = -1; // SHM ID of Kernel Data area static int kernel_area = -1; // SHM ID of Kernel Data area
static bool rom_area_mapped = false; // Flag: Mac ROM mmap()ped static bool rom_area_mapped = false; // Flag: Mac ROM mmap()ped
static bool ram_area_mapped = false; // Flag: Mac RAM mmap()ped static bool ram_area_mapped = false; // Flag: Mac RAM mmap()ped
static bool dr_cache_area_mapped = false; // Flag: Mac DR Cache mmap()ped
static bool dr_emulator_area_mapped = false;// Flag: Mac DR Emulator mmap()ped
static KernelData *kernel_data; // Pointer to Kernel Data static KernelData *kernel_data; // Pointer to Kernel Data
static EmulatorData *emulator_data; static EmulatorData *emulator_data;
@ -597,6 +600,22 @@ int main(int argc, char **argv)
KernelDataAddr = KERNEL_DATA_BASE; KernelDataAddr = KERNEL_DATA_BASE;
D(bug("Kernel Data at %p, Emulator Data at %p\n", kernel_data, emulator_data)); D(bug("Kernel Data at %p, Emulator Data at %p\n", kernel_data, emulator_data));
// Create area for DR Cache
if (vm_acquire_fixed((void *)DR_EMULATOR_BASE, DR_EMULATOR_SIZE) < 0) {
sprintf(str, GetString(STR_DR_EMULATOR_MMAP_ERR), strerror(errno));
ErrorAlert(str);
goto quit;
}
dr_emulator_area_mapped = true;
if (vm_acquire_fixed((void *)DR_CACHE_BASE, DR_CACHE_SIZE) < 0) {
sprintf(str, GetString(STR_DR_CACHE_MMAP_ERR), strerror(errno));
ErrorAlert(str);
goto quit;
}
dr_cache_area_mapped = true;
DRCacheAddr = DR_CACHE_BASE;
D(bug("DR Cache at %p\n", DRCacheAddr));
// Create area for SheepShaver data // Create area for SheepShaver data
if (!SheepMem::Init()) { if (!SheepMem::Init()) {
sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno)); sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno));
@ -1023,6 +1042,12 @@ static void Quit(void)
if (rom_area_mapped) if (rom_area_mapped)
vm_release((char *)ROM_BASE, ROM_AREA_SIZE); vm_release((char *)ROM_BASE, ROM_AREA_SIZE);
// Delete DR cache areas
if (dr_emulator_area_mapped)
vm_release((void *)DR_EMULATOR_BASE, DR_EMULATOR_SIZE);
if (dr_cache_area_mapped)
vm_release((void *)DR_CACHE_BASE, DR_CACHE_SIZE);
// Delete Kernel Data area // Delete Kernel Data area
if (kernel_area >= 0) { if (kernel_area >= 0) {
shmdt((void *)KERNEL_DATA_BASE); shmdt((void *)KERNEL_DATA_BASE);

View File

@ -38,6 +38,8 @@ user_string_def platform_strings[] = {
{STR_KD2_SHMAT_ERR, "Cannot map second Kernel Data area: %s."}, {STR_KD2_SHMAT_ERR, "Cannot map second Kernel Data area: %s."},
{STR_ROM_MMAP_ERR, "Cannot map ROM: %s."}, {STR_ROM_MMAP_ERR, "Cannot map ROM: %s."},
{STR_RAM_MMAP_ERR, "Cannot map RAM: %s."}, {STR_RAM_MMAP_ERR, "Cannot map RAM: %s."},
{STR_DR_CACHE_MMAP_ERR, "Cannot map DR Cache: %s."},
{STR_DR_EMULATOR_MMAP_ERR, "Cannot map DR Emulator: %s."},
{STR_SHEEP_MEM_MMAP_ERR, "Cannot map SheepShaver Data area: %s."}, {STR_SHEEP_MEM_MMAP_ERR, "Cannot map SheepShaver Data area: %s."},
{STR_SIGALTSTACK_ERR, "Cannot install alternate signal stack (%s). It seems that you need a newer kernel."}, {STR_SIGALTSTACK_ERR, "Cannot install alternate signal stack (%s). It seems that you need a newer kernel."},
{STR_SIGSEGV_INSTALL_ERR, "Cannot install SIGSEGV handler: %s."}, {STR_SIGSEGV_INSTALL_ERR, "Cannot install SIGSEGV handler: %s."},

View File

@ -29,6 +29,8 @@ enum {
STR_KD2_SHMAT_ERR, STR_KD2_SHMAT_ERR,
STR_ROM_MMAP_ERR, STR_ROM_MMAP_ERR,
STR_RAM_MMAP_ERR, STR_RAM_MMAP_ERR,
STR_DR_CACHE_MMAP_ERR,
STR_DR_EMULATOR_MMAP_ERR,
STR_SHEEP_MEM_MMAP_ERR, STR_SHEEP_MEM_MMAP_ERR,
STR_SIGALTSTACK_ERR, STR_SIGALTSTACK_ERR,
STR_SIGSEGV_INSTALL_ERR, STR_SIGSEGV_INSTALL_ERR,

View File

@ -287,15 +287,18 @@ void EmulOp(M68kRegisters *r, uint32 pc, int selector)
TimerReset(); TimerReset();
MacOSUtilReset(); MacOSUtilReset();
AudioReset(); AudioReset();
#if 0
printf("DR activated\n"); // Enable DR emulator from NewWorld ROMs
WriteMacInt32(KernelDataAddr + 0x17a0, 3); // Prepare for DR emulator activation if (ROMType == ROMTYPE_NEWWORLD) {
WriteMacInt32(KernelDataAddr + 0x17c0, DR_CACHE_BASE); D(bug("DR activated\n"));
WriteMacInt32(KernelDataAddr + 0x17c4, DR_CACHE_SIZE); WriteMacInt32(KernelDataAddr + 0x17a0, 3); // Prepare for DR emulator activation
WriteMacInt32(KernelDataAddr + 0x1b00, DR_CACHE_BASE + 0x10000); WriteMacInt32(KernelDataAddr + 0x17c0, DR_CACHE_BASE);
memcpy((void *)(DR_CACHE_BASE + 0x10000), (void *)(ROM_BASE + 0x370000), 0x10000); WriteMacInt32(KernelDataAddr + 0x17c4, DR_CACHE_SIZE);
clear_caches((void *)(DR_CACHE_BASE + 0x10000), 0x10000, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE); WriteMacInt32(KernelDataAddr + 0x1b04, DR_CACHE_BASE);
#endif WriteMacInt32(KernelDataAddr + 0x1b00, DR_EMULATOR_BASE);
memcpy((void *)DR_EMULATOR_BASE, (void *)(ROM_BASE + 0x370000), DR_EMULATOR_SIZE);
MakeExecutable(0, (void *)DR_EMULATOR_BASE, DR_EMULATOR_SIZE);
}
break; break;
case OP_IRQ: // Level 1 interrupt case OP_IRQ: // Level 1 interrupt

View File

@ -31,6 +31,8 @@ const uintptr ROM_BASE = 0x40800000; // Base address of ROM
const uint32 ROM_SIZE = 0x400000; // Size of ROM file const uint32 ROM_SIZE = 0x400000; // Size of ROM file
const uint32 ROM_AREA_SIZE = 0x500000; // Size of ROM area const uint32 ROM_AREA_SIZE = 0x500000; // Size of ROM area
const uintptr ROM_END = ROM_BASE + ROM_SIZE; // End of ROM const uintptr ROM_END = ROM_BASE + ROM_SIZE; // End of ROM
const uintptr DR_EMULATOR_BASE = 0x68070000; // Address of DR emulator code
const uint32 DR_EMULATOR_SIZE = 0x10000; // Size of DR emulator code
const uintptr DR_CACHE_BASE = 0x69000000; // Address of DR cache const uintptr DR_CACHE_BASE = 0x69000000; // Address of DR cache
const uint32 DR_CACHE_SIZE = 0x80000; // Size of DR Cache const uint32 DR_CACHE_SIZE = 0x80000; // Size of DR Cache

View File

@ -1058,7 +1058,7 @@ static bool patch_nanokernel_boot(void)
static bool patch_68k_emul(void) static bool patch_68k_emul(void)
{ {
uint32 *lp; uint32 *lp;
uint32 base; uint32 base, loc;
// Overwrite twi instructions // Overwrite twi instructions
static const uint8 twi_dat[] = {0x0f, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x01, 0x0f, 0xff, 0x00, 0x02}; static const uint8 twi_dat[] = {0x0f, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x01, 0x0f, 0xff, 0x00, 0x02};
@ -1266,12 +1266,21 @@ static bool patch_68k_emul(void)
return false; return false;
dr_found: dr_found:
lp++; lp++;
*lp = htonl(0x48000000 + 0xf000 - (((uint32)lp - ROM_BASE) & 0xffff)); // b DR_CACHE_BASE+0x1f000 loc = (uint32)lp - ROM_BASE;
lp = (uint32 *)(ROM_BASE + 0x37f000); if ((base = powerpc_branch_target(ROM_BASE + loc)) == 0) base = ROM_BASE + loc;
*lp++ = htonl(0x3c000000 + ((ROM_BASE + 0x46d0a4) >> 16)); // lis r0,xxx static const uint8 dr_ret_dat[] = {0x80, 0xbf, 0x08, 0x14, 0x53, 0x19, 0x4d, 0xac, 0x7c, 0xa8, 0x03, 0xa6};
*lp++ = htonl(0x60000000 + ((ROM_BASE + 0x46d0a4) & 0xffff)); // ori r0,r0,xxx if ((base = find_rom_data(base - ROM_BASE, 0x380000, dr_ret_dat, sizeof(dr_ret_dat))) == 0) return false;
*lp++ = htonl(0x7c0903a6); // mtctr r0 D(bug("dr_ret %08lx\n", base));
*lp = htonl(POWERPC_BCTR); // bctr if (base != loc) {
// OldWorld ROMs contain an absolute branch
D(bug(" patching absolute branch at %08x\n", (uint32)lp - ROM_BASE));
*lp = htonl(0x48000000 + 0xf000 - (((uint32)lp - ROM_BASE) & 0xffff)); // b DR_CACHE_BASE+0x1f000
lp = (uint32 *)(ROM_BASE + 0x37f000);
*lp++ = htonl(0x3c000000 + ((ROM_BASE + base) >> 16)); // lis r0,xxx
*lp++ = htonl(0x60000000 + ((ROM_BASE + base) & 0xffff)); // ori r0,r0,xxx
*lp++ = htonl(0x7c0803a6); // mtlr r0
*lp = htonl(POWERPC_BLR); // blr
}
return true; return true;
} }