diff --git a/src/emu/machine/vrc4373.c b/src/emu/machine/vrc4373.c index 234880b0b8e..860b7ff601a 100644 --- a/src/emu/machine/vrc4373.c +++ b/src/emu/machine/vrc4373.c @@ -269,22 +269,39 @@ void vrc4373_device::dma_transfer(int which) if (LOG_NILE) logerror("%08X:nile Start dma PCI: %08X MEM: %08X Words: %X\n", m_cpu->space(AS_PROGRAM).device().safe_pc(), m_cpu_regs[NREG_DMA_CPAR], m_cpu_regs[NREG_DMA_CMAR], m_cpu_regs[NREG_DMA_REM]); int pciSel = (m_cpu_regs[NREG_DMACR1+which*0xC] & DMA_MIO) ? AS_DATA : AS_IO; - UINT32 mem_mask = 0xffffffff; - while (m_cpu_regs[NREG_DMA_REM]>0) { - if (0 && LOG_NILE) - logerror("dma_transfer PCI: %08X Mem: %08X Words Remaining: %X\n", m_cpu_regs[NREG_DMA_CPAR], m_cpu_regs[NREG_DMA_CMAR], m_cpu_regs[NREG_DMA_REM]); - if (m_cpu_regs[NREG_DMACR1+which*0xC]&DMA_RW) { - // Read data from PCI and write to local - m_cpu->space(AS_PROGRAM).write_dword(m_cpu_regs[NREG_DMA_CMAR], this->space(pciSel).read_dword(m_cpu_regs[NREG_DMA_CPAR], mem_mask), mem_mask); - } else { - // Read data from local and write to PCI - this->space(pciSel).write_dword(m_cpu_regs[NREG_DMA_CPAR], m_cpu->space(AS_PROGRAM).read_dword(m_cpu_regs[NREG_DMA_CMAR], mem_mask), mem_mask); - } - m_cpu_regs[NREG_DMA_CMAR] += 0x4; - m_cpu_regs[NREG_DMA_CPAR] += 0x4; - m_cpu_regs[NREG_DMA_REM]--; + address_space *src, *dst; + UINT32 srcAddr, dstAddr; + + if (m_cpu_regs[NREG_DMACR1+which*0xC]&DMA_RW) { + // Read data from PCI and write to cpu + src = &this->space(pciSel); + dst = &m_cpu->space(AS_PROGRAM); + srcAddr = m_cpu_regs[NREG_DMA_CPAR]; + dstAddr = m_cpu_regs[NREG_DMA_CMAR]; + } else { + // Read data from cpu and write to PCI + src = &m_cpu->space(AS_PROGRAM); + dst = &this->space(pciSel); + srcAddr = m_cpu_regs[NREG_DMA_CMAR]; + dstAddr = m_cpu_regs[NREG_DMA_CPAR]; } + int count = m_cpu_regs[NREG_DMA_REM]; + while (count>0) { + dst->write_dword(dstAddr, src->read_dword(srcAddr)); + dstAddr += 0x4; + srcAddr += 0x4; + --count; + } + if (m_cpu_regs[NREG_DMACR1+which*0xC]&DMA_RW) { + m_cpu_regs[NREG_DMA_CPAR] = srcAddr; + m_cpu_regs[NREG_DMA_CMAR] = dstAddr; + } else { + m_cpu_regs[NREG_DMA_CMAR] = srcAddr; + m_cpu_regs[NREG_DMA_CPAR] = dstAddr; + } + m_cpu_regs[NREG_DMA_REM] = 0; } + // CPU I/F READ32_MEMBER (vrc4373_device::cpu_if_r) { diff --git a/src/emu/video/vooddefs.h b/src/emu/video/vooddefs.h index 437b3c84459..8dcd119a975 100644 --- a/src/emu/video/vooddefs.h +++ b/src/emu/video/vooddefs.h @@ -4635,12 +4635,7 @@ ATTR_FORCE_INLINE UINT32 genTexture(tmu_state *TT, const UINT8 ditherX, const UI /* determine the S/T/LOD values for this texture */ lod = (LODBASE); - /* clamp W */ - if (TEXMODE_CLAMP_NEG_W(TEXMODE) && (ITERW) < 0) - { - s = t = 0; - } - else if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE)) + if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE)) { INT32 wLog; oow = fast_reciplog((ITERW), &wLog); @@ -4654,6 +4649,11 @@ ATTR_FORCE_INLINE UINT32 genTexture(tmu_state *TT, const UINT8 ditherX, const UI t = (ITERT) >> 14; } + /* clamp W */ + if (TEXMODE_CLAMP_NEG_W(TEXMODE) && (ITERW) < 0) + { + s = t = 0; + } /* clamp the LOD */ lod += (TT)->lodbias; diff --git a/src/emu/video/voodoo.c b/src/emu/video/voodoo.c index 73c421b90d0..ff98657a672 100644 --- a/src/emu/video/voodoo.c +++ b/src/emu/video/voodoo.c @@ -211,7 +211,8 @@ static TIMER_CALLBACK( stall_cpu_callback ); static void stall_cpu(voodoo_state *v, int state, attotime current_time); static TIMER_CALLBACK( vblank_callback ); static INT32 register_w(voodoo_state *v, offs_t offset, UINT32 data); -static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, bool lfb_3d); +static INT32 lfb_direct_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask); +static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask); static INT32 texture_w(voodoo_state *v, offs_t offset, UINT32 data); static INT32 banshee_2d_w(voodoo_state *v, offs_t offset, UINT32 data); @@ -1943,7 +1944,7 @@ static UINT32 cmdfifo_execute(voodoo_state *v, cmdfifo_info *f) /* loop over words */ for (i = 0; i < count; i++) - cycles += lfb_w(v, target++, *src++, 0xffffffff, true); + cycles += lfb_w(v, target++, *src++, 0xffffffff); break; } @@ -2931,8 +2932,52 @@ default_case: * Voodoo LFB writes * *************************************/ +static INT32 lfb_direct_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask) +{ + UINT16 *dest; + UINT32 destmax; + int x, y; + UINT32 bufoffs; -static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, bool lfb_3d) + /* statistics */ + v->stats.lfb_writes++; + + /* byte swizzling */ + if (LFBMODE_BYTE_SWIZZLE_WRITES(v->reg[lfbMode].u)) + { + data = FLIPENDIAN_INT32(data); + mem_mask = FLIPENDIAN_INT32(mem_mask); + } + + /* word swapping */ + if (LFBMODE_WORD_SWAP_WRITES(v->reg[lfbMode].u)) + { + data = (data << 16) | (data >> 16); + mem_mask = (mem_mask << 16) | (mem_mask >> 16); + } + + // TODO: This direct write is not verified. + // For direct lfb access just write the data + /* compute X,Y */ + offset <<= 1; + x = offset & ((1 << v->fbi.lfb_stride) - 1); + y = (offset >> v->fbi.lfb_stride); + dest = (UINT16 *)(v->fbi.ram + v->fbi.lfb_base*4); + destmax = (v->fbi.mask + 1 - v->fbi.lfb_base*4) / 2; + bufoffs = y * v->fbi.rowpixels + x; + if (bufoffs >= destmax) { + logerror("lfb_direct_w: Buffer offset out of bounds x=%i y=%i offset=%08X bufoffs=%08X data=%08X\n", x, y, offset, (UINT32) bufoffs, data); + return 0; + } + if (ACCESSING_BITS_0_15) + dest[bufoffs + 0] = data&0xffff; + if (ACCESSING_BITS_16_31) + dest[bufoffs + 1] = data>>16; + if (LOG_LFB) logerror("VOODOO.%d.LFB:write direct (%d,%d) = %08X & %08X\n", v->index, x, y, data, mem_mask); + return 0; +} + +static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask) { UINT16 *dest, *depth; UINT32 destmax, depthmax; @@ -2943,29 +2988,6 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, /* statistics */ v->stats.lfb_writes++; - // TODO: This direct write is not verified. - // For direct lfb access just write the data - if (!lfb_3d) { - UINT32 bufoffs; - /* compute X,Y */ - offset <<= 1; - x = offset & ((1 << v->fbi.lfb_stride) - 1); - y = (offset >> v->fbi.lfb_stride); - dest = (UINT16 *)(v->fbi.ram + v->fbi.lfb_base*4); - destmax = (v->fbi.mask + 1 - v->fbi.lfb_base*4) / 2; - bufoffs = y * v->fbi.rowpixels + x; - if (bufoffs >= destmax) { - logerror("LFB_W: Buffer offset out of bounds x=%i y=%i lfb_3d=%i offset=%08X bufoffs=%08X data=%08X\n", x, y, lfb_3d, offset, (UINT32) bufoffs, data); - return 0; - } - if (ACCESSING_BITS_0_15) - dest[bufoffs + 0] = data&0xffff; - if (ACCESSING_BITS_16_31) - dest[bufoffs + 1] = data>>16; - if (LOG_LFB) logerror("VOODOO.%d.LFB:write direct (%d,%d) = %08X & %08X\n", v->index, x, y, data, mem_mask); - return 0; - } - /* byte swizzling */ if (LFBMODE_BYTE_SWIZZLE_WRITES(v->reg[lfbMode].u)) { @@ -3187,9 +3209,6 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, depth = (UINT16 *)(v->fbi.ram + v->fbi.auxoffs); depthmax = (v->fbi.mask + 1 - v->fbi.auxoffs) / 2; - /* wait for any outstanding work to finish */ - poly_wait(v->poly, "LFB Write"); - /* simple case: no pipeline */ if (!LFBMODE_ENABLE_PIXEL_PIPELINE(v->reg[lfbMode].u)) { @@ -3209,6 +3228,9 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, /* compute dithering */ COMPUTE_DITHER_POINTERS_NO_DITHER_VAR(v->reg[fbzMode].u, y); + /* wait for any outstanding work to finish */ + poly_wait(v->poly, "LFB Write"); + /* loop over up to two pixels */ for (pix = 0; mask; pix++) { @@ -3349,7 +3371,7 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, if (USE_OLD_RASTER) { /* Perform depth testing */ DEPTH_TEST(v, stats, x, v->reg[fbzMode].u); - + /* apply chroma key, alpha mask, and alpha testing */ APPLY_CHROMAKEY(v, stats, v->reg[fbzMode].u, color); APPLY_ALPHAMASK(v, stats, v->reg[fbzMode].u, color.rgb.a); @@ -3358,7 +3380,7 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, /* Perform depth testing */ if (!depthTest((UINT16) v->reg[zaColor].u, stats, depth[x], v->reg[fbzMode].u, biasdepth)) goto nextpixel; - + /* handle chroma key */ if (!chromaKeyTest(v, stats, v->reg[fbzMode].u, color)) goto nextpixel; @@ -3370,6 +3392,9 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, goto nextpixel; } + /* wait for any outstanding work to finish */ + poly_wait(v->poly, "LFB Write"); + /* pixel pipeline part 2 handles color combine, fog, alpha, and final output */ PIXEL_PIPELINE_END(v, stats, dither, dither4, dither_lookup, x, dest, depth, v->reg[fbzMode].u, v->reg[fbzColorPath].u, v->reg[alphaMode].u, v->reg[fogMode].u, @@ -3606,7 +3631,7 @@ static void flush_fifos(voodoo_state *v, attotime current_time) mem_mask &= 0xffff0000; address &= 0xffffff; - cycles = lfb_w(v, address, data, mem_mask, true); + cycles = lfb_w(v, address, data, mem_mask); } } @@ -3732,7 +3757,7 @@ WRITE32_MEMBER( voodoo_device::voodoo_w ) else if (offset & (0x800000/4)) cycles = texture_w(v, offset, data); else - cycles = lfb_w(v, offset, data, mem_mask, true); + cycles = lfb_w(v, offset, data, mem_mask); /* if we ended up with cycles, mark the operation pending */ if (cycles) @@ -4769,7 +4794,7 @@ WRITE32_MEMBER( voodoo_banshee_device::banshee_w ) logerror("%s:banshee_w(YUV:%X) = %08X & %08X\n", machine().describe_context(), (offset*4) & 0x3fffff, data, mem_mask); else if (offset < 0x2000000/4) { - lfb_w(v, offset & 0xffffff/4, data, mem_mask, true); + lfb_w(v, offset & 0xffffff/4, data, mem_mask); } else { logerror("%s:banshee_w Address out of range %08X = %08X & %08X\n", machine().describe_context(), (offset*4), data, mem_mask); } @@ -4803,7 +4828,7 @@ WRITE32_MEMBER( voodoo_banshee_device::banshee_fb_w ) } } else - lfb_w(v, offset - v->fbi.lfb_base, data, mem_mask, false); + lfb_direct_w(v, offset - v->fbi.lfb_base, data, mem_mask); }