]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Interrupt status atomic operations.
authorToni Wilen <twilen@winuae.net>
Sun, 31 Jan 2016 13:48:57 +0000 (15:48 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 31 Jan 2016 13:48:57 +0000 (15:48 +0200)
a2065.cpp
cpuboard.cpp
custom.cpp
include/custom.h
newcpu.cpp
pci.cpp
sndboard.cpp

index c43cc377b4f167a6b3e556b48a82c58cb28c29f3..b35f207548fe8ee6690010ec23c522e86c876d81 100644 (file)
--- a/a2065.cpp
+++ b/a2065.cpp
@@ -558,14 +558,14 @@ void a2065_hsync_handler (void)
 void rethink_a2065 (void)
 {
        bool was = (uae_int_requested & 4) != 0;
-       uae_int_requested &= ~4;
+       atomic_and(&uae_int_requested, ~4);
        if (!configured)
                return;
        csr[0] &= ~CSR0_INTR;
        if (csr[0] & (CSR0_BABL | CSR0_MISS | CSR0_MERR | CSR0_RINT | CSR0_TINT | CSR0_IDON))
                csr[0] |= CSR0_INTR;
        if ((csr[0] & (CSR0_INTR | CSR0_INEA)) == (CSR0_INTR | CSR0_INEA)) {
-               uae_int_requested |= 4;
+               atomic_or(&uae_int_requested, 4);
                if (!was && log_a2065 > 2)
                        write_log(_T("A2065 +IRQ\n"));
        }
index 3c4200ed7013271c9f0d28a4d91b7c6b9b651e1f..d501c19e2aec2451620ddea2830de1ed5df35743 100644 (file)
@@ -33,7 +33,9 @@
 #include "scsi.h"
 #include "cpummu030.h"
 
-// 00F83B7C 3.1 ROM expansion board diagrom
+// ROM expansion board diagrom call
+// 00F83B7C 3.1 A4000
+// 00F83C96 3.1 A1200
 
 #define PPC_IRQ_DEBUG 0
 #define CPUBOARD_IO_LOG 0
@@ -886,15 +888,15 @@ void cpuboard_rethink(void)
                if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_SCSI_EN | P5_IRQ_SCSI))) {
                        INTREQ_0(0x8000 | 0x0008);
                        if (currprefs.cachesize)
-                               uae_int_requested |= 0x010000;
+                               atomic_or(&uae_int_requested, 0x010000);
                        uae_ppc_wakeup_main();
                } else if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_PPC_1 | P5_IRQ_PPC_2))) {
                        INTREQ_0(0x8000 | 0x0008);
                        if (currprefs.cachesize)
-                               uae_int_requested |= 0x010000;
+                               atomic_or(&uae_int_requested, 0x010000);
                        uae_ppc_wakeup_main();
                } else {
-                       uae_int_requested &= ~0x010000;
+                       atomic_and(&uae_int_requested, ~0x010000);
                }
                check_ppc_int_lvl();
                ppc_interrupt(intlev());
index 10dd3884c4bace016d8e2588c1ec5d82c0616040..dda4bd5a8ca7e3ca3455ad4d245190e185de8905 100644 (file)
@@ -4979,6 +4979,31 @@ STATIC_INLINE int use_eventmode (uae_u16 v)
        return 0;
 }
 
+
+void rethink_uae_int(void)
+{
+       bool irq2 = false;
+       bool irq6 = false;
+
+       if (uae_int_requested) {
+               if (uae_int_requested & 0xff00)
+                       irq6 = true;
+               if (uae_int_requested & 0x00ff)
+                       irq2 = true;
+       }
+
+       {
+               extern void bsdsock_fake_int_handler(void);
+               extern int volatile bsd_int_requested;
+               if (bsd_int_requested)
+                       bsdsock_fake_int_handler();
+       }
+
+       uae_u16 mask = (irq6 ? 0x2000 : 0) | (irq2 ? 0x0008 : 0);
+       if (mask)
+               INTREQ_0(0x8000 | mask);
+}
+
 static void rethink_intreq (void)
 {
        serial_check_irq ();
@@ -5280,7 +5305,7 @@ static void BPLCON0 (int hpos, uae_u16 v)
                v &= ~0x00F1;
        else if (! (currprefs.chipset_mask & CSMASK_AGA))
                v &= ~0x00B0;
-       v &= ~(0x0080 | 0x0020);
+       v &= ~0x0080;
 
 #if SPRBORDER
        v |= 1;
@@ -8179,25 +8204,7 @@ static void hsync_handler_post (bool onvsync)
                reset_decisions ();
        }
 
