X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fmdec.c;h=d6c7ab68fd34bb95cf3f556856830158097de206;hb=HEAD;hp=61ed5ea53047e2ccbd2178d96689ccacc01e2507;hpb=1ffdacd535251ca7d979e23df81a0f1181d6170c;p=pcsx_rearmed.git diff --git a/libpcsxcore/mdec.c b/libpcsxcore/mdec.c index 61ed5ea5..38b03e1b 100644 --- a/libpcsxcore/mdec.c +++ b/libpcsxcore/mdec.c @@ -33,12 +33,10 @@ * so 2.0 to 4.0 should be fine. */ -/* Was set to 2 before but it would cause issues in R-types and Vandal Hearts videos. - * Setting it to 6 as dmitrysmagin did fix those... except for Galerians. - * Galerians needs this to be set to 10 (!!) before it looks properly. - * I've tried this with a few other games (including R-Types) and so far, this - * has not backfired. - * */ +/* + * >= 10 for Galerians + * <= 18 for "Disney's Treasure Planet" + */ #define MDEC_BIAS 10 #define DSIZE 8 @@ -229,8 +227,8 @@ struct _pending_dma1 { static struct { u32 reg0; u32 reg1; - u16 * rl; - u16 * rl_end; + const u16 * rl; + const u16 * rl_end; u8 * block_buffer_pos; u8 block_buffer[16*16*3]; struct _pending_dma1 pending_dma1; @@ -260,7 +258,7 @@ static int aanscales[DSIZE2] = { 289301, 401273, 377991, 340183, 289301, 227303, 156569, 79818 }; -static void iqtab_init(int *iqtab, unsigned char *iq_y) { +static void iqtab_init(int *iqtab, const unsigned char *iq_y) { int i; for (i = 0; i < DSIZE2; i++) { @@ -270,7 +268,7 @@ static void iqtab_init(int *iqtab, unsigned char *iq_y) { #define MDEC_END_OF_DATA 0xfe00 -static unsigned short *rl2blk(int *blk, unsigned short *mdec_rl) { +static const unsigned short *rl2blk(int *blk, const unsigned short *mdec_rl) { int i, k, q_scale, rl, used_col; int *iqtab; @@ -474,10 +472,12 @@ u32 mdecRead1(void) { } void psxDma0(u32 adr, u32 bcr, u32 chcr) { - int cmd = mdec.reg0; + u32 cmd = mdec.reg0, words_max = 0; + const void *mem; int size; if (chcr != 0x01000201) { + log_unhandled("mdec0: invalid dma %08x\n", chcr); return; } @@ -486,19 +486,25 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) { size = (bcr >> 16) * (bcr & 0xffff); + adr &= ~3; + mem = getDmaRam(adr, &words_max); + if (mem == INVALID_PTR || size > words_max) { + log_unhandled("bad dma0 madr %x\n", adr); + HW_DMA0_CHCR &= SWAP32(~0x01000000); + return; + } + switch (cmd >> 28) { - case 0x3: // decode - mdec.rl = (u16 *) PSXM(adr); + case 0x3: // decode 15/24bpp + mdec.rl = mem; /* now the mdec is busy till all data are decoded */ mdec.reg1 |= MDEC1_BUSY; /* detect the end of decoding */ mdec.rl_end = mdec.rl + (size * 2); /* sanity check */ - if(mdec.rl_end <= mdec.rl) { - MDECINDMA_INT( size / 4 ); - return; - } + if(mdec.rl_end <= mdec.rl) + break; /* process the pending dma1 */ if(mdec.pending_dma1.adr){ @@ -510,30 +516,25 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) { case 0x4: // quantization table upload { - u8 *p = (u8 *)PSXM(adr); + const u8 *p = mem; // printf("uploading new quantization table\n"); // printmatrixu8(p); // printmatrixu8(p + 64); iqtab_init(iq_y, p); iqtab_init(iq_uv, p + 64); } - - MDECINDMA_INT( size / 4 ); - return; + break; case 0x6: // cosine table // printf("mdec cosine table\n"); - - MDECINDMA_INT( size / 4 ); - return; + break; default: - // printf("mdec unknown command\n"); + log_unhandled("mdec: unknown command %08x\n", cmd); break; } - HW_DMA0_CHCR &= SWAP32(~0x01000000); - DMA_INTERRUPT(0); + set_event(PSXINT_MDECINDMA, size); } void mdec0Interrupt() @@ -549,12 +550,15 @@ void mdec0Interrupt() #define SIZE_OF_16B_BLOCK (16*16*2) void psxDma1(u32 adr, u32 bcr, u32 chcr) { + u32 words, words_max = 0; int blk[DSIZE2 * 6]; u8 * image; int size; - u32 words; - if (chcr != 0x01000200) return; + if (chcr != 0x01000200) { + log_unhandled("mdec1: invalid dma %08x\n", chcr); + return; + } words = (bcr >> 16) * (bcr & 0xffff); /* size in byte */ @@ -566,9 +570,16 @@ void psxDma1(u32 adr, u32 bcr, u32 chcr) { mdec.pending_dma1.bcr = bcr; mdec.pending_dma1.chcr = chcr; /* do not free the dma */ - } else { + return; + } - image = (u8 *)PSXM(adr); + adr &= ~3; + image = getDmaRam(adr, &words_max); + if (image == INVALID_PTR || words > words_max) { + log_unhandled("bad dma1 madr %x\n", adr); + HW_DMA1_CHCR &= SWAP32(~0x01000000); + return; + } if (mdec.reg0 & MDEC0_RGB24) { /* 16 bits decoding @@ -628,10 +639,13 @@ void psxDma1(u32 adr, u32 bcr, u32 chcr) { mdec.block_buffer_pos = mdec.block_buffer + size; } } + if (size < 0) + log_unhandled("mdec: bork\n"); /* define the power of mdec */ - MDECOUTDMA_INT(words * MDEC_BIAS); - } + set_event(PSXINT_MDECOUTDMA, words * MDEC_BIAS); + /* some CPU stalling */ + psxRegs.cycle += words; } void mdec1Interrupt() { @@ -660,6 +674,7 @@ void mdec1Interrupt() { */ /* MDEC_END_OF_DATA avoids read outside memory */ + //printf("mdec left %zd, v=%04x\n", mdec.rl_end - mdec.rl, *(mdec.rl)); if (mdec.rl >= mdec.rl_end || SWAP16(*(mdec.rl)) == MDEC_END_OF_DATA) { mdec.reg1 &= ~(MDEC1_STP|MDEC1_BUSY); if (HW_DMA0_CHCR & SWAP32(0x01000000)) @@ -677,27 +692,26 @@ void mdec1Interrupt() { } int mdecFreeze(void *f, int Mode) { - u8 *base = (u8 *)&psxM[0x100000]; + u8 *base = (u8 *)psxM; u32 v; gzfreeze(&mdec.reg0, sizeof(mdec.reg0)); gzfreeze(&mdec.reg1, sizeof(mdec.reg1)); - // old code used to save raw pointers.. v = (u8 *)mdec.rl - base; gzfreeze(&v, sizeof(v)); - mdec.rl = (u16 *)(base + (v & 0xffffe)); + mdec.rl = (u16 *)(base + (v & 0x1ffffe)); v = (u8 *)mdec.rl_end - base; gzfreeze(&v, sizeof(v)); - mdec.rl_end = (u16 *)(base + (v & 0xffffe)); + mdec.rl_end = (u16 *)(base + (v & 0x1ffffe)); v = 0; if (mdec.block_buffer_pos) - v = mdec.block_buffer_pos - base; + v = mdec.block_buffer_pos - mdec.block_buffer; gzfreeze(&v, sizeof(v)); mdec.block_buffer_pos = 0; - if (v) - mdec.block_buffer_pos = base + (v & 0xfffff); + if (v && v < sizeof(mdec.block_buffer)) + mdec.block_buffer_pos = mdec.block_buffer; gzfreeze(&mdec.block_buffer, sizeof(mdec.block_buffer)); gzfreeze(&mdec.pending_dma1, sizeof(mdec.pending_dma1));