1 /* FCE Ultra - NES/Famicom Emulator
\r
3 * Copyright notice for this file:
\r
4 * Copyright (C) 2011 CaH4e3
\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
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
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
23 #include "__serial.h"
\r
27 //#define DEBUG_SERIAL
\r
29 // *** COPY FAMICOM EMULATION ***
\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
45 CTRL R/W $3FFC ---aenic ($00 at reset)
\r
50 i - Ðåæèì IRQ âåêòîðà
\r
51 0 - îðèãèíàëüíûé âåêòîð
\r
52 1 - âåêòîð ïåðåõâà÷åí
\r
53 n - Ðåæèì NMI âåêòîðà
\r
54 0 - îðèãèíàëüíûé âåêòîð
\r
55 1 - âåêòîð ïåðåõâà÷åí
\r
63 BANK R/W $3FFD ---mbbbb
\r
65 b - Íîìåð áàíêà âíóòðåííåîãî ÏÇÓ
\r
66 m - Ìèððîðèíã â ðåæèìå ÀROM
\r
68 USBDATA R/W $3FFE dddddddd
\r
70 d - Áàéò äàííûõ ïðèåìà/ïåðåäà÷è
\r
72 STATUS R $3FFF vmnicptr
\r
74 r - Ñòàòóñ äàííûõ äëÿ ÷òåíèÿ èç USB
\r
77 t - Ñòàòóñ áóôåðà äëÿ çàïèñè â USB
\r
80 p - Ñòàòóñ ïîäêëþ÷åíèÿ USB êàáåëÿ
\r
83 c - Íàëè÷èå êàðòðèäæà â ñëîòå
\r
86 i - Ñîñòîÿíèå ñèãíàëà IRQ êàðòðèäæà
\r
89 n - Ñîñòîÿíèå ñèãíàëà NMI êàðòðèäæà
\r
92 m - Ñîñòîÿíèå àäðåñíîé øèíû À10 VRAM (ìèððîðèíã)
\r
99 Àêòèâèðóåòñÿ âíóòðåííÿÿ VRAM
\r
100 Ðåãèñòðû áàíêîâ è ìèððîðèíãà íà 8000-FFFF
\r
112 #define STATUS 0x03
\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
138 static uint32 debug_serial_data_size = sizeof(debug_serial_data);
\r
139 static uint32 debug_serial_data_pos;
\r
142 static uint8 *CHRRAM=NULL;
\r
143 static uint32 CHRRAMSIZE;
\r
145 static uint8 regs[4];
\r
147 static readfunc def_read_ram, def_read_rom;
\r
148 static writefunc def_write_ram;
\r
150 static SFORMAT StateRegs[]=
\r
152 {regs, 4, "CREGS"},
\r
158 FixMMC3PRG(MMC3_cmd);
\r
159 FixMMC3CHR(MMC3_cmd);
\r
162 static void MCopyFamiMMC3PW(uint32 A, uint8 V)
\r
164 if(regs[CTRL] & CCART)
\r
167 setprg32r(1,0x8000,(regs[BANK]&0x0F)^0x08);
\r
170 static void MCopyFamiMMC3CW(uint32 A, uint8 V)
\r
172 if((regs[STATUS] & SCART) && (regs[CTRL] & CAROM))
\r
178 static void MCopyFamiMMC3MW(uint8 V)
\r
180 if(regs[CTRL] & CAROM)
\r
182 setmirror(MI_0+((regs[BANK]>>4)&1));
\r
187 setmirror((V&1)^1);
\r
191 static uint32 direction = 0xffffffff;
\r
192 static uint32 bytes_count = 0;
\r
194 static DECLFW(MCopyFamiWriteReg)
\r
196 if(((A&3) == USB)&&!fceuindbg) {
\r
197 if(direction != 0) {
\r
202 #ifndef DEBUG_SERIAL
\r
203 while (!SerialSendChar(V)) {};
\r
206 // FCEU_printf(" %02X",V);
\r
215 static DECLFR(MCopyFamiReadReg)
\r
217 #ifdef DEBUG_SERIAL
\r
218 if(debug_serial_data_pos == debug_serial_data_size)
\r
219 regs[STATUS] |= SRX;
\r
221 regs[STATUS] &= ~SRX;
\r
225 #ifndef DEBUG_SERIAL
\r
226 if((A&3) == STATUS)
\r
229 if((data = SerialGetChar()) == EOF)
\r
230 regs[STATUS] |= SRX;
\r
232 regs[STATUS] &= ~SRX;
\r
233 regs[USB] = data & 0xff;
\r
238 #ifdef DEBUG_SERIAL
\r
239 regs[USB] = debug_serial_data[debug_serial_data_pos++];
\r
241 if(direction != 1) {
\r
242 if(direction != 0xffffffff) FCEU_printf(" bytes sent: %08x",bytes_count);
\r
245 FCEU_printf("\n<");
\r
247 FCEU_printf(" %02X",regs[USB]);
\r
253 static DECLFW(MCopyFamiMMC3Write)
\r
255 if(regs[CTRL] & CAROM)
\r
257 regs[BANK] = V & 0x1F;
\r
263 MMC3_IRQWrite(A,V);
\r
265 MMC3_CMDWrite(A,V);
\r
269 static DECLFW(MCopyFamiMMC3WriteNMI)
\r
271 if(regs[CTRL] & CVNMI)
\r
272 def_write_ram(0x3FFC + (A & 1), V);
\r
274 MCopyFamiMMC3Write(A, V);
\r
277 static DECLFW(MCopyFamiMMC3WriteIRQ)
\r
279 if(regs[CTRL] & CVIRQ)
\r
280 def_write_ram(0x3FFE + (A & 1), V);
\r
282 MCopyFamiMMC3Write(A, V);
\r
285 static DECLFR(MCopyFamiReadNMI)
\r
287 if(regs[CTRL] & CVNMI)
\r
288 return def_read_ram(0x3FFC + (A & 1));
\r
290 return def_read_rom(A);
\r
293 static DECLFR(MCopyFamiReadIRQ)
\r
295 if(regs[CTRL] & CVIRQ)
\r
296 return def_read_ram(0x3FFE + (A & 1));
\r
298 return def_read_rom(A);
\r
301 static void MCopyFamiMMC3Power(void)
\r
303 regs[CTRL] = regs[USB] = 0;
\r
304 regs[STATUS] = SIRQ | SNMI | SVRAM;
\r
306 #ifdef DEBUG_SERIAL
\r
307 debug_serial_data_pos = 0;
\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
317 SetWriteHandler(0x8000,0xFFF9,MCopyFamiMMC3Write);
\r
318 SetWriteHandler(0xFFFA,0xFFFB,MCopyFamiMMC3WriteNMI);
\r
319 SetWriteHandler(0xFFFE,0xFFFF,MCopyFamiMMC3WriteIRQ);
\r
321 def_read_rom = GetReadHandler(0xFFFA);
\r
322 SetReadHandler(0xFFFA,0xFFFB,MCopyFamiReadNMI);
\r
323 SetReadHandler(0xFFFE,0xFFFF,MCopyFamiReadIRQ);
\r
326 static void MCopyFamiMMC3Reset(void)
\r
328 regs[CTRL] = regs[USB] = 0;
\r
329 regs[STATUS] = SIRQ | SNMI | SVRAM;
\r
331 #ifdef DEBUG_SERIAL
\r
332 debug_serial_data_pos = 0;
\r
338 static void MCopyFamiClose(void)
\r
341 FCEU_gfree(CHRRAM);
\r
346 static void StateRestore(int version)
\r
351 void MapperCopyFamiMMC3_Init(CartInfo *info)
\r
353 GenMMC3_Init(info, 512, 512, 8, 0);
\r
355 cwrap=MCopyFamiMMC3CW;
\r
356 pwrap=MCopyFamiMMC3PW;
\r
357 mwrap=MCopyFamiMMC3MW;
\r
359 info->Reset=MCopyFamiMMC3Reset;
\r
360 info->Power=MCopyFamiMMC3Power;
\r
361 info->Close=MCopyFamiClose;
\r
362 GameStateRestore=StateRestore;
\r
365 CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSIZE);
\r
366 SetupCartCHRMapping(0x10,CHRRAM,CHRRAMSIZE,1);
\r
367 AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM");
\r
369 #ifndef DEBUG_SERIAL
\r
370 FCEU_printf("WAITING FOR PORT...\n");
\r
372 while(!SerialOpen(20, 921600)) {}
\r
374 FCEU_printf("PORT READY.\n");
\r
377 AddExState(&StateRegs, ~0, 0, 0);
\r