diff --git a/Assets/dll/gpgx.wbx.zst b/Assets/dll/gpgx.wbx.zst index bb61da0e3a..c30aa68375 100644 Binary files a/Assets/dll/gpgx.wbx.zst and b/Assets/dll/gpgx.wbx.zst differ diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IMemoryDomains.cs b/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IMemoryDomains.cs index 8f70d3691c..49f16344e8 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IMemoryDomains.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IMemoryDomains.cs @@ -66,23 +66,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx (addr, val) => { if (addr is < 0 or > 0x7F) throw new ArgumentOutOfRangeException(paramName: nameof(addr), addr, message: "address out of range"); - using (_elf.EnterExit()) - { - var c = *(ushort*)&p![addr & ~1]; - c = (ushort)(((c & 0x1C0) << 3) | ((c & 0x038) << 2) | ((c & 0x007) << 1)); - if ((addr & 1) != 0) - { - c &= 0xFF00; - c |= val; - } - else - { - c &= 0x00FF; - c |= (ushort)(val << 8); - } - c = (ushort)(((c & 0xE00) >> 3) | ((c & 0x0E0) >> 2) | ((c & 0x00E) >> 1)); - *(ushort*)&p![addr & ~1] = c; - } + Core.gpgx_poke_cram((int)addr, val); }, wordSize: 2)); } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/LibGPGX.cs b/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/LibGPGX.cs index 2e7f64ecf1..d2aeddbc60 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/LibGPGX.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/LibGPGX.cs @@ -310,6 +310,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx [BizImport(CallingConvention.Cdecl, Compatibility = true)] public abstract void gpgx_get_vdp_view([Out] VDPView view); + [BizImport(CallingConvention.Cdecl)] + public abstract void gpgx_poke_cram(int addr, byte value); + [BizImport(CallingConvention.Cdecl)] public abstract void gpgx_poke_vram(int addr, byte value); diff --git a/waterbox/gpgx/cinterface/cinterface.c b/waterbox/gpgx/cinterface/cinterface.c index 378c4792e8..1fdd924c7a 100644 --- a/waterbox/gpgx/cinterface/cinterface.c +++ b/waterbox/gpgx/cinterface/cinterface.c @@ -343,6 +343,11 @@ GPGX_EX int gpgx_put_sram(const uint8 *data, int size) } } +GPGX_EX void gpgx_poke_cram(int addr, uint8 val) +{ + write_cram_byte(addr, val); +} + GPGX_EX void gpgx_poke_vram(int addr, uint8 val) { write_vram_byte(addr, val); diff --git a/waterbox/gpgx/core/vdp_ctrl.c b/waterbox/gpgx/core/vdp_ctrl.c index a5c530f660..c759865d26 100644 --- a/waterbox/gpgx/core/vdp_ctrl.c +++ b/waterbox/gpgx/core/vdp_ctrl.c @@ -194,6 +194,45 @@ static void (*const dma_func[16])(unsigned int length) = vdp_dma_copy,vdp_dma_copy,vdp_dma_copy,vdp_dma_copy }; +void write_cram_byte(int addr, uint8 val) +{ + uint16 *p; + uint16 data; + int index; + + p = (uint16 *)&cram[addr & 0x7E]; + data = *p; + data = ((data & 0x1C0) << 3) | ((data & 0x038) << 2) | ((data & 0x007) << 1); + + if (addr & 1) + { + data &= 0xFF00; + data |= val; + } + else + { + data &= 0x00FF; + data |= val << 8; + } + + data = ((data & 0xE00) >> 3) | ((data & 0x0E0) >> 2) | ((data & 0x00E) >> 1); + + if (*p != data) + { + index = (addr >> 1) & 0x3F; + *p = data; + + if (index & 0x0F) + { + color_update_m5(index, data); + } + + if (index == border) + { + color_update_m5(0x00, data); + } + } +} void write_vram_byte(int addr, uint8 val) { diff --git a/waterbox/gpgx/core/vdp_ctrl.h b/waterbox/gpgx/core/vdp_ctrl.h index b3d60f8488..8d3036b284 100644 --- a/waterbox/gpgx/core/vdp_ctrl.h +++ b/waterbox/gpgx/core/vdp_ctrl.h @@ -100,6 +100,7 @@ extern unsigned int vdp_hvc_r(unsigned int cycles); extern void vdp_test_w(unsigned int data); extern int vdp_68k_irq_ack(int int_level); +void write_cram_byte(int addr, uint8 val); void write_vram_byte(int addr, uint8 val); void flush_vram_cache(void); void vdp_invalidate_full_cache(void);