gdrom: allow 0-len transfer

fixes Pro Pinball Trilogy hang during intro
This commit is contained in:
Flyinghead 2020-12-18 19:27:19 +01:00
parent 0d81c9fb0b
commit d0d9712545
1 changed files with 12 additions and 19 deletions

View File

@ -1047,17 +1047,18 @@ static int getGDROMTicks()
{
if (SB_GDST & 1)
{
if (SB_GDLEN - SB_GDLEND > 10240)
u32 len = SB_GDLEN == 0 ? 0x02000000 : SB_GDLEN;
if (len - SB_GDLEND > 10240)
return 1000000; // Large transfers: GD-ROM transfer rate 1.8 MB/s
else
return std::min((u32)10240, SB_GDLEN - SB_GDLEND) * 2; // Small transfers: Max G1 bus rate: 50 MHz x 16 bits
return std::min((u32)10240, len - SB_GDLEND) * 2; // Small transfers: Max G1 bus rate: 50 MHz x 16 bits
}
else
return 0;
}
//is this needed ?
int GDRomschd(int i, int c, int j)
static int GDRomschd(int i, int c, int j)
{
if (SecNumber.Status == GD_SEEK)
{
@ -1072,11 +1073,8 @@ int GDRomschd(int i, int c, int j)
if(!(SB_GDST&1) || !(SB_GDEN &1) || (read_buff.cache_size==0 && read_params.remaining_sectors==0))
return 0;
//TODO : Fix dmaor
u32 dmaor = DMAC_DMAOR.full;
u32 src = SB_GDSTARD,
len = SB_GDLEN-SB_GDLEND ;
u32 src = SB_GDSTARD;
u32 len = (SB_GDLEN == 0 ? 0x02000000 : SB_GDLEN) - SB_GDLEND;
if(SB_GDLEN & 0x1F)
{
@ -1091,9 +1089,9 @@ int GDRomschd(int i, int c, int j)
len = std::min(len, (u32)10240);
// do we need to do this for GDROM DMA?
if(0x8201 != (dmaor &DMAOR_MASK))
if (0x8201 != (DMAC_DMAOR.full & DMAOR_MASK))
{
INFO_LOG(GDROM, "GDROM: DMAOR has invalid settings (%X)", dmaor);
INFO_LOG(GDROM, "GDROM: DMAOR has invalid settings (%X)", DMAC_DMAOR.full);
//return;
}
@ -1130,17 +1128,12 @@ int GDRomschd(int i, int c, int j)
WARN_LOG(GDROM, "GDROM: SB_GDDIR %X (TO AICA WAVE MEM?)", src);
}
//SB_GDLEN = 0x00000000; //13/5/2k7 -> according to docs these regs are not updated by hardware
//SB_GDSTAR = (src + len_backup);
SB_GDLEND = (SB_GDLEND + len_backup) & 0x01ffffe0;
SB_GDSTARD += len_backup;
SB_GDLEND+= len_backup;
SB_GDSTARD+= len_backup;//(src + len_backup)&0x1FFFFFFF;
if (SB_GDLEND==SB_GDLEN)
if (SB_GDLEND == SB_GDLEN)
{
//printf("Streamed GDMA end - %d bytes transferred\n",SB_GDLEND);
SB_GDST=0;//done
// The DMA end interrupt flag
SB_GDST = 0;
asic_RaiseInterrupt(holly_GDROM_DMA);
}
//Read ALL sectors