32x: initial code (security code passes)
authornotaz <notasas@gmail.com>
Fri, 11 Sep 2009 11:29:19 +0000 (11:29 +0000)
committernotaz <notasas@gmail.com>
Fri, 11 Sep 2009 11:29:19 +0000 (11:29 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@772 be3aeb3a-fb24-0410-a615-afba39da0efa

pico/32x/32x.c [new file with mode: 0644]
pico/32x/memory.c [new file with mode: 0644]
pico/memory.c
pico/pico.c
pico/pico.h
pico/pico_int.h
platform/linux/Makefile
platform/linux/port_config.h

diff --git a/pico/32x/32x.c b/pico/32x/32x.c
new file mode 100644 (file)
index 0000000..dc881a9
--- /dev/null
@@ -0,0 +1,31 @@
+#include "../pico_int.h"
+
+struct Pico32x Pico32x;
+
+void Pico32xStartup(void)
+{
+  elprintf(EL_STATUS|EL_32X, "32X startup");
+
+  PicoAHW |= PAHW_32X;
+  PicoMemSetup32x();
+
+  // probably should only done on power
+//  memset(&Pico32x, 0, sizeof(Pico32x));
+
+  if (!Pico.m.pal)
+    Pico32x.vdp_regs[0] |= 0x8000;
+
+  // prefill checksum
+  Pico32x.regs[0x28/2] = *(unsigned short *)(Pico.rom + 0x18e);
+}
+
+void Pico32xInit(void)
+{
+  // XXX: mv
+  Pico32x.regs[0] = 0x0082;
+}
+
+void PicoReset32x(void)
+{
+}
+
diff --git a/pico/32x/memory.c b/pico/32x/memory.c
new file mode 100644 (file)
index 0000000..324c789
--- /dev/null
@@ -0,0 +1,252 @@
+#include "../pico_int.h"
+#include "../memory.h"
+
+static const char str_mars[] = "MARS";
+
+struct Pico32xMem {
+  u8 sdram[0x40000];
+  u8 dram[0x40000]; // AKA fb
+  u8 m68k_rom[M68K_BANK_SIZE]; // 0x100
+};
+
+static struct Pico32xMem *Pico32xMem;
+
+static u32 p32x_reg_read16(u32 a)
+{
+  a &= 0x3e;
+
+  return Pico32x.regs[a / 2];
+}
+
+static void p32x_reg_write16(u32 a, u32 d)
+{
+  a &= 0x3e;
+
+  if (a == 0 && !(Pico32x.regs[0] & 1)) {
+    Pico32x.regs[0] |= 1;
+    Pico32xStartup();
+    return;
+  }
+}
+
+static void p32x_reg_write8(u32 a, u32 d)
+{
+  a &= 0x3f;
+
+  if (a == 1 && !(Pico32x.regs[0] & 1)) {
+    Pico32x.regs[0] |= 1;
+    Pico32xStartup();
+    return;
+  }
+}
+
+// VDP regs
+static u32 p32x_vdp_read16(u32 a)
+{
+  a &= 0x0e;
+
+  return Pico32x.vdp_regs[a / 2];
+}
+
+static void p32x_vdp_write16(u32 a, u32 d)
+{
+  a &= 0x0e;
+
+  switch (a) {
+    case 0x0a:
+      Pico32x.pending_fb = d & 1;
+      if (Pico.video.status & 8) {
+        Pico32x.vdp_regs[0x0a/2] &= ~1;
+        Pico32x.vdp_regs[0x0a/2] |= d & 1;
+      }
+      break;
+  }
+}
+
+static void p32x_vdp_write8(u32 a, u32 d)
+{
+  a &= 0x0f;
+
+  switch (a) {
+    case 0x0b:
+      Pico32x.pending_fb = d & 1;
+      if (Pico.video.status & 8) {
+        Pico32x.vdp_regs[0x0a/2] &= ~1;
+        Pico32x.vdp_regs[0x0a/2] |= d & 1;
+      }
+      break;
+  }
+}
+
+// default 32x handlers
+u32 PicoRead8_32x(u32 a)
+{
+  u32 d = 0;
+  if ((a & 0xffc0) == 0x5100) { // a15100
+    d = p32x_reg_read16(a);
+    goto out_16to8;
+  }
+
+  if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) {
+    d = p32x_vdp_read16(a);
+    goto out_16to8;
+  }
+
+  if ((a & 0xfffc) == 0x30ec) { // a130ec
+    d = str_mars[a & 3];
+    goto out;
+  }
+
+  elprintf(EL_UIO, "m68k unmapped r8  [%06x] @%06x", a, SekPc);
+  return d;
+
+out_16to8:
+  if (a & 1)
+    d &= 0xff;
+  else
+    d >>= 8;
+
+out:
+  elprintf(EL_32X, "m68k 32x r8  [%06x]   %02x @%06x", a, d, SekPc);
+  return d;
+}
+
+u32 PicoRead16_32x(u32 a)
+{
+  u32 d = 0;
+  if ((a & 0xffc0) == 0x5100) { // a15100
+    d = p32x_reg_read16(a);
+    goto out;
+  }
+
+  if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180
+    d = p32x_vdp_read16(a);
+    goto out;
+  }
+
+  if ((a & 0xfffc) == 0x30ec) { // a130ec
+    d = !(a & 2) ? ('M'<<8)|'A' : ('R'<<8)|'S';
+    goto out;
+  }
+
+  elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc);
+  return d;
+
+out:
+  elprintf(EL_32X, "m68k 32x r16 [%06x] %04x @%06x", a, d, SekPc);
+  return d;
+}
+
+void PicoWrite8_32x(u32 a, u32 d)
+{
+  if ((a & 0xfc00) == 0x5000)
+    elprintf(EL_32X, "m68k 32x w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);
+
+  if ((a & 0xffc0) == 0x5100) { // a15100
+    p32x_reg_write8(a, d);
+    return;
+  }
+
+  if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180
+    p32x_vdp_write8(a, d);
+    return;
+  }
+
+  elprintf(EL_UIO, "m68k unmapped w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);
+}
+
+void PicoWrite16_32x(u32 a, u32 d)
+{
+  if ((a & 0xfc00) == 0x5000)
+    elprintf(EL_UIO, "m68k 32x w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
+
+  if ((a & 0xffc0) == 0x5100) { // a15100
+    p32x_reg_write16(a, d);
+    return;
+  }
+
+  if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180
+    p32x_vdp_write16(a, d);
+    return;
+  }
+
+  elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
+}
+
+// hint vector is writeable
+static void PicoWrite8_hint(u32 a, u32 d)
+{
+  if ((a & 0xfffc) == 0x0070) {
+    Pico32xMem->m68k_rom[a ^ 1] = d;
+    return;
+  }
+
+  elprintf(EL_UIO, "m68k unmapped w8  [%06x]   %02x @%06x", a, d & 0xff, SekPc);
+}
+
+static void PicoWrite16_hint(u32 a, u32 d)
+{
+  if ((a & 0xfffc) == 0x0070) {
+    ((u16 *)Pico32xMem->m68k_rom)[a/2] = d;
+    return;
+  }
+
+  elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
+}
+
+#define HWSWAP(x) (((x) << 16) | ((x) >> 16))
+void PicoMemSetup32x(void)
+{
+  unsigned short *ps;
+  unsigned int *pl;
+  unsigned int rs, rs1;
+  int i;
+
+  Pico32xMem = calloc(1, sizeof(*Pico32xMem));
+  if (Pico32xMem == NULL) {
+    elprintf(EL_STATUS, "OOM");
+    return;
+  }
+
+  // generate 68k ROM
+  ps = (unsigned short *)Pico32xMem->m68k_rom;
+  pl = (unsigned int *)Pico32xMem->m68k_rom;
+  for (i = 1; i < 0xc0/4; i++)
+    pl[i] = HWSWAP(0x880200 + i * 6);
+
+  // fill with nops
+  for (i = 0xc0/2; i < 0x100/2; i++)
+    ps[i] = 0x4e71;
+
+  ps[0xc0/2] = 0x46fc;
+  ps[0xc2/2] = 0x2700; // move #0x2700,sr
+  ps[0xfe/2] = 0x60fe; // jump to self
+
+  // fill remaining mem with ROM
+  memcpy(Pico32xMem->m68k_rom + 0x100, Pico.rom + 0x100, M68K_BANK_SIZE - 0x100);
+
+  // cartridge area becomes unmapped
+  // XXX: we take the easy way and don't unmap ROM,
+  // so that we can avoid handling the RV bit.
+  // m68k_map_unmap(0x000000, 0x3fffff);
+
+  // MD ROM area
+  cpu68k_map_set(m68k_read8_map,   0x000000, M68K_BANK_SIZE - 1, Pico32xMem->m68k_rom, 0);
+  cpu68k_map_set(m68k_read16_map,  0x000000, M68K_BANK_SIZE - 1, Pico32xMem->m68k_rom, 0);
+  cpu68k_map_set(m68k_write8_map,  0x000000, M68K_BANK_SIZE - 1, PicoWrite8_hint, 1); // TODO verify
+  cpu68k_map_set(m68k_write16_map, 0x000000, M68K_BANK_SIZE - 1, PicoWrite16_hint, 1);
+
+  // 32X ROM (unbanked, XXX: consider mirroring?)
+  rs1 = rs = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK;
+  if (rs1 > 0x80000)
+    rs1 = 0x80000;
+  cpu68k_map_set(m68k_read8_map,   0x880000, 0x880000 + rs1 - 1, Pico.rom, 0);
+  cpu68k_map_set(m68k_read16_map,  0x880000, 0x880000 + rs1 - 1, Pico.rom, 0);
+
+  // 32X ROM (banked)
+  if (rs > 0x100000)
+    rs = 0x100000;
+  cpu68k_map_set(m68k_read8_map,   0x900000, 0x900000 + rs - 1, Pico.rom, 0);
+  cpu68k_map_set(m68k_read16_map,  0x900000, 0x900000 + rs - 1, Pico.rom, 0);
+}
+
index da73961..d2dced3 100644 (file)
@@ -501,6 +501,11 @@ u32 PicoRead8_io(u32 a)
     goto end;\r
   }\r
 \r
