105 |
|
#include "xpram.h" |
106 |
|
#include "timer.h" |
107 |
|
#include "adb.h" |
108 |
– |
#include "sony.h" |
109 |
– |
#include "disk.h" |
110 |
– |
#include "cdrom.h" |
111 |
– |
#include "scsi.h" |
108 |
|
#include "video.h" |
113 |
– |
#include "audio.h" |
114 |
– |
#include "ether.h" |
115 |
– |
#include "serial.h" |
116 |
– |
#include "clip.h" |
117 |
– |
#include "extfs.h" |
109 |
|
#include "sys.h" |
110 |
|
#include "macos_util.h" |
111 |
|
#include "rom_patches.h" |
112 |
|
#include "user_strings.h" |
113 |
|
#include "vm_alloc.h" |
114 |
|
#include "sigsegv.h" |
124 |
– |
#include "thunks.h" |
115 |
|
|
116 |
|
#define DEBUG 0 |
117 |
|
#include "debug.h" |
325 |
|
uint32 SheepMem::page_size; // Size of a native page |
326 |
|
uintptr SheepMem::zero_page = 0; // Address of ro page filled in with zeros |
327 |
|
uintptr SheepMem::base = 0x60000000; // Address of SheepShaver data |
328 |
< |
uintptr SheepMem::top = 0; // Top of SheepShaver data (stack like storage) |
328 |
> |
uintptr SheepMem::proc; // Bottom address of SheepShave procedures |
329 |
> |
uintptr SheepMem::data; // Top of SheepShaver data (stack like storage) |
330 |
|
|
331 |
|
|
332 |
|
// Prototypes |
333 |
+ |
static bool kernel_data_init(void); |
334 |
+ |
static void kernel_data_exit(void); |
335 |
|
static void Quit(void); |
336 |
|
static void *emul_func(void *arg); |
337 |
|
static void *nvram_func(void *arg); |
416 |
|
|
417 |
|
|
418 |
|
/* |
419 |
+ |
* Memory management helpers |
420 |
+ |
*/ |
421 |
+ |
|
422 |
+ |
static inline int vm_mac_acquire(uint32 addr, uint32 size) |
423 |
+ |
{ |
424 |
+ |
return vm_acquire_fixed(Mac2HostAddr(addr), size); |
425 |
+ |
} |
426 |
+ |
|
427 |
+ |
static inline int vm_mac_release(uint32 addr, uint32 size) |
428 |
+ |
{ |
429 |
+ |
return vm_release(Mac2HostAddr(addr), size); |
430 |
+ |
} |
431 |
+ |
|
432 |
+ |
|
433 |
+ |
/* |
434 |
|
* Main program |
435 |
|
*/ |
436 |
|
|
446 |
|
int main(int argc, char **argv) |
447 |
|
{ |
448 |
|
char str[256]; |
441 |
– |
int16 i16; |
449 |
|
int rom_fd; |
450 |
|
FILE *proc_file; |
451 |
|
const char *rom_path; |
776 |
|
|
777 |
|
#ifndef PAGEZERO_HACK |
778 |
|
// Create Low Memory area (0x0000..0x3000) |
779 |
< |
if (vm_acquire_fixed((char *)NATMEM_OFFSET, 0x3000) < 0) { |
779 |
> |
if (vm_mac_acquire(0, 0x3000) < 0) { |
780 |
|
sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno)); |
781 |
|
ErrorAlert(str); |
782 |
|
goto quit; |
785 |
|
#endif |
786 |
|
|
787 |
|
// Create areas for Kernel Data |
788 |
< |
kernel_area = shmget(IPC_PRIVATE, KERNEL_AREA_SIZE, 0600); |
782 |
< |
if (kernel_area == -1) { |
783 |
< |
sprintf(str, GetString(STR_KD_SHMGET_ERR), strerror(errno)); |
784 |
< |
ErrorAlert(str); |
788 |
> |
if (!kernel_data_init()) |
789 |
|
goto quit; |
790 |
< |
} |
787 |
< |
if (shmat(kernel_area, (void *)(KERNEL_DATA_BASE + NATMEM_OFFSET), 0) < 0) { |
788 |
< |
sprintf(str, GetString(STR_KD_SHMAT_ERR), strerror(errno)); |
789 |
< |
ErrorAlert(str); |
790 |
< |
goto quit; |
791 |
< |
} |
792 |
< |
if (shmat(kernel_area, (void *)(KERNEL_DATA2_BASE + NATMEM_OFFSET), 0) < 0) { |
793 |
< |
sprintf(str, GetString(STR_KD2_SHMAT_ERR), strerror(errno)); |
794 |
< |
ErrorAlert(str); |
795 |
< |
goto quit; |
796 |
< |
} |
797 |
< |
kernel_data = (KernelData *)(KERNEL_DATA_BASE + NATMEM_OFFSET); |
790 |
> |
kernel_data = (KernelData *)Mac2HostAddr(KERNEL_DATA_BASE); |
791 |
|
emulator_data = &kernel_data->ed; |
792 |
|
KernelDataAddr = KERNEL_DATA_BASE; |
793 |
|
D(bug("Kernel Data at %p (%08x)\n", kernel_data, KERNEL_DATA_BASE)); |
794 |
|
D(bug("Emulator Data at %p (%08x)\n", emulator_data, KERNEL_DATA_BASE + offsetof(KernelData, ed))); |
795 |
|
|
796 |
|
// Create area for DR Cache |
797 |
< |
if (vm_acquire_fixed((void *)(DR_EMULATOR_BASE + NATMEM_OFFSET), DR_EMULATOR_SIZE) < 0) { |
797 |
> |
if (vm_mac_acquire(DR_EMULATOR_BASE, DR_EMULATOR_SIZE) < 0) { |
798 |
|
sprintf(str, GetString(STR_DR_EMULATOR_MMAP_ERR), strerror(errno)); |
799 |
|
ErrorAlert(str); |
800 |
|
goto quit; |
801 |
|
} |
802 |
|
dr_emulator_area_mapped = true; |
803 |
< |
if (vm_acquire_fixed((void *)(DR_CACHE_BASE + NATMEM_OFFSET), DR_CACHE_SIZE) < 0) { |
803 |
> |
if (vm_mac_acquire(DR_CACHE_BASE, DR_CACHE_SIZE) < 0) { |
804 |
|
sprintf(str, GetString(STR_DR_CACHE_MMAP_ERR), strerror(errno)); |
805 |
|
ErrorAlert(str); |
806 |
|
goto quit; |
824 |
|
} |
825 |
|
|
826 |
|
// Create area for Mac ROM |
827 |
< |
ROMBaseHost = (uint8 *)(ROM_BASE + NATMEM_OFFSET); |
835 |
< |
if (vm_acquire_fixed(ROMBaseHost, ROM_AREA_SIZE) < 0) { |
827 |
> |
if (vm_mac_acquire(ROM_BASE, ROM_AREA_SIZE) < 0) { |
828 |
|
sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno)); |
829 |
|
ErrorAlert(str); |
830 |
|
goto quit; |
831 |
|
} |
832 |
+ |
ROMBaseHost = Mac2HostAddr(ROM_BASE); |
833 |
|
#if !EMULATED_PPC |
834 |
|
if (vm_protect(ROMBaseHost, ROM_AREA_SIZE, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) { |
835 |
|
sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno)); |
847 |
|
RAMSize = 8*1024*1024; |
848 |
|
} |
849 |
|
|
850 |
< |
RAMBaseHost = (uint8 *)(RAM_BASE + NATMEM_OFFSET); |
858 |
< |
if (vm_acquire_fixed(RAMBaseHost, RAMSize) < 0) { |
850 |
> |
if (vm_mac_acquire(RAM_BASE, RAMSize) < 0) { |
851 |
|
sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno)); |
852 |
|
ErrorAlert(str); |
853 |
|
goto quit; |
854 |
|
} |
855 |
+ |
RAMBaseHost = Mac2HostAddr(RAM_BASE); |
856 |
|
#if !EMULATED_PPC |
857 |
|
if (vm_protect(RAMBaseHost, RAMSize, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) { |
858 |
|
sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno)); |
898 |
|
} |
899 |
|
delete[] rom_tmp; |
900 |
|
|
901 |
< |
// Load NVRAM |
902 |
< |
XPRAMInit(); |
910 |
< |
|
911 |
< |
// Load XPRAM default values if signature not found |
912 |
< |
if (XPRAM[0x130c] != 0x4e || XPRAM[0x130d] != 0x75 |
913 |
< |
|| XPRAM[0x130e] != 0x4d || XPRAM[0x130f] != 0x63) { |
914 |
< |
D(bug("Loading XPRAM default values\n")); |
915 |
< |
memset(XPRAM + 0x1300, 0, 0x100); |
916 |
< |
XPRAM[0x130c] = 0x4e; // "NuMc" signature |
917 |
< |
XPRAM[0x130d] = 0x75; |
918 |
< |
XPRAM[0x130e] = 0x4d; |
919 |
< |
XPRAM[0x130f] = 0x63; |
920 |
< |
XPRAM[0x1301] = 0x80; // InternalWaitFlags = DynWait (don't wait for SCSI devices upon bootup) |
921 |
< |
XPRAM[0x1310] = 0xa8; // Standard PRAM values |
922 |
< |
XPRAM[0x1311] = 0x00; |
923 |
< |
XPRAM[0x1312] = 0x00; |
924 |
< |
XPRAM[0x1313] = 0x22; |
925 |
< |
XPRAM[0x1314] = 0xcc; |
926 |
< |
XPRAM[0x1315] = 0x0a; |
927 |
< |
XPRAM[0x1316] = 0xcc; |
928 |
< |
XPRAM[0x1317] = 0x0a; |
929 |
< |
XPRAM[0x131c] = 0x00; |
930 |
< |
XPRAM[0x131d] = 0x02; |
931 |
< |
XPRAM[0x131e] = 0x63; |
932 |
< |
XPRAM[0x131f] = 0x00; |
933 |
< |
XPRAM[0x1308] = 0x13; |
934 |
< |
XPRAM[0x1309] = 0x88; |
935 |
< |
XPRAM[0x130a] = 0x00; |
936 |
< |
XPRAM[0x130b] = 0xcc; |
937 |
< |
XPRAM[0x1376] = 0x00; // OSDefault = MacOS |
938 |
< |
XPRAM[0x1377] = 0x01; |
939 |
< |
} |
940 |
< |
|
941 |
< |
// Set boot volume |
942 |
< |
i16 = PrefsFindInt32("bootdrive"); |
943 |
< |
XPRAM[0x1378] = i16 >> 8; |
944 |
< |
XPRAM[0x1379] = i16 & 0xff; |
945 |
< |
i16 = PrefsFindInt32("bootdriver"); |
946 |
< |
XPRAM[0x137a] = i16 >> 8; |
947 |
< |
XPRAM[0x137b] = i16 & 0xff; |
948 |
< |
|
949 |
< |
// Create BootGlobs at top of Mac memory |
950 |
< |
memset(RAMBaseHost + RAMSize - 4096, 0, 4096); |
951 |
< |
BootGlobsAddr = RAMBase + RAMSize - 0x1c; |
952 |
< |
WriteMacInt32(BootGlobsAddr - 5 * 4, RAMBase + RAMSize); // MemTop |
953 |
< |
WriteMacInt32(BootGlobsAddr + 0 * 4, RAMBase); // First RAM bank |
954 |
< |
WriteMacInt32(BootGlobsAddr + 1 * 4, RAMSize); |
955 |
< |
WriteMacInt32(BootGlobsAddr + 2 * 4, (uint32)-1); // End of bank table |
956 |
< |
|
957 |
< |
// Init thunks |
958 |
< |
if (!ThunksInit()) |
959 |
< |
goto quit; |
960 |
< |
|
961 |
< |
// Init drivers |
962 |
< |
SonyInit(); |
963 |
< |
DiskInit(); |
964 |
< |
CDROMInit(); |
965 |
< |
SCSIInit(); |
966 |
< |
|
967 |
< |
// Init external file system |
968 |
< |
ExtFSInit(); |
969 |
< |
|
970 |
< |
// Init ADB |
971 |
< |
ADBInit(); |
972 |
< |
|
973 |
< |
// Init audio |
974 |
< |
AudioInit(); |
975 |
< |
|
976 |
< |
// Init network |
977 |
< |
EtherInit(); |
978 |
< |
|
979 |
< |
// Init serial ports |
980 |
< |
SerialInit(); |
981 |
< |
|
982 |
< |
// Init Time Manager |
983 |
< |
TimerInit(); |
984 |
< |
|
985 |
< |
// Init clipboard |
986 |
< |
ClipInit(); |
987 |
< |
|
988 |
< |
// Init video |
989 |
< |
if (!VideoInit()) |
990 |
< |
goto quit; |
991 |
< |
|
992 |
< |
// Install ROM patches |
993 |
< |
if (!PatchROM()) { |
994 |
< |
ErrorAlert(GetString(STR_UNSUPPORTED_ROM_TYPE_ERR)); |
901 |
> |
// Initialize everything |
902 |
> |
if (!InitAll()) |
903 |
|
goto quit; |
904 |
< |
} |
904 |
> |
D(bug("Initialization complete\n")); |
905 |
|
|
906 |
|
// Clear caches (as we loaded and patched code) and write protect ROM |
907 |
|
#if !EMULATED_PPC |
909 |
|
#endif |
910 |
|
vm_protect(ROMBaseHost, ROM_AREA_SIZE, VM_PAGE_READ | VM_PAGE_EXECUTE); |
911 |
|
|
1004 |
– |
// Initialize Kernel Data |
1005 |
– |
memset(kernel_data, 0, sizeof(KernelData)); |
1006 |
– |
if (ROMType == ROMTYPE_NEWWORLD) { |
1007 |
– |
uint32 of_dev_tree = SheepMem::Reserve(4 * sizeof(uint32)); |
1008 |
– |
Mac_memset(of_dev_tree, 0, 4 * sizeof(uint32)); |
1009 |
– |
uint32 vector_lookup_tbl = SheepMem::Reserve(128); |
1010 |
– |
uint32 vector_mask_tbl = SheepMem::Reserve(64); |
1011 |
– |
memset((uint8 *)kernel_data + 0xb80, 0x3d, 0x80); |
1012 |
– |
Mac_memset(vector_lookup_tbl, 0, 128); |
1013 |
– |
Mac_memset(vector_mask_tbl, 0, 64); |
1014 |
– |
kernel_data->v[0xb80 >> 2] = htonl(ROM_BASE); |
1015 |
– |
kernel_data->v[0xb84 >> 2] = htonl(of_dev_tree); // OF device tree base |
1016 |
– |
kernel_data->v[0xb90 >> 2] = htonl(vector_lookup_tbl); |
1017 |
– |
kernel_data->v[0xb94 >> 2] = htonl(vector_mask_tbl); |
1018 |
– |
kernel_data->v[0xb98 >> 2] = htonl(ROM_BASE); // OpenPIC base |
1019 |
– |
kernel_data->v[0xbb0 >> 2] = htonl(0); // ADB base |
1020 |
– |
kernel_data->v[0xc20 >> 2] = htonl(RAMSize); |
1021 |
– |
kernel_data->v[0xc24 >> 2] = htonl(RAMSize); |
1022 |
– |
kernel_data->v[0xc30 >> 2] = htonl(RAMSize); |
1023 |
– |
kernel_data->v[0xc34 >> 2] = htonl(RAMSize); |
1024 |
– |
kernel_data->v[0xc38 >> 2] = htonl(0x00010020); |
1025 |
– |
kernel_data->v[0xc3c >> 2] = htonl(0x00200001); |
1026 |
– |
kernel_data->v[0xc40 >> 2] = htonl(0x00010000); |
1027 |
– |
kernel_data->v[0xc50 >> 2] = htonl(RAMBase); |
1028 |
– |
kernel_data->v[0xc54 >> 2] = htonl(RAMSize); |
1029 |
– |
kernel_data->v[0xf60 >> 2] = htonl(PVR); |
1030 |
– |
kernel_data->v[0xf64 >> 2] = htonl(CPUClockSpeed); // clock-frequency |
1031 |
– |
kernel_data->v[0xf68 >> 2] = htonl(BusClockSpeed); // bus-frequency |
1032 |
– |
kernel_data->v[0xf6c >> 2] = htonl(TimebaseSpeed); // timebase-frequency |
1033 |
– |
} else { |
1034 |
– |
kernel_data->v[0xc80 >> 2] = htonl(RAMSize); |
1035 |
– |
kernel_data->v[0xc84 >> 2] = htonl(RAMSize); |
1036 |
– |
kernel_data->v[0xc90 >> 2] = htonl(RAMSize); |
1037 |
– |
kernel_data->v[0xc94 >> 2] = htonl(RAMSize); |
1038 |
– |
kernel_data->v[0xc98 >> 2] = htonl(0x00010020); |
1039 |
– |
kernel_data->v[0xc9c >> 2] = htonl(0x00200001); |
1040 |
– |
kernel_data->v[0xca0 >> 2] = htonl(0x00010000); |
1041 |
– |
kernel_data->v[0xcb0 >> 2] = htonl(RAMBase); |
1042 |
– |
kernel_data->v[0xcb4 >> 2] = htonl(RAMSize); |
1043 |
– |
kernel_data->v[0xf80 >> 2] = htonl(PVR); |
1044 |
– |
kernel_data->v[0xf84 >> 2] = htonl(CPUClockSpeed); // clock-frequency |
1045 |
– |
kernel_data->v[0xf88 >> 2] = htonl(BusClockSpeed); // bus-frequency |
1046 |
– |
kernel_data->v[0xf8c >> 2] = htonl(TimebaseSpeed); // timebase-frequency |
1047 |
– |
} |
1048 |
– |
|
1049 |
– |
// Initialize extra low memory |
1050 |
– |
D(bug("Initializing Low Memory...\n")); |
1051 |
– |
Mac_memset(0, 0, 0x3000); |
1052 |
– |
WriteMacInt32(XLM_SIGNATURE, FOURCC('B','a','a','h')); // Signature to detect SheepShaver |
1053 |
– |
WriteMacInt32(XLM_KERNEL_DATA, KernelDataAddr); // For trap replacement routines |
1054 |
– |
WriteMacInt32(XLM_PVR, PVR); // Theoretical PVR |
1055 |
– |
WriteMacInt32(XLM_BUS_CLOCK, BusClockSpeed); // For DriverServicesLib patch |
1056 |
– |
WriteMacInt16(XLM_EXEC_RETURN_OPCODE, M68K_EXEC_RETURN); // For Execute68k() (RTS from the executed 68k code will jump here and end 68k mode) |
1057 |
– |
WriteMacInt32(XLM_ZERO_PAGE, SheepMem::ZeroPage()); // Pointer to read-only page with all bits set to 0 |
1058 |
– |
#if !EMULATED_PPC |
1059 |
– |
WriteMacInt32(XLM_TOC, (uint32)TOC); // TOC pointer of emulator |
1060 |
– |
#endif |
1061 |
– |
WriteMacInt32(XLM_ETHER_INIT, NativeFunction(NATIVE_ETHER_INIT)); // DLPI ethernet driver functions |
1062 |
– |
WriteMacInt32(XLM_ETHER_TERM, NativeFunction(NATIVE_ETHER_TERM)); |
1063 |
– |
WriteMacInt32(XLM_ETHER_OPEN, NativeFunction(NATIVE_ETHER_OPEN)); |
1064 |
– |
WriteMacInt32(XLM_ETHER_CLOSE, NativeFunction(NATIVE_ETHER_CLOSE)); |
1065 |
– |
WriteMacInt32(XLM_ETHER_WPUT, NativeFunction(NATIVE_ETHER_WPUT)); |
1066 |
– |
WriteMacInt32(XLM_ETHER_RSRV, NativeFunction(NATIVE_ETHER_RSRV)); |
1067 |
– |
WriteMacInt32(XLM_VIDEO_DOIO, NativeFunction(NATIVE_VIDEO_DO_DRIVER_IO)); |
1068 |
– |
D(bug("Low Memory initialized\n")); |
1069 |
– |
|
912 |
|
// Start 60Hz thread |
913 |
|
tick_thread_cancel = false; |
914 |
|
tick_thread_active = (pthread_create(&tick_thread, NULL, tick_func, NULL) == 0); |
1009 |
|
} |
1010 |
|
#endif |
1011 |
|
|
1012 |
< |
// Save NVRAM |
1013 |
< |
XPRAMExit(); |
1172 |
< |
|
1173 |
< |
// Exit clipboard |
1174 |
< |
ClipExit(); |
1175 |
< |
|
1176 |
< |
// Exit Time Manager |
1177 |
< |
TimerExit(); |
1178 |
< |
|
1179 |
< |
// Exit serial |
1180 |
< |
SerialExit(); |
1181 |
< |
|
1182 |
< |
// Exit network |
1183 |
< |
EtherExit(); |
1184 |
< |
|
1185 |
< |
// Exit audio |
1186 |
< |
AudioExit(); |
1187 |
< |
|
1188 |
< |
// Exit ADB |
1189 |
< |
ADBExit(); |
1190 |
< |
|
1191 |
< |
// Exit video |
1192 |
< |
VideoExit(); |
1193 |
< |
|
1194 |
< |
// Exit external file system |
1195 |
< |
ExtFSExit(); |
1196 |
< |
|
1197 |
< |
// Exit drivers |
1198 |
< |
SCSIExit(); |
1199 |
< |
CDROMExit(); |
1200 |
< |
DiskExit(); |
1201 |
< |
SonyExit(); |
1202 |
< |
|
1203 |
< |
// Delete thunks |
1204 |
< |
ThunksExit(); |
1012 |
> |
// Deinitialize everything |
1013 |
> |
ExitAll(); |
1014 |
|
|
1015 |
|
// Delete SheepShaver globals |
1016 |
|
SheepMem::Exit(); |
1017 |
|
|
1018 |
|
// Delete RAM area |
1019 |
|
if (ram_area_mapped) |
1020 |
< |
vm_release(RAMBaseHost, RAMSize); |
1020 |
> |
vm_mac_release(RAM_BASE, RAMSize); |
1021 |
|
|
1022 |
|
// Delete ROM area |
1023 |
|
if (rom_area_mapped) |
1024 |
< |
vm_release(ROMBaseHost, ROM_AREA_SIZE); |
1024 |
> |
vm_mac_release(ROM_BASE, ROM_AREA_SIZE); |
1025 |
|
|
1026 |
|
// Delete DR cache areas |
1027 |
|
if (dr_emulator_area_mapped) |
1028 |
< |
vm_release((void *)(DR_EMULATOR_BASE + NATMEM_OFFSET), DR_EMULATOR_SIZE); |
1028 |
> |
vm_mac_release(DR_EMULATOR_BASE, DR_EMULATOR_SIZE); |
1029 |
|
if (dr_cache_area_mapped) |
1030 |
< |
vm_release((void *)(DR_CACHE_BASE + NATMEM_OFFSET), DR_CACHE_SIZE); |
1030 |
> |
vm_mac_release(DR_CACHE_BASE, DR_CACHE_SIZE); |
1031 |
|
|
1032 |
|
// Delete Kernel Data area |
1033 |
< |
if (kernel_area >= 0) { |
1225 |
< |
shmdt((void *)(KERNEL_DATA_BASE + NATMEM_OFFSET)); |
1226 |
< |
shmdt((void *)(KERNEL_DATA2_BASE + NATMEM_OFFSET)); |
1227 |
< |
shmctl(kernel_area, IPC_RMID, NULL); |
1228 |
< |
} |
1033 |
> |
kernel_data_exit(); |
1034 |
|
|
1035 |
|
// Delete Low Memory area |
1036 |
|
if (lm_area_mapped) |
1037 |
< |
vm_release((void *)NATMEM_OFFSET, 0x3000); |
1037 |
> |
vm_mac_release(0, 0x3000); |
1038 |
|
|
1039 |
|
// Close /dev/zero |
1040 |
|
if (zero_fd > 0) |
1062 |
|
|
1063 |
|
|
1064 |
|
/* |
1065 |
+ |
* Initialize Kernel Data segments |
1066 |
+ |
*/ |
1067 |
+ |
|
1068 |
+ |
#if defined(__CYGWIN__) |
1069 |
+ |
#define WIN32_LEAN_AND_MEAN |
1070 |
+ |
#include <windows.h> |
1071 |
+ |
|
1072 |
+ |
static HANDLE kernel_handle; // Shared memory handle for Kernel Data |
1073 |
+ |
static DWORD allocation_granule; // Minimum size of allocateable are (64K) |
1074 |
+ |
static DWORD kernel_area_size; // Size of Kernel Data area |
1075 |
+ |
#endif |
1076 |
+ |
|
1077 |
+ |
static bool kernel_data_init(void) |
1078 |
+ |
{ |
1079 |
+ |
char str[256]; |
1080 |
+ |
#ifdef _WIN32 |
1081 |
+ |
SYSTEM_INFO si; |
1082 |
+ |
GetSystemInfo(&si); |
1083 |
+ |
allocation_granule = si.dwAllocationGranularity; |
1084 |
+ |
kernel_area_size = (KERNEL_AREA_SIZE + allocation_granule - 1) & -allocation_granule; |
1085 |
+ |
|
1086 |
+ |
char rcs[10]; |
1087 |
+ |
LPVOID kernel_addr; |
1088 |
+ |
kernel_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, kernel_area_size, NULL); |
1089 |
+ |
if (kernel_handle == NULL) { |
1090 |
+ |
sprintf(rcs, "%d", GetLastError()); |
1091 |
+ |
sprintf(str, GetString(STR_KD_SHMGET_ERR), rcs); |
1092 |
+ |
ErrorAlert(str); |
1093 |
+ |
return false; |
1094 |
+ |
} |
1095 |
+ |
kernel_addr = (LPVOID)Mac2HostAddr(KERNEL_DATA_BASE & -allocation_granule); |
1096 |
+ |
if (MapViewOfFileEx(kernel_handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, kernel_area_size, kernel_addr) != kernel_addr) { |
1097 |
+ |
sprintf(rcs, "%d", GetLastError()); |
1098 |
+ |
sprintf(str, GetString(STR_KD_SHMAT_ERR), rcs); |
1099 |
+ |
ErrorAlert(str); |
1100 |
+ |
return false; |
1101 |
+ |
} |
1102 |
+ |
kernel_addr = (LPVOID)Mac2HostAddr(KERNEL_DATA2_BASE & -allocation_granule); |
1103 |
+ |
if (MapViewOfFileEx(kernel_handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, kernel_area_size, kernel_addr) != kernel_addr) { |
1104 |
+ |
sprintf(rcs, "%d", GetLastError()); |
1105 |
+ |
sprintf(str, GetString(STR_KD2_SHMAT_ERR), rcs); |
1106 |
+ |
ErrorAlert(str); |
1107 |
+ |
return false; |
1108 |
+ |
} |
1109 |
+ |
#else |
1110 |
+ |
kernel_area = shmget(IPC_PRIVATE, KERNEL_AREA_SIZE, 0600); |
1111 |
+ |
if (kernel_area == -1) { |
1112 |
+ |
sprintf(str, GetString(STR_KD_SHMGET_ERR), strerror(errno)); |
1113 |
+ |
ErrorAlert(str); |
1114 |
+ |
return false; |
1115 |
+ |
} |
1116 |
+ |
if (shmat(kernel_area, Mac2HostAddr(KERNEL_DATA_BASE), 0) < 0) { |
1117 |
+ |
sprintf(str, GetString(STR_KD_SHMAT_ERR), strerror(errno)); |
1118 |
+ |
ErrorAlert(str); |
1119 |
+ |
return false; |
1120 |
+ |
} |
1121 |
+ |
if (shmat(kernel_area, Mac2HostAddr(KERNEL_DATA2_BASE), 0) < 0) { |
1122 |
+ |
sprintf(str, GetString(STR_KD2_SHMAT_ERR), strerror(errno)); |
1123 |
+ |
ErrorAlert(str); |
1124 |
+ |
return false; |
1125 |
+ |
} |
1126 |
+ |
#endif |
1127 |
+ |
return true; |
1128 |
+ |
} |
1129 |
+ |
|
1130 |
+ |
|
1131 |
+ |
/* |
1132 |
+ |
* Deallocate Kernel Data segments |
1133 |
+ |
*/ |
1134 |
+ |
|
1135 |
+ |
static void kernel_data_exit(void) |
1136 |
+ |
{ |
1137 |
+ |
#ifdef _WIN32 |
1138 |
+ |
if (kernel_handle) { |
1139 |
+ |
UnmapViewOfFile(Mac2HostAddr(KERNEL_DATA_BASE & -allocation_granule)); |
1140 |
+ |
UnmapViewOfFile(Mac2HostAddr(KERNEL_DATA2_BASE & -allocation_granule)); |
1141 |
+ |
CloseHandle(kernel_handle); |
1142 |
+ |
} |
1143 |
+ |
#else |
1144 |
+ |
if (kernel_area >= 0) { |
1145 |
+ |
shmdt(Mac2HostAddr(KERNEL_DATA_BASE)); |
1146 |
+ |
shmdt(Mac2HostAddr(KERNEL_DATA2_BASE)); |
1147 |
+ |
shmctl(kernel_area, IPC_RMID, NULL); |
1148 |
+ |
} |
1149 |
+ |
#endif |
1150 |
+ |
} |
1151 |
+ |
|
1152 |
+ |
|
1153 |
+ |
/* |
1154 |
|
* Jump into Mac ROM, start 680x0 emulator |
1155 |
|
*/ |
1156 |
|
|
1292 |
|
|
1293 |
|
|
1294 |
|
/* |
1401 |
– |
* Patch things after system startup (gets called by disk driver accRun routine) |
1402 |
– |
*/ |
1403 |
– |
|
1404 |
– |
void PatchAfterStartup(void) |
1405 |
– |
{ |
1406 |
– |
ExecuteNative(NATIVE_VIDEO_INSTALL_ACCEL); |
1407 |
– |
InstallExtFS(); |
1408 |
– |
} |
1409 |
– |
|
1410 |
– |
|
1411 |
– |
/* |
1295 |
|
* NVRAM watchdog thread (saves NVRAM every minute) |
1296 |
|
*/ |
1297 |
|
|
1444 |
|
pthread_mutexattr_init(&attr); |
1445 |
|
// Initialize the mutex for priority inheritance -- |
1446 |
|
// required for accurate timing. |
1447 |
< |
#ifdef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL |
1447 |
> |
#if defined(HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL) && !defined(__CYGWIN__) |
1448 |
|
pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); |
1449 |
|
#endif |
1450 |
|
#if defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) && defined(PTHREAD_MUTEX_NORMAL) |
2094 |
|
page_size = getpagesize(); |
2095 |
|
|
2096 |
|
// Allocate SheepShaver globals |
2097 |
< |
if (vm_acquire_fixed((char *)(base + NATMEM_OFFSET), size) < 0) |
2097 |
> |
proc = base; |
2098 |
> |
if (vm_mac_acquire(base, size) < 0) |
2099 |
|
return false; |
2100 |
|
|
2101 |
< |
// Allocate page with all bits set to 0 |
2102 |
< |
zero_page = base + size; |
2103 |
< |
uint8 *zero_page_host = (uint8 *)zero_page + NATMEM_OFFSET; |
2104 |
< |
if (vm_acquire_fixed(zero_page_host, page_size) < 0) |
2105 |
< |
return false; |
2222 |
< |
memset(zero_page_host, 0, page_size); |
2223 |
< |
if (vm_protect(zero_page_host, page_size, VM_PAGE_READ) < 0) |
2101 |
> |
// Allocate page with all bits set to 0, right in the middle |
2102 |
> |
// This is also used to catch undesired overlaps between proc and data areas |
2103 |
> |
zero_page = proc + (size / 2); |
2104 |
> |
Mac_memset(zero_page, 0, page_size); |
2105 |
> |
if (vm_protect(Mac2HostAddr(zero_page), page_size, VM_PAGE_READ) < 0) |
2106 |
|
return false; |
2107 |
|
|
2108 |
|
#if EMULATED_PPC |
2109 |
|
// Allocate alternate stack for PowerPC interrupt routine |
2110 |
< |
sig_stack = zero_page + page_size; |
2111 |
< |
if (vm_acquire_fixed((char *)(sig_stack + NATMEM_OFFSET), SIG_STACK_SIZE) < 0) |
2110 |
> |
sig_stack = base + size; |
2111 |
> |
if (vm_mac_acquire(sig_stack, SIG_STACK_SIZE) < 0) |
2112 |
|
return false; |
2113 |
|
#endif |
2114 |
|
|
2115 |
< |
top = base + size; |
2115 |
> |
data = base + size; |
2116 |
|
return true; |
2117 |
|
} |
2118 |
|
|
2119 |
|
void SheepMem::Exit(void) |
2120 |
|
{ |
2121 |
< |
if (top) { |
2121 |
> |
if (data) { |
2122 |
|
// Delete SheepShaver globals |
2123 |
< |
vm_release((void *)(base + NATMEM_OFFSET), size); |
2242 |
< |
|
2243 |
< |
// Delete zero page |
2244 |
< |
vm_release((void *)(zero_page + NATMEM_OFFSET), page_size); |
2123 |
> |
vm_mac_release(base, size); |
2124 |
|
|
2125 |
|
#if EMULATED_PPC |
2126 |
|
// Delete alternate stack for PowerPC interrupt routine |
2127 |
< |
vm_release((void *)(sig_stack + NATMEM_OFFSET), SIG_STACK_SIZE); |
2127 |
> |
vm_mac_release(sig_stack, SIG_STACK_SIZE); |
2128 |
|
#endif |
2129 |
|
} |
2130 |
|
} |