aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/dfsound/Makefile.c64p4
-rw-r--r--plugins/dfsound/dma.c2
-rw-r--r--plugins/dfsound/externals.h1
-rw-r--r--plugins/dfsound/freeze.c1
-rw-r--r--plugins/dfsound/spu.c2
-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
8 files changed, 103 insertions, 15 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 8bbf4e0..2db75ac 100644
--- a/plugins/dfsound/externals.h
+++ b/plugins/dfsound/externals.h
@@ -189,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 72c9d22..43e6535 100644
--- a/plugins/dfsound/freeze.c
+++ b/plugins/dfsound/freeze.c
@@ -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/spu.c b/plugins/dfsound/spu.c
index 193a5d0..8e41d50 100644
--- a/plugins/dfsound/spu.c
+++ b/plugins/dfsound/spu.c
@@ -842,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];
@@ -1055,6 +1056,7 @@ static void sync_worker_thread(int force)
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);
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: