From ddee848342c959d2df927c5e5bf4c39e985d3839 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 10 Sep 2014 17:12:21 +0300 Subject: [PATCH] PPC update. --- include/uae/ppc.h | 1 + ppc/ppc.cpp | 76 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/include/uae/ppc.h b/include/uae/ppc.h index c1570eb9..404ad8e5 100644 --- a/include/uae/ppc.h +++ b/include/uae/ppc.h @@ -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); diff --git a/ppc/ppc.cpp b/ppc/ppc.cpp index 68bb1401..2f50065d 100644 --- a/ppc/ppc.cpp +++ b/ppc/ppc.cpp @@ -30,6 +30,9 @@ #ifdef _WIN32 static volatile unsigned int ppc_spinlock, spinlock_cnt; +#else +#include +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; -- 2.47.3