mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-06-01 07:41:57 +00:00
Make Basilisk II (mostly) 64bit clean
This commit is contained in:
parent
ab2fedcbe4
commit
2e2f2a6b46
|
@ -78,7 +78,7 @@ extern void update_sdl_video(SDL_Surface *screen, int numrects, SDL_Rect *rects)
|
|||
#endif
|
||||
|
||||
// Prototypes
|
||||
static void vosf_do_set_dirty_area(uintptr first, uintptr last);
|
||||
static void vosf_do_set_dirty_area(const size_t, const size_t);
|
||||
static void vosf_set_dirty_area(int x, int y, int w, int h, unsigned screen_width, unsigned screen_height, unsigned bytes_per_row);
|
||||
|
||||
// Variables for Video on SEGV support
|
||||
|
@ -89,17 +89,17 @@ struct ScreenPageInfo {
|
|||
};
|
||||
|
||||
struct ScreenInfo {
|
||||
uintptr memStart; // Start address aligned to page boundary
|
||||
uint32 memLength; // Length of the memory addressed by the screen pages
|
||||
|
||||
uintptr pageSize; // Size of a page
|
||||
int pageBits; // Shift count to get the page number
|
||||
uint32 pageCount; // Number of pages allocated to the screen
|
||||
|
||||
uint8* memStart; // Start address aligned to page boundary
|
||||
int memLength; // Length of the memory addressed by the screen pages
|
||||
|
||||
int pageSize; // Size of a page
|
||||
int pageBits; // Shift count to get the page number
|
||||
int pageCount; // Number of pages allocated to the screen
|
||||
|
||||
char* dirtyPages; // Table of flags set if page was altered
|
||||
ScreenPageInfo* pageInfo; // Table of mappings page -> Mac scanlines
|
||||
bool dirty; // Flag: set if the frame buffer was touched
|
||||
bool very_dirty; // Flag: set if the frame buffer was completely modified (e.g. colormap changes)
|
||||
char * dirtyPages; // Table of flags set if page was altered
|
||||
ScreenPageInfo * pageInfo; // Table of mappings page -> Mac scanlines
|
||||
};
|
||||
|
||||
static ScreenInfo mainBuffer;
|
||||
|
@ -251,7 +251,7 @@ static bool video_vosf_profitable(uint32 *duration_p = NULL, uint32 *n_page_faul
|
|||
for (uint32 p = 0; p < mainBuffer.pageCount; p++) {
|
||||
uint8 *addr = (uint8 *)(mainBuffer.memStart + (p * mainBuffer.pageSize));
|
||||
if (accel)
|
||||
vosf_do_set_dirty_area((uintptr)addr, (uintptr)addr + mainBuffer.pageSize - 1);
|
||||
vosf_do_set_dirty_area((size_t)addr, (size_t)addr + mainBuffer.pageSize - 1);
|
||||
else
|
||||
addr[0] = 0; // Trigger Screen_fault_handler()
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ static bool video_vosf_profitable(uint32 *duration_p = NULL, uint32 *n_page_faul
|
|||
if (n_page_faults_p)
|
||||
*n_page_faults_p = n_page_faults;
|
||||
|
||||
D(bug("Triggered %d page faults in %ld usec (%.1f usec per fault)\n", n_page_faults, duration, double(duration) / double(n_page_faults)));
|
||||
D(bug("Triggered %d page faults in %ld usec (%.1f usec per fault)\n", n_page_faults, (long int)duration, double(duration) / double(n_page_faults)));
|
||||
return ((duration / n_tries) < (VOSF_PROFITABLE_THRESHOLD * (frame_skip ? frame_skip : 1)));
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,7 @@ static bool video_vosf_init(MONITOR_INIT){
|
|||
// Must be page aligned (use page_extend)
|
||||
assert(is_page_aligned((size_t)MacFrameBaseHost));
|
||||
assert(is_page_aligned(the_buffer_size));
|
||||
mainBuffer.memStart = (uintptr)MacFrameBaseHost;
|
||||
mainBuffer.memStart = MacFrameBaseHost;
|
||||
mainBuffer.memLength = the_buffer_size;
|
||||
|
||||
mainBuffer.pageSize = page_size;
|
||||
|
@ -353,16 +353,14 @@ static void video_vosf_exit(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update VOSF state with specified dirty area
|
||||
*/
|
||||
|
||||
static void vosf_do_set_dirty_area(uintptr first, uintptr last)
|
||||
{
|
||||
const int first_page = (first - mainBuffer.memStart) >> mainBuffer.pageBits;
|
||||
const int last_page = (last - mainBuffer.memStart) >> mainBuffer.pageBits;
|
||||
uint8 *addr = (uint8 *)(first & ~(mainBuffer.pageSize - 1));
|
||||
static void vosf_do_set_dirty_area(const size_t first, const size_t last){
|
||||
const int first_page = ((size_t)first - (size_t)mainBuffer.memStart) >> mainBuffer.pageBits;
|
||||
const int last_page = ((size_t)last - (size_t)mainBuffer.memStart) >> mainBuffer.pageBits;
|
||||
uint8* addr = (uint8*)((size_t)first & ~((size_t)mainBuffer.pageSize - 1));
|
||||
for (int i = first_page; i <= last_page; i++) {
|
||||
if (PFLAG_ISCLEAR(i)) {
|
||||
PFLAG_SET(i);
|
||||
|
@ -392,26 +390,26 @@ static void vosf_set_dirty_area(int x, int y, int w, int h, unsigned screen_widt
|
|||
if (bytes_per_row >= screen_width) {
|
||||
const int bytes_per_pixel = bytes_per_row / screen_width;
|
||||
if (bytes_per_row <= mainBuffer.pageSize) {
|
||||
const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x * bytes_per_pixel;
|
||||
const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) * bytes_per_pixel;
|
||||
const size_t a0 = (size_t)mainBuffer.memStart + y * bytes_per_row + x * bytes_per_pixel;
|
||||
const size_t a1 = (size_t)mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) * bytes_per_pixel;
|
||||
vosf_do_set_dirty_area(a0, a1);
|
||||
} else {
|
||||
for (int j = y; j < y + h; j++) {
|
||||
const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x * bytes_per_pixel;
|
||||
const uintptr a1 = a0 + (w - 1) * bytes_per_pixel;
|
||||
const size_t a0 = (size_t)mainBuffer.memStart + j * bytes_per_row + x * bytes_per_pixel;
|
||||
const size_t a1 = a0 + (w - 1) * bytes_per_pixel;
|
||||
vosf_do_set_dirty_area(a0, a1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const int pixels_per_byte = screen_width / bytes_per_row;
|
||||
if (bytes_per_row <= mainBuffer.pageSize) {
|
||||
const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x / pixels_per_byte;
|
||||
const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) / pixels_per_byte;
|
||||
const size_t a0 = (size_t)mainBuffer.memStart + y * bytes_per_row + x / pixels_per_byte;
|
||||
const size_t a1 = (size_t)mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) / pixels_per_byte;
|
||||
vosf_do_set_dirty_area(a0, a1);
|
||||
} else {
|
||||
for (int j = y; j < y + h; j++) {
|
||||
const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x / pixels_per_byte;
|
||||
const uintptr a1 = mainBuffer.memStart + j * bytes_per_row + (x + w - 1) / pixels_per_byte;
|
||||
const size_t a0 = (size_t)mainBuffer.memStart + j * bytes_per_row + x / pixels_per_byte;
|
||||
const size_t a1 = (size_t)mainBuffer.memStart + j * bytes_per_row + (x + w - 1) / pixels_per_byte;
|
||||
vosf_do_set_dirty_area(a0, a1);
|
||||
}
|
||||
}
|
||||
|
@ -420,25 +418,23 @@ static void vosf_set_dirty_area(int x, int y, int w, int h, unsigned screen_widt
|
|||
UNLOCK_VOSF;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Screen fault handler
|
||||
*/
|
||||
|
||||
bool Screen_fault_handler(sigsegv_info_t *sip)
|
||||
{
|
||||
const uintptr addr = (uintptr)sigsegv_get_fault_address(sip);
|
||||
bool Screen_fault_handler(sigsegv_info_t* sip){
|
||||
const size_t addr = (size_t)sigsegv_get_fault_address(sip);
|
||||
|
||||
/* Someone attempted to write to the frame buffer. Make it writeable
|
||||
* now so that the data could actually be written to. It will be made
|
||||
* read-only back in one of the screen update_*() functions.
|
||||
*/
|
||||
if (((uintptr)addr - mainBuffer.memStart) < mainBuffer.memLength) {
|
||||
const int page = ((uintptr)addr - mainBuffer.memStart) >> mainBuffer.pageBits;
|
||||
if ((addr - (size_t)mainBuffer.memStart) < mainBuffer.memLength) {
|
||||
const int page = (addr - (size_t)mainBuffer.memStart) >> mainBuffer.pageBits;
|
||||
LOCK_VOSF;
|
||||
if (PFLAG_ISCLEAR(page)) {
|
||||
PFLAG_SET(page);
|
||||
vm_protect((char *)(addr & ~(mainBuffer.pageSize - 1)), mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE);
|
||||
vm_protect((char*)(addr & ~(mainBuffer.pageSize - 1)), mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE);
|
||||
}
|
||||
mainBuffer.dirty = true;
|
||||
UNLOCK_VOSF;
|
||||
|
|
|
@ -61,21 +61,14 @@ typedef UINT_PTR vm_uintptr_t;
|
|||
typedef unsigned long vm_uintptr_t;
|
||||
#endif
|
||||
|
||||
/* We want MAP_32BIT, if available, for SheepShaver and BasiliskII
|
||||
because the emulated target is 32-bit and this helps to allocate
|
||||
memory so that branches could be resolved more easily (32-bit
|
||||
displacement to code in .text), on AMD64 for example. */
|
||||
/* FIXME: make JIT 64bit clean */
|
||||
#if defined(__hpux)
|
||||
#define MAP_32BIT MAP_ADDR32
|
||||
#endif
|
||||
#ifndef MAP_32BIT
|
||||
#define MAP_32BIT 0
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#define FORCE_MAP_32BIT MAP_FIXED
|
||||
#else
|
||||
#define FORCE_MAP_32BIT MAP_32BIT
|
||||
#endif
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON 0
|
||||
#endif
|
||||
|
@ -83,41 +76,16 @@ typedef unsigned long vm_uintptr_t;
|
|||
#define MAP_ANONYMOUS 0
|
||||
#endif
|
||||
|
||||
/* NOTE: on linux MAP_32BIT is only implemented on AMD64
|
||||
it is a null op on all other architectures
|
||||
thus the MAP_BASE setting below is the only thing
|
||||
ensuring low addresses on aarch64 for example */
|
||||
#define MAP_EXTRA_FLAGS (MAP_32BIT)
|
||||
|
||||
#ifdef HAVE_MMAP_VM
|
||||
#if (defined(__linux__) && defined(__i386__)) || defined(__FreeBSD__) || HAVE_LINKER_SCRIPT
|
||||
/* Force a reasonnable address below 0x80000000 on x86 so that we
|
||||
don't get addresses above when the program is run on AMD64.
|
||||
NOTE: this is empirically determined on Linux/x86. */
|
||||
#define MAP_BASE 0x10000000
|
||||
#elif DIRECT_ADDRESSING
|
||||
/* linux does not implement any useful fallback behavior
|
||||
such as allocating the next available address
|
||||
and the first 4k-64k of address space is marked unavailable
|
||||
for security reasons (see https://wiki.debian.org/mmap_min_addr)
|
||||
so we must start requesting after the first page
|
||||
or we get a high 64bit address that will crash direct addressing
|
||||
|
||||
leaving NULL unmapped is a good idea anyway for debugging reasons */
|
||||
#define MAP_BASE 0x00010000
|
||||
#else
|
||||
#define MAP_BASE 0x00000000
|
||||
#endif
|
||||
static char * next_address = (char *)MAP_BASE;
|
||||
#ifdef HAVE_MMAP_ANON
|
||||
#define map_flags (MAP_ANON | MAP_EXTRA_FLAGS)
|
||||
#define map_flags (MAP_ANON)
|
||||
#define zero_fd -1
|
||||
#else
|
||||
#ifdef HAVE_MMAP_ANONYMOUS
|
||||
#define map_flags (MAP_ANONYMOUS | MAP_EXTRA_FLAGS)
|
||||
#define map_flags (MAP_ANONYMOUS)
|
||||
#define zero_fd -1
|
||||
#else
|
||||
#define map_flags (MAP_EXTRA_FLAGS)
|
||||
#define map_flags (0)
|
||||
static int zero_fd = -1;
|
||||
#endif
|
||||
#endif
|
||||
|
@ -126,8 +94,7 @@ static int zero_fd = -1;
|
|||
/* Translate generic VM map flags to host values. */
|
||||
|
||||
#ifdef HAVE_MMAP_VM
|
||||
static int translate_map_flags(int vm_flags)
|
||||
{
|
||||
static int translate_map_flags(int vm_flags){
|
||||
int flags = 0;
|
||||
if (vm_flags & VM_MAP_SHARED)
|
||||
flags |= MAP_SHARED;
|
||||
|
@ -238,8 +205,8 @@ void vm_exit(void)
|
|||
and default protection bits are read / write. The return value
|
||||
is the actual mapping address chosen or VM_MAP_FAILED for errors. */
|
||||
|
||||
void * vm_acquire(size_t size, int options){
|
||||
void * addr;
|
||||
void* vm_acquire(size_t size, int options){
|
||||
void* addr=NULL;
|
||||
errno = 0;
|
||||
|
||||
#ifndef HAVE_VM_WRITE_WATCH
|
||||
|
@ -258,19 +225,16 @@ void * vm_acquire(size_t size, int options){
|
|||
int fd = zero_fd;
|
||||
int the_map_flags = translate_map_flags(options) | map_flags;
|
||||
|
||||
if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED)
|
||||
printf("mmap addr=%p size=%p flags=%p\n",addr,size,the_map_flags);
|
||||
if ((addr = mmap(addr, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0))==(void*)MAP_FAILED)
|
||||
return VM_MAP_FAILED;
|
||||
printf("next=%p got=%p size=%p\n",next_address,addr,size);
|
||||
|
||||
#if DIRECT_ADDRESSING
|
||||
// If MAP_32BIT and MAP_BASE fail to ensure
|
||||
// a 32-bit address crash now instead of later.
|
||||
// FIXME: make everything 64-bit clean and tear this all out.
|
||||
printf("mmap got=%p\n",addr);
|
||||
|
||||
// If MAP_32BIT fails to ensure a 32bit address, crash now instead of later.
|
||||
// FIXME: Make JIT 64bit clean and tear all this VM_MAP_32BIT hackery out.
|
||||
if(sizeof(void *) > 4 && (options & VM_MAP_32BIT))
|
||||
assert((size_t)addr<0xffffffffL);
|
||||
#endif
|
||||
|
||||
next_address = (char *)addr + size;
|
||||
#elif defined(HAVE_WIN32_VM)
|
||||
int alloc_type = MEM_RESERVE | MEM_COMMIT;
|
||||
if (options & VM_MAP_WRITE_WATCH)
|
||||
|
|
|
@ -171,8 +171,7 @@ static sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip)
|
|||
* Dump state when everything went wrong after a SEGV
|
||||
*/
|
||||
|
||||
static void sigsegv_dump_state(sigsegv_info_t *sip)
|
||||
{
|
||||
static void sigsegv_dump_state(sigsegv_info_t *sip){
|
||||
const sigsegv_address_t fault_address = sigsegv_get_fault_address(sip);
|
||||
const sigsegv_address_t fault_instruction = sigsegv_get_fault_instruction_address(sip);
|
||||
fprintf(stderr, "Caught SIGSEGV at address %p", fault_address);
|
||||
|
@ -199,7 +198,6 @@ static void sigsegv_dump_state(sigsegv_info_t *sip)
|
|||
QuitEmulator();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update virtual clock and trigger interrupts if necessary
|
||||
*/
|
||||
|
@ -404,6 +402,14 @@ int main(int argc, char **argv){
|
|||
}
|
||||
}
|
||||
|
||||
// Init system routines
|
||||
SysInit();
|
||||
|
||||
// Show preferences editor
|
||||
if (!gui_connection && !PrefsFindBool("nogui"))
|
||||
if (!PrefsEditor())
|
||||
QuitEmulator();
|
||||
|
||||
#ifdef USE_SDL
|
||||
// Initialize SDL system
|
||||
int sdl_flags = 0;
|
||||
|
@ -435,14 +441,6 @@ int main(int argc, char **argv){
|
|||
|
||||
#endif
|
||||
|
||||
// Init system routines
|
||||
SysInit();
|
||||
|
||||
// Show preferences editor
|
||||
if (!gui_connection && !PrefsFindBool("nogui"))
|
||||
if (!PrefsEditor())
|
||||
QuitEmulator();
|
||||
|
||||
// Install the handler for SIGSEGV
|
||||
if (!sigsegv_install_handler(sigsegv_handler)) {
|
||||
sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIGSEGV", strerror(errno));
|
||||
|
@ -463,9 +461,6 @@ int main(int argc, char **argv){
|
|||
QuitEmulator();
|
||||
D(bug("Initialization complete\n"));
|
||||
|
||||
D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
|
||||
D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
|
||||
|
||||
#ifdef ENABLE_MON
|
||||
// Setup SIGINT handler to enter mon
|
||||
sigemptyset(&sigint_sa.sa_mask);
|
||||
|
@ -618,24 +613,6 @@ void QuitEmulator(void)
|
|||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Code was patched, flush caches if neccessary (i.e. when using a real 680x0
|
||||
* or a dynamically recompiling emulator)
|
||||
*/
|
||||
|
||||
void FlushCodeCache(void *start, uint32 size){
|
||||
#if USE_JIT
|
||||
if (UseJIT)
|
||||
#ifdef UPDATE_UAE
|
||||
flush_icache();
|
||||
#else
|
||||
flush_icache_range((uint8 *)start, size);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SIGINT handler, enters mon
|
||||
*/
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -42,11 +42,6 @@
|
|||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
// CPU and FPU type, addressing mode
|
||||
int CPUType;
|
||||
int FPUType;
|
||||
bool TwentyFourBitAddressing;
|
||||
|
||||
#if ENABLE_MON
|
||||
#include "mon.h"
|
||||
|
||||
|
@ -59,6 +54,11 @@ static void mon_write_byte_b2(uintptr adr, uint32 b){
|
|||
}
|
||||
#endif
|
||||
|
||||
// CPU and FPU type, addressing mode
|
||||
int CPUType;
|
||||
int FPUType;
|
||||
bool TwentyFourBitAddressing;
|
||||
|
||||
/*
|
||||
* Initialize everything, returns false on error
|
||||
*/
|
||||
|
|
|
@ -37,22 +37,22 @@
|
|||
#include "debug.h"
|
||||
|
||||
#if DIRECT_ADDRESSING
|
||||
uintptr MEMBaseDiff = 0; // Global offset between a Mac address and its Host equivalent
|
||||
size_t MEMBaseDiff = 0; // Global offset between a Mac address and its Host equivalent
|
||||
#endif
|
||||
|
||||
// RAM and ROM pointers
|
||||
uint8* RAMBaseHost = 0; // RAM base (host address space)
|
||||
uint8* ROMBaseHost = 0; // ROM base (host address space)
|
||||
uint32 RAMBaseMac = 0; // RAM base (Mac address space)
|
||||
uint32 ROMBaseMac = 0; // ROM base (Mac address space)
|
||||
uint32 RAMSize = 0; // Size of RAM
|
||||
uint32 ROMSize = 0; // Size of ROM
|
||||
uint8* RAMBaseHost = 0; // RAM base (host address space)
|
||||
uint8* ROMBaseHost = 0; // ROM base (host address space)
|
||||
const uint32 RAMBaseMac = 0; // RAM base (Mac address space)
|
||||
uint32 ROMBaseMac = 0; // ROM base (Mac address space)
|
||||
uint32 RAMSize = 0; // Size of RAM
|
||||
uint32 ROMSize = 0; // Size of ROM
|
||||
|
||||
// Mac frame buffer
|
||||
uint8* MacFrameBaseHost; // Frame buffer base (host address space)
|
||||
uint32 MacFrameSize; // Size of current frame buffer
|
||||
int MacFrameLayout; // Frame buffer layout
|
||||
uint32 VRAMSize; // Size of VRAM
|
||||
uint8* MacFrameBaseHost = 0; // Frame buffer base (host address space)
|
||||
uint32 MacFrameSize = 0; // Size of current frame buffer
|
||||
int MacFrameLayout = 0; // Frame buffer layout
|
||||
uint32 VRAMSize = 0; // Size of VRAM
|
||||
|
||||
uint32 JITCacheSize=0;
|
||||
|
||||
|
@ -66,10 +66,6 @@ int ScratchMemSize = 64*1024; // 64k
|
|||
int ScratchMemSize = 0;
|
||||
#endif
|
||||
|
||||
#if USE_JIT
|
||||
bool UseJIT = false;
|
||||
#endif
|
||||
|
||||
// From newcpu.cpp
|
||||
extern bool quit_program;
|
||||
|
||||
|
@ -93,7 +89,8 @@ bool InitMacMem(void){
|
|||
VRAMSize = 16*1024*1024; // 16mb, more than enough for 1920x1440x32
|
||||
|
||||
#if USE_JIT
|
||||
JITCacheSize = 1024*PrefsFindInt32("jitcachesize") + 1024;
|
||||
JITCacheSize = compiler_get_jit_cache_size();
|
||||
printf("JITCacheSize=%p\n",JITCacheSize);
|
||||
#endif
|
||||
|
||||
// Initialize VM system
|
||||
|
@ -102,7 +99,11 @@ bool InitMacMem(void){
|
|||
// Create our virtual Macintosh memory map
|
||||
RAMBaseHost = (uint8*)vm_acquire(
|
||||
RAMSize + ScratchMemSize + MAX_ROM_SIZE + VRAMSize + JITCacheSize,
|
||||
VM_MAP_DEFAULT | VM_MAP_32BIT);
|
||||
#if USE_JIT
|
||||
// FIXME: JIT is not 64bit clean
|
||||
((JITCacheSize>0)?VM_MAP_32BIT:0)|
|
||||
#endif
|
||||
VM_MAP_DEFAULT);
|
||||
if (RAMBaseHost == VM_MAP_FAILED) {
|
||||
ErrorAlert(STR_NO_MEM_ERR);
|
||||
return false;
|
||||
|
@ -167,7 +168,7 @@ bool InitMacMem(void){
|
|||
if (ReadFile(rom_fh, ROMBaseHost, ROMSize, &bytes_read, NULL) == 0 || bytes_read != ROMSize) {
|
||||
#else
|
||||
lseek(rom_fd, 0, SEEK_SET);
|
||||
if (read(rom_fd, ROMBaseHost, ROMSize) != (ssize_t)ROMSize) {
|
||||
if (read(rom_fd, ROMBaseHost, ROMSize) != ROMSize) {
|
||||
#endif
|
||||
ErrorAlert(STR_ROM_FILE_READ_ERR);
|
||||
#ifdef WIN32
|
||||
|
@ -185,7 +186,7 @@ bool InitMacMem(void){
|
|||
|
||||
#if DIRECT_ADDRESSING
|
||||
// Mac address space = host address space minus constant offset (MEMBaseDiff)
|
||||
MEMBaseDiff = (uintptr)RAMBaseHost;
|
||||
MEMBaseDiff = (size_t)RAMBaseHost;
|
||||
ROMBaseMac = Host2MacAddr(ROMBaseHost);
|
||||
#else
|
||||
// Initialize UAE memory banks
|
||||
|
@ -229,23 +230,20 @@ void MacMemExit(void){
|
|||
bool Init680x0(void){
|
||||
init_m68k();
|
||||
#if USE_JIT
|
||||
UseJIT = compiler_use_jit();
|
||||
if (UseJIT)
|
||||
compiler_init(MacFrameBaseHost + VRAMSize);
|
||||
if(JITCacheSize>0)
|
||||
compiler_init(MacFrameBaseHost + VRAMSize, JITCacheSize); // put JIT cache after VRAM
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Deinitialize 680x0 emulation
|
||||
*/
|
||||
|
||||
void Exit680x0(void)
|
||||
{
|
||||
void Exit680x0(void){
|
||||
#if USE_JIT
|
||||
if (UseJIT)
|
||||
compiler_exit();
|
||||
if(JITCacheSize>0)
|
||||
compiler_exit();
|
||||
#endif
|
||||
exit_m68k();
|
||||
}
|
||||
|
@ -254,18 +252,16 @@ void Exit680x0(void)
|
|||
* Reset and start 680x0 emulation (doesn't return)
|
||||
*/
|
||||
|
||||
void Start680x0(void)
|
||||
{
|
||||
void Start680x0(void){
|
||||
m68k_reset();
|
||||
#if USE_JIT
|
||||
if (UseJIT)
|
||||
m68k_compile_execute();
|
||||
else
|
||||
if (JITCacheSize>0)
|
||||
m68k_compile_execute();
|
||||
else
|
||||
#endif
|
||||
m68k_execute();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Trigger interrupt
|
||||
*/
|
||||
|
@ -383,3 +379,19 @@ void Execute68k(uint32 addr, struct M68kRegisters *r)
|
|||
r->a[i] = m68k_areg(regs, i);
|
||||
quit_program = false;
|
||||
}
|
||||
|
||||
#if USE_JIT
|
||||
extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Code was patched, flush caches if neccessary (i.e. when using a real 680x0
|
||||
* or a dynamically recompiling emulator)
|
||||
*/
|
||||
|
||||
void FlushCodeCache(void *start, uint32 size){
|
||||
#if USE_JIT
|
||||
if (JITCacheSize>0)
|
||||
flush_icache_range((uint8 *)start, size);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -3841,10 +3841,9 @@ x86_get_cpu_vendor(struct cpuinfo_x86 *c)
|
|||
}
|
||||
|
||||
static void
|
||||
cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx)
|
||||
{
|
||||
cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx){
|
||||
const int CPUID_SPACE = 4096;
|
||||
uae_u8* cpuid_space = (uae_u8 *)vm_acquire(CPUID_SPACE);
|
||||
uae_u8* cpuid_space = (uae_u8 *)vm_acquire(CPUID_SPACE,VM_MAP_DEFAULT|VM_MAP_32BIT);
|
||||
if (cpuid_space == VM_MAP_FAILED)
|
||||
abort();
|
||||
vm_protect(cpuid_space, CPUID_SPACE, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE);
|
||||
|
|
|
@ -139,9 +139,9 @@ union cacheline {
|
|||
|
||||
/* Functions exposed to newcpu, or to what was moved from newcpu.c to
|
||||
* compemu_support.c */
|
||||
extern void compiler_init(void*);
|
||||
extern void compiler_init(void*,int);
|
||||
extern void compiler_exit(void);
|
||||
extern bool compiler_use_jit(void);
|
||||
extern uint32 compiler_get_jit_cache_size(void);
|
||||
extern void init_comp(void);
|
||||
extern void flush(int save_regs);
|
||||
extern void small_flush(int save_regs);
|
||||
|
|
|
@ -5003,12 +5003,13 @@ static inline const char *str_on_off(bool b)
|
|||
return b ? "on" : "off";
|
||||
}
|
||||
|
||||
void compiler_init(void* buf){
|
||||
void compiler_init(void* buf, int JITCacheSize){
|
||||
static bool initialized = false;
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
compiled_code=(uint8*)buf;
|
||||
cache_size=JITCacheSize;
|
||||
|
||||
#if JIT_DEBUG
|
||||
// JIT debug mode ?
|
||||
|
@ -5025,10 +5026,6 @@ void compiler_init(void* buf){
|
|||
#endif
|
||||
write_log("<JIT compiler> : compile FPU instructions : %s\n", !avoid_fpu ? "yes" : "no");
|
||||
|
||||
// Get size of the translation cache (in KB)
|
||||
cache_size = PrefsFindInt32("jitcachesize");
|
||||
write_log("<JIT compiler> : requested translation cache size : %d KB\n", cache_size);
|
||||
|
||||
// Initialize target CPU (check for features, e.g. CMOV, rat stalls)
|
||||
raw_init_cpu();
|
||||
setzflg_uses_bsf = target_check_bsf();
|
||||
|
@ -5123,25 +5120,29 @@ void compiler_exit(void){
|
|||
#endif
|
||||
}
|
||||
|
||||
bool compiler_use_jit(void)
|
||||
{
|
||||
// Return bytes needed for JIT cache
|
||||
uint32 compiler_get_jit_cache_size(void){
|
||||
// Check for the "jit" prefs item
|
||||
if (!PrefsFindBool("jit"))
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
// Don't use JIT if translation cache size is less then MIN_CACHE_SIZE KB
|
||||
if (PrefsFindInt32("jitcachesize") < MIN_CACHE_SIZE) {
|
||||
uint32 JITCacheSize=PrefsFindInt32("jitcachesize");
|
||||
if (JITCacheSize < MIN_CACHE_SIZE) {
|
||||
write_log("<JIT compiler> : translation cache size is less than %d KB. Disabling JIT.\n", MIN_CACHE_SIZE);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// Enable JIT for 68020+ emulation only
|
||||
if (CPUType < 2) {
|
||||
write_log("<JIT compiler> : JIT is not supported in 680%d0 emulation mode, disabling.\n", CPUType);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
write_log("<JIT compiler> : translation cache size : %d KB\n", JITCacheSize);
|
||||
return (1024*JITCacheSize) + POPALLSPACE_SIZE;
|
||||
}
|
||||
|
||||
void init_comp(void)
|
||||
|
@ -5635,10 +5636,6 @@ void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp)
|
|||
forget_about(tmp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void set_cache_state(int enabled)
|
||||
{
|
||||
if (enabled!=letit)
|
||||
|
@ -5658,35 +5655,19 @@ uae_u32 get_jitted_size(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const int CODE_ALLOC_MAX_ATTEMPTS = 10;
|
||||
const int CODE_ALLOC_BOUNDARIES = 128 * 1024; // 128 KB
|
||||
|
||||
static inline uint8 *alloc_code(uint32 size){
|
||||
uint8 *ptr = (uint8 *)vm_acquire(size);
|
||||
ptr == VM_MAP_FAILED ? NULL : ptr;
|
||||
/* allocated code must fit in 32-bit boundaries */
|
||||
assert((size_t)ptr<0xffffffffL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void alloc_cache(void){
|
||||
assert(compiled_code);
|
||||
|
||||
if (cache_size == 0)
|
||||
return;
|
||||
assert(cache_size);
|
||||
|
||||
vm_protect(compiled_code, cache_size * 1024, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE);
|
||||
|
||||
if (compiled_code) {
|
||||
write_log("<JIT compiler> : actual translation cache size : %d KB at 0x%08X\n", cache_size, compiled_code);
|
||||
max_compile_start = compiled_code + cache_size*1024 - BYTES_PER_INST;
|
||||
current_compile_p = compiled_code;
|
||||
current_cache_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void op_illg_1 (uae_u32 opcode) REGPARAM;
|
||||
|
||||
static void calc_checksum(blockinfo* bi, uae_u32* c1, uae_u32* c2)
|
||||
|
|
|
@ -23,18 +23,17 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* Memory system
|
||||
*/
|
||||
|
||||
// RAM and ROM pointers (allocated and set by main_*.cpp)
|
||||
extern uint32 RAMBaseMac; // RAM base (Mac address space), does not include Low Mem when != 0
|
||||
extern uint8 *RAMBaseHost; // RAM base (host address space)
|
||||
extern const uint32 RAMBaseMac; // RAM base (Mac address space)
|
||||
extern uint8* RAMBaseHost; // RAM base (host address space)
|
||||
extern uint32 RAMSize; // Size of RAM
|
||||
|
||||
extern uint32 ROMBaseMac; // ROM base (Mac address space)
|
||||
extern uint8 *ROMBaseHost; // ROM base (host address space)
|
||||
extern uint8* ROMBaseHost; // ROM base (host address space)
|
||||
extern uint32 ROMSize; // Size of ROM
|
||||
extern uint32 VRAMSize; // Size of VRAM
|
||||
|
||||
|
@ -42,8 +41,8 @@ extern uint32 VRAMSize; // Size of VRAM
|
|||
// If we are not using direct addressing, the Mac frame buffer gets
|
||||
// mapped to this location. The memory must be allocated by VideoInit().
|
||||
// If multiple monitors are used, they must share the frame buffer
|
||||
const uint32 MacFrameBaseMac = 0xa0000000;
|
||||
extern uint8 *MacFrameBaseHost; // Frame buffer base (host address space)
|
||||
const uint32 MacFrameBaseMac = 0xa0000000;
|
||||
extern uint8* MacFrameBaseHost; // Frame buffer base (host address space)
|
||||
extern uint32 MacFrameSize; // Size of frame buffer
|
||||
#endif
|
||||
extern int MacFrameLayout; // Frame buffer layout (see defines below)
|
||||
|
|
|
@ -136,7 +136,7 @@ static void REGPARAM2 ram_wput(uaecptr, uae_u32) REGPARAM;
|
|||
static void REGPARAM2 ram_bput(uaecptr, uae_u32) REGPARAM;
|
||||
static uae_u8 *REGPARAM2 ram_xlate(uaecptr addr) REGPARAM;
|
||||
|
||||
static uintptr RAMBaseDiff; // RAMBaseHost - RAMBaseMac
|
||||
static size_t RAMBaseDiff; // RAMBaseHost - RAMBaseMac
|
||||
|
||||
uae_u32 REGPARAM2 ram_lget(uaecptr addr)
|
||||
{
|
||||
|
@ -244,7 +244,7 @@ static void REGPARAM2 rom_wput(uaecptr, uae_u32) REGPARAM;
|
|||
static void REGPARAM2 rom_bput(uaecptr, uae_u32) REGPARAM;
|
||||
static uae_u8 *REGPARAM2 rom_xlate(uaecptr addr) REGPARAM;
|
||||
|
||||
static uintptr ROMBaseDiff; // ROMBaseHost - ROMBaseMac
|
||||
static size_t ROMBaseDiff; // ROMBaseHost - ROMBaseMac
|
||||
|
||||
uae_u32 REGPARAM2 rom_lget(uaecptr addr)
|
||||
{
|
||||
|
@ -343,7 +343,7 @@ static void REGPARAM2 frame_host_888_lput(uaecptr, uae_u32) REGPARAM;
|
|||
|
||||
static uae_u8 *REGPARAM2 frame_xlate(uaecptr addr) REGPARAM;
|
||||
|
||||
static uintptr FrameBaseDiff; // MacFrameBaseHost - MacFrameBaseMac
|
||||
static size_t FrameBaseDiff; // MacFrameBaseHost - MacFrameBaseMac
|
||||
|
||||
uae_u32 REGPARAM2 frame_direct_lget(uaecptr addr)
|
||||
{
|
||||
|
@ -585,12 +585,12 @@ void memory_init(void){
|
|||
for(long i=0; i<65536; i++)
|
||||
put_mem_bank(i<<16, &dummy_bank);
|
||||
|
||||
// RAM must not overlap ROM
|
||||
assert(RAMSize<ROMBaseMac);
|
||||
// Limit RAM size to not overlap ROM
|
||||
uint32 ram_size = RAMSize > ROMBaseMac ? ROMBaseMac : RAMSize;
|
||||
|
||||
RAMBaseDiff = (uintptr)RAMBaseHost - (uintptr)RAMBaseMac;
|
||||
ROMBaseDiff = (uintptr)ROMBaseHost - (uintptr)ROMBaseMac;
|
||||
FrameBaseDiff = (uintptr)MacFrameBaseHost - (uintptr)MacFrameBaseMac;
|
||||
RAMBaseDiff = (size_t)RAMBaseHost - RAMBaseMac;
|
||||
ROMBaseDiff = (size_t)ROMBaseHost - ROMBaseMac;
|
||||
FrameBaseDiff = (size_t)MacFrameBaseHost - MacFrameBaseMac;
|
||||
|
||||
// Map RAM, ROM and display
|
||||
if (TwentyFourBitAddressing) {
|
||||
|
|
|
@ -118,7 +118,7 @@ extern void byteput(uaecptr addr, uae_u32 b);
|
|||
#endif /* !DIRECT_ADDRESSING */
|
||||
|
||||
#if DIRECT_ADDRESSING
|
||||
extern uintptr MEMBaseDiff;
|
||||
extern size_t MEMBaseDiff;
|
||||
|
||||
static __inline__ uae_u8 *do_get_real_address(uaecptr addr)
|
||||
{
|
||||
|
@ -126,7 +126,7 @@ static __inline__ uae_u8 *do_get_real_address(uaecptr addr)
|
|||
}
|
||||
static __inline__ uae_u32 do_get_virtual_address(uae_u8 *addr)
|
||||
{
|
||||
return (uintptr)addr - MEMBaseDiff;
|
||||
return (size_t)addr - MEMBaseDiff;
|
||||
}
|
||||
static __inline__ uae_u32 get_long(uaecptr addr)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user