X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=fceu.git;a=blobdiff_plain;f=boards%2Fcopyfami_emu.c;fp=boards%2Fcopyfami_emu.c;h=353d78baaded1ab8f1579484e21e402e418f6cfe;hp=0000000000000000000000000000000000000000;hb=43725da7349c85fa13e828fdbf20cc7ac8d298d6;hpb=386f5371eb984fb9c2860c83e740890a75cd45c1 diff --git a/boards/copyfami_emu.c b/boards/copyfami_emu.c new file mode 100644 index 0000000..353d78b --- /dev/null +++ b/boards/copyfami_emu.c @@ -0,0 +1,380 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2011 CaH4e3 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef COPYFAMI + +#include "__serial.h" +#include "mapinc.h" +#include "mmc3.h" + +//#define DEBUG_SERIAL + +// *** COPY FAMICOM EMULATION *** + +/* +Êàðòà ïàìÿòè + + $0000-$1FFF Îñíîâíîå ÎÇÓ + $2000-$200F Ðåãèñòðû PPU + $2010-$3FFB Ñèñòåìíîå ÎÇÓ + $3FFC-$3FFF Ñèñòåìíûå ðåãèñòðû + $4000-$7FFF APU ðåãèñòðû/ñâîáîäíî + $8000-$FFF9 CART/ROM + $FFFA-$FFFB CART/Âåêòîð NMI + $FFFE-$FFFF CART/Âåêòîð IRQ + +Ðåãèñòðû + + CTRL R/W $3FFC ---aenic ($00 at reset) + + c - Ðåæèì êàðòðèäæà + 0 - âûêëþ÷åí + 1 - âêëþ÷åí + i - Ðåæèì IRQ âåêòîðà + 0 - îðèãèíàëüíûé âåêòîð + 1 - âåêòîð ïåðåõâà÷åí + n - Ðåæèì NMI âåêòîðà + 0 - îðèãèíàëüíûé âåêòîð + 1 - âåêòîð ïåðåõâà÷åí + e - Çàïðåò NMI + 0 - çàïðåùåí + 1 - ðàçðåøåí + a - Ðåæèì AROM + 0 - âûêëþ÷åí + 1 - âêëþ÷åí + + BANK R/W $3FFD ---mbbbb + + b - Íîìåð áàíêà âíóòðåííåîãî ÏÇÓ + m - Ìèððîðèíã â ðåæèìå ÀROM + + USBDATA R/W $3FFE dddddddd + + d - Áàéò äàííûõ ïðèåìà/ïåðåäà÷è + + STATUS R $3FFF vmnicptr + + r - Ñòàòóñ äàííûõ äëÿ ÷òåíèÿ èç USB + 0 - Åñòü äàííûå + 1 - Íåò äàííûõ + t - Ñòàòóñ áóôåðà äëÿ çàïèñè â USB + 0 - Åñòü ìåñòî + 1 - Íåò ìåñòà + p - Ñòàòóñ ïîäêëþ÷åíèÿ USB êàáåëÿ + 0 - Ïîäêëþ÷åí + 1 - Îòêëþ÷åí + c - Íàëè÷èå êàðòðèäæà â ñëîòå + 0 - Ïðèñóòñòâóåò + 1 - Îòñóòñòâóåò + i - Ñîñòîÿíèå ñèãíàëà IRQ êàðòðèäæà + 0 - Àêòèâåí + 1 - Íåàêòèâåí + n - Ñîñòîÿíèå ñèãíàëà NMI êàðòðèäæà + 0 - Àêòèâåí + 1 - Íåàêòèâåí + m - Ñîñòîÿíèå àäðåñíîé øèíû À10 VRAM (ìèððîðèíã) + v - Ñîñòîÿíèå VRAM + 0 - Âûáðàíà + 1 - Íå âûáðàíà + +Ðåæèì AROM + + Àêòèâèðóåòñÿ âíóòðåííÿÿ VRAM + Ðåãèñòðû áàíêîâ è ìèððîðèíãà íà 8000-FFFF +*/ + +#define CTRL 0x00 +#define CCART 0x01 +#define CVIRQ 0x02 +#define CVNMI 0x04 +#define CDNMI 0x08 +#define CAROM 0x10 +#define BANK 0x01 +#define BMIRR 0x10 +#define USB 0x02 +#define STATUS 0x03 +#define SRX 0x01 +#define STX 0x02 +#define SPEN 0x04 +#define SCART 0x08 +#define SIRQ 0x10 +#define SNMI 0x20 +#define SA10 0x40 +#define SVRAM 0x80 + +#ifdef DEBUG_SERIAL +static uint8 debug_serial_data[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0x00, + 0xDE, 0xAD, 0xBE, 0xEF, 0x01, + + 0x02, + + 0x14, 0x50, 0xB0, + + 0x02, + + 0x14, 0x50, 0xB0, + + 0x02, + + }; +static uint32 debug_serial_data_size = sizeof(debug_serial_data); +static uint32 debug_serial_data_pos; +#endif + +static uint8 *CHRRAM=NULL; +static uint32 CHRRAMSIZE; + +static uint8 regs[4]; + +static readfunc def_read_ram, def_read_rom; +static writefunc def_write_ram; + +static SFORMAT StateRegs[]= +{ + {regs, 4, "CREGS"}, + {0} +}; + +static void Sync() +{ + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); +} + +static void MCopyFamiMMC3PW(uint32 A, uint8 V) +{ + if(regs[CTRL] & CCART) + setprg8(A,V); + else + setprg32r(1,0x8000,(regs[BANK]&0x0F)^0x08); +} + +static void MCopyFamiMMC3CW(uint32 A, uint8 V) +{ + if((regs[STATUS] & SCART) && (regs[CTRL] & CAROM)) + setchr8r(0x10,0); + else + setchr1r(0,A,V); +} + +static void MCopyFamiMMC3MW(uint8 V) +{ + if(regs[CTRL] & CAROM) + { + setmirror(MI_0+((regs[BANK]>>4)&1)); + } + else + { + A000B=V; + setmirror((V&1)^1); + } +} + +static uint32 direction = 0xffffffff; +static uint32 bytes_count = 0; + +static DECLFW(MCopyFamiWriteReg) +{ + if(((A&3) == USB)&&!fceuindbg) { + if(direction != 0) { + direction = 0; + bytes_count = 0; + FCEU_printf(" >"); + } +#ifndef DEBUG_SERIAL + while (!SerialSendChar(V)) {}; +#endif + bytes_count++; +// FCEU_printf(" %02X",V); + } + else + { + regs[A&3]=V; + Sync(); + } +} + +static DECLFR(MCopyFamiReadReg) +{ +#ifdef DEBUG_SERIAL + if(debug_serial_data_pos == debug_serial_data_size) + regs[STATUS] |= SRX; + else + regs[STATUS] &= ~SRX; +#endif + if (!fceuindbg) + { +#ifndef DEBUG_SERIAL + if((A&3) == STATUS) + { + int data; + if((data = SerialGetChar()) == EOF) + regs[STATUS] |= SRX; + else + regs[STATUS] &= ~SRX; + regs[USB] = data & 0xff; + } else +#endif + if((A&3) == USB) + { +#ifdef DEBUG_SERIAL + regs[USB] = debug_serial_data[debug_serial_data_pos++]; +#endif + if(direction != 1) { + if(direction != 0xffffffff) FCEU_printf(" bytes sent: %08x",bytes_count); + direction = 1; + bytes_count = 0; + FCEU_printf("\n<"); + } + FCEU_printf(" %02X",regs[USB]); + } + } + return regs[A&3]; +} + +static DECLFW(MCopyFamiMMC3Write) +{ + if(regs[CTRL] & CAROM) + { + regs[BANK] = V & 0x1F; + Sync(); + } + else + { + if(A >= 0xC000) + MMC3_IRQWrite(A,V); + else + MMC3_CMDWrite(A,V); + } +} + +static DECLFW(MCopyFamiMMC3WriteNMI) +{ + if(regs[CTRL] & CVNMI) + def_write_ram(0x3FFC + (A & 1), V); + else + MCopyFamiMMC3Write(A, V); +} + +static DECLFW(MCopyFamiMMC3WriteIRQ) +{ + if(regs[CTRL] & CVIRQ) + def_write_ram(0x3FFE + (A & 1), V); + else + MCopyFamiMMC3Write(A, V); +} + +static DECLFR(MCopyFamiReadNMI) +{ + if(regs[CTRL] & CVNMI) + return def_read_ram(0x3FFC + (A & 1)); + else + return def_read_rom(A); +} + +static DECLFR(MCopyFamiReadIRQ) +{ + if(regs[CTRL] & CVIRQ) + return def_read_ram(0x3FFE + (A & 1)); + else + return def_read_rom(A); +} + +static void MCopyFamiMMC3Power(void) +{ + regs[CTRL] = regs[USB] = 0; + regs[STATUS] = SIRQ | SNMI | SVRAM; + regs[BANK] = 0x08; +#ifdef DEBUG_SERIAL + debug_serial_data_pos = 0; +#endif + GenMMC3Power(); + Sync(); + + def_write_ram = GetWriteHandler(0x3FFC); + SetWriteHandler(0x3FFC,0x3FFF,MCopyFamiWriteReg); + def_read_ram = GetReadHandler(0x3FFC); + SetReadHandler(0x3FFC,0x3FFF,MCopyFamiReadReg); + + SetWriteHandler(0x8000,0xFFF9,MCopyFamiMMC3Write); + SetWriteHandler(0xFFFA,0xFFFB,MCopyFamiMMC3WriteNMI); + SetWriteHandler(0xFFFE,0xFFFF,MCopyFamiMMC3WriteIRQ); + + def_read_rom = GetReadHandler(0xFFFA); + SetReadHandler(0xFFFA,0xFFFB,MCopyFamiReadNMI); + SetReadHandler(0xFFFE,0xFFFF,MCopyFamiReadIRQ); +} + +static void MCopyFamiMMC3Reset(void) +{ + regs[CTRL] = regs[USB] = 0; + regs[STATUS] = SIRQ | SNMI | SVRAM; + regs[BANK] = 0x08; +#ifdef DEBUG_SERIAL + debug_serial_data_pos = 0; +#endif + MMC3RegReset(); + Sync(); +} + +static void MCopyFamiClose(void) +{ + if(CHRRAM) + FCEU_gfree(CHRRAM); + CHRRAM=NULL; + SerialClose(); +} + +static void StateRestore(int version) +{ + Sync(); +} + +void MapperCopyFamiMMC3_Init(CartInfo *info) +{ + GenMMC3_Init(info, 512, 512, 8, 0); + + cwrap=MCopyFamiMMC3CW; + pwrap=MCopyFamiMMC3PW; + mwrap=MCopyFamiMMC3MW; + + info->Reset=MCopyFamiMMC3Reset; + info->Power=MCopyFamiMMC3Power; + info->Close=MCopyFamiClose; + GameStateRestore=StateRestore; + + CHRRAMSIZE=8192; + CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSIZE); + SetupCartCHRMapping(0x10,CHRRAM,CHRRAMSIZE,1); + AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM"); + +#ifndef DEBUG_SERIAL + FCEU_printf("WAITING FOR PORT...\n"); + + while(!SerialOpen(20, 921600)) {} + + FCEU_printf("PORT READY.\n"); +#endif + + AddExState(&StateRegs, ~0, 0, 0); +} + +#endif