updated bords/mappers/stuff to 0.98.15, lots of them got broken, asmcore support...
[fceu.git] / boards / tengen.c
diff --git a/boards/tengen.c b/boards/tengen.c
new file mode 100644 (file)
index 0000000..84f050a
--- /dev/null
@@ -0,0 +1,198 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ *  Copyright (C) 2002 Xodnizel
+ *
+ * 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 cmd,mir,rmode,IRQmode;
+static uint8 DRegs[11];
+static uint8 IRQCount,IRQa,IRQLatch;
+
+static SFORMAT Rambo_StateRegs[]={
+        {&cmd, 1, "CMD"},
+        {&mir, 1, "MIR"},
+        {&rmode, 1, "RMOD"},
+        {&IRQmode, 1, "IRQM"},
+        {&IRQCount, 1, "IRQC"},
+        {&IRQa, 1, "IRQA"},
+        {&IRQLatch, 1, "IRQL"},
+        {DRegs, 11, "DREG"},
+        {0}
+};
+
+static void FP_FASTAPASS(2) (*setchr1wrap)(unsigned int A, unsigned int V);
+static int nomirror;
+
+static void FP_FASTAPASS(1) RAMBO1_IRQHook(int a)
+{
+ static int smallcount;
+ if(!IRQmode) return;
+
+ smallcount+=a;
+ while(smallcount>=4)
+ {
+  smallcount-=4;
+  IRQCount--;
+  if(IRQCount==0xFF)
+      if(IRQa) X6502_IRQBegin(FCEU_IQEXT);
+ }
+}
+
+static void RAMBO1_hb(void)
+{
+      if(IRQmode) return;
+  if(scanline==240) return;        /* hmm.  Maybe that should be an mmc3-only call in fce.c. */
+      rmode=0;
+      IRQCount--;
+      if(IRQCount==0xFF)
+      {
+       if(IRQa)
+       {
+        rmode = 1;
+        X6502_IRQBegin(FCEU_IQEXT);
+       }
+      }
+}
+
+static void Synco(void)
+{
+ int x;
+
+ if(cmd&0x20)
+ {
+  setchr1wrap(0x0000,DRegs[0]);
+  setchr1wrap(0x0800,DRegs[1]);
+  setchr1wrap(0x0400,DRegs[8]);
+  setchr1wrap(0x0c00,DRegs[9]);
+ }
+ else
+ {
+  setchr1wrap(0x0000,(DRegs[0]&0xFE));
+  setchr1wrap(0x0400,(DRegs[0]&0xFE)|1);
+  setchr1wrap(0x0800,(DRegs[1]&0xFE));
+  setchr1wrap(0x0C00,(DRegs[1]&0xFE)|1);
+ }
+
+ for(x=0;x<4;x++)
+  setchr1wrap(0x1000+x*0x400,DRegs[2+x]);
+
+ setprg8(0x8000,DRegs[6]);
+ setprg8(0xA000,DRegs[7]);
+
+ setprg8(0xC000,DRegs[10]);
+}
+
+
+static DECLFW(RAMBO1_write)
+{
+ switch(A&0xF001)
+  {
+    case 0xa000: mir=V&1;
+                 if(!nomirror)
+                   setmirror(mir^1);
+                 break;
+    case 0x8000: cmd = V;
+                 break;
+    case 0x8001: if((cmd&0xF)<10)
+                     DRegs[cmd&0xF]=V;
+                    else if((cmd&0xF)==0xF)
+                     DRegs[10]=V;
+                    Synco();
+                    break;
+    case 0xc000: IRQLatch=V;
+                 if(rmode==1)
+                   IRQCount=IRQLatch;
+                 break;
+    case 0xc001: rmode=1;
+                    IRQCount=IRQLatch;
+                    IRQmode=V&1;
+                    break;
+    case 0xE000: IRQa=0;
+                 X6502_IRQEnd(FCEU_IQEXT);
+                 if(rmode==1)
+                   IRQCount=IRQLatch;
+                 break;
+    case 0xE001: IRQa=1;
+                 if(rmode==1)
+                   IRQCount=IRQLatch;
+                    break;
+  }
+}
+
+static void RAMBO1_Restore(int version)
+{
+ Synco();
+ if(!nomirror)
+  setmirror(mir^1);
+}
+
+static void RAMBO1_init(void)
+{
+        int x;
+        for(x=0;x<11;x++)
+         DRegs[x]=~0;
+  cmd=mir=0;
+        if(!nomirror)
+         setmirror(1);
+        Synco();
+        GameHBIRQHook=RAMBO1_hb;
+        MapIRQHook=RAMBO1_IRQHook;
+        GameStateRestore=RAMBO1_Restore;
+        SetWriteHandler(0x8000,0xffff,RAMBO1_write);
+        AddExState(Rambo_StateRegs, ~0, 0, 0);
+}
+
+static void FP_FASTAPASS(2) CHRWrap(unsigned int A, unsigned int V)
+{
+ setchr1(A,V);
+}
+
+void Mapper64_init(void)
+{
+        setchr1wrap=CHRWrap;
+        nomirror=0;
+        RAMBO1_init();
+}
+
+static int MirCache[8];
+static unsigned int PPUCHRBus;
+
+static void FP_FASTAPASS(2) MirWrap(unsigned int A, unsigned int V)
+{
+ MirCache[A>>10]=(V>>7)&1;
+ if(PPUCHRBus==(A>>10))
+  setmirror(MI_0+((V>>7)&1));
+ setchr1(A,V);
+}
+
+static void FP_FASTAPASS(1) MirrorFear(uint32 A)
+{
+ A&=0x1FFF;
+ A>>=10;
+ PPUCHRBus=A;
+ setmirror(MI_0+MirCache[A]);
+}
+
+void Mapper158_init(void)
+{
+        setchr1wrap=MirWrap;
+        PPU_hook=MirrorFear;
+        nomirror=1;
+        RAMBO1_init();
+}