-       if (uae_int_requested) {
-               if (uae_int_requested & 0xff00)
-                       INTREQ(0x8000 | 0x2000);
-               if (uae_int_requested & 0x00ff)
-                       INTREQ(0x8000 | 0x0008);
-       }
-
-       {
-               if (uaenet_int_requested || (uaenet_vsync_requested && vpos == 10)) {
-                       INTREQ (0x8000 | 0x0008);
-               }
-       }
-
-       {
-               extern void bsdsock_fake_int_handler (void);
-               extern int volatile bsd_int_requested;
-               if (bsd_int_requested)
-                       bsdsock_fake_int_handler ();
-       }
+       rethink_uae_int();
 
        /* Default to no bitplane DMA overriding sprite DMA */
        plfstrt_sprite = 0xff;
index e876bd47fd5299baae553ada9adb5bff5e2470d0..ebc1a2f44fd64d8d4f17319ee96de5366c50c769 100644 (file)
@@ -71,6 +71,7 @@ STATIC_INLINE int dmaen (unsigned int dmamask)
 #define SPCFLAG_COPPER 4
 #define SPCFLAG_INT 8
 #define SPCFLAG_BRK 16
+#define SPCFLAG_UAEINT 32
 #define SPCFLAG_TRACE 64
 #define SPCFLAG_DOTRACE 128
 #define SPCFLAG_DOINT 256 /* arg, JIT fails without this.. */
@@ -89,11 +90,12 @@ extern uae_u16 adkcon;
 extern unsigned int joy0dir, joy1dir;
 extern int joy0button, joy1button;
 
-extern void INTREQ (uae_u16);
-extern bool INTREQ_0 (uae_u16);
-extern void INTREQ_f (uae_u16);
-extern void send_interrupt (int num, int delay);
-extern uae_u16 INTREQR (void);
+extern void INTREQ(uae_u16);
+extern bool INTREQ_0(uae_u16);
+extern void INTREQ_f(uae_u16);
+extern void send_interrupt(int num, int delay);
+extern void rethink_uae_int(void);
+extern uae_u16 INTREQR(void);
 
 /* maximums for statically allocated tables */
 #ifdef UAE_MINI
