]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Spinlock io access optimization.
authorToni Wilen <twilen@winuae.net>
Sun, 7 Sep 2014 18:48:53 +0000 (21:48 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 7 Sep 2014 18:48:53 +0000 (21:48 +0300)
cpuboard.cpp
expansion.cpp
gfxboard.cpp
include/memory.h
memory.cpp
ncr_scsi.cpp
ppc/ppc.cpp

index 10a5d1ac2d396a787572959d66cbee5536afa276..f27397b81888d69cf072ff4f830152956efa8091 100644 (file)
@@ -4,6 +4,7 @@
 * Misc accelerator board special features
 * Blizzard 1230 IV, 1240/1260, 2040/2060, PPC
 * CyberStorm MK1, MK2, MK3, PPC.
+* TekMagic
 * Warp Engine
 *
 * Copyright 2014 Toni Wilen
@@ -262,7 +263,7 @@ static addrbank blizzardio_bank = {
        blizzardio_lget, blizzardio_wget, blizzardio_bget,
        blizzardio_lput, blizzardio_wput, blizzardio_bput,
        default_xlate, default_check, NULL, NULL, _T("CPUBoard IO"),
-       blizzardio_wget, blizzardio_bget, ABFLAG_IO
+       blizzardio_wget, blizzardio_bget, ABFLAG_IO | ABFLAG_THREADSAFE
 };
 
 DECLARE_MEMORY_FUNCTIONS(blizzardram);
@@ -270,7 +271,7 @@ static addrbank blizzardram_bank = {
        blizzardram_lget, blizzardram_wget, blizzardram_bget,
        blizzardram_lput, blizzardram_wput, blizzardram_bput,
        blizzardram_xlate, blizzardram_check, NULL, NULL, _T("CPUBoard RAM"),
-       blizzardram_lget, blizzardram_wget, ABFLAG_RAM
+       blizzardram_lget, blizzardram_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 
 DECLARE_MEMORY_FUNCTIONS(blizzardea);
@@ -302,7 +303,7 @@ static addrbank blizzardram_nojit_bank = {
        blizzardram_nojit_lget, blizzardram_nojit_wget, blizzardram_nojit_bget,
        blizzardram_nojit_lput, blizzardram_nojit_wput, blizzardram_nojit_bput,
        blizzardram_nojit_xlate, blizzardram_nojit_check, NULL, NULL, _T("CPUBoard RAM"),
-       blizzardram_nojit_lget, blizzardram_nojit_wget, ABFLAG_RAM
+       blizzardram_nojit_lget, blizzardram_nojit_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 
 DECLARE_MEMORY_FUNCTIONS(blizzardmaprom);
index 0069624fd270283391334b00cdb4ff63a30548eb..0b46933d11ef23bc7521f4654adfd05de33f6b87 100644 (file)
@@ -718,25 +718,25 @@ addrbank fastmem_bank = {
        fastmem_lget, fastmem_wget, fastmem_bget,
        fastmem_lput, fastmem_wput, fastmem_bput,
        fastmem_xlate, fastmem_check, NULL, _T("fast"), _T("Fast memory"),
-       fastmem_lget, fastmem_wget, ABFLAG_RAM
+       fastmem_lget, fastmem_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 addrbank fastmem_nojit_bank = {
        fastmem_nojit_lget, fastmem_nojit_wget, fastmem_bget,
        fastmem_nojit_lput, fastmem_nojit_wput, fastmem_bput,
        fastmem_nojit_xlate, fastmem_nojit_check, NULL, NULL, _T("Fast memory (nojit)"),
-       fastmem_nojit_lget, fastmem_nojit_wget, ABFLAG_RAM
+       fastmem_nojit_lget, fastmem_nojit_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 addrbank fastmem2_bank = {
        fastmem2_lget, fastmem2_wget, fastmem2_bget,
        fastmem2_lput, fastmem2_wput, fastmem2_bput,
        fastmem2_xlate, fastmem2_check, NULL,_T("fast2"), _T("Fast memory 2"),
-       fastmem2_lget, fastmem2_wget, ABFLAG_RAM
+       fastmem2_lget, fastmem2_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 addrbank fastmem2_nojit_bank = {
        fastmem2_nojit_lget, fastmem2_nojit_wget, fastmem2_nojit_bget,
        fastmem2_nojit_lput, fastmem2_nojit_wput, fastmem2_nojit_bput,
        fastmem2_nojit_xlate, fastmem2_nojit_check, NULL, NULL, _T("Fast memory #2 (nojit)"),
-       fastmem2_nojit_lget, fastmem2_nojit_wget, ABFLAG_RAM
+       fastmem2_nojit_lget, fastmem2_nojit_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 
 static addrbank *fastbanks[] = 
@@ -969,19 +969,19 @@ addrbank z3fastmem_bank = {
        z3fastmem_lget, z3fastmem_wget, z3fastmem_bget,
        z3fastmem_lput, z3fastmem_wput, z3fastmem_bput,
        z3fastmem_xlate, z3fastmem_check, NULL, _T("z3"), _T("Zorro III Fast RAM"),
-       z3fastmem_lget, z3fastmem_wget, ABFLAG_RAM
+       z3fastmem_lget, z3fastmem_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 addrbank z3fastmem2_bank = {
        z3fastmem2_lget, z3fastmem2_wget, z3fastmem2_bget,
        z3fastmem2_lput, z3fastmem2_wput, z3fastmem2_bput,
        z3fastmem2_xlate, z3fastmem2_check, NULL, _T("z3_2"), _T("Zorro III Fast RAM #2"),
-       z3fastmem2_lget, z3fastmem2_wget, ABFLAG_RAM
+       z3fastmem2_lget, z3fastmem2_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 addrbank z3chipmem_bank = {
        z3chipmem_lget, z3chipmem_wget, z3chipmem_bget,
        z3chipmem_lput, z3chipmem_wput, z3chipmem_bput,
        z3chipmem_xlate, z3chipmem_check, NULL, _T("z3_chip"), _T("MegaChipRAM"),
-       z3chipmem_lget, z3chipmem_wget, ABFLAG_RAM
+       z3chipmem_lget, z3chipmem_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 
 /* ********************************************************** */
index 1ff91cdc5cabd5e1177afbe04c32ef07aaacca04..11d518f027f9eb8e04868bd6c8e26352b7f65678 100644 (file)
@@ -40,6 +40,8 @@ static bool memlogw = false;
 #include "qemuvga/qemuuaeglue.h"
 #include "qemuvga/vga.h"
 
+#define MONITOR_SWITCH_DELAY 25
+
 #define GFXBOARD_AUTOCONFIG_SIZE 131072
 
 #define BOARD_REGISTERS_SIZE 0x00010000
@@ -183,9 +185,9 @@ static CirrusVGAState vga;
 static uae_u8 *vram, *vramrealstart;
 static int vram_start_offset;
 static uae_u32 gfxboardmem_start;
-static bool monswitch;
-static bool oldswitch;
+static bool monswitch_current, monswitch_new;
 static bool monswitch_reset;
+static int monswitch_delay;
 static int fullrefresh;
 static bool modechanged;
 static uae_u8 *gfxboard_surface, *vram_address, *fakesurface_surface;
@@ -238,15 +240,17 @@ bool gfxboard_toggle (int mode)
 {
        if (vram == NULL)
                return false;
-       if (monswitch) {
-               monswitch = false;
+       if (monswitch_current) {
+               monswitch_new = false;
+               monswitch_delay = 1;
                picasso_requested_on = 0;
                return true;
        } else {
                int width, height;
                vga.vga.get_resolution (&vga.vga, &width, &height);
                if (width > 16 && height > 16) {
-                       monswitch = true;
+                       monswitch_new = true;
+                       monswitch_delay = 1;
                        picasso_requested_on = 1;
                        return true;
                }
@@ -357,7 +361,7 @@ void gfxboard_vsync_handler (void)
        if (!configured_mem || !configured_regs)
                return;
 
-       if (monswitch && (modechanged || gfxboard_checkchanged ())) {
+       if (monswitch_current && (modechanged || gfxboard_checkchanged ())) {
                if (!gfxboard_setmode ()) {
                        picasso_requested_on = 0;
                        return;
@@ -368,14 +372,20 @@ void gfxboard_vsync_handler (void)
                return;
        }
 
-       if (monswitch != oldswitch) {
-               if (!monswitch)
-                       picasso_requested_on = monswitch;
-               oldswitch = monswitch;
-               write_log (_T("GFXBOARD ACTIVE=%d\n"), monswitch);
+       if (monswitch_new != monswitch_current) {
+               if (monswitch_delay > 0)
+                       monswitch_delay--;
+               if (monswitch_delay == 0) {
+                       if (!monswitch_new)
+                               picasso_requested_on = 0;
+                       monswitch_current = monswitch_new;
+                       write_log (_T("GFXBOARD ACTIVE=%d\n"), monswitch_current);
+               }
+       } else {
+               monswitch_delay = 0;
        }
 
-       if (monswitch) {
+       if (monswitch_current) {
                picasso_getwritewatch (vram_start_offset);
                if (fullrefresh)
                        vga.vga.graphic_mode = -1;
@@ -562,6 +572,14 @@ static void reset_pci (void)
        cirrus_pci[0x13] &= ~1; // memory
 }
 
+static void set_monswitch(bool newval)
+{
+       if (monswitch_new == newval)
+               return;
+       monswitch_new = newval; 
+       monswitch_delay = MONITOR_SWITCH_DELAY;
+}
+
 static void picassoiv_checkswitch (void)
 {
        if (ISP4()) {
@@ -571,7 +589,7 @@ static void picassoiv_checkswitch (void)
                if (monswitch_reset && rtg_active)
                        return;
                monswitch_reset = false;
-               monswitch = rtg_active; 
+               set_monswitch(rtg_active);
        }
 }
 
@@ -1453,16 +1471,17 @@ static void REGPARAM2 gfxboard_bput_regs (uaecptr addr, uae_u32 b)
                        {
                                if ((addr & 1) == 0) {
                                        int idx = addr >> 12;
-                                       if (idx == 0x0b || idx == 0x09)
-                                               monswitch = false;
-                                       else if (idx == 0x0a || idx == 0x08)
-                                               monswitch = true;
+                                       if (idx == 0x0b || idx == 0x09) {
+                                               set_monswitch(false);
+                                       } else if (idx == 0x0a || idx == 0x08) {
+                                               set_monswitch(true);
+                                       }
                                }
                        }
                break;
                case BOARD_MANUFACTURER_PICCOLO:
                case BOARD_MANUFACTURER_SPECTRUM:
-                       monswitch = (b & 0x20) != 0;
+                       set_monswitch((b & 0x20) != 0);
                        gfxboard_intena = (b & 0x40) != 0;
                break;
                }
@@ -1533,8 +1552,9 @@ void gfxboard_reset (void)
        fakesurface_surface = NULL;
        configured_mem = 0;
        configured_regs = 0;
-       monswitch = false;
-       oldswitch = false;
+       monswitch_new = false;
+       monswitch_current = false;
+       monswitch_delay = -1;
        monswitch_reset = true;
        modechanged = false;
        gfxboard_vblank = false;
@@ -1552,42 +1572,40 @@ static addrbank gfxboard_bank_memory = {
        gfxboard_lget_mem, gfxboard_wget_mem, gfxboard_bget_mem,
        gfxboard_lput_mem, gfxboard_wput_mem, gfxboard_bput_mem,
        gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
-       gfxboard_lget_mem, gfxboard_wget_mem, ABFLAG_RAM
+       gfxboard_lget_mem, gfxboard_wget_mem, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 static addrbank gfxboard_bank_memory_nojit = {
        gfxboard_lget_mem_nojit, gfxboard_wget_mem_nojit, gfxboard_bget_mem_nojit,
        gfxboard_lput_mem_nojit, gfxboard_wput_mem_nojit, gfxboard_bput_mem_nojit,
        gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
-       gfxboard_lget_mem_nojit, gfxboard_wget_mem_nojit, ABFLAG_RAM
+       gfxboard_lget_mem_nojit, gfxboard_wget_mem_nojit, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 
 static addrbank gfxboard_bank_wbsmemory = {
        gfxboard_lget_wbsmem, gfxboard_wget_wbsmem, gfxboard_bget_bsmem,
        gfxboard_lput_wbsmem, gfxboard_wput_wbsmem, gfxboard_bput_bsmem,
        gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
-       gfxboard_lget_wbsmem, gfxboard_wget_wbsmem, ABFLAG_RAM
+       gfxboard_lget_wbsmem, gfxboard_wget_wbsmem, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 static addrbank gfxboard_bank_lbsmemory = {
        gfxboard_lget_lbsmem, gfxboard_wget_lbsmem, gfxboard_bget_bsmem,
        gfxboard_lput_lbsmem, gfxboard_wput_lbsmem, gfxboard_bput_bsmem,
        gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
-       gfxboard_lget_lbsmem, gfxboard_wget_lbsmem, ABFLAG_RAM
+       gfxboard_lget_lbsmem, gfxboard_wget_lbsmem, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 static addrbank gfxboard_bank_nbsmemory = {
        gfxboard_lget_nbsmem, gfxboard_wget_nbsmem, gfxboard_bget_bsmem,
        gfxboard_lput_nbsmem, gfxboard_wput_nbsmem, gfxboard_bput_bsmem,
        gfxboard_xlate, gfxboard_check, NULL, NULL, _T("Picasso IV banked VRAM"),
-       gfxboard_lget_nbsmem, gfxboard_wget_nbsmem, ABFLAG_RAM
+       gfxboard_lget_nbsmem, gfxboard_wget_nbsmem, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 static addrbank gfxboard_bank_registers = {
        gfxboard_lget_regs, gfxboard_wget_regs, gfxboard_bget_regs,
        gfxboard_lput_regs, gfxboard_wput_regs, gfxboard_bput_regs,
        default_xlate, default_check, NULL, NULL, NULL,
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
+       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE | ABFLAG_THREADSAFE
 };
 
-
-
 static uae_u32 REGPARAM2 gfxboards_lget_regs (uaecptr addr)
 {
        uae_u32 v = 0;
@@ -1932,7 +1950,7 @@ addrbank gfxboard_bank_special = {
        gfxboards_lget_regs, gfxboards_wget_regs, gfxboards_bget_regs,
        gfxboards_lput_regs, gfxboards_wput_regs, gfxboards_bput_regs,
        default_xlate, default_check, NULL, NULL, _T("Picasso IV MISC"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
+       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE | ABFLAG_THREADSAFE
 };
 bool gfxboard_is_z3 (int type)
 {
index 6f647df94414612178458765ea02b03974db655c..695279a606112a20364ec4d790c6418e53dee70d 100644 (file)
@@ -69,7 +69,12 @@ extern uaecptr rtarea_base;
 
 extern uae_u8* baseaddr[];
 
-enum { ABFLAG_UNK = 0, ABFLAG_RAM = 1, ABFLAG_ROM = 2, ABFLAG_ROMIN = 4, ABFLAG_IO = 8, ABFLAG_NONE = 16, ABFLAG_SAFE = 32, ABFLAG_INDIRECT = 64, ABFLAG_NOALLOC = 128, ABFLAG_RTG = 256 };
+enum
+{
+       ABFLAG_UNK = 0, ABFLAG_RAM = 1, ABFLAG_ROM = 2, ABFLAG_ROMIN = 4, ABFLAG_IO = 8,
+       ABFLAG_NONE = 16, ABFLAG_SAFE = 32, ABFLAG_INDIRECT = 64, ABFLAG_NOALLOC = 128,
+       ABFLAG_RTG = 256, ABFLAG_THREADSAFE = 512
+};
 typedef struct {
        /* These ones should be self-explanatory... */
        mem_get_func lget, wget, bget;
index 02e10f3f4966c75478edcc077b9a20fd8c35a91a..678e68075c4725405a09b6ca299c53cf247ccd68 100644 (file)
@@ -1107,7 +1107,7 @@ addrbank chipmem_bank = {
        chipmem_lget, chipmem_wget, chipmem_bget,
        chipmem_lput, chipmem_wput, chipmem_bput,
        chipmem_xlate, chipmem_check, NULL, _T("chip"), _T("Chip memory"),
-       chipmem_lget, chipmem_wget, ABFLAG_RAM
+       chipmem_lget, chipmem_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 
 addrbank chipmem_dummy_bank = {
@@ -1131,7 +1131,7 @@ addrbank bogomem_bank = {
        bogomem_lget, bogomem_wget, bogomem_bget,
        bogomem_lput, bogomem_wput, bogomem_bput,
        bogomem_xlate, bogomem_check, NULL, _T("bogo"), _T("Slow memory"),
-       bogomem_lget, bogomem_wget, ABFLAG_RAM
+       bogomem_lget, bogomem_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 
 addrbank cardmem_bank = {
@@ -1145,21 +1145,21 @@ addrbank a3000lmem_bank = {
        a3000lmem_lget, a3000lmem_wget, a3000lmem_bget,
        a3000lmem_lput, a3000lmem_wput, a3000lmem_bput,
        a3000lmem_xlate, a3000lmem_check, NULL, _T("ramsey_low"), _T("RAMSEY memory (low)"),
-       a3000lmem_lget, a3000lmem_wget, ABFLAG_RAM
+       a3000lmem_lget, a3000lmem_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 
 addrbank a3000hmem_bank = {
        a3000hmem_lget, a3000hmem_wget, a3000hmem_bget,
        a3000hmem_lput, a3000hmem_wput, a3000hmem_bput,
        a3000hmem_xlate, a3000hmem_check, NULL, _T("ramsey_high"), _T("RAMSEY memory (high)"),
-       a3000hmem_lget, a3000hmem_wget, ABFLAG_RAM
+       a3000hmem_lget, a3000hmem_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 
 addrbank kickmem_bank = {
        kickmem_lget, kickmem_wget, kickmem_bget,
        kickmem_lput, kickmem_wput, kickmem_bput,
        kickmem_xlate, kickmem_check, NULL, _T("kick"), _T("Kickstart ROM"),
-       kickmem_lget, kickmem_wget, ABFLAG_ROM
+       kickmem_lget, kickmem_wget, ABFLAG_ROM | ABFLAG_THREADSAFE
 };
 
 addrbank kickram_bank = {
@@ -1173,13 +1173,13 @@ addrbank extendedkickmem_bank = {
        extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget,
        extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput,
        extendedkickmem_xlate, extendedkickmem_check, NULL, NULL, _T("Extended Kickstart ROM"),
-       extendedkickmem_lget, extendedkickmem_wget, ABFLAG_ROM
+       extendedkickmem_lget, extendedkickmem_wget, ABFLAG_ROM | ABFLAG_THREADSAFE
 };
 addrbank extendedkickmem2_bank = {
        extendedkickmem2_lget, extendedkickmem2_wget, extendedkickmem2_bget,
        extendedkickmem2_lput, extendedkickmem2_wput, extendedkickmem2_bput,
        extendedkickmem2_xlate, extendedkickmem2_check, NULL, _T("rom_a8"), _T("Extended 2nd Kickstart ROM"),
-       extendedkickmem2_lget, extendedkickmem2_wget, ABFLAG_ROM
+       extendedkickmem2_lget, extendedkickmem2_wget, ABFLAG_ROM | ABFLAG_THREADSAFE
 };
 
 MEMORY_FUNCTIONS(custmem1);
@@ -1189,13 +1189,13 @@ addrbank custmem1_bank = {
        custmem1_lget, custmem1_wget, custmem1_bget,
        custmem1_lput, custmem1_wput, custmem1_bput,
        custmem1_xlate, custmem1_check, NULL, _T("custmem1"), _T("Non-autoconfig RAM #1"),
-       custmem1_lget, custmem1_wget, ABFLAG_RAM
+       custmem1_lget, custmem1_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 addrbank custmem2_bank = {
        custmem2_lget, custmem2_wget, custmem2_bget,
        custmem2_lput, custmem2_wput, custmem2_bput,
        custmem2_xlate, custmem2_check, NULL, _T("custmem2"), _T("Non-autoconfig RAM #2"),
-       custmem2_lget, custmem2_wget, ABFLAG_RAM
+       custmem2_lget, custmem2_wget, ABFLAG_RAM | ABFLAG_THREADSAFE
 };
 
 #define fkickmem_size ROM_SIZE_512
index 7413b870448c03a0f354a27235c4194665f3253c..9979264c3691a6ed9a75362543f3314de7e92579 100644 (file)
@@ -465,7 +465,7 @@ static addrbank ncr_bank_a4091 = {
        ncr4_lget, ncr4_wget, ncr4_bget,
        ncr4_lput, ncr4_wput, ncr4_bput,
        default_xlate, default_check, NULL, NULL, _T("A4091"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
+       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE | ABFLAG_THREADSAFE
 };
 
 DECLARE_MEMORY_FUNCTIONS(ncr42)
@@ -474,7 +474,7 @@ static addrbank ncr_bank_a4091_2 = {
        ncr42_lget, ncr42_wget, ncr42_bget,
        ncr42_lput, ncr42_wput, ncr42_bput,
        default_xlate, default_check, NULL, NULL, _T("A4091 #2"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
+       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE | ABFLAG_THREADSAFE
 };
 
 static void REGPARAM2 ncr_wput (struct ncr_state *ncr, uaecptr addr, uae_u32 w)
@@ -662,20 +662,20 @@ static addrbank ncr_bank_warpengine = {
        we_lget, we_wget, we_bget,
        we_lput, we_wput, we_bput,
        default_xlate, default_check, NULL, NULL, _T("Warp Engine SCSI"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO
+       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_THREADSAFE
 };
 
 static addrbank ncr_bank_cs_scsi_ram = {
        cs_lget, cs_wget, cs_bget,
        cs_lput, cs_wput, cs_bput,
        cyberstorm_scsi_ram_xlate, cyberstorm_scsi_ram_check, NULL, NULL, _T("CyberStorm SCSI RAM"),
-       cs_lget, cs_wget, ABFLAG_IO
+       cs_lget, cs_wget, ABFLAG_IO | ABFLAG_THREADSAFE
 };
 static addrbank ncr_bank_cs_scsi_io = {
        cs_lget, cs_wget, cs_bget,
        cs_lput, cs_wput, cs_bput,
        default_xlate, default_check, NULL, NULL, _T("CyberStorm SCSI IO"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO
+       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_THREADSAFE
 };
 
 static struct addrbank_sub ncr_sub_bank_cs[] = {
@@ -695,14 +695,14 @@ addrbank ncr_bank_cyberstorm = {
        sub_bank_lget, sub_bank_wget, sub_bank_bget,
        sub_bank_lput, sub_bank_wput, sub_bank_bput,
        sub_bank_xlate, sub_bank_check, NULL, NULL, _T("CyberStorm SCSI"),
-       sub_bank_lgeti, sub_bank_wgeti, ABFLAG_IO, ncr_sub_bank_cs
+       sub_bank_lgeti, sub_bank_wgeti, ABFLAG_IO | ABFLAG_THREADSAFE, ncr_sub_bank_cs
 };
 
 addrbank ncr_bank_blizzardppc = {
        bppc_lget, bppc_wget, bppc_bget,
        bppc_lput, bppc_wput, bppc_bput,
        default_xlate, default_check, NULL, NULL, _T("Blizzard PPC SCSI"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO
+       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_THREADSAFE
 };
 
 
index 6b6a6c4e866ce0245e8df20034a6bd9a100ca350..8fda57e0c52edfb9b6164214f12c6eb06c87a758 100644 (file)
@@ -35,6 +35,10 @@ static volatile unsigned int ppc_spinlock, spinlock_cnt;
 void uae_ppc_spinlock_get(void)
 {
 #ifdef _WIN32
+       int sp = spinlock_cnt;
+       if (sp != 0 && sp != 1)
+               write_log(_T("uae_ppc_spinlock_get invalid %d\n"),  sp);
+
        while (true)
        {
                if(InterlockedCompareExchange(&ppc_spinlock, 1, 0) == 0) {
@@ -367,10 +371,10 @@ bool uae_ppc_to_main_thread(void)
 void uae_ppc_execute_quick(int linetype)
 {
        if (linetype == 0) {
-               for (int i = 0; i < 2; i++) {
-                       uae_ppc_spinlock_release();
-                       uae_ppc_spinlock_get();
-               }
+               uae_ppc_spinlock_release();
+               read_processor_time(); // tiny delay..
+               read_processor_time();
+               uae_ppc_spinlock_get();
        } else {
                uae_ppc_spinlock_release();
                sleep_millis(1);
@@ -470,9 +474,27 @@ bool uae_ppc_direct_physical_memory_handle(uint32_t addr, uint8_t *&ptr)
        return false;
 }
 
+STATIC_INLINE bool spinlock_pre(uaecptr addr)
+{
+       if (ppc_use_spinlock) {
+               addrbank *ab = &get_mem_bank(addr);
+               if ((ab->flags & ABFLAG_THREADSAFE) == 0) {
+                       uae_ppc_spinlock_get();
+                       return true;
+               }
+       }
+       return false;
+}
+
+STATIC_INLINE void spinlock_post(bool locked)
+{
+       if (ppc_use_spinlock && locked)
+               uae_ppc_spinlock_release();
+}
+
 bool UAECALL uae_ppc_io_mem_write(uint32_t addr, uint32_t data, int size)
 {
-       bool valid = false;
+       bool locked = false;
        while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
 
        if (ppc_io_pipe && !valid_address(addr, size)) {
@@ -495,11 +517,7 @@ bool UAECALL uae_ppc_io_mem_write(uint32_t addr, uint32_t data, int size)
                        write_log(_T("PPC io write %08x = %08x %d\n"), addr, data, size);
        }
 #endif
-       if (ppc_use_spinlock) {
-               valid = valid_address(addr, size) != 0;
-               if (!valid)
-                       uae_ppc_spinlock_get();
-       }
+       locked = spinlock_pre(addr);
        switch (size)
        {
        case 4:
@@ -512,12 +530,12 @@ bool UAECALL uae_ppc_io_mem_write(uint32_t addr, uint32_t data, int size)
                put_byte(addr, data);
                break;
        }
-       if (ppc_use_spinlock && !valid) {
+       if (ppc_use_spinlock) {
                if (addr == 0xdff09c || addr == 0xdff09a) {
                        int lev = intlev();
                        ppc_interrupt(lev);
                }
-               uae_ppc_spinlock_release();
+               spinlock_post(locked);
        }
 #if PPC_ACCESS_LOG > 2
        write_log(_T("PPC mem write %08x = %08x %d\n"), addr, data, size);
@@ -528,7 +546,7 @@ bool UAECALL uae_ppc_io_mem_write(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;
-       bool valid = false;
+       bool locked = false;
 
        while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
 
@@ -544,11 +562,7 @@ bool UAECALL uae_ppc_io_mem_read(uint32_t addr, uint32_t *data, int size)
                return true;
        }
 
-       if (ppc_use_spinlock) {
-               valid = valid_address(addr, size) != 0;
-               if (!valid)
-                       uae_ppc_spinlock_get();
-       }
+       locked = spinlock_pre(addr);
        switch (size)
        {
        case 4:
@@ -562,8 +576,7 @@ bool UAECALL uae_ppc_io_mem_read(uint32_t addr, uint32_t *data, int size)
                break;
        }
        *data = v;
-       if (ppc_use_spinlock && !valid)
-               uae_ppc_spinlock_release();
+       spinlock_post(locked);
 
 #if PPC_ACCESS_LOG > 0
        if (!ppc_io_pipe && !valid_address(addr, size)) {
@@ -579,7 +592,7 @@ bool UAECALL uae_ppc_io_mem_read(uint32_t addr, uint32_t *data, int size)
 
 bool UAECALL uae_ppc_io_mem_write64(uint32_t addr, uint64_t data)
 {
-       bool valid = false;
+       bool locked = false;
        while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
 
        if (ppc_io_pipe && !valid_address(addr, 8)) {
@@ -597,15 +610,10 @@ bool UAECALL uae_ppc_io_mem_write64(uint32_t addr, uint64_t data)
 #endif
                return true;
        }
-       if (ppc_use_spinlock) {
-               valid = valid_address(addr, 8) != 0;
-               if (!valid)
-                       uae_ppc_spinlock_get();
-       }
+       locked = spinlock_pre(addr);
        put_long(addr + 0, data >> 32);
        put_long(addr + 4, data & 0xffffffff);
-       if (ppc_use_spinlock && !valid)
-               uae_ppc_spinlock_release();
+       spinlock_post(locked);
 #if PPC_ACCESS_LOG > 2
        write_log(_T("PPC mem write64 %08x = %08llx\n"), addr, data);
 #endif
@@ -614,7 +622,7 @@ bool UAECALL uae_ppc_io_mem_write64(uint32_t addr, uint64_t data)
 
 bool UAECALL uae_ppc_io_mem_read64(uint32_t addr, uint64_t *data)
 {
-       bool valid = false;
+       bool locked = false;
        uint32_t v1, v2;
 
        while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
@@ -630,16 +638,11 @@ bool UAECALL uae_ppc_io_mem_read64(uint32_t addr, uint64_t *data)
 #endif
                return true;
        }
-       if (ppc_use_spinlock) {
-               valid = valid_address(addr, 8) != 0;
-               if (!valid)
-                       uae_ppc_spinlock_get();
-       }
+       locked = spinlock_pre(addr);
        v1 = get_long(addr + 0);
        v2 = get_long(addr + 4);
        *data = ((uint64_t)v1 << 32) | v2;
-       if (ppc_use_spinlock && !valid)
-               uae_ppc_spinlock_release();
+       spinlock_post(locked);
 #if PPC_ACCESS_LOG > 2
        write_log(_T("PPC mem read64 %08x = %08llx\n"), addr, *data);
 #endif
@@ -656,6 +659,10 @@ void uae_ppc_cpu_stop(void)
                while (ppc_state != PPC_STATE_STOP && ppc_state != PPC_STATE_CRASH) {
                        uae_ppc_wakeup();
                        uae_ppc_poll_queue();
+                       if (ppc_use_spinlock) {
+                               uae_ppc_spinlock_release();
+                               uae_ppc_spinlock_get();
+                       }
                }
                read_comm_pipe_u32_blocking(&ppcreturn);
                ppc_state = PPC_STATE_STOP;