+  if (!(PicoOpt & POPT_DIS_32X)) {\r
+    d = PicoRead8_32x(a);\r
+    goto end;\r
+  }\r
+\r
   d = m68k_unmapped_read8(a);\r
 end:\r
   return d;\r
@@ -529,6 +534,11 @@ u32 PicoRead16_io(u32 a)
     goto end;\r
   }\r
 \r
+  if (!(PicoOpt & POPT_DIS_32X)) {\r
+    d = PicoRead16_32x(a);\r
+    goto end;\r
+  }\r
+\r
   d = m68k_unmapped_read16(a);\r
 end:\r
   return d;\r
@@ -554,6 +564,11 @@ void PicoWrite8_io(u32 a, u32 d)
     Pico.m.sram_reg |= (u8)(d & 3);\r
     return;\r
   }\r
+  if (!(PicoOpt & POPT_DIS_32X)) {\r
+    PicoWrite8_32x(a, d);\r
+    return;\r
+  }\r
+\r
   m68k_unmapped_write8(a, d);\r
 }\r
 \r
@@ -577,6 +592,10 @@ void PicoWrite16_io(u32 a, u32 d)
     Pico.m.sram_reg |= (u8)(d & 3);\r
     return;\r
   }\r
+  if (!(PicoOpt & POPT_DIS_32X)) {\r
+    PicoWrite16_32x(a, d);\r
+    return;\r
+  }\r
   m68k_unmapped_write16(a, d);\r
 }\r
 \r
