cd: integrate new gfx code
authornotaz <notasas@gmail.com>
Sun, 22 Sep 2013 00:44:42 +0000 (03:44 +0300)
committernotaz <notasas@gmail.com>
Sun, 22 Sep 2013 23:11:26 +0000 (02:11 +0300)
14 files changed:
pico/cd/genplus_macros.h [new file with mode: 0644]
pico/cd/genplus_types.h [deleted file]
pico/cd/gfx.c
pico/cd/gfx_cd.c [deleted file]
pico/cd/gfx_cd.h [deleted file]
pico/cd/gfx_dma.c [new file with mode: 0644]
pico/cd/mcd.c
pico/cd/memory.c
pico/cd/memory_arm.s
pico/pico_int.h
pico/state.c
pico/videoport.c
platform/base_readme.txt
platform/common/common.mak

diff --git a/pico/cd/genplus_macros.h b/pico/cd/genplus_macros.h
new file mode 100644 (file)
index 0000000..8ac5d35
--- /dev/null
@@ -0,0 +1,24 @@
+#undef uint8\r
+#undef uint16\r
+#undef uint32\r
+#undef int8\r
+#undef int16\r
+#undef int32\r
+\r
+#define uint8  unsigned char\r
+#define uint16 unsigned short\r
+#define uint32 unsigned int\r
+#define int8  signed char\r
+#define int16 signed short\r
+#define int32 signed int\r
+\r
+#define READ_BYTE(BASE, ADDR) (BASE)[(ADDR)^1]\r
+#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[(ADDR)^1] = (VAL)\r
+\r
+#define load_param(param, size) \\r
+  memcpy(param, &state[bufferptr], size); \\r
+  bufferptr += size;\r
+  \r
+#define save_param(param, size) \\r
+  memcpy(&state[bufferptr], param, size); \\r
+  bufferptr += size;\r
diff --git a/pico/cd/genplus_types.h b/pico/cd/genplus_types.h
deleted file mode 100644 (file)
index 942aafb..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#undef uint8\r
-#undef uint16\r
-#undef uint32\r
-#undef int8\r
-#undef int16\r
-#undef int32\r
-\r
-#define uint8  unsigned char\r
-#define uint16 unsigned short\r
-#define uint32 unsigned int\r
-#define int8  signed char\r
-#define int16 signed short\r
-#define int32 signed int\r
index 00a5d49..bf91552 100644 (file)
  *  POSSIBILITY OF SUCH DAMAGE.
  *
  ****************************************************************************************/
-#include "genplus_types.h"
+#include "../pico_int.h"
+#include "genplus_macros.h"
 
 typedef struct
 {
-  uint32 cycles;                    /* current cycles count for graphics operation */
-  uint32 cyclesPerLine;             /* current graphics operation timings */
+  //uint32 cycles;                    /* current cycles count for graphics operation */
+  //uint32 cyclesPerLine;             /* current graphics operation timings */
   uint32 dotMask;                   /* stamp map size mask */
   uint16 *tracePtr;                 /* trace vector pointer */
   uint16 *mapPtr;                   /* stamp map table base address */
@@ -48,6 +49,7 @@ typedef struct
   uint8 mapShift;                   /* stamp map table shift value (related to stamp map size) */
   uint16 bufferOffset;              /* image buffer column offset */
   uint32 bufferStart;               /* image buffer start index */
+  uint32 y_step;                    /* pico: render line step */
   uint8 lut_prio[4][0x100][0x100];  /* WORD-RAM data writes priority lookup table */
   uint8 lut_pixel[0x200];           /* Graphics operation dot offset lookup table */
   uint8 lut_cell[0x100];            /* Graphics operation stamp offset lookup table */
@@ -55,6 +57,8 @@ typedef struct
 
 static gfx_t gfx;
 
+static void gfx_schedule(void);
+
 /***************************************************************/
 /*      Rotation / Scaling operation (2M Mode)                 */
 /***************************************************************/
@@ -62,7 +66,6 @@ static gfx_t gfx;
 void gfx_init(void)
 {
   int i, j;
-  uint16 offset;
   uint8 mask, row, col, temp;
 
   memset(&gfx, 0, sizeof(gfx));
@@ -124,41 +127,37 @@ void gfx_init(void)
   }
 }
 
-void gfx_reset(void)
-{ 
-  /* Reset cycle counter */
-  gfx.cycles = 0;
-}
-
 int gfx_context_save(uint8 *state)
 {
   uint32 tmp32;
   int bufferptr = 0;
 
-  save_param(&gfx.cycles, sizeof(gfx.cycles));
-  save_param(&gfx.cyclesPerLine, sizeof(gfx.cyclesPerLine));
+  //save_param(&gfx.cycles, sizeof(gfx.cycles));
+  //save_param(&gfx.cyclesPerLine, sizeof(gfx.cyclesPerLine));
   save_param(&gfx.dotMask, sizeof(gfx.dotMask));
   save_param(&gfx.stampShift, sizeof(gfx.stampShift));
   save_param(&gfx.mapShift, sizeof(gfx.mapShift));
   save_param(&gfx.bufferOffset, sizeof(gfx.bufferOffset));
   save_param(&gfx.bufferStart, sizeof(gfx.bufferStart));
 
-  tmp32 = (uint8 *)(gfx.tracePtr) - scd.word_ram_2M;
+  tmp32 = (uint8 *)(gfx.tracePtr) - Pico_mcd->word_ram2M;
   save_param(&tmp32, 4);
 
-  tmp32 = (uint8 *)(gfx.mapPtr) - scd.word_ram_2M;
+  tmp32 = (uint8 *)(gfx.mapPtr) - Pico_mcd->word_ram2M;
   save_param(&tmp32, 4);
 
+  save_param(&gfx.y_step, sizeof(gfx.y_step));
+
   return bufferptr;
 }
 
-int gfx_context_load(uint8 *state)
+int gfx_context_load(const uint8 *state)
 {
   uint32 tmp32;
   int bufferptr = 0;
 
-  load_param(&gfx.cycles, sizeof(gfx.cycles));
-  load_param(&gfx.cyclesPerLine, sizeof(gfx.cyclesPerLine));
+  //load_param(&gfx.cycles, sizeof(gfx.cycles));
+  //load_param(&gfx.cyclesPerLine, sizeof(gfx.cyclesPerLine));
   load_param(&gfx.dotMask, sizeof(gfx.dotMask));
   load_param(&gfx.stampShift, sizeof(gfx.stampShift));
   load_param(&gfx.mapShift, sizeof(gfx.mapShift));
@@ -166,19 +165,22 @@ int gfx_context_load(uint8 *state)
   load_param(&gfx.bufferStart, sizeof(gfx.bufferStart));
 
   load_param(&tmp32, 4);
-  gfx.tracePtr = (uint16 *)(scd.word_ram_2M + tmp32);
+  gfx.tracePtr = (uint16 *)(Pico_mcd->word_ram2M + tmp32);
 
   load_param(&tmp32, 4);
-  gfx.mapPtr = (uint16 *)(scd.word_ram_2M + tmp32);
+  gfx.mapPtr = (uint16 *)(Pico_mcd->word_ram2M + tmp32);
+
+  load_param(&gfx.y_step, sizeof(gfx.y_step));
 
   return bufferptr;
 }
 
