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

View File

@ -299,7 +299,7 @@ template< uint page >
__fi u32 dmacRead32( u32 mem ) __fi u32 dmacRead32( u32 mem )
{ {
// Fixme: OPH hack. Toggle the flag on GIF_STAT access. (rama) // 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; static unsigned counter = 1;
if (++counter == 8) if (++counter == 8)
@ -374,166 +374,110 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value )
allow_write:; allow_write:;
} }
iswitch(mem) { switch(mem) {
icase(D0_CHCR) // dma0 - vif0
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); DMA_LOG("VIF0dma EXECUTE, value=0x%x", value);
DmaExec(dmaVIF0, mem, value); DmaExec(dmaVIF0, mem, value);
return false; return false;
} }
icase(D0_QWC) // dma0 - vif0 case (D1_CHCR): // dma1 - vif1 - chcr
{
psHu32(mem) = (u16)value;
return false;
}
icase(D1_CHCR) // dma1 - vif1 - chcr
{ {
DMA_LOG("VIF1dma EXECUTE, value=0x%x", value); DMA_LOG("VIF1dma EXECUTE, value=0x%x", value);
DmaExec(dmaVIF1, mem, value); DmaExec(dmaVIF1, mem, value);
return false; return false;
} }
icase(D1_QWC) // dma1 - vif1 case (D2_CHCR): // dma2 - gif
{
psHu32(mem) = (u16)value;
return false;
}
icase(D2_CHCR) // dma2 - gif
{ {
DMA_LOG("GIFdma EXECUTE, value=0x%x", value); DMA_LOG("GIFdma EXECUTE, value=0x%x", value);
DmaExec(dmaGIF, mem, value); DmaExec(dmaGIF, mem, value);
return false; return false;
} }
icase(D2_QWC) // dma2 - gif case (D3_CHCR): // dma3 - fromIPU
{
psHu32(mem) = (u16)value;
return false;
}
icase(D3_CHCR) // dma3 - fromIPU
{ {
DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value); DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value);
DmaExec(dmaIPU0, mem, value); DmaExec(dmaIPU0, mem, value);
return false; return false;
} }
icase(D3_QWC) // dma3 - fromIPU case (D4_CHCR): // dma4 - toIPU
{
psHu32(mem) = (u16)value;
return false;
}
icase(D4_CHCR) // dma4 - toIPU
{ {
DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value); DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value);
DmaExec(dmaIPU1, mem, value); DmaExec(dmaIPU1, mem, value);
return false; return false;
} }
icase(D4_QWC) // dma4 - toIPU case (D5_CHCR): // dma5 - sif0
{
psHu32(mem) = (u16)value;
return false;
}
icase(D5_CHCR) // dma5 - sif0
{ {
DMA_LOG("SIF0dma EXECUTE, value=0x%x", value); DMA_LOG("SIF0dma EXECUTE, value=0x%x", value);
DmaExec(dmaSIF0, mem, value); DmaExec(dmaSIF0, mem, value);
return false; return false;
} }
icase(D5_QWC) // dma5 - sif0 case (D6_CHCR): // dma6 - sif1
{
psHu32(mem) = (u16)value;
return false;
}
icase(D6_CHCR) // dma6 - sif1
{ {
DMA_LOG("SIF1dma EXECUTE, value=0x%x", value); DMA_LOG("SIF1dma EXECUTE, value=0x%x", value);
DmaExec(dmaSIF1, mem, value); DmaExec(dmaSIF1, mem, value);
return false; return false;
} }
icase(D6_QWC) // dma6 - sif1 case (D7_CHCR): // dma7 - sif2
{
psHu32(mem) = (u16)value;
return false;
}
icase(D7_CHCR) // dma7 - sif2
{ {
DMA_LOG("SIF2dma EXECUTE, value=0x%x", value); DMA_LOG("SIF2dma EXECUTE, value=0x%x", value);
DmaExec(dmaSIF2, mem, value); DmaExec(dmaSIF2, mem, value);
return false; return false;
} }
icase(D7_QWC) // dma7 - sif2 case (D8_CHCR): // dma8 - fromSPR
{
psHu32(mem) = (u16)value;
return false;
}
icase(D8_CHCR) // dma8 - fromSPR
{ {
DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value); DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value);
DmaExec(dmaSPR0, mem, value); DmaExec(dmaSPR0, mem, value);
return false; return false;
} }
icase(D8_QWC) // dma8 - fromSPR case (D9_CHCR): // dma9 - toSPR
{
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
{ {
DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x", value); DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x", value);
DmaExec(dmaSPR1, mem, value); DmaExec(dmaSPR1, mem, value);
return false; 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; 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); 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 //Midway are a bunch of idiots, writing to E100 (reserved) instead of E010
//Which causes a CPCOND0 to fail. //Which causes a CPCOND0 to fail.
icase(DMAC_FAKESTAT) case (DMAC_FAKESTAT):
case (DMAC_STAT):
{ {
//DevCon.Warning("Midway fixup addr=%x writing %x for DMA_STAT", mem, value); if (DMAC_FAKESTAT)
HW_LOG("Midways own DMAC_STAT Write 32bit %x", 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 // lower 16 bits: clear on 1
// upper 16 bits: reverse on 1 // upper 16 bits: reverse on 1
@ -609,21 +557,7 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value )
return false; return false;
} }
icase(DMAC_STAT) case (DMAC_ENABLEW):
{
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)
{ {
HW_LOG("DMAC_ENABLEW Write 32bit %lx", value); HW_LOG("DMAC_ENABLEW Write 32bit %lx", value);
oldvalue = psHu8(DMAC_ENABLEW + 2); oldvalue = psHu8(DMAC_ENABLEW + 2);
@ -635,6 +569,8 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value )
} }
return false; return false;
} }
default:
return true;
} }
// fall-through: use the default writeback provided by caller. // 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; 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 // Not exactly sure what RST needs to do
gifRegs.ctrl.write(value & 9); gifRegs.ctrl.write(value & 9);
@ -111,7 +111,7 @@ void _hwWrite32( u32 mem, u32 value )
return; return;
} }
icase(GIF_MODE) case (GIF_MODE):
{ {
gifRegs.mode.write(value); gifRegs.mode.write(value);
//Need to kickstart the GIF if the M3R mask comes off //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 PSX_EXTRALOGS
if ((mem & 0x1000ff00) == 0x1000f300) DevCon.Warning("8bit Write to SIF Register %x value %x wibble", mem, value); if ((mem & 0x1000ff00) == 0x1000f300) DevCon.Warning("8bit Write to SIF Register %x value %x wibble", mem, value);
#endif #endif
iswitch (mem) if (mem == SIO_TXFIFO)
icase(SIO_TXFIFO)
{ {
static bool iggy_newline = false; static bool iggy_newline = false;
static char sio_buffer[1024]; static char sio_buffer[1024];

View File

@ -17,25 +17,6 @@
#include "Hw.h" #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 // hw read functions
template< uint page > extern mem8_t hwRead8 (u32 mem); template< uint page > extern mem8_t hwRead8 (u32 mem);