]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Flush trap queues during reset.
authorToni Wilen <twilen@winuae.net>
Sun, 15 Sep 2024 14:53:47 +0000 (17:53 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 15 Sep 2024 14:53:47 +0000 (17:53 +0300)
devices.cpp
include/traps.h
traps.cpp

index 74635b16128115cb78a8701f014c71b2304007bd..73376174ede23c03178cc7774df2965b6a8be1ca 100644 (file)
@@ -218,6 +218,7 @@ void devices_reset(int hardreset)
        driveclick_reset();
 #endif
        ethernet_reset();
+       reset_traps();
 #ifdef FILESYS
        filesys_prepare_reset();
        filesys_reset();
@@ -321,13 +322,14 @@ void virtualdevice_free(void)
 
        execute_device_items(device_leaves_early, device_leave_early_cnt);
 
+       reset_traps();
+       free_traps();
 #ifdef FILESYS
        filesys_cleanup();
 #endif
 #ifdef BSDSOCKET
        bsdlib_reset();
 #endif
-       free_traps();
        sampler_free();
        inputdevice_close();
        DISK_free();
index fb11bc867d37401f1568827161c1b1165aedc7f8..5288b0acda2709cd1bea9d243137867969a9b9d3 100644 (file)
@@ -83,6 +83,7 @@ extern uae_u32 CallFunc (TrapContext *context, uaecptr func);
  */
 void init_traps(void);
 void free_traps(void);
+void reset_traps(void);
 void init_extended_traps(void);
 
 #define deftrap(f) define_trap((f), 0, _T(#f))
index 4498e7e750d1fa6aa1990df35218adea6e8b3c4a..15841fcb729066ae46c6ed82e064e50dc9a56d27 100644 (file)
--- a/traps.cpp
+++ b/traps.cpp
@@ -78,6 +78,7 @@ struct Trap
 /* Defined traps */
 static struct Trap  traps[MAX_TRAPS];
 static unsigned int trap_count = 1;
+static volatile int hardware_trap_state[MAX_TRAPS];
 
 volatile uae_atomic hwtrap_waiting;
 
@@ -576,8 +577,16 @@ static void hardware_trap_thread(void *arg)
        size_t tid = (size_t)arg;
        for (;;) {
                TrapContext *ctx = (TrapContext*)read_comm_pipe_pvoid_blocking(&trap_thread_pipe[tid]);
-               if (!ctx)
-                       break;
+               if (!ctx) {
+                       if (!hardware_trap_state[tid]) {
+                               break;
+                       }
+                       while (comm_pipe_has_data(&trap_thread_pipe[tid])) {
+                               read_comm_pipe_pvoid_blocking(&trap_thread_pipe[tid]);
+                       }
+                       hardware_trap_state[tid] = 0;
+                       continue;
+               }
 
                if (trap_in_use[ctx->trap_slot]) {
                        write_log(_T("TRAP SLOT %d ALREADY IN USE!\n"));
@@ -700,6 +709,14 @@ void free_host_trap_context(TrapContext *ctx)
 static uae_u32 call_hardware_trap_back(TrapContext *ctx, uae_u16 cmd, uae_u32 p1, uae_u32 p2, uae_u32 p3, uae_u32 p4)
 {
        int trap_slot = ((ctx->amiga_trap_data & 0xffff) - RTAREA_TRAP_DATA) / RTAREA_TRAP_DATA_SLOT_SIZE;
+
+       if (hardware_trap_kill[trap_slot] != 1) {
+               if (hardware_trap_kill[trap_slot] == 0) {
+                       hardware_trap_kill[trap_slot] = 2;
+               }
+               return 0;
+       }
+       
        uae_u8 *data = ctx->host_trap_data + RTAREA_TRAP_DATA_SECOND;
        uae_u8 *status = ctx->host_trap_status + RTAREA_TRAP_STATUS_SECOND;
 
@@ -737,15 +754,17 @@ static uae_u32 call_hardware_trap_back(TrapContext *ctx, uae_u16 cmd, uae_u32 p1
        }
 
        for (;;) {
-               if (hardware_trap_kill[trap_slot] < 0)
+               if (hardware_trap_kill[trap_slot] != 0 && hardware_trap_kill[trap_slot] != 1) {
                        return 0;
-               uae_u8 v = *d;
-               if (v == 0x01 || v == 0x02 || v == 0x03)
-                       break;
+               }
                if (hardware_trap_kill[trap_slot] == 0) {
                        hardware_trap_kill[trap_slot] = 2;
                        return  0;
                }
+               uae_u8 v = *d;
+               if (v == 0x01 || v == 0x02 || v == 0x03) {
+                       break;
+               }
                if (uae_sem_trywait_delay(&hardware_trap_event[trap_slot], 100) == -2) {
                        hardware_trap_kill[trap_slot] = 3;
                        return 0;
@@ -828,9 +847,34 @@ void init_traps(void)
        }
 }
 
+void reset_traps(void)
+{
+       for (int i = 0; i < TRAP_THREADS; i++) {
+               if (trap_thread_id[i]) {
+                       int htk = hardware_trap_kill[i];
+                       hardware_trap_kill[i] = -1;
+                       hardware_trap_state[i] = 1;
+                       write_comm_pipe_pvoid(&trap_thread_pipe[i], NULL, 1);
+                       while (hardware_trap_state[i] > 0) {
+                               for (int j = 0; j < RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE; j++) {
+                                       uae_sem_post(&hardware_trap_event[j]);
+                                       uae_sem_post(&hardware_trap_event2[j]);
+                               }
+                               sleep_millis(1);
+                       }
+                       hardware_trap_kill[i] = htk;
+               }
+       }
+       for (int j = 0; j < RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE; j++) {
+               uae_sem_unpost(&hardware_trap_event[j]);
+               uae_sem_unpost(&hardware_trap_event2[j]);
+       }
+}
+
 void free_traps(void)
 {
        for (int i = 0; i < TRAP_THREADS; i++) {
+               hardware_trap_state[i] = 0;
                if (trap_thread_id[i]) {
                        if (hardware_trap_kill[i] >= 0) {
                                hardware_trap_kill[i] = 0;