updated bords/mappers/stuff to 0.98.15, lots of them got broken, asmcore support...
[fceu.git] / boards / tengen.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Xodnizel
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "mapinc.h"
22
23 static uint8 cmd,mir,rmode,IRQmode;
24 static uint8 DRegs[11];
25 static uint8 IRQCount,IRQa,IRQLatch;
26
27 static SFORMAT Rambo_StateRegs[]={
28         {&cmd, 1, "CMD"},
29         {&mir, 1, "MIR"},
30         {&rmode, 1, "RMOD"},
31         {&IRQmode, 1, "IRQM"},
32         {&IRQCount, 1, "IRQC"},
33         {&IRQa, 1, "IRQA"},
34         {&IRQLatch, 1, "IRQL"},
35         {DRegs, 11, "DREG"},
36         {0}
37 };
38
39 static void FP_FASTAPASS(2) (*setchr1wrap)(unsigned int A, unsigned int V);
40 static int nomirror;
41
42 static void FP_FASTAPASS(1) RAMBO1_IRQHook(int a)
43 {
44  static int smallcount;
45  if(!IRQmode) return;
46
47  smallcount+=a;
48  while(smallcount>=4)
49  {
50   smallcount-=4;
51   IRQCount--;
52   if(IRQCount==0xFF)
53       if(IRQa) X6502_IRQBegin(FCEU_IQEXT);
54  }
55 }
56
57 static void RAMBO1_hb(void)
58 {
59       if(IRQmode) return;
60   if(scanline==240) return;        /* hmm.  Maybe that should be an mmc3-only call in fce.c. */
61       rmode=0;
62       IRQCount--;
63       if(IRQCount==0xFF)
64       {
65        if(IRQa)
66        {
67         rmode = 1;
68         X6502_IRQBegin(FCEU_IQEXT);
69        }
70       }
71 }
72
73 static void Synco(void)
74 {
75  int x;
76
77  if(cmd&0x20)
78  {
79   setchr1wrap(0x0000,DRegs[0]);
80   setchr1wrap(0x0800,DRegs[1]);
81   setchr1wrap(0x0400,DRegs[8]);
82   setchr1wrap(0x0c00,DRegs[9]);
83  }
84  else
85  {
86   setchr1wrap(0x0000,(DRegs[0]&0xFE));
87   setchr1wrap(0x0400,(DRegs[0]&0xFE)|1);
88   setchr1wrap(0x0800,(DRegs[1]&0xFE));
89   setchr1wrap(0x0C00,(DRegs[1]&0xFE)|1);
90  }
91
92  for(x=0;x<4;x++)
93   setchr1wrap(0x1000+x*0x400,DRegs[2+x]);
94
95  setprg8(0x8000,DRegs[6]);
96  setprg8(0xA000,DRegs[7]);
97
98  setprg8(0xC000,DRegs[10]);
99 }
100
101
102 static DECLFW(RAMBO1_write)
103 {
104  switch(A&0xF001)
105   {
106     case 0xa000: mir=V&1;
107                  if(!nomirror)
108                    setmirror(mir^1);
109                  break;
110     case 0x8000: cmd = V;
111                  break;
112     case 0x8001: if((cmd&0xF)<10)
113                      DRegs[cmd&0xF]=V;
114                     else if((cmd&0xF)==0xF)
115                      DRegs[10]=V;
116                     Synco();
117                     break;
118     case 0xc000: IRQLatch=V;
119                  if(rmode==1)
120                    IRQCount=IRQLatch;
121                  break;
122     case 0xc001: rmode=1;
123                     IRQCount=IRQLatch;
124                     IRQmode=V&1;
125                     break;
126     case 0xE000: IRQa=0;
127                  X6502_IRQEnd(FCEU_IQEXT);
128                  if(rmode==1)
129                    IRQCount=IRQLatch;
130                  break;
131     case 0xE001: IRQa=1;
132                  if(rmode==1)
133                    IRQCount=IRQLatch;
134                     break;
135   }
136 }
137
138 static void RAMBO1_Restore(int version)
139 {
140  Synco();
141  if(!nomirror)
142   setmirror(mir^1);
143 }
144
145 static void RAMBO1_init(void)
146 {
147         int x;
148         for(x=0;x<11;x++)
149          DRegs[x]=~0;
150   cmd=mir=0;
151         if(!nomirror)
152          setmirror(1);
153         Synco();
154         GameHBIRQHook=RAMBO1_hb;
155         MapIRQHook=RAMBO1_IRQHook;
156         GameStateRestore=RAMBO1_Restore;
157         SetWriteHandler(0x8000,0xffff,RAMBO1_write);
158         AddExState(Rambo_StateRegs, ~0, 0, 0);
159 }
160
161 static void FP_FASTAPASS(2) CHRWrap(unsigned int A, unsigned int V)
162 {
163  setchr1(A,V);
164 }
165
166 void Mapper64_init(void)
167 {
168         setchr1wrap=CHRWrap;
169         nomirror=0;
170         RAMBO1_init();
171 }
172
173 static int MirCache[8];
174 static unsigned int PPUCHRBus;
175
176 static void FP_FASTAPASS(2) MirWrap(unsigned int A, unsigned int V)
177 {
178  MirCache[A>>10]=(V>>7)&1;
179  if(PPUCHRBus==(A>>10))
180   setmirror(MI_0+((V>>7)&1));
181  setchr1(A,V);
182 }
183
184 static void FP_FASTAPASS(1) MirrorFear(uint32 A)
185 {
186  A&=0x1FFF;
187  A>>=10;
188  PPUCHRBus=A;
189  setmirror(MI_0+MirCache[A]);
190 }
191
192 void Mapper158_init(void)
193 {
194         setchr1wrap=MirWrap;
195         PPU_hook=MirrorFear;
196         nomirror=1;
197         RAMBO1_init();
198 }