mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-12-25 17:29:19 +00:00
Enable Apple DR emulator from NewWorld ROMs only.
This commit is contained in:
parent
d048916fda
commit
7bc86b27ee
@ -117,6 +117,7 @@ const char KERNEL_AREA2_NAME[] = "Macintosh Kernel Data 2";
|
||||
const char RAM_AREA_NAME[] = "Macintosh RAM";
|
||||
const char ROM_AREA_NAME[] = "Macintosh ROM";
|
||||
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 uint32 SIG_STACK_SIZE = 8192; // Size of signal stack
|
||||
@ -142,7 +143,7 @@ public:
|
||||
// Initialize other variables
|
||||
sheep_fd = -1;
|
||||
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;
|
||||
ReadyForSignals = false;
|
||||
AllowQuitting = true;
|
||||
@ -190,6 +191,7 @@ private:
|
||||
area_id rom_area; // ROM area ID
|
||||
area_id ram_area; // RAM 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 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 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM
|
||||
uint32 DRCacheAddr; // Address of DR Cache
|
||||
uint32 DREmulatorAddr; // Address of DR Emulator
|
||||
uint32 PVR; // Theoretical PVR
|
||||
int64 CPUClockSpeed; // Processor 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);
|
||||
if (old_dr_cache_area > 0)
|
||||
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
|
||||
int argc = 0;
|
||||
@ -403,7 +409,7 @@ void SheepShaver::StartEmulator(void)
|
||||
|
||||
// Create area for SheepShaver data
|
||||
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);
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
@ -458,6 +464,17 @@ void SheepShaver::StartEmulator(void)
|
||||
}
|
||||
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
|
||||
XPRAMInit();
|
||||
|
||||
@ -683,6 +700,10 @@ void SheepShaver::Quit(void)
|
||||
// Delete SheepShaver globals
|
||||
SheepMem::Exit();
|
||||
|
||||
// Delete DR Emulator area
|
||||
if (dr_emulator_area >= 0)
|
||||
delete_area(dr_emulator_area);
|
||||
|
||||
// Delete DR Cache area
|
||||
if (dr_cache_area >= 0)
|
||||
delete_area(dr_cache_area);
|
||||
|
@ -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_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_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
|
||||
};
|
||||
|
@ -29,7 +29,9 @@ enum {
|
||||
STR_NET_CONFIG_MODIFY_WARN,
|
||||
STR_NET_ADDON_INIT_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
|
||||
|
@ -265,6 +265,7 @@ uint32 RAMBase; // Base address of Mac RAM
|
||||
uint32 RAMSize; // Size of Mac RAM
|
||||
uint32 KernelDataAddr; // Address of Kernel Data
|
||||
uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM
|
||||
uint32 DRCacheAddr; // Address of DR Cache
|
||||
uint32 PVR; // Theoretical PVR
|
||||
int64 CPUClockSpeed; // Processor 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 bool rom_area_mapped = false; // Flag: Mac ROM 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 EmulatorData *emulator_data;
|
||||
|
||||
@ -597,6 +600,22 @@ int main(int argc, char **argv)
|
||||
KernelDataAddr = KERNEL_DATA_BASE;
|
||||
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
|
||||
if (!SheepMem::Init()) {
|
||||
sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno));
|
||||
@ -1023,6 +1042,12 @@ static void Quit(void)
|
||||
if (rom_area_mapped)
|
||||
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
|
||||
if (kernel_area >= 0) {
|
||||
shmdt((void *)KERNEL_DATA_BASE);
|
||||
|
@ -38,6 +38,8 @@ user_string_def platform_strings[] = {
|
||||
{STR_KD2_SHMAT_ERR, "Cannot map second Kernel Data area: %s."},
|
||||
{STR_ROM_MMAP_ERR, "Cannot map ROM: %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_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."},
|
||||
|
@ -29,6 +29,8 @@ enum {
|
||||
STR_KD2_SHMAT_ERR,
|
||||
STR_ROM_MMAP_ERR,
|
||||
STR_RAM_MMAP_ERR,
|
||||
STR_DR_CACHE_MMAP_ERR,
|
||||
STR_DR_EMULATOR_MMAP_ERR,
|
||||
STR_SHEEP_MEM_MMAP_ERR,
|
||||
STR_SIGALTSTACK_ERR,
|
||||
STR_SIGSEGV_INSTALL_ERR,
|
||||
|
@ -287,15 +287,18 @@ void EmulOp(M68kRegisters *r, uint32 pc, int selector)
|
||||
TimerReset();
|
||||
MacOSUtilReset();
|
||||
AudioReset();
|
||||
#if 0
|
||||
printf("DR activated\n");
|
||||
WriteMacInt32(KernelDataAddr + 0x17a0, 3); // Prepare for DR emulator activation
|
||||
WriteMacInt32(KernelDataAddr + 0x17c0, DR_CACHE_BASE);
|
||||
WriteMacInt32(KernelDataAddr + 0x17c4, DR_CACHE_SIZE);
|
||||
WriteMacInt32(KernelDataAddr + 0x1b00, DR_CACHE_BASE + 0x10000);
|
||||
memcpy((void *)(DR_CACHE_BASE + 0x10000), (void *)(ROM_BASE + 0x370000), 0x10000);
|
||||
clear_caches((void *)(DR_CACHE_BASE + 0x10000), 0x10000, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE);
|
||||
#endif
|
||||
|
||||
// Enable DR emulator from NewWorld ROMs
|
||||
if (ROMType == ROMTYPE_NEWWORLD) {
|
||||
D(bug("DR activated\n"));
|
||||
WriteMacInt32(KernelDataAddr + 0x17a0, 3); // Prepare for DR emulator activation
|
||||
WriteMacInt32(KernelDataAddr + 0x17c0, DR_CACHE_BASE);
|
||||
WriteMacInt32(KernelDataAddr + 0x17c4, DR_CACHE_SIZE);
|
||||
WriteMacInt32(KernelDataAddr + 0x1b04, DR_CACHE_BASE);
|
||||
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;
|
||||
|
||||
case OP_IRQ: // Level 1 interrupt
|
||||
|
@ -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_AREA_SIZE = 0x500000; // Size of ROM area
|
||||
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 uint32 DR_CACHE_SIZE = 0x80000; // Size of DR Cache
|
||||
|
||||
|
@ -1058,7 +1058,7 @@ static bool patch_nanokernel_boot(void)
|
||||
static bool patch_68k_emul(void)
|
||||
{
|
||||
uint32 *lp;
|
||||
uint32 base;
|
||||
uint32 base, loc;
|
||||
|
||||
// Overwrite twi instructions
|
||||
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;
|
||||
dr_found:
|
||||
lp++;
|
||||
*lp = htonl(0x48000000 + 0xf000 - (((uint32)lp - ROM_BASE) & 0xffff)); // b DR_CACHE_BASE+0x1f000
|
||||
lp = (uint32 *)(ROM_BASE + 0x37f000);
|
||||
*lp++ = htonl(0x3c000000 + ((ROM_BASE + 0x46d0a4) >> 16)); // lis r0,xxx
|
||||
*lp++ = htonl(0x60000000 + ((ROM_BASE + 0x46d0a4) & 0xffff)); // ori r0,r0,xxx
|
||||
*lp++ = htonl(0x7c0903a6); // mtctr r0
|
||||
*lp = htonl(POWERPC_BCTR); // bctr
|
||||
loc = (uint32)lp - ROM_BASE;
|
||||
if ((base = powerpc_branch_target(ROM_BASE + loc)) == 0) base = ROM_BASE + loc;
|
||||
static const uint8 dr_ret_dat[] = {0x80, 0xbf, 0x08, 0x14, 0x53, 0x19, 0x4d, 0xac, 0x7c, 0xa8, 0x03, 0xa6};
|
||||
if ((base = find_rom_data(base - ROM_BASE, 0x380000, dr_ret_dat, sizeof(dr_ret_dat))) == 0) return false;
|
||||
D(bug("dr_ret %08lx\n", base));
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user