-INLINE void gfx_render(uint32 bufferIndex, uint32 width)
+static void gfx_render(uint32 bufferIndex, uint32 width)
 {
   uint8 pixel_in, pixel_out;
   uint16 stamp_data;
   uint32 stamp_index;
+  uint32 reg;
 
   /* pixel map start position for current line (13.3 format converted to 13.11) */
   uint32 xpos = *gfx.tracePtr++ << 8;
@@ -192,7 +194,7 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
   while (width--)
   {
     /* check if stamp map is repeated */
-    if (scd.regs[0x58>>1].byte.l & 0x01)
+    if (Pico_mcd->s68k_regs[0x58+1] & 0x01)
     {
       /* stamp map range */
       xpos &= gfx.dotMask;
@@ -235,7 +237,9 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
         /*       xx = cell column (0-3) = (xpos >> (11 + 3)) & 3 */
         /*        s = stamp size (0=16x16, 1=32x32)              */
         /*      hrr = HFLIP & ROTATION bits                      */
-        stamp_index |= gfx.lut_cell[stamp_data | ((scd.regs[0x58>>1].byte.l & 0x02) << 2 ) | ((ypos >> 8) & 0xc0) | ((xpos >> 10) & 0x30)] << 6;
+        stamp_index |= gfx.lut_cell[
+          stamp_data | ((Pico_mcd->s68k_regs[0x58+1] & 0x02) << 2 )
+          | ((ypos >> 8) & 0xc0) | ((xpos >> 10) & 0x30)] << 6;
             
         /* pixel  offset (0-63)                              */
         /* table entry = yyyxxxhrr (9 bits)                  */
@@ -245,7 +249,7 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
         stamp_index |= gfx.lut_pixel[stamp_data | ((xpos >> 8) & 0x38) | ((ypos >> 5) & 0x1c0)];
 
         /* read pixel pair (2 pixels/byte) */
-        pixel_out = READ_BYTE(scd.word_ram_2M, stamp_index >> 1);
+        pixel_out = READ_BYTE(Pico_mcd->word_ram2M, stamp_index >> 1);
 
         /* extract left or rigth pixel */
         if (stamp_index & 1)
@@ -265,7 +269,7 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
     }
 
     /* read out paired pixel data */
-    pixel_in = READ_BYTE(scd.word_ram_2M, bufferIndex >> 1);
+    pixel_in = READ_BYTE(Pico_mcd->word_ram2M, bufferIndex >> 1);
 
     /* update left or rigth pixel */
     if (bufferIndex & 1)
@@ -278,10 +282,11 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
     }
 
     /* priority mode write */
-    pixel_out = gfx.lut_prio[(scd.regs[0x02>>1].w >> 3) & 0x03][pixel_in][pixel_out];
+    reg = (Pico_mcd->s68k_regs[2] << 8) | Pico_mcd->s68k_regs[3];
+    pixel_out = gfx.lut_prio[(reg >> 3) & 0x03][pixel_in][pixel_out];
 
     /* write data to image buffer */
-    WRITE_BYTE(scd.word_ram_2M, bufferIndex >> 1, pixel_out);
+    WRITE_BYTE(Pico_mcd->word_ram2M, bufferIndex >> 1, pixel_out);
 
     /* check current pixel position  */
     if ((bufferIndex & 7) != 7)
@@ -301,18 +306,19 @@ INLINE void gfx_render(uint32 bufferIndex, uint32 width)
   }
 }
 
-void gfx_start(unsigned int base, int cycles)
+void gfx_start(unsigned int base)
 {
   /* make sure 2M mode is enabled */
-  if (!(scd.regs[0x02>>1].byte.l & 0x04))
+  if (!(Pico_mcd->s68k_regs[3] & 0x04))
   {
     uint32 mask;
+    uint32 reg;
     
     /* trace vector pointer */
-    gfx.tracePtr = (uint16 *)(scd.word_ram_2M + ((base << 2) & 0x3fff8));
+    gfx.tracePtr = (uint16 *)(Pico_mcd->word_ram2M + ((base << 2) & 0x3fff8));
 
     /* stamps & stamp map size */
-    switch ((scd.regs[0x58>>1].byte.l >> 1) & 0x03)
+    switch ((Pico_mcd->s68k_regs[0x58+1] >> 1) & 0x03)
     {
       case 0:
         gfx.dotMask = 0x07ffff;   /* 256x256 dots/map  */
@@ -344,78 +350,97 @@ void gfx_start(unsigned int base, int cycles)
     }
 
     /* stamp map table base address */
-    gfx.mapPtr = (uint16 *)(scd.word_ram_2M + ((scd.regs[0x5a>>1].w << 2) & mask));
+    reg = (Pico_mcd->s68k_regs[0x5a] << 8) | Pico_mcd->s68k_regs[0x5b];
+    gfx.mapPtr = (uint16 *)(Pico_mcd->word_ram2M + ((reg << 2) & mask));
 
     /* image buffer column offset (64 pixels/cell, minus 7 pixels to restart at cell beginning) */
-    gfx.bufferOffset = (((scd.regs[0x5c>>1].byte.l & 0x1f) + 1) << 6) - 7;
+    gfx.bufferOffset = (((Pico_mcd->s68k_regs[0x5c+1] & 0x1f) + 1) << 6) - 7;
 
     /* image buffer start index in dot units (2 pixels/byte) */
-    gfx.bufferStart = (scd.regs[0x5e>>1].w << 3) & 0x7ffc0;
+    reg = (Pico_mcd->s68k_regs[0x5e] << 8) | Pico_mcd->s68k_regs[0x5f];
+    gfx.bufferStart = (reg << 3) & 0x7ffc0;
 
     /* add image buffer horizontal dot offset */
-    gfx.bufferStart += (scd.regs[0x60>>1].byte.l & 0x3f);
+    gfx.bufferStart += (Pico_mcd->s68k_regs[0x60+1] & 0x3f);
 
     /* reset GFX chip cycle counter */
-    gfx.cycles = cycles;
+    //gfx.cycles = cycles;
 
     /* update GFX chip timings (see AC3:Thunderhawk / Thunderstrike) */
-    gfx.cyclesPerLine = 4 * 5 * scd.regs[0x62>>1].w; 
+    //gfx.cyclesPerLine = 4 * 5 * scd.regs[0x62>>1].w;
 
     /* start graphics operation */
-    scd.regs[0x58>>1].byte.h = 0x80;
+    Pico_mcd->s68k_regs[0x58] = 0x80;
+
+    gfx_schedule();
   }
 }
 
