+#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);
#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
* addox Add with Overflow
* .422
*/
-void ppc_opc_addox()
+static void ppc_opc_addox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* addcox Add Carrying with Overflow
* .423
*/
-void ppc_opc_addcox()
+static void ppc_opc_addcox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* addeox Add Extended with Overflow
* .424
*/
-void ppc_opc_addeox()
+static void ppc_opc_addeox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* addmeox Add to Minus One Extended with Overflow
* .429
*/
-void ppc_opc_addmeox()
+static void ppc_opc_addmeox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* addzeox Add to Zero Extended with Overflow
* .430
*/
-void ppc_opc_addzeox()
+static void ppc_opc_addzeox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* divwox Divide Word with Overflow
* .470
*/
-void ppc_opc_divwox()
+static void ppc_opc_divwox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* divwuox Divide Word Unsigned with Overflow
* .472
*/
-void ppc_opc_divwuox()
+static void ppc_opc_divwuox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* negox Negate with Overflow
* .601
*/
-void ppc_opc_negox()
+static void ppc_opc_negox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* subfox Subtract From with Overflow
* .666
*/
-void ppc_opc_subfox()
+static void ppc_opc_subfox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* subfcox Subtract From Carrying with Overflow
* .667
*/
-void ppc_opc_subfcox()
+static void ppc_opc_subfcox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* subfeox Subtract From Extended with Overflow
* .668
*/
-void ppc_opc_subfeox()
+static void ppc_opc_subfeox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* subfmeox Subtract From Minus One Extended with Overflow
* .670
*/
-void ppc_opc_subfmeox()
+static void ppc_opc_subfmeox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
* subfzeox Subtract From Zero Extended with Overflow
* .671
*/
-void ppc_opc_subfzeox()
+static void ppc_opc_subfzeox()
{
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
-
#include "sysconfig.h"
#include "sysdeps.h"
#include "options.h"
#include "threaddep/thread.h"
-#include "ppc.h"
#include "memory.h"
#include "cpuboard.h"
#include "debug.h"
#include "custom.h"
#include "uae.h"
-#include "cpu/cpu.h"
+#if defined(__cplusplus) && defined(WITH_QEMU_CPU)
+#define PPC_EXTERN_C extern "C"
+#endif
+
+#include "ppc.h"
+//#include "ppc-if.h"
+
+#ifdef WITH_PEARPC_CPU
+#include "pearpc/cpu/cpu.h"
+#include "pearpc/io/io.h"
+#include "pearpc/cpu/cpu_generic/ppc_cpu.h"
+#endif
#define PPC_SYNC_WRITE 0
-#define PPC_ACCESS_LOG 0
+#define PPC_ACCESS_LOG 2
volatile int ppc_state;
#define CSPPC_PVR 0x00090204
#define BLIZZPPC_PVR 0x00070101
+#define KB * 1024
+#define MB * (1024 * 1024)
+
+static void map_banks(void)
+{
+#ifdef WITH_QEMU_CPU
+ /*
+ * 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
+ * is needed by JIT, or at least more work is needed on QEmu Side
+ * to allow all memory access to go via callbacks).
+ */
+
+ // 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");
+#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
+#endif
+}
+
static void uae_ppc_cpu_reset(void)
{
+#ifdef WITH_PPC
+ write_log("---- uae_ppc_cpu_reset ----\n");
if (!ppc_init_done) {
write_log(_T("PPC: Hard reset\n"));
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_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)
}
ppc_thread_running = false;
+#endif
return NULL;
}
void uae_ppc_to_main_thread(void)
{
+ write_log("---- 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");
if (ppc_state == PPC_STATE_ACTIVE || ppc_state == PPC_STATE_SLEEP)
ppc_cpu_run_single(10);
+#endif
}
bool uae_ppc_poll_queue(void)
while (ppc_thread_running && comm_pipe_has_data(&ppcquery));
}
-bool uae_ppc_direct_physical_memory_handle(uint32 addr, byte *&ptr)
+bool uae_ppc_direct_physical_memory_handle(uint32_t addr, uint8_t *&ptr)
{
if (valid_address(addr, 0x1000)) {
ptr = get_real_address(addr);
return false;
}
-bool uae_ppc_io_mem_write(uint32 addr, uint32 data, int size)
+PPC_EXTERN_C bool 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;
}
-bool uae_ppc_io_mem_read(uint32 addr, uint32 &data, int size)
+PPC_EXTERN_C bool uae_ppc_io_mem_read(uint32_t addr, uint32_t *data, int size)
{
- uint32 v;
+ uint32_t v;
while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
if (addr != 0xbfe001)
write_log(_T("PPC io read %08x=%08x %d\n"), addr, v, size);
#endif
- data = v;
+ *data = v;
return true;
}
#if PPC_ACCESS_LOG > 0
write_log(_T("unknown ppc read %d %08x\n"), addr, size);
return false;
}
- data = v;
+ *data = v;
#if PPC_ACCESS_LOG > 2
write_log(_T("PPC mem read %08x=%08x %d\n"), addr, v, size);
return true;
}
-bool uae_ppc_io_mem_write64(uint32 addr, uint64 data)
+bool uae_ppc_io_mem_write64(uint32_t addr, uint64_t data)
{
while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
if (ppc_thread_running && !valid_address(addr, 8)) {
#if PPC_ACCESS_LOG > 0
- write_log(_T("PPC io write64 %08x = %08llx\n"), addr, data);
+ write_log(_T("PPC io write64 %08x = %08llx\n"), addr, (unsigned long long) data);
#endif
write_comm_pipe_u32(&ppcquery, addr, 0);
write_comm_pipe_u32(&ppcquery, 8 | 0x80, 0);
return true;
}
-bool uae_ppc_io_mem_read64(uint32 addr, uint64 &data)
+bool uae_ppc_io_mem_read64(uint32_t addr, uint64_t *data)
{
- uae_u32 v1, v2;
+ uint32_t v1, v2;
while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
write_comm_pipe_u32(&ppcquery, 8, 0);
v1 = read_comm_pipe_u32_blocking(&ppcreply);
v2 = read_comm_pipe_u32_blocking(&ppcreply);
- data = ((uint64)v1 << 32) | v2;
+ *data = ((uint64_t)v1 << 32) | v2;
#if PPC_ACCESS_LOG > 0
- write_log(_T("PPC io read64 %08x = %08llx\n"), addr, data);
+ write_log(_T("PPC io read64 %08x = %08llx\n"), addr, (unsigned long long) *data);
#endif
return true;
}
v1 = get_long(addr + 0);
v2 = get_long(addr + 4);
- data = ((uint64)v1 << 32) | v2;
+ *data = ((uint64_t)v1 << 32) | v2;
#if PPC_ACCESS_LOG > 2
- write_log(_T("PPC mem read64 %08x = %08llx\n"), addr, data);
+ write_log(_T("PPC mem read64 %08x = %08llx\n"), addr, *data);
#endif
return true;
}
void uae_ppc_cpu_stop(void)
{
+ write_log("---- uae_ppc_cpu_stop ----\n");
+#ifdef WITH_PPC
if (ppc_thread_running && ppc_state) {
write_log(_T("Stopping PPC.\n"));
uae_ppc_wakeup();
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
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
uae_ppc_cpu_stop();
ppc_main_thread = false;
if (hardreset) {
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
if (ppc_state == PPC_STATE_SLEEP)
ppc_state = PPC_STATE_ACTIVE;
+#endif
}
-void ppc_cpu_atomic_raise_ext_exception(void);
-void ppc_cpu_atomic_cancel_ext_exception(void);
-
void uae_ppc_interrupt(bool active)
{
+ write_log("---- uae_ppc_interrupt ----\n");
+#ifdef WITH_PPC
if (active) {
ppc_cpu_atomic_raise_ext_exception();
uae_ppc_wakeup();
} else {
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
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
ppc_state = PPC_STATE_CRASH;
ppc_cpu_stop();
+#endif
}
+void uae_ppc_hsync_handler(void)
+{
+#ifdef WITH_PPC
+ if (ppc_state != PPC_STATE_SLEEP)
+ return;
+ if (ppc_cpu_get_dec() == 0) {
+ uae_ppc_wakeup();
+ } else {
+ ppc_cpu_do_dec(ppc_cycle_count);
+ }
+#endif
+}
+
+#ifdef WITH_PEARPC_CPU
+
typedef void * sys_mutex;
-int sys_lock_mutex(sys_mutex m)
+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)
+
+int sys_create_mutex(sys_mutex *m)
{
if (!(*m))
uae_sem_init(m, 0, 1);
void sys_destroy_mutex(sys_mutex m)
{
uae_sem_destroy(&m);
-}
\ No newline at end of file
+}
+
+#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