DMAC: Remove some old defines, optimize case statements

This commit is contained in:
Christian Kenny 2022-05-21 14:35:19 -04:00 committed by refractionpcsx2
parent e7d1477a7e
commit d13c7b6b3e
4 changed files with 85 additions and 169 deletions

View File

@ -1061,24 +1061,24 @@ __fi u16 rcntRead32( u32 mem )
// are all fixed to 0, so we always truncate everything in these two pages using a u16
// return value! --air
iswitch( mem ) {
icase(RCNT0_COUNT) return (u16)rcntRcount(0);
icase(RCNT0_MODE) return (u16)counters[0].modeval;
icase(RCNT0_TARGET) return (u16)counters[0].target;
icase(RCNT0_HOLD) return (u16)counters[0].hold;
switch( mem ) {
case(RCNT0_COUNT): return (u16)rcntRcount(0);
case(RCNT0_MODE): return (u16)counters[0].modeval;
case(RCNT0_TARGET): return (u16)counters[0].target;
case(RCNT0_HOLD): return (u16)counters[0].hold;
icase(RCNT1_COUNT) return (u16)rcntRcount(1);
icase(RCNT1_MODE) return (u16)counters[1].modeval;
icase(RCNT1_TARGET) return (u16)counters[1].target;
icase(RCNT1_HOLD) return (u16)counters[1].hold;
case(RCNT1_COUNT): return (u16)rcntRcount(1);
case(RCNT1_MODE): return (u16)counters[1].modeval;
case(RCNT1_TARGET): return (u16)counters[1].target;
case(RCNT1_HOLD): return (u16)counters[1].hold;
icase(RCNT2_COUNT) return (u16)rcntRcount(2);
icase(RCNT2_MODE) return (u16)counters[2].modeval;
icase(RCNT2_TARGET) return (u16)counters[2].target;
case(RCNT2_COUNT): return (u16)rcntRcount(2);
case(RCNT2_MODE): return (u16)counters[2].modeval;
case(RCNT2_TARGET): return (u16)counters[2].target;
icase(RCNT3_COUNT) return (u16)rcntRcount(3);
icase(RCNT3_MODE) return (u16)counters[3].modeval;
icase(RCNT3_TARGET) return (u16)counters[3].target;
case(RCNT3_COUNT): return (u16)rcntRcount(3);
case(RCNT3_MODE): return (u16)counters[3].modeval;
case(RCNT3_TARGET): return (u16)counters[3].target;
}
return psHu16(mem);
@ -1093,24 +1093,24 @@ __fi bool rcntWrite32( u32 mem, mem32_t& value )
// count, mode, target, and hold. This will allow for a simplified handler for register
// reads.
iswitch( mem ) {
icase(RCNT0_COUNT) return rcntWcount(0, value), false;
icase(RCNT0_MODE) return rcntWmode(0, value), false;
icase(RCNT0_TARGET) return rcntWtarget(0, value), false;
icase(RCNT0_HOLD) return rcntWhold(0, value), false;
switch( mem ) {
case(RCNT0_COUNT): return rcntWcount(0, value), false;
case(RCNT0_MODE): return rcntWmode(0, value), false;
case(RCNT0_TARGET): return rcntWtarget(0, value), false;
case(RCNT0_HOLD): return rcntWhold(0, value), false;
icase(RCNT1_COUNT) return rcntWcount(1, value), false;
icase(RCNT1_MODE) return rcntWmode(1, value), false;
icase(RCNT1_TARGET) return rcntWtarget(1, value), false;
icase(RCNT1_HOLD) return rcntWhold(1, value), false;
case(RCNT1_COUNT): return rcntWcount(1, value), false;
case(RCNT1_MODE): return rcntWmode(1, value), false;
case(RCNT1_TARGET): return rcntWtarget(1, value), false;
case(RCNT1_HOLD): return rcntWhold(1, value), false;
icase(RCNT2_COUNT) return rcntWcount(2, value), false;
icase(RCNT2_MODE) return rcntWmode(2, value), false;
icase(RCNT2_TARGET) return rcntWtarget(2, value), false;
case(RCNT2_COUNT): return rcntWcount(2, value), false;
case(RCNT2_MODE): return rcntWmode(2, value), false;
case(RCNT2_TARGET): return rcntWtarget(2, value), false;
icase(RCNT3_COUNT) return rcntWcount(3, value), false;
icase(RCNT3_MODE) return rcntWmode(3, value), false;
icase(RCNT3_TARGET) return rcntWtarget(3, value), false;
case(RCNT3_COUNT): return rcntWcount(3, value), false;
case(RCNT3_MODE): return rcntWmode(3, value), false;
case(RCNT3_TARGET): return rcntWtarget(3, value), false;
}
// unhandled .. do memory writeback.

View File

@ -299,7 +299,7 @@ template< uint page >
__fi u32 dmacRead32( u32 mem )
{
// Fixme: OPH hack. Toggle the flag on GIF_STAT access. (rama)
if (IsPageFor(mem) && (mem == GIF_STAT) && CHECK_OPHFLAGHACK)
if ((CHECK_OPHFLAGHACK) && (page << 12) == (mem & (0xf << 12)) && (mem == GIF_STAT))
{
static unsigned counter = 1;
if (++counter == 8)
@ -374,166 +374,110 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value )
allow_write:;
}
iswitch(mem) {
icase(D0_CHCR) // dma0 - vif0
switch(mem) {
case (D0_QWC): // dma0 - vif0
case (D1_QWC): // dma1 - vif1
case (D2_QWC): // dma2 - gif
case (D3_QWC): // dma3 - fromIPU
case (D4_QWC): // dma4 - toIPU
case (D5_QWC): // dma5 - sif0
case (D6_QWC): // dma6 - sif1
case (D7_QWC): // dma7 - sif2
case (D8_QWC): // dma8 - fromSPR
case (D9_QWC): // dma9 - toSPR
{
psHu32(mem) = (u16)value;
return false;
}
case (D0_CHCR): // dma0 - vif0
{
DMA_LOG("VIF0dma EXECUTE, value=0x%x", value);
DmaExec(dmaVIF0, mem, value);
return false;
}
icase(D0_QWC) // dma0 - vif0
{
psHu32(mem) = (u16)value;
return false;
}
icase(D1_CHCR) // dma1 - vif1 - chcr
case (D1_CHCR): // dma1 - vif1 - chcr
{
DMA_LOG("VIF1dma EXECUTE, value=0x%x", value);
DmaExec(dmaVIF1, mem, value);
return false;
}
icase(D1_QWC) // dma1 - vif1
{
psHu32(mem) = (u16)value;
return false;
}
icase(D2_CHCR) // dma2 - gif
case (D2_CHCR): // dma2 - gif
{
DMA_LOG("GIFdma EXECUTE, value=0x%x", value);
DmaExec(dmaGIF, mem, value);
return false;
}
icase(D2_QWC) // dma2 - gif
{
psHu32(mem) = (u16)value;
return false;
}
icase(D3_CHCR) // dma3 - fromIPU
case (D3_CHCR): // dma3 - fromIPU
{
DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value);
DmaExec(dmaIPU0, mem, value);
return false;
}
icase(D3_QWC) // dma3 - fromIPU
{
psHu32(mem) = (u16)value;
return false;
}
icase(D4_CHCR) // dma4 - toIPU
case (D4_CHCR): // dma4 - toIPU
{
DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value);
DmaExec(dmaIPU1, mem, value);
return false;
}
icase(D4_QWC) // dma4 - toIPU
{
psHu32(mem) = (u16)value;
return false;
}
icase(D5_CHCR) // dma5 - sif0
case (D5_CHCR): // dma5 - sif0
{
DMA_LOG("SIF0dma EXECUTE, value=0x%x", value);
DmaExec(dmaSIF0, mem, value);
return false;
}
icase(D5_QWC) // dma5 - sif0
{
psHu32(mem) = (u16)value;
return false;
}
icase(D6_CHCR) // dma6 - sif1
case (D6_CHCR): // dma6 - sif1
{
DMA_LOG("SIF1dma EXECUTE, value=0x%x", value);
DmaExec(dmaSIF1, mem, value);
return false;
}
icase(D6_QWC) // dma6 - sif1
{
psHu32(mem) = (u16)value;
return false;
}
icase(D7_CHCR) // dma7 - sif2
case (D7_CHCR): // dma7 - sif2
{
DMA_LOG("SIF2dma EXECUTE, value=0x%x", value);
DmaExec(dmaSIF2, mem, value);
return false;
}
icase(D7_QWC) // dma7 - sif2
{
psHu32(mem) = (u16)value;
return false;
}
icase(D8_CHCR) // dma8 - fromSPR
case (D8_CHCR): // dma8 - fromSPR
{
DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value);
DmaExec(dmaSPR0, mem, value);
return false;
}
icase(D8_QWC) // dma8 - fromSPR
{
psHu32(mem) = (u16)value;
return false;
}
icase(fromSPR_MADR)
{
// SPR bit is fixed at 0 for this channel
psHu32(mem) = value & 0x7FFFFFFF;
return false;
}
icase(toSPR_MADR)
{
// SPR bit is fixed at 0 for this channel
psHu32(mem) = value & 0x7FFFFFFF;
return false;
}
icase(fromSPR_SADR)
{
// Address must be QW aligned and fit in the 16K range of SPR
psHu32(mem) = value & 0x3FF0;
return false;
}
icase(toSPR_SADR)
{
// Address must be QW aligned and fit in the 16K range of SPR
psHu32(mem) = value & 0x3FF0;
return false;
}
icase(D9_CHCR) // dma9 - toSPR
case (D9_CHCR): // dma9 - toSPR
{
DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x", value);
DmaExec(dmaSPR1, mem, value);
return false;
}
icase(D9_QWC) // dma9 - toSPR
case (fromSPR_MADR):
case (toSPR_MADR):
{
psHu32(mem) = (u16)value;
// SPR bit is fixed at 0 for this channel
psHu32(mem) = value & 0x7FFFFFFF;
return false;
}
icase(DMAC_CTRL)
case (fromSPR_SADR):
case (toSPR_SADR):
{
// Address must be QW aligned and fit in the 16K range of SPR
psHu32(mem) = value & 0x3FF0;
return false;
}
case (DMAC_CTRL):
{
u32 oldvalue = psHu32(mem);
@ -594,10 +538,14 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value )
//Midway are a bunch of idiots, writing to E100 (reserved) instead of E010
//Which causes a CPCOND0 to fail.
icase(DMAC_FAKESTAT)
case (DMAC_FAKESTAT):
case (DMAC_STAT):
{
if (DMAC_FAKESTAT)
{
//DevCon.Warning("Midway fixup addr=%x writing %x for DMA_STAT", mem, value);
HW_LOG("Midways own DMAC_STAT Write 32bit %x", value);
}
else HW_LOG("DMAC_STAT Write 32bit %x", value);
// lower 16 bits: clear on 1
// upper 16 bits: reverse on 1
@ -609,21 +557,7 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value )
return false;
}
icase(DMAC_STAT)
{
HW_LOG("DMAC_STAT Write 32bit %x", value);
// lower 16 bits: clear on 1
// upper 16 bits: reverse on 1
psHu16(0xe010) &= ~(value & 0xffff);
psHu16(0xe012) ^= (u16)(value >> 16);
cpuTestDMACInts();
return false;
}
icase(DMAC_ENABLEW)
case (DMAC_ENABLEW):
{
HW_LOG("DMAC_ENABLEW Write 32bit %lx", value);
oldvalue = psHu8(DMAC_ENABLEW + 2);
@ -635,6 +569,8 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value )
}
return false;
}
default:
return true;
}
// fall-through: use the default writeback provided by caller.

