cleanups, savestates, input (combos), menu
[fceu.git] / mappers / 187.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2003 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 LastWr;
24 static uint8 ExtMode;
25 static uint8 cmd;
26 static uint8 DRegs[8];
27 static uint32 count=0;
28 static uint32 last=0;
29 static int safe=0;
30 static uint8 poofish;
31
32 static void Sync(void)
33 {
34  int x;
35  uint32 base=0;
36
37  if(cmd&0x80) base=0x1000;
38  setchr2(0x0000^base,(0x100|DRegs[0])>>1);
39  setchr2(0x0800^base,(0x100|DRegs[1])>>1);
40  for(x=0;x<4;x++)
41   setchr1((0x1000^base)+x*0x400,DRegs[2+x]);
42
43  if(ExtMode&0x80)
44  {
45   if(ExtMode&0x20)
46    setprg32(0x8000,(ExtMode&0x1F)>>1);
47   else
48   {
49    setprg16(0x8000,(ExtMode&0x1F));
50    setprg16(0xc000,(ExtMode&0x1F));
51   }
52  }
53  else
54  {
55   setprg8(0x8000,DRegs[6]);
56   setprg8(0xa000,DRegs[7]);
57   setprg8(0xc000,~1);
58   setprg8(0xe000,~0);
59  }
60 }
61
62 static DECLFW(M187Write)
63 {
64 // FCEU_printf("Write: %04x:%04x (%04x,%d)\n",A,V,X.PC,scanline);
65  LastWr=V;
66  if(A==0x5000)
67   ExtMode=V;
68  Sync();
69 }
70
71 static DECLFW(M187HWrite)
72 {
73 // FCEU_printf("Write: %04x:%04x (%04x,%d)\n",A,V,X.PC,scanline);
74  //if(A==0x8003 && X.PC<0x800) FCEUI_DumpMem("dmp",0x0000,0xFFFF);
75  //printf("$%04x:$%02x, %04x\n",A,V,X.PC);
76  LastWr=V;
77
78  if(A==0x8003)
79  {
80 //  if(V==0x28 || V==0x2A)
81    poofish=V;
82  }
83  else if(A==0x8000) poofish=0;
84
85  switch(A)
86  {
87   case 0xc000:IRQLatch=IRQCount=V;break;
88   case 0xc001:IRQCount=IRQLatch;last=count=0;break;
89   case 0xe000:IRQa=0;X6502_IRQEnd(FCEU_IQEXT);break;
90   case 0xe001:IRQa=1;break;
91   case 0xa000:MIRROR_SET(V&1);break;
92
93   case 0x8000:cmd=V;safe=1;break;
94   case 0x8001:
95               if(safe)
96               {
97                //printf("Cmd: %d, %02x, %04x\n",cmd&0x7,V,X.PC);
98                DRegs[cmd&7]=V;
99                Sync();
100                safe=0;
101               }
102                 if(poofish==0x28)
103                   setprg8(0xC000,0x17);
104                 else if(poofish==0x2A)
105                   setprg8(0xA000,0x0F);
106               break;
107
108  }
109 }
110
111 static DECLFR(ProtRead)
112 {
113  switch(LastWr&0x3)
114  {
115   case 0x1:
116   case 0x0: return(0x83);
117   case 0x2: return(0x42);
118  }
119  return(0);
120 }
121
122 DECLFW(Write_IRQFM);
123
124 static void M187Power(void)
125 {
126  Write_IRQFM(0x4017,0x40);
127  SetWriteHandler(0x5000,0x5fff,M187Write);
128  SetWriteHandler(0x8000,0xFFFF,M187HWrite);
129  SetReadHandler(0x5000,0x5FFF,ProtRead);
130  SetWriteHandler(0x6000,0x7FFF,M187Write);
131  SetReadHandler(0x8000,0xffff,CartBR);
132  Sync();
133 }
134
135 static void sl(void)
136 {
137  if(IRQa)
138  {
139   if(IRQCount>=0)
140   {
141    IRQCount--;
142    if(IRQCount<0)
143    {
144     X6502_IRQBegin(FCEU_IQEXT);
145    }
146   }
147  }
148 }
149
150 static void FP_FASTAPASS(1) foo(uint32 A)
151 {
152  if((A&0x2000) && !(last&0x2000))
153  {
154   count++;
155   if(count==42)
156   {
157    sl();
158    count=0;
159   }
160  }
161  last=A;
162 }
163
164 void Mapper187_Init(CartInfo *info)
165 {
166  info->Power=M187Power;
167 // GameHBIRQHook=sl;
168  PPU_hook=foo;
169 }
170