-void gfx_update(int cycles)
+/* PicoDrive specific */
+#define UPDATE_CYCLES 20000
+
+static void gfx_schedule(void)
 {
-  /* synchronize GFX chip with SUB-CPU */
-  cycles -= gfx.cycles;
+  int w, h, cycles;
+  int y_step;
 
-  /* make sure SUB-CPU is ahead */
-  if (cycles > 0)
-  {
-    /* number of lines to process */
-    unsigned int lines = (cycles + gfx.cyclesPerLine - 1) / gfx.cyclesPerLine;
+  w = (Pico_mcd->s68k_regs[0x62] << 8) | Pico_mcd->s68k_regs[0x63];
+  h = (Pico_mcd->s68k_regs[0x64] << 8) | Pico_mcd->s68k_regs[0x65];
 
-    /* check against remaining lines */
-    if (lines < scd.regs[0x64>>1].byte.l)
-    {
-      /* update Vdot remaining size */
-      scd.regs[0x64>>1].byte.l -= lines;
+  cycles = 5 * w * h;
+  if (cycles > UPDATE_CYCLES)
+    y_step = (UPDATE_CYCLES + 5 * w - 1) / (5 * w);
+  else
+    y_step = h;
 
-      /* increment cycle counter */
-      gfx.cycles += lines * gfx.cyclesPerLine;
-    }
-    else
-    {
-      /* process remaining lines */
-      lines = scd.regs[0x64>>1].byte.l;
+  gfx.y_step = y_step;
+  pcd_event_schedule_s68k(PCD_EVENT_GFX, 5 * w * y_step);
+}
 
-      /* clear Vdot remaining size */
-      scd.regs[0x64>>1].byte.l = 0;
+void gfx_update(unsigned int cycles)
+{
+  int lines, lines_reg;
+  int w;
 
-      /* end of graphics operation */
-      scd.regs[0x58>>1].byte.h = 0;
-      /* level 1 interrupt enabled ? */
-      if (scd.regs[0x32>>1].byte.l & 0x02)
-      {
-        /* trigger level 1 interrupt */
-        scd.pending |= (1 << 1);
+  if (!(Pico_mcd->s68k_regs[0x58] & 0x80))
+    return;
 
-        /* update IRQ level */
-        s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
-      }
+  w = (Pico_mcd->s68k_regs[0x62] << 8) | Pico_mcd->s68k_regs[0x63];
+  lines = (Pico_mcd->s68k_regs[0x64] << 8) | Pico_mcd->s68k_regs[0x65];
+  lines_reg = lines - gfx.y_step;
+
+  if (lines_reg <= 0) {
+    Pico_mcd->s68k_regs[0x58] = 0;
+    Pico_mcd->s68k_regs[0x64] =
+    Pico_mcd->s68k_regs[0x65] = 0;
+
+    if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN1) {
+      elprintf(EL_INTS|EL_CD, "s68k: gfx_cd irq 1");
+      SekInterruptS68k(1);
     }
+  }
+  else {
+    Pico_mcd->s68k_regs[0x64] = lines_reg >> 8;
+    Pico_mcd->s68k_regs[0x65] = lines_reg;
+
+    if (lines > gfx.y_step)
+      lines = gfx.y_step;
+
+    pcd_event_schedule(cycles, PCD_EVENT_GFX, 5 * w * lines);
+  }
 
+  if (PicoOpt & POPT_EN_MCD_GFX)
+  {
     /* render lines */
     while (lines--)
     {
       /* process dots to image buffer */
-      gfx_render(gfx.bufferStart, scd.regs[0x62>>1].w);
+      gfx_render(gfx.bufferStart, w);
 
       /* increment image buffer start index for next line (8 pixels/line) */
       gfx.bufferStart += 8;
     }
   }
 }
+
+// vim:shiftwidth=2:ts=2:expandtab
diff --git a/pico/cd/gfx_cd.c b/pico/cd/gfx_cd.c
deleted file mode 100644 (file)
index 085c5e3..0000000
+++ /dev/null
@@ -1,458 +0,0 @@
-// This is a direct rewrite of gfx_cd.asm (x86 asm to C).
-// You can even find some x86 register names :)
-// Original code (c) 2002 by Stéphane Dallongeville
-
-// (c) Copyright 2007, Grazvydas "notaz" Ignotas
-
-
-#include "../pico_int.h"
-
-#undef dprintf
-#define dprintf(...)
-
-#define UPDATE_CYCLES 20000
-
-#define _rot_comp Pico_mcd->rot_comp
-
-static void gfx_do_line(unsigned int func, unsigned short *stamp_base,
-       unsigned int H_Dot);
-
-static void gfx_cd_start(void)
-{
-       int w, h, cycles;
-       int y_step;
-
-       w = _rot_comp.Reg_62;
-       h = _rot_comp.Reg_64;
-       if (w == 0 || h == 0) {
-               elprintf(EL_CD|EL_ANOMALY, "gfx_cd_start with %ux%u", w, h);
-               _rot_comp.Reg_64 = 0;
-               // irq?
-               return;
-       }
-
-       // _rot_comp.XD_Mul = ((_rot_comp.Reg_5C & 0x1f) + 1) * 4; // unused
-       _rot_comp.Function = (_rot_comp.Reg_58 & 7) | (Pico_mcd->s68k_regs[3] & 0x18);  // Jmp_Adr
-       // _rot_comp.Buffer_Adr = (_rot_comp.Reg_5E & 0xfff8) << 2; // unused?
-       _rot_comp.YD = (_rot_comp.Reg_60 >> 3) & 7;
-       _rot_comp.Vector_Adr = (_rot_comp.Reg_66 & 0xfffe) << 2;
-
-       switch (_rot_comp.Reg_58 & 6)   // Scr_16?
-       {
-               case 0: // ?
-                       _rot_comp.Stamp_Map_Adr = (_rot_comp.Reg_5A & 0xff80) << 2;
-                       break;
-               case 2: // .Dot_32
-                       _rot_comp.Stamp_Map_Adr = (_rot_comp.Reg_5A & 0xffe0) << 2;
-                       break;
-               case 4: // .Scr_16
-                       _rot_comp.Stamp_Map_Adr = 0x20000;
-                       break;
-               case 6: // .Scr_16_Dot_32
-                       _rot_comp.Stamp_Map_Adr = (_rot_comp.Reg_5A & 0xe000) << 2;
-                       break;
-       }
-
-       _rot_comp.Reg_58 |= 0x8000;     // Stamp_Size,  we start a new GFX operation
-
-       cycles = 5 * w * h;
-       if (cycles > UPDATE_CYCLES)
-               y_step = (UPDATE_CYCLES + 5 * w - 1) / (5 * w);
-       else
-               y_step = h;
-
-       _rot_comp.y_step = y_step;
-       pcd_event_schedule_s68k(PCD_EVENT_GFX, 5 * w * y_step);
-}
-
-void gfx_cd_update(unsigned int cycles)
-{
-       int w = _rot_comp.Reg_62;
-       int h, next;
-
-       if (!(Pico_mcd->rot_comp.Reg_58 & 0x8000))
-               return;
-
-       h = _rot_comp.Reg_64;
-       _rot_comp.Reg_64 -= _rot_comp.y_step;
-
-       if ((int)_rot_comp.Reg_64 <= 0) {
-               Pico_mcd->rot_comp.Reg_58 &= 0x7fff;
-               Pico_mcd->rot_comp.Reg_64  = 0;
-               if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN1) {
-                       elprintf(EL_INTS  |EL_CD, "s68k: gfx_cd irq 1");
-                       SekInterruptS68k(1);
-               }
-       }
-       else {
-               next = _rot_comp.Reg_64;
-               if (next > _rot_comp.y_step)
-                       next = _rot_comp.y_step;
-
-               pcd_event_schedule(cycles, PCD_EVENT_GFX, 5 * w * next);
-               h = _rot_comp.y_step;
-       }
-
-       if (PicoOpt & POPT_EN_MCD_GFX)
-       {
-               unsigned int func = _rot_comp.Function;
-               unsigned short *stamp_base = (unsigned short *)
-                       (Pico_mcd->word_ram2M + _rot_comp.Stamp_Map_Adr);
-
-               while (h--)
-                       gfx_do_line(func, stamp_base, w);
-       }
-}
-
-PICO_INTERNAL_ASM unsigned int gfx_cd_read(unsigned int a)
-{
-       unsigned int d = 0;
-
-       switch (a) {
-               case 0x58: d = _rot_comp.Reg_58; break;
-               case 0x5A: d = _rot_comp.Reg_5A; break;
-               case 0x5C: d = _rot_comp.Reg_5C; break;
-               case 0x5E: d = _rot_comp.Reg_5E; break;
-               case 0x60: d = _rot_comp.Reg_60; break;
-               case 0x62: d = _rot_comp.Reg_62; break;
-               case 0x64: d = _rot_comp.Reg_64; break;
-               case 0x66: break;
-               default: dprintf("gfx_cd_read FIXME: unexpected address: %02x", a); break;
-       }
-
-       dprintf("gfx_cd_read(%02x) = %04x", a, d);
-
-       return d;
-
-}
-
-static void gfx_do_line(unsigned int func, unsigned short *stamp_base,
-       unsigned int H_Dot)
-{
-       unsigned int eax, ebx, ecx, edx, esi, edi, pixel;
-       unsigned int XD, Buffer_Adr;
-       int DYXS;
-
-       XD = _rot_comp.Reg_60 & 7;
-       Buffer_Adr = ((_rot_comp.Reg_5E & 0xfff8) + _rot_comp.YD) << 2;
-       ecx = *(unsigned int *)(Pico_mcd->word_ram2M + _rot_comp.Vector_Adr);
-       edx = ecx >> 16;
-       ecx = (ecx & 0xffff) << 8;
-       edx <<= 8;
-       DYXS = *(int *)(Pico_mcd->word_ram2M + _rot_comp.Vector_Adr + 4);
-       _rot_comp.Vector_Adr += 8;
-
-       // MAKE_IMAGE_LINE
-       while (H_Dot)
-       {
-               // MAKE_IMAGE_PIXEL
-               if (!(func & 1))        // NOT TILED
-               {
-                       int mask = (func & 4) ? 0x00800000 : 0x00f80000;
-                       if ((ecx | edx) & mask)
-                       {
-                               if (func & 0x18) goto Next_Pixel;
-                               pixel = 0;
-                               goto Pixel_Out;
-                       }
-               }
-
-               if (func & 2)           // mode 32x32 dot
-               {
-                       if (func & 4)   // 16x16 screen
-                       {
-                               ebx = ((ecx >> (11+5)) & 0x007f) |
-                                     ((edx >> (11-2)) & 0x3f80);
-                       }
-                       else            // 1x1 screen
-                       {
-                               ebx = ((ecx >> (11+5)) & 0x07) |
-                                     ((edx >> (11+2)) & 0x38);
-                       }
-               }
-               else                    // mode 16x16 dot
-               {
-                       if (func & 4)   // 16x16 screen
-                       {
-                               ebx = ((ecx >> (11+4)) & 0x00ff) |
-                                     ((edx >> (11-4)) & 0xff00);
-                       }
-                       else            // 1x1 screen
-                       {
-                               ebx = ((ecx >> (11+4)) & 0x0f) |
-                                     ((edx >> (11+0)) & 0xf0);
-                       }
-               }
-
-               edi = stamp_base[ebx];
-               esi = (edi & 0x7ff) << 7;
-               if (!esi) { pixel = 0; goto Pixel_Out; }
-               edi >>= (11+1);
-               edi &= (0x1c>>1);
-               eax = ecx;
-               ebx = edx;
-               if (func & 2) edi |= 1; // 32 dots?
-               switch (edi)
-               {
-                       case 0x00:      // No_Flip_0, 16x16 dots
-                               ebx = (ebx >> 9) & 0x3c;
-                               ebx += esi;
-                               edi = (eax & 0x3800) ^ 0x1000;          // bswap
-                               eax = ((eax >> 8) & 0x40) + ebx;
-                               break;
-                       case 0x01:      // No_Flip_0, 32x32 dots
-                               ebx = (ebx >> 9) & 0x7c;
-                               ebx += esi;
-                               edi = (eax & 0x3800) ^ 0x1000;          // bswap
-                               eax = ((eax >> 7) & 0x180) + ebx;
-                               break;
-                       case 0x02:      // No_Flip_90, 16x16 dots
-                               eax = (eax >> 9) & 0x3c;
-                               eax += esi;
-                               edi = (ebx & 0x3800) ^ 0x2800;          // bswap
-                               eax += ((ebx >> 8) & 0x40) ^ 0x40;
-                               break;
-                       case 0x03:      // No_Flip_90, 32x32 dots
-                               eax = (eax >> 9) & 0x7c;
-                               eax += esi;
-                               edi = (ebx & 0x3800) ^ 0x2800;          // bswap
-                               eax += ((ebx >> 7) & 0x180) ^ 0x180;
-                               break;
-                       case 0x04:      // No_Flip_180, 16x16 dots
-                               ebx = ((ebx >> 9) & 0x3c) ^ 0x3c;
-                               ebx += esi;
-                               edi = (eax & 0x3800) ^ 0x2800;          // bswap and flip
-                               eax = (((eax >> 8) & 0x40) ^ 0x40) + ebx;
-                               break;
-                       case 0x05:      // No_Flip_180, 32x32 dots
-                               ebx = ((ebx >> 9) & 0x7c) ^ 0x7c;
-                               ebx += esi;
-                               edi = (eax & 0x3800) ^ 0x2800;          // bswap and flip
-                               eax = (((eax >> 7) & 0x180) ^ 0x180) + ebx;
-                               break;
-                       case 0x06:      // No_Flip_270, 16x16 dots
-                               eax = ((eax >> 9) & 0x3c) ^ 0x3c;
-                               eax += esi;
-                               edi = (ebx & 0x3800) ^ 0x1000;          // bswap
-                               eax += (ebx >> 8) & 0x40;
-                               break;
-                       case 0x07:      // No_Flip_270, 32x32 dots
-                               eax = ((eax >> 9) & 0x7c) ^ 0x7c;
-                               eax += esi;
-                               edi = (ebx & 0x3800) ^ 0x1000;          // bswap
-                               eax += (ebx >> 7) & 0x180;
-                               break;
-                       case 0x08:      // Flip_0, 16x16 dots
-                               ebx = (ebx >> 9) & 0x3c;
-                               ebx += esi;
-                               edi = (eax & 0x3800) ^ 0x2800;          // bswap, flip
-                               eax = (((eax >> 8) & 0x40) ^ 0x40) + ebx;
-                               break;
-                       case 0x09:      // Flip_0, 32x32 dots
-                               ebx = (ebx >> 9) & 0x7c;
-                               ebx += esi;
-                               edi = (eax & 0x3800) ^ 0x2800;          // bswap, flip
-                               eax = (((eax >> 7) & 0x180) ^ 0x180) + ebx;
-                               break;
-                       case 0x0a:      // Flip_90, 16x16 dots
-                               eax = ((eax >> 9) & 0x3c) ^ 0x3c;
-                               eax += esi;
-                               edi = (ebx & 0x3800) ^ 0x2800;          // bswap, flip
-                               eax += ((ebx >> 8) & 0x40) ^ 0x40;
-                               break;
-                       case 0x0b:      // Flip_90, 32x32 dots
-                               eax = ((eax >> 9) & 0x7c) ^ 0x7c;
-                               eax += esi;
-                               edi = (ebx & 0x3800) ^ 0x2800;          // bswap, flip
-                               eax += ((ebx >> 7) & 0x180) ^ 0x180;
-                               break;
-                       case 0x0c:      // Flip_180, 16x16 dots
-                               ebx = ((ebx >> 9) & 0x3c) ^ 0x3c;
-                               ebx += esi;
-                               edi = (eax & 0x3800) ^ 0x1000;          // bswap
-                               eax = ((eax >> 8) & 0x40) + ebx;
-                               break;
-                       case 0x0d:      // Flip_180, 32x32 dots
-                               ebx = ((ebx >> 9) & 0x7c) ^ 0x7c;
-                               ebx += esi;
-                               edi = (eax & 0x3800) ^ 0x1000;          // bswap
-                               eax = ((eax >> 7) & 0x180) + ebx;
-                               break;
-                       case 0x0e:      // Flip_270, 16x16 dots
-                               eax = (eax >> 9) & 0x3c;
-                               eax += esi;
-                               edi = (ebx & 0x3800) ^ 0x1000;          // bswap, flip
-                               eax += (ebx >> 8) & 0x40;
-                               break;
-                       case 0x0f:      // Flip_270, 32x32 dots
-                               eax = (eax >> 9) & 0x7c;
-                               eax += esi;
-                               edi = (ebx & 0x3800) ^ 0x1000;          // bswap, flip
-                               eax += (ebx >> 7) & 0x180;
-                               break;
-               }
-
-               pixel = *(Pico_mcd->word_ram2M + (edi >> 12) + eax);
-               if (!(edi & 0x800)) pixel >>= 4;
-               else pixel &= 0x0f;
-
-Pixel_Out:
-               if (!pixel && (func & 0x18)) goto Next_Pixel;
-               esi = Buffer_Adr + ((XD>>1)^1);                         // pixel addr
-               eax = *(Pico_mcd->word_ram2M + esi);                    // old pixel
-               if (XD & 1)
-               {
-                       if ((eax & 0x0f) && (func & 0x18) == 0x08) goto Next_Pixel; // underwrite
-                       *(Pico_mcd->word_ram2M + esi) = pixel | (eax & 0xf0);
-               }
-               else
-               {
-                       if ((eax & 0xf0) && (func & 0x18) == 0x08) goto Next_Pixel; // underwrite
-                       *(Pico_mcd->word_ram2M + esi) = (pixel << 4) | (eax & 0xf);
-               }
-
-
-Next_Pixel:
-               ecx += (DYXS << 16) >> 16;      // _rot_comp.DXS;
-               edx +=  DYXS >> 16;             // _rot_comp.DYS;
-               XD++;
-               if (XD >= 8)
-               {
-                       Buffer_Adr += ((_rot_comp.Reg_5C & 0x1f) + 1) << 5;
-                       XD = 0;
-               }
-               H_Dot--;
-       }
-       // end while
-
-
-// nothing_to_draw:
-       _rot_comp.YD++;
-       // _rot_comp.V_Dot--; // will be done by caller
-}
-
-
-PICO_INTERNAL_ASM void gfx_cd_write16(unsigned int a, unsigned int d)
-{
-       dprintf("gfx_cd_write16(%x, %04x)", a, d);
-
-       if (_rot_comp.Reg_58 & 0x8000)
-               elprintf(EL_CD|EL_ANOMALY, "cd: busy gfx reg write %02x %04x", a, d);
-
-       switch (a) {
-               case 0x58: // .Reg_Stamp_Size
-                       _rot_comp.Reg_58 = d & 7;
-                       return;
-
-               case 0x5A: // .Reg_Stamp_Adr
-                       _rot_comp.Reg_5A = d & 0xffe0;
-                       return;
-
-               case 0x5C: // .Reg_IM_VCell_Size
-                       _rot_comp.Reg_5C = d & 0x1f;
-                       return;
-
-               case 0x5E: // .Reg_IM_Adr
-                       _rot_comp.Reg_5E = d & 0xFFF8;
-                       return;
-
-               case 0x60: // .Reg_IM_Offset
-                       _rot_comp.Reg_60 = d & 0x3f;
-                       return;
-
-               case 0x62: // .Reg_IM_HDot_Size
-                       _rot_comp.Reg_62 = d & 0x1ff;
-                       return;
-
-               case 0x64: // .Reg_IM_VDot_Size
-                       _rot_comp.Reg_64 = d & 0xff;    // V_Dot, must be 32bit?
-                       return;
-
-               case 0x66: // .Reg_Vector_Adr
-                       _rot_comp.Reg_66 = d & 0xfffe;
-                       if (Pico_mcd->s68k_regs[3]&4) return; // can't do tanformations in 1M mode
-                       gfx_cd_start();
-                       return;
-
-               default: dprintf("gfx_cd_write16 FIXME: unexpected address: %02x", a); return;
-       }
-}
-
-
-PICO_INTERNAL void gfx_cd_reset(void)
-{
-       memset(&_rot_comp.Reg_58, 0, sizeof(_rot_comp));
-}
-
-
-// --------------------------------
-
-#include "cell_map.c"
-
-#ifndef UTYPES_DEFINED
-typedef unsigned short u16;
-#endif
-
-// check: Heart of the alien, jaguar xj 220
-PICO_INTERNAL void DmaSlowCell(unsigned int source, unsigned int a, int len, unsigned char inc)
-{
-  unsigned char *base;
-  unsigned int asrc, a2;
-  u16 *r;
-
-  base = Pico_mcd->word_ram1M[Pico_mcd->s68k_regs[3]&1];
-
-  switch (Pico.video.type)
-  {
-    case 1: // vram
-      r = Pico.vram;
-      for(; len; len--)
-      {
-        asrc = cell_map(source >> 2) << 2;
-        asrc |= source & 2;
-        // if(a&1) d=(d<<8)|(d>>8); // ??
-        r[a>>1] = *(u16 *)(base + asrc);
-       source += 2;
-        // AutoIncrement
-        a=(u16)(a+inc);
-      }
-      rendstatus |= PDRAW_SPRITES_MOVED;
-      break;
-
-    case 3: // cram
-      Pico.m.dirtyPal = 1;
-      r = Pico.cram;
-      for(a2=a&0x7f; len; len--)
-      {
-        asrc = cell_map(source >> 2) << 2;
-        asrc |= source & 2;
-        r[a2>>1] = *(u16 *)(base + asrc);
-       source += 2;
-        // AutoIncrement
-        a2+=inc;
-        // good dest?
-        if(a2 >= 0x80) break;
-      }
-      a=(a&0xff00)|a2;
-      break;
-
-    case 5: // vsram[a&0x003f]=d;
-      r = Pico.vsram;
-      for(a2=a&0x7f; len; len--)
-      {
-        asrc = cell_map(source >> 2) << 2;
-        asrc |= source & 2;
-        r[a2>>1] = *(u16 *)(base + asrc);
-       source += 2;
-        // AutoIncrement
-        a2+=inc;
-        // good dest?
-        if(a2 >= 0x80) break;
-      }
-      a=(a&0xff00)|a2;
-      break;
-  }
-  // remember addr
-  Pico.video.addr=(u16)a;
-}
-
diff --git a/pico/cd/gfx_cd.h b/pico/cd/gfx_cd.h
deleted file mode 100644 (file)
index 20cc9ae..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _GFX_CD_H
-#define _GFX_CD_H
-
-
-typedef struct
-{
-       unsigned int Reg_58;            // Stamp_Size
-       unsigned int Reg_5A;
-       unsigned int Reg_5C;
-       unsigned int Reg_5E;
-       unsigned int Reg_60;
-       unsigned int Reg_62;
-       unsigned int Reg_64;            // V_Dot
-       unsigned int Reg_66;
-
-       unsigned int Stamp_Map_Adr;
-       unsigned int Vector_Adr;
-       unsigned int Function;          // Jmp_Adr;
-       unsigned int Float_Part;
-       unsigned int Draw_Speed;
-       unsigned int YD;
-
-       unsigned int y_step;
-       int pad[9];
-} Rot_Comp;
-
-
-PICO_INTERNAL_ASM unsigned int gfx_cd_read(unsigned int a);
-PICO_INTERNAL_ASM void gfx_cd_write16(unsigned int a, unsigned int d);
-void gfx_cd_update(unsigned int cycles);
-
-PICO_INTERNAL void gfx_cd_reset(void);
-
-PICO_INTERNAL void DmaSlowCell(unsigned int source, unsigned int a, int len, unsigned char inc);
-
-#endif // _GFX_CD_H
-
diff --git a/pico/cd/gfx_dma.c b/pico/cd/gfx_dma.c
new file mode 100644 (file)
index 0000000..44fa7ab
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * PicoDrive
+ * (C) notaz, 2007
+ *
+ * This work is licensed under the terms of MAME license.
+ * See COPYING file in the top-level directory.
+ */
+
+#include "../pico_int.h"
+
+#include "cell_map.c"
+
+#ifndef UTYPES_DEFINED
+typedef unsigned short u16;
+#endif
+
+// check: Heart of the alien, jaguar xj 220
+PICO_INTERNAL void DmaSlowCell(unsigned int source, unsigned int a, int len, unsigned char inc)
+{
+  unsigned char *base;
+  unsigned int asrc, a2;
+  u16 *r;
+
+  base = Pico_mcd->word_ram1M[Pico_mcd->s68k_regs[3]&1];
+
+  switch (Pico.video.type)
+  {
+    case 1: // vram
+      r = Pico.vram;
+      for(; len; len--)
+      {
+        asrc = cell_map(source >> 2) << 2;
+        asrc |= source & 2;
+        // if(a&1) d=(d<<8)|(d>>8); // ??
+        r[a>>1] = *(u16 *)(base + asrc);
+       source += 2;
+        // AutoIncrement
+        a=(u16)(a+inc);
+      }
+      rendstatus |= PDRAW_SPRITES_MOVED;
+      break;
+
+    case 3: // cram
+      Pico.m.dirtyPal = 1;
+      r = Pico.cram;
+      for(a2=a&0x7f; len; len--)
+      {
+        asrc = cell_map(source >> 2) << 2;
+        asrc |= source & 2;
+        r[a2>>1] = *(u16 *)(base + asrc);
+       source += 2;
+        // AutoIncrement
+        a2+=inc;
+        // good dest?
+        if(a2 >= 0x80) break;
+      }
+      a=(a&0xff00)|a2;
+      break;
+
+    case 5: // vsram[a&0x003f]=d;
+      r = Pico.vsram;
+      for(a2=a&0x7f; len; len--)
+      {
+        asrc = cell_map(source >> 2) << 2;
+        asrc |= source & 2;
+        r[a2>>1] = *(u16 *)(base + asrc);
+       source += 2;
+        // AutoIncrement
+        a2+=inc;
+        // good dest?
+        if(a2 >= 0x80) break;
+      }
+      a=(a&0xff00)|a2;
+      break;
+  }
+  // remember addr
+  Pico.video.addr=(u16)a;
+}
+
index 3048484..ef8d8f2 100644 (file)
@@ -21,6 +21,7 @@ PICO_INTERNAL void PicoInitMCD(void)
 {
   SekInitS68k();
   Init_CD_Driver();
+  gfx_init();
 }
 
 PICO_INTERNAL void PicoExitMCD(void)
