diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IStatable.cs
index 954098b2d7..9ec418d7a7 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IStatable.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.IStatable.cs
@@ -40,6 +40,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
Core.gpgx_set_input_callback(InputCallback);
RefreshMemCallbacks();
Core.gpgx_set_cdd_callback(cd_callback_handle);
+ Core.gpgx_invalidate_pattern_cache();
UpdateVideo();
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs
index 4b6852566f..d47a89eefe 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs
@@ -304,9 +304,18 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
[BizImport(CallingConvention.Cdecl)]
public abstract void gpgx_poke_vram(int addr, byte value);
- [BizImport(CallingConvention.Cdecl)]
+ ///
+ /// regenerate whatever portions of the bg pattern cache are currently dirty.
+ ///
+ [BizImport(CallingConvention.Cdecl)] // the core will handle this itself; you only need to call this when using the cache for your own purposes
public abstract void gpgx_flush_vram();
+ ///
+ /// mark the bg pattern cache as dirty
+ ///
+ [BizImport(CallingConvention.Cdecl)]
+ public abstract void gpgx_invalidate_pattern_cache();
+
[StructLayout(LayoutKind.Sequential)]
public struct RegisterInfo
{
diff --git a/waterbox/gpgx/cinterface/cinterface.c b/waterbox/gpgx/cinterface/cinterface.c
index 119817ac20..57b6b89441 100644
--- a/waterbox/gpgx/cinterface/cinterface.c
+++ b/waterbox/gpgx/cinterface/cinterface.c
@@ -211,7 +211,7 @@ typedef struct
} vdpview_t;
-extern uint8 bg_pattern_cache[];
+extern uint8 *bg_pattern_cache;
extern uint32 pixel[];
GPGX_EX void gpgx_get_vdp_view(vdpview_t *view)
@@ -509,6 +509,7 @@ GPGX_EX int gpgx_init(const char *feromextension, ECL_ENTRY int (*feload_archive
bitmap.pitch = 1024 * 4;
bitmap.data = alloc_invisible(2 * 1024 * 1024);
tempsram = alloc_invisible(24 * 1024);
+ bg_pattern_cache = alloc_invisible(0x80000);
ext.md_cart.rom = alloc_sealed(32 * 1024 * 1024);
scd.bootrom = malloc(0x20000); // FIXME: this should be sealed, but that crashes. huh?
@@ -617,6 +618,11 @@ GPGX_EX void gpgx_set_draw_mask(int mask)
color_update_m5(0x00, *(uint16 *)&cram[border << 1]);
}
+GPGX_EX void gpgx_invalidate_pattern_cache(void)
+{
+ vdp_invalidate_full_cache();
+}
+
typedef struct
{
unsigned int value;
diff --git a/waterbox/gpgx/core/vdp_ctrl.c b/waterbox/gpgx/core/vdp_ctrl.c
index 29e128d027..0242a75e6c 100644
--- a/waterbox/gpgx/core/vdp_ctrl.c
+++ b/waterbox/gpgx/core/vdp_ctrl.c
@@ -147,7 +147,7 @@ static void (*set_irq_line)(unsigned int level);
static void (*set_irq_line_delay)(unsigned int level);
/* Vertical counter overflow values (see hvc.h) */
-static const uint16 vc_table[4][2] =
+static const uint16 vc_table[4][2] =
{
/* NTSC, PAL */
{0xDA , 0xF2}, /* Mode 4 (192 lines) */
@@ -203,6 +203,16 @@ void flush_vram_cache(void)
}
}
+void vdp_invalidate_full_cache(void)
+{
+ bg_list_index = 0x800;
+ for (int i=0;i SYSTEM_SG)
{
- for (i=0;i<0x10;i++)
+ for (i=0;i<0x10;i++)
{
pending = 1;
addr_latch = temp_reg[i];
@@ -479,7 +489,7 @@ int vdp_context_load(uint8 *state, uint8 version)
}
else
{
- for (i=0;i<0x08;i++)
+ for (i=0;i<0x08;i++)
{
pending = 1;
addr_latch = temp_reg[i];
@@ -489,7 +499,7 @@ int vdp_context_load(uint8 *state, uint8 version)
}
else
{
- for (i=0;i<0x20;i++)
+ for (i=0;i<0x20;i++)
{
vdp_reg_w(i, temp_reg[i], 0);
}
@@ -560,7 +570,7 @@ int vdp_context_load(uint8 *state, uint8 version)
}
/* invalidate cache */
- for (i=0;i 0x%x (%x)\n", v_counter, (cycles/MCYCLES_PER_LINE-1)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, data, m68k_get_reg(M68K_REG_PC));
#endif
@@ -1716,7 +1726,7 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
if ((r & 0x20) && vint_pending)
{
/* Update IRQ status */
- if (d & 0x20)
+ if (d & 0x20)
{
set_irq_line_delay(6);
}
@@ -1851,7 +1861,7 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
}
/* Invalidate pattern cache */
- for (i=0;i> 1) & 0x1F;
-
+
/* Write CRAM data */
*p = data;
@@ -3053,7 +3063,7 @@ static void vdp_dma_68k_ext(unsigned int length)
}
}
-
+
/* Increment source address */
source += 2;
@@ -3081,7 +3091,7 @@ static void vdp_dma_68k_ram(unsigned int length)
{
/* access Work-RAM by default */
data = *(uint16 *)(work_ram + (source & 0xFFFF));
-
+
/* Increment source address */
source += 2;
@@ -3115,7 +3125,7 @@ static void vdp_dma_68k_io(unsigned int length)
data = ((zstate ^ 3) ? *(uint16 *)(work_ram + (source & 0xFFFF)) : 0xFFFF);
}
- /* The I/O chip and work RAM try to drive the data bus which results
+ /* The I/O chip and work RAM try to drive the data bus which results
in both values being combined in random ways when read.
We return the I/O chip values which seem to have precedence, */
else if (source <= 0xA1001F)
@@ -3153,7 +3163,7 @@ static void vdp_dma_copy(unsigned int length)
{
int name;
uint8 data;
-
+
/* VRAM source address */
uint16 source = dma_src;
@@ -3258,7 +3268,7 @@ static void vdp_dma_fill(unsigned int length)
color_update_m5(0x00, data);
}
}
-
+
/* Increment CRAM address */
addr += reg[15];
}
@@ -3275,7 +3285,7 @@ static void vdp_dma_fill(unsigned int length)
{
/* Write VSRAM data */
*(uint16 *)&vsram[addr & 0x7E] = data;
-
+
/* Increment VSRAM address */
addr += reg[15];
}
diff --git a/waterbox/gpgx/core/vdp_ctrl.h b/waterbox/gpgx/core/vdp_ctrl.h
index 6cdcd5cf3c..454ea45f43 100644
--- a/waterbox/gpgx/core/vdp_ctrl.h
+++ b/waterbox/gpgx/core/vdp_ctrl.h
@@ -104,5 +104,6 @@ extern int vdp_68k_irq_ack(int int_level);
void write_vram_byte(int addr, uint8 val);
void flush_vram_cache(void);
+void vdp_invalidate_full_cache(void);
#endif /* _VDP_H_ */
diff --git a/waterbox/gpgx/core/vdp_render.c b/waterbox/gpgx/core/vdp_render.c
index 895d294501..161503d606 100644
--- a/waterbox/gpgx/core/vdp_render.c
+++ b/waterbox/gpgx/core/vdp_render.c
@@ -560,7 +560,7 @@ static const uint32 tms_palette[16] =
#endif
/* Cached and flipped patterns */
-uint8 bg_pattern_cache[0x80000];
+uint8 *bg_pattern_cache;
/* Sprite pattern name offset look-up table (Mode 5) */
static uint8 name_lut[0x400];