Merge pull request #516 from negativeExponent/cleanups

Cleanups
This commit is contained in:
LibretroAdmin 2022-06-09 12:29:04 +01:00 committed by GitHub
commit c17f39167c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 3 additions and 1225 deletions

View File

@ -1,355 +0,0 @@
/* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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

View File

@ -1,596 +0,0 @@
/* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef COPYFAMI
/* *** COPY FAMICOM HARDWARE INTERFACE *** */
#define MESSAGE_LOG
#define NO_CACHE
#define NO_RAM
#include <streams/file_stream.h>
#include "__serial.h"
#include "mapinc.h"
#define FNV_32_PRIME ((uint32)0x01000193)
#define CHR_CACHE_SIZE (1024 * 4)
#define WRAM_CACHE_SIZE (1024 / 2)
#define PRG_CACHE_SIZE (1024 / 4)
#define CMD_CACHE_SIZE (1024 * 128)
#define CMD_MAX_SIZE (5)
#define CMD_MAX_RETEST (16)
#define CMD_MAX_VERIFY (16)
static uint8 *WRAM = NULL;
uint8 InitVector[] = { 0xDE, 0xAD, 0xBE, 0xEF };/* args none, return DE AD BE EF */
uint8 ResetCmd[] = { 0x00 }; /* args none, return none */
uint8 StateCmd[] = { 0x01 }; /* args none, return 7 bytes status */
uint8 StatusCmd[] = { 0x02 }; /* args none, return 32 bytes status */
uint8 LoadPlugCmd[] = { 0x03, 0x00, 0x00 }; /* args 2b size, Nb data return none */
uint8 RunPlugCmd[] = { 0x04 }; /* args none, return none */
uint8 RunGameCmd[] = { 0x05 }; /* args none, return none */
uint8 NROMSave[] = { 0x06 }; /* args none, return 16b + 32kb + 8kb */
uint8 PRGWBCmd[] = { 0x08, 0x00, 0x00, 0x00 }; /* args 2b addr, 1b data return none */
uint8 PRGRBCmd[] = { 0x09, 0x00, 0x00 }; /* args 2b addr return 1b data */
uint8 CHRWBCmd[] = { 0x0A, 0x00, 0x00, 0x00 }; /* args 2b addr, 1b data return none */
uint8 CHRRBCmd[] = { 0x0B, 0x00, 0x00 }; /* args 2b addr, return 1b data */
uint8 PRGSUMCmd[] = { 0x10, 0x00, 0x00 }; /* args 1b addr, 1b size return (256 * N)b */
uint8 PRG32KSUMCmd[] = { 0x10, 0x80, 0x80 }; /* args 1b addr, 1b size return 32kb */
uint8 PRG16KSUMCmd[] = { 0x10, 0x00, 0x40 }; /* args 1b addr, 1b size return 16kb */
uint8 PRG8KSUMCmd[] = { 0x10, 0x00, 0x20 }; /* args 1b addr, 1b size return 8kb */
uint8 PRG4KSUMCmd[] = { 0x10, 0x00, 0x10 }; /* args 1b addr, 1b size return 4kb */
uint8 CHRSUMCmd[] = { 0x11, 0x00, 0x00 }; /* args 1b addr, 1b size return (256 * N)b */
uint8 CHR8KSUMCmd[] = { 0x11, 0x00, 0x20 }; /* args 1b addr, 1b size return 8kb */
uint8 CHR4KSUMCmd[] = { 0x11, 0x00, 0x10 }; /* args 1b addr, 1b size return 4kb */
uint8 CHR2KSUMCmd[] = { 0x11, 0x00, 0x08 }; /* args 1b addr, 1b size return 2kb */
uint8 CHR1KSUMCmd[] = { 0x11, 0x00, 0x04 }; /* args 1b addr, 1b size return 1kb */
uint8 PRGGetCmd[] = { 0x12, 0x00, 0x00 }; /* args 1b addr, 1b size return (256 * N)b */
uint8 PRG32KGetCmd[] = { 0x12, 0x80, 0x80 }; /* args 1b addr, 1b size return 32kb */
uint8 PRG16KGetCmd[] = { 0x12, 0x00, 0x40 }; /* args 1b addr, 1b size return 16kb */
uint8 PRG8KGetCmd[] = { 0x12, 0x00, 0x20 }; /* args 1b addr, 1b size return 8kb */
uint8 PRG4KGetCmd[] = { 0x12, 0x00, 0x10 }; /* args 1b addr, 1b size return 4kb */
uint8 CHRGetCmd[] = { 0x13, 0x00, 0x00 }; /* args 1b addr, 1b size return (256 * N)b */
uint8 CHR8KGetCmd[] = { 0x13, 0x00, 0x20 }; /* args 1b addr, 1b size return 8kb */
uint8 CHR4KGetCmd[] = { 0x13, 0x00, 0x10 }; /* args 1b addr, 1b size return 4kb */
uint8 CHR2KGetCmd[] = { 0x13, 0x00, 0x08 }; /* args 1b addr, 1b size return 2kb */
uint8 CHR1KGetCmd[] = { 0x13, 0x00, 0x04 }; /* args 1b addr, 1b size return 1kb */
uint8 CPUTestCmd[] = { 0x14, 0x00, 0x00 }; /* args 1b addr, 1b size return (2b + 1b) * N + 3b */
typedef struct {
int32 mirror;
int32 chrsum[8];
int32 prgsum[4];
} SYNC_STATE;
static SYNC_STATE state_cur, state_new, state_def;
typedef struct {
uint8 *buf;
int32 count;
} DATA_BANKS;
static DATA_BANKS chr_data;
static int32 chr_bank[0x10000];
static DATA_BANKS prg_data;
static int32 prg_bank[0x10000];
typedef struct {
SYNC_STATE states[CMD_CACHE_SIZE];
int32 seqs[CMD_CACHE_SIZE][CMD_MAX_SIZE];
int32 count;
} SYNC_CMDS;
typedef struct {
int32 seq[CMD_MAX_SIZE];
int32 size;
int32 found;
uint32 hash;
uint16 hashf;
} SYNC_CMD;
static SYNC_CMD cmd;
static SYNC_CMDS cmds;
typedef struct {
int32 index;
int32 size;
int32 retest;
int32 verify;
} CMD_CACHE;
static CMD_CACHE cmd_cache[0x10000];
static SFORMAT StateRegs[] =
{
{ state_cur.chrsum, sizeof(state_cur.chrsum), "CHRREG" },
{ state_cur.prgsum, sizeof(state_cur.prgsum), "ROMREG" },
{ &state_cur.mirror, sizeof(state_cur.mirror), "MIRREG" },
{ 0 }
};
#define MI_U 4
static char *mirror_names[5] = { "Horizontal", "Vertical", "Mirror 0", "Mirror 1", "Unknown mirror" };
static int32 mirror_modes[16] = {
MI_0, MI_U, MI_U, MI_H, MI_U, MI_V, MI_U, MI_U,
MI_U, MI_U, MI_U, MI_U, MI_U, MI_U, MI_U, MI_1
};
#define CHRDEF(slot) (chr_bank[state_def.chrsum[slot]])
#define PRGDEF(slot) (prg_bank[state_def.prgsum[slot]])
#define CHRCUR(slot) (chr_bank[state_cur.chrsum[slot]])
#define PRGCUR(slot) (prg_bank[state_cur.prgsum[slot]])
#define CHRNEW(slot) (chr_bank[state_new.chrsum[slot]])
#define PRGNEW(slot) (prg_bank[state_new.prgsum[slot]])
static void GetStatus(SYNC_STATE *state) {
uint8 resp0;
uint16 resp1, i;
SEND(StatusCmd);
GET(resp0, 1);
state->mirror = resp0;
GET(resp0, 1);
for (i = 0; i < 8; i++) {
GET(resp1, 2);
state->chrsum[i] = resp1;
}
for (i = 0; i < 4; i++) {
GET(resp1, 2);
state->prgsum[i] = resp1;
}
}
static int32 FetchNewCHRBank(int32 slot) {
RFILE *ofile;
char name[256];
int32 bank = chr_data.count++;
CHR1KGetCmd[1] = slot << 2;
SENDGET(CHR1KGetCmd, chr_data.buf[bank * 1024], 1024);
sprintf(name, "%04x.chr", bank);
ofile = filestream_open(name,
RETRO_VFS_FILE_ACCESS_WRITE,
RETRO_VFS_FILE_ACCESS_HINT_NONE);
filestream_write(ofile, (void*)&chr_data.buf[bank * 1024], 1024);
filestream_close(ofile);
return bank;
}
static int32 FetchNewPRGBank(int32 slot) {
RFILE *ofile;
char name[256];
int32 bank = prg_data.count++;
PRG8KGetCmd[1] = 0x80 + (slot << 5);
SENDGET(PRG8KGetCmd, prg_data.buf[bank * 8192], 8192);
sprintf(name, "%04x.prg", bank);
ofile = filestream_open(name,
RETRO_VFS_FILE_ACCESS_WRITE,
RETRO_VFS_FILE_ACCESS_HINT_NONE);
filestream_write(ofile, (void*)&prg_data.buf[bank * 8192], 8192);
filestream_close(ofile);
return bank;
}
static int CheckStatus(void) {
int32 i, ischanged = 0;
GetStatus(&state_new);
if (state_cur.mirror != state_new.mirror) {
state_cur.mirror = state_new.mirror;
#ifdef MESSAGE_LOG
FCEU_printf(">> mirror changed to %s (%02X)\n", mirror_names[mirror_modes[state_cur.mirror]], state_cur.mirror);
#endif
ischanged = 1;
} else {
state_new.mirror = -1;
}
for (i = 0; i < 8; i++) {
if (state_cur.chrsum[i] != state_new.chrsum[i]) {
state_cur.chrsum[i] = state_new.chrsum[i];
if (CHRCUR(i) == -1) {
CHRCUR(i) = FetchNewCHRBank(i);
#ifdef MESSAGE_LOG
FCEU_printf(">> chr[%d] bank %d loaded\n", i, CHRCUR(i));
#endif
}
#ifdef MESSAGE_LOG
else
FCEU_printf(">> chr[%d] bank %d switched\n", i, CHRCUR(i));
#endif
ischanged = 1;
} else {
state_new.chrsum[i] = -1;
}
}
for (i = 0; i < 4; i++) {
if (state_cur.prgsum[i] != state_new.prgsum[i]) {
state_cur.prgsum[i] = state_new.prgsum[i];
if (PRGCUR(i) == -1) {
PRGCUR(i) = FetchNewPRGBank(i);
#ifdef MESSAGE_LOG
FCEU_printf(">> prg[%d] bank %d loaded\n", i, PRGCUR(i));
#endif
}
#ifdef MESSAGE_LOG
else
FCEU_printf(">> prg[%d] bank %d switched\n", i, PRGCUR(i));
#endif
ischanged = 1;
} else {
state_new.prgsum[i] = -1;
}
}
return ischanged;
}
#ifndef NO_CACHE
static void ApplyStatus() {
int32 i;
if ((cmds.states[cmd.found].mirror != -1) && (cmds.states[cmd.found].mirror != state_cur.mirror)) {
state_cur.mirror = cmds.states[cmd.found].mirror;
setmirror(mirror_modes[state_cur.mirror]);
#ifdef MESSAGE_LOG
FCEU_printf(">> mirror changed to %s (%02X)\n", mirror_names[mirror_modes[state_cur.mirror]], state_cur.mirror);
#endif
}
for (i = 0; i < 8; i++) {
int32 sum = cmds.states[cmd.found].chrsum[i];
if (sum != -1) {
if (sum != state_cur.chrsum[i]) {
state_cur.chrsum[i] = sum;
setchr1r(1, i * 1024, CHRCUR(i));
#ifdef MESSAGE_LOG
FCEU_printf(">> chr[%d] bank %d switched\n", i, chr_bank[sum]);
#endif
} else
#ifdef MESSAGE_LOG
FCEU_printf(">> chr[%d] bank %d switched the same\n", i, chr_bank[sum]);
}
#endif
}
for (i = 0; i < 4; i++) {
int32 sum = cmds.states[cmd.found].prgsum[i];
if (sum != -1) {
if (sum != state_cur.prgsum[i]) {
state_cur.prgsum[i] = sum;
setprg8r(2, 0x8000 + (i * 8192), PRGCUR(i));
#ifdef MESSAGE_LOG
FCEU_printf(">> prg[%d] bank %d switched\n", i, prg_bank[sum]);
#endif
} else
#ifdef MESSAGE_LOG
FCEU_printf(">> prg[%d] bank %d switched the same\n", i, prg_bank[sum]);
}
#endif
}
}
static void LogCmd() {
int32 i;
FCEU_printf(">> new cmd size %d [", cmd_cache[cmd.hashf].size);
for (i = 0; i < cmd_cache[cmd.hashf].size; i++)
FCEU_printf(" %06X", cmds.seqs[cmd.found][i]);
FCEU_printf(" ], switched to (");
if (cmds.states[cmd.found].mirror != -1)
FCEU_printf(" mirror=%s", mirror_names[mirror_modes[cmds.states[cmd.found].mirror]]);
for (i = 0; i < 8; i++)
if (cmds.states[cmd.found].chrsum[i] != -1)
FCEU_printf(" chr%d=%02X", i, chr_bank[cmds.states[cmd.found].chrsum[i]]);
for (i = 0; i < 4; i++)
if (cmds.states[cmd.found].prgsum[i] != -1)
FCEU_printf(" prg%d=%02X", i, prg_bank[cmds.states[cmd.found].prgsum[i]]);
FCEU_printf(" )\n");
}
#endif
static void Sync() {
setchr1r(1, 0x0000, CHRCUR(0));
setchr1r(1, 0x0400, CHRCUR(1));
setchr1r(1, 0x0800, CHRCUR(2));
setchr1r(1, 0x0C00, CHRCUR(3));
setchr1r(1, 0x1000, CHRCUR(4));
setchr1r(1, 0x1400, CHRCUR(5));
setchr1r(1, 0x1800, CHRCUR(6));
setchr1r(1, 0x1C00, CHRCUR(7));
#ifndef NO_RAM
setprg8r(1, 0x6000, 0);
#endif
setprg8r(2, 0x8000, PRGCUR(0));
setprg8r(2, 0xA000, PRGCUR(1));
setprg8r(2, 0xC000, PRGCUR(2));
setprg8r(2, 0xE000, PRGCUR(3));
setmirror(mirror_modes[state_cur.mirror]);
}
#ifndef NO_CACHE
static void UpdateCmd(uint32 val) {
int32 index;
if (cmd.size < CMD_MAX_SIZE) {
index = cmd.size++;
} else {
/* åñëè äîñòèãíóò ìàêñèìóì äëÿ êîìàíäû, âûáðîñèòü ïîñëåäíóþþ, äîáàâèòü íîâóþ,
* ïðîäîëæàòü äî áàíêñâè÷èíãà
*/
cmd.hash = 0;
for (index = 0; index < (CMD_MAX_SIZE - 1); index++) {
cmd.seq[index] = cmd.seq[index + 1];
cmd.hash *= FNV_32_PRIME;
cmd.hash ^= cmd.seq[index];
}
}
cmd.seq[index] = val;
cmd.hash *= FNV_32_PRIME;
cmd.hash ^= val;
cmd.hashf = (cmd.hash >> 16) ^ (cmd.hash & 0xffff);
cmd.found = cmd_cache[cmd.hashf].index;
}
#endif
static DECLFW(MCopyFamiWrite) {
#ifndef NO_CACHE
int32 i;
#endif
#ifdef MESSAGE_LOG
FCEU_printf("> WRITE %04X:%02X\n", A, V);
#endif
PRGWBCmd[1] = A & 0xFF;
PRGWBCmd[2] = A >> 8;
PRGWBCmd[3] = V & 0xFF;
SEND(PRGWBCmd);
#ifdef NO_CACHE
CheckStatus();
Sync();
#else
UpdateCmd((A << 8) | V);
/* èùåì êîìàíäó â êåøå */
if (cmd.found == -1) {
/* íå íàéäåíà, ïðîâåðÿåì, èçìåíèëîñü ëè ñîñòîÿíèå áàíêîâ
* ëèáî íå ïðåäåëüíîé ëè îíà äëèíû äëÿ êîìàíäû
*/
cmd_cache[cmd.hashf].index = cmd.found = cmds.count++;
cmd_cache[cmd.hashf].retest = 0;
cmd_cache[cmd.hashf].verify = 0;
for (i = 0; i < cmd.size; i++)
cmds.seqs[cmd.found][i] = cmd.seq[i];
cmd_cache[cmd.hashf].size = cmd.size;
if (CheckStatus()) {
cmds.states[cmd.found] = state_new;
LogCmd();
cmd.size = 0;
cmd.hash = 0;
Sync();
} else {
/* åñëè äîáàâëåíà ïîëíàÿ êîìàíäà áåç áàíêñâèò÷èíãà */
cmd_cache[cmd.hashf].index = -2;
}
} else if (cmd.found == -2) {
/* ÷àñòè÷íîå ñîâïàäåíèå, åñëè ÷èñëî ïðîâåðîê íå ïðåâûñèëî ëèìèò */
if (cmd_cache[cmd.hashf].retest < CMD_MAX_RETEST) {
/* òî ïðîâåðèì ñîñòîÿíèå áàíêîâ */
if (CheckStatus()) {
/* èçìåíèëîñü, çàïèøåì íîâóþ êîìàíäó */
cmd_cache[cmd.hashf].index = cmd.found = cmds.count++;
cmd_cache[cmd.hashf].retest = 0;
cmd_cache[cmd.hashf].verify = 0;
for (i = 0; i < cmd.size; i++)
cmds.seqs[cmd.found][i] = cmd.seq[i];
cmd_cache[cmd.hashf].size = cmd.size;
cmds.states[cmd.found] = state_new;
LogCmd();
cmd.size = 0;
cmd.hash = 0;
Sync();
} else {
/* íå èçìåíèëîñü, îòìåòèì óâåëè÷èì ñ÷åò÷èê ïðîâåðîê */
cmd_cache[cmd.hashf].retest++;
}
}
} else {
/* íàéäåíà, ïîñëåäíèé ðóáåæ îáîðîíû îò ãîâíà */
#if 0
if(cmd_cache[cmd.hashf].verify < CMD_MAX_VERIFY) {
if(CheckStatus()) {
int32 changed = 0;
if(cmds.states[cmd.found].mirror != state_new.mirror)
changed = 1;
for(i=0; i<8; i++)
if(cmds.states[cmd.found].chrsum[i] != state_new.chrsum[i])
changed = 1;
for(i=0; i<4; i++)
if(cmds.states[cmd.found].prgsum[i] != state_new.prgsum[i])
changed = 1;
if(changed) {
cmd_cache[cmd.hashf].index = -1;
cmd_cache[cmd.hashf].retest = 0;
cmd_cache[cmd.hashf].verify = 0;
Sync();
}
} else
cmd_cache[cmd.hashf].verify++;
} else
#endif
{
/* ïðèìåíÿåì áåç ìàëåéøåãî çàçðåíèÿ ñîâåñòè */
ApplyStatus();
cmd.size = 0;
cmd.hash = 0;
}
}
#endif
}
static DECLFR(MCopyFamiRead) {
uint8 result;
PRGRBCmd[1] = A & 0xFF;
PRGRBCmd[2] = A >> 8;
SENDGET(PRGRBCmd, result, 1);
#ifdef MESSAGE_LOG
FCEU_printf("> READ %04X:%02X\n", A, result);
#endif
return result;
}
static void MCopyFamiReset(void) {
state_cur = state_def;
Sync();
}
static void MCopyFamiPower(void) {
/* uint32 resp, presp; */
FCEU_printf("NOW POWERING... ");
Sync();
SetWriteHandler(0x4018, 0x7fff, MCopyFamiWrite);
SetReadHandler(0x4018, 0x7fff, MCopyFamiRead);
#ifndef NO_RAM
SetWriteHandler(0x6000, 0x7fff, CartBW);
SetReadHandler(0x6000, 0x7fff, CartBR);
#endif
#if 0
FCEU_printf("READING MEMORY MAP...\n");
CPUTestCmd[1] = 0x50;
CPUTestCmd[2] = 0x30;
SEND(CPUTestCmd);
resp = 0;
presp = 0xffffffff;
while (presp != 0x00ff0000) {
GET(resp, 3);
if(presp != 0xffffffff) {
switch(presp & 0x00FF0000) {
case 0x00000000: /* BUS */
FCEU_printf(" %04X-%04X OPEN BUS\n",presp & 0x7fff, (resp - 1) & 0x7fff);
break;
case 0x00010000: /* RAM */
FCEU_printf(" %04X-%04X RAM\n",presp & 0x7fff, (resp - 1) & 0x7fff);
SetWriteHandler(presp & 0x7fff, (resp - 1) & 0x7fff, CartBW);
SetReadHandler(presp & 0x7fff, (resp - 1) & 0x7fff, CartBR);
break;
}
}
presp = resp;
}
#endif
SetWriteHandler(0x8000, 0xffff, MCopyFamiWrite);
SetReadHandler(0x8000, 0xffff, CartBR);
FCEU_printf("DONE!\nNOW COLLECTING DATA...\n");
}
static void MCopyFamiClose(void) {
if (chr_data.buf)
FCEU_gfree(chr_data.buf);
chr_data.buf = NULL;
if (prg_data.buf)
FCEU_gfree(prg_data.buf);
prg_data.buf = NULL;
if (WRAM)
FCEU_gfree(WRAM);
WRAM = NULL;
SerialClose();
}
static void StateRestore(int version) {
Sync();
}
void MapperCopyFami_Init(CartInfo *info) {
uint32 resp = 0, i, size;
memset(chr_bank, -1, sizeof(chr_bank));
memset(prg_bank, -1, sizeof(chr_bank));
memset(cmd_cache, -1, sizeof(cmd_cache));
memset(&cmds, 0, sizeof(cmds));
memset(&cmd, 0, sizeof(cmd));
info->Reset = MCopyFamiReset;
info->Power = MCopyFamiPower;
info->Close = MCopyFamiClose;
GameStateRestore = StateRestore;
size = 1024 * CHR_CACHE_SIZE; /* ðàçìåð ñòðàíèöû 1êá */
chr_data.buf = (uint8*)FCEU_gmalloc(size);
SetupCartCHRMapping(1, chr_data.buf, size, 1); /* ïðîâåðÿòü ïïó ðàì, èíà÷å èãðà ìîæåò ïîðòèòü äàííûå */
AddExState(chr_data.buf, size, 0, "CCHR");
size = 8192; /* ðàçìåð ñòðàíèöû 8êá */
WRAM = (uint8*)FCEU_gmalloc(size);
SetupCartPRGMapping(1, WRAM, size, 1);
AddExState(WRAM, size, 0, "CPRM");
size = 8192 * PRG_CACHE_SIZE; /* ðàçìåð ñòðàíèöû 8êá */
prg_data.buf = (uint8*)FCEU_gmalloc(size);
SetupCartPRGMapping(2, prg_data.buf, size, 0);
AddExState(prg_data.buf, size, 0, "CPPR");
FCEU_printf("WAITING FOR SERIAL PORT... ");
while (!SerialOpen(19, 921600)) {
Sleep(500);
}
FCEU_printf("READY!\n");
FCEU_printf("WAITING FOR DEVICE... ");
while (resp != *(uint32*)&InitVector[0]) {
SEND(ResetCmd);
SENDGET(InitVector, resp, 4);
Sleep(500);
}
FCEU_printf("READY!\n");
FCEU_printf("READING STATUS...\n");
GetStatus(&state_cur);
FCEU_printf("MIRRORING IS %s (%02X)\n", mirror_names[mirror_modes[state_cur.mirror]], state_cur.mirror);
FCEU_printf("READING CHR...\n INITIAL STATE:");
for (i = 0; i < 8; i++) {
if (CHRCUR(i) == -1)
CHRCUR(i) = FetchNewCHRBank(i);
FCEU_printf(" CHR%d=%02X", i, CHRCUR(i));
}
FCEU_printf("\n");
FCEU_printf("READING PRG...\n INITIAL STATE:");
for (i = 0; i < 4; i++) {
if (PRGCUR(i) == -1)
PRGCUR(i) = FetchNewPRGBank(i);
FCEU_printf(" PRG%d=%02X", i, PRGCUR(i));
}
FCEU_printf("\nDONE!\n");
state_def = state_cur;
AddExState(&StateRegs, ~0, 0, 0);
}
#endif