@@ -57,7 +58,6 @@ void pcd_soft_reset(void)
   // Reset_CD(); // breaks Fahrenheit CD swap
 
   LC89510_Reset();
-  gfx_cd_reset();
 #ifdef _ASM_CD_MEMORY_C
   //PicoMemResetCDdecode(1); // don't have to call this in 2M mode
 #endif
@@ -160,7 +160,7 @@ static unsigned int event_time_next;
 static event_cb *pcd_event_cbs[PCD_EVENT_COUNT] = {
   [PCD_EVENT_CDC]      = pcd_cdc_event,
   [PCD_EVENT_TIMER3]   = pcd_int3_timer_event,
-  [PCD_EVENT_GFX]      = gfx_cd_update,
+  [PCD_EVENT_GFX]      = gfx_update,
   [PCD_EVENT_DMA]      = pcd_dma_event,
 };
 
@@ -341,12 +341,6 @@ void pcd_state_loaded(void)
       pcd_event_schedule(SekCycleAimS68k, PCD_EVENT_TIMER3,
         Pico_mcd->s68k_regs[0x31] * 384);
 
-    if (Pico_mcd->rot_comp.Reg_58 & 0x8000) {
-      Pico_mcd->rot_comp.Reg_58 &= 0x7fff;
-      Pico_mcd->rot_comp.Reg_64  = 0;
-      if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN1)
-        SekInterruptS68k(1);
-    }
     if (Pico_mcd->scd.Status_CDC & 0x08)
            Update_CDC_TRansfer(Pico_mcd->s68k_regs[4] & 7);
   }
