mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-02-16 14:30:34 +00:00
Hope it works
This commit is contained in:
parent
77e20bda2a
commit
8353a9ed44
@ -104,6 +104,8 @@ set_source_files_properties(${BasiliskII_SRCS}
|
||||
|
||||
target_link_libraries(BasiliskII ${COREFOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${SDL_LIBRARY})
|
||||
|
||||
# set(CMAKE_POSITION_INDEPENDENT_CODE OFF)
|
||||
|
||||
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pagezero_size 0x2000" )
|
||||
|
||||
add_definitions(-march=native)
|
||||
|
@ -83,27 +83,17 @@ bool TwentyFourBitAddressing;
|
||||
|
||||
static uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
|
||||
static bool xpram_thread_active = false; // Flag: XPRAM watchdog installed
|
||||
static volatile bool xpram_thread_cancel = false; // Flag: Cancel XPRAM thread
|
||||
static pthread_t xpram_thread; // XPRAM watchdog
|
||||
static SDL_Thread *xpram_thread = NULL; // XPRAM watchdog
|
||||
|
||||
static bool tick_thread_active = false; // Flag: 60Hz thread installed
|
||||
static volatile bool tick_thread_cancel = false; // Flag: Cancel 60Hz thread
|
||||
static pthread_t tick_thread; // 60Hz thread
|
||||
static pthread_attr_t tick_thread_attr; // 60Hz thread attributes
|
||||
static SDL_Thread *tick_thread; // 60Hz thread
|
||||
|
||||
static pthread_mutex_t intflag_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to protect InterruptFlags
|
||||
#define LOCK_INTFLAGS pthread_mutex_lock(&intflag_lock)
|
||||
#define UNLOCK_INTFLAGS pthread_mutex_unlock(&intflag_lock)
|
||||
|
||||
#else
|
||||
|
||||
#define LOCK_INTFLAGS
|
||||
#define UNLOCK_INTFLAGS
|
||||
|
||||
#endif
|
||||
static SDL_mutex *intflag_lock = NULL; // Mutex to protect InterruptFlags
|
||||
#define LOCK_INTFLAGS SDL_LockMutex(intflag_lock)
|
||||
#define UNLOCK_INTFLAGS SDL_UnlockMutex(intflag_lock)
|
||||
|
||||
#if USE_SCRATCHMEM_SUBTERFUGE
|
||||
uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes
|
||||
@ -124,8 +114,8 @@ static const char *gui_connection_path = NULL; // GUI connection identifier
|
||||
|
||||
|
||||
// Prototypes
|
||||
static void *xpram_func(void *arg);
|
||||
static void *tick_func(void *arg);
|
||||
static int xpram_func(void *arg);
|
||||
static int tick_func(void *arg);
|
||||
static void one_tick(...);
|
||||
|
||||
|
||||
@ -482,11 +472,10 @@ int main(int argc, char **argv)
|
||||
|
||||
|
||||
#ifndef USE_CPU_EMUL_SERVICES
|
||||
#if defined(HAVE_PTHREADS)
|
||||
#ifdef USE_SDL
|
||||
|
||||
// POSIX threads available, start 60Hz thread
|
||||
Set_pthread_attr(&tick_thread_attr, 0);
|
||||
tick_thread_active = (pthread_create(&tick_thread, &tick_thread_attr, tick_func, NULL) == 0);
|
||||
// SDL threads available, start 60Hz thread
|
||||
tick_thread_active = ((tick_thread = SDL_CreateThread(tick_func, NULL)) != NULL);
|
||||
if (!tick_thread_active) {
|
||||
sprintf(str, GetString(STR_TICK_THREAD_ERR), strerror(errno));
|
||||
ErrorAlert(str);
|
||||
@ -494,60 +483,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
D(bug("60Hz thread started\n"));
|
||||
|
||||
#elif defined(HAVE_TIMER_CREATE) && defined(_POSIX_REALTIME_SIGNALS)
|
||||
|
||||
// POSIX.4 timers and real-time signals available, start 60Hz timer
|
||||
sigemptyset(&timer_sa.sa_mask);
|
||||
timer_sa.sa_sigaction = (void (*)(int, siginfo_t *, void *))one_tick;
|
||||
timer_sa.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
if (sigaction(SIG_TIMER, &timer_sa, NULL) < 0) {
|
||||
sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIG_TIMER", strerror(errno));
|
||||
ErrorAlert(str);
|
||||
QuitEmulator();
|
||||
}
|
||||
struct sigevent timer_event;
|
||||
timer_event.sigev_notify = SIGEV_SIGNAL;
|
||||
timer_event.sigev_signo = SIG_TIMER;
|
||||
if (timer_create(CLOCK_REALTIME, &timer_event, &timer) < 0) {
|
||||
sprintf(str, GetString(STR_TIMER_CREATE_ERR), strerror(errno));
|
||||
ErrorAlert(str);
|
||||
QuitEmulator();
|
||||
}
|
||||
struct itimerspec req;
|
||||
req.it_value.tv_sec = 0;
|
||||
req.it_value.tv_nsec = 16625000;
|
||||
req.it_interval.tv_sec = 0;
|
||||
req.it_interval.tv_nsec = 16625000;
|
||||
if (timer_settime(timer, 0, &req, NULL) < 0) {
|
||||
sprintf(str, GetString(STR_TIMER_SETTIME_ERR), strerror(errno));
|
||||
ErrorAlert(str);
|
||||
QuitEmulator();
|
||||
}
|
||||
D(bug("60Hz timer started\n"));
|
||||
|
||||
#else
|
||||
|
||||
// Start 60Hz timer
|
||||
sigemptyset(&timer_sa.sa_mask); // Block virtual 68k interrupts during SIGARLM handling
|
||||
timer_sa.sa_handler = one_tick;
|
||||
timer_sa.sa_flags = SA_ONSTACK | SA_RESTART;
|
||||
if (sigaction(SIGALRM, &timer_sa, NULL) < 0) {
|
||||
sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIGALRM", strerror(errno));
|
||||
ErrorAlert(str);
|
||||
QuitEmulator();
|
||||
}
|
||||
struct itimerval req;
|
||||
req.it_interval.tv_sec = req.it_value.tv_sec = 0;
|
||||
req.it_interval.tv_usec = req.it_value.tv_usec = 16625;
|
||||
setitimer(ITIMER_REAL, &req, NULL);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_PTHREADS_SERVICES
|
||||
#ifdef USE_SDL
|
||||
// Start XPRAM watchdog thread
|
||||
memcpy(last_xpram, XPRAM, XPRAM_SIZE);
|
||||
xpram_thread_active = (pthread_create(&xpram_thread, NULL, xpram_func, NULL) == 0);
|
||||
xpram_thread_active = ((xpram_thread = SDL_CreateThread(xpram_func, NULL)) != NULL);
|
||||
D(bug("XPRAM thread started\n"));
|
||||
#endif
|
||||
|
||||
@ -573,41 +515,17 @@ void QuitEmulator(void)
|
||||
Exit680x0();
|
||||
#endif
|
||||
|
||||
#if defined(USE_CPU_EMUL_SERVICES)
|
||||
// Show statistics
|
||||
uint64 emulated_ticks_end = GetTicks_usec();
|
||||
D(bug("%ld ticks in %ld usec = %f ticks/sec [%ld tick checks]\n",
|
||||
(long)emulated_ticks_count, (long)(emulated_ticks_end - emulated_ticks_start),
|
||||
emulated_ticks_count * 1000000.0 / (emulated_ticks_end - emulated_ticks_start), (long)n_check_ticks));
|
||||
#elif defined(USE_PTHREADS_SERVICES)
|
||||
// Stop 60Hz thread
|
||||
if (tick_thread_active) {
|
||||
tick_thread_cancel = true;
|
||||
#ifdef HAVE_PTHREAD_CANCEL
|
||||
pthread_cancel(tick_thread);
|
||||
#endif
|
||||
pthread_join(tick_thread, NULL);
|
||||
SDL_WaitThread(tick_thread, NULL);
|
||||
}
|
||||
#elif defined(HAVE_TIMER_CREATE) && defined(_POSIX_REALTIME_SIGNALS)
|
||||
// Stop 60Hz timer
|
||||
timer_delete(timer);
|
||||
#else
|
||||
struct itimerval req;
|
||||
req.it_interval.tv_sec = req.it_value.tv_sec = 0;
|
||||
req.it_interval.tv_usec = req.it_value.tv_usec = 0;
|
||||
setitimer(ITIMER_REAL, &req, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef USE_PTHREADS_SERVICES
|
||||
// Stop XPRAM watchdog thread
|
||||
if (xpram_thread_active) {
|
||||
xpram_thread_cancel = true;
|
||||
#ifdef HAVE_PTHREAD_CANCEL
|
||||
pthread_cancel(xpram_thread);
|
||||
#endif
|
||||
pthread_join(xpram_thread, NULL);
|
||||
SDL_WaitThread(xpram_thread, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Deinitialize everything
|
||||
ExitAll();
|
||||
@ -659,71 +577,14 @@ void FlushCodeCache(void *start, uint32 size)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
/*
|
||||
* Pthread configuration
|
||||
*/
|
||||
|
||||
void Set_pthread_attr(pthread_attr_t *attr, int priority)
|
||||
{
|
||||
pthread_attr_init(attr);
|
||||
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
|
||||
// Some of these only work for superuser
|
||||
if (geteuid() == 0) {
|
||||
pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
|
||||
pthread_attr_setschedpolicy(attr, SCHED_FIFO);
|
||||
struct sched_param fifo_param;
|
||||
fifo_param.sched_priority = ((sched_get_priority_min(SCHED_FIFO) +
|
||||
sched_get_priority_max(SCHED_FIFO)) / 2 +
|
||||
priority);
|
||||
pthread_attr_setschedparam(attr, &fifo_param);
|
||||
}
|
||||
if (pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM) != 0) {
|
||||
#ifdef PTHREAD_SCOPE_BOUND_NP
|
||||
// If system scope is not available (eg. we're not running
|
||||
// with CAP_SCHED_MGT capability on an SGI box), try bound
|
||||
// scope. It exposes pthread scheduling to the kernel,
|
||||
// without setting realtime priority.
|
||||
pthread_attr_setscope(attr, PTHREAD_SCOPE_BOUND_NP);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // HAVE_PTHREADS
|
||||
|
||||
|
||||
/*
|
||||
* Mutexes
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
|
||||
struct B2_mutex {
|
||||
B2_mutex() {
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
// Initialize the mutex for priority inheritance --
|
||||
// required for accurate timing.
|
||||
#if defined(HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL) && !defined(__CYGWIN__)
|
||||
pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
|
||||
#endif
|
||||
#if defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) && defined(PTHREAD_MUTEX_NORMAL)
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
|
||||
#endif
|
||||
#ifdef HAVE_PTHREAD_MUTEXATTR_SETPSHARED
|
||||
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
|
||||
#endif
|
||||
pthread_mutex_init(&m, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
~B2_mutex() {
|
||||
pthread_mutex_trylock(&m); // Make sure it's locked before
|
||||
pthread_mutex_unlock(&m); // unlocking it.
|
||||
pthread_mutex_destroy(&m);
|
||||
}
|
||||
pthread_mutex_t m;
|
||||
B2_mutex() { m = SDL_CreateMutex(); }
|
||||
~B2_mutex() { if (m) SDL_DestroyMutex(m); }
|
||||
SDL_mutex *m;
|
||||
};
|
||||
|
||||
B2_mutex *B2_create_mutex(void)
|
||||
@ -733,12 +594,14 @@ B2_mutex *B2_create_mutex(void)
|
||||
|
||||
void B2_lock_mutex(B2_mutex *mutex)
|
||||
{
|
||||
pthread_mutex_lock(&mutex->m);
|
||||
if (mutex)
|
||||
SDL_LockMutex(mutex->m);
|
||||
}
|
||||
|
||||
void B2_unlock_mutex(B2_mutex *mutex)
|
||||
{
|
||||
pthread_mutex_unlock(&mutex->m);
|
||||
if (mutex)
|
||||
SDL_UnlockMutex(mutex->m);
|
||||
}
|
||||
|
||||
void B2_delete_mutex(B2_mutex *mutex)
|
||||
@ -746,33 +609,6 @@ void B2_delete_mutex(B2_mutex *mutex)
|
||||
delete mutex;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct B2_mutex {
|
||||
int dummy;
|
||||
};
|
||||
|
||||
B2_mutex *B2_create_mutex(void)
|
||||
{
|
||||
return new B2_mutex;
|
||||
}
|
||||
|
||||
void B2_lock_mutex(B2_mutex *mutex)
|
||||
{
|
||||
}
|
||||
|
||||
void B2_unlock_mutex(B2_mutex *mutex)
|
||||
{
|
||||
}
|
||||
|
||||
void B2_delete_mutex(B2_mutex *mutex)
|
||||
{
|
||||
delete mutex;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Interrupt flags (must be handled atomically!)
|
||||
*/
|
||||
@ -808,17 +644,15 @@ static void xpram_watchdog(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_PTHREADS_SERVICES
|
||||
static void *xpram_func(void *arg)
|
||||
static int xpram_func(void *arg)
|
||||
{
|
||||
while (!xpram_thread_cancel) {
|
||||
for (int i=0; i<60 && !xpram_thread_cancel; i++)
|
||||
Delay_usec(999999); // Only wait 1 second so we quit promptly when xpram_thread_cancel becomes true
|
||||
xpram_watchdog();
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@ -832,14 +666,6 @@ static void one_second(void)
|
||||
|
||||
SetInterruptFlag(INTFLAG_1HZ);
|
||||
TriggerInterrupt();
|
||||
|
||||
#ifndef USE_PTHREADS_SERVICES
|
||||
static int second_counter = 0;
|
||||
if (++second_counter > 60) {
|
||||
second_counter = 0;
|
||||
xpram_watchdog();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void one_tick(...)
|
||||
@ -850,16 +676,6 @@ static void one_tick(...)
|
||||
one_second();
|
||||
}
|
||||
|
||||
#ifndef USE_PTHREADS_SERVICES
|
||||
// Threads not used to trigger interrupts, perform video refresh from here
|
||||
VideoRefresh();
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PTHREADS
|
||||
// No threads available, perform networking from here
|
||||
SetInterruptFlag(INTFLAG_ETHER);
|
||||
#endif
|
||||
|
||||
// Trigger 60Hz interrupt
|
||||
if (ROMVersion != ROM_VERSION_CLASSIC || HasMacStarted()) {
|
||||
SetInterruptFlag(INTFLAG_60HZ);
|
||||
@ -867,8 +683,7 @@ static void one_tick(...)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_PTHREADS_SERVICES
|
||||
static void *tick_func(void *arg)
|
||||
static int tick_func(void *arg)
|
||||
{
|
||||
uint64 start = GetTicks_usec();
|
||||
int64 ticks = 0;
|
||||
@ -878,17 +693,15 @@ static void *tick_func(void *arg)
|
||||
next += 16625;
|
||||
int64 delay = next - GetTicks_usec();
|
||||
if (delay > 0)
|
||||
Delay_usec(delay);
|
||||
Delay_usec(uint32(delay));
|
||||
else if (delay < -16625)
|
||||
next = GetTicks_usec();
|
||||
ticks++;
|
||||
}
|
||||
uint64 end = GetTicks_usec();
|
||||
D(bug("%lld ticks in %lld usec = %f ticks/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start)));
|
||||
return NULL;
|
||||
D(bug("%Ld ticks in %Ld usec = %f ticks/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start)));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Display error alert
|
||||
|
@ -315,51 +315,54 @@ void Delay_usec(uint32 usec)
|
||||
* Suspend emulator thread, virtual CPU in idle mode
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
#if defined(HAVE_PTHREAD_COND_INIT)
|
||||
#define IDLE_USES_COND_WAIT 1
|
||||
static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t idle_cond = PTHREAD_COND_INITIALIZER;
|
||||
#elif defined(HAVE_SEM_INIT)
|
||||
#define IDLE_USES_SEMAPHORE 1
|
||||
#include <semaphore.h>
|
||||
#ifdef HAVE_SPINLOCKS
|
||||
static spinlock_t idle_lock = SPIN_LOCK_UNLOCKED;
|
||||
#define LOCK_IDLE spin_lock(&idle_lock)
|
||||
#define UNLOCK_IDLE spin_unlock(&idle_lock)
|
||||
#else
|
||||
static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define LOCK_IDLE pthread_mutex_lock(&idle_lock)
|
||||
#define UNLOCK_IDLE pthread_mutex_unlock(&idle_lock)
|
||||
#endif
|
||||
static sem_t idle_sem;
|
||||
static int idle_sem_ok = -1;
|
||||
#endif
|
||||
#endif
|
||||
// #ifdef HAVE_PTHREADS
|
||||
// #if defined(HAVE_PTHREAD_COND_INIT)
|
||||
// #define IDLE_USES_COND_WAIT 1
|
||||
// static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
// static pthread_cond_t idle_cond = PTHREAD_COND_INITIALIZER;
|
||||
// #elif defined(HAVE_SEM_INIT)
|
||||
// #define IDLE_USES_SEMAPHORE 1
|
||||
// #include <semaphore.h>
|
||||
// #ifdef HAVE_SPINLOCKS
|
||||
// static spinlock_t idle_lock = SPIN_LOCK_UNLOCKED;
|
||||
// #define LOCK_IDLE spin_lock(&idle_lock)
|
||||
// #define UNLOCK_IDLE spin_unlock(&idle_lock)
|
||||
// #else
|
||||
// static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
// #define LOCK_IDLE pthread_mutex_lock(&idle_lock)
|
||||
// #define UNLOCK_IDLE pthread_mutex_unlock(&idle_lock)
|
||||
// #endif
|
||||
// static sem_t idle_sem;
|
||||
// static int idle_sem_ok = -1;
|
||||
// #endif
|
||||
// #endif
|
||||
|
||||
void idle_wait(void)
|
||||
{
|
||||
#ifdef IDLE_USES_COND_WAIT
|
||||
pthread_mutex_lock(&idle_lock);
|
||||
pthread_cond_wait(&idle_cond, &idle_lock);
|
||||
pthread_mutex_unlock(&idle_lock);
|
||||
#else
|
||||
#ifdef IDLE_USES_SEMAPHORE
|
||||
LOCK_IDLE;
|
||||
if (idle_sem_ok < 0)
|
||||
idle_sem_ok = (sem_init(&idle_sem, 0, 0) == 0);
|
||||
if (idle_sem_ok > 0) {
|
||||
idle_sem_ok++;
|
||||
UNLOCK_IDLE;
|
||||
sem_wait(&idle_sem);
|
||||
return;
|
||||
}
|
||||
UNLOCK_IDLE;
|
||||
#endif
|
||||
//This causes events to not process randomly in JIT so commented out
|
||||
usleep(10);
|
||||
|
||||
// Fallback: sleep 10 ms
|
||||
Delay_usec(10000);
|
||||
#endif
|
||||
// #ifdef IDLE_USES_COND_WAIT
|
||||
// pthread_mutex_lock(&idle_lock);
|
||||
// pthread_cond_wait(&idle_cond, &idle_lock);
|
||||
// pthread_mutex_unlock(&idle_lock);
|
||||
// #else
|
||||
// #ifdef IDLE_USES_SEMAPHORE
|
||||
// LOCK_IDLE;
|
||||
// if (idle_sem_ok < 0)
|
||||
// idle_sem_ok = (sem_init(&idle_sem, 0, 0) == 0);
|
||||
// if (idle_sem_ok > 0) {
|
||||
// idle_sem_ok++;
|
||||
// UNLOCK_IDLE;
|
||||
// sem_wait(&idle_sem);
|
||||
// return;
|
||||
// }
|
||||
// UNLOCK_IDLE;
|
||||
// #endif
|
||||
|
||||
// // Fallback: sleep 10 ms
|
||||
// Delay_usec(10000);
|
||||
// #endif
|
||||
}
|
||||
|
||||
|
||||
@ -369,18 +372,19 @@ void idle_wait(void)
|
||||
|
||||
void idle_resume(void)
|
||||
{
|
||||
#ifdef IDLE_USES_COND_WAIT
|
||||
pthread_cond_signal(&idle_cond);
|
||||
#else
|
||||
#ifdef IDLE_USES_SEMAPHORE
|
||||
LOCK_IDLE;
|
||||
if (idle_sem_ok > 1) {
|
||||
idle_sem_ok--;
|
||||
UNLOCK_IDLE;
|
||||
sem_post(&idle_sem);
|
||||
return;
|
||||
}
|
||||
UNLOCK_IDLE;
|
||||
#endif
|
||||
#endif
|
||||
//This causes events to not process randomly in JIT so commented out
|
||||
// #ifdef IDLE_USES_COND_WAIT
|
||||
// pthread_cond_signal(&idle_cond);
|
||||
// #else
|
||||
// #ifdef IDLE_USES_SEMAPHORE
|
||||
// LOCK_IDLE;
|
||||
// if (idle_sem_ok > 1) {
|
||||
// idle_sem_ok--;
|
||||
// UNLOCK_IDLE;
|
||||
// sem_post(&idle_sem);
|
||||
// return;
|
||||
// }
|
||||
// UNLOCK_IDLE;
|
||||
// #endif
|
||||
// #endif
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ void TriggerInterrupt(void)
|
||||
|
||||
void TriggerNMI(void)
|
||||
{
|
||||
//!! not implemented yet
|
||||
SPCFLAGS_SET( SPCFLAG_BRK ); // use _BRK for NMI
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,6 +35,11 @@
|
||||
// #include "sysconfig.h"
|
||||
#include "newcpu.h"
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define CPU_64_BIT 1
|
||||
#define CPU_x86_64 1
|
||||
#endif
|
||||
|
||||
#ifdef UAE
|
||||
#ifdef CPU_64_BIT
|
||||
typedef uae_u64 uintptr;
|
||||
|
@ -43,6 +43,12 @@
|
||||
#error "Only [LS]AHF scheme to [gs]et flags is supported with the JIT Compiler"
|
||||
#endif
|
||||
|
||||
//TODO: detect i386 and arm platforms
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define CPU_x86_64 1
|
||||
#endif
|
||||
|
||||
/* NOTE: support for AMD64 assumes translation cache and other code
|
||||
* buffers are allocated into a 32-bit address space because (i) B2/JIT
|
||||
* code is not 64-bit clean and (ii) it's faster to resolve branches
|
||||
@ -254,7 +260,7 @@ uae_u8* comp_pc_p;
|
||||
#else
|
||||
// External variables
|
||||
// newcpu.cpp
|
||||
extern int quit_program;
|
||||
extern bool quit_program;
|
||||
#endif
|
||||
|
||||
// gb-- Extra data for Basilisk II/JIT
|
||||
@ -4401,41 +4407,28 @@ void flush_icache_range(uae_u8 *start_p, uae_u32 length)
|
||||
blockinfo *bi = active;
|
||||
while (bi) {
|
||||
#if USE_CHECKSUM_INFO
|
||||
bool candidate = false;
|
||||
for (checksum_info *csi = bi->csi; csi; csi = csi->next) {
|
||||
if (((start_p - csi->start_p) < csi->length) ||
|
||||
((csi->start_p - start_p) < length)) {
|
||||
candidate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool invalidate = false;
|
||||
for (checksum_info *csi = bi->csi; csi && !invalidate; csi = csi->next)
|
||||
invalidate = (((start_p - csi->start_p) < csi->length) ||
|
||||
((csi->start_p - start_p) < length));
|
||||
#else
|
||||
// Assume system is consistent and would invalidate the right range
|
||||
const bool candidate = (bi->pc_p - start_p) < length;
|
||||
const bool invalidate = (bi->pc_p - start_p) < length;
|
||||
#endif
|
||||
blockinfo *dbi = bi;
|
||||
bi = bi->next;
|
||||
if (candidate) {
|
||||
uae_u32 cl = cacheline(dbi->pc_p);
|
||||
if (dbi->status == BI_INVALID || dbi->status == BI_NEED_RECOMP) {
|
||||
if (dbi == cache_tags[cl+1].bi)
|
||||
if (invalidate) {
|
||||
uae_u32 cl = cacheline(bi->pc_p);
|
||||
if (bi == cache_tags[cl + 1].bi)
|
||||
cache_tags[cl].handler = (cpuop_func *)popall_execute_normal;
|
||||
dbi->handler_to_use = (cpuop_func *)popall_execute_normal;
|
||||
set_dhtu(dbi, dbi->direct_pen);
|
||||
dbi->status = BI_INVALID;
|
||||
}
|
||||
else {
|
||||
if (dbi == cache_tags[cl+1].bi)
|
||||
cache_tags[cl].handler = (cpuop_func *)popall_check_checksum;
|
||||
dbi->handler_to_use = (cpuop_func *)popall_check_checksum;
|
||||
set_dhtu(dbi, dbi->direct_pcc);
|
||||
dbi->status = BI_NEED_CHECK;
|
||||
}
|
||||
remove_from_list(dbi);
|
||||
add_to_dormant(dbi);
|
||||
bi->handler_to_use = (cpuop_func *)popall_execute_normal;
|
||||
set_dhtu(bi, bi->direct_pen);
|
||||
bi->status = BI_NEED_RECOMP;
|
||||
}
|
||||
bi = bi->next;
|
||||
}
|
||||
return;
|
||||
#else
|
||||
// UNUSED(start);
|
||||
// UNUSED(length);
|
||||
#endif
|
||||
flush_icache(-1);
|
||||
}
|
||||
@ -5138,15 +5131,11 @@ void m68k_compile_execute (void)
|
||||
setjmpagain:
|
||||
TRY(prb) {
|
||||
for (;;) {
|
||||
if (quit_program > 0) {
|
||||
if (quit_program == 1) {
|
||||
if (quit_program == 1) {
|
||||
#if FLIGHT_RECORDER
|
||||
dump_flight_recorder();
|
||||
dump_flight_recorder();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
quit_program = 0;
|
||||
m68k_reset ();
|
||||
break;
|
||||
}
|
||||
m68k_do_compile_execute();
|
||||
}
|
||||
|
@ -854,11 +854,11 @@ int m68k_move2c (int regno, uae_u32 *regp)
|
||||
case 0: regs.sfc = *regp & 7; break;
|
||||
case 1: regs.dfc = *regp & 7; break;
|
||||
case 2:
|
||||
cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000);
|
||||
regs.cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000);
|
||||
#if USE_JIT
|
||||
set_cache_state(regs.cacr & 0x8000);
|
||||
if (*regp & 0x08) { /* Just to be on the safe side */
|
||||
flush_icache(2);
|
||||
flush_icache(1);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
@ -1267,6 +1267,9 @@ void mmu_op(uae_u32 opcode, uae_u16 extra)
|
||||
if ((opcode & 0xFE0) == 0x0500) {
|
||||
/* PFLUSH */
|
||||
mmusr = 0;
|
||||
#ifdef USE_JIT
|
||||
flush_icache(0);
|
||||
#endif
|
||||
} else if ((opcode & 0x0FD8) == 0x548) {
|
||||
/* PTEST */
|
||||
} else
|
||||
|
Loading…
x
Reference in New Issue
Block a user