void psxDma3(u32 madr, u32 bcr, u32 chcr) { u32 cdsize; CDVD_LOG("*** DMA 3 *** %lx addr = %lx size = %lx", chcr, madr, bcr); switch (chcr) { case 0x11000000: case 0x11400100: if (cdr.Readed == 0) { DevCon.Warning("*** DMA 3 *** NOT READY"); HW_DMA3_CHCR &= ~0x01000000; //hack psxDmaInterrupt(3); //hack return; } cdsize = (bcr & 0xffff) * 4; memcpy(iopPhysMem(madr), cdr.pTransfer, cdsize); psxCpu->Clear(madr, cdsize/4); cdr.pTransfer+=cdsize; break; case 0x41000200: //SysPrintf("unhandled cdrom dma3: madr: %x, bcr: %x, chcr %x\n", madr, bcr, chcr); return; default: CDVD_LOG("Unknown cddma %lx", chcr); break; } HW_DMA3_CHCR &= ~0x01000000; psxDmaInterrupt(3); }
void psxDma0(u32 adr, u32 bcr, u32 chcr) { int cmd = mdec.command; MDEC_LOG("DMA0 %lx %lx %lx", adr, bcr, chcr); if (chcr != 0x01000201) return; // bcr LSBs are the blocksize in words // bcr MSBs are the number of block int size = (bcr >> 16)*(bcr & 0xffff); if (size < 0) { // Need to investigate what happen if the transfer is huge Console.Error("psxDma0 DMA transfer overflow !"); return; } for (int i = 0; i<(size); i++) { *(u32*)PSXM(((i + 0) * 4)) = iopMemRead32(adr + ((i + 0) * 4)); if (i <20) MDEC_LOG(" data %08X %08X ", iopMemRead32((adr & 0x00FFFFFF) + (i * 4)), *(u32*)PSXM((i * 4))); } if (cmd == 0x40000001) { u8 *p = (u8*)PSXM(0); //u8 *p = (u8*)PSXM(adr); iqtab_init(iq_y, p); iqtab_init(iq_uv, p + 64); } else if ((cmd & 0xf5ff0000) == 0x30000000) { mdec.rl = (u16*)PSXM(0); //mdec.rl = (u16*)PSXM(adr); } HW_DMA0_CHCR &= ~0x01000000; psxDmaInterrupt(0); }
void pgpuDmaIntr(int trigDma) { //For the IOP GPU DMA channel. //trigDma: 1=normal,ToGPU; 2=normal,FromGPU, 3=LinkedList // psxmode: 25.09.2016 at this point, the emulator works even when removing this interrupt call. how? why? #if PREVENT_IRQ_ON_NORM_DMA_TO_GPU == 1 if (trigDma != 1) //Interrupt on ToGPU DMA breaks some games. TODO: Why? #endif psxDmaInterrupt(2); }
void psxDma1(u32 adr, u32 bcr, u32 chcr) { int blk[DCTSIZE2*6]; unsigned short *image; MDEC_LOG("DMA1 %lx %lx %lx (cmd = %lx)", adr, bcr, chcr, mdec.command); if (chcr != 0x01000200) return; // bcr LSBs are the blocksize in words // bcr MSBs are the number of block int size = (bcr >> 16)*(bcr & 0xffff); int size2 = (bcr >> 16)*(bcr & 0xffff); if (size < 0) { // Need to investigate what happen if the transfer is huge Console.Error("psxDma1 DMA transfer overflow !"); return; } image = (u16*)mdecArr2;//(u16*)PSXM(0); //image = (u16*)PSXM(adr); if (mdec.command&0x08000000) { for (;size>0;size-=(16*16)/2,image+=(16*16)) { mdec.rl = rl2blk(blk,mdec.rl); yuv2rgb15(blk,image); } } else { for (;size>0;size-=(24*16)/2,image+=(24*16)) { mdec.rl = rl2blk(blk,mdec.rl); yuv2rgb24(blk,(u8 *)image); } } for (int i = 0; i<(size2); i++) { iopMemWrite32(((adr & 0x00FFFFFF) + (i * 4) + 0), mdecArr2[i]); if (i <20) MDEC_LOG(" data %08X %08X ", iopMemRead32((adr & 0x00FFFFFF) + (i * 4)), mdecArr2[i]); } HW_DMA1_CHCR &= ~0x01000000; psxDmaInterrupt(1); }