From: Toni Wilen Date: Mon, 1 Sep 2014 14:45:29 +0000 (+0300) Subject: QEMU PPC support updates. X-Git-Tag: 3000~63 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=02255c4a8d2236a143d444300ae86c766a72ef98;p=francis%2Fwinuae.git QEMU PPC support updates. --- diff --git a/debug.cpp b/debug.cpp index 97950841..2cdb1f86 100644 --- a/debug.cpp +++ b/debug.cpp @@ -40,6 +40,7 @@ #include "cpummu030.h" #include "ar.h" #include "ppc/ppcd.h" +#include "uae/ppc.h" int debugger_active; static uaecptr skipaddr_start, skipaddr_end; @@ -2893,13 +2894,37 @@ static uae_u8 *dump_xlate (uae_u32 addr) return mem_banks[addr >> 16]->xlateaddr (addr); } -static void memory_map_dump_2 (int log) +#if 0 +#define UAE_MEMORY_REGIONS_MAX 64 +#define UAE_MEMORY_REGION_NAME_LENGTH 64 + +#define UAE_MEMORY_REGION_RAM (1 << 0) +#define UAE_MEMORY_REGION_ALIAS (1 << 1) +#define UAE_MEMORY_REGION_MIRROR (1 << 2) + +typedef struct UaeMemoryRegion { + uaecptr start; + int size; + TCHAR name[UAE_MEMORY_REGION_NAME_LENGTH]; + TCHAR rom_name[UAE_MEMORY_REGION_NAME_LENGTH]; + uaecptr alias; + int flags; +} UaeMemoryRegion; + +typedef struct UaeMemoryMap { + UaeMemoryRegion regions[UAE_MEMORY_REGIONS_MAX]; + int num_regions; +} UaeMemoryMap; +#endif + +static void memory_map_dump_3(UaeMemoryMap *map, int log) { bool imold; int i, j, max; addrbank *a1 = mem_banks[0]; TCHAR txt[256]; + map->num_regions = 0; imold = currprefs.illegal_mem; currprefs.illegal_mem = false; max = currprefs.address_space_24 ? 256 : 65536; @@ -2912,12 +2937,12 @@ static void memory_map_dump_2 (int log) int k, mirrored, mirrored2, size, size_out; TCHAR size_ext; uae_u8 *caddr; - const TCHAR *name; TCHAR tmp[MAX_DPATH]; - name = a1->name; - if (name == NULL) + const TCHAR *name = a1->name; + if (name == NULL) { name = _T(""); + } k = j; caddr = dump_xlate (k << 16); @@ -2938,9 +2963,10 @@ static void memory_map_dump_2 (int log) size_out /= 1024; size_ext = 'M'; } +#if 1 _stprintf (txt, _T("%08X %7d%c/%d = %7d%c %s"), j << 16, size_out, size_ext, mirrored, mirrored ? size_out / mirrored : size_out, size_ext, name); - +#endif tmp[0] = 0; if (a1->flags == ABFLAG_ROM && mirrored) { TCHAR *p = txt + _tcslen (txt); @@ -2953,6 +2979,30 @@ static void memory_map_dump_2 (int log) _tcscat (tmp, _T("\n")); } } + + int region_size = ((i - j) << 16) / mirrored2; + for (int m = 0; m < mirrored2; m++) { + UaeMemoryRegion *r = &map->regions[map->num_regions]; + r->start = (j << 16) + region_size * m; + r->size = region_size; + r->flags = 0; + r->memory = NULL; + if (mirrored > 0) { + r->flags |= UAE_MEMORY_REGION_RAM; + r->memory = caddr; + } + /* just to make it easier to spot in debugger */ + r->alias = 0xffffffff; + if (m >= 0) { + r->alias = j << 16; + r->flags |= UAE_MEMORY_REGION_ALIAS | UAE_MEMORY_REGION_MIRROR; + } + _stprintf(r->name, _T("%s"), name); + _stprintf(r->rom_name, _T("%s"), tmp); + map->num_regions += 1; + } + +#if 1 _tcscat (txt, _T("\n")); if (log) write_log (txt); @@ -2964,15 +3014,50 @@ static void memory_map_dump_2 (int log) else console_out (tmp); } +#endif j = i; a1 = a2; } } currprefs.illegal_mem = imold; } -void memory_map_dump (void) + +void uae_memory_map(UaeMemoryMap *map) { - memory_map_dump_2 (1); + memory_map_dump_3(map, 0); +} + +static void memory_map_dump_2 (int log) +{ + UaeMemoryMap map; + memory_map_dump_3(&map, log); +#if 0 + for (int i = 0; i < map.num_regions; i++) { + TCHAR txt[256]; + UaeMemoryRegion *r = &map.regions[i]; + int size = r->size / 1024; + TCHAR size_ext = 'K'; + int mirrored = 1; + int size_out = 0; + _stprintf (txt, _T("%08X %7u%c/%d = %7u%c %s\n"), r->start, size, size_ext, + r->flags & UAE_MEMORY_REGION_RAM, size, size_ext, r->name); + if (log) + write_log (_T("%s"), txt); + else + console_out (txt); + if (r->rom_name[0]) { + if (log) + write_log (_T("%s"), r->rom_name); + else + console_out (r->rom_name); + } + } +#endif +} + +void memory_map_dump (void) + { + memory_map_dump_2 (1); } STATIC_INLINE uaecptr BPTR2APTR (uaecptr addr) @@ -3227,7 +3312,7 @@ static void show_exec_lists (TCHAR *t) get_word_debug(list + 16 + 4), get_byte_debug(list + 16 + 1), get_long_debug(list + 16 + 6), rom_vector, get_word_debug(list + 16 + 4), get_byte_debug(list + 16 + 1)); - if (1 || (type & 0x10)) { + if ((type & 0x10)) { uae_u8 diagarea[32]; uae_u16 nameoffset; uaecptr rom = addr + rom_vector; @@ -4588,6 +4673,9 @@ void debug (void) } wasactive = ismouseactive (); +#ifdef WITH_PPC + uae_ppc_pause(1); +#endif inputdevice_unacquire (); pause_sound (); setmouseactive (0); @@ -4627,6 +4715,9 @@ void debug (void) } resume_sound (); inputdevice_acquire (TRUE); +#ifdef WITH_PPC + uae_ppc_pause(0); +#endif setmouseactive (wasactive ? 2 : 0); } diff --git a/dlopen.cpp b/dlopen.cpp index 01a48e1a..3a34f77c 100644 --- a/dlopen.cpp +++ b/dlopen.cpp @@ -8,11 +8,16 @@ #include #endif -UAE_DLHANDLE uae_dlopen(const TCHAR *path) { -#ifdef _WIN32 - UAE_DLHANDLE result = LoadLibrary(path); +UAE_DLHANDLE uae_dlopen(const TCHAR *path) +{ + UAE_DLHANDLE result; +#ifdef WINUAE + extern HMODULE WIN32_LoadLibrary(const TCHAR *name); + result = WIN32_LoadLibrary(path); +#elif _WIN32 + result = LoadLibrary(path); #else - UAE_DLHANDLE result = dlopen(path, RTLD_NOW); + result = dlopen(path, RTLD_NOW); const char *error = dlerror(); if (error != NULL) { write_log("uae_dlopen failed: %s\n", error); diff --git a/include/memory.h b/include/memory.h index c7f08818..8723129f 100644 --- a/include/memory.h +++ b/include/memory.h @@ -558,4 +558,30 @@ extern void memcpyah (uae_u8 *dst, uaecptr src, int size); extern uae_s32 getz2size (struct uae_prefs *p); extern ULONG getz2endaddr (void); +#define UAE_MEMORY_REGIONS_MAX 64 +#define UAE_MEMORY_REGION_NAME_LENGTH 64 + +#define UAE_MEMORY_REGION_RAM (1 << 0) +#define UAE_MEMORY_REGION_ALIAS (1 << 1) +#define UAE_MEMORY_REGION_MIRROR (1 << 2) + +/* Get a list of memory regions in the Amiga address space */ + +typedef struct UaeMemoryRegion { + uaecptr start; + int size; + TCHAR name[UAE_MEMORY_REGION_NAME_LENGTH]; + TCHAR rom_name[UAE_MEMORY_REGION_NAME_LENGTH]; + uaecptr alias; + int flags; + uae_u8 *memory; +} UaeMemoryRegion; + +typedef struct UaeMemoryMap { + UaeMemoryRegion regions[UAE_MEMORY_REGIONS_MAX]; + int num_regions; +} UaeMemoryMap; + +void uae_memory_map(UaeMemoryMap *map); + #endif /* MEMORY_H */ diff --git a/include/ppc.h b/include/ppc.h deleted file mode 100644 index ec563b6a..00000000 --- a/include/ppc.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef UAE_PPC_H -#define UAE_PPC_H - -/* - * This file only consists of default includes, so it can safely be included - * in other projects (PearPC, QEmu) without pulling in lots of headers. - */ - -#include -#include - -/* PPC_EXTERN_C is defined (on the UAE side) when compiling with QEmu CPU. */ -#ifndef PPC_EXTERN_C -/* - * If it is not defined, we are either compiling "on the QEmu side (C)", or - * the file is used with the PearPC implementation. In both cases, - * PPC_EXTERN_C should expand to nothing. - */ -#define PPC_EXTERN_C -#endif - -/* UAE PPC functions */ - -void uae_ppc_doze(void); -void uae_ppc_sync (void); -void uae_ppc_crash(void); - -void uae_ppc_cpu_reboot(void); -void uae_ppc_cpu_stop(void); -bool uae_ppc_poll_queue(void); -void uae_ppc_interrupt(bool active); -void uae_ppc_cpu_lock(void); -bool uae_ppc_cpu_unlock(void); -void uae_ppc_to_main_thread(void); -void uae_ppc_emulate(void); -void uae_ppc_reset(bool hardreset); -void uae_ppc_hsync_handler(void); -void uae_ppc_wakeup(void); - -#define PPC_STATE_STOP 0 -#define PPC_STATE_ACTIVE 1 -#define PPC_STATE_SLEEP 2 -#define PPC_STATE_CRASH 3 - -extern volatile int ppc_state; - -#ifdef __cplusplus -bool uae_ppc_direct_physical_memory_handle(uint32_t addr, uint8_t *&ptr); -#endif - -PPC_EXTERN_C bool uae_ppc_io_mem_read(uint32_t addr, uint32_t *data, int size); -PPC_EXTERN_C bool uae_ppc_io_mem_write(uint32_t addr, uint32_t data, int size); - -bool uae_ppc_io_mem_read64(uint32_t addr, uint64_t *data); -bool uae_ppc_io_mem_write64(uint32_t addr, uint64_t data); - -extern int ppc_cycle_count; - -/* PPC CPU implementation */ - -PPC_EXTERN_C bool ppc_cpu_init(uint32_t pvr); -PPC_EXTERN_C void ppc_cpu_free(void); - -PPC_EXTERN_C void ppc_cpu_stop(void); - -PPC_EXTERN_C void ppc_cpu_atomic_raise_ext_exception(void); -PPC_EXTERN_C void ppc_cpu_atomic_cancel_ext_exception(void); - -PPC_EXTERN_C void ppc_cpu_map_memory(uint32_t addr, uint32_t size, void *memory, const char *name); - -PPC_EXTERN_C void ppc_cpu_set_pc(int cpu, uint32_t value); -PPC_EXTERN_C void ppc_cpu_run_continuous(void); -PPC_EXTERN_C void ppc_cpu_run_single(int count); - -PPC_EXTERN_C uint64_t ppc_cpu_get_dec(void); -PPC_EXTERN_C void ppc_cpu_do_dec(int value); - -#if 0 -uint32 ppc_cpu_get_gpr(int cpu, int i); -void ppc_cpu_set_gpr(int cpu, int i, uint32 newvalue); -void ppc_cpu_set_msr(int cpu, uint32 newvalue); -uint32 ppc_cpu_get_pc(int cpu); -uint32 ppc_cpu_get_pvr(int cpu); -#endif - -#endif // UAE_PPC_H diff --git a/include/uae/ppc.h b/include/uae/ppc.h index f95045e7..caf3191c 100644 --- a/include/uae/ppc.h +++ b/include/uae/ppc.h @@ -35,11 +35,17 @@ bool uae_ppc_poll_queue(void); void uae_ppc_interrupt(bool active); void uae_ppc_cpu_lock(void); bool uae_ppc_cpu_unlock(void); -void uae_ppc_to_main_thread(void); +bool uae_ppc_to_main_thread(void); void uae_ppc_emulate(void); void uae_ppc_reset(bool hardreset); void uae_ppc_hsync_handler(void); void uae_ppc_wakeup(void); +/** + * Pauses the PPC emulation (for some implementations). Currently triggers + * a simple pause implementation intended only for debugging. + * @param pause Whether to pause (1) or not (0). + */ +void uae_ppc_pause(int pause); #ifdef __cplusplus bool uae_ppc_direct_physical_memory_handle(uint32_t addr, uint8_t *&ptr); @@ -75,17 +81,26 @@ extern uae_ppc_io_mem_write64_function uae_ppc_io_mem_write64; /* Prototypes for PPC CPU implementation, used by PearPC and QEmu */ +typedef struct PPCMemoryRegion { + uint32_t start; + uint32_t size; + void *memory; + const char *name; + uint32_t alias; +} PPCMemoryRegion; + bool PPCCALL ppc_cpu_init(uint32_t pvr); void PPCCALL ppc_cpu_free(void); void PPCCALL ppc_cpu_stop(void); void PPCCALL ppc_cpu_atomic_raise_ext_exception(void); void PPCCALL ppc_cpu_atomic_cancel_ext_exception(void); -void PPCCALL ppc_cpu_map_memory(uint32_t addr, uint32_t size, void *memory, const char *name); +void PPCCALL ppc_cpu_map_memory(PPCMemoryRegion *regions, int count); void PPCCALL ppc_cpu_set_pc(int cpu, uint32_t value); void PPCCALL ppc_cpu_run_continuous(void); void PPCCALL ppc_cpu_run_single(int count); uint64_t PPCCALL ppc_cpu_get_dec(void); void PPCCALL ppc_cpu_do_dec(int value); +void PPCCALL ppc_cpu_pause(int pause); /* Other PPC defines */ diff --git a/newcpu.cpp b/newcpu.cpp index 2fbde9c7..b9fc120e 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -3169,9 +3169,10 @@ static void uae_ppc_poll_check(void) static bool haltloop(void) { #ifdef WITH_PPC + bool ppc_main_thread = false; // m68k stopped? Move PPC emulator to main thread. if (regs.halted < 0) { - uae_ppc_to_main_thread(); + ppc_main_thread = uae_ppc_to_main_thread(); } #endif @@ -3193,7 +3194,7 @@ static bool haltloop(void) do_copper(); #ifdef WITH_PPC - if (regs.halted < 0) + if (ppc_main_thread && regs.halted < 0) uae_ppc_emulate(); else uae_ppc_poll_check(); diff --git a/ppc/ppc.cpp b/ppc/ppc.cpp index 5b3cce87..77f41cca 100644 --- a/ppc/ppc.cpp +++ b/ppc/ppc.cpp @@ -19,7 +19,7 @@ #endif #define PPC_SYNC_WRITE 0 -#define PPC_ACCESS_LOG 2 +#define PPC_ACCESS_LOG 0 #define TRACE(format, ...) write_log(_T("PPC: ---------------- ") format, ## __VA_ARGS__) @@ -33,6 +33,7 @@ static volatile bool ppc_access; static volatile int ppc_cpu_lock_state; static bool ppc_main_thread; static bool ppc_init_done; +static int ppc_implementation; #define CSPPC_PVR 0x00090204 #define BLIZZPPC_PVR 0x00070101 @@ -47,13 +48,17 @@ 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) { } static void PPCCALL dummy_ppc_cpu_atomic_cancel_ext_exception(void) { } -static void PPCCALL dummy_ppc_cpu_map_memory(uint32_t addr, uint32_t size, void *memory, const char *name) { } +static void PPCCALL dummy_ppc_cpu_map_memory(PPCMemoryRegion *regions, int count) { } static void PPCCALL dummy_ppc_cpu_set_pc(int cpu, uint32_t value) { } static void PPCCALL dummy_ppc_cpu_run_continuous(void) { } static void PPCCALL dummy_ppc_cpu_run_single(int count) { } static uint64_t PPCCALL dummy_ppc_cpu_get_dec(void) { return 0; } static void PPCCALL dummy_ppc_cpu_do_dec(int value) { } +static void PPCCALL dummy_ppc_cpu_pause(int pause) +{ +} + /* Functions typedefs for PPC implementation */ typedef bool (PPCCALL *ppc_cpu_init_function)(uint32_t pvr); @@ -61,12 +66,13 @@ 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); typedef void (PPCCALL *ppc_cpu_atomic_cancel_ext_exception_function)(void); -typedef void (PPCCALL *ppc_cpu_map_memory_function)(uint32_t addr, uint32_t size, void *memory, const char *name); +typedef void (PPCCALL *ppc_cpu_map_memory_function)(PPCMemoryRegion *regions, int count); typedef void (PPCCALL *ppc_cpu_set_pc_function)(int cpu, uint32_t value); typedef void (PPCCALL *ppc_cpu_run_continuous_function)(void); typedef void (PPCCALL *ppc_cpu_run_single_function)(int count); typedef uint64_t (PPCCALL *ppc_cpu_get_dec_function)(void); typedef void (PPCCALL *ppc_cpu_do_dec_function)(int value); +typedef void (PPCCALL *ppc_cpu_pause_function)(int pause); /* Function pointers to active PPC implementation */ @@ -81,6 +87,7 @@ static ppc_cpu_run_continuous_function g_ppc_cpu_run_continuous; static ppc_cpu_run_single_function g_ppc_cpu_run_single; static ppc_cpu_get_dec_function g_ppc_cpu_get_dec; static ppc_cpu_do_dec_function g_ppc_cpu_do_dec; +static ppc_cpu_pause_function g_ppc_cpu_pause; static void load_dummy_implementation() { @@ -96,6 +103,7 @@ static void load_dummy_implementation() g_ppc_cpu_run_single = dummy_ppc_cpu_run_single; g_ppc_cpu_get_dec = dummy_ppc_cpu_get_dec; g_ppc_cpu_do_dec = dummy_ppc_cpu_do_dec; + g_ppc_cpu_pause = dummy_ppc_cpu_pause; } #ifdef WITH_QEMU_CPU @@ -145,6 +153,7 @@ static bool load_qemu_implementation() g_ppc_cpu_run_single = (ppc_cpu_run_single_function) uae_dlsym(handle, "ppc_cpu_run_single"); g_ppc_cpu_get_dec = (ppc_cpu_get_dec_function) uae_dlsym(handle, "ppc_cpu_get_dec"); g_ppc_cpu_do_dec = (ppc_cpu_do_dec_function) uae_dlsym(handle, "ppc_cpu_do_dec"); + g_ppc_cpu_pause = (ppc_cpu_pause_function) uae_dlsym(handle, "ppc_cpu_pause"); #if 0 /* register callback functions */ @@ -183,21 +192,24 @@ static bool load_pearpc_implementation() static void load_ppc_implementation() { int impl = currprefs.ppc_implementation; -#ifdef WITH_PEARPC_CPU - if (impl == PPC_IMPLEMENTATION_AUTO || impl == PPC_IMPLEMENTATION_PEARPC) { - if (load_pearpc_implementation()) { +#ifdef WITH_QEMU_CPU + if (impl == PPC_IMPLEMENTATION_AUTO || impl == PPC_IMPLEMENTATION_QEMU) { + if (load_qemu_implementation()) { + ppc_implementation = PPC_IMPLEMENTATION_QEMU; return; } } #endif -#ifdef WITH_QEMU_CPU - if (impl == PPC_IMPLEMENTATION_AUTO || impl == PPC_IMPLEMENTATION_QEMU) { - if (load_qemu_implementation()) { +#ifdef WITH_PEARPC_CPU + if (impl == PPC_IMPLEMENTATION_AUTO || impl == PPC_IMPLEMENTATION_PEARPC) { + if (load_pearpc_implementation()) { + ppc_implementation = PPC_IMPLEMENTATION_PEARPC; return; } } #endif load_dummy_implementation(); + ppc_implementation = 0; } static void initialize() @@ -219,22 +231,22 @@ static void map_banks(void) * to allow all memory access to go via callbacks). */ - // FIXME: hack, replace with automatic / dynamic mapping -#if 1 - g_ppc_cpu_map_memory(0x00000000, 2048 KB, NULL, "Chip memory"); - g_ppc_cpu_map_memory(0x00BF0000, 64 KB, NULL, "CIA"); - g_ppc_cpu_map_memory(0x00F00000, 256 KB, get_real_address(0x00F00000), "CPUBoard F00000"); - g_ppc_cpu_map_memory(0x00F50000, 192 KB, NULL, "CPUBoard IO"); - g_ppc_cpu_map_memory(0x00DF0000, 64 KB, NULL, "Custom chipset"); - g_ppc_cpu_map_memory(0x08000000, 16 MB, get_real_address(0x08000000), "RAMSEY memory (high)"); - g_ppc_cpu_map_memory(0xFFF00000, 512 KB, get_real_address(0xFFF00000), "CPUBoard MAPROM"); -#else - g_ppc_cpu_map_memory(0x00BF0000, 64 KB, NULL, "CIA"); - g_ppc_cpu_map_memory(0x00F00000, 256 KB, NULL, "CPUBoard F00000"); - g_ppc_cpu_map_memory(0x00F50000, 192 KB, NULL, "CPUBoard IO"); - g_ppc_cpu_map_memory(0x08000000, 16 MB, NULL, "RAMSEY memory (high)"); - g_ppc_cpu_map_memory(0xFFF00000, 512 KB, get_real_address(0xFFF00000), "CPUBoard MAPROM"); -#endif + PPCMemoryRegion regions[UAE_MEMORY_REGIONS_MAX]; + UaeMemoryMap map; + uae_memory_map(&map); + + for (int i = 0; i < map.num_regions; i++) { + UaeMemoryRegion *r = &map.regions[i]; + regions[i].start = r->start; + regions[i].size = r->size; + regions[i].name = ua(r->name); + regions[i].alias = r->alias; + regions[i].memory = r->memory; + } + g_ppc_cpu_map_memory(regions, map.num_regions); + for (int i = 0; i < map.num_regions; i++) { + free((void*)regions[i].name); + } } static void uae_ppc_cpu_reset(void) @@ -272,9 +284,14 @@ static void *ppc_thread(void *v) return NULL; } -void uae_ppc_to_main_thread(void) +bool uae_ppc_to_main_thread(void) { TRACE(_T("uae_ppc_to_main_thread\n")); + + // QEMU: not yet supported + if (ppc_implementation == PPC_IMPLEMENTATION_QEMU) + return false; + if (ppc_thread_running) { write_log(_T("PPC: transferring PPC emulation to main thread.\n")); uae_ppc_cpu_stop(); @@ -287,11 +304,12 @@ void uae_ppc_to_main_thread(void) } ppc_state = PPC_STATE_ACTIVE; ppc_main_thread = true; + return true; } void uae_ppc_emulate(void) { - TRACE(_T("uae_ppc_emulate\n")); + //TRACE(_T("uae_ppc_emulate\n")); if (ppc_state == PPC_STATE_ACTIVE || ppc_state == PPC_STATE_SLEEP) g_ppc_cpu_run_single(10); } @@ -587,14 +605,14 @@ bool uae_ppc_cpu_unlock(void) void uae_ppc_wakeup(void) { - TRACE(_T("uae_ppc_wakeup\n")); + //TRACE(_T("uae_ppc_wakeup\n")); if (ppc_state == PPC_STATE_SLEEP) ppc_state = PPC_STATE_ACTIVE; } void uae_ppc_interrupt(bool active) { - TRACE(_T("uae_ppc_interrupt\n")); + //TRACE(_T("uae_ppc_interrupt\n")); if (active) { g_ppc_cpu_atomic_raise_ext_exception(); uae_ppc_wakeup(); @@ -632,3 +650,10 @@ void uae_ppc_hsync_handler(void) g_ppc_cpu_do_dec(ppc_cycle_count); } } + +void uae_ppc_pause(int pause) +{ + if (g_ppc_cpu_pause) { + g_ppc_cpu_pause(pause); + } +}