View File

@ -47,13 +47,6 @@ int FCEUI_EndWaveRecord(void);
void FCEUI_ResetNES(void);
void FCEUI_PowerNES(void);
void FCEUI_NTSCSELHUE(void);
void FCEUI_NTSCSELTINT(void);
void FCEUI_NTSCDEC(void);
void FCEUI_NTSCINC(void);
void FCEUI_GetNTSCTH(int *tint, int *hue);
void FCEUI_SetNTSCTH(int n, int tint, int hue);
void FCEUI_SetInput(int port, int type, void *ptr, int attrib);
void FCEUI_SetInputFC(int type, void *ptr, int attrib);
void FCEUI_DisableFourScore(int s);
@ -110,11 +103,6 @@ typedef void (*frontend_post_load_init_cb_t)(void);
FCEUGI *FCEUI_LoadGame(const char *name, const uint8_t *databuf, size_t databufsize,
frontend_post_load_init_cb_t frontend_post_load_init_cb);
#ifdef COPYFAMI
/* Fake UNIF board to start new CFHI instance */
FCEUGI *FCEUI_CopyFamiStart();
#endif
/* allocates memory. 0 on failure, 1 on success. */
int FCEUI_Initialize(void);

View File

@ -166,11 +166,7 @@ void FASTAPASS(3) SetWriteHandler(int32 start, int32 end, writefunc func)
BWrite[x] = func;
}
#ifdef COPYFAMI
uint8 RAM[0x4000];
#else
uint8 RAM[0x800];
#endif
uint8 PAL = 0;
@ -184,7 +180,6 @@ static DECLFR(ARAML)
return RAM[A];
}
#ifndef COPYFAMI
static DECLFW(BRAMH)
{
RAM[A & 0x7FF] = V;
@ -194,7 +189,6 @@ static DECLFR(ARAMH)
{
return RAM[A & 0x7FF];
}
#endif
void FCEUI_CloseGame(void)
{
@ -312,49 +306,6 @@ endlseq:
return(GameInfo);
}
int CopyFamiLoad(void);
FCEUGI *FCEUI_CopyFamiStart(void)
{
ResetGameLoaded();
GameInfo = (FCEUGI*)malloc(sizeof(FCEUGI));
memset(GameInfo, 0, sizeof(FCEUGI));
GameInfo->soundchan = 0;
GameInfo->soundrate = 0;
GameInfo->name = (uint8_t*)"copyfami";
GameInfo->type = GIT_CART;
GameInfo->vidsys = GIV_USER;
GameInfo->input[0] = GameInfo->input[1] = -1;
GameInfo->inputfc = -1;
GameInfo->cspecial = 0;
FCEU_printf("Starting CopyFamicom...\n\n");
if (!CopyFamiLoad()) {
FCEU_PrintError("An error occurred while starting CopyFamicom.");
return 0;
}
FCEU_ResetVidSys();
if (GameInfo->type != GIT_NSF)
if (FSettings.GameGenie)
FCEU_OpenGenie();
PowerNES();
if (GameInfo->type != GIT_NSF) {
FCEU_LoadGamePalette();
FCEU_LoadGameCheats();
}
FCEU_ResetPalette();
FCEU_ResetMessages(); /* Save state, status messages, etc. */
return(GameInfo);
}
int FCEUI_Initialize(void) {
if (!FCEU_InitVirtualVideo())
return 0;
@ -447,23 +398,17 @@ void PowerNES(void)
FCEU_GeniePower();
#ifndef COPYFAMI
FCEU_MemoryRand(RAM, 0x800);
#endif
SetReadHandler(0x0000, 0xFFFF, ANull);
SetWriteHandler(0x0000, 0xFFFF, BNull);
#ifdef COPYFAMI
SetReadHandler(0, 0x3FFF, ARAML);
SetWriteHandler(0, 0x3FFF, BRAML);
#else
SetReadHandler(0, 0x7FF, ARAML);
SetWriteHandler(0, 0x7FF, BRAML);
SetReadHandler(0x800, 0x1FFF, ARAMH); /* Part of a little */
SetWriteHandler(0x800, 0x1FFF, BRAMH); /* hack for a small speed boost. */
#endif
InitializeInput();
FCEUSND_Power();
FCEUPPU_Power();

View File

@ -55,11 +55,7 @@ extern uint8 MMC50x5130;
extern uint8 MMC5HackSPScroll;
extern uint8 MMC5HackSPPage;
#ifdef COPYFAMI
extern uint8 RAM[0x4000];
#else
extern uint8 RAM[0x800];
#endif
extern readfunc ARead[0x10000];
extern writefunc BWrite[0x10000];

View File

@ -33,20 +33,10 @@
#include "palette.h"
#include "palettes/palettes.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
static int ntsccol = 0;
static int ntsctint = 46 + 10;
static int ntschue = 72;
/* These are dynamically filled/generated palettes: */
pal palettei[64]; /* Custom palette for an individual game. */
pal palettec[64]; /* Custom "global" palette. */
pal paletten[64]; /* Mathematically generated palette. */
static void CalculatePalette(void);
static void ChoosePalette(void);
static void WritePalette(void);
uint8 pale = 0;
@ -77,14 +67,6 @@ void FCEUI_SetPaletteArray(uint8 *pal) {
FCEU_ResetPalette();
}
void FCEUI_SetNTSCTH(int n, int tint, int hue) {
ntsctint = tint;
ntschue = hue;
ntsccol = n;
FCEU_ResetPalette();
}
static uint8 lastd = 0;
void SetNESDeemph(uint8 d, int force) {
static uint16 rtmul[7] = { 32768 * 1.239, 32768 * .794, 32768 * 1.019, 32768 * .905, 32768 * 1.023, 32768 * .741, 32768 * .75 };
@ -142,50 +124,6 @@ void SetNESDeemph(uint8 d, int force) {
lastd = d;
}
/* Converted from Kevin Horton's qbasic palette generator. */
static void CalculatePalette(void) {
int x, z;
int r, g, b;
double s, luma, theta;
static uint8 cols[16] = { 0, 24, 21, 18, 15, 12, 9, 6, 3, 0, 33, 30, 27, 0, 0, 0 };
static uint8 br1[4] = { 6, 9, 12, 12 };
static double br2[4] = { .29, .45, .73, .9 };
static double br3[4] = { 0, .24, .47, .77 };
for (x = 0; x <= 3; x++)
for (z = 0; z < 16; z++) {
s = (double)ntsctint / 128;
luma = br2[x];
if (z == 0) {
s = 0; luma = ((double)br1[x]) / 12;
}
if (z >= 13) {
s = luma = 0;
if (z == 13)
luma = br3[x];
}
theta = (double)M_PI * (double)(((double)cols[z] * 10 + (((double)ntschue / 2) + 300)) / (double)180);
r = (int)((luma + s * sin(theta)) * 256);
g = (int)((luma - (double)27 / 53 * s * sin(theta) + (double)10 / 53 * s * cos(theta)) * 256);
b = (int)((luma - s * cos(theta)) * 256);
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
paletten[(x << 4) + z].r = r;
paletten[(x << 4) + z].g = g;
paletten[(x << 4) + z].b = b;
}
WritePalette();
}
int ipalette = 0;
void FCEU_LoadGamePalette(void) {
@ -228,10 +166,7 @@ static void ChoosePalette(void) {
palo = 0;
else if (ipalette)
palo = palettei;
else if (ntsccol && !PAL && GameInfo->type != GIT_VSUNI) {
palo = paletten;
CalculatePalette();
} else
else
palo = palpoint[pale];
}
@ -247,89 +182,3 @@ void WritePalette(void) {
SetNESDeemph(lastd, 1);
}
}
void FCEUI_GetNTSCTH(int *tint, int *hue) {
*tint = ntsctint;
*hue = ntschue;
}
static int controlselect = 0;
static int controllength = 0;
void FCEUI_NTSCDEC(void) {
if (ntsccol && GameInfo->type != GIT_VSUNI && !PAL && GameInfo->type != GIT_NSF) {
int which;
if (controlselect) {
if (controllength) {
which = controlselect == 1 ? ntschue : ntsctint;
which--;
if (which < 0) which = 0;
if (controlselect == 1)
ntschue = which;
else ntsctint = which;
CalculatePalette();
}
controllength = 360;
}
}
}
void FCEUI_NTSCINC(void) {
if (ntsccol && GameInfo->type != GIT_VSUNI && !PAL && GameInfo->type != GIT_NSF)
if (controlselect) {
if (controllength) {
switch (controlselect) {
case 1: ntschue++;
if (ntschue > 128) ntschue = 128;
CalculatePalette();
break;
case 2: ntsctint++;
if (ntsctint > 128) ntsctint = 128;
CalculatePalette();
break;
}
}
controllength = 360;
}
}
void FCEUI_NTSCSELHUE(void) {
if (ntsccol && GameInfo->type != GIT_VSUNI && !PAL && GameInfo->type != GIT_NSF) {
controlselect = 1; controllength = 360;
}
}
void FCEUI_NTSCSELTINT(void) {
if (ntsccol && GameInfo->type != GIT_VSUNI && !PAL && GameInfo->type != GIT_NSF) {
controlselect = 2; controllength = 360;
}
}
void FCEU_DrawNTSCControlBars(uint8 *XBuf) {
uint8 *XBaf;
int which = 0;
int x, x2;
if (!controllength) return;
controllength--;
if (!XBuf) return;
if (controlselect == 1) {
DrawTextTrans(XBuf + 128 - 12 + 180 * 256, 256, (uint8*)"Hue", 0x85);
which = ntschue << 1;
} else if (controlselect == 2) {
DrawTextTrans(XBuf + 128 - 16 + 180 * 256, 256, (uint8*)"Tint", 0x85);
which = ntsctint << 1;
}
XBaf = XBuf + 200 * 256;
for (x = 0; x < which; x += 2) {
for (x2 = 6; x2 >= -6; x2--) {
XBaf[x - 256 * x2] = 0x85;
}
}
for (; x < 256; x += 2) {
for (x2 = 2; x2 >= -2; x2--)
XBaf[x - 256 * x2] = 0x85;
}
}

View File

@ -12,6 +12,5 @@ void FCEU_ResetPalette(void);
void FCEU_ResetPalette(void);
void FCEU_ResetMessages();
void FCEU_LoadGamePalette(void);
void FCEU_DrawNTSCControlBars(uint8 *XBuf);
#endif

View File

@ -1096,26 +1096,6 @@ void FCEUPPU_Power(void) {
memset(UPALRAM, 0x00, 0x03);
memset(SPRAM, 0x00, 0x100);
FCEUPPU_Reset();
#ifdef COPYFAMI
for (x = 0x2000; x < 0x2010; x += 8) {
ARead[x] = A200x;
BWrite[x] = B2000;
ARead[x + 1] = A200x;
BWrite[x + 1] = B2001;
ARead[x + 2] = A2002;
BWrite[x + 2] = B2002;
ARead[x + 3] = A200x;
BWrite[x + 3] = B2003;
ARead[x + 4] = A200x; /* A2004; */
BWrite[x + 4] = B2004;
ARead[x + 5] = A200x;
BWrite[x + 5] = B2005;
ARead[x + 6] = A200x;
BWrite[x + 6] = B2006;
ARead[x + 7] = A2007;
BWrite[x + 7] = B2007;
}
#else
for (x = 0x2000; x < 0x4000; x += 8) {
ARead[x] = A200x;
BWrite[x] = B2000;
@ -1134,7 +1114,7 @@ void FCEUPPU_Power(void) {
ARead[x + 7] = A2007;
BWrite[x + 7] = B2007;
}
#endif
BWrite[0x4014] = B4014;
}

View File

@ -61,11 +61,7 @@ SFORMAT SFCPU[] = {
{ &X.S, 1, "S\0\0" },
{ &X.P, 1, "P\0\0" },
{ &X.DB, 1, "DB"},
#ifdef COPYFAMI
{ RAM, 0x4000, "RAM" },
#else
{ RAM, 0x800, "RAM" },
#endif
{ 0 }
};

View File

@ -622,11 +622,6 @@ static BMAPPING bmap[] = {
{ "BS-4040R", 422, Mapper422_Init, 0 },
{ "22026", 271, Mapper271_Init, 0 },
#ifdef COPYFAMI
{ "COPYFAMI_MMC3", NO_INES, MapperCopyFamiMMC3_Init, 0 },
{ "COPYFAMI", NO_INES, MapperCopyFami_Init, 0 },
#endif
{ NULL, NO_INES, NULL, 0 }
};
@ -849,17 +844,3 @@ int UNIFLoad(const char *name, FCEUFILE *fp) {
return 1;
}
int CopyFamiLoad() {
ResetCartMapping();
ResetExState(0, 0);
sboardname = (uint8_t*)"COPYFAMI";
if (!InitializeBoard()) {
Cleanup();
return 0;
}
GameInterface = UNIFGI;
return 1;
}

View File

@ -187,11 +187,6 @@ void WAIXINGFS005_Init(CartInfo *info);
void Mapper422_Init(CartInfo *info);
void Mapper444_Init(CartInfo *info);
#ifdef COPYFAMI
void MapperCopyFamiMMC3_Init(CartInfo *info);
void MapperCopyFami_Init(CartInfo *info);
#endif
extern uint8 *UNIFchrrama; /* Meh. So I can stop CHR RAM
* bank switcherooing with certain boards...
*/