mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-08-10 09:25:03 +00:00
Hope it works
This commit is contained in:
@@ -104,6 +104,8 @@ set_source_files_properties(${BasiliskII_SRCS}
|
|||||||
|
|
||||||
target_link_libraries(BasiliskII ${COREFOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${SDL_LIBRARY})
|
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" )
|
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pagezero_size 0x2000" )
|
||||||
|
|
||||||
add_definitions(-march=native)
|
add_definitions(-march=native)
|
||||||
|
@@ -83,27 +83,17 @@ bool TwentyFourBitAddressing;
|
|||||||
|
|
||||||
static uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes
|
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 bool xpram_thread_active = false; // Flag: XPRAM watchdog installed
|
||||||
static volatile bool xpram_thread_cancel = false; // Flag: Cancel XPRAM thread
|
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 bool tick_thread_active = false; // Flag: 60Hz thread installed
|
||||||
static volatile bool tick_thread_cancel = false; // Flag: Cancel 60Hz thread
|
static volatile bool tick_thread_cancel = false; // Flag: Cancel 60Hz thread
|
||||||
static pthread_t tick_thread; // 60Hz thread
|
static SDL_Thread *tick_thread; // 60Hz thread
|
||||||
static pthread_attr_t tick_thread_attr; // 60Hz thread attributes
|
|
||||||
|
|
||||||
static pthread_mutex_t intflag_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to protect InterruptFlags
|
static SDL_mutex *intflag_lock = NULL; // Mutex to protect InterruptFlags
|
||||||
#define LOCK_INTFLAGS pthread_mutex_lock(&intflag_lock)
|
#define LOCK_INTFLAGS SDL_LockMutex(intflag_lock)
|
||||||
#define UNLOCK_INTFLAGS pthread_mutex_unlock(&intflag_lock)
|
#define UNLOCK_INTFLAGS SDL_UnlockMutex(intflag_lock)
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define LOCK_INTFLAGS
|
|
||||||
#define UNLOCK_INTFLAGS
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if USE_SCRATCHMEM_SUBTERFUGE
|
#if USE_SCRATCHMEM_SUBTERFUGE
|
||||||
uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes
|
uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes
|
||||||
@@ -124,8 +114,8 @@ static const char *gui_connection_path = NULL; // GUI connection identifier
|
|||||||
|
|
||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
static void *xpram_func(void *arg);
|
static int xpram_func(void *arg);
|
||||||
static void *tick_func(void *arg);
|
static int tick_func(void *arg);
|
||||||
static void one_tick(...);
|
static void one_tick(...);
|
||||||
|
|
||||||
|
|
||||||
@@ -482,11 +472,10 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
|
|
||||||
#ifndef USE_CPU_EMUL_SERVICES
|
#ifndef USE_CPU_EMUL_SERVICES
|
||||||
#if defined(HAVE_PTHREADS)
|
#ifdef USE_SDL
|
||||||
|
|
||||||
// POSIX threads available, start 60Hz thread
|
// SDL threads available, start 60Hz thread
|
||||||
Set_pthread_attr(&tick_thread_attr, 0);
|
tick_thread_active = ((tick_thread = SDL_CreateThread(tick_func, NULL)) != NULL);
|
||||||
tick_thread_active = (pthread_create(&tick_thread, &tick_thread_attr, tick_func, NULL) == 0);
|
|
||||||
if (!tick_thread_active) {
|
if (!tick_thread_active) {
|
||||||
sprintf(str, GetString(STR_TICK_THREAD_ERR), strerror(errno));
|
sprintf(str, GetString(STR_TICK_THREAD_ERR), strerror(errno));
|
||||||
ErrorAlert(str);
|
ErrorAlert(str);
|
||||||
@@ -494,60 +483,13 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
D(bug("60Hz thread started\n"));
|
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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PTHREADS_SERVICES
|
#ifdef USE_SDL
|
||||||
// Start XPRAM watchdog thread
|
// Start XPRAM watchdog thread
|
||||||
memcpy(last_xpram, XPRAM, XPRAM_SIZE);
|
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"));
|
D(bug("XPRAM thread started\n"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -573,41 +515,17 @@ void QuitEmulator(void)
|
|||||||
Exit680x0();
|
Exit680x0();
|
||||||
#endif
|
#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
|
// Stop 60Hz thread
|
||||||
if (tick_thread_active) {
|
if (tick_thread_active) {
|
||||||
tick_thread_cancel = true;
|
tick_thread_cancel = true;
|
||||||
#ifdef HAVE_PTHREAD_CANCEL
|
SDL_WaitThread(tick_thread, NULL);
|
||||||
pthread_cancel(tick_thread);
|
|
||||||
#endif
|
|
||||||
pthread_join(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
|
// Stop XPRAM watchdog thread
|
||||||
if (xpram_thread_active) {
|
if (xpram_thread_active) {
|
||||||
xpram_thread_cancel = true;
|
xpram_thread_cancel = true;
|
||||||
#ifdef HAVE_PTHREAD_CANCEL
|
SDL_WaitThread(xpram_thread, NULL);
|
||||||
pthread_cancel(xpram_thread);
|
|
||||||
#endif
|
|
||||||
pthread_join(xpram_thread, NULL);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Deinitialize everything
|
// Deinitialize everything
|
||||||
ExitAll();
|
ExitAll();
|
||||||
@@ -659,71 +577,14 @@ void FlushCodeCache(void *start, uint32 size)
|
|||||||
#endif
|
#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
|
* Mutexes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_PTHREADS
|
|
||||||
|
|
||||||
struct B2_mutex {
|
struct B2_mutex {
|
||||||
B2_mutex() {
|
B2_mutex() { m = SDL_CreateMutex(); }
|
||||||
pthread_mutexattr_t attr;
|
~B2_mutex() { if (m) SDL_DestroyMutex(m); }
|
||||||
pthread_mutexattr_init(&attr);
|
SDL_mutex *m;
|
||||||
// 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 *B2_create_mutex(void)
|
B2_mutex *B2_create_mutex(void)
|
||||||
@@ -733,12 +594,14 @@ B2_mutex *B2_create_mutex(void)
|
|||||||
|
|
||||||
void B2_lock_mutex(B2_mutex *mutex)
|
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)
|
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)
|
void B2_delete_mutex(B2_mutex *mutex)
|
||||||
@@ -746,33 +609,6 @@ void B2_delete_mutex(B2_mutex *mutex)
|
|||||||
delete 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!)
|
* Interrupt flags (must be handled atomically!)
|
||||||
*/
|
*/
|
||||||
@@ -808,17 +644,15 @@ static void xpram_watchdog(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_PTHREADS_SERVICES
|
static int xpram_func(void *arg)
|
||||||
static void *xpram_func(void *arg)
|
|
||||||
{
|
{
|
||||||
while (!xpram_thread_cancel) {
|
while (!xpram_thread_cancel) {
|
||||||
for (int i=0; i<60 && !xpram_thread_cancel; i++)
|
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
|
Delay_usec(999999); // Only wait 1 second so we quit promptly when xpram_thread_cancel becomes true
|
||||||
xpram_watchdog();
|
xpram_watchdog();
|
||||||
}
|
}
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -832,14 +666,6 @@ static void one_second(void)
|
|||||||
|
|
||||||
SetInterruptFlag(INTFLAG_1HZ);
|
SetInterruptFlag(INTFLAG_1HZ);
|
||||||
TriggerInterrupt();
|
TriggerInterrupt();
|
||||||
|
|
||||||
#ifndef USE_PTHREADS_SERVICES
|
|
||||||
static int second_counter = 0;
|
|
||||||
if (++second_counter > 60) {
|
|
||||||
second_counter = 0;
|
|
||||||
xpram_watchdog();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void one_tick(...)
|
static void one_tick(...)
|
||||||
@@ -850,16 +676,6 @@ static void one_tick(...)
|
|||||||
one_second();
|
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
|
// Trigger 60Hz interrupt
|
||||||
if (ROMVersion != ROM_VERSION_CLASSIC || HasMacStarted()) {
|
if (ROMVersion != ROM_VERSION_CLASSIC || HasMacStarted()) {
|
||||||
SetInterruptFlag(INTFLAG_60HZ);
|
SetInterruptFlag(INTFLAG_60HZ);
|
||||||
@@ -867,8 +683,7 @@ static void one_tick(...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_PTHREADS_SERVICES
|
static int tick_func(void *arg)
|
||||||
static void *tick_func(void *arg)
|
|
||||||
{
|
{
|
||||||
uint64 start = GetTicks_usec();
|
uint64 start = GetTicks_usec();
|
||||||
int64 ticks = 0;
|
int64 ticks = 0;
|
||||||
@@ -878,17 +693,15 @@ static void *tick_func(void *arg)
|
|||||||
next += 16625;
|
next += 16625;
|
||||||
int64 delay = next - GetTicks_usec();
|
int64 delay = next - GetTicks_usec();
|
||||||
if (delay > 0)
|
if (delay > 0)
|
||||||
Delay_usec(delay);
|
Delay_usec(uint32(delay));
|
||||||
else if (delay < -16625)
|
else if (delay < -16625)
|
||||||
next = GetTicks_usec();
|
next = GetTicks_usec();
|
||||||
ticks++;
|
ticks++;
|
||||||
}
|
}
|
||||||
uint64 end = GetTicks_usec();
|
uint64 end = GetTicks_usec();
|
||||||
D(bug("%lld ticks in %lld usec = %f ticks/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start)));
|
D(bug("%Ld ticks in %Ld usec = %f ticks/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start)));
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display error alert
|
* Display error alert
|
||||||
|
@@ -315,51 +315,54 @@ void Delay_usec(uint32 usec)
|
|||||||
* Suspend emulator thread, virtual CPU in idle mode
|
* Suspend emulator thread, virtual CPU in idle mode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_PTHREADS
|
// #ifdef HAVE_PTHREADS
|
||||||
#if defined(HAVE_PTHREAD_COND_INIT)
|
// #if defined(HAVE_PTHREAD_COND_INIT)
|
||||||
#define IDLE_USES_COND_WAIT 1
|
// #define IDLE_USES_COND_WAIT 1
|
||||||
static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER;
|
// static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_cond_t idle_cond = PTHREAD_COND_INITIALIZER;
|
// static pthread_cond_t idle_cond = PTHREAD_COND_INITIALIZER;
|
||||||
#elif defined(HAVE_SEM_INIT)
|
// #elif defined(HAVE_SEM_INIT)
|
||||||
#define IDLE_USES_SEMAPHORE 1
|
// #define IDLE_USES_SEMAPHORE 1
|
||||||
#include <semaphore.h>
|
// #include <semaphore.h>
|
||||||
#ifdef HAVE_SPINLOCKS
|
// #ifdef HAVE_SPINLOCKS
|
||||||
static spinlock_t idle_lock = SPIN_LOCK_UNLOCKED;
|
// static spinlock_t idle_lock = SPIN_LOCK_UNLOCKED;
|
||||||
#define LOCK_IDLE spin_lock(&idle_lock)
|
// #define LOCK_IDLE spin_lock(&idle_lock)
|
||||||
#define UNLOCK_IDLE spin_unlock(&idle_lock)
|
// #define UNLOCK_IDLE spin_unlock(&idle_lock)
|
||||||
#else
|
// #else
|
||||||
static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER;
|
// static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
#define LOCK_IDLE pthread_mutex_lock(&idle_lock)
|
// #define LOCK_IDLE pthread_mutex_lock(&idle_lock)
|
||||||
#define UNLOCK_IDLE pthread_mutex_unlock(&idle_lock)
|
// #define UNLOCK_IDLE pthread_mutex_unlock(&idle_lock)
|
||||||
#endif
|
// #endif
|
||||||
static sem_t idle_sem;
|
// static sem_t idle_sem;
|
||||||
static int idle_sem_ok = -1;
|
// static int idle_sem_ok = -1;
|
||||||
#endif
|
// #endif
|
||||||
#endif
|
// #endif
|
||||||
|
|
||||||
void idle_wait(void)
|
void idle_wait(void)
|
||||||
{
|
{
|
||||||
#ifdef IDLE_USES_COND_WAIT
|
//This causes events to not process randomly in JIT so commented out
|
||||||
pthread_mutex_lock(&idle_lock);
|
usleep(10);
|
||||||
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
|
// #ifdef IDLE_USES_COND_WAIT
|
||||||
Delay_usec(10000);
|
// pthread_mutex_lock(&idle_lock);
|
||||||
#endif
|
// 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)
|
void idle_resume(void)
|
||||||
{
|
{
|
||||||
#ifdef IDLE_USES_COND_WAIT
|
//This causes events to not process randomly in JIT so commented out
|
||||||
pthread_cond_signal(&idle_cond);
|
// #ifdef IDLE_USES_COND_WAIT
|
||||||
#else
|
// pthread_cond_signal(&idle_cond);
|
||||||
#ifdef IDLE_USES_SEMAPHORE
|
// #else
|
||||||
LOCK_IDLE;
|
// #ifdef IDLE_USES_SEMAPHORE
|
||||||
if (idle_sem_ok > 1) {
|
// LOCK_IDLE;
|
||||||
idle_sem_ok--;
|
// if (idle_sem_ok > 1) {
|
||||||
UNLOCK_IDLE;
|
// idle_sem_ok--;
|
||||||
sem_post(&idle_sem);
|
// UNLOCK_IDLE;
|
||||||
return;
|
// sem_post(&idle_sem);
|
||||||
}
|
// return;
|
||||||
UNLOCK_IDLE;
|
// }
|
||||||
#endif
|
// UNLOCK_IDLE;
|
||||||
#endif
|
// #endif
|
||||||
|
// #endif
|
||||||
}
|
}
|
||||||
|
@@ -159,7 +159,7 @@ void TriggerInterrupt(void)
|
|||||||
|
|
||||||
void TriggerNMI(void)
|
void TriggerNMI(void)
|
||||||
{
|
{
|
||||||
//!! not implemented yet
|
SPCFLAGS_SET( SPCFLAG_BRK ); // use _BRK for NMI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -35,6 +35,11 @@
|
|||||||
// #include "sysconfig.h"
|
// #include "sysconfig.h"
|
||||||
#include "newcpu.h"
|
#include "newcpu.h"
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define CPU_64_BIT 1
|
||||||
|
#define CPU_x86_64 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef UAE
|
#ifdef UAE
|
||||||
#ifdef CPU_64_BIT
|
#ifdef CPU_64_BIT
|
||||||
typedef uae_u64 uintptr;
|
typedef uae_u64 uintptr;
|
||||||
|
@@ -43,6 +43,12 @@
|
|||||||
#error "Only [LS]AHF scheme to [gs]et flags is supported with the JIT Compiler"
|
#error "Only [LS]AHF scheme to [gs]et flags is supported with the JIT Compiler"
|
||||||
#endif
|
#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
|
/* NOTE: support for AMD64 assumes translation cache and other code
|
||||||
* buffers are allocated into a 32-bit address space because (i) B2/JIT
|
* 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
|
* code is not 64-bit clean and (ii) it's faster to resolve branches
|
||||||
@@ -254,7 +260,7 @@ uae_u8* comp_pc_p;
|
|||||||
#else
|
#else
|
||||||
// External variables
|
// External variables
|
||||||
// newcpu.cpp
|
// newcpu.cpp
|
||||||
extern int quit_program;
|
extern bool quit_program;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// gb-- Extra data for Basilisk II/JIT
|
// 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;
|
blockinfo *bi = active;
|
||||||
while (bi) {
|
while (bi) {
|
||||||
#if USE_CHECKSUM_INFO
|
#if USE_CHECKSUM_INFO
|
||||||
bool candidate = false;
|
bool invalidate = false;
|
||||||
for (checksum_info *csi = bi->csi; csi; csi = csi->next) {
|
for (checksum_info *csi = bi->csi; csi && !invalidate; csi = csi->next)
|
||||||
if (((start_p - csi->start_p) < csi->length) ||
|
invalidate = (((start_p - csi->start_p) < csi->length) ||
|
||||||
((csi->start_p - start_p) < length)) {
|
((csi->start_p - start_p) < length));
|
||||||
candidate = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
// Assume system is consistent and would invalidate the right range
|
// 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
|
#endif
|
||||||
blockinfo *dbi = bi;
|
if (invalidate) {
|
||||||
bi = bi->next;
|
uae_u32 cl = cacheline(bi->pc_p);
|
||||||
if (candidate) {
|
if (bi == cache_tags[cl + 1].bi)
|
||||||
uae_u32 cl = cacheline(dbi->pc_p);
|
|
||||||
if (dbi->status == BI_INVALID || dbi->status == BI_NEED_RECOMP) {
|
|
||||||
if (dbi == cache_tags[cl+1].bi)
|
|
||||||
cache_tags[cl].handler = (cpuop_func *)popall_execute_normal;
|
cache_tags[cl].handler = (cpuop_func *)popall_execute_normal;
|
||||||
dbi->handler_to_use = (cpuop_func *)popall_execute_normal;
|
bi->handler_to_use = (cpuop_func *)popall_execute_normal;
|
||||||
set_dhtu(dbi, dbi->direct_pen);
|
set_dhtu(bi, bi->direct_pen);
|
||||||
dbi->status = BI_INVALID;
|
bi->status = BI_NEED_RECOMP;
|
||||||
}
|
|
||||||
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 = bi->next;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
#else
|
||||||
|
// UNUSED(start);
|
||||||
|
// UNUSED(length);
|
||||||
#endif
|
#endif
|
||||||
flush_icache(-1);
|
flush_icache(-1);
|
||||||
}
|
}
|
||||||
@@ -5138,15 +5131,11 @@ void m68k_compile_execute (void)
|
|||||||
setjmpagain:
|
setjmpagain:
|
||||||
TRY(prb) {
|
TRY(prb) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (quit_program > 0) {
|
if (quit_program == 1) {
|
||||||
if (quit_program == 1) {
|
|
||||||
#if FLIGHT_RECORDER
|
#if FLIGHT_RECORDER
|
||||||
dump_flight_recorder();
|
dump_flight_recorder();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
quit_program = 0;
|
|
||||||
m68k_reset ();
|
|
||||||
}
|
}
|
||||||
m68k_do_compile_execute();
|
m68k_do_compile_execute();
|
||||||
}
|
}
|
||||||
|
@@ -854,11 +854,11 @@ int m68k_move2c (int regno, uae_u32 *regp)
|
|||||||
case 0: regs.sfc = *regp & 7; break;
|
case 0: regs.sfc = *regp & 7; break;
|
||||||
case 1: regs.dfc = *regp & 7; break;
|
case 1: regs.dfc = *regp & 7; break;
|
||||||
case 2:
|
case 2:
|
||||||
cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000);
|
regs.cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000);
|
||||||
#if USE_JIT
|
#if USE_JIT
|
||||||
set_cache_state(regs.cacr & 0x8000);
|
set_cache_state(regs.cacr & 0x8000);
|
||||||
if (*regp & 0x08) { /* Just to be on the safe side */
|
if (*regp & 0x08) { /* Just to be on the safe side */
|
||||||
flush_icache(2);
|
flush_icache(1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
@@ -1267,6 +1267,9 @@ void mmu_op(uae_u32 opcode, uae_u16 extra)
|
|||||||
if ((opcode & 0xFE0) == 0x0500) {
|
if ((opcode & 0xFE0) == 0x0500) {
|
||||||
/* PFLUSH */
|
/* PFLUSH */
|
||||||
mmusr = 0;
|
mmusr = 0;
|
||||||
|
#ifdef USE_JIT
|
||||||
|
flush_icache(0);
|
||||||
|
#endif
|
||||||
} else if ((opcode & 0x0FD8) == 0x548) {
|
} else if ((opcode & 0x0FD8) == 0x548) {
|
||||||
/* PTEST */
|
/* PTEST */
|
||||||
} else
|
} else
|
||||||
|
Reference in New Issue
Block a user