d97315ac |
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 | |