mcd, some improvements (dma timing, interrupt handling)
authorkub <derkub@gmail.com>
Fri, 19 Apr 2024 19:08:09 +0000 (21:08 +0200)
committerkub <derkub@gmail.com>
Fri, 19 Apr 2024 22:41:57 +0000 (00:41 +0200)
pico/cd/cdc.c
pico/cd/mcd.c
pico/cd/memory.c

index de16acb..1163cb2 100644 (file)
@@ -66,6 +66,7 @@
 
 /* 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,
@@ -354,7 +355,7 @@ void cdc_dma_update(void)
     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);
@@ -405,6 +406,9 @@ int cdc_decoder_update(uint8 header[4])
     /* set !VALST */
     cdc.stat[3] = 0x00;
 
+    /* set CRCOK bit */
+    cdc.stat[0] = BIT_DECEN;
+
     /* pending decoder interrupt */
     cdc.ifstat &= ~BIT_DECI;
 
@@ -602,7 +606,7 @@ void cdc_reg_w(unsigned char data)
         }
 
         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;
@@ -643,11 +647,8 @@ void cdc_reg_w(unsigned char data)
 
     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 */
@@ -827,7 +828,7 @@ unsigned short cdc_host_r(void)
     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);
index 4437632..2fdbe72 100644 (file)
@@ -149,7 +149,7 @@ static void pcd_cdc_event(unsigned int now)
     /* 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);
     }
@@ -209,8 +209,7 @@ void pcd_event_schedule(unsigned int now, enum pcd_event event, int after)
 
 void pcd_event_schedule_s68k(enum pcd_event event, int after)
 {
-  if (SekCyclesLeftS68k > after)
-    SekEndRunS68k(after);
+  SekEndRunS68k(after);
 
   pcd_event_schedule(SekCyclesDoneS68k(), event, after);
 }
index b13644b..fc4ddb7 100644 (file)
@@ -142,7 +142,7 @@ static u32 m68k_reg_read16(u32 a)
     // 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
@@ -172,7 +172,8 @@ void m68k_reg_write8(u32 a, u32 d)
         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
@@ -456,9 +457,9 @@ void s68k_reg_write8(u32 a, u32 d)
     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
@@ -474,11 +475,12 @@ void s68k_reg_write8(u32 a, u32 d)
     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
@@ -1223,9 +1225,10 @@ static void m68k_mem_setup_cd(void);
 \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