View File

@ -96,9 +96,9 @@ void _hwWrite32( u32 mem, u32 value )
if (!vifWrite32<0>(mem, value)) return;
}
}
else iswitch(mem)
else switch(mem)
{
icase(GIF_CTRL)
case (GIF_CTRL):
{
// Not exactly sure what RST needs to do
gifRegs.ctrl.write(value & 9);
@ -111,7 +111,7 @@ void _hwWrite32( u32 mem, u32 value )
return;
}
icase(GIF_MODE)
case (GIF_MODE):
{
gifRegs.mode.write(value);
//Need to kickstart the GIF if the M3R mask comes off
@ -291,8 +291,7 @@ void _hwWrite8(u32 mem, u8 value)
#if PSX_EXTRALOGS
if ((mem & 0x1000ff00) == 0x1000f300) DevCon.Warning("8bit Write to SIF Register %x value %x wibble", mem, value);
#endif
iswitch (mem)
icase(SIO_TXFIFO)
if (mem == SIO_TXFIFO)
{
static bool iggy_newline = false;
static char sio_buffer[1024];

View File

@ -17,25 +17,6 @@
#include "Hw.h"
// --------------------------------------------------------------------------------------
// IsPageFor() / iswitch() / icase() [macros!]
// --------------------------------------------------------------------------------------
// Page-granulated switch helpers: In order for the compiler to optimize hardware register
// handlers, which dispatch registers along a series of switches, the compiler needs to know
// that the case entry applies to the current page only. Under MSVC, I tried all manners of
// bitmasks against the templated page value, and this was the only one that worked:
//
// Note: MSVC 2008 actually fails to optimize "switch" properly due to being overly aggressive
// about trying to use its clever BSP-tree logic for long switches. It adds the BSP tree logic,
// even though most of the "tree" is empty (resulting in several compare/jumps that do nothing).
// Explained: Even though only one or two of the switch entires are valid, MSVC will still
// compile in its BSP tree check (which divides the switch into 2 or 4 ranges of values). Three
// of the ranges just link to "RET", while the fourth range contains the handler for the one
// register operation contained in the templated page.
#define IsPageFor(_mem) ((page<<12) == (_mem&(0xf<<12)))
#define icase(ugh) if(IsPageFor(ugh) && (mem==ugh))
#define iswitch(mem)
// hw read functions
template< uint page > extern mem8_t hwRead8 (u32 mem);