dsp cleaning
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6846 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
b0d2df0bad
commit
3cba9afe79
|
@ -71,6 +71,7 @@ u16 dsp_read_aram_d3()
|
|||
const u32 EndAddress = (g_dsp.ifx_regs[DSP_ACEAH] << 16) | g_dsp.ifx_regs[DSP_ACEAL];
|
||||
u32 Address = (g_dsp.ifx_regs[DSP_ACCAH] << 16) | g_dsp.ifx_regs[DSP_ACCAL];
|
||||
u16 val = 0;
|
||||
|
||||
switch (g_dsp.ifx_regs[DSP_FORMAT]) {
|
||||
case 0x5: // u8 reads
|
||||
val = DSPHost_ReadHostMemory(Address);
|
||||
|
@ -81,14 +82,16 @@ u16 dsp_read_aram_d3()
|
|||
Address++;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(DSPLLE, "dsp_read_aram_d3: Unseen Format %i", g_dsp.ifx_regs[DSP_FORMAT]);
|
||||
ERROR_LOG(DSPLLE, "dsp_read_aram_d3() - unknown format 0x%x", g_dsp.ifx_regs[DSP_FORMAT]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Address >= EndAddress)
|
||||
{
|
||||
// Set address back to start address.
|
||||
// Set address back to start address. (never seen this here!)
|
||||
Address = (g_dsp.ifx_regs[DSP_ACSAH] << 16) | g_dsp.ifx_regs[DSP_ACSAL];
|
||||
}
|
||||
|
||||
g_dsp.ifx_regs[DSP_ACCAH] = Address >> 16;
|
||||
g_dsp.ifx_regs[DSP_ACCAL] = Address & 0xffff;
|
||||
return val;
|
||||
|
@ -98,8 +101,8 @@ void dsp_write_aram_d3(u16 value)
|
|||
{
|
||||
// Zelda ucode writes a bunch of zeros to ARAM through d3 during
|
||||
// initialization. Don't know if it ever does it later, too.
|
||||
// const u32 EndAddress = (g_dsp.ifx_regs[DSP_ACEAH] << 16) | g_dsp.ifx_regs[DSP_ACEAL]; // Unused?
|
||||
u32 Address = (g_dsp.ifx_regs[DSP_ACCAH] << 16) | g_dsp.ifx_regs[DSP_ACCAL];
|
||||
|
||||
switch (g_dsp.ifx_regs[DSP_FORMAT]) {
|
||||
case 0xA: // u16 writes
|
||||
DSPHost_WriteHostMemory(value >> 8, Address*2);
|
||||
|
@ -107,9 +110,10 @@ void dsp_write_aram_d3(u16 value)
|
|||
Address++;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(DSPLLE, "dsp_write_aram_d3: Unseen Format %i", g_dsp.ifx_regs[DSP_FORMAT]);
|
||||
ERROR_LOG(DSPLLE, "dsp_write_aram_d3() - unknown format 0x%x", g_dsp.ifx_regs[DSP_FORMAT]);
|
||||
break;
|
||||
}
|
||||
|
||||
g_dsp.ifx_regs[DSP_ACCAH] = Address >> 16;
|
||||
g_dsp.ifx_regs[DSP_ACCAL] = Address & 0xffff;
|
||||
}
|
||||
|
@ -118,7 +122,6 @@ u16 dsp_read_accelerator()
|
|||
{
|
||||
const u32 EndAddress = (g_dsp.ifx_regs[DSP_ACEAH] << 16) | g_dsp.ifx_regs[DSP_ACEAL];
|
||||
u32 Address = (g_dsp.ifx_regs[DSP_ACCAH] << 16) | g_dsp.ifx_regs[DSP_ACCAL];
|
||||
|
||||
u16 val;
|
||||
|
||||
// let's do the "hardware" decode DSP_FORMAT is interesting - the Zelda
|
||||
|
@ -139,42 +142,33 @@ u16 dsp_read_accelerator()
|
|||
Address++;
|
||||
break;
|
||||
case 0x19: // 8-bit PCM audio
|
||||
val = DSPHost_ReadHostMemory(Address) << 8; // probably wrong
|
||||
val = DSPHost_ReadHostMemory(Address) << 8;
|
||||
g_dsp.ifx_regs[DSP_YN2] = g_dsp.ifx_regs[DSP_YN1];
|
||||
g_dsp.ifx_regs[DSP_YN1] = val;
|
||||
Address++;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(DSPLLE, "Unknown DSP Format %x", g_dsp.ifx_regs[DSP_FORMAT]);
|
||||
ERROR_LOG(DSPLLE, "dsp_read_accelerator() - unknown format 0x%x", g_dsp.ifx_regs[DSP_FORMAT]);
|
||||
Address++;
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: Take GAIN into account, whatever it is.
|
||||
// TODO: Take GAIN into account
|
||||
// adpcm = 0, pcm8 = 0x100, pcm16 = 0x800
|
||||
// games using pcm8 : Phoenix Wright Ace Attorney (Wiiware), Megaman 9-10 (WiiWare)
|
||||
if (g_dsp.ifx_regs[DSP_GAIN] > 0)
|
||||
{
|
||||
//NOTICE_LOG(DSPLLE,"format: 0x%04x - val: 0x%04x - gain: 0x%04x", g_dsp.ifx_regs[DSP_FORMAT], val, g_dsp.ifx_regs[DSP_GAIN]);
|
||||
}
|
||||
// games using pcm16: gc sega games, ...
|
||||
|
||||
// Check for loop.
|
||||
// Somehow, YN1 and YN2 must be initialized with their "loop" values,
|
||||
// so yeah, it seems likely that we should raise an exception to let
|
||||
// the DSP program do that, at least if DSP_FORMAT == 0x0A.
|
||||
if (Address >= EndAddress)
|
||||
{
|
||||
// Set address back to start address.
|
||||
Address = (g_dsp.ifx_regs[DSP_ACSAH] << 16) | g_dsp.ifx_regs[DSP_ACSAL];
|
||||
|
||||
// Do we really need both? (nakee: seems to cause problems with some
|
||||
// AX games)
|
||||
// DSPHost_InterruptRequest();
|
||||
// DSPCore_SetException(EXP_2);
|
||||
DSPCore_SetException(EXP_ACCOV);
|
||||
|
||||
// Somehow, YN1 and YN2 must be initialized with their "loop" values,
|
||||
// so yeah, it seems likely that we should raise an exception to let
|
||||
// the DSP program do that, at least if DSP_FORMAT == 0x0A.
|
||||
}
|
||||
//else
|
||||
// DSPCore_SetException(EXP_6); // test! (bunch of NOPs there - helps "SMB S&R (wii)")
|
||||
|
||||
g_dsp.ifx_regs[DSP_ACCAH] = Address >> 16;
|
||||
g_dsp.ifx_regs[DSP_ACCAL] = Address & 0xffff;
|
||||
|
|
|
@ -136,7 +136,7 @@ void gdsp_ifx_write(u32 addr, u32 val)
|
|||
if (val & 0x1)
|
||||
DSPHost_InterruptRequest();
|
||||
else
|
||||
WARN_LOG(DSPLLE, "Unknown Interrupt Request pc=%04x (%04x)", g_dsp.pc, val);
|
||||
INFO_LOG(DSPLLE, "Unknown Interrupt Request pc=%04x (%04x)", g_dsp.pc, val);
|
||||
break;
|
||||
|
||||
case DSP_DMBH:
|
||||
|
|
|
@ -191,7 +191,6 @@ void srri(const UDSPInstruction opc)
|
|||
u8 sreg = opc & 0x1f;
|
||||
|
||||
u16 val = dsp_op_read_reg(sreg);
|
||||
|
||||
dsp_dmem_write(g_dsp.r.ar[dreg], val);
|
||||
g_dsp.r.ar[dreg] = dsp_increment_addr_reg(dreg);
|
||||
}
|
||||
|
|
|
@ -173,6 +173,7 @@ void movpz(const UDSPInstruction opc)
|
|||
// Adds secondary accumulator $axS to product register and stores result
|
||||
// in accumulator register. Low 16-bits of $acD ($acD.l) are set (round) to 0.
|
||||
//
|
||||
// TODO: ugly code and still small error here (+/- 1 in .m - randomly)
|
||||
// flags out: --xx xx0x
|
||||
void addpaxz(const UDSPInstruction opc)
|
||||
{
|
||||
|
@ -367,7 +368,7 @@ void mulxmv(const UDSPInstruction opc)
|
|||
Update_SR_Register64(dsp_get_long_acc(rreg));
|
||||
}
|
||||
|
||||
// MULXMV $ax0.S, $ax1.T, $acR
|
||||
// MULXMVZ $ax0.S, $ax1.T, $acR
|
||||
// 101s t01r xxxx xxxx
|
||||
// Move product register to accumulator register $acR and clear (round) low part
|
||||
// of accumulator register $acR.l. Multiply one part $ax0 by one part $ax1
|
||||
|
|
|
@ -119,29 +119,24 @@ void CUCode_Zelda::RenderSynth_Constant(ZeldaVoicePB &PB, s32* _Buffer, int _Siz
|
|||
|
||||
// A piece of code from LLE so we can see how the wrap register affects the sound
|
||||
|
||||
// HORRIBLE UGLINESS, someone please fix.
|
||||
// See http://code.google.com/p/dolphin-emu/source/detail?r=3125
|
||||
inline u16 ToMask(u16 a)
|
||||
inline u16 AddValueToReg(u32 ar, s32 ix)
|
||||
{
|
||||
a = a | (a >> 8);
|
||||
a = a | (a >> 4);
|
||||
a = a | (a >> 2);
|
||||
return a | (a >> 1);
|
||||
}
|
||||
u32 wr = 0x3f;
|
||||
u32 mx = (wr | 1) << 1;
|
||||
u32 nar = ar + ix;
|
||||
u32 dar = (nar ^ ar ^ ix) & mx;
|
||||
|
||||
inline s16 AddValueToReg(s16 reg, s32 value)
|
||||
{
|
||||
s16 tmp = reg;
|
||||
u16 tmb = ToMask(0x003f);
|
||||
|
||||
for(int i = 0; i < value; i++) {
|
||||
if ((tmp & tmb) == tmb)
|
||||
tmp ^= 0x003f;
|
||||
else
|
||||
tmp++;
|
||||
if (ix >= 0)
|
||||
{
|
||||
if (dar > wr) //overflow
|
||||
nar -= wr + 1;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
else
|
||||
{
|
||||
if ((((nar + wr + 1) ^ nar) & dar) <= wr) //underflow or below min for mask
|
||||
nar += wr + 1;
|
||||
}
|
||||
return nar;
|
||||
}
|
||||
|
||||
void CUCode_Zelda::RenderSynth_WaveTable(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
|
||||
|
@ -167,7 +162,7 @@ void CUCode_Zelda::RenderSynth_WaveTable(ZeldaVoicePB &PB, s32* _Buffer, int _Si
|
|||
}
|
||||
|
||||
// TODO: Resample this!
|
||||
WARN_LOG(DSPHLE, "Synthesizing the incomplete format 0x%04x", PB.Format);
|
||||
INFO_LOG(DSPHLE, "Synthesizing the incomplete format 0x%04x", PB.Format);
|
||||
|
||||
u64 ACC0 = PB.CurSampleFrac << 6;
|
||||
|
||||
|
|
Loading…
Reference in New Issue