--- /dev/null
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "uae/dlopen.h"
+#ifdef _WIN32
+
+#else
+#include <dlfcn.h>
+#endif
+
+UAE_DLHANDLE uae_dlopen(const TCHAR *path) {
+#ifdef _WIN32
+ UAE_DLHANDLE result = LoadLibrary(path);
+#else
+ UAE_DLHANDLE result = dlopen(path, RTLD_NOW);
+ const char *error = dlerror();
+ if (error != NULL) {
+ write_log("uae_dlopen failed: %s\n", error);
+ }
+#endif
+ return result;
+}
+
+void *uae_dlsym(UAE_DLHANDLE handle, const char *name)
+{
+#if 0
+ if (handle == NULL) {
+ return NULL;
+ }
+#endif
+#ifdef _WIN32
+ return (void *) GetProcAddress(handle, name);
+#else
+ return dlsym(handle, name);
+#endif
+}
+
+void uae_dlclose(UAE_DLHANDLE handle)
+{
+#ifdef _WIN32
+ FreeLibrary (handle);
+#else
+ dlclose(handle);
+#endif
+}
+
+#include "uae/log.h"
+
+void uae_patch_library_common(UAE_DLHANDLE handle)
+{
+ void *ptr;
+
+ ptr = uae_dlsym(handle, "uae_log");
+ if (ptr) *((uae_log_function *) ptr) = &uae_log;
+}
--- /dev/null
+/*
+ * Helpers used to export UAE functions for use with other modules
+ * Copyright (C) 2014 Frode Solheim
+ *
+ * Licensed under the terms of the GNU General Public License version 2.
+ * See the file 'COPYING' for full license text.
+ */
+
+#ifndef UAE_API_H
+#define UAE_API_H
+
+/* This file is intended to be included by external libraries as well,
+ * so don't pull in too much UAE-specific stuff. */
+
+#include "uae/attributes.h"
+
+/* Handy define so we can disable C++ name mangling without considering
+ * whether the source language is C or C++. */
+
+#ifdef __cplusplus
+#define UAE_EXTERN_C extern "C"
+#else
+#define UAE_EXTERN_C
+#endif
+
+/* UAE_EXPORT / UAE_IMPORT are mainly intended as helpers for UAEAPI
+ * defined below. */
+
+#ifdef _WIN32
+#define UAE_EXPORT __declspec(dllexport)
+#define UAE_IMPORT __declspec(dllimport)
+#else
+#define UAE_EXPORT __attribute__((visibility("default")))
+#define UAE_IMPORT
+#endif
+
+/* UAEAPI marks a function for export across library boundaries. You'll
+ * likely want to use this together with UAECALL. */
+
+#ifdef UAE
+#define UAEAPI UAE_EXTERN_C UAE_EXPORT
+#else
+#define UAEAPI UAE_EXTERN_C UAE_IMPORT
+#endif
+
+/* WinUAE (or external libs) might be compiled with fastcall by default,
+ * so we force all external functions to use cdecl calling convention. */
+
+#ifdef _WIN32
+#define UAECALL __cdecl
+#else
+#define UAECALL
+#endif
+
+#endif /* UAE_API_H */
--- /dev/null
+/*
+ * Defines useful functions and variable attributes for UAE
+ * Copyright (C) 2014 Frode Solheim
+ *
+ * Licensed under the terms of the GNU General Public License version 2.
+ * See the file 'COPYING' for full license text.
+ */
+
+#ifndef UAE_ATTRIBUTES_H
+#define UAE_ATTRIBUTES_H
+
+/* This file is intended to be included by external libraries as well,
+ * so don't pull in too much UAE-specific stuff. */
+
+/* This attribute allows (some) compiles to emit warnings when incorrect
+ * arguments are used with the format string. */
+
+#ifdef __GNUC__
+#define UAE_PRINTF_FORMAT(f, a) __attribute__((format(printf, f, a)))
+#else
+#define UAE_PRINTF_FORMAT(f, a)
+#endif
+
+#endif /* UAE_ATTRIBUTES_H */
--- /dev/null
+/*
+ * Platform-independent loadable module functions for UAE.
+ * Copyright (C) 2014 Frode Solheim
+ *
+ * Licensed under the terms of the GNU General Public License version 2.
+ * See the file 'COPYING' for full license text.
+ */
+
+#ifndef UAE_DLOPEN_H
+#define UAE_DLOPEN_H
+
+#include "uae/types.h"
+
+#ifdef _WIN32
+#define UAE_DLHANDLE HINSTANCE
+#else
+#define UAE_DLHANDLE void *
+#endif
+
+UAE_DLHANDLE uae_dlopen(const TCHAR *path);
+void *uae_dlsym(UAE_DLHANDLE handle, const char *symbol);
+void uae_dlclose(UAE_DLHANDLE handle);
+
+void uae_patch_library_common(UAE_DLHANDLE handle);
+
+#endif /* UAE_DLOPEN_H */
--- /dev/null
+/*
+ * Logging functions for use with UAE and external modules
+ * Copyright (C) 2014 Frode Solheim
+ *
+ * Licensed under the terms of the GNU General Public License version 2.
+ * See the file 'COPYING' for full license text.
+ */
+
+#ifndef UAE_LOGGING_H
+#define UAE_LOGGING_H
+
+/* This file is intended to be included by external libraries as well,
+ * so don't pull in too much UAE-specific stuff. */
+
+#include "uae/api.h"
+#include "uae/attributes.h"
+#include "uae/types.h"
+
+typedef void (UAECALL *uae_log_function)(const char *format, ...) UAE_PRINTF_FORMAT(1, 2);
+#ifdef UAE
+//UAEAPI void UAECALL uae_log(const char *format, ...) UAE_PRINTF_FORMAT(1, 2);
+void UAECALL uae_log(const char *format, ...) UAE_PRINTF_FORMAT(1, 2);
+#else
+extern uae_log_function uae_log;
+#endif
+
+#if 0
+void uae_warning(const char *format, ...) UAE_PRINTF_FORMAT(1, 2);
+void uae_error(const char *format, ...) UAE_PRINTF_FORMAT(1, 2);
+void uae_fatal(const char *format, ...) UAE_PRINTF_FORMAT(1, 2);
+#endif
+
+#define UAE_LOG_VA_ARGS(format, ap) \
+{ \
+ char buffer[1024]; \
+ vsnprintf(buffer, 1024, format, ap); \
+ uae_log("%s", buffer); \
+}
+
+#define UAE_LOG_VA_ARGS_FULL(format) \
+{ \
+ va_list ap; \
+ va_start(ap, format); \
+ UAE_LOG_VA_ARGS(format, ap); \
+ va_end(ap); \
+}
+
+/* Helpers to log use of stubbed functions */
+
+#define UAE_LOG_STUB(format, ...) \
+{ \
+ uae_log(" -- stub -- %s " format "\n", __func__, ##__VA_ARGS__); \
+}
+
+#define UAE_LOG_STUB_MAX(max, format, ...) \
+{ \
+ static int log_stub_count = 0; \
+ if (log_stub_count < max) { \
+ LOG_STUB(format, ##__VA_ARGS__) \
+ if (++log_stub_count == max) { \
+ uae_log(" (ignoring further calls to %s)\n", __func__); \
+ } \
+ } \
+}
+
+#define UAE_STUB(format, ...) \
+{ \
+ UAE_LOG_STUB(format, ##__VA_ARGS__) \
+ printf(" -- stub -- %s " format "\n", __func__, ##__VA_ARGS__); \
+}
+
+/* UAE-specific functions */
+
+#ifdef UAE
+
+void write_log (const char *, ...) UAE_PRINTF_FORMAT(1, 2);
+#if SIZEOF_TCHAR != 1
+void write_log (const TCHAR *, ...) UAE_PRINTF_FORMAT(1, 2);
+#endif
+
+#endif
+
+/* Deprecated defines */
+
+#ifdef UAE
+
+#define STUB UAE_STUB
+#define LOG_STUB UAE_LOG_STUB
+#define LOG_STUB_MAX UAE_LOG_STUB_MAX
+#define VERBOSE_STUB STUB
+
+#endif
+
+#endif /* UAE_LOGGING_H */
--- /dev/null
+/*
+ * Platform-independent loadable module functions for UAE
+ * Copyright (C) 2014 Toni Wilen, Frode Solheim
+ *
+ * Licensed under the terms of the GNU General Public License version 2.
+ * See the file 'COPYING' for full license text.
+ */
+
+#ifndef UAE_PPC_H
+#define UAE_PPC_H
+
+/* This file is intended to be included by external libraries as well,
+ * so don't pull in too much UAE-specific stuff. */
+
+#include "uae/api.h"
+#include "uae/types.h"
+
+#ifdef UAE
+#define PPCAPI UAE_EXTERN_C UAE_IMPORT
+#else
+#define PPCAPI UAE_EXTERN_C UAE_EXPORT
+#endif
+#define PPCCALL UAECALL
+
+/* UAE PPC functions and variables only visible to UAE */
+
+#ifdef UAE
+
+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);
+
+#ifdef __cplusplus
+bool uae_ppc_direct_physical_memory_handle(uint32_t addr, uint8_t *&ptr);
+#endif
+
+extern volatile int ppc_state;
+extern int ppc_cycle_count;
+
+#endif /* UAE */
+
+/* Exported UAE functions which external PPC implementations can use */
+
+typedef bool (UAECALL *uae_ppc_io_mem_read_function)(uint32_t addr, uint32_t *data, int size);
+typedef bool (UAECALL *uae_ppc_io_mem_write_function)(uint32_t addr, uint32_t data, int size);
+typedef bool (UAECALL *uae_ppc_io_mem_read64_function)(uint32_t addr, uint64_t *data);
+typedef bool (UAECALL *uae_ppc_io_mem_write64_function)(uint32_t addr, uint64_t data);
+
+#ifdef UAE
+
+bool UAECALL uae_ppc_io_mem_read(uint32_t addr, uint32_t *data, int size);
+bool UAECALL uae_ppc_io_mem_write(uint32_t addr, uint32_t data, int size);
+bool UAECALL uae_ppc_io_mem_read64(uint32_t addr, uint64_t *data);
+bool UAECALL uae_ppc_io_mem_write64(uint32_t addr, uint64_t data);
+
+#else
+
+extern uae_ppc_io_mem_read_function uae_ppc_io_mem_read;
+extern uae_ppc_io_mem_write_function uae_ppc_io_mem_write;
+extern uae_ppc_io_mem_read64_function uae_ppc_io_mem_read64;
+extern uae_ppc_io_mem_write64_function uae_ppc_io_mem_write64;
+
+#endif
+
+/* Prototypes for PPC CPU implementation, used by PearPC and QEmu */
+
+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_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);
+
+/* Other PPC defines */
+
+#define PPC_IMPLEMENTATION_AUTO 0
+#define PPC_IMPLEMENTATION_DUMMY 1
+#define PPC_IMPLEMENTATION_PEARPC 2
+#define PPC_IMPLEMENTATION_QEMU 3
+
+#define PPC_STATE_STOP 0
+#define PPC_STATE_ACTIVE 1
+#define PPC_STATE_SLEEP 2
+#define PPC_STATE_CRASH 3
+
+#endif /* UAE_PPC_H */
--- /dev/null
+/*
+ * Common types used throughout the UAE source code
+ * Copyright (C) 2014 Frode Solheim
+ *
+ * Licensed under the terms of the GNU General Public License version 2.
+ * See the file 'COPYING' for full license text.
+ */
+
+#ifndef UAE_TYPES_H
+#define UAE_TYPES_H
+
+/* This file is intended to be included by external libraries as well,
+ * so don't pull in too much UAE-specific stuff. */
+
+#if 0
+#include "config.h"
+#endif
+
+/* Define uae_ integer types. Prefer long long int for uae_x64 since we can
+ * then use the %lld format specifier for both 32-bit and 64-bit instead of
+ * the ugly PRIx64 macros. */
+
+#include <stdint.h>
+
+typedef int8_t uae_s8;
+typedef uint8_t uae_u8;
+
+typedef int16_t uae_s16;
+typedef uint16_t uae_u16;
+
+typedef int32_t uae_s32;
+typedef uint32_t uae_u32;
+
+#ifndef uae_s64
+typedef long long int uae_s64;
+#endif
+
+#ifndef uae_u64
+typedef unsigned long long int uae_u64;
+#endif
+
+/* Parts of the UAE/WinUAE code uses the bool type (from C++).
+ * Including stdbool.h lets this be valid also when compiling with C. */
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+/* Use uaecptr to represent 32-bit (or 24-bit) addresses into the Amiga
+ * address space. This is a 32-bit unsigned int regarless of host arch. */
+
+typedef uae_u32 uaecptr;
+
+/* Define UAE character types. WinUAE uses TCHAR (typedef for wchar_t) for
+ * many strings. FS-UAE always uses char-based strings in UTF-8 format.
+ * Defining SIZEOF_TCHAR lets us determine whether to include overloaded
+ * functions in some cases or not. */
+
+typedef char uae_char;
+
+#ifdef _WIN32
+#include <tchar.h>
+#ifdef UNICODE
+#define SIZEOF_TCHAR 2
+#else
+#define SIZEOF_TCHAR 1
+#endif
+#else
+typedef char TCHAR;
+#define SIZEOF_TCHAR 1
+#endif
+
+#ifndef _T
+#if SIZEOF_TCHAR == 1
+#define _T(x) x
+#else
+#define _T(x) Lx
+#endif
+#endif
+
+#ifndef BOOL
+#define BOOL int
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#endif /* UAE_TYPES_H */
--- /dev/null
+#include "uae/log.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+//UAEAPI void UAECALL uae_log(const char *format, ...)
+void UAECALL uae_log(const char *format, ...)
+{
+ char buffer[1000];
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(buffer, 1000, format, ap);
+ write_log("%s", buffer);
+ va_end(ap);
+}
#define __CPU_H__
#include "system/types.h"
+#include "uae/ppc.h"
uint64 ppc_get_clock_frequency(int cpu);
uint64 ppc_get_bus_frequency(int cpu);
uint64 ppc_get_timebase_frequency(int cpu);
-bool ppc_cpu_init(uint32);
+bool PPCCALL ppc_cpu_init(uint32);
void ppc_cpu_init_config();
-void ppc_cpu_free(void);
+void PPCCALL ppc_cpu_free(void);
-void ppc_cpu_stop();
+void PPCCALL ppc_cpu_stop();
void ppc_cpu_wakeup();
void ppc_machine_check_exception();
* May only be called from within a CPU thread.
*/
-void ppc_cpu_run_continuous();
-void ppc_cpu_run_single(int);
+void PPCCALL ppc_cpu_run_continuous();
+void PPCCALL ppc_cpu_run_single(int);
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);
-void ppc_cpu_set_pc(int cpu, uint32 newvalue);
+void PPCCALL ppc_cpu_set_pc(int cpu, uint32 newvalue);
uint32 ppc_cpu_get_pc(int cpu);
uint32 ppc_cpu_get_pvr(int cpu);
#include "ppc_exc.h"
#include "ppc_mmu.h"
#include "ppc_tools.h"
-#include "ppc.h"
+#include "uae/ppc.h"
//#include "io/graphic/gcard.h"
sys_mutex exception_mutex;
-void ppc_cpu_atomic_raise_ext_exception()
+void PPCCALL ppc_cpu_atomic_raise_ext_exception()
{
sys_lock_mutex(exception_mutex);
gCPU.ext_exception = true;
sys_unlock_mutex(exception_mutex);
}
-void ppc_cpu_atomic_cancel_ext_exception()
+void PPCCALL ppc_cpu_atomic_cancel_ext_exception()
{
sys_lock_mutex(exception_mutex);
gCPU.ext_exception = false;
}
}
-uint64_t ppc_cpu_get_dec(void)
+uint64_t PPCCALL ppc_cpu_get_dec(void)
{
return gCPU.pdec;
}
-void ppc_cpu_do_dec(int val)
+void PPCCALL ppc_cpu_do_dec(int val)
{
ppc_do_dec(val);
}
static uint ops = 0;
static int ppc_trace;
-void ppc_cpu_run_single(int count)
+void PPCCALL ppc_cpu_run_single(int count)
{
while (count != 0) {
if (count > 0)
}
}
-void ppc_cpu_run_continuous(void)
+void PPCCALL ppc_cpu_run_continuous(void)
{
PPC_CPU_TRACE("execution started at %08x\n", gCPU.pc);
gCPU.effective_code_page = 0xffffffff;
ppc_cpu_run_single(-1);
}
-void ppc_cpu_stop()
+void PPCCALL ppc_cpu_stop()
{
sys_lock_mutex(exception_mutex);
gCPU.stop_exception = true;
}
// Handle as CPU reset
-void ppc_cpu_set_pc(int cpu, uint32 newvalue)
+void PPCCALL ppc_cpu_set_pc(int cpu, uint32 newvalue)
{
gCPU.srr[0] = gCPU.pc;
gCPU.srr[1] = gCPU.msr & 0xff73;
//#include "configparser.h"
-bool ppc_cpu_init(uint32 pvr)
+bool PPCCALL ppc_cpu_init(uint32 pvr)
{
memset(&gCPU, 0, sizeof gCPU);
gCPU.pvr = pvr; //gConfig->getConfigInt(CPU_KEY_PVR);
return true;
}
-void ppc_cpu_free(void)
+void PPCCALL ppc_cpu_free(void)
{
sys_destroy_mutex(exception_mutex);
}
extern PPC_CPU_State gCPU;
-void ppc_cpu_atomic_raise_ext_exception();
-void ppc_cpu_atomic_cancel_ext_exception();
+#include "uae/ppc.h"
+
+void PPCCALL ppc_cpu_atomic_raise_ext_exception();
+void PPCCALL ppc_cpu_atomic_cancel_ext_exception();
extern uint32 gBreakpoint;
extern uint32 gBreakpoint2;
#define IO_MEM_ACCESS_EXC 1
#define IO_MEM_ACCESS_FATAL 2
-#include "ppc.h"
+#include "uae/ppc.h"
static inline int io_mem_write(uint32 addr, uint32 data, int size)
{
#include "system/systhread.h"
-void write_log(const char *format, ...);
+extern void write_log (const char *, ...);
int ht_printf(const char *fmt,...)
{
char buffer[1000];
va_list parms;
va_start(parms, fmt);
- vsprintf(buffer, fmt, parms);
- write_log(buffer);
+ vsnprintf(buffer, 1000, fmt, parms);
+ write_log("%s", buffer);
va_end(parms);
return 0;
}
{
}
#endif
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+#include <threaddep/thread.h>
+
+typedef void * sys_mutex;
+
+int sys_lock_mutex(sys_mutex m)
+{
+ uae_sem_wait(&m);
+ return 1;
+}
+
+void sys_unlock_mutex(sys_mutex m)
+{
+ uae_sem_post(&m);
+}
+
+int sys_create_mutex(sys_mutex *m)
+{
+ if (!(*m))
+ uae_sem_init(m, 0, 1);
+ return 1;
+}
+
+void sys_destroy_mutex(sys_mutex m)
+{
+ uae_sem_destroy(&m);
+}
#include "debug.h"
#include "custom.h"
#include "uae.h"
+#include "uae/dlopen.h"
-#if defined(__cplusplus) && defined(WITH_QEMU_CPU)
-#define PPC_EXTERN_C extern "C"
-#endif
-
-#include "ppc.h"
-//#include "ppc-if.h"
+#include "uae/ppc.h"
#ifdef WITH_PEARPC_CPU
#include "pearpc/cpu/cpu.h"
#define PPC_SYNC_WRITE 0
#define PPC_ACCESS_LOG 2
+#define TRACE(format, ...) write_log(_T("PPC: ---------------- ") format, ## __VA_ARGS__)
+
volatile int ppc_state;
static volatile bool ppc_thread_running;
#define KB * 1024
#define MB * (1024 * 1024)
-static void map_banks(void)
+/* Dummy PPC implementation */
+
+static bool PPCCALL dummy_ppc_cpu_init(uint32_t pvr) { 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) { }
+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_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) { }
+
+/* Functions typedefs for PPC implementation */
+
+typedef bool (PPCCALL *ppc_cpu_init_function)(uint32_t pvr);
+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_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);
+
+/* Function pointers to active PPC implementation */
+
+static ppc_cpu_init_function g_ppc_cpu_init;
+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;
+static ppc_cpu_atomic_cancel_ext_exception_function g_ppc_cpu_atomic_cancel_ext_exception;
+static ppc_cpu_map_memory_function g_ppc_cpu_map_memory;
+static ppc_cpu_set_pc_function g_ppc_cpu_set_pc;
+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 void load_dummy_implementation()
{
+ write_log(_T("PPC: Loading dummy implementation\n"));
+ g_ppc_cpu_init = dummy_ppc_cpu_init;
+ 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;
+ g_ppc_cpu_atomic_cancel_ext_exception = dummy_ppc_cpu_atomic_cancel_ext_exception;
+ g_ppc_cpu_map_memory = dummy_ppc_cpu_map_memory;
+ g_ppc_cpu_set_pc = dummy_ppc_cpu_set_pc;
+ g_ppc_cpu_run_continuous = dummy_ppc_cpu_run_continuous;
+ 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;
+}
+
#ifdef WITH_QEMU_CPU
+
+static void uae_patch_library_ppc(UAE_DLHANDLE handle)
+{
+ void *ptr;
+
+ ptr = uae_dlsym(handle, "uae_ppc_io_mem_read");
+ if (ptr) *((uae_ppc_io_mem_read_function *) ptr) = &uae_ppc_io_mem_read;
+ else write_log(_T("WARNING: uae_ppc_io_mem_read not set\n"));
+
+ ptr = uae_dlsym(handle, "uae_ppc_io_mem_write");
+ if (ptr) *((uae_ppc_io_mem_write_function *) ptr) = &uae_ppc_io_mem_write;
+ else write_log(_T("WARNING: uae_ppc_io_mem_write not set\n"));
+
+ ptr = uae_dlsym(handle, "uae_ppc_io_mem_read64");
+ if (ptr) *((uae_ppc_io_mem_read64_function *) ptr) = &uae_ppc_io_mem_read64;
+ else write_log(_T("WARNING: uae_ppc_io_mem_read64 not set\n"));
+
+ ptr = uae_dlsym(handle, "uae_ppc_io_mem_write64");
+ if (ptr) *((uae_ppc_io_mem_write64_function *) ptr) = &uae_ppc_io_mem_write64;
+ else write_log(_T("WARNING: uae_ppc_io_mem_write64 not set\n"));
+}
+
+static bool load_qemu_implementation()
+{
+ write_log(_T("PPC: Loading QEmu implementation\n"));
+ // FIXME: replace with a callback to get the qemu path (so it can be
+ // 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"));
+ 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_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");
+ g_ppc_cpu_atomic_cancel_ext_exception = (ppc_cpu_atomic_cancel_ext_exception_function) uae_dlsym(handle, "ppc_cpu_atomic_cancel_ext_exception");
+ g_ppc_cpu_map_memory = (ppc_cpu_map_memory_function) uae_dlsym(handle, "ppc_cpu_map_memory");
+ g_ppc_cpu_set_pc = (ppc_cpu_set_pc_function) uae_dlsym(handle, "ppc_cpu_set_pc");
+ g_ppc_cpu_run_continuous = (ppc_cpu_run_continuous_function) uae_dlsym(handle, "ppc_cpu_run_continuous");
+ 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");
+
+#if 0
+ /* register callback functions */
+#endif
+
+ uae_patch_library_common(handle);
+ uae_patch_library_ppc(handle);
+ return true;
+}
+
+#endif
+
+#ifdef WITH_PEARPC_CPU
+
+static bool load_pearpc_implementation()
+{
+ write_log(_T("PPC: Loading PearPC implementation\n"));
+ g_ppc_cpu_init = ppc_cpu_init;
+ 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;
+ g_ppc_cpu_atomic_cancel_ext_exception = ppc_cpu_atomic_cancel_ext_exception;
+
+ g_ppc_cpu_map_memory = dummy_ppc_cpu_map_memory;
+
+ g_ppc_cpu_set_pc = ppc_cpu_set_pc;
+ g_ppc_cpu_run_continuous = ppc_cpu_run_continuous;
+ g_ppc_cpu_run_single = ppc_cpu_run_single;
+ g_ppc_cpu_get_dec = ppc_cpu_get_dec;
+ g_ppc_cpu_do_dec = ppc_cpu_do_dec;
+ return true;
+}
+
+#endif
+
+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()) {
+ return;
+ }
+ }
+#endif
+#ifdef WITH_QEMU_CPU
+ if (impl == PPC_IMPLEMENTATION_AUTO || impl == PPC_IMPLEMENTATION_QEMU) {
+ if (load_qemu_implementation()) {
+ return;
+ }
+ }
+#endif
+ load_dummy_implementation();
+}
+
+static void initialize()
+{
+ static bool initialized = false;
+ if (initialized) {
+ return;
+ }
+ initialized = true;
+ load_ppc_implementation();
+}
+
+static void map_banks(void)
+{
/*
* Use NULL to get callbacks to uae_ppc_io_mem_read/write. Use real
* memory address for direct access to RAM banks (looks like this
// FIXME: hack, replace with automatic / dynamic mapping
#if 1
- ppc_cpu_map_memory(0x00000000, 2048 KB, NULL, "Chip memory");
- ppc_cpu_map_memory(0x00BF0000, 64 KB, NULL, "CIA");
- ppc_cpu_map_memory(0x00F00000, 256 KB, get_real_address(0x00F00000), "CPUBoard F00000");
- ppc_cpu_map_memory(0x00F50000, 192 KB, NULL, "CPUBoard IO");
- ppc_cpu_map_memory(0x00DF0000, 64 KB, NULL, "Custom chipset");
- ppc_cpu_map_memory(0x08000000, 128 MB, get_real_address(0x08000000), "RAMSEY memory (high)");
- ppc_cpu_map_memory(0xFFF00000, 512 KB, get_real_address(0xFFF00000), "CPUBoard MAPROM");
+ 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
- ppc_cpu_map_memory(0x00BF0000, 64 KB, NULL, "CIA");
- ppc_cpu_map_memory(0x00F00000, 256 KB, NULL, "CPUBoard F00000");
- ppc_cpu_map_memory(0x00F50000, 192 KB, NULL, "CPUBoard IO");
- ppc_cpu_map_memory(0x08000000, 128 MB, NULL, "RAMSEY memory (high)");
- ppc_cpu_map_memory(0xFFF00000, 512 KB, get_real_address(0xFFF00000), "CPUBoard MAPROM");
-#endif
+ 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
}
static void uae_ppc_cpu_reset(void)
{
-#ifdef WITH_PPC
- write_log("---- uae_ppc_cpu_reset ----\n");
+ TRACE(_T("uae_ppc_cpu_reset\n"));
+ initialize();
if (!ppc_init_done) {
write_log(_T("PPC: Hard reset\n"));
- ppc_cpu_init(currprefs.cpuboard_type == BOARD_BLIZZARDPPC ? BLIZZPPC_PVR : CSPPC_PVR);
+ g_ppc_cpu_init(currprefs.cpuboard_type == BOARD_BLIZZARDPPC ? BLIZZPPC_PVR : CSPPC_PVR);
map_banks();
ppc_init_done = true;
}
write_log(_T("PPC: Init\n"));
- ppc_cpu_set_pc(0, 0xfff00100);
+ g_ppc_cpu_set_pc(0, 0xfff00100);
ppc_cycle_count = 2000;
ppc_state = PPC_STATE_ACTIVE;
ppc_cpu_lock_state = 0;
-#endif
}
static void *ppc_thread(void *v)
{
-#ifdef WITH_PPC
for (;;) {
uae_u32 v = read_comm_pipe_u32_blocking(&ppcrequests);
if (v == 0xffffffff)
break;
uae_ppc_cpu_reset();
- ppc_cpu_run_continuous();
+ g_ppc_cpu_run_continuous();
if (ppc_state == PPC_STATE_ACTIVE || ppc_state == PPC_STATE_SLEEP)
ppc_state = PPC_STATE_STOP;
write_log(_T("ppc_cpu_run() exited.\n"));
}
ppc_thread_running = false;
-#endif
return NULL;
}
void uae_ppc_to_main_thread(void)
{
- write_log("---- uae_ppc_to_main_thread ----\n");
+ TRACE(_T("uae_ppc_to_main_thread\n"));
if (ppc_thread_running) {
write_log(_T("PPC: transferring PPC emulation to main thread.\n"));
uae_ppc_cpu_stop();
void uae_ppc_emulate(void)
{
-#ifdef WITH_PPC
- write_log("---- uae_ppc_emulate ----\n");
+ TRACE(_T("uae_ppc_emulate\n"));
if (ppc_state == PPC_STATE_ACTIVE || ppc_state == PPC_STATE_SLEEP)
- ppc_cpu_run_single(10);
-#endif
+ g_ppc_cpu_run_single(10);
}
bool uae_ppc_poll_queue(void)
return false;
}
-PPC_EXTERN_C bool uae_ppc_io_mem_write(uint32_t addr, uint32_t data, int size)
+bool UAECALL uae_ppc_io_mem_write(uint32_t addr, uint32_t data, int size)
{
while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
return true;
}
-PPC_EXTERN_C bool uae_ppc_io_mem_read(uint32_t addr, uint32_t *data, int size)
+bool UAECALL uae_ppc_io_mem_read(uint32_t addr, uint32_t *data, int size)
{
uint32_t v;
*data = v;
return true;
}
-#if PPC_ACCESS_LOG > 0
- if (!ppc_thread_running && !valid_address(addr, size)) {
- write_log(_T("PPC io read %08x=%08x %d\n"), addr, v, size);
- }
-#endif
switch (size)
{
case 4:
}
*data = v;
+#if PPC_ACCESS_LOG > 0
+ if (!ppc_thread_running && !valid_address(addr, size)) {
+ write_log(_T("PPC io read %08x=%08x %d\n"), addr, v, size);
+ }
+#endif
#if PPC_ACCESS_LOG > 2
write_log(_T("PPC mem read %08x=%08x %d\n"), addr, v, size);
#endif
return true;
}
-bool uae_ppc_io_mem_write64(uint32_t addr, uint64_t data)
+bool UAECALL uae_ppc_io_mem_write64(uint32_t addr, uint64_t data)
{
while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
return true;
}
-bool uae_ppc_io_mem_read64(uint32_t addr, uint64_t *data)
+bool UAECALL uae_ppc_io_mem_read64(uint32_t addr, uint64_t *data)
{
uint32_t v1, v2;
void uae_ppc_cpu_stop(void)
{
- write_log("---- uae_ppc_cpu_stop ----\n");
-#ifdef WITH_PPC
+ TRACE(_T("uae_ppc_cpu_stop\n"));
if (ppc_thread_running && ppc_state) {
write_log(_T("Stopping PPC.\n"));
uae_ppc_wakeup();
- ppc_cpu_stop();
+ g_ppc_cpu_stop();
while (ppc_state != PPC_STATE_STOP && ppc_state != PPC_STATE_CRASH) {
uae_ppc_wakeup();
uae_ppc_poll_queue();
ppc_state = PPC_STATE_STOP;
write_log(_T("PPC stopped.\n"));
}
-#endif
}
void uae_ppc_cpu_reboot(void)
{
- write_log("---- uae_ppc_cpu_reboot ----\n");
-#ifdef WITH_PPC
+ TRACE(_T("uae_ppc_cpu_reboot\n"));
if (ppc_main_thread) {
uae_ppc_cpu_reset();
} else {
}
write_comm_pipe_u32(&ppcrequests, 1, 1);
}
-#endif
}
void uae_ppc_reset(bool hardreset)
{
- write_log("---- uae_ppc_reset ----\n");
-#ifdef WITH_PPC
+ TRACE(_T("uae_ppc_reset hardreset=%d\n"), hardreset);
uae_ppc_cpu_stop();
ppc_main_thread = false;
if (hardreset) {
if (ppc_init_done)
- ppc_cpu_free();
+ g_ppc_cpu_free();
ppc_init_done = false;
}
-#endif
}
void uae_ppc_cpu_lock(void)
{
-#ifdef WITH_PPC
// when called, lock was already set by other CPU
if (ppc_access) {
// ppc accessing but m68k already locked
// m68k accessing but ppc already locked
ppc_cpu_lock_state = 1;
}
-#endif
}
+
bool uae_ppc_cpu_unlock(void)
{
-#ifdef WITH_PPC
if (!ppc_cpu_lock_state)
return true;
ppc_cpu_lock_state = 0;
return false;
-#endif
}
void uae_ppc_wakeup(void)
{
- write_log("---- uae_ppc_wakeup ----\n");
-#ifdef WITH_PPC
+ TRACE(_T("uae_ppc_wakeup\n"));
if (ppc_state == PPC_STATE_SLEEP)
ppc_state = PPC_STATE_ACTIVE;
-#endif
}
void uae_ppc_interrupt(bool active)
{
- write_log("---- uae_ppc_interrupt ----\n");
-#ifdef WITH_PPC
+ TRACE(_T("uae_ppc_interrupt\n"));
if (active) {
- ppc_cpu_atomic_raise_ext_exception();
+ g_ppc_cpu_atomic_raise_ext_exception();
uae_ppc_wakeup();
} else {
- ppc_cpu_atomic_cancel_ext_exception();
+ g_ppc_cpu_atomic_cancel_ext_exception();
}
-#endif
}
// sleep until interrupt (or PPC stopped)
void uae_ppc_doze(void)
{
- write_log("---- uae_ppc_doze ----\n");
-#ifdef WITH_PPC
+ TRACE(_T("uae_ppc_doze\n"));
if (!ppc_thread_running)
return;
ppc_state = PPC_STATE_SLEEP;
while (ppc_state == PPC_STATE_SLEEP) {
sleep_millis(2);
}
-#endif
}
void uae_ppc_crash(void)
{
- write_log("---- uae_ppc_crash ----\n");
-#ifdef WITH_PPC
+ TRACE(_T("uae_ppc_crash\n"));
ppc_state = PPC_STATE_CRASH;
- ppc_cpu_stop();
-#endif
+ g_ppc_cpu_stop();
}
void uae_ppc_hsync_handler(void)
{
-#ifdef WITH_PPC
if (ppc_state != PPC_STATE_SLEEP)
return;
- if (ppc_cpu_get_dec() == 0) {
+ if (g_ppc_cpu_get_dec() == 0) {
uae_ppc_wakeup();
} else {
- ppc_cpu_do_dec(ppc_cycle_count);
+ g_ppc_cpu_do_dec(ppc_cycle_count);
}
-#endif
}
-
-#ifdef WITH_PEARPC_CPU
-
-typedef void * sys_mutex;
-
-int sys_lock_mutex(sys_mutex m)
-{
- uae_sem_wait(&m);
- return 1;
-}
-
-void sys_unlock_mutex(sys_mutex m)
-{
- uae_sem_post(&m);
-}
-
-int sys_create_mutex(sys_mutex *m)
-{
- if (!(*m))
- uae_sem_init(m, 0, 1);
- return 1;
-}
-
-void sys_destroy_mutex(sys_mutex m)
-{
- uae_sem_destroy(&m);
-}
-
-#endif
-
-#ifndef _MSV_VER
-#define __cdecl
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void __cdecl pixman_format_supported_source(void);
-void __cdecl pixman_format_supported_source(void) { }
-
-void __cdecl pixman_image_composite(void);
-void __cdecl pixman_image_composite(void) { }
-
-void __cdecl pixman_image_create_bits(void);
-void __cdecl pixman_image_create_bits(void) { }
-
-void __cdecl pixman_image_create_solid_fill(void);
-void __cdecl pixman_image_create_solid_fill(void) { }
-
-void __cdecl pixman_image_fill_rectangles(void);
-void __cdecl pixman_image_fill_rectangles(void) { }
-
-void __cdecl pixman_image_get_data(void);
-void __cdecl pixman_image_get_data(void) { }
-
-void __cdecl pixman_image_get_height(void);
-void __cdecl pixman_image_get_height(void) { }
-
-void __cdecl pixman_image_get_width(void);
-void __cdecl pixman_image_get_width(void) { }
-
-void __cdecl pixman_image_get_stride(void);
-void __cdecl pixman_image_get_stride(void) { }
-
-void __cdecl pixman_image_unref(void);
-void __cdecl pixman_image_unref(void) { }
-
-#ifdef __cplusplus
-}
-#endif
--- /dev/null
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/timeb.h>
+
+void write_log (const char *format, ...);
+
+extern "C"
+{
+extern void __cdecl ppc_translate_init(void);
+
+int __cdecl snprintf (char * s, size_t n, const char * format, ... )
+{
+ return 0;
+}
+
+int __cdecl __mingw_vprintf(const char * format, va_list arg)
+{
+ return 0;
+}
+
+int __cdecl __mingw_vfprintf(void *stream, const char * format, va_list arg)
+{
+ return 0;
+}
+
+struct timeval {
+ long tv_sec; /* seconds */
+ long tv_usec; /* and microseconds */
+};
+
+void __cdecl gettimeofday(struct timeval *tv, void *blah)
+{
+ struct timeb time;
+
+ ftime (&time);
+
+ tv->tv_sec = time.time;
+ tv->tv_usec = time.millitm * 1000;
+}
+
+void __cdecl inflateInit2_(void)
+{
+}
+void __cdecl inflate(void)
+{
+}
+void __cdecl inflateEnd(void)
+{
+}
+void __cdecl compress2(void)
+{
+}
+void __cdecl compressBound(void)
+{
+}
+
+void __cdecl opendir(void)
+{
+}
+void __cdecl readdir(void)
+{
+}
+void __cdecl closedir(void)
+{
+}
+
+void __cdecl popen(void)
+{
+}
+void __cdecl pclose(void)
+{
+}
+
+void __cdecl pixman_format_supported_source(void) { }
+void __cdecl pixman_image_composite(void) { }
+void __cdecl pixman_image_create_bits(void) { }
+void __cdecl pixman_image_create_solid_fill(void) { }
+void __cdecl pixman_image_fill_rectangles(void) { }
+void __cdecl pixman_image_get_data(void) { }
+void __cdecl pixman_image_get_height(void) { }
+void __cdecl pixman_image_get_width(void) { }
+void __cdecl pixman_image_get_stride(void) { }
+void __cdecl pixman_image_unref(void) { }
+
+int optarg;
+int optind;
+int getopt;
+
+void __cdecl __emutls_get_address(void)
+{
+}
+
+int __cdecl sizeof_CPUPPCState(void);
+int __cdecl sizeof_PowerPCCPU(void);
+
+void * __cdecl cpu_ppc_init(const char *cpu_model);
+
+
+}
+
+void crap(void)
+{
+ const char *cpu_model = "604e";
+ void *cpu, *env;
+ int cpu_size, env_size;
+
+ cpu_size = sizeof_CPUPPCState();
+ env_size = sizeof_PowerPCCPU();
+
+ cpu = cpu_ppc_init(cpu_model);
+
+}