]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
QEMU PPC support updates.
authorToni Wilen <twilen@winuae.net>
Mon, 1 Sep 2014 14:45:29 +0000 (17:45 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 1 Sep 2014 14:45:29 +0000 (17:45 +0300)
debug.cpp
dlopen.cpp
include/memory.h
include/ppc.h [deleted file]
include/uae/ppc.h
newcpu.cpp
ppc/ppc.cpp

index 97950841b9fc9227afb3b0ba060caa4bc8f6917d..2cdb1f86fe103f60b8b6f0fb6f20f39054b744df 100644 (file)
--- 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("<none>");
+                       }
 
                        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);
 }
 
index 01a48e1a8dedbf21a3453c4e521964ebdcdd0088..3a34f77cdd5df844dcc06c1164d28652803f76cf 100644 (file)
@@ -8,11 +8,16 @@
 #include <dlfcn.h>
 #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);
index c7f088185970b2dd8a4342800b3ae8f8b3299633..8723129fb48948f9a749afff2ca17eaa61912129 100644 (file)
@@ -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 (file)
index ec563b6..0000000
+++ /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 <stdint.h>
-#include <stdbool.h>
-
-/* 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
index f95045e7fe4b95f12595634275903cb1ca88a7c0..caf3191c1cf7ac0fac1da5957c718a7a9e721101 100644 (file)
@@ -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 */
 
index 2fbde9c789112e2b047e22bb4ea75c73ec041a24..b9fc120ed2309170d051f3b7185e97eb793d0e29 100644 (file)
@@ -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();
index 5b3cce87672990ae6e8d7cba000c5fe649da0aae..77f41cca7056757b8e16a154849a5896ccf28993 100644 (file)
@@ -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);
+       }
+}