index 8fce606..2c53b33 100644 (file)
@@ -9,8 +9,6 @@
 #include "../pico_int.h"\r
 #include "../memory.h"\r
 \r
-#include "gfx_cd.h"\r
-\r
 uptr s68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];\r
 uptr s68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];\r
 uptr s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];\r
@@ -429,6 +427,8 @@ void s68k_reg_write8(u32 a, u32 d)
       Pico_mcd->s68k_regs[a] = (u8) d;\r
       CDD_Import_Command();\r
       return;\r
+    case 0x58:\r
+      return;\r
   }\r
 \r
   if ((a&0x1f0) == 0x20)\r
@@ -450,6 +450,65 @@ write_comm:
   Pico_mcd->m.m68k_poll_cnt = 0;\r
 }\r
 \r
+void s68k_reg_write16(u32 a, u32 d)\r
+{\r
+  u8 *r = Pico_mcd->s68k_regs;\r
+\r
+  if ((a & 0x1f0) == 0x20)\r
+    goto write_comm;\r
+\r
+  switch (a) {\r
+    case 0x0e:\r
+      // special case, 2 byte writes would be handled differently\r
+      // TODO: verify\r
+      r[0xf] = d;\r
+      return;\r
+    case 0x58: // stamp data size\r
+      r[0x59] = d & 7;\r
+      return;\r
+    case 0x5a: // stamp map base address\r
+      r[0x5a] = d >> 8;\r
+      r[0x5b] = d & 0xe0;\r
+      return;\r
+    case 0x5c: // V cell size\r
+      r[0x5d] = d & 0x1f;\r
+      return;\r
+    case 0x5e: // image buffer start address\r
+      r[0x5e] = d >> 8;\r
+      r[0x5f] = d & 0xf8;\r
+      return;\r
+    case 0x60: // image buffer offset\r
+      r[0x61] = d & 0x3f;\r
+      return;\r
+    case 0x62: // h dot size\r
+      r[0x62] = (d >> 8) & 1;\r
+      r[0x63] = d;\r
+      return;\r
+    case 0x64: // v dot size\r
+      r[0x65] = d;\r
+      return;\r
+    case 0x66: // trace vector base address\r
+      d &= 0xfffe;\r
+      r[0x66] = d >> 8;\r
+      r[0x67] = d;\r
+      gfx_start(d);\r
+      return;\r
+    default:\r
+      break;\r
+  }\r
+\r
+  s68k_reg_write8(a,     d >> 8);\r
+  s68k_reg_write8(a + 1, d & 0xff);\r
+  return;\r
+\r
+write_comm:\r
+  r[a] = d >> 8;\r
+  r[a + 1] = d;\r
+  if (Pico_mcd->m.m68k_poll_cnt)\r
+    SekEndRunS68k(0);\r
+  Pico_mcd->m.m68k_poll_cnt = 0;\r
+}\r
+\r
 // -----------------------------------------------------------------\r
 //                          Main 68k\r
 // -----------------------------------------------------------------\r