index f2da10b..aa2be38 100644 (file)
@@ -40,6 +40,7 @@ void PicoInit(void)
 \r
   PicoInitMCD();\r
   PicoSVPInit();\r
+  Pico32xInit();\r
 }\r
 \r
 // to be called once on emu exit\r
@@ -187,6 +188,11 @@ int PicoReset(void)
   if (!(PicoOpt & POPT_DIS_IDLE_DET))\r
     SekInitIdleDet();\r
 \r
+  if (!(PicoOpt & POPT_DIS_32X)) {\r
+    PicoReset32x();\r
+    return 0;\r
+  }\r
+\r
   // reset sram state; enable sram access by default if it doesn't overlap with ROM\r
   Pico.m.sram_reg = 0;\r
   if ((SRam.flags & SRF_EEPROM) || Pico.romsize <= SRam.start)\r
index 45e948f..8b7d032 100644 (file)
@@ -55,7 +55,9 @@ extern void emu_video_mode_change(int start_line, int line_count, int is_32cols)
 #define POPT_EN_SVP_DRC     (1<<17)\r
 #define POPT_DIS_SPRITE_LIM (1<<18)\r
 #define POPT_DIS_IDLE_DET   (1<<19)\r
+#define POPT_DIS_32X        (1<<20)\r
 extern int PicoOpt; // bitfield\r
+\r
 #define PAHW_MCD  (1<<0)\r
 #define PAHW_32X  (1<<1)\r
 #define PAHW_SVP  (1<<2)\r
index cb12bc1..85f2506 100644 (file)
@@ -257,15 +257,15 @@ struct PicoMisc
   unsigned char pal;           // 08 1=PAL 0=NTSC\r
   unsigned char sram_reg;      // 09 SRAM reg. See SRR_* below\r
   unsigned short z80_bank68k;  // 0a\r
