random warning fixes
[fceu.git] / boards / copyfami_emu.c
1 /* FCE Ultra - NES/Famicom Emulator\r
2  *\r
3  * Copyright notice for this file:\r
4  *  Copyright (C) 2011 CaH4e3\r
5  *\r
6  * This program is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 2 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * This program is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with this program; if not, write to the Free Software\r
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19  */\r
20 \r
21 #ifdef COPYFAMI\r
22 \r
23 #include "__serial.h"\r
24 #include "mapinc.h"\r
25 #include "mmc3.h"\r
26 \r
27 //#define DEBUG_SERIAL\r
28 \r
29 // *** COPY FAMICOM EMULATION ***\r
30 \r
31 /*\r
32 Êàðòà ïàìÿòè\r
33 \r
34         $0000-$1FFF Îñíîâíîå ÎÇÓ\r
35         $2000-$200F Ðåãèñòðû PPU\r
36         $2010-$3FFB Ñèñòåìíîå ÎÇÓ\r
37         $3FFC-$3FFF Ñèñòåìíûå ðåãèñòðû\r
38         $4000-$7FFF APU ðåãèñòðû/ñâîáîäíî\r
39         $8000-$FFF9 CART/ROM\r
40         $FFFA-$FFFB CART/Âåêòîð NMI\r
41         $FFFE-$FFFF CART/Âåêòîð IRQ\r
42 \r
43 Ðåãèñòðû\r
44 \r
45         CTRL            R/W     $3FFC   ---aenic        ($00 at reset)\r
46 \r
47                 c - Ðåæèì êàðòðèäæà\r
48                         0 - âûêëþ÷åí\r
49                         1 - âêëþ÷åí\r
50                 i - Ðåæèì IRQ âåêòîðà\r
51                         0 - îðèãèíàëüíûé âåêòîð\r
52                         1 - âåêòîð ïåðåõâà÷åí\r
53                 n - Ðåæèì NMI âåêòîðà\r
54                         0 - îðèãèíàëüíûé âåêòîð\r
55                         1 - âåêòîð ïåðåõâà÷åí\r
56                 e - Çàïðåò NMI\r
57                         0 - çàïðåùåí\r
58                         1 - ðàçðåøåí\r
59                 a - Ðåæèì AROM\r
60                         0 - âûêëþ÷åí\r
61                         1 - âêëþ÷åí\r
62 \r
63         BANK            R/W     $3FFD   ---mbbbb\r
64 \r
65                 b - Íîìåð áàíêà âíóòðåííåîãî ÏÇÓ\r
66                 m - Ìèððîðèíã â ðåæèìå ÀROM\r
67 \r
68         USBDATA         R/W     $3FFE   dddddddd\r
69 \r
70                 d - Áàéò äàííûõ ïðèåìà/ïåðåäà÷è\r
71 \r
72         STATUS          R       $3FFF   vmnicptr\r
73 \r
74                 r - Ñòàòóñ äàííûõ äëÿ ÷òåíèÿ èç USB\r
75                         0 - Åñòü äàííûå\r
76                         1 - Íåò äàííûõ\r
77                 t - Ñòàòóñ áóôåðà äëÿ çàïèñè â USB\r
78                         0 - Åñòü ìåñòî\r
79                         1 - Íåò ìåñòà\r
80                 p - Ñòàòóñ ïîäêëþ÷åíèÿ USB êàáåëÿ\r
81                         0 - Ïîäêëþ÷åí\r
82                         1 - Îòêëþ÷åí\r
83                 c - Íàëè÷èå êàðòðèäæà â ñëîòå\r
84                         0 - Ïðèñóòñòâóåò\r
85                         1 - Îòñóòñòâóåò\r
86                 i - Ñîñòîÿíèå ñèãíàëà IRQ êàðòðèäæà\r
87                         0 - Àêòèâåí\r
88                         1 - Íåàêòèâåí\r
89                 n - Ñîñòîÿíèå ñèãíàëà NMI êàðòðèäæà\r
90                         0 - Àêòèâåí\r
91                         1 - Íåàêòèâåí\r
92                 m - Ñîñòîÿíèå àäðåñíîé øèíû À10 VRAM (ìèððîðèíã)\r
93                 v - Ñîñòîÿíèå VRAM\r
94                         0 - Âûáðàíà\r
95                         1 - Íå âûáðàíà\r
96 \r
97 Ðåæèì AROM\r
98 \r
99         Àêòèâèðóåòñÿ âíóòðåííÿÿ VRAM\r
100         Ðåãèñòðû áàíêîâ è ìèððîðèíãà íà 8000-FFFF\r
101 */\r
102 \r
103 #define CTRL     0x00\r
104 #define  CCART   0x01\r
105 #define  CVIRQ   0x02\r
106 #define  CVNMI   0x04\r
107 #define  CDNMI   0x08\r
108 #define  CAROM   0x10\r
109 #define BANK     0x01\r
110 #define  BMIRR   0x10\r
111 #define USB      0x02\r
112 #define STATUS   0x03\r
113 #define  SRX     0x01\r
114 #define  STX     0x02\r
115 #define  SPEN    0x04\r
116 #define  SCART   0x08\r
117 #define  SIRQ    0x10\r
118 #define  SNMI    0x20\r
119 #define  SA10    0x40\r
120 #define  SVRAM   0x80\r
121 \r
122 #ifdef DEBUG_SERIAL\r
123 static uint8 debug_serial_data[] = { \r
124        0xDE, 0xAD, 0xBE, 0xEF, 0x00,\r
125        0xDE, 0xAD, 0xBE, 0xEF, 0x01,\r
126       \r
127        0x02,\r
128 \r
129        0x14, 0x50, 0xB0,\r
130        \r
131        0x02,\r
132 \r
133        0x14, 0x50, 0xB0,\r
134 \r
135        0x02,\r
136 \r
137        };\r
138 static uint32 debug_serial_data_size = sizeof(debug_serial_data);\r
139 static uint32 debug_serial_data_pos;\r
140 #endif\r
141 \r
142 static uint8 *CHRRAM=NULL;\r
143 static uint32 CHRRAMSIZE;\r
144 \r
145 static uint8 regs[4];\r
146 \r
147 static readfunc def_read_ram, def_read_rom;\r
148 static writefunc def_write_ram;\r
149 \r
150 static SFORMAT StateRegs[]=\r
151 {\r
152   {regs, 4, "CREGS"},\r
153   {0}\r
154 };\r
155 \r
156 static void Sync()\r
157 {\r
158   FixMMC3PRG(MMC3_cmd);\r
159   FixMMC3CHR(MMC3_cmd);\r
160 }\r
161 \r
162 static void MCopyFamiMMC3PW(uint32 A, uint8 V)\r
163 {\r
164   if(regs[CTRL] & CCART)\r
165     setprg8(A,V);\r
166   else\r
167     setprg32r(1,0x8000,(regs[BANK]&0x0F)^0x08);\r
168 }\r
169 \r
170 static void MCopyFamiMMC3CW(uint32 A, uint8 V)\r
171 {\r
172   if((regs[STATUS] & SCART) && (regs[CTRL] & CAROM))\r
173     setchr8r(0x10,0);\r
174   else\r
175     setchr1r(0,A,V);\r
176 }\r
177 \r
178 static void MCopyFamiMMC3MW(uint8 V)\r
179 {\r
180   if(regs[CTRL] & CAROM)\r
181   {\r
182     setmirror(MI_0+((regs[BANK]>>4)&1));\r
183   }\r
184   else\r
185   {\r
186     A000B=V;\r
187     setmirror((V&1)^1);\r
188   }\r
189 }\r
190 \r
191 static uint32 direction = 0xffffffff;\r
192 static uint32 bytes_count = 0;\r
193 \r
194 static DECLFW(MCopyFamiWriteReg)\r
195 {\r
196   if(((A&3) == USB)&&!fceuindbg) {\r
197     if(direction != 0) {\r
198       direction = 0;\r
199       bytes_count = 0;\r
200       FCEU_printf(" >");\r
201     }\r
202 #ifndef DEBUG_SERIAL\r
203     while (!SerialSendChar(V)) {};\r
204 #endif\r
205     bytes_count++;\r
206 //    FCEU_printf(" %02X",V);\r
207   }\r
208   else\r
209   {\r
210     regs[A&3]=V;\r
211     Sync();\r
212   }\r
213 }\r
214 \r
215 static DECLFR(MCopyFamiReadReg)\r
216 {\r
217 #ifdef DEBUG_SERIAL\r
218   if(debug_serial_data_pos == debug_serial_data_size)\r
219     regs[STATUS] |= SRX;\r
220   else\r
221     regs[STATUS] &= ~SRX;\r
222 #endif\r
223   if (!fceuindbg) \r
224   {\r
225 #ifndef DEBUG_SERIAL\r
226     if((A&3) == STATUS)\r
227     {\r
228       int data;\r
229       if((data = SerialGetChar()) == EOF)\r
230         regs[STATUS] |= SRX;\r
231       else\r
232         regs[STATUS] &= ~SRX;\r
233       regs[USB] = data & 0xff;\r
234     } else\r
235 #endif\r
236     if((A&3) == USB)\r
237     {\r
238 #ifdef DEBUG_SERIAL\r
239       regs[USB] = debug_serial_data[debug_serial_data_pos++];\r
240 #endif\r
241       if(direction != 1) {\r
242         if(direction != 0xffffffff) FCEU_printf(" bytes sent: %08x",bytes_count);\r
243         direction = 1;\r
244         bytes_count = 0;\r
245         FCEU_printf("\n<");\r
246       }\r
247     FCEU_printf(" %02X",regs[USB]);\r
248     }\r
249   }\r
250   return regs[A&3];\r
251 }\r
252 \r
253 static DECLFW(MCopyFamiMMC3Write)\r
254 {\r
255   if(regs[CTRL] & CAROM)\r
256   {\r
257     regs[BANK] = V & 0x1F;\r
258     Sync();\r
259   }\r
260   else\r
261   {\r
262     if(A >= 0xC000)\r
263      MMC3_IRQWrite(A,V);\r
264     else\r
265      MMC3_CMDWrite(A,V);\r
266   }\r
267 }\r
268 \r
269 static DECLFW(MCopyFamiMMC3WriteNMI)\r
270 {\r
271   if(regs[CTRL] & CVNMI)\r
272     def_write_ram(0x3FFC + (A & 1), V);\r
273   else\r
274     MCopyFamiMMC3Write(A, V);\r
275 }\r
276 \r
277 static DECLFW(MCopyFamiMMC3WriteIRQ)\r
278 {\r
279   if(regs[CTRL] & CVIRQ)\r
280     def_write_ram(0x3FFE + (A & 1), V);\r
281   else\r
282     MCopyFamiMMC3Write(A, V);\r
283 }\r
284 \r
285 static DECLFR(MCopyFamiReadNMI)\r
286 {\r
287   if(regs[CTRL] & CVNMI)\r
288     return def_read_ram(0x3FFC + (A & 1));\r
289   else\r
290     return def_read_rom(A);\r
291 }\r
292 \r
293 static DECLFR(MCopyFamiReadIRQ)\r
294 {\r
295   if(regs[CTRL] & CVIRQ)\r
296     return def_read_ram(0x3FFE + (A & 1));\r
297   else\r
298     return def_read_rom(A);\r
299 }\r
300 \r
301 static void MCopyFamiMMC3Power(void)\r
302 {\r
303   regs[CTRL] = regs[USB] = 0;\r
304   regs[STATUS] = SIRQ | SNMI | SVRAM;\r
305   regs[BANK] = 0x08;\r
306 #ifdef DEBUG_SERIAL\r
307   debug_serial_data_pos = 0;\r
308 #endif\r
309   GenMMC3Power();\r
310   Sync();\r
311 \r
312   def_write_ram = GetWriteHandler(0x3FFC);\r
313   SetWriteHandler(0x3FFC,0x3FFF,MCopyFamiWriteReg);\r
314   def_read_ram = GetReadHandler(0x3FFC);\r
315   SetReadHandler(0x3FFC,0x3FFF,MCopyFamiReadReg);\r
316 \r
317   SetWriteHandler(0x8000,0xFFF9,MCopyFamiMMC3Write);\r
318   SetWriteHandler(0xFFFA,0xFFFB,MCopyFamiMMC3WriteNMI);\r
319   SetWriteHandler(0xFFFE,0xFFFF,MCopyFamiMMC3WriteIRQ);\r
320 \r
321   def_read_rom = GetReadHandler(0xFFFA);\r
322   SetReadHandler(0xFFFA,0xFFFB,MCopyFamiReadNMI);\r
323   SetReadHandler(0xFFFE,0xFFFF,MCopyFamiReadIRQ);\r
324 }\r
325 \r
326 static void MCopyFamiMMC3Reset(void)\r
327 {\r
328   regs[CTRL] = regs[USB] = 0;\r
329   regs[STATUS] = SIRQ | SNMI | SVRAM;\r
330   regs[BANK] = 0x08;\r
331 #ifdef DEBUG_SERIAL\r
332   debug_serial_data_pos = 0;\r
333 #endif\r
334   MMC3RegReset();\r
335   Sync();\r
336 }\r
337 \r
338 static void MCopyFamiClose(void)\r
339 {\r
340   if(CHRRAM)\r
341     FCEU_gfree(CHRRAM);\r
342   CHRRAM=NULL;\r
343   SerialClose();\r
344 }\r
345 \r
346 static void StateRestore(int version)\r
347 {\r
348   Sync();\r
349 }\r
350 \r
351 void MapperCopyFamiMMC3_Init(CartInfo *info)\r
352 {\r
353   GenMMC3_Init(info, 512, 512, 8, 0);\r
354 \r
355   cwrap=MCopyFamiMMC3CW;\r
356   pwrap=MCopyFamiMMC3PW;\r
357   mwrap=MCopyFamiMMC3MW;\r
358 \r
359   info->Reset=MCopyFamiMMC3Reset;\r
360   info->Power=MCopyFamiMMC3Power;\r
361   info->Close=MCopyFamiClose;\r
362   GameStateRestore=StateRestore;\r
363 \r
364   CHRRAMSIZE=8192;\r
365   CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSIZE);\r
366   SetupCartCHRMapping(0x10,CHRRAM,CHRRAMSIZE,1);\r
367   AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM");\r
368 \r
369 #ifndef DEBUG_SERIAL\r
370   FCEU_printf("WAITING FOR PORT...\n");\r
371   \r
372   while(!SerialOpen(20, 921600)) {}\r
373 \r
374   FCEU_printf("PORT READY.\n");\r
375 #endif\r
376 \r
377   AddExState(&StateRegs, ~0, 0, 0);\r
378 }\r
379 \r
380 #endif\r