Merge branch 'ekeeke:master' into master
Some checks failed
Crowdin Translation Integration / create_intl_file (push) Failing after 1s

This commit is contained in:
ds22x 2024-09-19 00:13:10 +02:00 committed by GitHub
commit 7de0f0b6cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 110 additions and 76 deletions

View File

@ -37,7 +37,8 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
* improved CDD status report accuracy (fixes track looping with Mode 1 patched games using MSU-MD driver)
* improved Word-RAM byte access accuracy (verified on schematics)
* improved GFX processing accuracy to halt it while Word RAM is allocated to Main CPU in 2M mode
* improved GFX timing accuracy (fixes "Night Striker" crashing after completing a game)
* improved GFX processing timing accuracy (fixes "Night Striker" crashing after completing a game)
* improved GFX processing robustness in case of word-RAM address overflow (fixes potential emulator crash in Flink level 20)
* improved Sub-CPU BUSREQ status accuracy
* disabled 68k and Z80 access to PRG-RAM when SUB-CPU is running (fixes "Dungeon Explorer")
* disabled CD hardware reset on Soft-Reset (verified on real hardware)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 MiB

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 MiB

After

Width:  |  Height:  |  Size: 4.0 MiB

View File

@ -224,7 +224,8 @@ static const md_entry_t rom_database[] =
{0x0000,0x19ff,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,m68k_unused_8_w,default_regs_r,NULL}},
/* Soul Blade */
{0x0000,0x0c5b,0x40,0x40,{{0x63,0x98,0xc9,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,m68k_unused_8_w,default_regs_r,NULL}},
/* Shi San Zhang Ma Jiang: Zhong Guo Mei Nv Pian (only $400004 is checked, other addresses/values are assumed) */
{0xffff,0xd41d,0x40,0x40,{{0x63,0x98,0xc9,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,m68k_unused_8_w,default_regs_r,NULL}},
/* King of Fighter 98 */
{0x0000,0xd0a0,0x48,0x4f,{{0x00,0x00,0xaa,0xf0},{0xffffff,0xffffff,0xfc0000,0xfc0000},{0x000000,0x000000,0x480000,0x4c0000},0,0,NULL,m68k_unused_8_w,default_regs_r,NULL}},

View File

@ -209,6 +209,9 @@ void cdd_reset(void)
/* reset status */
cdd.status = cdd.loaded ? CD_TOC : NO_DISC;
/* reset pending flag */
cdd.pending = 0;
/* reset CD-DA fader (full volume) */
cdd.fader[0] = cdd.fader[1] = 0x400;
@ -220,6 +223,7 @@ int cdd_context_save(uint8 *state)
{
int bufferptr = 0;
unsigned int offset = 0;
uint8 tmp8;
save_param(&cdd.cycles, sizeof(cdd.cycles));
save_param(&cdd.latency, sizeof(cdd.latency));
@ -227,7 +231,10 @@ int cdd_context_save(uint8 *state)
save_param(&cdd.lba, sizeof(cdd.lba));
save_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
save_param(&cdd.fader, sizeof(cdd.fader));
save_param(&cdd.status, sizeof(cdd.status));
/* 4-bit pending flag and 4-bit CDD status are saved together (to maintain backward savestate compatibility) */
tmp8 = cdd.status | (cdd.pending << 4);
save_param(&tmp8, sizeof(tmp8));
/* current track is an audio track ? */
if (cdd.toc.tracks[cdd.index].type == TYPE_AUDIO)
@ -266,6 +273,7 @@ int cdd_context_load(uint8 *state, char *version)
{
unsigned int offset, lba, index;
int bufferptr = 0;
uint8 tmp8;
load_param(&cdd.cycles, sizeof(cdd.cycles));
load_param(&cdd.latency, sizeof(cdd.latency));
@ -273,7 +281,11 @@ int cdd_context_load(uint8 *state, char *version)
load_param(&lba, sizeof(cdd.lba));
load_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
load_param(&cdd.fader, sizeof(cdd.fader));
load_param(&cdd.status, sizeof(cdd.status));
/* 4-bit pending flag and 4-bit CDD status are saved together (to maintain backward savestate compatibility) */
load_param(&tmp8, sizeof(tmp8));
cdd.status = tmp8 & 0xf;
cdd.pending = tmp8 >> 4;
/* update current sector */
cdd.lba = lba;
@ -1869,86 +1881,86 @@ void cdd_update(void)
{
/* CDC decoder is still running while disc is not being read (fixes MCD-verificator CDC Flags Test #30) */
cdc_decoder_update(0);
}
/* scanning disc */
if (cdd.status == CD_SCAN)
{
/* current track index */
int index = cdd.index;
/* fast-forward or fast-rewind */
cdd.lba += cdd.scanOffset;
/* check current track limits */
if (cdd.lba >= cdd.toc.tracks[index].end)
/* scanning disc */
if (cdd.status == CD_SCAN)
{
/* next track */
index++;
/* current track index */
int index = cdd.index;
/* check disc limits */
if (index < cdd.toc.last)
/* fast-forward or fast-rewind */
cdd.lba += cdd.scanOffset;
/* check current track limits */
if (cdd.lba >= cdd.toc.tracks[index].end)
{
/* skip directly to next track start position */
cdd.lba = cdd.toc.tracks[index].start;
/* next track */
index++;
/* check disc limits */
if (index < cdd.toc.last)
{
/* skip directly to next track start position */
cdd.lba = cdd.toc.tracks[index].start;
}
else
{
/* end of disc */
cdd.lba = cdd.toc.end;
cdd.index = cdd.toc.last;
cdd.status = CD_END;
/* no audio track playing */
scd.regs[0x36>>1].byte.h = 0x01;
return;
}
}
else if (cdd.lba < cdd.toc.tracks[index].start)
{
/* check disc limits */
if (index > 0)
{
/* previous track */
index--;
/* skip directly to previous track end position */
cdd.lba = cdd.toc.tracks[index].end;
}
else
{
/* start of first track */
cdd.lba = 0;
}
}
/* seek to current subcode position */
if (cdd.toc.sub)
{
cdStreamSeek(cdd.toc.sub, cdd.lba * 96, SEEK_SET);
}
/* current track is an audio track ? */
if (cdd.toc.tracks[index].type == TYPE_AUDIO)
{
/* seek to current track sector */
cdd_seek_audio(index, cdd.lba);
/* audio track playing */
scd.regs[0x36>>1].byte.h = 0x00;
}
else
{
/* end of disc */
cdd.lba = cdd.toc.end;
cdd.index = cdd.toc.last;
cdd.status = CD_END;
/* no audio track playing */
scd.regs[0x36>>1].byte.h = 0x01;
return;
}
}
else if (cdd.lba < cdd.toc.tracks[index].start)
{
/* check disc limits */
if (index > 0)
{
/* previous track */
index--;
/* skip directly to previous track end position */
cdd.lba = cdd.toc.tracks[index].end;
}
else
{
/* start of first track */
cdd.lba = 0;
}
/* udpate current track index */
cdd.index = index;
}
/* seek to current subcode position */
if (cdd.toc.sub)
{
cdStreamSeek(cdd.toc.sub, cdd.lba * 96, SEEK_SET);
}
/* current track is an audio track ? */
if (cdd.toc.tracks[index].type == TYPE_AUDIO)
{
/* seek to current track sector */
cdd_seek_audio(index, cdd.lba);
/* audio track playing */
scd.regs[0x36>>1].byte.h = 0x00;
}
else
{
/* no audio track playing */
scd.regs[0x36>>1].byte.h = 0x01;
}
/* udpate current track index */
cdd.index = index;
}
/* seeking should start with at least one interrupt delay (fixes Radical Rex incorrect PRG-RAM & Word-RAM initialization, causing missing sprites during intro) */
if (scd.regs[0x38>>1].byte.h == CD_SEEK)
/* check if seeking is pending */
if (cdd.pending)
{
/* reset track index */
int index = 0;
@ -2016,8 +2028,11 @@ void cdd_update(void)
/* no audio track playing (yet) */
scd.regs[0x36>>1].byte.h = 0x01;
/* update CDD status to either PLAY or PAUSE depending on host command (will be reported to host once seeking has ended) */
cdd.status = scd.regs[0x42>>1].byte.h & 0x05;
/* update CDD status with pending end status (will be reported to host once seeking has ended) */
cdd.status = cdd.pending;
/* clear pending flag */
cdd.pending = 0;
}
}
@ -2202,6 +2217,10 @@ void cdd_process(void)
scd.regs[0x3c>>1].w = 0x0000;
scd.regs[0x3e>>1].w = 0x0000;
scd.regs[0x40>>1].w = ~(CD_SEEK + 0x0f) & 0x0f;
/* seeking should start with at least one interrupt delay (fixes Radical Rex incorrect PRG-RAM & Word-RAM initialization, causing missing sprites during intro) */
/* so pending flag is set (with CDD end status) to indicate seeking is pending */
cdd.pending = CD_PLAY;
return;
}
@ -2213,6 +2232,10 @@ void cdd_process(void)
scd.regs[0x3c>>1].w = 0x0000;
scd.regs[0x3e>>1].w = 0x0000;
scd.regs[0x40>>1].w = ~(CD_SEEK + 0x0f) & 0x0f;
/* seeking should start with at least one interrupt delay (same as 'Play' command) */
/* so pending flag is set (with CDD end status) to indicate seeking is pending */
cdd.pending = CD_PAUSE;
return;
}

View File

@ -117,6 +117,7 @@ typedef struct
int scanOffset;
uint16 fader[2];
uint8 status;
uint8 pending;
uint16 sectorSize;
toc_t toc;
#if defined(USE_LIBCHDR)

View File

@ -455,9 +455,11 @@ int gfx_context_load(uint8 *state)
load_param(&gfx.bufferStart, sizeof(gfx.bufferStart));
load_param(&tmp32, 4);
tmp32 &= 0x3fff8;
gfx.tracePtr = (uint16 *)(scd.word_ram_2M + tmp32);
load_param(&tmp32, 4);
tmp32 &= ~((1 << ((2*gfx.mapShift) + 1)) - 1) & 0x3ffff;
gfx.mapPtr = (uint16 *)(scd.word_ram_2M + tmp32);
return bufferptr;
@ -480,6 +482,12 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
uint32 xoffset = (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 */
while (width--)
{
@ -557,7 +565,7 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
}
/* 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 */
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];
/* 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 */
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 */
/* 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 */
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 */
scd.regs[0x58>>1].byte.h = 0x80;
@ -731,7 +739,7 @@ void gfx_update(int cycles)
while (lines--)
{
/* 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) */
gfx.bufferStart += 8;