-  unsigned short z80_lastaddr; // this is for Z80 faking\r
-  unsigned char  pad0;\r
+  unsigned short pad0;\r
+  unsigned char  pad1;\r
   unsigned char  z80_reset;    // z80 reset held\r
   unsigned char  padDelay[2];  // 10 gamepad phase time outs, so we count a delay\r
   unsigned short eeprom_addr;  // EEPROM address register\r
   unsigned char  eeprom_cycle; // EEPROM cycle number\r
   unsigned char  eeprom_slave; // EEPROM slave word for X24C02 and better SRAMs\r
   unsigned char  eeprom_status;\r
-  unsigned char  pad1;\r
+  unsigned char  pad2;\r
   unsigned short dma_xfers;    // 18\r
   unsigned char  eeprom_wb[2]; // EEPROM latch/write buffer\r
   unsigned int  frame_count;   // 1c for movies and idle det\r
@@ -385,8 +385,17 @@ typedef struct
        Rot_Comp rot_comp;\r
 } mcd_state;\r
 \r
+// XXX: this will need to be reworked for cart+cd support.\r
 #define Pico_mcd ((mcd_state *)Pico.rom)\r
 \r
+// 32X\r
+struct Pico32x\r
+{\r
+  unsigned short regs[0x20];\r
+  unsigned short vdp_regs[0x10];\r
+  unsigned char pending_fb;\r
+  unsigned char pad[3];\r
+};\r
 \r
 // area.c\r
 PICO_INTERNAL void PicoAreaPackCpu(unsigned char *cpu, int is_sub);\r
@@ -576,6 +585,19 @@ void PicoMemSetupMS(void);
 void PicoFrameMS(void);\r
 void PicoFrameDrawOnlyMS(void);\r
 \r
+// 32x/32x.c\r
+extern struct Pico32x Pico32x;\r
+void Pico32xInit(void);\r
+void Pico32xStartup(void);\r
+void PicoReset32x(void);\r
+\r
+// 32x/memory.c\r
+unsigned int PicoRead8_32x(unsigned int a);\r
+unsigned int PicoRead16_32x(unsigned int a);\r
+void PicoWrite8_32x(unsigned int a, unsigned int d);\r
+void PicoWrite16_32x(unsigned int a, unsigned int d);\r
+void PicoMemSetup32x(void);\r
+\r
 /* avoid dependency on newer glibc */\r
 static __inline int isspace_(int c)\r
 {\r
@@ -606,6 +628,7 @@ static __inline int isspace_(int c)
 #define EL_IDLE    0x00010000 /* idle loop det. */\r
 #define EL_CDREGS  0x00020000 /* MCD: register access */\r
 #define EL_CDREG3  0x00040000 /* MCD: register 3 only */\r
+#define EL_32X     0x00080000\r
 \r
 #define EL_STATUS  0x40000000 /* status messages */\r
 #define EL_ANOMALY 0x80000000 /* some unexpected conditions (during emulation) */\r
index 3ec56b9..e6a94a2 100644 (file)
@@ -39,6 +39,8 @@ OBJS += pico/area.o pico/cart.o pico/memory.o pico/pico.o pico/sek.o \
 OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \
        pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \
        pico/cd/area.o pico/cd/misc.o pico/cd/pcm.o pico/cd/buffering.o
+# Pico - 32X
+OBJS += pico/32x/32x.o pico/32x/memory.o
 # Pico - Pico
 OBJS += pico/pico/pico.o pico/pico/memory.o pico/pico/xpcm.o
 # Pico - sound
@@ -81,7 +83,7 @@ CFLAGS += $(addprefix -D,$(DEFINES))
 vpath %.c = ../..
 
 DIRS = platform platform/gp2x platform/common pico pico/cd pico/pico pico/sound pico/carthw/svp \
-       zlib unzip cpu cpu/musashi cpu/fame cpu/mz80 cpu/cz80
+       pico/32x zlib unzip cpu cpu/musashi cpu/fame cpu/mz80 cpu/cz80
 
 all: mkdirs PicoDrive
 clean: tidy
index fc2e118..152d1a8 100644 (file)
@@ -26,7 +26,7 @@
 #define SIMPLE_WRITE_SOUND     0
 #define mix_32_to_16l_stereo_lvl mix_32_to_16l_stereo
 
-#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_UIO|EL_IDLE)//|EL_VDPDMA|EL_HVCNT|EL_ASVDP)//|EL_SVP)
+#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_UIO|EL_IDLE|EL_32X)//|EL_VDPDMA|EL_HVCNT|EL_ASVDP)//|EL_SVP)
 // EL_VDPDMA|EL_ASVDP|EL_SR) // |EL_BUSREQ|EL_Z80BNK)
 
 //#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)