]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2900b20
authorToni Wilen <twilen@winuae.net>
Sun, 12 Oct 2014 16:29:59 +0000 (19:29 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 12 Oct 2014 16:29:59 +0000 (19:29 +0300)
debug.cpp
include/uae/qemu.h [new file with mode: 0644]
od-win32/win32.h
od-win32/winuae_msvc11/winuae_msvc.vcxproj
od-win32/winuae_msvc11/winuae_msvc.vcxproj.filters
od-win32/winuaechangelog.txt
ppc/ppc.cpp

index 610cfd453952d51db96de78c0d30df5a1df72ef9..241483ec1de69a3878d342340ab14bab40d4a764 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -2998,7 +2998,9 @@ static void memory_map_dump_3(UaeMemoryMap *map, int log)
                                tmp[0] = 0;
                                if ((a1->flags & ABFLAG_ROM) && mirrored) {
                                        TCHAR *p = txt + _tcslen (txt);
-                                       uae_u32 crc = get_crc32 (a1->xlateaddr((j << 16) | bankoffset), (size * 1024) / mirrored);
+                                       uae_u32 crc = 0xffffffff;
+                                       if (a1->check(((j << 16) | bankoffset), (size * 1024) / mirrored))
+                                               crc = get_crc32 (a1->xlateaddr((j << 16) | bankoffset), (size * 1024) / mirrored);
                                        struct romdata *rd = getromdatabycrc (crc);
                                        _stprintf (p, _T(" (%08X)"), crc);
                                        if (rd) {
diff --git a/include/uae/qemu.h b/include/uae/qemu.h
new file mode 100644 (file)
index 0000000..2283370
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef UAE_QEMU_H
+#define UAE_QEMU_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"
+
+/* The qemu-uae major version must match this */
+#define QEMU_UAE_VERSION_MAJOR 3
+
+/* The qemu-uae minor version must be at least this */
+#define QEMU_UAE_VERSION_MINOR 3
+
+UAE_DECLARE_IMPORT_FUNCTION(
+       void, qemu_uae_version, int *major, int *minor, int *revision)
+UAE_DECLARE_IMPORT_FUNCTION(
+       void, qemu_uae_init, void)
+UAE_DECLARE_IMPORT_FUNCTION(
+       void, qemu_uae_start, void)
+UAE_DECLARE_IMPORT_FUNCTION(
+       int, qemu_uae_lock, int)
+
+UAE_DECLARE_IMPORT_FUNCTION(
+       void, qemu_uae_slirp_init, void)
+UAE_DECLARE_IMPORT_FUNCTION(
+       void, qemu_uae_slirp_input, const uint8_t *pkt, int pkt_len)
+
+UAE_DECLARE_EXPORT_FUNCTION(
+       void, uae_slirp_output, const uint8_t *pkt, int pkt_len)
+
+UAE_DECLARE_IMPORT_FUNCTION(
+       bool, qemu_uae_ppc_init, const char* model, uint32_t hid1)
+UAE_DECLARE_IMPORT_FUNCTION(
+       bool, qemu_uae_ppc_in_cpu_thread, void)
+UAE_DECLARE_IMPORT_FUNCTION(
+       void, qemu_uae_ppc_external_interrupt, bool)
+
+#define QEMU_UAE_LOCK_TRYLOCK 1
+#define QEMU_UAE_LOCK_TRYLOCK_CANCEL 2
+#define QEMU_UAE_LOCK_ACQUIRE 3
+#define QEMU_UAE_LOCK_RELEASE 4
+
+#ifdef UAE
+
+#include "uae/dlopen.h"
+
+UAE_DLHANDLE uae_qemu_uae_init(void);
+
+#endif /* UAE */
+
+#if 0
+#ifdef UAE
+typedef void (QEMUCALL *qemu_uae_version_function)(int *major, int *minor,
+                                                                                                  int *revision);
+extern qemu_uae_version_function qemu_uae_version;
+#else
+void qemu_uae_version(int *major, int *minor, int *revision);
+#endif
+
+#ifdef UAE
+typedef void (QEMUCALL *qemu_uae_init_function)(void);
+extern qemu_uae_init_function qemu_uae_init;
+#else
+void qemu_uae_init(void);
+#endif
+#endif
+
+#endif /* UAE_QEMU_H */
index 83f74b0f22435497255e60a5dd2b5d1532726dc6..c99962bf900697229f85c1fc4a9e02e96489135d 100644 (file)
 #define LANG_DLL_FULL_VERSION_MATCH 1
 
 #if WINUAEPUBLICBETA
-#define WINUAEBETA _T("19")
+#define WINUAEBETA _T("20")
 #else
 #define WINUAEBETA _T("")
 #endif
 
-#define WINUAEDATE MAKEBD(2014, 10, 6)
+#define WINUAEDATE MAKEBD(2014, 10, 12)
 
 //#define WINUAEEXTRA _T("AmiKit Preview")
 //#define WINUAEEXTRA _T("Amiga Forever Edition")
index 088bbb358e8cc2fc7eaa9b9a9bdb500a225e9df2..b17339e3237bb8c4e074458a9e81ab97bfd24101 100644 (file)
     <ClCompile Include="..\..\aros.rom.cpp" />
     <ClCompile Include="..\..\calc.cpp" />
     <ClCompile Include="..\..\cd32_fmv_genlock.cpp" />
+    <ClCompile Include="..\..\cdtvcr.cpp" />
     <ClCompile Include="..\..\cpuboard.cpp" />
     <ClCompile Include="..\..\cpuemu_13.cpp" />
     <ClCompile Include="..\..\cpuemu_21.cpp" />
index cc787cc16e84eea9368d89903256daa3c4a63a14..70db4f03b6bfcf7546b7f788e3fd61b4d52d1036 100644 (file)
     <ClCompile Include="..\..\logging.cpp">
       <Filter>common</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\cdtvcr.cpp">
+      <Filter>common</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\resources\35floppy.ico">
index 80e8295d5fa7ea34f7c124e561ad7b16ad05c7c6..0a2828a8408aefc45588cf6bd7563204e816280a 100644 (file)
@@ -18,9 +18,19 @@ Things that may happen in 2015:
 
 - restore only single input target to default.
 
+Beta 20:
+
+- A2630 rom was not unmapped completely (only first half)
+- CSMK3/CSPPC/BPPC Amiga reset bit should stop the PPC before reseting the system to prevent random hangs.
+- CSMK3/CSPPC/BPPC switching off maprom programmatically (not hard reset) didn't restore original KS ROM.
+- Added preliminary CDTV-CR emulation. Boots to title screen, preferences screen also works. Only clock
+  and 4k (nonvolatile?) RAM emulated. No CD, no nothing else. v3.32 extended ROM added to ROM scanner,
+  CDTV-CR option added to Quickstart.
+- PPC interrupt/thread-safety hang problems should be fixed.
+
 Beta 19:
 
-- Restartarting and loading another config crashed if PPC or RTG without JIT direct was active.
+- Restarting and loading another config crashed if PPC or RTG without JIT direct was active.
 - After restarting non-JIT config, JIT direct was not available (old restriction that should have been gone
   few official releases ago)
 - Added A2620/A2630 emulation and two rom images to rom scanner. (390282-06/390283-06 and 390282-07/390283-07)
index b6571d65d2b29fae8a110863790a6c11dcc7557e..1a8d885a7b0eea513a64d7a9ad4c85ee53f63e37 100644 (file)
 
 #include "uae/ppc.h"
 
-/* The qemu-uae major version must match this */
-#define QEMU_UAE_VERSION_MAJOR 2
-
-/* The qemu-uae minor version must be at least this */
-#define QEMU_UAE_VERSION_MINOR 0
+#include "uae/qemu.h"
 
 #define SPINLOCK_DEBUG 0
 #define PPC_ACCESS_LOG 0
@@ -189,6 +185,10 @@ static struct impl {
        ppc_cpu_check_state_function check_state;
        ppc_cpu_set_state_function set_state;
        ppc_cpu_reset_function reset;
+       qemu_uae_ppc_in_cpu_thread_function in_cpu_thread;
+       qemu_uae_ppc_external_interrupt_function external_interrupt;
+       qemu_uae_lock_function lock;
+
 } impl;
 
 static void load_dummy_implementation(void)
@@ -247,8 +247,7 @@ static bool load_qemu_implementation(void)
        impl.init = (ppc_cpu_init_function) uae_dlsym(handle, "ppc_cpu_init");
        //impl.free = (ppc_cpu_free_function) uae_dlsym(handle, "ppc_cpu_free");
        //impl.stop = (ppc_cpu_stop_function) uae_dlsym(handle, "ppc_cpu_stop");
-       impl.atomic_raise_ext_exception = (ppc_cpu_atomic_raise_ext_exception_function) uae_dlsym(handle, "ppc_cpu_atomic_raise_ext_exception");
-       impl.atomic_cancel_ext_exception = (ppc_cpu_atomic_cancel_ext_exception_function) uae_dlsym(handle, "ppc_cpu_atomic_cancel_ext_exception");
+       impl.external_interrupt = (qemu_uae_ppc_external_interrupt_function) uae_dlsym(handle, "qemu_uae_ppc_external_interrupt");
        impl.map_memory = (ppc_cpu_map_memory_function) uae_dlsym(handle, "ppc_cpu_map_memory");
        //impl.set_pc = (ppc_cpu_set_pc_function) uae_dlsym(handle, "ppc_cpu_set_pc");
        impl.run_continuous = (ppc_cpu_run_continuous_function) uae_dlsym(handle, "ppc_cpu_run_continuous");
@@ -259,6 +258,8 @@ static bool load_qemu_implementation(void)
        impl.check_state = (ppc_cpu_check_state_function) uae_dlsym(handle, "ppc_cpu_check_state");
        impl.set_state = (ppc_cpu_set_state_function) uae_dlsym(handle, "ppc_cpu_set_state");
        impl.reset = (ppc_cpu_reset_function) uae_dlsym(handle, "ppc_cpu_reset");
+       impl.in_cpu_thread = (qemu_uae_ppc_in_cpu_thread_function) uae_dlsym(handle, "qemu_uae_ppc_in_cpu_thread");
+       impl.lock = (qemu_uae_lock_function) uae_dlsym(handle, "qemu_uae_lock");
 
        /* Check major version (=) and minor version (>=) */
 
@@ -340,6 +341,64 @@ static bool using_pearpc(void)
        return ppc_implementation == PPC_IMPLEMENTATION_PEARPC;
 }
 
+enum PPCLockMethod {
+       PPC_RELEASE_SPINLOCK,
+       PPC_KEEP_SPINLOCK,
+};
+
+enum PPCLockStatus {
+       PPC_NO_LOCK_NEEDED,
+       PPC_LOCKED,
+       PPC_LOCKED_WITHOUT_SPINLOCK,
+};
+
+static PPCLockStatus get_ppc_lock(PPCLockMethod method)
+{
+       if (impl.in_cpu_thread()) {
+               return PPC_NO_LOCK_NEEDED;
+       } else if (method == PPC_RELEASE_SPINLOCK) {
+
+               uae_ppc_spinlock_release();
+               impl.lock(QEMU_UAE_LOCK_ACQUIRE);
+               return PPC_LOCKED_WITHOUT_SPINLOCK;
+
+       } else if (method == PPC_KEEP_SPINLOCK) {
+
+               bool trylock_called = false;
+               while (true) {
+                       if (ppc_spinlock_waiting) {
+                               /* PPC CPU is waiting for the spinlock and the UAE side
+                                * owns the spinlock - no additional locking needed */
+                               if (trylock_called) {
+                                       impl.lock(QEMU_UAE_LOCK_TRYLOCK_CANCEL);
+                               }
+                               return PPC_NO_LOCK_NEEDED;
+                       }
+                       int error = impl.lock(QEMU_UAE_LOCK_TRYLOCK);
+                       if (error == 0) {
+                               /* Lock succeeded */
+                               return PPC_LOCKED;
+                       }
+                       trylock_called = true;
+               }
+       } else {
+               write_log("?\n");
+               return PPC_NO_LOCK_NEEDED;
+       }
+}
+
+static void release_ppc_lock(PPCLockStatus status)
+{
+       if (status == PPC_NO_LOCK_NEEDED) {
+               return;
+       } else if (status == PPC_LOCKED_WITHOUT_SPINLOCK) {
+               impl.lock(QEMU_UAE_LOCK_RELEASE);
+               uae_ppc_spinlock_get();
+       } else if (status == PPC_LOCKED) {
+               impl.lock(QEMU_UAE_LOCK_RELEASE);
+       }
+}
+
 static void initialize(void)
 {
        static bool initialized = false;
@@ -380,7 +439,15 @@ static void map_banks(void)
                regions[i].alias = r->alias;
                regions[i].memory = r->memory;
        }
+
+       if (impl.in_cpu_thread() == false) {
+               uae_ppc_spinlock_release();
+       }
        impl.map_memory(regions, map.num_regions);
+       if (impl.in_cpu_thread() == false) {
+               uae_ppc_spinlock_get();
+       }
+
        for (int i = 0; i < map.num_regions; i++) {
                free((void*)regions[i].name);
        }
@@ -400,14 +467,13 @@ static void set_and_wait_for_state(int state, int unlock)
                return;
        }
        if (using_qemu()) {
-               impl.set_state(state);
-               if (unlock)
+               if (impl.in_cpu_thread() == false) {
                        uae_ppc_spinlock_release();
-               while (!impl.check_state(state)) {
-                       sleep_millis(1);
                }
-               if (unlock)
-                       uae_ppc_spinlock_get();
+               impl.set_state(state);
+               if (impl.in_cpu_thread() == false) {
+                       uae_ppc_spinlock_get();
+               }
        }
 }
 
@@ -421,7 +487,16 @@ void ppc_map_banks(uae_u32 start, uae_u32 size, const TCHAR *name, void *addr, b
        r.name = ua(name);
        r.alias = remove ? 0xffffffff : 0;
        r.memory = addr;
+
+       if (impl.in_cpu_thread() == false) {
+               /* map_memory will acquire the qemu global lock, so we must ensure
+                * the PPC CPU can finish any I/O requests and release the lock. */
+               uae_ppc_spinlock_release();
+       }
        impl.map_memory(&r, -1);
+       if (impl.in_cpu_thread() == false) {
+               uae_ppc_spinlock_get();
+       }
        free((void*)r.name);
 }
 
@@ -775,12 +850,19 @@ void uae_ppc_wakeup(void)
 void uae_ppc_interrupt(bool active)
 {
        //TRACE(_T("uae_ppc_interrupt\n"));
-       if (active) {
-               impl.atomic_raise_ext_exception();
-               uae_ppc_wakeup();
-       } else {
-               impl.atomic_cancel_ext_exception();
-       }
+       if (using_pearpc()) {
+               if (active) {
+                       impl.atomic_raise_ext_exception();
+                       uae_ppc_wakeup();
+               } else {
+                       impl.atomic_cancel_ext_exception();
+               }
+               return;
+       }
+
+       PPCLockStatus status = get_ppc_lock(PPC_KEEP_SPINLOCK);
+       impl.external_interrupt(active);
+       release_ppc_lock(status);
 }
 
 // sleep until interrupt (or PPC stopped)