/* PicoDrive: doing DMA at once, not using callbacks */
//#define DMA_BYTES_PER_LINE 512
+#define DMA_CYCLES_PER_BYTE 4 // or 6?
enum dma_type {
word_ram_0_dma_w = 1,
do_dma(cdc.dma_w, cdc.dbc + 1);
/* reset data byte counter (DBCH bits 4-7 should be set to 1) */
- cdc.dbc = 0xf000;
+ cdc.dbc = 0xffff;
/* clear !DTEN and !DTBSY */
cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
/* set !VALST */
cdc.stat[3] = 0x00;
+ /* set CRCOK bit */
+ cdc.stat[0] = BIT_DECEN;
+
/* pending decoder interrupt */
cdc.ifstat &= ~BIT_DECI;
}
if (cdc.dma_w)
- pcd_event_schedule_s68k(PCD_EVENT_DMA, cdc.dbc / 2);
+ pcd_event_schedule_s68k(PCD_EVENT_DMA, cdc.dbc * DMA_CYCLES_PER_BYTE);
}
Pico_mcd->s68k_regs[0x04+1] = 0x07;
case 0x0a: /* CTRL0 */
{
- /* set CRCOK bit only if decoding is enabled */
- cdc.stat[0] = data & BIT_DECEN;
-
/* reset DECI if decoder turned off */
- if (!cdc.stat[0])
+ if (!(data & BIT_DECEN))
cdc.ifstat |= BIT_DECI;
/* update decoding mode */
if ((int16)cdc.dbc <= 0)
{
/* reset data byte counter (DBCH bits 4-7 should be set to 1) */
- cdc.dbc = 0xf000;
+ cdc.dbc = 0xffff;
/* clear !DTEN and !DTBSY */
cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
/* reset CDD command wait flag */
Pico_mcd->s68k_regs[0x4b] = 0xf0;
- if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) {
+ if ((Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) && (Pico_mcd->s68k_regs[0x37] & 4)) {
elprintf(EL_INTS|EL_CD, "s68k: cdd irq 4");
pcd_irq_s68k(4, 1);
}
void pcd_event_schedule_s68k(enum pcd_event event, int after)
{
- if (SekCyclesLeftS68k > after)
- SekEndRunS68k(after);
+ SekEndRunS68k(after);
pcd_event_schedule(SekCyclesDoneS68k(), event, after);
}
// comm flag/cmd/status (0xE-0x2F)\r
m68k_comm_check(a);\r
d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
- goto end;\r
+ return d;\r
}\r
\r
elprintf(EL_UIO, "m68k_regs FIXME invalid read @ %02x", a);\r
elprintf(EL_INTS, "m68k: s68k irq 2");\r
pcd_sync_s68k(SekCyclesDone(), 0);\r
pcd_irq_s68k(2, 1);\r
- }\r
+ } else\r
+ pcd_irq_s68k(2, 0);\r
return;\r
case 1:\r
d &= 3;\r
case 0x33: // IRQ mask\r
elprintf(EL_CDREGS|EL_CD, "s68k irq mask: %02x", d);\r
d &= 0x7e;\r
- if ((d ^ Pico_mcd->s68k_regs[0x33]) & d & PCDS_IEN4) {\r
+ if ((d ^ Pico_mcd->s68k_regs[0x33]) & PCDS_IEN4) {\r
// XXX: emulate pending irq instead?\r
- if (Pico_mcd->s68k_regs[0x37] & 4) {\r
+ if ((d & PCDS_IEN4) && (Pico_mcd->s68k_regs[0x37] & 4)) {\r
elprintf(EL_INTS, "cdd export irq 4 (unmask)");\r
pcd_irq_s68k(4, 1);\r
}\r
case 0x37: {\r
u32 d_old = Pico_mcd->s68k_regs[0x37];\r
Pico_mcd->s68k_regs[0x37] = d & 7;\r
- if ((d&4) && !(d_old&4)) {\r
+ if ((d ^ d_old) & 4) {\r
// ??\r
- pcd_event_schedule_s68k(PCD_EVENT_CDC, 12500000/75);\r
+ if (d & 4)\r
+ pcd_event_schedule_s68k(PCD_EVENT_CDC, 12500000/75);\r
\r
- if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) {\r
+ if ((d & 4) && (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4)) {\r
elprintf(EL_INTS, "cdd export irq 4");\r
pcd_irq_s68k(4, 1);\r
}\r
\r
PICO_INTERNAL void PicoMemSetupCD(void)\r
{\r
- if (!Pico_mcd)\r
+ if (!Pico_mcd) {\r
Pico_mcd = plat_mmap(0x05000000, sizeof(mcd_state), 0, 0);\r
- memset(Pico_mcd, 0, sizeof(mcd_state));\r
+ memset(Pico_mcd, 0, sizeof(mcd_state));\r
+ }\r
pcd_base_address = (Pico.romsize > 0x20000 ? 0x400000 : 0x000000);\r
\r
// setup default main68k map\r