From: Toni Wilen Date: Sun, 7 Sep 2014 18:48:53 +0000 (+0300) Subject: Spinlock io access optimization. X-Git-Tag: 3000~48 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=06347265d5b90f7556a833e6fb309a3fea3ffaf6;p=francis%2Fwinuae.git Spinlock io access optimization. --- diff --git a/cpuboard.cpp b/cpuboard.cpp index 10a5d1ac..f27397b8 100644 --- a/cpuboard.cpp +++ b/cpuboard.cpp @@ -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); diff --git a/expansion.cpp b/expansion.cpp index 0069624f..0b46933d 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -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 }; /* ********************************************************** */ diff --git a/gfxboard.cpp b/gfxboard.cpp index 1ff91cdc..11d518f0 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -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) { diff --git a/include/memory.h b/include/memory.h index 6f647df9..695279a6 100644 --- a/include/memory.h +++ b/include/memory.h @@ -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; diff --git a/memory.cpp b/memory.cpp index 02e10f3f..678e6807 100644 --- a/memory.cpp +++ b/memory.cpp @@ -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 diff --git a/ncr_scsi.cpp b/ncr_scsi.cpp index 7413b870..9979264c 100644 --- a/ncr_scsi.cpp +++ b/ncr_scsi.cpp @@ -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 }; diff --git a/ppc/ppc.cpp b/ppc/ppc.cpp index 6b6a6c4e..8fda57e0 100644 --- a/ppc/ppc.cpp +++ b/ppc/ppc.cpp @@ -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;