--- SheepShaver/src/BeOS/main_beos.cpp 2002/04/21 15:07:08 1.2 +++ SheepShaver/src/BeOS/main_beos.cpp 2004/01/12 15:37:19 1.10 @@ -1,7 +1,7 @@ /* * main_beos.cpp - Emulation core, BeOS implementation * - * SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig + * SheepShaver (C) 1997-2004 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 @@ -88,6 +88,7 @@ #include "macos_util.h" #include "rom_patches.h" #include "user_strings.h" +#include "thunks.h" #include "sheep_driver.h" @@ -116,31 +117,13 @@ const char KERNEL_AREA2_NAME[] = "Macint const char RAM_AREA_NAME[] = "Macintosh RAM"; const char ROM_AREA_NAME[] = "Macintosh ROM"; const char DR_CACHE_AREA_NAME[] = "Macintosh DR Cache"; - -const uint32 ROM_AREA_SIZE = 0x500000; // Size of ROM area - -const uint32 KERNEL_DATA_BASE = 0x68ffe000; // Address of Kernel Data -const uint32 KERNEL_DATA2_BASE = 0x5fffe000;// Alternate address of Kernel Data -const uint32 KERNEL_AREA_SIZE = 0x2000; // Size of Kernel Data area +const char SHEEP_AREA_NAME[] = "SheepShaver Virtual Stack"; const uint32 SIG_STACK_SIZE = 8192; // Size of signal stack const uint32 MSG_START = 'strt'; // Emulator start message -// Emulator Data -struct EmulatorData { - uint32 v[0x400]; -}; - - -// Kernel Data -struct KernelData { - uint32 v[0x400]; - EmulatorData ed; -}; - - // Application object class SheepShaver : public BApplication { public: @@ -237,6 +220,10 @@ system_info SysInfo; // System informati static void *sig_stack = NULL; // Stack for signal handlers static void *extra_stack = NULL; // Stack for SIGSEGV inside interrupt handler +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) +static area_id SheepMemArea; // SheepShaver data area ID // Prototypes @@ -372,6 +359,7 @@ 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); @@ -412,6 +400,14 @@ void SheepShaver::StartEmulator(void) } D(bug("Kernel Data 2 area %ld at %p\n", kernel_area2, kernel_data2)); + // Create area for SheepShaver data + if (!SheepMem::Init()) { + sprintf(str, GetString(STR_NO_SHEEP_MEM_AREA_ERR)); + ErrorAlert(str); + PostMessage(B_QUIT_REQUESTED); + return; + } + // Create area for Mac RAM RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary if (RAMSize < 8*1024*1024) { @@ -465,10 +461,10 @@ void SheepShaver::StartEmulator(void) XPRAMInit(); // Set boot volume - drive = PrefsFindInt32("bootdrive"); + i16 = PrefsFindInt32("bootdrive"); XPRAM[0x1378] = i16 >> 8; XPRAM[0x1379] = i16 & 0xff; - driver = PrefsFindInt32("bootdriver"); + i16 = PrefsFindInt32("bootdriver"); XPRAM[0x137a] = i16 >> 8; XPRAM[0x137b] = i16 & 0xff; @@ -481,6 +477,12 @@ void SheepShaver::StartEmulator(void) 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(); @@ -577,6 +579,7 @@ void SheepShaver::StartEmulator(void) 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 @@ -673,6 +676,12 @@ void SheepShaver::Quit(void) DiskExit(); SonyExit(); + // Delete thunks + ThunksExit(); + + // Delete SheepShaver globals + SheepMem::Exit(); + // Delete DR Cache area if (dr_cache_area >= 0) delete_area(dr_cache_area); @@ -1261,18 +1270,6 @@ void Execute68kTrap(uint16 trap, M68kReg /* - * Execute PPC code from EMUL_OP routine (real mode switch) - */ - -void ExecutePPC(void (*func)()) -{ - RoutineDescriptor desc = BUILD_PPC_ROUTINE_DESCRIPTOR(0, func); - M68kRegisters r; - Execute68k((uint32)&desc, &r); -} - - -/* * Quit emulator (must only be called from main thread) */ @@ -1327,7 +1324,7 @@ void MakeExecutable(int dummy, void *sta void PatchAfterStartup(void) { - ExecutePPC(VideoInstallAccel); + ExecuteNative(NATIVE_VIDEO_INSTALL_ACCEL); InstallExtFS(); } @@ -1336,7 +1333,7 @@ void PatchAfterStartup(void) * NVRAM watchdog thread (saves NVRAM every minute) */ -static status_t SheepShaver::nvram_func(void *arg) +status_t SheepShaver::nvram_func(void *arg) { SheepShaver *obj = (SheepShaver *)arg; @@ -1575,7 +1572,7 @@ void SheepShaver::sigusr1_handler(vregs if (InterruptFlags & INTFLAG_VIA) { ClearInterruptFlag(INTFLAG_VIA); ADBInterrupt(); - ExecutePPC(VideoVBL); + ExecuteNative(NATIVE_VIDEO_VBL); } } #endif @@ -2070,6 +2067,39 @@ rti: } +/* + * Helpers to share 32-bit addressable data with MacOS + */ + +bool SheepMem::Init(void) +{ + // Delete old area + area_id old_sheep_area = find_area(SHEEP_AREA_NAME); + if (old_sheep_area > 0) + delete_area(old_sheep_area); + + // Create area for SheepShaver data + 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; + + // Create read-only area with all bits set to 0 + static const uint8 const_zero_page[4096] = {0,}; + zero_page = const_zero_page; + + D(bug("SheepShaver area %ld at %p\n", SheepMemArea, base)); + top = base + size; + return true; +} + +void SheepMem::Exit(void) +{ + if (SheepMemArea >= 0) + delete_area(SheepMemArea); +} + + /* * Display error alert */