merge mapper code from FCEUX
[fceu.git] / boards / sl1632.c
index 9e99722..18895fb 100644 (file)
-/* FCE Ultra - NES/Famicom Emulator
- *
- * Copyright notice for this file:
- *  Copyright (C) 2005 CaH4e3
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "mapinc.h"
-
-static uint8 chrcmd[8], prg0, prg1, brk, mirr;
-static uint8 reg[8], cmd;
-static uint8 IRQCount,IRQLatch,IRQa;
-static uint8 IRQReload;
-static SFORMAT StateRegs[]=
-{
-  {reg, 8, "MMCREG"},
-  {&cmd, 1, "MMCCMD"},
-  {chrcmd, 8, "CHRCMD"},
-  {&prg0, 1, "PRG0"},
-  {&prg1, 1, "PRG1"},
-  {&brk, 1, "BRK"},
-  {&mirr, 1, "MIRR"},
-  {&IRQReload, 1, "IRQR"},
-  {&IRQCount, 1, "IRQC"},
-  {&IRQLatch, 1, "IRQL"},
-  {&IRQa, 1, "IRQA"},
-  {0}
-};
-
-static void Sync(void)
-{
-//  if(brk&2)
-//  {
-//    setprg16(0x8000,~0);
-//    setprg16(0xC000,~0); 
-//  }
-//  else
-  {
-    setprg8(0x8000,prg0);
-    setprg8(0xA000,prg1);
-  }
-  int i;
-  for(i=0; i<8; i++)
-     setchr1(i<<10,chrcmd[i]);
-  setmirror(mirr^1);
-}
-
-static void Sync2(void)
-{
-  setprg8(0x8000,reg[6]&0x3F);
-  setprg8(0xA000,reg[7]&0x3F);
-  setchr2(0x0000,reg[0]>>1);
-  setchr2(0x8000,reg[1]>>1);
-  setchr1(0x1000,reg[2]);
-  setchr1(0x1400,reg[3]);
-  setchr1(0x1800,reg[4]);
-  setchr1(0x1C00,reg[5]);
-  setmirror(mirr^1);
-}
-
-static DECLFW(UNLSL1632CMDWrite)
-{
-  FCEU_printf("bs %04x %02x\n",A,V);     
-//  if((A&0xA131)==0xA131) brk=V;
-  if((A&0xA131)==0xA131) brk=V;
-  if(brk==2)
-  {
-  switch(A&0xE001)
-  {
-    case 0x8000: cmd=V&7; break;
-    case 0x8001: reg[cmd]=V; Sync(); break;
-    case 0xA000: mirr=V&1; break;
-    case 0xC000: IRQLatch=V; break;
-    case 0xC001: IRQReload=1; break;
-    case 0xE000: X6502_IRQEnd(FCEU_IQEXT); IRQa=0; break;
-    case 0xE001: IRQa=1; break;
-  }
-  Sync2();
-  }
-  else
-  {
-  switch(A&0xF003)
-  {
-    case 0x8000: prg0=V; break;
-    case 0xA000: prg1=V; break;
-    case 0x9000: mirr=V&1; break;
-    case 0xB000: chrcmd[0]=(chrcmd[0]&0xF0)|(V&0x0F); break;
-    case 0xB001: chrcmd[0]=(chrcmd[0]&0x0F)|(V<<4); break;
-    case 0xB002: chrcmd[1]=(chrcmd[1]&0xF0)|(V&0x0F); break;
-    case 0xB003: chrcmd[1]=(chrcmd[1]&0x0F)|(V<<4); break;
-    case 0xC000: chrcmd[2]=(chrcmd[2]&0xF0)|(V&0x0F); break;
-    case 0xC001: chrcmd[2]=(chrcmd[2]&0x0F)|(V<<4); break;
-    case 0xC002: chrcmd[3]=(chrcmd[3]&0xF0)|(V&0x0F); break;
-    case 0xC003: chrcmd[3]=(chrcmd[3]&0x0F)|(V<<4); break;
-    case 0xD000: chrcmd[4]=(chrcmd[4]&0xF0)|(V&0x0F); break;
-    case 0xD001: chrcmd[4]=(chrcmd[4]&0x0F)|(V<<4); break;
-    case 0xD002: chrcmd[5]=(chrcmd[5]&0xF0)|(V&0x0F); break;
-    case 0xD003: chrcmd[5]=(chrcmd[5]&0x0F)|(V<<4); break;
-    case 0xE000: chrcmd[6]=(chrcmd[6]&0xF0)|(V&0x0F); break;
-    case 0xE001: chrcmd[6]=(chrcmd[6]&0x0F)|(V<<4); break;
-    case 0xE002: chrcmd[7]=(chrcmd[7]&0xF0)|(V&0x0F); break;
-    case 0xE003: chrcmd[7]=(chrcmd[7]&0x0F)|(V<<4); break;
-  }
-  Sync();
-  }
-}
-
-static void UNLSL1632IRQHook(void)
-{
- int count = IRQCount;
- if((scanline==128)&&IRQa)X6502_IRQBegin(FCEU_IQEXT);
- if(!count || IRQReload)
- {
-    IRQCount = IRQLatch;
-    IRQReload = 0;
- }
- else
-    IRQCount--;
- if(!IRQCount)
- {
-    if(IRQa)
-    {
-       X6502_IRQBegin(FCEU_IQEXT);
-    }
- }
-}
-
-static void StateRestore(int version)
-{
-  Sync();
-}
-
-static void UNLSL1632Power(void)
-{
-  setprg16(0xC000,~0);
-  SetReadHandler(0x8000,0xFFFF,CartBR);
-  SetWriteHandler(0x8000,0xFFFF,UNLSL1632CMDWrite);
-}
-
-void UNLSL1632_Init(CartInfo *info)
-{
-  info->Power=UNLSL1632Power;
-  GameHBIRQHook2=UNLSL1632IRQHook;
-  GameStateRestore=StateRestore;
-  AddExState(&StateRegs, ~0, 0, 0);
-}
+/* FCE Ultra - NES/Famicom Emulator\r
+ *\r
+ * Copyright notice for this file:\r
+ *  Copyright (C) 2005 CaH4e3\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r
+ */\r
+\r
+#include "mapinc.h"\r
+#include "mmc3.h"\r
+\r
+// brk is a system call in *nix, and is an illegal variable name - soules\r
+static uint8 chrcmd[8], prg0, prg1, bbrk, mirr, swap;\r
+static SFORMAT StateRegs[]=\r
+{\r
+  {chrcmd, 8, "CHRCMD"},\r
+  {&prg0, 1, "PRG0"},\r
+  {&prg1, 1, "PRG1"},\r
+  {&bbrk, 1, "BRK"},\r
+  {&mirr, 1, "MIRR"},\r
+  {&swap, 1, "SWAP"},\r
+  {0}\r
+};\r
+\r
+static void Sync(void)\r
+{\r
+  int i;\r
+  setprg8(0x8000,prg0);\r
+  setprg8(0xA000,prg1);\r
+  setprg8(0xC000,~1);\r
+  setprg8(0xE000,~0);\r
+  for(i=0; i<8; i++)\r
+     setchr1(i<<10,chrcmd[i]);\r
+  setmirror(mirr^1);\r
+}\r
+\r
+static void UNLSL1632CW(uint32 A, uint8 V)\r
+{\r
+  int cbase=(MMC3_cmd&0x80)<<5;\r
+  int page0=(bbrk&0x08)<<5;\r
+  int page1=(bbrk&0x20)<<3;\r
+  int page2=(bbrk&0x80)<<1;\r
+  setchr1(cbase^0x0000,page0|(DRegBuf[0]&(~1)));\r
+  setchr1(cbase^0x0400,page0|DRegBuf[0]|1);\r
+  setchr1(cbase^0x0800,page0|(DRegBuf[1]&(~1)));\r
+  setchr1(cbase^0x0C00,page0|DRegBuf[1]|1);\r
+  setchr1(cbase^0x1000,page1|DRegBuf[2]);\r
+  setchr1(cbase^0x1400,page1|DRegBuf[3]);\r
+  setchr1(cbase^0x1800,page2|DRegBuf[4]);\r
+  setchr1(cbase^0x1c00,page2|DRegBuf[5]);\r
+}\r
+\r
+static DECLFW(UNLSL1632CMDWrite)\r
+{\r
+  if(A==0xA131)\r
+  {\r
+    bbrk=V;\r
+  }\r
+  if(bbrk&2)\r
+  {\r
+    FixMMC3PRG(MMC3_cmd);\r
+    FixMMC3CHR(MMC3_cmd);\r
+    if(A<0xC000)\r
+      MMC3_CMDWrite(A,V);\r
+    else\r
+      MMC3_IRQWrite(A,V);\r
+  }\r
+  else\r
+  {\r
+    if((A>=0xB000)&&(A<=0xE003))\r
+    {\r
+      int ind=((((A&2)|(A>>10))>>1)+2)&7;\r
+      int sar=((A&1)<<2);\r
+      chrcmd[ind]=(chrcmd[ind]&(0xF0>>sar))|((V&0x0F)<<sar);\r
+    }\r
+    else\r
+      switch(A&0xF003)\r
+      {\r
+        case 0x8000: prg0=V; break;\r
+        case 0xA000: prg1=V; break;\r
+        case 0x9000: mirr=V&1; break;\r
+      }\r
+    Sync();\r
+  }\r
+}\r
+\r
+static void StateRestore(int version)\r
+{\r
+  if(bbrk&2)\r
+  {\r
+    FixMMC3PRG(MMC3_cmd);\r
+    FixMMC3CHR(MMC3_cmd);\r
+  }\r
+  else\r
+    Sync();\r
+}\r
+\r
+static void UNLSL1632Power(void)\r
+{\r
+  GenMMC3Power();\r
+  SetReadHandler(0x8000,0xFFFF,CartBR);\r
+  SetWriteHandler(0x4100,0xFFFF,UNLSL1632CMDWrite);\r
+}\r
+\r
+void UNLSL1632_Init(CartInfo *info)\r
+{\r
+  GenMMC3_Init(info, 256, 512, 0, 0);\r
+  cwrap=UNLSL1632CW;\r
+  info->Power=UNLSL1632Power;\r
+  GameStateRestore=StateRestore;\r
+  AddExState(&StateRegs, ~0, 0, 0);\r
+}\r