aboutsummaryrefslogtreecommitdiff
path: root/plugins/dfsound
diff options
context:
space:
mode:
authornotaz2015-02-06 01:29:00 +0200
committernotaz2015-02-06 01:29:00 +0200
commit2af7e74feec67c0a798ac190774cb4b3e925be76 (patch)
tree27a148679e25f6edb7a2dd85c54514139bb72450 /plugins/dfsound
parentcebb70f24ab54693b12aaa27b85a52689e26e1ff (diff)
parent1e0eac2348343c8a046f7a75d460f087556cf7f6 (diff)
downloadpcsx_rearmed-2af7e74feec67c0a798ac190774cb4b3e925be76.tar.gz
pcsx_rearmed-2af7e74feec67c0a798ac190774cb4b3e925be76.tar.bz2
pcsx_rearmed-2af7e74feec67c0a798ac190774cb4b3e925be76.zip
Merge branch 'upstream' into libretro
Diffstat (limited to 'plugins/dfsound')
-rw-r--r--plugins/dfsound/Makefile.c64p4
-rw-r--r--plugins/dfsound/dma.c2
-rw-r--r--plugins/dfsound/externals.h9
-rw-r--r--plugins/dfsound/freeze.c5
-rw-r--r--plugins/dfsound/registers.c75
-rw-r--r--plugins/dfsound/reverb.c83
-rw-r--r--plugins/dfsound/spu.c23
-rw-r--r--plugins/dfsound/spu_c64x.c54
-rw-r--r--plugins/dfsound/spu_c64x.h2
-rw-r--r--plugins/dfsound/spu_c64x_dspcode.c52
-rw-r--r--plugins/dfsound/spu_config.h1
11 files changed, 196 insertions, 114 deletions
diff --git a/plugins/dfsound/Makefile.c64p b/plugins/dfsound/Makefile.c64p
index 45fe76a..5b97781 100644
--- a/plugins/dfsound/Makefile.c64p
+++ b/plugins/dfsound/Makefile.c64p
@@ -5,7 +5,9 @@ endif
include $(C64_TOOLS_DSP_ROOT)/install.mk
TARGET_BASENAME = pcsxr_spu
-OPTFLAGS += -O2
+OPTFLAGS += -o3
+CFLAGS += -mo
+#CFLAGS += -k -mw
CFLAGS += -DNO_OS -DWANT_THREAD_CODE
OBJ = \
diff --git a/plugins/dfsound/dma.c b/plugins/dfsound/dma.c
index 4798a19..43019f1 100644
--- a/plugins/dfsound/dma.c
+++ b/plugins/dfsound/dma.c
@@ -71,6 +71,7 @@ void CALLBACK SPUwriteDMA(unsigned short val)
spu.spuAddr += 2;
spu.spuAddr &= 0x7fffe;
+ spu.bMemDirty = 1;
}
////////////////////////////////////////////////////////////////////////
@@ -83,6 +84,7 @@ void CALLBACK SPUwriteDMAMem(unsigned short *pusPSXMem, int iSize,
int i;
do_samples_if_needed(cycles, 1);
+ spu.bMemDirty = 1;
if(spu.spuAddr + iSize*2 < 0x80000)
{
diff --git a/plugins/dfsound/externals.h b/plugins/dfsound/externals.h
index f6fc440..2db75ac 100644
--- a/plugins/dfsound/externals.h
+++ b/plugins/dfsound/externals.h
@@ -162,14 +162,8 @@ typedef struct
int dirty; // registers changed
- // normalized offsets
- int nIIR_DEST_A0, nIIR_DEST_A1, nIIR_DEST_B0, nIIR_DEST_B1,
- nACC_SRC_A0, nACC_SRC_A1, nACC_SRC_B0, nACC_SRC_B1,
- nIIR_SRC_A0, nIIR_SRC_A1, nIIR_SRC_B0, nIIR_SRC_B1,
- nACC_SRC_C0, nACC_SRC_C1, nACC_SRC_D0, nACC_SRC_D1,
- nMIX_DEST_A0, nMIX_DEST_A1, nMIX_DEST_B0, nMIX_DEST_B1;
// MIX_DEST_xx - FB_SRC_x
- int nFB_SRC_A0, nFB_SRC_A1, nFB_SRC_B0, nFB_SRC_B1;
+ int FB_SRC_A0, FB_SRC_A1, FB_SRC_B0, FB_SRC_B1;
} REVERBInfo;
///////////////////////////////////////////////////////////
@@ -195,6 +189,7 @@ typedef struct
int decode_dirty_ch;
unsigned int bSpuInit:1;
unsigned int bSPUIsOpen:1;
+ unsigned int bMemDirty:1; // had external write to SPU RAM
unsigned int dwNoiseVal; // global noise generator
unsigned int dwNoiseCount;
diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c
index 5b4267b..43e6535 100644
--- a/plugins/dfsound/freeze.c
+++ b/plugins/dfsound/freeze.c
@@ -231,6 +231,8 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF,
if(!pF) return 0; // first check
+ do_samples(cycles, 1);
+
if(ulFreezeMode) // info or save?
{//--------------------------------------------------//
if(ulFreezeMode==1)
@@ -242,8 +244,6 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF,
if(ulFreezeMode==2) return 1; // info mode? ok, bye
// save mode:
- do_samples(cycles, 1);
-
memcpy(pF->cSPURam,spu.spuMem,0x80000); // copy common infos
memcpy(pF->cSPUPort,spu.regArea,0x200);
@@ -279,6 +279,7 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF,
memcpy(spu.spuMem,pF->cSPURam,0x80000); // get ram
memcpy(spu.regArea,pF->cSPUPort,0x200);
+ spu.bMemDirty = 1;
if(pF->xaS.nsamples<=4032) // start xa again
SPUplayADPCMchannel(&pF->xaS);
diff --git a/plugins/dfsound/registers.c b/plugins/dfsound/registers.c
index 4588fa7..91bcaf8 100644
--- a/plugins/dfsound/registers.c
+++ b/plugins/dfsound/registers.c
@@ -145,17 +145,6 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val,
break;
//-------------------------------------------------//
case H_SPUReverbAddr:
- if(val==0xFFFF || val<=0x200)
- {spu.rvb->StartAddr=spu.rvb->CurrAddr=0;}
- else
- {
- const long iv=(unsigned long)val<<2;
- if(spu.rvb->StartAddr!=iv)
- {
- spu.rvb->StartAddr=(unsigned long)val<<2;
- spu.rvb->CurrAddr=spu.rvb->StartAddr;
- }
- }
goto rvbd;
//-------------------------------------------------//
case H_SPUirqAddr:
@@ -246,38 +235,38 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val,
ReverbOn(16,24,val);
break;
//-------------------------------------------------//
- case H_Reverb+0 : spu.rvb->FB_SRC_A=val*4; goto rvbd;
- case H_Reverb+2 : spu.rvb->FB_SRC_B=val*4; goto rvbd;
- case H_Reverb+4 : spu.rvb->IIR_ALPHA=(short)val; goto rvbd;
- case H_Reverb+6 : spu.rvb->ACC_COEF_A=(short)val; goto rvbd;
- case H_Reverb+8 : spu.rvb->ACC_COEF_B=(short)val; goto rvbd;
- case H_Reverb+10 : spu.rvb->ACC_COEF_C=(short)val; goto rvbd;
- case H_Reverb+12 : spu.rvb->ACC_COEF_D=(short)val; goto rvbd;
- case H_Reverb+14 : spu.rvb->IIR_COEF=(short)val; goto rvbd;
- case H_Reverb+16 : spu.rvb->FB_ALPHA=(short)val; goto rvbd;
- case H_Reverb+18 : spu.rvb->FB_X=(short)val; goto rvbd;
- case H_Reverb+20 : spu.rvb->IIR_DEST_A0=val*4; goto rvbd;
- case H_Reverb+22 : spu.rvb->IIR_DEST_A1=val*4; goto rvbd;
- case H_Reverb+24 : spu.rvb->ACC_SRC_A0=val*4; goto rvbd;
- case H_Reverb+26 : spu.rvb->ACC_SRC_A1=val*4; goto rvbd;
- case H_Reverb+28 : spu.rvb->ACC_SRC_B0=val*4; goto rvbd;
- case H_Reverb+30 : spu.rvb->ACC_SRC_B1=val*4; goto rvbd;
- case H_Reverb+32 : spu.rvb->IIR_SRC_A0=val*4; goto rvbd;
- case H_Reverb+34 : spu.rvb->IIR_SRC_A1=val*4; goto rvbd;
- case H_Reverb+36 : spu.rvb->IIR_DEST_B0=val*4; goto rvbd;
- case H_Reverb+38 : spu.rvb->IIR_DEST_B1=val*4; goto rvbd;
- case H_Reverb+40 : spu.rvb->ACC_SRC_C0=val*4; goto rvbd;
- case H_Reverb+42 : spu.rvb->ACC_SRC_C1=val*4; goto rvbd;
- case H_Reverb+44 : spu.rvb->ACC_SRC_D0=val*4; goto rvbd;
- case H_Reverb+46 : spu.rvb->ACC_SRC_D1=val*4; goto rvbd;
- case H_Reverb+48 : spu.rvb->IIR_SRC_B1=val*4; goto rvbd;
- case H_Reverb+50 : spu.rvb->IIR_SRC_B0=val*4; goto rvbd;
- case H_Reverb+52 : spu.rvb->MIX_DEST_A0=val*4; goto rvbd;
- case H_Reverb+54 : spu.rvb->MIX_DEST_A1=val*4; goto rvbd;
- case H_Reverb+56 : spu.rvb->MIX_DEST_B0=val*4; goto rvbd;
- case H_Reverb+58 : spu.rvb->MIX_DEST_B1=val*4; goto rvbd;
- case H_Reverb+60 : spu.rvb->IN_COEF_L=(short)val; goto rvbd;
- case H_Reverb+62 : spu.rvb->IN_COEF_R=(short)val; goto rvbd;
+ case H_Reverb+0 : goto rvbd;
+ case H_Reverb+2 : goto rvbd;
+ case H_Reverb+4 : spu.rvb->IIR_ALPHA=(short)val; break;
+ case H_Reverb+6 : spu.rvb->ACC_COEF_A=(short)val; break;
+ case H_Reverb+8 : spu.rvb->ACC_COEF_B=(short)val; break;
+ case H_Reverb+10 : spu.rvb->ACC_COEF_C=(short)val; break;
+ case H_Reverb+12 : spu.rvb->ACC_COEF_D=(short)val; break;
+ case H_Reverb+14 : spu.rvb->IIR_COEF=(short)val; break;
+ case H_Reverb+16 : spu.rvb->FB_ALPHA=(short)val; break;
+ case H_Reverb+18 : spu.rvb->FB_X=(short)val; break;
+ case H_Reverb+20 : goto rvbd;
+ case H_Reverb+22 : goto rvbd;
+ case H_Reverb+24 : goto rvbd;
+ case H_Reverb+26 : goto rvbd;
+ case H_Reverb+28 : goto rvbd;
+ case H_Reverb+30 : goto rvbd;
+ case H_Reverb+32 : goto rvbd;
+ case H_Reverb+34 : goto rvbd;
+ case H_Reverb+36 : goto rvbd;
+ case H_Reverb+38 : goto rvbd;
+ case H_Reverb+40 : goto rvbd;
+ case H_Reverb+42 : goto rvbd;
+ case H_Reverb+44 : goto rvbd;
+ case H_Reverb+46 : goto rvbd;
+ case H_Reverb+48 : goto rvbd;
+ case H_Reverb+50 : goto rvbd;
+ case H_Reverb+52 : goto rvbd;
+ case H_Reverb+54 : goto rvbd;
+ case H_Reverb+56 : goto rvbd;
+ case H_Reverb+58 : goto rvbd;
+ case H_Reverb+60 : spu.rvb->IN_COEF_L=(short)val; break;
+ case H_Reverb+62 : spu.rvb->IN_COEF_R=(short)val; break;
}
return;
diff --git a/plugins/dfsound/reverb.c b/plugins/dfsound/reverb.c
index 2ff6edc..ec570fb 100644
--- a/plugins/dfsound/reverb.c
+++ b/plugins/dfsound/reverb.c
@@ -50,16 +50,16 @@ INLINE int rvb2ram_offs(int curr, int space, int iOff)
// get_buffer content helper: takes care about wraps
#define g_buffer(var) \
- ((int)(signed short)spu.spuMem[rvb2ram_offs(curr_addr, space, rvb->n##var)])
+ ((int)(signed short)spu.spuMem[rvb2ram_offs(curr_addr, space, rvb->var)])
// saturate iVal and store it as var
#define s_buffer(var, iVal) \
ssat32_to_16(iVal); \
- spu.spuMem[rvb2ram_offs(curr_addr, space, rvb->n##var)] = iVal
+ spu.spuMem[rvb2ram_offs(curr_addr, space, rvb->var)] = iVal
#define s_buffer1(var, iVal) \
ssat32_to_16(iVal); \
- spu.spuMem[rvb2ram_offs(curr_addr, space, rvb->n##var + 1)] = iVal
+ spu.spuMem[rvb2ram_offs(curr_addr, space, rvb->var + 1)] = iVal
////////////////////////////////////////////////////////////////////////
@@ -174,43 +174,54 @@ static void MixREVERB_off(int *SSumLR, int ns_to, int curr_addr)
static void REVERBPrep(void)
{
REVERBInfo *rvb = spu.rvb;
- int space = 0x40000 - rvb->StartAddr;
- int t;
- #define prep_offs(v) \
- t = rvb->v; \
+ int space, t;
+
+ t = spu.regArea[(H_SPUReverbAddr - 0xc00) >> 1];
+ if (t == 0xFFFF || t <= 0x200)
+ spu.rvb->StartAddr = spu.rvb->CurrAddr = 0;
+ else if (spu.rvb->StartAddr != (t << 2))
+ spu.rvb->StartAddr = spu.rvb->CurrAddr = t << 2;
+
+ space = 0x40000 - rvb->StartAddr;
+
+ #define prep_offs(v, r) \
+ t = spu.regArea[(0x1c0 + r) >> 1] * 4; \
while (t >= space) \
t -= space; \
- rvb->n##v = t
- #define prep_offs2(d, v1, v2) \
- t = rvb->v1 - rvb->v2; \
+ rvb->v = t
+ #define prep_offs2(d, r1, r2) \
+ t = spu.regArea[(0x1c0 + r1) >> 1] * 4; \
+ t -= spu.regArea[(0x1c0 + r2) >> 1] * 4; \
+ while (t < 0) \
+ t += space; \
while (t >= space) \
t -= space; \
- rvb->n##d = t
-
- prep_offs(IIR_SRC_A0);
- prep_offs(IIR_SRC_A1);
- prep_offs(IIR_SRC_B0);
- prep_offs(IIR_SRC_B1);
- prep_offs(IIR_DEST_A0);
- prep_offs(IIR_DEST_A1);
- prep_offs(IIR_DEST_B0);
- prep_offs(IIR_DEST_B1);
- prep_offs(ACC_SRC_A0);
- prep_offs(ACC_SRC_A1);
- prep_offs(ACC_SRC_B0);
- prep_offs(ACC_SRC_B1);
- prep_offs(ACC_SRC_C0);
- prep_offs(ACC_SRC_C1);
- prep_offs(ACC_SRC_D0);
- prep_offs(ACC_SRC_D1);
- prep_offs(MIX_DEST_A0);
- prep_offs(MIX_DEST_A1);
- prep_offs(MIX_DEST_B0);
- prep_offs(MIX_DEST_B1);
- prep_offs2(FB_SRC_A0, MIX_DEST_A0, FB_SRC_A);
- prep_offs2(FB_SRC_A1, MIX_DEST_A1, FB_SRC_A);
- prep_offs2(FB_SRC_B0, MIX_DEST_B0, FB_SRC_B);
- prep_offs2(FB_SRC_B1, MIX_DEST_B1, FB_SRC_B);
+ rvb->d = t
+
+ prep_offs(IIR_SRC_A0, 32);
+ prep_offs(IIR_SRC_A1, 34);
+ prep_offs(IIR_SRC_B0, 36);
+ prep_offs(IIR_SRC_B1, 38);
+ prep_offs(IIR_DEST_A0, 20);
+ prep_offs(IIR_DEST_A1, 22);
+ prep_offs(IIR_DEST_B0, 36);
+ prep_offs(IIR_DEST_B1, 38);
+ prep_offs(ACC_SRC_A0, 24);
+ prep_offs(ACC_SRC_A1, 26);
+ prep_offs(ACC_SRC_B0, 28);
+ prep_offs(ACC_SRC_B1, 30);
+ prep_offs(ACC_SRC_C0, 40);
+ prep_offs(ACC_SRC_C1, 42);
+ prep_offs(ACC_SRC_D0, 44);
+ prep_offs(ACC_SRC_D1, 46);
+ prep_offs(MIX_DEST_A0, 52);
+ prep_offs(MIX_DEST_A1, 54);
+ prep_offs(MIX_DEST_B0, 56);
+ prep_offs(MIX_DEST_B1, 58);
+ prep_offs2(FB_SRC_A0, 52, 0);
+ prep_offs2(FB_SRC_A1, 54, 0);
+ prep_offs2(FB_SRC_B0, 56, 2);
+ prep_offs2(FB_SRC_B1, 58, 2);
#undef prep_offs
#undef prep_offs2
diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c
index 8681d35..c6a1bf5 100644
--- a/plugins/dfsound/spu.c
+++ b/plugins/dfsound/spu.c
@@ -818,12 +818,8 @@ static void do_channels(int ns_to)
}
if (spu.rvb->StartAddr) {
- if (do_rvb) {
- if (unlikely(spu.rvb->dirty))
- REVERBPrep();
-
+ if (do_rvb)
REVERBDo(spu.SSumLR, RVB, ns_to, spu.rvb->CurrAddr);
- }
spu.rvb->CurrAddr += ns_to / 2;
while (spu.rvb->CurrAddr >= 0x40000)
@@ -846,6 +842,7 @@ static struct spu_worker {
unsigned int i_ready;
unsigned int i_reaped;
unsigned int last_boot_cnt; // dsp
+ unsigned int ram_dirty;
};
// aligning for C64X_DSP
unsigned int _pad0[128/4];
@@ -970,11 +967,8 @@ static void queue_channel_work(int ns_to, unsigned int silentch)
work->rvb_addr = 0;
if (spu.rvb->StartAddr) {
- if (spu_config.iUseReverb) {
- if (unlikely(spu.rvb->dirty))
- REVERBPrep();
+ if (spu_config.iUseReverb)
work->rvb_addr = spu.rvb->CurrAddr;
- }
spu.rvb->CurrAddr += ns_to / 2;
while (spu.rvb->CurrAddr >= 0x40000)
@@ -989,9 +983,9 @@ static void do_channel_work(struct work_item *work)
{
unsigned int mask;
unsigned int decode_dirty_ch = 0;
+ const SPUCHAN *s_chan;
int *SB, sinc, spos, sbpos;
int d, ch, ns_to;
- SPUCHAN *s_chan;
ns_to = work->ns_to;
@@ -1057,8 +1051,12 @@ static void sync_worker_thread(int force)
struct work_item *work;
int done, used_space;
+ // rvb offsets will change, thread may be using them
+ force |= spu.rvb->dirty && spu.rvb->StartAddr;
+
done = thread_get_i_done() - worker->i_reaped;
used_space = worker->i_ready - worker->i_reaped;
+
//printf("done: %d use: %d dsp: %u/%u\n", done, used_space,
// worker->boot_cnt, worker->i_done);
@@ -1150,6 +1148,9 @@ void do_samples(unsigned int cycles_to, int do_direct)
}
}
+ if (unlikely(spu.rvb->dirty))
+ REVERBPrep();
+
if (do_direct || worker == NULL || !spu_config.iUseThread) {
do_channels(ns_to);
do_samples_finish(spu.SSumLR, ns_to, silentch, spu.decode_pos);
@@ -1252,7 +1253,7 @@ void schedule_next_irq(void)
void CALLBACK SPUasync(unsigned int cycle, unsigned int flags)
{
- do_samples(cycle, 0);
+ do_samples(cycle, spu_config.iUseFixedUpdates);
if (spu.spuCtrl & CTRL_IRQ)
schedule_next_irq();
diff --git a/plugins/dfsound/spu_c64x.c b/plugins/dfsound/spu_c64x.c
index be10a6b..e0aa0da 100644
--- a/plugins/dfsound/spu_c64x.c
+++ b/plugins/dfsound/spu_c64x.c
@@ -47,6 +47,25 @@ static struct {
unsigned int req_sent:1;
} f;
+static noinline void dsp_fault(void)
+{
+ dsp_msg_t msg;
+
+ f.dsp_cache_inv_virt(worker, sizeof(*worker));
+ printf("dsp crash/fault/corruption:\n");
+ printf("state rdy/reap/done: %u %u %u\n",
+ worker->i_ready, worker->i_reaped, worker->i_done);
+ printf("active/boot: %u %u\n",
+ worker->active, worker->boot_cnt);
+
+ if (f.req_sent) {
+ f.dsp_rpc_recv(&msg);
+ f.req_sent = 0;
+ }
+ f.dsp_logbuf_print();
+ spu_config.iUseThread = 0;
+}
+
static void thread_work_start(void)
{
struct region_mem *mem;
@@ -84,9 +103,11 @@ static void thread_work_start(void)
f.dsp_cache_inv_virt(&worker->i_done, 64);
worker->last_boot_cnt = worker->boot_cnt;
+ worker->ram_dirty = spu.bMemDirty;
+ spu.bMemDirty = 0;
mem = (void *)f.region.virt_addr;
- memcpy(&mem->spu_config, &spu_config, sizeof(mem->spu_config));
+ memcpy(&mem->in.spu_config, &spu_config, sizeof(mem->in.spu_config));
DSP_MSG_INIT(&msg, f.compid, CCMD_DOIT, f.region.phys_addr, 0);
ret = f.dsp_rpc_send(&msg);
@@ -97,6 +118,11 @@ static void thread_work_start(void)
return;
}
f.req_sent = 1;
+
+#if 0
+ f.dsp_rpc_recv(&msg);
+ f.req_sent = 0;
+#endif
}
static int thread_get_i_done(void)
@@ -110,6 +136,11 @@ static void thread_work_wait_sync(struct work_item *work, int force)
int limit = 1000;
int ns_to;
+ if ((unsigned int)(worker->i_done - worker->i_reaped) > WORK_MAXCNT) {
+ dsp_fault();
+ return;
+ }
+
while (worker->i_done == worker->i_reaped && limit-- > 0) {
if (!f.req_sent) {
printf("dsp: req not sent?\n");
@@ -222,7 +253,7 @@ static void init_spu_thread(void)
}
mem = (void *)f.region.virt_addr;
- memcpy(&mem->spu_config, &spu_config, sizeof(mem->spu_config));
+ memcpy(&mem->in.spu_config, &spu_config, sizeof(mem->in.spu_config));
DSP_MSG_INIT(&init_msg, f.compid, CCMD_INIT, f.region.phys_addr, 0);
ret = f.dsp_rpc(&init_msg, &msg_in);
@@ -301,4 +332,23 @@ static void exit_spu_thread(void)
worker = NULL;
}
+/* debug: "access" shared mem from gdb */
+#if 0
+struct region_mem *dbg_dsp_mem;
+
+void dbg_dsp_mem_update(void)
+{
+ struct region_mem *mem;
+
+ if (dbg_dsp_mem == NULL)
+ dbg_dsp_mem = malloc(sizeof(*dbg_dsp_mem));
+ if (dbg_dsp_mem == NULL)
+ return;
+
+ mem = (void *)f.region.virt_addr;
+ f.dsp_cache_inv_virt(mem, sizeof(*mem));
+ memcpy(dbg_dsp_mem, mem, sizeof(*dbg_dsp_mem));
+}
+#endif
+
// vim:shiftwidth=1:expandtab
diff --git a/plugins/dfsound/spu_c64x.h b/plugins/dfsound/spu_c64x.h
index 8210e63..7c4d565 100644
--- a/plugins/dfsound/spu_c64x.h
+++ b/plugins/dfsound/spu_c64x.h
@@ -15,10 +15,10 @@ struct region_mem {
// these are not to be modified by DSP
SPUCHAN s_chan[24 + 1];
REVERBInfo rvb;
+ SPUConfig spu_config;
} in;
int _pad2[128/4 - ((sizeof(struct spu_in) / 4) & (128/4 - 1))];
struct spu_worker worker;
- SPUConfig spu_config;
// init/debug
int sizeof_region_mem;
int offsetof_s_chan1;
diff --git a/plugins/dfsound/spu_c64x_dspcode.c b/plugins/dfsound/spu_c64x_dspcode.c
index b0352a9..570da5e 100644
--- a/plugins/dfsound/spu_c64x_dspcode.c
+++ b/plugins/dfsound/spu_c64x_dspcode.c
@@ -37,13 +37,40 @@ struct out_driver *out_current;
void SetupSound(void) {}
+static void enable_l2_cache(void)
+{
+ volatile uint32_t *L2CFG = (volatile uint32_t *)0x01840000;
+ uint32_t *MARi = (void *)0x01848000;
+ int i;
+
+ // program Memory Attribute Registers
+ // (old c64_tools has the defaults messed up)
+ // 00000000-0fffffff - not configurable
+ // 10000000-7fffffff - system
+ for (i = 0x10; i < 0x80; i++)
+ MARi[i] = 0;
+ // 80000000-9fffffff - RAM
+ for ( ; i < 0xa0; i++)
+ MARi[i] = 1;
+ // 0xa00000-ffffffff - reserved, etc
+ for ( ; i < 0x100; i++)
+ MARi[i] = 0;
+
+ // enable L2 (1 for 32k, 2 for 64k)
+ if (!(*L2CFG & 2)) {
+ *L2CFG = 2;
+ // wait the for the write
+ *L2CFG;
+ }
+}
+
static void invalidate_cache(struct work_item *work)
{
// see comment in writeout_cache()
//syscalls.cache_inv(work, offsetof(typeof(*work), SSumLR), 1);
- syscalls.cache_inv(spu.s_chan, sizeof(spu.s_chan[0]) * 24, 0);
+ syscalls.cache_inv(spu.s_chan, sizeof(spu.s_chan[0]) * 24, 1);
syscalls.cache_inv(work->SSumLR,
- sizeof(work->SSumLR[0]) * 2 * work->ns_to, 0);
+ sizeof(work->SSumLR[0]) * 2 * work->ns_to, 1);
}
static void writeout_cache(struct work_item *work)
@@ -53,7 +80,7 @@ static void writeout_cache(struct work_item *work)
syscalls.cache_wb(work->SSumLR, sizeof(work->SSumLR[0]) * 2 * ns_to, 1);
// have to invalidate now, otherwise there is a race between
// DSP evicting dirty lines and ARM writing new data to this area
- syscalls.cache_inv(work, offsetof(typeof(*work), SSumLR), 0);
+ syscalls.cache_inv(work, offsetof(typeof(*work), SSumLR), 1);
}
static void do_processing(void)
@@ -112,6 +139,7 @@ static unsigned int exec(dsp_component_cmd_t cmd,
switch (cmd) {
case CCMD_INIT:
+ enable_l2_cache();
InitADSR();
spu.spuMemC = mem->spu_ram;
@@ -119,7 +147,7 @@ static unsigned int exec(dsp_component_cmd_t cmd,
spu.s_chan = mem->in.s_chan;
spu.rvb = &mem->in.rvb;
worker = &mem->worker;
- memcpy(&spu_config, &mem->spu_config, sizeof(spu_config));
+ memcpy(&spu_config, &mem->in.spu_config, sizeof(spu_config));
mem->sizeof_region_mem = sizeof(*mem);
mem->offsetof_s_chan1 = offsetof(typeof(*mem), in.s_chan[1]);
@@ -131,16 +159,18 @@ static unsigned int exec(dsp_component_cmd_t cmd,
case CCMD_DOIT:
worker->active = ACTIVE_CNT;
worker->boot_cnt++;
- syscalls.cache_wb(&worker->i_done, 64, 1);
- memcpy(&spu_config, &mem->spu_config, sizeof(spu_config));
+ syscalls.cache_inv(worker, 128, 1);
+ syscalls.cache_wb(&worker->i_done, 128, 1);
+ memcpy(&spu_config, &mem->in.spu_config, sizeof(spu_config));
+
+ if (worker->ram_dirty)
+ // it's faster to do it all than just a 512k buffer
+ syscalls.cache_wbInvAll();
do_processing();
- // c64_tools lib does BCACHE_wbInvAll() when it receives mailbox irq,
- // but invalidate anyway in case c64_tools is ever fixed..
- // XXX edit: don't bother as reverb is not handled, will fix if needed
- //syscalls.cache_inv(mem, sizeof(mem->spu_ram) + sizeof(mem->SB), 0);
- //syscalls.cache_inv(&mem->in, sizeof(mem->in), 0);
+ syscalls.cache_inv(&mem->SB, sizeof(mem->SB), 0);
+ syscalls.cache_inv(&mem->in, sizeof(mem->in), 0);
break;
default:
diff --git a/plugins/dfsound/spu_config.h b/plugins/dfsound/spu_config.h
index fce1cda..3e88a2c 100644
--- a/plugins/dfsound/spu_config.h
+++ b/plugins/dfsound/spu_config.h
@@ -8,6 +8,7 @@ typedef struct
int iUseInterpolation;
int iTempo;
int iUseThread;
+ int iUseFixedUpdates; // output fixed number of samples/frame
// status
int iThreadAvail;