index 6fdf3b38d0c2c64b696c2071e859a644ebc99b00..f70d9adca8dfea38cafa1b0dd105b8418e113a11 100644 (file)
@@ -3439,19 +3439,19 @@ static void do_trace (void)
 
 static void check_uae_int_request(void)
 {
-       if (uae_int_requested || uaenet_int_requested) {
+       if (uae_int_requested) {
                bool irq = false;
-               if ((uae_int_requested & 0x00ff) || uaenet_int_requested) {
-                       INTREQ_f(0x8000 | 0x0008);
+               if (uae_int_requested & 0x00ff) {
+                       INTREQ_0(0x8000 | 0x0008);
                        irq = true;
                }
                if (uae_int_requested & 0xff00) {
-                       INTREQ_f(0x8000 | 0x2000);
+                       INTREQ_0(0x8000 | 0x2000);
                        irq = true;
                }
                if (uae_int_requested & 0xff0000) {
                        if (!cpuboard_is_ppcboard_irq())
-                               uae_int_requested &= ~0x010000;
+                               atomic_and(&uae_int_requested, ~0x010000);
                }
                if (irq)
                        set_special(SPCFLAG_INT);
@@ -3569,6 +3569,9 @@ static bool haltloop(void)
                                ovpos = vpos;
                                while (ovpos == vpos) {
                                        x_do_cycles(8 * CYCLE_UNIT);
+                                       unset_special(SPCFLAG_UAEINT);
+                                       check_uae_int_request();
+                                       ppc_interrupt(intlev());
                                        uae_ppc_execute_check();
                                        if (regs.spcflags & SPCFLAG_COPPER)
                                                do_copper();
@@ -3673,6 +3676,7 @@ static int do_specialties (int cycles)
        
        if (regs.spcflags & SPCFLAG_CHECK) {
                if (regs.halted) {
+                       unset_special(SPCFLAG_CHECK);
                        if (haltloop())
                                return 1;
                }
@@ -3829,6 +3833,11 @@ static int do_specialties (int cycles)
        if (regs.spcflags & SPCFLAG_TRACE)
                do_trace ();
 
+       if (regs.spcflags & SPCFLAG_UAEINT) {
+               check_uae_int_request();
+               unset_special(SPCFLAG_UAEINT);
+       }
+
        if (m68k_interrupt_delay) {
                if (time_for_interrupt ()) {
                        do_interrupt (regs.ipl);
@@ -4401,7 +4410,7 @@ void exec_nostats (void)
 #endif
                }
 
-               if (end_block(r->opcode) || r->spcflags || uae_int_requested || uaenet_int_requested)
+               if (end_block(r->opcode) || r->spcflags || uae_int_requested)
                        return; /* We will deal with the spcflags in the caller */
        }
 }
@@ -4440,7 +4449,7 @@ void execute_normal (void)
                total_cycles += cpu_cycles;
                pc_hist[blocklen].specmem = special_mem;
                blocklen++;
-               if (end_block (r->opcode) || blocklen >= MAXRUN || r->spcflags || uae_int_requested || uaenet_int_requested) {
+               if (end_block (r->opcode) || blocklen >= MAXRUN || r->spcflags || uae_int_requested) {
                        compile_block (pc_hist, blocklen, total_cycles);
                        return; /* We will deal with the spcflags in the caller */
                }
diff --git a/pci.cpp b/pci.cpp
index 2315ae1052971b9caa15f24a231a20ffccea4462..38e14694929cc2f1c8fec687587ef1e9729fb1ff 100644 (file)
--- a/pci.cpp
+++ b/pci.cpp
@@ -138,7 +138,7 @@ void pci_free(void)
        for (int i = 0; i < MAX_PCI_BOARDS; i++) {
                hsyncs[i] = NULL;
        }
-       uae_int_requested &= ~(0x10 | 0x100);
+       atomic_and(&uae_int_requested, ~(0x10 | 0x100));
 }
 void pci_reset(void)
 {
@@ -155,7 +155,7 @@ void pci_hsync(void)
 
 void pci_rethink(void)
 {
-       uae_int_requested &= ~(0x10 | 0x100);
+       atomic_and(&uae_int_requested, ~(0x10 | 0x100));
        for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
                struct pci_bridge *pcib = bridges[i];
                if (!pcib)
@@ -173,7 +173,7 @@ void pci_rethink(void)
                        }
                }
                if (pcib->irq & pcib->intena) {
-                       uae_int_requested |= pcib->intreq_mask;
+                       atomic_or(&uae_int_requested, pcib->intreq_mask);
                }
        }
 }
index 578a7c67b1279e28723707699c159c7de0ae8557..11cb2a21d50e8dfec22a80918e8c2c2dd7ac818c 100644 (file)
@@ -269,9 +269,9 @@ static void codec_stop(void)
 void sndboard_rethink(void)
 {
        struct toccata_data *data = &toccata;
-       uae_int_requested &= ~0x200;
+       atomic_and(&uae_int_requested, ~0x200);
        if (data->toccata_irq)
-               uae_int_requested |= 0x200;
+               atomic_or(&uae_int_requested, 0x200);
 }
 
 static void sndboard_process_capture(void)
@@ -638,7 +638,7 @@ void sndboard_free(void)
 {
        struct toccata_data *data = &toccata;
        data->toccata_irq = 0;
-       uae_int_requested &= ~0x200;
+       atomic_and(&uae_int_requested, ~0x200);
 }
 
 void sndboard_reset(void)