ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/BeOS/main_beos.cpp
(Generate patch)

Comparing SheepShaver/src/BeOS/main_beos.cpp (file contents):
Revision 1.1 by cebix, 2002-02-04T16:58:13Z vs.
Revision 1.19 by gbeauche, 2008-01-01T09:47:38Z

# Line 1 | Line 1
1   /*
2   *  main_beos.cpp - Emulation core, BeOS implementation
3   *
4 < *  SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
4 > *  SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
5   *
6   *  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
# Line 74 | Line 74
74   #include "xpram.h"
75   #include "timer.h"
76   #include "adb.h"
77 #include "sony.h"
78 #include "disk.h"
79 #include "cdrom.h"
80 #include "scsi.h"
77   #include "video.h"
82 #include "audio.h"
83 #include "ether.h"
84 #include "serial.h"
85 #include "clip.h"
86 #include "extfs.h"
78   #include "sys.h"
79   #include "macos_util.h"
80   #include "rom_patches.h"
# Line 116 | Line 107 | const char KERNEL_AREA2_NAME[] = "Macint
107   const char RAM_AREA_NAME[] = "Macintosh RAM";
108   const char ROM_AREA_NAME[] = "Macintosh ROM";
109   const char DR_CACHE_AREA_NAME[] = "Macintosh DR Cache";
110 <
111 < const uint32 ROM_AREA_SIZE = 0x500000;          // Size of ROM area
121 <
122 < const uint32 KERNEL_DATA_BASE = 0x68ffe000;     // Address of Kernel Data
123 < const uint32 KERNEL_DATA2_BASE = 0x5fffe000;// Alternate address of Kernel Data
124 < const uint32 KERNEL_AREA_SIZE = 0x2000;         // Size of Kernel Data area
110 > const char DR_EMULATOR_AREA_NAME[] = "Macintosh DR Emulator";
111 > const char SHEEP_AREA_NAME[] = "SheepShaver Virtual Stack";
112  
113   const uint32 SIG_STACK_SIZE = 8192;                     // Size of signal stack
114  
115   const uint32 MSG_START = 'strt';                        // Emulator start message
116  
117  
131 // Emulator Data
132 struct EmulatorData {
133        uint32 v[0x400];        
134 };
135
136
137 // Kernel Data
138 struct KernelData {
139        uint32 v[0x400];
140        EmulatorData ed;
141 };
142
143
118   // Application object
119   class SheepShaver : public BApplication {
120   public:
# Line 159 | Line 133 | public:
133                  // Initialize other variables
134                  sheep_fd = -1;
135                  emulator_data = NULL;
136 <                kernel_area = kernel_area2 = rom_area = ram_area = dr_cache_area = -1;
136 >                kernel_area = kernel_area2 = rom_area = ram_area = dr_cache_area = dr_emulator_area = -1;
137                  emul_thread = nvram_thread = tick_thread = -1;
138                  ReadyForSignals = false;
139                  AllowQuitting = true;
# Line 207 | Line 181 | private:
181          area_id rom_area;               // ROM area ID
182          area_id ram_area;               // RAM area ID
183          area_id dr_cache_area;  // DR Cache area ID
184 +        area_id dr_emulator_area;       // DR Emulator area ID
185  
186          struct sigaction sigusr1_action;        // Interrupt signal (of emulator thread)
187          struct sigaction sigsegv_action;        // Data access exception signal (of emulator thread)
# Line 230 | Line 205 | uint32 RAMSize;                        // Size of Mac RAM
205   uint32 KernelDataAddr;  // Address of Kernel Data
206   uint32 BootGlobsAddr;   // Address of BootGlobs structure at top of Mac RAM
207   uint32 DRCacheAddr;             // Address of DR Cache
208 + uint32 DREmulatorAddr;  // Address of DR Emulator
209   uint32 PVR;                             // Theoretical PVR
210   int64 CPUClockSpeed;    // Processor clock speed (Hz)
211   int64 BusClockSpeed;    // Bus clock speed (Hz)
212 + int64 TimebaseSpeed;    // Timebase clock speed (Hz)
213   system_info SysInfo;    // System information
214 + uint8 *RAMBaseHost;             // Base address of Mac RAM (host address space)
215 + uint8 *ROMBaseHost;             // Base address of Mac ROM (host address space)
216  
217   static void *sig_stack = NULL;          // Stack for signal handlers
218   static void *extra_stack = NULL;        // Stack for SIGSEGV inside interrupt handler
219 + uint32  SheepMem::page_size;            // Size of a native page
220 + uintptr SheepMem::zero_page = 0;        // Address of ro page filled in with zeros
221 + uintptr SheepMem::base;                         // Address of SheepShaver data
222 + uintptr SheepMem::proc;                         // Bottom address of SheepShave procedures
223 + uintptr SheepMem::data;                         // Top of SheepShaver data (stack like storage)
224 + static area_id SheepMemArea;            // SheepShaver data area ID
225  
226  
227   // Prototypes
# Line 308 | Line 293 | void SheepShaver::ReadyToRun(void)
293          }
294          CPUClockSpeed = SysInfo.cpu_clock_speed;
295          BusClockSpeed = SysInfo.bus_clock_speed;
296 +        TimebaseSpeed = BusClockSpeed / 4;
297  
298          // Delete old areas
299          area_id old_kernel_area = find_area(KERNEL_AREA_NAME);
# Line 325 | Line 311 | void SheepShaver::ReadyToRun(void)
311          area_id old_dr_cache_area = find_area(DR_CACHE_AREA_NAME);
312          if (old_dr_cache_area > 0)
313                  delete_area(old_dr_cache_area);
314 +        area_id old_dr_emulator_area = find_area(DR_EMULATOR_AREA_NAME);
315 +        if (old_dr_emulator_area > 0)
316 +                delete_area(old_dr_emulator_area);
317  
318          // Read preferences
319          int argc = 0;
# Line 412 | Line 401 | void SheepShaver::StartEmulator(void)
401          }
402          D(bug("Kernel Data 2 area %ld at %p\n", kernel_area2, kernel_data2));
403  
404 +        // Create area for SheepShaver data
405 +        if (!SheepMem::Init()) {
406 +                sprintf(str, GetString(STR_NO_SHEEP_MEM_AREA_ERR), strerror(SheepMemArea), SheepMemArea);
407 +                ErrorAlert(str);
408 +                PostMessage(B_QUIT_REQUESTED);
409 +                return;
410 +        }
411 +        
412          // Create area for Mac RAM
413          RAMSize = PrefsFindInt32("ramsize") & 0xfff00000;       // Round down to 1MB boundary
414          if (RAMSize < 8*1024*1024) {
# Line 427 | Line 424 | void SheepShaver::StartEmulator(void)
424                  PostMessage(B_QUIT_REQUESTED);
425                  return;
426          }
427 <        D(bug("RAM area %ld at %p\n", ram_area, RAMBase));
427 >        RAMBaseHost = (uint8 *)RAMBase
428 >        D(bug("RAM area %ld at %p\n", ram_area, RAMBaseHost));
429  
430          // Create area and load Mac ROM
431          try {
# Line 461 | Line 459 | void SheepShaver::StartEmulator(void)
459          }
460          D(bug("DR Cache area %ld at %p\n", dr_cache_area, DRCacheAddr));
461  
462 <        // Load NVRAM
463 <        XPRAMInit();
464 <
465 <        // Set boot volume
466 <        drive = PrefsFindInt32("bootdrive");
467 <        XPRAM[0x1378] = i16 >> 8;
470 <        XPRAM[0x1379] = i16 & 0xff;
471 <        driver = PrefsFindInt32("bootdriver");
472 <        XPRAM[0x137a] = i16 >> 8;
473 <        XPRAM[0x137b] = i16 & 0xff;
474 <
475 <        // Create BootGlobs at top of Mac memory
476 <        memset((void *)(RAMBase + RAMSize - 4096), 0, 4096);
477 <        BootGlobsAddr = RAMBase + RAMSize - 0x1c;
478 <        uint32 *boot_globs = (uint32 *)BootGlobsAddr;
479 <        boot_globs[-5] = htonl(RAMBase + RAMSize);              // MemTop
480 <        boot_globs[0] = htonl(RAMBase);                                 // First RAM bank
481 <        boot_globs[1] = htonl(RAMSize);
482 <        boot_globs[2] = htonl((uint32)-1);                              // End of bank table
483 <
484 <        // Init drivers
485 <        SonyInit();
486 <        DiskInit();
487 <        CDROMInit();
488 <        SCSIInit();
489 <
490 <        // Init external file system
491 <        ExtFSInit();
492 <
493 <        // Init audio
494 <        AudioInit();
495 <
496 <        // Init network
497 <        EtherInit();
498 <
499 <        // Init serial ports
500 <        SerialInit();
501 <
502 <        // Init Time Manager
503 <        TimerInit();
504 <
505 <        // Init clipboard
506 <        ClipInit();
507 <
508 <        // Init video
509 <        if (!VideoInit()) {
462 >        // Create area for DR Emulator
463 >        DREmulatorAddr = DR_EMULATOR_BASE;
464 >        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);
465 >        if (dr_emulator_area < 0) {
466 >                sprintf(str, GetString(STR_NO_KERNEL_DATA_ERR), strerror(dr_emulator_area), dr_emulator_area);
467 >                ErrorAlert(str);
468                  PostMessage(B_QUIT_REQUESTED);
469                  return;
470          }
471 +        D(bug("DR Emulator area %ld at %p\n", dr_emulator_area, DREmulatorAddr));
472  
473 <        // Install ROM patches
474 <        if (!PatchROM()) {
516 <                ErrorAlert(GetString(STR_UNSUPPORTED_ROM_TYPE_ERR));
473 >        // Initialize everything
474 >        if (!InitAll()) {
475                  PostMessage(B_QUIT_REQUESTED);
476                  return;
477          }
478 +        D(bug("Initialization complete\n"));
479  
480          // Clear caches (as we loaded and patched code) and write protect ROM
481   #if !EMULATED_PPC
482 <        clear_caches((void *)ROM_BASE, ROM_AREA_SIZE, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE);
482 >        clear_caches(ROMBaseHost, ROM_AREA_SIZE, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE);
483   #endif
484          set_area_protection(rom_area, B_READ_AREA);
485  
527        // Initialize Kernel Data
528        memset(kernel_data, 0, sizeof(KernelData));
529        if (ROMType == ROMTYPE_NEWWORLD) {
530                static uint32 of_dev_tree[4] = {0, 0, 0, 0};
531                static uint8 vector_lookup_tbl[128];
532                static uint8 vector_mask_tbl[64];
533                memset((uint8 *)kernel_data + 0xb80, 0x3d, 0x80);
534                memset(vector_lookup_tbl, 0, 128);
535                memset(vector_mask_tbl, 0, 64);
536                kernel_data->v[0xb80 >> 2] = htonl(ROM_BASE);
537                kernel_data->v[0xb84 >> 2] = htonl((uint32)of_dev_tree);        // OF device tree base
538                kernel_data->v[0xb90 >> 2] = htonl((uint32)vector_lookup_tbl);
539                kernel_data->v[0xb94 >> 2] = htonl((uint32)vector_mask_tbl);
540                kernel_data->v[0xb98 >> 2] = htonl(ROM_BASE);                           // OpenPIC base
541                kernel_data->v[0xbb0 >> 2] = htonl(0);                                          // ADB base
542                kernel_data->v[0xc20 >> 2] = htonl(RAMSize);
543                kernel_data->v[0xc24 >> 2] = htonl(RAMSize);
544                kernel_data->v[0xc30 >> 2] = htonl(RAMSize);
545                kernel_data->v[0xc34 >> 2] = htonl(RAMSize);
546                kernel_data->v[0xc38 >> 2] = htonl(0x00010020);
547                kernel_data->v[0xc3c >> 2] = htonl(0x00200001);
548                kernel_data->v[0xc40 >> 2] = htonl(0x00010000);
549                kernel_data->v[0xc50 >> 2] = htonl(RAMBase);
550                kernel_data->v[0xc54 >> 2] = htonl(RAMSize);
551                kernel_data->v[0xf60 >> 2] = htonl(PVR);
552                kernel_data->v[0xf64 >> 2] = htonl(CPUClockSpeed);
553                kernel_data->v[0xf68 >> 2] = htonl(BusClockSpeed);
554                kernel_data->v[0xf6c >> 2] = htonl(CPUClockSpeed);
555        } else {
556                kernel_data->v[0xc80 >> 2] = htonl(RAMSize);
557                kernel_data->v[0xc84 >> 2] = htonl(RAMSize);
558                kernel_data->v[0xc90 >> 2] = htonl(RAMSize);
559                kernel_data->v[0xc94 >> 2] = htonl(RAMSize);
560                kernel_data->v[0xc98 >> 2] = htonl(0x00010020);
561                kernel_data->v[0xc9c >> 2] = htonl(0x00200001);
562                kernel_data->v[0xca0 >> 2] = htonl(0x00010000);
563                kernel_data->v[0xcb0 >> 2] = htonl(RAMBase);
564                kernel_data->v[0xcb4 >> 2] = htonl(RAMSize);
565                kernel_data->v[0xf80 >> 2] = htonl(PVR);
566                kernel_data->v[0xf84 >> 2] = htonl(CPUClockSpeed);
567                kernel_data->v[0xf88 >> 2] = htonl(BusClockSpeed);
568                kernel_data->v[0xf8c >> 2] = htonl(CPUClockSpeed);
569        }
570
486          // Initialize extra low memory
487 <        D(bug("Initializing Low Memory...\n"));
573 <        memset(NULL, 0, 0x3000);
574 <        WriteMacInt32(XLM_SIGNATURE, 'Baah');                                                   // Signature to detect SheepShaver
575 <        WriteMacInt32(XLM_KERNEL_DATA, (uint32)kernel_data);                    // For trap replacement routines
487 >        D(bug("Initializing extra Low Memory...\n"));
488          WriteMacInt32(XLM_SHEEP_OBJ, (uint32)this);                                             // Pointer to SheepShaver object
489 <        WriteMacInt32(XLM_PVR, PVR);                                                                    // Theoretical PVR
578 <        WriteMacInt32(XLM_BUS_CLOCK, BusClockSpeed);                                    // For DriverServicesLib patch
579 <        WriteMacInt16(XLM_EXEC_RETURN_OPCODE, M68K_EXEC_RETURN);                // For Execute68k() (RTS from the executed 68k code will jump here and end 68k mode)
580 < #if !EMULATED_PPC
581 <        WriteMacInt32(XLM_TOC, (uint32)TOC);                                                    // TOC pointer of emulator
582 <        WriteMacInt32(XLM_ETHER_INIT, *(uint32 *)InitStreamModule);             // DLPI ethernet driver functions
583 <        WriteMacInt32(XLM_ETHER_TERM, *(uint32 *)TerminateStreamModule);
584 <        WriteMacInt32(XLM_ETHER_OPEN, *(uint32 *)ether_open);
585 <        WriteMacInt32(XLM_ETHER_CLOSE, *(uint32 *)ether_close);
586 <        WriteMacInt32(XLM_ETHER_WPUT, *(uint32 *)ether_wput);
587 <        WriteMacInt32(XLM_ETHER_RSRV, *(uint32 *)ether_rsrv);
588 <        WriteMacInt32(XLM_VIDEO_DOIO, *(uint32 *)VideoDoDriverIO);
589 < #endif
590 <        D(bug("Low Memory initialized\n"));
489 >        D(bug("Extra Low Memory initialized\n"));
490  
491          // Disallow quitting with Alt-Q from now on
492          AllowQuitting = false;
# Line 643 | Line 542 | void SheepShaver::Quit(void)
542          if (emul_thread > 0)
543                  wait_for_thread(emul_thread, &l);
544  
545 <        // Save NVRAM
546 <        XPRAMExit();
648 <
649 <        // Exit clipboard
650 <        ClipExit();
651 <
652 <        // Exit Time Manager
653 <        TimerExit();
654 <
655 <        // Exit serial
656 <        SerialExit();
657 <
658 <        // Exit network
659 <        EtherExit();
545 >        // Deinitialize everything
546 >        ExitAll();
547  
548 <        // Exit audio
549 <        AudioExit();
548 >        // Delete SheepShaver globals
549 >        SheepMem::Exit();
550  
551 <        // Exit video
552 <        VideoExit();
553 <
667 <        // Exit external file system
668 <        ExtFSExit();
669 <
670 <        // Exit drivers
671 <        SCSIExit();
672 <        CDROMExit();
673 <        DiskExit();
674 <        SonyExit();
551 >        // Delete DR Emulator area
552 >        if (dr_emulator_area >= 0)
553 >                delete_area(dr_emulator_area);
554  
555          // Delete DR Cache area
556          if (dr_cache_area >= 0)
# Line 717 | Line 596 | void SheepShaver::Quit(void)
596  
597   void SheepShaver::init_rom(void)
598   {
599 +        // Size of a native page
600 +        page_size = B_PAGE_SIZE;
601 +
602          // Create area for ROM
603 <        void *rom_addr = (void *)ROM_BASE;
604 <        rom_area = create_area(ROM_AREA_NAME, &rom_addr, B_EXACT_ADDRESS, ROM_AREA_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
603 >        ROMBaseHost = (uint8 *)ROM_BASE;
604 >        rom_area = create_area(ROM_AREA_NAME, (void **)&ROMBaseHost, B_EXACT_ADDRESS, ROM_AREA_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
605          if (rom_area < 0)
606                  throw area_error();
607          D(bug("ROM area %ld at %p\n", rom_area, rom_addr));
# Line 736 | Line 618 | void SheepShaver::init_rom(void)
618   *  file_read_error: Cannot read ROM file
619   */
620  
739 // Decode LZSS data
740 static void decode_lzss(const uint8 *src, uint8 *dest, int size)
741 {
742        char dict[0x1000];
743        int run_mask = 0, dict_idx = 0xfee;
744        for (;;) {
745                if (run_mask < 0x100) {
746                        // Start new run
747                        if (--size < 0)
748                                break;
749                        run_mask = *src++ | 0xff00;
750                }
751                bool bit = run_mask & 1;
752                run_mask >>= 1;
753                if (bit) {
754                        // Verbatim copy
755                        if (--size < 0)
756                                break;
757                        int c = *src++;
758                        dict[dict_idx++] = c;
759                        *dest++ = c;
760                        dict_idx &= 0xfff;
761                } else {
762                        // Copy from dictionary
763                        if (--size < 0)
764                                break;
765                        int idx = *src++;
766                        if (--size < 0)
767                                break;
768                        int cnt = *src++;
769                        idx |= (cnt << 4) & 0xf00;
770                        cnt = (cnt & 0x0f) + 3;
771                        while (cnt--) {
772                                char c = dict[idx++];
773                                dict[dict_idx++] = c;
774                                *dest++ = c;
775                                idx &= 0xfff;
776                                dict_idx &= 0xfff;
777                        }
778                }
779        }
780 }
781
621   void SheepShaver::load_rom(void)
622   {
623          // Get rom file path from preferences
# Line 807 | Line 646 | void SheepShaver::load_rom(void)
646  
647          uint8 *rom = new uint8[ROM_SIZE];       // Reading directly into the area doesn't work
648          ssize_t actual = file.Read((void *)rom, ROM_SIZE);
649 <        if (actual == ROM_SIZE) {
650 <                // Plain ROM image
651 <                memcpy((void *)ROM_BASE, rom, ROM_SIZE);
652 <                delete[] rom;
814 <        } else {
815 <                if (strncmp((char *)rom, "<CHRP-BOOT>", 11) == 0) {
816 <                        // CHRP compressed ROM image
817 <                        D(bug("CHRP ROM image\n"));
818 <                        uint32 lzss_offset, lzss_size;
819 <
820 <                        char *s = strstr((char *)rom, "constant lzss-offset");
821 <                        if (s == NULL)
822 <                                throw rom_size_error();
823 <                        s -= 7;
824 <                        if (sscanf(s, "%06lx", &lzss_offset) != 1)
825 <                                throw rom_size_error();
826 <                        s = strstr((char *)rom, "constant lzss-size");
827 <                        if (s == NULL)
828 <                                throw rom_size_error();
829 <                        s -= 7;
830 <                        if (sscanf(s, "%06lx", &lzss_size) != 1)
831 <                                throw rom_size_error();
832 <                        D(bug("Offset of compressed data: %08lx\n", lzss_offset));
833 <                        D(bug("Size of compressed data: %08lx\n", lzss_size));
834 <
835 <                        D(bug("Uncompressing ROM...\n"));
836 <                        decode_lzss(rom + lzss_offset, (uint8 *)ROM_BASE, lzss_size);
837 <                        delete[] rom;
838 <                } else if (rom_size != 4*1024*1024)
649 >        
650 >        // Decode Mac ROM
651 >        if (!DecodeROM(rom, actual)) {
652 >                if (rom_size != 4*1024*1024)
653                          throw rom_size_error();
654                  else
655                          throw file_read_error();
656          }
657 +        delete[] rom;
658   }
659  
660  
# Line 1328 | Line 1143 | void Execute68kTrap(uint16 trap, M68kReg
1143  
1144  
1145   /*
1331 *  Execute PPC code from EMUL_OP routine (real mode switch)
1332 */
1333
1334 void ExecutePPC(void (*func)())
1335 {
1336        RoutineDescriptor desc = BUILD_PPC_ROUTINE_DESCRIPTOR(0, func);
1337        M68kRegisters r;
1338        Execute68k((uint32)&desc, &r);
1339 }
1340
1341
1342 /*
1146   *  Quit emulator (must only be called from main thread)
1147   */
1148  
# Line 1380 | Line 1183 | void Dump68kRegs(M68kRegisters *r)
1183   *  Make code executable
1184   */
1185  
1186 < void MakeExecutable(int dummy, void *start, uint32 length)
1186 > void MakeExecutable(int dummy, uint32 start, uint32 length)
1187   {
1188 <        if (((uint32)start >= ROM_BASE) && ((uint32)start < (ROM_BASE + ROM_SIZE)))
1188 >        if ((start >= ROM_BASE) && (start < (ROM_BASE + ROM_SIZE)))
1189                  return;
1190 <        clear_caches(start, length, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE);
1388 < }
1389 <
1390 <
1391 < /*
1392 < *  Patch things after system startup (gets called by disk driver accRun routine)
1393 < */
1394 <
1395 < void PatchAfterStartup(void)
1396 < {
1397 <        ExecutePPC(VideoInstallAccel);
1398 <        InstallExtFS();
1190 >        clear_caches((void *)start, length, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE);
1191   }
1192  
1193  
# Line 1403 | Line 1195 | void PatchAfterStartup(void)
1195   *  NVRAM watchdog thread (saves NVRAM every minute)
1196   */
1197  
1198 < static status_t SheepShaver::nvram_func(void *arg)
1198 > status_t SheepShaver::nvram_func(void *arg)
1199   {
1200          SheepShaver *obj = (SheepShaver *)arg;
1201  
# Line 1456 | Line 1248 | status_t SheepShaver::tick_func(void *ar
1248  
1249   void TriggerInterrupt(void)
1250   {
1251 +        idle_resume();
1252   #if 0
1253          WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
1254   #else
# Line 1642 | Line 1435 | void SheepShaver::sigusr1_handler(vregs
1435                                          if (InterruptFlags & INTFLAG_VIA) {
1436                                                  ClearInterruptFlag(INTFLAG_VIA);
1437                                                  ADBInterrupt();
1438 <                                                ExecutePPC(VideoVBL);
1438 >                                                ExecuteNative(NATIVE_VIDEO_VBL);
1439                                          }
1440                                  }
1441   #endif
# Line 2137 | Line 1930 | rti:
1930   }
1931  
1932  
1933 + /*
1934 + *  Helpers to share 32-bit addressable data with MacOS
1935 + */
1936 +
1937 + bool SheepMem::Init(void)
1938 + {
1939 +        // Delete old area
1940 +        area_id old_sheep_area = find_area(SHEEP_AREA_NAME);
1941 +        if (old_sheep_area > 0)
1942 +                delete_area(old_sheep_area);
1943 +
1944 +        // Create area for SheepShaver data
1945 +        proc = base = 0x60000000;
1946 +        SheepMemArea = create_area(SHEEP_AREA_NAME, (void **)&base, B_BASE_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
1947 +        if (SheepMemArea < 0)
1948 +                return false;
1949 +
1950 +        // Create read-only area with all bits set to 0
1951 +        static const uint8 const_zero_page[4096] = {0,};
1952 +        zero_page = const_zero_page;
1953 +
1954 +        D(bug("SheepShaver area %ld at %p\n", SheepMemArea, base));
1955 +        data = base + size;
1956 +        return true;
1957 + }
1958 +
1959 + void SheepMem::Exit(void)
1960 + {
1961 +        if (SheepMemArea >= 0)
1962 +                delete_area(SheepMemArea);
1963 + }
1964 +
1965 +
1966   /*
1967   *  Display error alert
1968   */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines