]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
PPC update.
authorToni Wilen <twilen@winuae.net>
Wed, 10 Sep 2014 14:12:21 +0000 (17:12 +0300)
committerToni Wilen <twilen@winuae.net>
Wed, 10 Sep 2014 14:12:21 +0000 (17:12 +0300)
include/uae/ppc.h
ppc/ppc.cpp

index c1570eb99e5b8f02f90924d5d176795146c63990..404ad8e506ed12256d07cd7880a52e15c23c8847 100644 (file)
@@ -94,6 +94,7 @@ typedef struct PPCMemoryRegion {
 } PPCMemoryRegion;
 
 bool PPCCALL ppc_cpu_init(uint32_t pvr);
+bool PPCCALL ppc_cpu_init_with_model(const char *model);
 void PPCCALL ppc_cpu_free(void);
 void PPCCALL ppc_cpu_stop(void);
 void PPCCALL ppc_cpu_atomic_raise_ext_exception(void);
index 68bb1401d7728f2c020082fa62aa53e55aa5afde..2f50065d6eef0b27a4963e586484142f8484caa9 100644 (file)
@@ -30,6 +30,9 @@
 
 #ifdef _WIN32
 static volatile unsigned int ppc_spinlock, spinlock_cnt;
+#else
+#include <glib.h>
+static GMutex mutex;
 #endif
 
 void uae_ppc_spinlock_get(void)
@@ -39,16 +42,12 @@ void uae_ppc_spinlock_get(void)
        if (sp != 0 && sp != 1)
                write_log(_T("uae_ppc_spinlock_get invalid %d\n"),  sp);
 
-       while (true)
-       {
-               if(InterlockedCompareExchange(&ppc_spinlock, 1, 0) == 0) {
-                       if (spinlock_cnt)
-                               write_log(_T("uae_ppc_spinlock_get %d!\n"), spinlock_cnt);
-                       spinlock_cnt = 1;
-                       break;
-               }
-       }
+       while (InterlockedExchange (&ppc_spinlock, 1));
+       if (spinlock_cnt)
+               write_log(_T("uae_ppc_spinlock_get %d!\n"), spinlock_cnt);
+       spinlock_cnt = 1;
 #else
+       g_mutex_lock(&mutex);
 #endif
 }
 void uae_ppc_spinlock_release(void)
@@ -58,6 +57,7 @@ void uae_ppc_spinlock_release(void)
                write_log(_T("uae_ppc_spinlock_release %d!\n"), spinlock_cnt);
        InterlockedExchange(&ppc_spinlock, 0);
 #else
+       g_mutex_unlock(&mutex);
 #endif
 }
 void uae_ppc_spinlock_reset(void)
@@ -87,6 +87,7 @@ static int ppc_implementation;
 /* Dummy PPC implementation */
 
 static bool PPCCALL dummy_ppc_cpu_init(uint32_t pvr) { return false; }
+static bool PPCCALL dummy_ppc_cpu_init_with_model(const char *model) { return false; }
 static void PPCCALL dummy_ppc_cpu_free(void) { }
 static void PPCCALL dummy_ppc_cpu_stop(void) { }
 static void PPCCALL dummy_ppc_cpu_atomic_raise_ext_exception(void) { }
@@ -105,6 +106,7 @@ static void PPCCALL dummy_ppc_cpu_pause(int pause)
 /* Functions typedefs for PPC implementation */
 
 typedef bool (PPCCALL *ppc_cpu_init_function)(uint32_t pvr);
+typedef bool (PPCCALL *ppc_cpu_init_with_model_function)(const char *model);
 typedef void (PPCCALL *ppc_cpu_free_function)(void);
 typedef void (PPCCALL *ppc_cpu_stop_function)(void);
 typedef void (PPCCALL *ppc_cpu_atomic_raise_ext_exception_function)(void);
@@ -120,6 +122,7 @@ typedef void (PPCCALL *ppc_cpu_pause_function)(int pause);
 /* Function pointers to active PPC implementation */
 
 static ppc_cpu_init_function g_ppc_cpu_init;
+static ppc_cpu_init_with_model_function g_ppc_cpu_init_with_model;
 static ppc_cpu_free_function g_ppc_cpu_free;
 static ppc_cpu_stop_function g_ppc_cpu_stop;
 static ppc_cpu_atomic_raise_ext_exception_function g_ppc_cpu_atomic_raise_ext_exception;
@@ -136,6 +139,7 @@ static void load_dummy_implementation()
 {
        write_log(_T("PPC: Loading dummy implementation\n"));
        g_ppc_cpu_init = dummy_ppc_cpu_init;
+       g_ppc_cpu_init_with_model = dummy_ppc_cpu_init_with_model;
        g_ppc_cpu_free = dummy_ppc_cpu_free;
        g_ppc_cpu_stop = dummy_ppc_cpu_stop;
        g_ppc_cpu_atomic_raise_ext_exception = dummy_ppc_cpu_atomic_raise_ext_exception;
@@ -179,13 +183,15 @@ static bool load_qemu_implementation()
        // implemented separately by WinUAE and FS-UAE.
        UAE_DLHANDLE handle = uae_dlopen(_T("qemu-uae.dll"));
        if (!handle) {
-               write_log(_T("Error loading qemu-uae library\n"));
+               gui_message(_T("PPC: Error loading qemu-uae library\n"));
                return false;
        }
        write_log(_T("PPC: Loaded qemu-uae library at %p\n"), handle);
 
        /* get function pointers */
+
        g_ppc_cpu_init = (ppc_cpu_init_function) uae_dlsym(handle, "ppc_cpu_init");
+       g_ppc_cpu_init_with_model = (ppc_cpu_init_with_model_function) uae_dlsym(handle, "ppc_cpu_init_with_model");
        g_ppc_cpu_free = (ppc_cpu_free_function) uae_dlsym(handle, "ppc_cpu_free");
        g_ppc_cpu_stop = (ppc_cpu_stop_function) uae_dlsym(handle, "ppc_cpu_stop");
        g_ppc_cpu_atomic_raise_ext_exception = (ppc_cpu_atomic_raise_ext_exception_function) uae_dlsym(handle, "ppc_cpu_atomic_raise_ext_exception");
@@ -215,6 +221,7 @@ static bool load_pearpc_implementation()
 {
        write_log(_T("PPC: Loading PearPC implementation\n"));
        g_ppc_cpu_init = ppc_cpu_init;
+       g_ppc_cpu_init_with_model = NULL;
        g_ppc_cpu_free = ppc_cpu_free;
        g_ppc_cpu_stop = ppc_cpu_stop;
        g_ppc_cpu_atomic_raise_ext_exception = ppc_cpu_atomic_raise_ext_exception;
@@ -292,14 +299,57 @@ static void map_banks(void)
        }
 }
 
+static void cpu_init()
+{
+       const TCHAR *model;
+
+       /* Setting default CPU model based on accelerator board */
+       if (currprefs.cpuboard_type == BOARD_BLIZZARDPPC) {
+               model = _T("603ev");
+       } else {
+               model = _T("604e");
+       }
+
+        /* Override PPC CPU model. See qemu/target-ppc/cpu-models.c for
+         * a list of valid CPU model identifiers */
+#if 0
+       // FIXME: if ppc_model is overridden in currprefs, point to option
+       if (currprefs.ppc_model[0]) {
+               model = currprefs.ppc_model
+       }
+#endif
+
+       if (g_ppc_cpu_init_with_model) {
+               char *models = ua(model);
+               g_ppc_cpu_init_with_model(models);
+               free(models);
+       } else {
+               uint32_t pvr = 0;
+               if (_tcsicmp(model, _T("603ev")) == 0) {
+                       pvr = BLIZZPPC_PVR;
+               }
+               else if (_tcsicmp(model, _T("604e")) == 0) {
+                       pvr = CSPPC_PVR;
+               }
+               else {
+                       pvr = CSPPC_PVR;
+                       write_log(_T("PPC: Unrecognized model \"%s\", using PVR 0x%08x\n"), model, pvr);
+               }
+               write_log(_T("PPC: Calling ppc_cpu_init with PVR 0x%08x\n"), pvr);
+               g_ppc_cpu_init(pvr);
+       }
+
+       /* Map memory and I/O banks (for QEmu PPC implementation) */
+       map_banks();
+}
+
 static void uae_ppc_cpu_reset(void)
 {
        TRACE(_T("uae_ppc_cpu_reset\n"));
        initialize();
        if (!ppc_cpu_init_done) {
                write_log(_T("PPC: Hard reset\n"));
-               g_ppc_cpu_init(currprefs.cpuboard_type == BOARD_BLIZZARDPPC ? BLIZZPPC_PVR : CSPPC_PVR);
-               map_banks();
+               cpu_init();
                ppc_cpu_init_done = true;
        }
        write_log(_T("PPC: Init\n"));
@@ -589,7 +639,7 @@ void uae_ppc_interrupt(bool active)
 // sleep until interrupt (or PPC stopped)
 void uae_ppc_doze(void)
 {
-       TRACE(_T("uae_ppc_doze\n"));
+       //TRACE(_T("uae_ppc_doze\n"));
        if (!ppc_thread_running)
                return;
        ppc_state = PPC_STATE_SLEEP;