mcd, fixes and improvements by mcd-verificator
authorkub <derkub@gmail.com>
Fri, 19 May 2023 14:10:22 +0000 (14:10 +0000)
committerkub <derkub@gmail.com>
Fri, 19 May 2023 14:12:35 +0000 (14:12 +0000)
pico/cart.c
pico/cd/cdc.c
pico/cd/mcd.c
pico/cd/memory.c
pico/cd/sek.c
pico/pico_int.h

index 86cab1d..526ea44 100644 (file)
@@ -404,7 +404,9 @@ size_t pm_read(void *ptr, size_t bytes, pm_file *stream)
 {\r
   int ret;\r
 \r
-  if (stream->type == PMT_UNCOMPRESSED)\r
+  if (stream == NULL)\r
+    return -1;\r
+  else if (stream->type == PMT_UNCOMPRESSED)\r
   {\r
     ret = fread(ptr, 1, bytes, stream->file);\r
   }\r
@@ -514,8 +516,10 @@ size_t pm_read(void *ptr, size_t bytes, pm_file *stream)
 \r
 size_t pm_read_audio(void *ptr, size_t bytes, pm_file *stream)\r
 {\r
+  if (stream == NULL)\r
+    return -1;\r
 #if !(CPU_IS_LE)\r
-  if (stream->type == PMT_UNCOMPRESSED)\r
+  else if (stream->type == PMT_UNCOMPRESSED)\r
   {\r
     // convert little endian audio samples from WAV file\r
     int ret = pm_read(ptr, bytes, stream);\r
@@ -542,7 +546,9 @@ size_t pm_read_audio(void *ptr, size_t bytes, pm_file *stream)
 \r
 int pm_seek(pm_file *stream, long offset, int whence)\r
 {\r
-  if (stream->type == PMT_UNCOMPRESSED)\r
+  if (stream == NULL)\r
+    return -1;\r
+  else if (stream->type == PMT_UNCOMPRESSED)\r
   {\r
     fseek(stream->file, offset, whence);\r
     return ftell(stream->file);\r
index 7091463..f7ae04c 100644 (file)
@@ -244,65 +244,66 @@ int cdc_context_load_old(uint8 *state)
 #undef old_load
 }
 
-static void do_dma(enum dma_type type, int words_in)
+static void do_dma(enum dma_type type, int bytes_in)
 {
-       int dma_addr = (Pico_mcd->s68k_regs[0x0a] << 8) | Pico_mcd->s68k_regs[0x0b];
+  int dma_addr = (Pico_mcd->s68k_regs[0x0a] << 8) | Pico_mcd->s68k_regs[0x0b];
   int src_addr = cdc.dac & 0x3ffe;
   int dst_addr = dma_addr;
-  int words = words_in;
+  int bytes = bytes_in;
+  int words = bytes_in >> 1;
   int dst_limit = 0;
   uint8 *dst;
   int len;
 
   elprintf(EL_CD, "dma %d %04x->%04x %x",
-    type, cdc.dac, dst_addr, words_in);
+    type, cdc.dac, dst_addr, bytes_in);
 
   switch (type)
   {
     case pcm_ram_dma_w:
       dst_addr = (dst_addr << 2) & 0xffc;
-      if (dst_addr + words * 2 > 0x1000) {
+      if (dst_addr + bytes > 0x1000) {
         elprintf(EL_ANOMALY, "pcm dma oflow: %x %x", dst_addr, words);
-        words = (0x1000 - dst_addr) / 2;
+        bytes = 0x1000 - dst_addr;
       }
       dst = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank];
       dst = dst + dst_addr;
-      while (words > 0)
+      while (bytes > 0)
       {
-        if (src_addr + words * 2 > 0x4000) {
+        if (src_addr + bytes > 0x4000) {
           len = 0x4000 - src_addr;
           memcpy(dst, cdc.ram + src_addr, len);
           dst += len;
           src_addr = 0;
-          words -= len / 2;
+          bytes -= len;
           continue;
         }
-        memcpy(dst, cdc.ram + src_addr, words * 2);
+        memcpy(dst, cdc.ram + src_addr, bytes);
         break;
       }
       goto update_dma;
 
     case prg_ram_dma_w:
       dst_addr <<= 3;
-                 dst = Pico_mcd->prg_ram + dst_addr;
+      dst = Pico_mcd->prg_ram + dst_addr;
       dst_limit = 0x80000;
       break;
 
     case word_ram_0_dma_w:
       dst_addr = (dst_addr << 3) & 0x1fffe;
-                       dst = Pico_mcd->word_ram1M[0] + dst_addr;
+      dst = Pico_mcd->word_ram1M[0] + dst_addr;
       dst_limit = 0x20000;
       break;
 
     case word_ram_1_dma_w:
       dst_addr = (dst_addr << 3) & 0x1fffe;
-                       dst = Pico_mcd->word_ram1M[1] + dst_addr;
+      dst = Pico_mcd->word_ram1M[1] + dst_addr;
       dst_limit = 0x20000;
       break;
 
     case word_ram_2M_dma_w:
       dst_addr = (dst_addr << 3) & 0x3fffe;
-                       dst = Pico_mcd->word_ram2M + dst_addr;
+      dst = Pico_mcd->word_ram2M + dst_addr;
       dst_limit = 0x40000;
       break;
 
@@ -329,13 +330,15 @@ static void do_dma(enum dma_type type, int words_in)
     break;
   }
 
+  bytes_in &= ~1; // Todo leftover byte?
+
 update_dma:
   /* update DMA addresses */
-  cdc.dac += words_in * 2;
+  cdc.dac += bytes_in;
   if (type == pcm_ram_dma_w)
-    dma_addr += words_in >> 1;
+    dma_addr += bytes_in >> 2;
   else
-    dma_addr += words_in >> 2;
+    dma_addr += bytes_in >> 3;
 
   Pico_mcd->s68k_regs[0x0a] = dma_addr >> 8;
   Pico_mcd->s68k_regs[0x0b] = dma_addr;
@@ -348,7 +351,7 @@ void cdc_dma_update(void)
   {
     /* transfer remaining words using 16-bit DMA */
     //cdc.dma_w((cdc.dbc + 1) >> 1);
-    do_dma(cdc.dma_w, (cdc.dbc + 1) >> 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;
@@ -356,24 +359,26 @@ void cdc_dma_update(void)
     /* clear !DTEN and !DTBSY */
     cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
 
-    /* pending Data Transfer End interrupt */
-    cdc.ifstat &= ~BIT_DTEI;
+    /* clear DSR bit & set EDT bit (SCD register $04) */
+    Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0x80;
 
-    /* Data Transfer End interrupt enabled ? */
-    if (cdc.ifctrl & BIT_DTEIEN)
-    {
-      /* level 5 interrupt enabled ? */
-      if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
+    if (cdc.ifstat & BIT_DTEI) {
+      /* pending Data Transfer End interrupt */
+      cdc.ifstat &= ~BIT_DTEI;
+
+      /* Data Transfer End interrupt enabled ? */
+      if (cdc.ifctrl & BIT_DTEIEN)
       {
-        /* update IRQ level */
-        elprintf(EL_INTS, "cdc DTE irq 5");
-        pcd_irq_s68k(5, 1);
+        /* level 5 interrupt enabled ? */
+        if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
+        {
+          /* update IRQ level */
+          elprintf(EL_INTS, "cdc DTE irq 5");
+          pcd_irq_s68k(5, 1);
+        }
       }
     }
 
-    /* clear DSR bit & set EDT bit (SCD register $04) */
-    Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0x80;
-
     /* disable DMA transfer */
     cdc.dma_w = 0;
   }
@@ -456,8 +461,11 @@ void cdc_reg_w(unsigned char data)
 #ifdef LOG_CDC
   elprintf(EL_STATUS, "CDC register %X write 0x%04x", Pico_mcd->s68k_regs[0x04+1] & 0x0F, data);
 #endif
-  switch (Pico_mcd->s68k_regs[0x04+1] & 0x0F)
+  switch (Pico_mcd->s68k_regs[0x04+1] & 0x1F)
   {
+    case 0x00:
+      break;
+
     case 0x01:  /* IFCTRL */
     {
       /* pending interrupts ? */
@@ -498,7 +506,7 @@ void cdc_reg_w(unsigned char data)
 
     case 0x03:  /* DBCH */
       cdc.dbc &= 0x00ff;
-      cdc.dbc |= data << 8;
+      cdc.dbc |= (data & 0x0f) << 8;
       Pico_mcd->s68k_regs[0x04+1] = 0x04;
       break;
 
@@ -638,6 +646,10 @@ void cdc_reg_w(unsigned char data)
       /* set CRCOK bit only if decoding is enabled */
       cdc.stat[0] = data & BIT_DECEN;
 
+      /* reset DECI if decoder turned off */
+      if (!cdc.stat[0])
+        cdc.ifstat |= BIT_DECI;
+
       /* update decoding mode */
       if (data & BIT_AUTORQ)
       {
@@ -692,17 +704,22 @@ void cdc_reg_w(unsigned char data)
 
     case 0x0f:  /* RESET */
       cdc_reset();
+      Pico_mcd->s68k_regs[0x04+1] = 0x10;
       break;
 
     default:  /* by default, SBOUT is not used */
+      Pico_mcd->s68k_regs[0x04+1] = (Pico_mcd->s68k_regs[0x04+1] + 1) & 0x1f;
       break;
   }
 }
 
 unsigned char cdc_reg_r(void)
 {
-  switch (Pico_mcd->s68k_regs[0x04+1] & 0x0F)
+  switch (Pico_mcd->s68k_regs[0x04+1] & 0x01F)
   {
+    case 0x00:
+      return 0xff;
+
     case 0x01:  /* IFSTAT */
       Pico_mcd->s68k_regs[0x04+1] = 0x02;
       return cdc.ifstat;
@@ -778,11 +795,12 @@ unsigned char cdc_reg_r(void)
       }
 #endif
 
-      Pico_mcd->s68k_regs[0x04+1] = 0x00;
+      Pico_mcd->s68k_regs[0x04+1] = 0x10;
       return data;
     }
 
     default:  /* by default, COMIN is always empty */
+      Pico_mcd->s68k_regs[0x04+1] = (Pico_mcd->s68k_regs[0x04+1] + 1) & 0x1f;
       return 0xff;
   }
 }
@@ -815,23 +833,27 @@ unsigned short cdc_host_r(void)
       /* clear !DTEN and !DTBSY */
       cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
 
-      /* pending Data Transfer End interrupt */
-      cdc.ifstat &= ~BIT_DTEI;
+      /* clear DSR bit & set EDT bit (SCD register $04) */
+      Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0x80;
+    } else if ((int16)cdc.dbc <= 2) {
+      if (cdc.ifstat & BIT_DTEI) {
+        /* pending Data Transfer End interrupt */
+        cdc.ifstat &= ~BIT_DTEI;
 
-      /* Data Transfer End interrupt enabled ? */
-      if (cdc.ifctrl & BIT_DTEIEN)
-      {
-        /* level 5 interrupt enabled ? */
-        if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
+        /* Data Transfer End interrupt enabled ? */
+        if (cdc.ifctrl & BIT_DTEIEN)
         {
-          /* update IRQ level */
-          elprintf(EL_INTS, "cdc DTE irq 5");
-          pcd_irq_s68k(5, 1);
+          /* level 5 interrupt enabled ? */
+          if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
+          {
+            /* update IRQ level */
+            elprintf(EL_INTS, "cdc DTE irq 5");
+            pcd_irq_s68k(5, 1);
+          }
         }
       }
-
-      /* clear DSR bit & set EDT bit (SCD register $04) */
-      Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0x80;
+      /* set DSR and EDT bit (SCD register $04) */
+      Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0xc0;
     }
 
     return data;
index 840f916..50c85ac 100644 (file)
@@ -166,7 +166,7 @@ static void pcd_int3_timer_event(unsigned int now)
 
   if (Pico_mcd->s68k_regs[0x31] != 0)
     pcd_event_schedule(now, PCD_EVENT_TIMER3,
-      Pico_mcd->s68k_regs[0x31] * 384);
+      (Pico_mcd->s68k_regs[0x31]+1) * 384);
 }
 
 static void pcd_dma_event(unsigned int now)
@@ -190,13 +190,13 @@ void pcd_event_schedule(unsigned int now, enum pcd_event event, int after)
 {
   unsigned int when;
 
-  when = now + after;
-  if (when == 0) {
+  if ((now|after) == 0) {
     // event cancelled
     pcd_event_times[event] = 0;
     return;
   }
 
+  when = now + after;
   when |= 1;
 
   elprintf(EL_CD, "cd: new event #%u %u->%u", event, now, when);
index e51ea24..b26b629 100644 (file)
@@ -100,9 +100,9 @@ static u32 m68k_reg_read16(u32 a)
 \r
   switch (a) {\r
     case 0:\r
-      // here IFL2 is always 0, just like in Gens\r
-      d = ((Pico_mcd->s68k_regs[0x33] << 13) & 0x8000)\r
-        | Pico_mcd->m.busreq;\r
+      pcd_sync_s68k(SekCyclesDone(), 0);\r
+      d = ((Pico_mcd->s68k_regs[0x33] & PCDS_IEN2) << 13) |\r
+          (Pico_mcd->m.state_flags & PCD_ST_S68K_IFL2) | Pico_mcd->m.busreq;\r
       goto end;\r
     case 2:\r
       m68k_comm_check(a);\r
@@ -158,6 +158,8 @@ void m68k_reg_write8(u32 a, u32 d)
   switch (a) {\r
     case 0:\r
       d &= 1;\r
+      Pico_mcd->m.state_flags &= ~PCD_ST_S68K_IFL2;\r
+      if (d) Pico_mcd->m.state_flags |= PCD_ST_S68K_IFL2;\r
       if (d && (Pico_mcd->s68k_regs[0x33] & PCDS_IEN2)) {\r
         elprintf(EL_INTS, "m68k: s68k irq 2");\r
         pcd_sync_s68k(SekCyclesDone(), 0);\r
@@ -179,7 +181,7 @@ void m68k_reg_write8(u32 a, u32 d)
       if (!(d & 1))\r
         Pico_mcd->m.state_flags |= PCD_ST_S68K_RST;\r
       else if (d == 1 && (Pico_mcd->m.state_flags & PCD_ST_S68K_RST)) {\r
-        Pico_mcd->m.state_flags &= ~PCD_ST_S68K_RST;\r
+        Pico_mcd->m.state_flags &= ~(PCD_ST_S68K_RST|PCD_ST_S68K_POLL|PCD_ST_S68K_SLEEP);\r
         elprintf(EL_CDREGS, "m68k: resetting s68k");\r
         SekResetS68k();\r
       }\r
@@ -193,8 +195,8 @@ void m68k_reg_write8(u32 a, u32 d)
       elprintf(EL_CDREGS, "m68k: prg wp=%02x", d);\r
       goto write_comm;\r
     case 3:\r
-      dold = Pico_mcd->s68k_regs[3];\r
       elprintf(EL_CDREG3, "m68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
+      dold = Pico_mcd->s68k_regs[3];\r
       if ((d ^ dold) & 0xc0) {\r
         elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i",\r
           (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
@@ -214,7 +216,6 @@ void m68k_reg_write8(u32 a, u32 d)
         d = (d & 0xc0) | (dold & 0x1c) | Pico_mcd->m.dmna_ret_2m;\r
       if ((dold ^ d) & 0x1f)\r
         remap_word_ram(d);\r
-\r
       goto write_comm;\r
     case 6:\r
       Pico_mcd->bios[MEM_BE2(0x72)] = d; // simple hint vector changer\r
@@ -224,6 +225,9 @@ void m68k_reg_write8(u32 a, u32 d)
       elprintf(EL_CDREGS, "hint vector set to %04x%04x",\r
         ((u16 *)Pico_mcd->bios)[0x70/2], ((u16 *)Pico_mcd->bios)[0x72/2]);\r
       return;\r
+    case 8:\r
+      (void) cdc_host_r(); // acts same as reading\r
+      return;\r
     case 0x0f:\r
       a = 0x0e;\r
     case 0x0e:\r
@@ -277,7 +281,7 @@ u32 s68k_poll_detect(u32 a, u32 d)
         elprintf(EL_CDPOLL, "s68k poll detected @%06x, a=%02x",\r
           SekPcS68k, a);\r
       } else if (cnt > 2)\r
-        SekEndRunS68k(80);\r
+        SekEndRunS68k(240);\r
     }\r
   }\r
   Pico_mcd->m.s68k_poll_a = a;\r
@@ -308,38 +312,47 @@ u32 s68k_reg_read16(u32 a)
 \r
   switch (a) {\r
     case 0:\r
-      return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
+      d = ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
+      goto end;\r
     case 2:\r
       d = (Pico_mcd->s68k_regs[2]<<8) | (Pico_mcd->s68k_regs[3]&0x1f);\r
       elprintf(EL_CDREG3, "s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);\r
-      return s68k_poll_detect(a, d);\r
+      s68k_poll_detect(a, d);\r
+      goto end;\r
+    case 4:\r
+      d = (Pico_mcd->s68k_regs[4]<<8) | (Pico_mcd->s68k_regs[5]&0x1f);\r
+      goto end;\r
     case 6:\r
-      return cdc_reg_r();\r
+      d = cdc_reg_r();\r
+      goto end;\r
     case 8:\r
-      return cdc_host_r();\r
+      d = cdc_host_r();\r
+      goto end;\r
     case 0xC:\r
       d = SekCyclesDoneS68k() - Pico_mcd->m.stopwatch_base_c;\r
       d /= 384;\r
       d &= 0x0fff;\r
       elprintf(EL_CDREGS, "s68k stopwatch timer read (%04x)", d);\r
-      return d;\r
+      goto end;\r
     case 0x30:\r
-      elprintf(EL_CDREGS, "s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]);\r
-      return Pico_mcd->s68k_regs[31];\r
+      elprintf(EL_CDREGS, "s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[0x31]);\r
+      d = Pico_mcd->s68k_regs[0x31];\r
+      goto end;\r
     case 0x34: // fader\r
-      return 0; // no busy bit\r
+      d = 0; // no busy bit\r
+      goto end;\r
     case 0x50: // font data (check: Lunar 2, Silpheed)\r
       READ_FONT_DATA(0x00100000);\r
-      return d;\r
+      goto end;\r
     case 0x52:\r
       READ_FONT_DATA(0x00010000);\r
-      return d;\r
+      goto end;\r
     case 0x54:\r
       READ_FONT_DATA(0x10000000);\r
-      return d;\r
+      goto end;\r
     case 0x56:\r
       READ_FONT_DATA(0x01000000);\r
-      return d;\r
+      goto end;\r
   }\r
 \r
   d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
@@ -347,6 +360,7 @@ u32 s68k_reg_read16(u32 a)
   if (a >= 0x0e && a < 0x30)\r
     return s68k_poll_detect(a, d);\r
 \r
+end:\r
   return d;\r
 }\r
 \r
@@ -361,8 +375,7 @@ void s68k_reg_write8(u32 a, u32 d)
       if (!(d & 1))\r
         pcd_soft_reset();\r
       return;\r
-    case 2:\r
-      return; // only m68k can change WP\r
+    case 2: a++; // byte access only, ignores LDS/UDS\r
     case 3: {\r
       int dold = Pico_mcd->s68k_regs[3];\r
       elprintf(EL_CDREG3, "s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k);\r
@@ -399,33 +412,38 @@ void s68k_reg_write8(u32 a, u32 d)
     }\r
     case 4:\r
       elprintf(EL_CDREGS, "s68k CDC dest: %x", d&7);\r
-      Pico_mcd->s68k_regs[4] = (Pico_mcd->s68k_regs[4]&0xC0) | (d&7); // CDC mode\r
+      Pico_mcd->s68k_regs[a] = (d&7); // CDC mode\r
+      Pico_mcd->s68k_regs[0xa] = Pico_mcd->s68k_regs[0xb] = 0; // resets DMA\r
       return;\r
     case 5:\r
-      //dprintf("s68k CDC reg addr: %x", d&0xf);\r
-      break;\r
+      //dprintf("s68k CDC reg addr: %x", d&0x1f);\r
+      Pico_mcd->s68k_regs[a] = (d&0x1f);\r
+      return;\r
     case 7:\r
       cdc_reg_w(d & 0xff);\r
       return;\r
     case 0xa:\r
+    case 0xb:\r
+      // word access only. 68k sets both bus halves to value d.\r
       elprintf(EL_CDREGS, "s68k set CDC dma addr");\r
-      break;\r
+      Pico_mcd->s68k_regs[0xa] = Pico_mcd->s68k_regs[0xb] = d;\r
+      return;\r
     case 0xc:\r
     case 0xd: // 384 cycle stopwatch timer\r
       elprintf(EL_CDREGS|EL_CD, "s68k clear stopwatch (%x)", d);\r
       // does this also reset internal 384 cycle counter?\r
       Pico_mcd->m.stopwatch_base_c = SekCyclesDoneS68k();\r
       return;\r
-    case 0x0e:\r
-      a = 0x0f;\r
+    case 0x0e: a++;\r
     case 0x0f:\r
       goto write_comm;\r
+    case 0x30: a++;\r
     case 0x31: // 384 cycle int3 timer\r
       d &= 0xff;\r
       elprintf(EL_CDREGS|EL_CD, "s68k set int3 timer: %02x", d);\r
       Pico_mcd->s68k_regs[a] = (u8) d;\r
-      if (d) // d or d+1??\r
-        pcd_event_schedule_s68k(PCD_EVENT_TIMER3, d * 384);\r
+      if (d) // XXX: d or d+1? mcd-verificator results suggest d+1\r
+        pcd_event_schedule_s68k(PCD_EVENT_TIMER3, (d+1) * 384);\r
       else\r
         pcd_event_schedule(0, PCD_EVENT_TIMER3, 0);\r
       break;\r
@@ -439,6 +457,8 @@ void s68k_reg_write8(u32 a, u32 d)
           pcd_irq_s68k(4, 1);\r
         }\r
       }\r
+      if ((d ^ Pico_mcd->s68k_regs[0x33]) & ~d & PCDS_IEN2)\r
+       pcd_irq_s68k(2, 0);\r
       break;\r
     case 0x34: // fader\r
       Pico_mcd->s68k_regs[a] = (u8) d & 0x7f;\r
@@ -478,6 +498,8 @@ void s68k_reg_write8(u32 a, u32 d)
           s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);\r
       }\r
       return;\r
+    case 0x4c: a++;\r
+      break;\r
     case 0x58:\r
       return;\r
   }\r
@@ -517,11 +539,18 @@ void s68k_reg_write16(u32 a, u32 d)
     goto write_comm;\r
 \r
   switch (a) {\r
+    case 0x02:\r
     case 0x0e:\r
-      // special case, 2 byte writes would be handled differently\r
-      // TODO: verify\r
-      d = (u8)d | (r[0xe] << 8);\r
-      goto write_comm;\r
+    case 0x30:\r
+    case 0x4c:\r
+      // these are only byte registers, LDS/UDS ignored\r
+      return s68k_reg_write8(a + 1, d);\r
+    case 0x08:\r
+      return (void) cdc_host_r(); // acts same as reading\r
+    case 0x0a: // DMA address\r
+      r[0xa] = d >> 8;\r
+      r[0xb] = d;\r
+      return;\r
     case 0x58: // stamp data size\r
       r[0x59] = d & 7;\r
       return;\r
@@ -634,19 +663,19 @@ static void PicoWriteM68k16_cell1(u32 a, u32 d)
 static u32 PicoReadM68k8_ramc(u32 a)\r
 {\r
   u32 d = 0;\r
-  if (a == 0x400001) {\r
+  if ((a & 0xf00001) == 0x400001) {\r
     if (Pico.sv.data != NULL)\r
       d = 3; // 64k cart\r
     return d;\r
   }\r
 \r
-  if ((a & 0xfe0000) == 0x600000) {\r
+  if ((a & 0xf00001) == 0x600001) {\r
     if (Pico.sv.data != NULL)\r
       d = Pico.sv.data[((a >> 1) & 0xffff) + 0x2000];\r
     return d;\r
   }\r
 \r
-  if (a == 0x7fffff)\r
+  if ((a & 0xf00001) == 0x700001)\r
     return Pico_mcd->m.bcram_reg;\r
 \r
   elprintf(EL_UIO, "m68k unmapped r8  [%06x] @%06x", a, SekPc);\r
@@ -661,15 +690,15 @@ static u32 PicoReadM68k16_ramc(u32 a)
 \r
 static void PicoWriteM68k8_ramc(u32 a, u32 d)\r
 {\r
-  if ((a & 0xfe0000) == 0x600000) {\r
+  if ((a & 0xf00001) == 0x600001) {\r
     if (Pico.sv.data != NULL && (Pico_mcd->m.bcram_reg & 1)) {\r
-      Pico.sv.data[((a>>1) & 0xffff) + 0x2000] = d;\r
+      Pico.sv.data[((a >> 1) & 0xffff) + 0x2000] = d;\r
       Pico.sv.changed = 1;\r
     }\r
     return;\r
   }\r
 \r
-  if (a == 0x7fffff) {\r
+  if ((a & 0xf00001) == 0x700001) {\r
     Pico_mcd->m.bcram_reg = d;\r
     return;\r
   }\r
@@ -902,15 +931,16 @@ static u32 PicoReadS68k16_bram(u32 a)
   u32 d;\r
   elprintf(EL_ANOMALY, "FIXME: s68k_bram r16: [%06x] @%06x", a, SekPcS68k);\r
   a = (a >> 1) & 0x1fff;\r
-  d = Pico_mcd->bram[a++];\r
-  d|= Pico_mcd->bram[a++] << 8; // probably wrong, TODO: verify\r
+  d = Pico_mcd->bram[a];\r
   return d;\r
 }\r
 \r
 static void PicoWriteS68k8_bram(u32 a, u32 d)\r
 {\r
-  Pico_mcd->bram[(a >> 1) & 0x1fff] = d;\r
-  Pico.sv.changed = 1;\r
+  if (a & 1) {\r
+    Pico_mcd->bram[(a >> 1) & 0x1fff] = d;\r
+    Pico.sv.changed = 1;\r
+  }\r
 }\r
 \r
 static void PicoWriteS68k16_bram(u32 a, u32 d)\r
@@ -918,7 +948,6 @@ static void PicoWriteS68k16_bram(u32 a, u32 d)
   elprintf(EL_ANOMALY, "s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
   a = (a >> 1) & 0x1fff;\r
   Pico_mcd->bram[a++] = d;\r
-  Pico_mcd->bram[a++] = d >> 8; // TODO: verify..\r
   Pico.sv.changed = 1;\r
 }\r
 \r
@@ -1079,28 +1108,6 @@ static void remap_prg_window(u32 r1, u32 r3)
 // is reassigned to it (e.g. Mega Race).\r
 // since DTACK isn't on the expansion port, main cpu accesses are not blocked.\r
 // XXX is data read/written if main is accessing Word_RAM while not owning it?\r
-static u32 m68k_wordram_sub_read8(u32 a)\r
-{\r
-  return 0xff;\r
-//  return Pico_mcd->word_ram2M[MEM_BE2(a) & 0x3ffff];\r
-}\r
-\r
-static u32 m68k_wordram_sub_read16(u32 a)\r
-{\r
-  return 0xffff;\r
-//  return ((u16 *)Pico_mcd->word_ram2M)[(a >> 1) & 0x1ffff];\r
-}\r
-\r
-static void m68k_wordram_sub_write8(u32 a, u32 d)\r
-{\r
-//  Pico_mcd->word_ram2M[MEM_BE2(a) & 0x3ffff] = d;\r
-}\r
-\r
-static void m68k_wordram_sub_write16(u32 a, u32 d)\r
-{\r
-//  ((u16 *)Pico_mcd->word_ram2M)[(a >> 1) & 0x1ffff] = d;\r
-}\r
-\r
 static u32 s68k_wordram_main_read8(u32 a)\r
 {\r
   Pico_mcd->m.state_flags |= PCD_ST_S68K_SLEEP;\r
@@ -1145,9 +1152,7 @@ static void remap_word_ram(u32 r3)
     } else {\r
       Pico_mcd->m.state_flags &= ~PCD_ST_S68K_SLEEP;\r
       cpu68k_map_all_ram(0x080000, 0x0bffff, bank, 1);\r
-      cpu68k_map_all_funcs(0x200000, 0x23ffff,\r
-          m68k_wordram_sub_read8, m68k_wordram_sub_read16,\r
-          m68k_wordram_sub_write8, m68k_wordram_sub_write16, 0);\r
+      m68k_map_unmap(0x200000, 0x23ffff);\r
     }\r
     // TODO: handle 0x0c0000\r
   }\r
@@ -1236,6 +1241,7 @@ PICO_INTERNAL void PicoMemSetupCD(void)
   cpu68k_map_set(s68k_write16_map, 0xff0000, 0xffffff, PicoWriteS68k16_pr, 1);\r
 \r
   // RAMs\r
+  remap_prg_window(2,1);\r
   remap_word_ram(1);\r
 \r
 #ifdef EMU_C68K\r
index baf0d9e..9bb7282 100644 (file)
@@ -32,6 +32,8 @@ static int new_irq_level(int level)
 {
   int level_new = 0, irqs;
   Pico_mcd->m.s68k_pend_ints &= ~(1 << level);
+  if (level == 2) // clear pending bit
+    Pico_mcd->m.state_flags &= ~PCD_ST_S68K_IFL2;
   irqs = Pico_mcd->m.s68k_pend_ints;
   irqs &= Pico_mcd->s68k_regs[0x33];
   while ((irqs >>= 1)) level_new++;
index ac8a7ec..578fcb6 100644 (file)
@@ -511,6 +511,7 @@ struct mcd_pcm
 #define PCD_ST_S68K_SLEEP   4\r
 #define PCD_ST_S68K_POLL   16\r
 #define PCD_ST_M68K_POLL   32\r
+#define PCD_ST_S68K_IFL2   0x100\r
 \r
 struct mcd_misc\r
 {\r