@@ -814,9 +873,7 @@ static u32 PicoReadS68k8_pr(u32 a)
       s68k_poll_detect(a & ~1, d);\r
       goto regs_done;\r
     }\r
-    else if (a >= 0x58 && a < 0x68)\r
-         d = gfx_cd_read(a & ~1);\r
-    else d = s68k_reg_read16(a & ~1);\r
+    d = s68k_reg_read16(a & ~1);\r
     if (!(a & 1))\r
       d >>= 8;\r
 \r
@@ -849,9 +906,7 @@ static u32 PicoReadS68k16_pr(u32 a)
   // regs\r
   if ((a & 0xfe00) == 0x8000) {\r
     a &= 0x1fe;\r
-    if (0x58 <= a && a < 0x68)\r
-         d = gfx_cd_read(a);\r
-    else d = s68k_reg_read16(a);\r
+    d = s68k_reg_read16(a);\r
 \r
     elprintf(EL_CDREGS, "s68k_regs r16: [%02x] %04x @%06x",\r
       a, d, SekPcS68k);\r
@@ -878,9 +933,10 @@ static void PicoWriteS68k8_pr(u32 a, u32 d)
   if ((a & 0xfe00) == 0x8000) {\r
     a &= 0x1ff;\r
     elprintf(EL_CDREGS, "s68k_regs w8: [%02x] %02x @%06x", a, d, SekPcS68k);\r
-    if (0x58 <= a && a < 0x68)\r
-         gfx_cd_write16(a&~1, (d<<8)|d);\r
-    else s68k_reg_write8(a,d);\r
+    if (0x59 <= a && a < 0x68) // word regs\r
+      s68k_reg_write16(a & ~1, (d << 8) | d);\r
+    else\r
+      s68k_reg_write8(a, d);\r
     return;\r
   }\r
 \r
@@ -903,18 +959,7 @@ static void PicoWriteS68k16_pr(u32 a, u32 d)
   if ((a & 0xfe00) == 0x8000) {\r
     a &= 0x1fe;\r
     elprintf(EL_CDREGS, "s68k_regs w16: [%02x] %04x @%06x", a, d, SekPcS68k);\r
-    if (a >= 0x58 && a < 0x68)\r
-      gfx_cd_write16(a, d);\r
-    else {\r
-      if (a == 0xe) {\r
-        // special case, 2 byte writes would be handled differently\r
-        // TODO: verify\r
-        Pico_mcd->s68k_regs[0xf] = d;\r
-        return;\r
-      }\r
-      s68k_reg_write8(a,     d >> 8);\r
-      s68k_reg_write8(a + 1, d & 0xff);\r
-    }\r
+    s68k_reg_write16(a, d);\r
     return;\r
   }\r
 \r
index db5b8a2..b54d995 100644 (file)
@@ -53,9 +53,8 @@
 .extern m68k_reg_write8
 .extern s68k_reg_read16
 .extern s68k_reg_write8
+.extern s68k_reg_write16
 .extern s68k_poll_detect
-.extern gfx_cd_read
-.extern gfx_cd_write16
 .extern pcd_pcm_write
 .extern pcd_pcm_read
 .extern PicoCpuCS68k
@@ -420,14 +419,9 @@ m_s68k_read8_regs:
     sub     r2, r0, #0x0e
     cmp     r2, #(0x30-0x0e)
     blo     m_s68k_read8_comm
-    sub     r2, r0, #0x58
-    cmp     r2, #0x10
-    ldrlo   r2, =gfx_cd_read
-    ldrhs   r2, =s68k_reg_read16
     stmfd   sp!,{r0,lr}
     bic     r0, r0, #1
-    mov     lr, pc
-    bx      r2
+    bl      s68k_reg_read16
     ldmfd   sp!,{r1,lr}
     tst     r1, #1
     moveq   r0, r0, lsr #8
@@ -503,9 +497,6 @@ m_s68k_read16_regs:
     bic     r0, r0, #0xff0000
     bic     r0, r0, #0x008000
     bic     r0, r0, #0x000001
-    sub     r2, r0, #0x58
-    cmp     r2, #0x10
-    blo     gfx_cd_read
     cmp     r0, #8
     bne     s68k_reg_read16
     mov     r0, #1
@@ -580,12 +571,12 @@ m_s68k_write8_regs:
     tst     r0, #0x7e00
     movne   r0, #0
     bxne    lr
-    sub     r2, r0, #0x58
-    cmp     r2, #0x10
+    sub     r2, r0, #0x59
+    cmp     r2, #0x0f
     bhs     s68k_reg_write8
     bic     r0, r0, #1
     orr     r1, r1, r1, lsl #8
-    b       gfx_cd_write16
+    b       s68k_reg_write16
 
 
 m_s68k_write8_pcm:
@@ -697,17 +688,7 @@ m_s68k_write16_regs:
     movne   r0, #0
     bxne    lr
     cmp     r0, #0x0e
-    beq     m_s68k_write16_regs_spec
-    sub     r2, r0, #0x58
-    cmp     r2, #0x10
-    blo     gfx_cd_write16
-    and     r3, r1, #0xff
-    add     r2, r0, #1
-    stmfd   sp!,{r2,r3,lr}
-    mov     r1, r1, lsr #8
-    bl      s68k_reg_write8
-    ldmfd   sp!,{r0,r1,lr}
-    b       s68k_reg_write8
+    bne     s68k_reg_write16
 
 m_s68k_write16_regs_spec:               @ special case
     ldr     r2, =(Pico+0x22200)
index ccc1a9b..a33051c 100644 (file)
@@ -376,7 +376,6 @@ struct PicoSRAM
 // MCD\r
 #include "cd/cd_sys.h"\r
 #include "cd/LC89510.h"\r
-#include "cd/gfx_cd.h"\r
 \r
 #define PCM_MIXBUF_LEN ((12500000 / 384) / 50 + 1)\r
 \r
@@ -446,7 +445,6 @@ typedef struct
        CDD  cdd;\r
        CDC  cdc;\r
        _scd scd;\r
-       Rot_Comp rot_comp;\r
        int pcm_mixbuf[PCM_MIXBUF_LEN * 2];\r
        int pcm_mixpos;\r
        int pcm_mixbuf_dirty;\r
@@ -611,6 +609,16 @@ void PicoWrite16_io(unsigned int a, unsigned int d);
 // pico/memory.c\r
 PICO_INTERNAL void PicoMemSetupPico(void);\r
 \r
+// cd/gfx.c\r
+void gfx_init(void);\r
+void gfx_start(unsigned int base);\r
+void gfx_update(unsigned int cycles);\r
+int gfx_context_save(unsigned char *state);\r
+int gfx_context_load(const unsigned char *state);\r
+\r
+// cd/gfx_dma.c\r
+void DmaSlowCell(unsigned int source, unsigned int a, int len, unsigned char inc);\r
+\r
 // cd/memory.c\r
 PICO_INTERNAL void PicoMemSetupCD(void);\r
 unsigned int PicoRead8_mcd_io(unsigned int a);\r
index f9a7f83..a1ceac2 100644 (file)
@@ -175,6 +175,7 @@ typedef enum {
   CHUNK_32X_LAST = CHUNK_32X_EVT,\r
   // add new stuff here\r
   CHUNK_CD_EVT = 50,\r
+  CHUNK_CD_GFX,\r
   //\r
   CHUNK_DEFAULT_COUNT,\r
   CHUNK_CARTHW_ = CHUNK_CARTHW,  // 64 (defined in PicoInt)\r
@@ -258,6 +259,7 @@ static int state_save(void *file)
   unsigned char buff[0x60], buff_z80[Z80_STATE_SIZE];\r
   void *ym2612_regs = YM2612GetRegs();\r
   int ver = 0x0170; // not really used..\r
+  int len;\r
 \r
   areaWrite("PicoSEXT", 1, 8, file);\r
   areaWrite(&ver, 1, 4, file);\r
@@ -305,11 +307,12 @@ static int state_save(void *file)
     CHECKED_WRITE_BUFF(CHUNK_CDD,      Pico_mcd->cdd);\r
     CHECKED_WRITE_BUFF(CHUNK_CDC,      Pico_mcd->cdc);\r
     CHECKED_WRITE_BUFF(CHUNK_SCD,      Pico_mcd->scd);\r
-    CHECKED_WRITE_BUFF(CHUNK_RC,       Pico_mcd->rot_comp);\r
     CHECKED_WRITE_BUFF(CHUNK_MISC_CD,  Pico_mcd->m);\r
     memset(buff, 0, 0x40);\r
     memcpy(buff, pcd_event_times, sizeof(pcd_event_times));\r
     CHECKED_WRITE(CHUNK_CD_EVT, 0x40, buff);\r
+    len = gfx_context_save(buff);\r
+    CHECKED_WRITE(CHUNK_CD_GFX, len, buff);\r
 \r
     if (Pico_mcd->s68k_regs[3] & 4) // convert back\r
       wram_2M_to_1M(Pico_mcd->word_ram2M);\r
@@ -464,7 +467,6 @@ static int state_load(void *file)
       case CHUNK_CDD:      CHECKED_READ_BUFF(Pico_mcd->cdd); break;\r
       case CHUNK_CDC:      CHECKED_READ_BUFF(Pico_mcd->cdc); break;\r
       case CHUNK_SCD:      CHECKED_READ_BUFF(Pico_mcd->scd); break;\r
-      case CHUNK_RC:       CHECKED_READ_BUFF(Pico_mcd->rot_comp); break;\r
       case CHUNK_MISC_CD:  CHECKED_READ_BUFF(Pico_mcd->m); break;\r
 \r
       case CHUNK_CD_EVT:\r
@@ -472,6 +474,11 @@ static int state_load(void *file)
         memcpy(pcd_event_times, buff, sizeof(pcd_event_times));\r
         break;\r
 \r
+      case CHUNK_CD_GFX:\r
+        CHECKED_READ2(0x18, buff);\r
+        gfx_context_load(buff);\r
+        break;\r
+\r
       // 32x stuff\r
 #ifndef NO_32X\r
       case CHUNK_MSH2:\r
index 1e60686..6c876ae 100644 (file)
@@ -8,7 +8,6 @@
  */\r
 \r
 #include "pico_int.h"\r
-#include "cd/gfx_cd.h"\r
 \r
 int line_base_cycles;\r
 extern const unsigned char  hcounts_32[];\r
index 0b2748e..7ec66df 100644 (file)
@@ -509,7 +509,7 @@ CZ80 Z80 interpreter core
 \r
 Reesy & FluBBa\r
 DrZ80, the Z80 interpreter written in ARM assembly.\r
-Homepage: http://reesy.gp32x.de/\r
+Homepage: http://reesy.gp32x.de/ (defunct)\r
 \r
 Tatsuyuki Satoh, Jarek Burczynski, MAME development\r
 software implementation of Yamaha FM sound generator\r
@@ -518,8 +518,11 @@ MAME development
 Texas Instruments SN76489 / SN76496 programmable tone/noise generator\r
 Homepage: http://www.mame.net/\r
 \r
+Eke\r
+CD graphics processor implementation (from Genesis Plus GX)\r
+\r
 Stephane Dallongeville\r
-Gens, MD/Mega CD/32X emulator. Most Sega CD code is based on this emu.\r
+Gens, MD/Mega CD/32X emulator. Some Sega CD code is based on this emu.\r
 #ifdef PSP\r
 \r
 people @ ps2dev.org forums / PSPSDK crew\r
@@ -562,6 +565,14 @@ Additional thanks
 \r
 Changelog\r
 ---------\r
+1.xx (2013-09-)\r
+  + 32X+CD emulation has been implemented.\r
+  + CD graphics processor code has been replaced with much cleaner Eke's\r
+    implamentation from Genesis Plus GX.\r
+  + CD PCM code has been completely rewritten\r
+  * Various CD compatibility issues have been solved. Hopefully no more\r
+    regressions this time.\r
+\r
 1.85 (2013-08-31)\r
   * Lots of 32X compatibility and accuracy improvements. All commercial games\r
     are booting now, but some still have issues.\r
index a87a6b4..3a836e1 100644 (file)
@@ -94,8 +94,8 @@ endif
 # CD
 SRCS_COMMON += $(R)pico/cd/mcd.c $(R)pico/cd/memory.c $(R)pico/cd/sek.c \
        $(R)pico/cd/LC89510.c $(R)pico/cd/cd_sys.c $(R)pico/cd/cd_file.c \
-       $(R)pico/cd/cue.c $(R)pico/cd/gfx_cd.c $(R)pico/cd/misc.c \
-       $(R)pico/cd/pcm.c $(R)pico/cd/buffering.c
+       $(R)pico/cd/cue.c $(R)pico/cd/gfx.c $(R)pico/cd/gfx_dma.c \
+       $(R)pico/cd/misc.c $(R)pico/cd/pcm.c $(R)pico/cd/buffering.c
 # 32X
 ifneq "$(no_32x)" "1"
 SRCS_COMMON += $(R)pico/32x/32x.c $(R)pico/32x/memory.c $(R)pico/32x/draw.c \