--- SheepShaver/src/BeOS/main_beos.cpp 2004/11/13 14:09:15 1.14 +++ SheepShaver/src/BeOS/main_beos.cpp 2009/08/26 00:11:56 1.22 @@ -1,7 +1,7 @@ /* * main_beos.cpp - Emulation core, BeOS implementation * - * SheepShaver (C) 1997-2004 Christian Bauer and Marc Hellwig + * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -74,21 +74,11 @@ #include "xpram.h" #include "timer.h" #include "adb.h" -#include "sony.h" -#include "disk.h" -#include "cdrom.h" -#include "scsi.h" #include "video.h" -#include "audio.h" -#include "ether.h" -#include "serial.h" -#include "clip.h" -#include "extfs.h" #include "sys.h" #include "macos_util.h" #include "rom_patches.h" #include "user_strings.h" -#include "thunks.h" #include "sheep_driver.h" @@ -120,6 +110,8 @@ const char DR_CACHE_AREA_NAME[] = "Macin const char DR_EMULATOR_AREA_NAME[] = "Macintosh DR Emulator"; const char SHEEP_AREA_NAME[] = "SheepShaver Virtual Stack"; +const uintptr ROM_BASE = 0x40800000; // Base address of ROM + const uint32 SIG_STACK_SIZE = 8192; // Size of signal stack const uint32 MSG_START = 'strt'; // Emulator start message @@ -212,6 +204,7 @@ void *TOC; // TOC pointer #endif uint32 RAMBase; // Base address of Mac RAM uint32 RAMSize; // Size of Mac RAM +uint32 ROMBase; // Base address of Mac ROM uint32 KernelDataAddr; // Address of Kernel Data uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM uint32 DRCacheAddr; // Address of DR Cache @@ -229,7 +222,8 @@ static void *extra_stack = NULL; // Stac uint32 SheepMem::page_size; // Size of a native page uintptr SheepMem::zero_page = 0; // Address of ro page filled in with zeros uintptr SheepMem::base; // Address of SheepShaver data -uintptr SheepMem::top; // Top of SheepShaver data (stack like storage) +uintptr SheepMem::proc; // Bottom address of SheepShave procedures +uintptr SheepMem::data; // Top of SheepShaver data (stack like storage) static area_id SheepMemArea; // SheepShaver data area ID @@ -327,7 +321,7 @@ void SheepShaver::ReadyToRun(void) // Read preferences int argc = 0; char **argv = NULL; - PrefsInit(argc, argv); + PrefsInit(NULL, argc, argv); // Init system routines SysInit(); @@ -370,7 +364,6 @@ void SheepShaver::MessageReceived(BMessa void SheepShaver::StartEmulator(void) { char str[256]; - int16 i16; // Open sheep driver and remap low memory sheep_fd = open("/dev/sheep", 0); @@ -480,68 +473,12 @@ void SheepShaver::StartEmulator(void) } D(bug("DR Emulator area %ld at %p\n", dr_emulator_area, DREmulatorAddr)); - // Load NVRAM - XPRAMInit(); - - // Set boot volume - i16 = PrefsFindInt32("bootdrive"); - XPRAM[0x1378] = i16 >> 8; - XPRAM[0x1379] = i16 & 0xff; - i16 = PrefsFindInt32("bootdriver"); - XPRAM[0x137a] = i16 >> 8; - XPRAM[0x137b] = i16 & 0xff; - - // Create BootGlobs at top of Mac memory - memset((void *)(RAMBase + RAMSize - 4096), 0, 4096); - BootGlobsAddr = RAMBase + RAMSize - 0x1c; - uint32 *boot_globs = (uint32 *)BootGlobsAddr; - boot_globs[-5] = htonl(RAMBase + RAMSize); // MemTop - boot_globs[0] = htonl(RAMBase); // First RAM bank - boot_globs[1] = htonl(RAMSize); - boot_globs[2] = htonl((uint32)-1); // End of bank table - - // Init thunks - if (!InitThunks()) { - PostMessage(B_QUIT_REQUESTED); - return; - } - - // Init drivers - SonyInit(); - DiskInit(); - CDROMInit(); - SCSIInit(); - - // Init external file system - ExtFSInit(); - - // Init audio - AudioInit(); - - // Init network - EtherInit(); - - // Init serial ports - SerialInit(); - - // Init Time Manager - TimerInit(); - - // Init clipboard - ClipInit(); - - // Init video - if (!VideoInit()) { - PostMessage(B_QUIT_REQUESTED); - return; - } - - // Install ROM patches - if (!PatchROM()) { - ErrorAlert(GetString(STR_UNSUPPORTED_ROM_TYPE_ERR)); + // Initialize everything + if (!InitAll()) { PostMessage(B_QUIT_REQUESTED); return; } + D(bug("Initialization complete\n")); // Clear caches (as we loaded and patched code) and write protect ROM #if !EMULATED_PPC @@ -549,71 +486,10 @@ void SheepShaver::StartEmulator(void) #endif set_area_protection(rom_area, B_READ_AREA); - // Initialize Kernel Data - memset(kernel_data, 0, sizeof(KernelData)); - if (ROMType == ROMTYPE_NEWWORLD) { - static uint32 of_dev_tree[4] = {0, 0, 0, 0}; - static uint8 vector_lookup_tbl[128]; - static uint8 vector_mask_tbl[64]; - memset((uint8 *)kernel_data + 0xb80, 0x3d, 0x80); - memset(vector_lookup_tbl, 0, 128); - memset(vector_mask_tbl, 0, 64); - kernel_data->v[0xb80 >> 2] = htonl(ROM_BASE); - kernel_data->v[0xb84 >> 2] = htonl((uint32)of_dev_tree); // OF device tree base - kernel_data->v[0xb90 >> 2] = htonl((uint32)vector_lookup_tbl); - kernel_data->v[0xb94 >> 2] = htonl((uint32)vector_mask_tbl); - kernel_data->v[0xb98 >> 2] = htonl(ROM_BASE); // OpenPIC base - kernel_data->v[0xbb0 >> 2] = htonl(0); // ADB base - kernel_data->v[0xc20 >> 2] = htonl(RAMSize); - kernel_data->v[0xc24 >> 2] = htonl(RAMSize); - kernel_data->v[0xc30 >> 2] = htonl(RAMSize); - kernel_data->v[0xc34 >> 2] = htonl(RAMSize); - kernel_data->v[0xc38 >> 2] = htonl(0x00010020); - kernel_data->v[0xc3c >> 2] = htonl(0x00200001); - kernel_data->v[0xc40 >> 2] = htonl(0x00010000); - kernel_data->v[0xc50 >> 2] = htonl(RAMBase); - kernel_data->v[0xc54 >> 2] = htonl(RAMSize); - kernel_data->v[0xf60 >> 2] = htonl(PVR); - kernel_data->v[0xf64 >> 2] = htonl(CPUClockSpeed); - kernel_data->v[0xf68 >> 2] = htonl(BusClockSpeed); - kernel_data->v[0xf6c >> 2] = htonl(CPUClockSpeed); - } else { - kernel_data->v[0xc80 >> 2] = htonl(RAMSize); - kernel_data->v[0xc84 >> 2] = htonl(RAMSize); - kernel_data->v[0xc90 >> 2] = htonl(RAMSize); - kernel_data->v[0xc94 >> 2] = htonl(RAMSize); - kernel_data->v[0xc98 >> 2] = htonl(0x00010020); - kernel_data->v[0xc9c >> 2] = htonl(0x00200001); - kernel_data->v[0xca0 >> 2] = htonl(0x00010000); - kernel_data->v[0xcb0 >> 2] = htonl(RAMBase); - kernel_data->v[0xcb4 >> 2] = htonl(RAMSize); - kernel_data->v[0xf80 >> 2] = htonl(PVR); - kernel_data->v[0xf84 >> 2] = htonl(CPUClockSpeed); - kernel_data->v[0xf88 >> 2] = htonl(BusClockSpeed); - kernel_data->v[0xf8c >> 2] = htonl(CPUClockSpeed); - } - // Initialize extra low memory - D(bug("Initializing Low Memory...\n")); - memset(NULL, 0, 0x3000); - WriteMacInt32(XLM_SIGNATURE, 'Baah'); // Signature to detect SheepShaver - WriteMacInt32(XLM_KERNEL_DATA, (uint32)kernel_data); // For trap replacement routines + D(bug("Initializing extra Low Memory...\n")); WriteMacInt32(XLM_SHEEP_OBJ, (uint32)this); // Pointer to SheepShaver object - WriteMacInt32(XLM_PVR, PVR); // Theoretical PVR - WriteMacInt32(XLM_BUS_CLOCK, BusClockSpeed); // For DriverServicesLib patch - WriteMacInt16(XLM_EXEC_RETURN_OPCODE, M68K_EXEC_RETURN); // For Execute68k() (RTS from the executed 68k code will jump here and end 68k mode) - WriteMacInt32(XLM_ZERO_PAGE, SheepMem::ZeroPage()); // Pointer to read-only page with all bits set to 0 -#if !EMULATED_PPC - WriteMacInt32(XLM_TOC, (uint32)TOC); // TOC pointer of emulator - WriteMacInt32(XLM_ETHER_INIT, *(uint32 *)InitStreamModule); // DLPI ethernet driver functions - WriteMacInt32(XLM_ETHER_TERM, *(uint32 *)TerminateStreamModule); - WriteMacInt32(XLM_ETHER_OPEN, *(uint32 *)ether_open); - WriteMacInt32(XLM_ETHER_CLOSE, *(uint32 *)ether_close); - WriteMacInt32(XLM_ETHER_WPUT, *(uint32 *)ether_wput); - WriteMacInt32(XLM_ETHER_RSRV, *(uint32 *)ether_rsrv); - WriteMacInt32(XLM_VIDEO_DOIO, *(uint32 *)VideoDoDriverIO); -#endif - D(bug("Low Memory initialized\n")); + D(bug("Extra Low Memory initialized\n")); // Disallow quitting with Alt-Q from now on AllowQuitting = false; @@ -669,38 +545,8 @@ void SheepShaver::Quit(void) if (emul_thread > 0) wait_for_thread(emul_thread, &l); - // Save NVRAM - XPRAMExit(); - - // Exit clipboard - ClipExit(); - - // Exit Time Manager - TimerExit(); - - // Exit serial - SerialExit(); - - // Exit network - EtherExit(); - - // Exit audio - AudioExit(); - - // Exit video - VideoExit(); - - // Exit external file system - ExtFSExit(); - - // Exit drivers - SCSIExit(); - CDROMExit(); - DiskExit(); - SonyExit(); - - // Delete thunks - ThunksExit(); + // Deinitialize everything + ExitAll(); // Delete SheepShaver globals SheepMem::Exit(); @@ -757,10 +603,11 @@ void SheepShaver::init_rom(void) page_size = B_PAGE_SIZE; // Create area for ROM - ROMBaseHost = (uint8 *)ROM_BASE; - rom_area = create_area(ROM_AREA_NAME, (void **)&ROMBaseHost, B_EXACT_ADDRESS, ROM_AREA_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); + ROMBase = ROM_BASE; + rom_area = create_area(ROM_AREA_NAME, (void **)&ROMBase, B_EXACT_ADDRESS, ROM_AREA_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); if (rom_area < 0) throw area_error(); + ROMBaseHost = (uint8 *)ROMBase; D(bug("ROM area %ld at %p\n", rom_area, rom_addr)); // Load ROM @@ -781,14 +628,14 @@ void SheepShaver::load_rom(void) const char *rom_path = PrefsFindString("rom"); // Try to open ROM file - BFile file(rom_path ? rom_path : ROM_FILE_NAME, B_READ_ONLY); + BFile file(rom_path && *rom_path ? rom_path : ROM_FILE_NAME, B_READ_ONLY); if (file.InitCheck() != B_NO_ERROR) { // Failed, then ask memory_mess driver for ROM uint8 *rom = new uint8[ROM_SIZE]; // Reading directly into the area doesn't work ssize_t actual = read(sheep_fd, (void *)rom, ROM_SIZE); if (actual == ROM_SIZE) { - memcpy((void *)ROM_BASE, rom, ROM_SIZE); + memcpy(ROMBaseHost, rom, ROM_SIZE); delete[] rom; return; } else @@ -859,7 +706,7 @@ status_t SheepShaver::emul_func(void *ar // Jump to ROM boot routine D(bug("Jumping to ROM\n")); - obj->jump_to_rom(ROM_BASE + 0x310000); + obj->jump_to_rom(ROMBase + 0x310000); D(bug("Returned from ROM\n")); // We're no longer ready to receive signals @@ -1342,24 +1189,13 @@ void Dump68kRegs(M68kRegisters *r) void MakeExecutable(int dummy, uint32 start, uint32 length) { - if ((start >= ROM_BASE) && (start < (ROM_BASE + ROM_SIZE))) + if ((start >= ROMBase) && (start < (ROMBase + ROM_SIZE))) return; clear_caches((void *)start, length, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE); } /* - * Patch things after system startup (gets called by disk driver accRun routine) - */ - -void PatchAfterStartup(void) -{ - ExecuteNative(NATIVE_VIDEO_INSTALL_ACCEL); - InstallExtFS(); -} - - -/* * NVRAM watchdog thread (saves NVRAM every minute) */ @@ -1416,6 +1252,7 @@ status_t SheepShaver::tick_func(void *ar void TriggerInterrupt(void) { + idle_resume(); #if 0 WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1); #else @@ -1567,9 +1404,9 @@ void SheepShaver::sigusr1_handler(vregs // Execute nanokernel interrupt routine (this will activate the 68k emulator) atomic_add((int32 *)XLM_IRQ_NEST, 1); if (ROMType == ROMTYPE_NEWWORLD) - ppc_interrupt(ROM_BASE + 0x312b1c); + ppc_interrupt(ROMBase + 0x312b1c); else - ppc_interrupt(ROM_BASE + 0x312a3c); + ppc_interrupt(ROMBase + 0x312a3c); } break; #endif @@ -1673,32 +1510,32 @@ static void sigsegv_handler(vregs *r) uint32 imm = opcode & 0xffff; // Fault in Mac ROM or RAM? - bool mac_fault = (r->pc >= ROM_BASE) && (r->pc < (ROM_BASE + ROM_AREA_SIZE)) || (r->pc >= RAMBase) && (r->pc < (RAMBase + RAMSize)); + bool mac_fault = (r->pc >= ROMBase) && (r->pc < (ROMBase + ROM_AREA_SIZE)) || (r->pc >= RAMBase) && (r->pc < (RAMBase + RAMSize)); if (mac_fault) { // "VM settings" during MacOS 8 installation - if (r->pc == ROM_BASE + 0x488160 && segv_r[20] == 0xf8000000) { + if (r->pc == ROMBase + 0x488160 && segv_r[20] == 0xf8000000) { r->pc += 4; segv_r[8] = 0; goto rti; // MacOS 8.5 installation - } else if (r->pc == ROM_BASE + 0x488140 && segv_r[16] == 0xf8000000) { + } else if (r->pc == ROMBase + 0x488140 && segv_r[16] == 0xf8000000) { r->pc += 4; segv_r[8] = 0; goto rti; // MacOS 8 serial drivers on startup - } else if (r->pc == ROM_BASE + 0x48e080 && (segv_r[8] == 0xf3012002 || segv_r[8] == 0xf3012000)) { + } else if (r->pc == ROMBase + 0x48e080 && (segv_r[8] == 0xf3012002 || segv_r[8] == 0xf3012000)) { r->pc += 4; segv_r[8] = 0; goto rti; // MacOS 8.1 serial drivers on startup - } else if (r->pc == ROM_BASE + 0x48c5e0 && (segv_r[20] == 0xf3012002 || segv_r[20] == 0xf3012000)) { + } else if (r->pc == ROMBase + 0x48c5e0 && (segv_r[20] == 0xf3012002 || segv_r[20] == 0xf3012000)) { r->pc += 4; goto rti; - } else if (r->pc == ROM_BASE + 0x4a10a0 && (segv_r[20] == 0xf3012002 || segv_r[20] == 0xf3012000)) { + } else if (r->pc == ROMBase + 0x4a10a0 && (segv_r[20] == 0xf3012002 || segv_r[20] == 0xf3012000)) { r->pc += 4; goto rti; } @@ -1809,7 +1646,7 @@ static void sigsegv_handler(vregs *r) } // Ignore ROM writes - if (transfer_type == TYPE_STORE && addr >= ROM_BASE && addr < ROM_BASE + ROM_SIZE) { + if (transfer_type == TYPE_STORE && addr >= ROMBase && addr < ROMBase + ROM_SIZE) { D(bug("WARNING: %s write access to ROM at %p, pc %p\n", transfer_size == SIZE_BYTE ? "Byte" : transfer_size == SIZE_HALFWORD ? "Halfword" : "Word", addr, r->pc)); if (addr_mode == MODE_U || addr_mode == MODE_UX) segv_r[ra] = addr; @@ -1944,7 +1781,7 @@ static void sigill_handler(vregs *r) uint32 imm = opcode & 0xffff; // Fault in Mac ROM or RAM? - bool mac_fault = (r->pc >= ROM_BASE) && (r->pc < (ROM_BASE + ROM_AREA_SIZE)) || (r->pc >= RAMBase) && (r->pc < (RAMBase + RAMSize)); + bool mac_fault = (r->pc >= ROMBase) && (r->pc < (ROMBase + ROM_AREA_SIZE)) || (r->pc >= RAMBase) && (r->pc < (RAMBase + RAMSize)); if (mac_fault) { switch (primop) { @@ -2109,7 +1946,7 @@ bool SheepMem::Init(void) delete_area(old_sheep_area); // Create area for SheepShaver data - base = 0x60000000; + proc = base = 0x60000000; SheepMemArea = create_area(SHEEP_AREA_NAME, (void **)&base, B_BASE_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); if (SheepMemArea < 0) return false; @@ -2119,7 +1956,7 @@ bool SheepMem::Init(void) zero_page = const_zero_page; D(bug("SheepShaver area %ld at %p\n", SheepMemArea, base)); - top = base + size; + data = base + size; return true; }