71 |
|
#include "user_strings.h" |
72 |
|
#include "version.h" |
73 |
|
#include "main.h" |
74 |
+ |
#include "vm_alloc.h" |
75 |
|
|
76 |
|
#ifdef ENABLE_MON |
77 |
|
# include "mon.h" |
109 |
|
char *x_display_name = NULL; // X11 display name |
110 |
|
Display *x_display = NULL; // X11 display handle |
111 |
|
|
111 |
– |
static int zero_fd = -1; // FD of /dev/zero |
112 |
|
static uint8 last_xpram[256]; // Buffer for monitoring XPRAM changes |
113 |
|
|
114 |
|
#ifdef HAVE_PTHREADS |
154 |
|
|
155 |
|
#if REAL_ADDRESSING |
156 |
|
static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped |
157 |
– |
static bool memory_mapped_from_zero = false; // Flag: Could allocate RAM area from 0 |
158 |
– |
#endif |
159 |
– |
|
160 |
– |
#if REAL_ADDRESSING || DIRECT_ADDRESSING |
161 |
– |
static uint32 mapped_ram_rom_size; // Total size of mmap()ed RAM/ROM area |
157 |
|
#endif |
158 |
|
|
159 |
|
|
267 |
|
if (!PrefsEditor()) |
268 |
|
QuitEmulator(); |
269 |
|
|
275 |
– |
// Open /dev/zero |
276 |
– |
zero_fd = open("/dev/zero", O_RDWR); |
277 |
– |
if (zero_fd < 0) { |
278 |
– |
sprintf(str, GetString(STR_NO_DEV_ZERO_ERR), strerror(errno)); |
279 |
– |
ErrorAlert(str); |
280 |
– |
QuitEmulator(); |
281 |
– |
} |
282 |
– |
|
270 |
|
// Read RAM size |
271 |
|
RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary |
272 |
|
if (RAMSize < 1024*1024) { |
275 |
|
} |
276 |
|
|
277 |
|
#if REAL_ADDRESSING || DIRECT_ADDRESSING |
278 |
< |
const uint32 page_size = getpagesize(); |
292 |
< |
const uint32 page_mask = page_size - 1; |
293 |
< |
const uint32 aligned_ram_size = (RAMSize + page_mask) & ~page_mask; |
294 |
< |
mapped_ram_rom_size = aligned_ram_size + 0x100000; |
278 |
> |
RAMSize = RAMSize & -getpagesize(); // Round down to page boundary |
279 |
|
#endif |
280 |
+ |
|
281 |
+ |
// Initialize VM system |
282 |
+ |
vm_init(); |
283 |
|
|
284 |
|
#if REAL_ADDRESSING |
285 |
< |
// Try to allocate the complete address space from zero |
286 |
< |
// gb-- the Solaris manpage about mmap(2) states that using MAP_FIXED |
287 |
< |
// implies undefined behaviour for further use of sbrk(), malloc(), etc. |
288 |
< |
// cebix-- on NetBSD/m68k, this causes a segfault |
285 |
> |
// Flag: RAM and ROM are contigously allocated from address 0 |
286 |
> |
bool memory_mapped_from_zero = false; |
287 |
> |
|
288 |
> |
// Under Solaris/SPARC and NetBSD/m68k, Basilisk II is known to crash |
289 |
> |
// when trying to map a too big chunk of memory starting at address 0 |
290 |
|
#if defined(OS_solaris) || defined(OS_netbsd) |
291 |
< |
// Anyway, it doesn't work... |
304 |
< |
if (0) { |
291 |
> |
const bool can_map_all_memory = false; |
292 |
|
#else |
293 |
< |
if (mmap((caddr_t)0x0000, mapped_ram_rom_size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) != MAP_FAILED) { |
293 |
> |
const bool can_map_all_memory = true; |
294 |
|
#endif |
295 |
+ |
|
296 |
+ |
// Try to allocate all memory from 0x0000, if it is not known to crash |
297 |
+ |
if (can_map_all_memory && (vm_acquire_fixed(0, RAMSize + 0x100000) == 0)) { |
298 |
|
D(bug("Could allocate RAM and ROM from 0x0000\n")); |
299 |
|
memory_mapped_from_zero = true; |
300 |
|
} |
301 |
< |
// Create Low Memory area (0x0000..0x2000) |
302 |
< |
else if (mmap((char *)0x0000, 0x2000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) != MAP_FAILED) { |
301 |
> |
|
302 |
> |
// Otherwise, just create the Low Memory area (0x0000..0x2000) |
303 |
> |
else if (vm_acquire_fixed(0, 0x2000) == 0) { |
304 |
|
D(bug("Could allocate the Low Memory globals\n")); |
305 |
|
lm_area_mapped = true; |
306 |
|
} |
307 |
< |
// Exit on error |
307 |
> |
|
308 |
> |
// Exit on failure |
309 |
|
else { |
310 |
|
sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno)); |
311 |
|
ErrorAlert(str); |
315 |
|
|
316 |
|
#if USE_SCRATCHMEM_SUBTERFUGE |
317 |
|
// Allocate scratch memory |
318 |
< |
ScratchMem = (uint8 *)malloc(SCRATCH_MEM_SIZE); |
319 |
< |
if (ScratchMem == NULL) { |
318 |
> |
ScratchMem = (uint8 *)vm_acquire(SCRATCH_MEM_SIZE); |
319 |
> |
if (ScratchMem == VM_MAP_FAILED) { |
320 |
|
ErrorAlert(GetString(STR_NO_MEM_ERR)); |
321 |
|
QuitEmulator(); |
322 |
|
} |
324 |
|
#endif |
325 |
|
|
326 |
|
// Create areas for Mac RAM and ROM |
335 |
– |
#if REAL_ADDRESSING || DIRECT_ADDRESSING |
336 |
– |
// gb-- Overkill, needs to be cleaned up. Probably explode it for either |
337 |
– |
// real or direct addressing mode. |
327 |
|
#if REAL_ADDRESSING |
328 |
|
if (memory_mapped_from_zero) { |
329 |
|
RAMBaseHost = (uint8 *)0; |
330 |
< |
ROMBaseHost = RAMBaseHost + aligned_ram_size; |
330 |
> |
ROMBaseHost = RAMBaseHost + RAMSize; |
331 |
|
} |
332 |
|
else |
333 |
|
#endif |
334 |
|
{ |
335 |
< |
RAMBaseHost = (uint8 *)mmap(0, mapped_ram_rom_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0); |
336 |
< |
if (RAMBaseHost == (uint8 *)MAP_FAILED) { |
335 |
> |
RAMBaseHost = (uint8 *)vm_acquire(RAMSize); |
336 |
> |
ROMBaseHost = (uint8 *)vm_acquire(0x100000); |
337 |
> |
if (RAMBaseHost == VM_MAP_FAILED || ROMBaseHost == VM_MAP_FAILED) { |
338 |
|
ErrorAlert(GetString(STR_NO_MEM_ERR)); |
339 |
|
QuitEmulator(); |
340 |
|
} |
351 |
– |
ROMBaseHost = RAMBaseHost + aligned_ram_size; |
341 |
|
} |
353 |
– |
#else |
354 |
– |
RAMBaseHost = (uint8 *)malloc(RAMSize); |
355 |
– |
ROMBaseHost = (uint8 *)malloc(0x100000); |
356 |
– |
if (RAMBaseHost == NULL || ROMBaseHost == NULL) { |
357 |
– |
ErrorAlert(GetString(STR_NO_MEM_ERR)); |
358 |
– |
QuitEmulator(); |
359 |
– |
} |
360 |
– |
#endif |
342 |
|
|
343 |
|
#if DIRECT_ADDRESSING |
344 |
< |
// Initialize MEMBaseDiff now so that Host2MacAddr in the Video module |
345 |
< |
// will return correct results |
344 |
> |
// RAMBaseMac shall always be zero |
345 |
> |
MEMBaseDiff = (uintptr)RAMBaseHost; |
346 |
|
RAMBaseMac = 0; |
347 |
< |
ROMBaseMac = RAMBaseMac + aligned_ram_size; |
367 |
< |
InitMEMBaseDiff(RAMBaseHost, RAMBaseMac); |
347 |
> |
ROMBaseMac = Host2MacAddr(ROMBaseHost); |
348 |
|
#endif |
349 |
< |
#if REAL_ADDRESSING // && !EMULATED_68K |
349 |
> |
#if REAL_ADDRESSING |
350 |
|
RAMBaseMac = (uint32)RAMBaseHost; |
351 |
|
ROMBaseMac = (uint32)ROMBaseHost; |
352 |
|
#endif |
603 |
|
ExitAll(); |
604 |
|
|
605 |
|
// Free ROM/RAM areas |
606 |
< |
#if REAL_ADDRESSING |
607 |
< |
if (memory_mapped_from_zero) |
628 |
< |
munmap((caddr_t)0x0000, mapped_ram_rom_size); |
629 |
< |
else |
630 |
< |
#endif |
631 |
< |
#if REAL_ADDRESSING || DIRECT_ADDRESSING |
632 |
< |
if (RAMBaseHost != (uint8 *)MAP_FAILED) { |
633 |
< |
munmap((caddr_t)RAMBaseHost, mapped_ram_rom_size); |
606 |
> |
if (RAMBaseHost != VM_MAP_FAILED) { |
607 |
> |
vm_release(RAMBaseHost, RAMSize); |
608 |
|
RAMBaseHost = NULL; |
609 |
|
} |
610 |
< |
#else |
611 |
< |
if (ROMBaseHost) { |
638 |
< |
free(ROMBaseHost); |
610 |
> |
if (ROMBaseHost != VM_MAP_FAILED) { |
611 |
> |
vm_release(ROMBaseHost, 0x100000); |
612 |
|
ROMBaseHost = NULL; |
613 |
|
} |
641 |
– |
if (RAMBaseHost) { |
642 |
– |
free(RAMBaseHost); |
643 |
– |
RAMBaseHost = NULL; |
644 |
– |
} |
645 |
– |
#endif |
614 |
|
|
615 |
|
#if USE_SCRATCHMEM_SUBTERFUGE |
616 |
|
// Delete scratch memory area |
617 |
< |
if (ScratchMem) { |
618 |
< |
free((void *)(ScratchMem - SCRATCH_MEM_SIZE/2)); |
617 |
> |
if (ScratchMem != (uint8 *)VM_MAP_FAILED) { |
618 |
> |
vm_release((void *)(ScratchMem - SCRATCH_MEM_SIZE/2), SCRATCH_MEM_SIZE); |
619 |
|
ScratchMem = NULL; |
620 |
|
} |
621 |
|
#endif |
623 |
|
#if REAL_ADDRESSING |
624 |
|
// Delete Low Memory area |
625 |
|
if (lm_area_mapped) |
626 |
< |
munmap((char *)0x0000, 0x2000); |
626 |
> |
vm_release(0, 0x2000); |
627 |
|
#endif |
628 |
< |
|
629 |
< |
// Close /dev/zero |
630 |
< |
if (zero_fd > 0) |
663 |
< |
close(zero_fd); |
628 |
> |
|
629 |
> |
// Exit VM wrappers |
630 |
> |
vm_exit(); |
631 |
|
|
632 |
|
// Exit system routines |
633 |
|
SysExit(); |