mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-26 11:11:48 +01:00
[Core/CD] improved GFX processing robustness in case of word-RAM address overflow (fixes potential emulator crash in Flink level 20)
This commit is contained in:
parent
f9f16d7a55
commit
3b95fdf328
@ -455,9 +455,11 @@ int gfx_context_load(uint8 *state)
|
|||||||
load_param(&gfx.bufferStart, sizeof(gfx.bufferStart));
|
load_param(&gfx.bufferStart, sizeof(gfx.bufferStart));
|
||||||
|
|
||||||
load_param(&tmp32, 4);
|
load_param(&tmp32, 4);
|
||||||
|
tmp32 &= 0x3fff8;
|
||||||
gfx.tracePtr = (uint16 *)(scd.word_ram_2M + tmp32);
|
gfx.tracePtr = (uint16 *)(scd.word_ram_2M + tmp32);
|
||||||
|
|
||||||
load_param(&tmp32, 4);
|
load_param(&tmp32, 4);
|
||||||
|
tmp32 &= ~((1 << ((2*gfx.mapShift) + 1)) - 1) & 0x3ffff;
|
||||||
gfx.mapPtr = (uint16 *)(scd.word_ram_2M + tmp32);
|
gfx.mapPtr = (uint16 *)(scd.word_ram_2M + tmp32);
|
||||||
|
|
||||||
return bufferptr;
|
return bufferptr;
|
||||||
@ -480,6 +482,12 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
|
|||||||
uint32 xoffset = (int16) *gfx.tracePtr++;
|
uint32 xoffset = (int16) *gfx.tracePtr++;
|
||||||
uint32 yoffset = (int16) *gfx.tracePtr++;
|
uint32 yoffset = (int16) *gfx.tracePtr++;
|
||||||
|
|
||||||
|
/* handle trace vector address overflow */
|
||||||
|
if (gfx.tracePtr == (uint16 *)(scd.word_ram_2M + 0x40000)
|
||||||
|
{
|
||||||
|
gfx.tracePtr = (uint16 *)(scd.word_ram_2M);
|
||||||
|
}
|
||||||
|
|
||||||
/* process all dots */
|
/* process all dots */
|
||||||
while (width--)
|
while (width--)
|
||||||
{
|
{
|
||||||
@ -557,7 +565,7 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read out paired pixel data */
|
/* read out paired pixel data */
|
||||||
pixel_in = READ_BYTE(scd.word_ram_2M, bufferIndex >> 1);
|
pixel_in = READ_BYTE(scd.word_ram_2M, (bufferIndex >> 1) & 0x3ffff);
|
||||||
|
|
||||||
/* update left or rigth pixel */
|
/* update left or rigth pixel */
|
||||||
if (bufferIndex & 1)
|
if (bufferIndex & 1)
|
||||||
@ -573,7 +581,7 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
|
|||||||
pixel_out = gfx.lut_prio[(scd.regs[0x02>>1].w >> 3) & 0x03][pixel_in][pixel_out];
|
pixel_out = gfx.lut_prio[(scd.regs[0x02>>1].w >> 3) & 0x03][pixel_in][pixel_out];
|
||||||
|
|
||||||
/* write data to image buffer */
|
/* write data to image buffer */
|
||||||
WRITE_BYTE(scd.word_ram_2M, bufferIndex >> 1, pixel_out);
|
WRITE_BYTE(scd.word_ram_2M, (bufferIndex >> 1) & 0x3ffff, pixel_out);
|
||||||
|
|
||||||
/* check current pixel position */
|
/* check current pixel position */
|
||||||
if ((bufferIndex & 7) != 7)
|
if ((bufferIndex & 7) != 7)
|
||||||
@ -657,7 +665,7 @@ void gfx_start(unsigned int base, int cycles)
|
|||||||
/* reference: https://github.com/MiSTer-devel/MegaCD_MiSTer/blob/master/docs/mcd%20logs/graphics_operations_and_68k_wordram_access.jpg */
|
/* reference: https://github.com/MiSTer-devel/MegaCD_MiSTer/blob/master/docs/mcd%20logs/graphics_operations_and_68k_wordram_access.jpg */
|
||||||
/* TODO: figure what happen exactly when pixel offset is different from 0 */
|
/* TODO: figure what happen exactly when pixel offset is different from 0 */
|
||||||
/* for the moment, one additional read-modify-write access is assumed at the start if pixel offset is not aligned to 4 pixels */
|
/* for the moment, one additional read-modify-write access is assumed at the start if pixel offset is not aligned to 4 pixels */
|
||||||
gfx.cyclesPerLine = 4 * 3 * (4 + 2 * scd.regs[0x62>>1].w + ((scd.regs[0x62>>1].w + (scd.regs[0x60>>1].byte.l & 0x03) + 3) >> 2));
|
gfx.cyclesPerLine = 4 * 3 * (4 + 2 * (scd.regs[0x62>>1].w & 0x1ff) + (((scd.regs[0x62>>1].w & 0x1ff) + (scd.regs[0x60>>1].byte.l & 0x03) + 3) >> 2));
|
||||||
|
|
||||||
/* start graphics operation */
|
/* start graphics operation */
|
||||||
scd.regs[0x58>>1].byte.h = 0x80;
|
scd.regs[0x58>>1].byte.h = 0x80;
|
||||||
@ -731,7 +739,7 @@ void gfx_update(int cycles)
|
|||||||
while (lines--)
|
while (lines--)
|
||||||
{
|
{
|
||||||
/* process dots to image buffer */
|
/* process dots to image buffer */
|
||||||
gfx_render(gfx.bufferStart, scd.regs[0x62>>1].w);
|
gfx_render(gfx.bufferStart, scd.regs[0x62>>1].w & 0x1ff);
|
||||||
|
|
||||||
/* increment image buffer start index for next line (8 pixels/line) */
|
/* increment image buffer start index for next line (8 pixels/line) */
|
||||||
gfx.bufferStart += 8;
|
gfx.bufferStart += 8;
|
||||||
|
Loading…
Reference in New Issue
Block a user