initial checkin of tasbuild
[[Split portion of a mixed commit.]]
This commit is contained in:
commit
dfd763c100
|
@ -0,0 +1,17 @@
|
||||||
|
# A simulation of Subversion default ignores, generated by reposurgeon.
|
||||||
|
*.o
|
||||||
|
*.lo
|
||||||
|
*.la
|
||||||
|
*.al
|
||||||
|
*.libs
|
||||||
|
*.so
|
||||||
|
*.so.[0-9]*
|
||||||
|
*.a
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.rej
|
||||||
|
*~
|
||||||
|
*.#*
|
||||||
|
.*.swp
|
||||||
|
.DS_store
|
||||||
|
# Simulated Subversion default ignores end here
|
|
@ -0,0 +1,90 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 reg[8];
|
||||||
|
static uint8 mirror, cmd;
|
||||||
|
static uint8 *WRAM=NULL;
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&cmd, 1, "CMD"},
|
||||||
|
{&mirror, 1, "MIRR"},
|
||||||
|
{reg, 8, "REGS"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setmirror(mirror^1);
|
||||||
|
setprg8(0x8000,reg[0]);
|
||||||
|
setprg8(0xA000,reg[1]);
|
||||||
|
setchr2(0x0000,reg[2]>>1);
|
||||||
|
setchr2(0x0800,reg[3]>>1);
|
||||||
|
setchr1(0x1000,reg[4]);
|
||||||
|
setchr1(0x1400,reg[5]);
|
||||||
|
setchr1(0x1800,reg[6]);
|
||||||
|
setchr1(0x1C00,reg[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M112Write)
|
||||||
|
{
|
||||||
|
switch(A)
|
||||||
|
{
|
||||||
|
case 0xe000: mirror=V&1; Sync(); ;break;
|
||||||
|
case 0x8000: cmd=V&7; break;
|
||||||
|
case 0xa000: reg[cmd]=V; Sync(); break;
|
||||||
|
}
|
||||||
|
FCEU_printf("%04x:%04x %d\n",A,V,scanline);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M112Close(void)
|
||||||
|
{
|
||||||
|
if(WRAM)
|
||||||
|
FCEU_gfree(WRAM);
|
||||||
|
WRAM = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M112Power(void)
|
||||||
|
{
|
||||||
|
setprg16(0xC000,~0);
|
||||||
|
setprg8r(0x10,0x6000,0);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,M112Write);
|
||||||
|
SetReadHandler(0x6000,0x7FFF,CartBR);
|
||||||
|
SetWriteHandler(0x6000,0x7FFF,CartBW);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper112_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=M112Power;
|
||||||
|
info->Close=M112Close;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
WRAM=(uint8*)FCEU_gmalloc(8192);
|
||||||
|
SetupCartPRGMapping(0x10,WRAM,8192,1);
|
||||||
|
AddExState(WRAM, 8192, 0, "WRAM");
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 prgreg[4], chrreg[8];
|
||||||
|
static uint8 IRQa, IRQCount, IRQLatch;
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&IRQa, 1, "IRQA"},
|
||||||
|
{&IRQCount, 1, "IRQC"},
|
||||||
|
{&IRQLatch, 1, "IRQL"},
|
||||||
|
{prgreg, 4, "PREGS"},
|
||||||
|
{chrreg, 8, "CREGS"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setprg8(0x8000,prgreg[0]);
|
||||||
|
setprg8(0xa000,prgreg[1]);
|
||||||
|
setprg8(0xc000,prgreg[2]);
|
||||||
|
setprg8(0xe000,prgreg[3]);
|
||||||
|
int i;
|
||||||
|
for(i=0; i<8; i++)
|
||||||
|
setchr1(i<<10,chrreg[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M117Write)
|
||||||
|
{
|
||||||
|
if(A<0x8004)
|
||||||
|
{
|
||||||
|
prgreg[A&3]=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
else if((A>=0xA000)&&(A<=0xA007))
|
||||||
|
{
|
||||||
|
chrreg[A&7]=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
else switch(A)
|
||||||
|
{
|
||||||
|
case 0xc001: IRQLatch=V; break;
|
||||||
|
case 0xc003: IRQCount=IRQLatch; IRQa|=2; break;
|
||||||
|
case 0xe000: IRQa&=~1; IRQa|=V&1; X6502_IRQEnd(FCEU_IQEXT); break;
|
||||||
|
case 0xc002: X6502_IRQEnd(FCEU_IQEXT); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M117Power(void)
|
||||||
|
{
|
||||||
|
prgreg[0]=~3; prgreg[1]=~2; prgreg[2]=~1; prgreg[3]=~0;
|
||||||
|
Sync();
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,M117Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M117IRQHook(void)
|
||||||
|
{
|
||||||
|
if(IRQa==3&&IRQCount)
|
||||||
|
{
|
||||||
|
IRQCount--;
|
||||||
|
if(!IRQCount)
|
||||||
|
{
|
||||||
|
IRQa&=1;
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper117_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=M117Power;
|
||||||
|
GameHBIRQHook=M117IRQHook;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 cmd;
|
||||||
|
static uint8 DRegs[8];
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&cmd, 1, "CMD"},
|
||||||
|
{DRegs, 8, "DREG"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,(DRegs[0]<<4)|(DRegs[1]&0xF));
|
||||||
|
setchr8(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(Write)
|
||||||
|
{
|
||||||
|
switch (A&0x7300)
|
||||||
|
{
|
||||||
|
case 0x5100: DRegs[0]=V; Sync(); break;
|
||||||
|
case 0x5000: DRegs[1]=V; Sync(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(Write2)
|
||||||
|
{
|
||||||
|
switch (A&0x7300)
|
||||||
|
{
|
||||||
|
case 0x5200: DRegs[0]=V; Sync(); break;
|
||||||
|
case 0x5000: DRegs[1]=V; Sync(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 WRAM[8192];
|
||||||
|
static DECLFR(AWRAM)
|
||||||
|
{
|
||||||
|
return(WRAM[A-0x6000]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BWRAM)
|
||||||
|
{
|
||||||
|
WRAM[A-0x6000]=V;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Power(void)
|
||||||
|
{
|
||||||
|
memset(DRegs,0,8);
|
||||||
|
DRegs[1]=0xFF;
|
||||||
|
cmd=0;
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x4020,0xFFFF,Write);
|
||||||
|
SetReadHandler(0x6000,0x7FFF,AWRAM);
|
||||||
|
SetWriteHandler(0x6000,0x7FFF,BWRAM);
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M163HB(void)
|
||||||
|
{
|
||||||
|
if(scanline==127&&DRegs[1]&0x80)
|
||||||
|
setchr4(0x0000,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void Power2(void)
|
||||||
|
{
|
||||||
|
memset(DRegs,0,8);
|
||||||
|
DRegs[1]=0xFF;
|
||||||
|
cmd=0;
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x4020,0xFFFF,Write2);
|
||||||
|
SetReadHandler(0x6000,0x7FFF,AWRAM);
|
||||||
|
SetWriteHandler(0x6000,0x7FFF,BWRAM);
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper164_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=Power;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper163_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=Power2;
|
||||||
|
GameHBIRQHook=M163HB;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*
|
||||||
|
* Gimmick Bootleg
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 prg[4];
|
||||||
|
static uint8 chr[8];
|
||||||
|
static uint8 IRQCount;
|
||||||
|
static uint8 IRQPre;
|
||||||
|
static uint8 IRQa;
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{prg, 4, "PRG"},
|
||||||
|
{chr, 8, "CHR"},
|
||||||
|
{&IRQCount, 1, "IRQCOUNT"},
|
||||||
|
{&IRQPre, 1, "IRQPRE"},
|
||||||
|
{&IRQa, 1, "IRQA"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void SyncPrg(void)
|
||||||
|
{
|
||||||
|
setprg8(0x6000,0);
|
||||||
|
setprg8(0x8000,prg[0]);
|
||||||
|
setprg8(0xA000,prg[1]);
|
||||||
|
setprg8(0xC000,prg[2]);
|
||||||
|
setprg8(0xE000,~0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SyncChr(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0; i<8; i++)
|
||||||
|
setchr1(i<<10,chr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
SyncPrg();
|
||||||
|
SyncChr();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M183Write)
|
||||||
|
{
|
||||||
|
if(((A&0xF80C)>=0xB000)&&((A&0xF80C)<=0xE00C))
|
||||||
|
{
|
||||||
|
uint8 index=(((A&0x7000)>>11)-6)|((A&8)>>3);
|
||||||
|
chr[index]=(chr[index]&(0xF0>>(A&4)))|((V&0x0F)<<(A&4));
|
||||||
|
SyncChr();
|
||||||
|
}
|
||||||
|
else switch (A&0xF80C)
|
||||||
|
{
|
||||||
|
case 0x8800: prg[0]=V; SyncPrg(); break;
|
||||||
|
case 0xA800: prg[1]=V; SyncPrg(); break;
|
||||||
|
case 0xA000: prg[2]=V; SyncPrg(); break;
|
||||||
|
case 0x9800: switch (V&3)
|
||||||
|
{
|
||||||
|
case 0: setmirror(MI_V); break;
|
||||||
|
case 1: setmirror(MI_H); break;
|
||||||
|
case 2: setmirror(MI_0); break;
|
||||||
|
case 3: setmirror(MI_1); break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xF000: IRQCount=((IRQCount&0xF0)|(V&0xF)); break;
|
||||||
|
case 0xF004: IRQCount=((IRQCount&0x0F)|((V&0xF)<<4)); break;
|
||||||
|
case 0xF008: IRQa=V; if(!V)IRQPre=0; X6502_IRQEnd(FCEU_IQEXT); break;
|
||||||
|
case 0xF00C: IRQPre=16; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M183IRQCounter(void)
|
||||||
|
{
|
||||||
|
if(IRQa)
|
||||||
|
{
|
||||||
|
IRQCount++;
|
||||||
|
if((IRQCount-IRQPre)==238)
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M183Power(void)
|
||||||
|
{
|
||||||
|
IRQPre=IRQCount=IRQa=0;
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,M183Write);
|
||||||
|
SetReadHandler(0x6000,0x7FFF,CartBR);
|
||||||
|
SyncPrg();
|
||||||
|
SyncChr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper183_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=M183Power;
|
||||||
|
GameHBIRQHook=M183IRQCounter;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*
|
||||||
|
* Family Study Box by Fukutake Shoten
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 *DummyCHR=NULL;
|
||||||
|
static uint8 datareg;
|
||||||
|
static void(*Sync)(void);
|
||||||
|
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&datareg, 1, "DREG"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
// on off
|
||||||
|
//1 0x0F, 0xF0 - Bird Week
|
||||||
|
//2 0x33, 0x00 - B-Wings
|
||||||
|
//3 0x11, 0x00 - Mighty Bomb Jack
|
||||||
|
//4 0x22, 0x20 - Sansuu 1 Nen, Sansuu 2 Nen
|
||||||
|
//5 0xFF, 0x00 - Sansuu 3 Nen
|
||||||
|
//6 0x21, 0x13 - Spy vs Spy
|
||||||
|
//7 0x20, 0x21 - Seicross
|
||||||
|
|
||||||
|
static void Sync185(void)
|
||||||
|
{
|
||||||
|
// little dirty eh? ;_)
|
||||||
|
if((datareg&3)&&(datareg!=0x13)) // 1, 2, 3, 4, 5, 6
|
||||||
|
setchr8(0);
|
||||||
|
else
|
||||||
|
setchr8r(0x10,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Sync181(void)
|
||||||
|
{
|
||||||
|
if(!(datareg&1)) // 7
|
||||||
|
setchr8(0);
|
||||||
|
else
|
||||||
|
setchr8r(0x10,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(MWrite)
|
||||||
|
{
|
||||||
|
datareg=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MPower(void)
|
||||||
|
{
|
||||||
|
datareg=0;
|
||||||
|
Sync();
|
||||||
|
setprg16(0x8000,0);
|
||||||
|
setprg16(0xC000,~0);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,MWrite);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MClose(void)
|
||||||
|
{
|
||||||
|
if(DummyCHR)
|
||||||
|
FCEU_gfree(DummyCHR);
|
||||||
|
DummyCHR=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper185_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Sync=Sync185;
|
||||||
|
info->Power=MPower;
|
||||||
|
info->Close=MClose;
|
||||||
|
GameStateRestore=MRestore;
|
||||||
|
DummyCHR=(uint8*)FCEU_gmalloc(8192);
|
||||||
|
int x;
|
||||||
|
for(x=0;x<8192;x++)
|
||||||
|
DummyCHR[x]=0xff;
|
||||||
|
SetupCartCHRMapping(0x10,DummyCHR,8192,0);
|
||||||
|
AddExState(StateRegs, ~0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper181_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Sync=Sync181;
|
||||||
|
info->Power=MPower;
|
||||||
|
info->Close=MClose;
|
||||||
|
GameStateRestore=MRestore;
|
||||||
|
DummyCHR=(uint8*)FCEU_gmalloc(8192);
|
||||||
|
int x;
|
||||||
|
for(x=0;x<8192;x++)
|
||||||
|
DummyCHR[x]=0xff;
|
||||||
|
SetupCartCHRMapping(0x10,DummyCHR,8192,0);
|
||||||
|
AddExState(StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*
|
||||||
|
* Family Study Box by Fukutake Shoten
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 SWRAM[2816];
|
||||||
|
static uint8 *WRAM=NULL;
|
||||||
|
static uint8 regs[4];
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{regs, 4, "DREG"},
|
||||||
|
{SWRAM, 2816, "SWRAM"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setprg8r(0x10,0x6000,regs[0]>>6);
|
||||||
|
setprg16(0x8000,regs[1]);
|
||||||
|
setprg16(0xc000,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M186Write)
|
||||||
|
{
|
||||||
|
if(A&0x4203) regs[A&3]=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(M186Read)
|
||||||
|
{
|
||||||
|
switch(A)
|
||||||
|
{
|
||||||
|
case 0x4200: return 0x00; break;
|
||||||
|
case 0x4201: return 0x00; break;
|
||||||
|
case 0x4202: return 0x40; break;
|
||||||
|
case 0x4203: return 0x00; break;
|
||||||
|
}
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(ASWRAM)
|
||||||
|
{
|
||||||
|
return(SWRAM[A-0x4400]);
|
||||||
|
}
|
||||||
|
static DECLFW(BSWRAM)
|
||||||
|
{
|
||||||
|
SWRAM[A-0x4400]=V;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M186Power(void)
|
||||||
|
{
|
||||||
|
setchr8(0);
|
||||||
|
SetReadHandler(0x6000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x6000,0xFFFF,CartBW);
|
||||||
|
SetReadHandler(0x4200,0x43FF,M186Read);
|
||||||
|
SetWriteHandler(0x4200,0x43FF,M186Write);
|
||||||
|
SetReadHandler(0x4400,0x4EFF,ASWRAM);
|
||||||
|
SetWriteHandler(0x4400,0x4EFF,BSWRAM);
|
||||||
|
regs[0]=regs[1]=regs[2]=regs[3];
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M186Close(void)
|
||||||
|
{
|
||||||
|
if(WRAM)
|
||||||
|
FCEU_gfree(WRAM);
|
||||||
|
WRAM=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M186Restore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper186_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=M186Power;
|
||||||
|
info->Close=M186Close;
|
||||||
|
GameStateRestore=M186Restore;
|
||||||
|
WRAM=(uint8*)FCEU_gmalloc(32384);
|
||||||
|
SetupCartPRGMapping(0x10,WRAM,32384,1);
|
||||||
|
AddExState(WRAM, 32384, 0, "WRAM");
|
||||||
|
AddExState(StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
#include "mmc3.h"
|
||||||
|
|
||||||
|
static void M187CW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if((A&0x1000)==((MMC3_cmd&0x80)<<5))
|
||||||
|
setchr1(A,V|0x100);
|
||||||
|
else
|
||||||
|
setchr1(A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M187PW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&0x80)
|
||||||
|
{
|
||||||
|
uint8 bank=EXPREGS[0]&0x1F;
|
||||||
|
if(EXPREGS[0]&0x20)
|
||||||
|
setprg32(0x8000,bank>>2);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setprg16(0x8000,bank);
|
||||||
|
setprg16(0xC000,bank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setprg8(A,V&0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M187Write8000)
|
||||||
|
{
|
||||||
|
EXPREGS[2]=1;
|
||||||
|
MMC3_CMDWrite(A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M187Write8001)
|
||||||
|
{
|
||||||
|
if(EXPREGS[2])
|
||||||
|
MMC3_CMDWrite(A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M187Write8003)
|
||||||
|
{
|
||||||
|
EXPREGS[2]=0;
|
||||||
|
if(V==0x28)setprg8(0xC000,0x17);
|
||||||
|
else if(V==0x2A)setprg8(0xA000,0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DECLFW(M187WriteLo)
|
||||||
|
{
|
||||||
|
EXPREGS[1]=V;
|
||||||
|
if(A==0x5000)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=V;
|
||||||
|
FixMMC3PRG(MMC3_cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 prot_data[4] = { 0x83, 0x83, 0x42, 0x00 };
|
||||||
|
static DECLFR(M187Read)
|
||||||
|
{
|
||||||
|
return prot_data[EXPREGS[1]&3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M187Power(void)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=0;
|
||||||
|
GenMMC3Power();
|
||||||
|
Write_IRQFM(0x4017,0x40);
|
||||||
|
SetReadHandler(0x5000,0x5FFF,M187Read);
|
||||||
|
SetWriteHandler(0x5000,0x5FFF,M187WriteLo);
|
||||||
|
SetWriteHandler(0x8000,0x8000,M187Write8000);
|
||||||
|
SetWriteHandler(0x8001,0x8001,M187Write8001);
|
||||||
|
SetWriteHandler(0x8003,0x8003,M187Write8003);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper187_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC3_Init(info, 256, 256, 0, 0);
|
||||||
|
pwrap=M187PW;
|
||||||
|
cwrap=M187CW;
|
||||||
|
info->Power=M187Power;
|
||||||
|
AddExState(EXPREGS, 3, 0, "EXPR");
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
#include "mmc3.h"
|
||||||
|
|
||||||
|
static void M189PW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,EXPREGS[0]&3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M189Write)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=V|(V>>4); //actually, there is a two versions of 189 mapper with hi or lo bits bankswitching.
|
||||||
|
FixMMC3PRG(MMC3_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M189Power(void)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=EXPREGS[1]=0;
|
||||||
|
GenMMC3Power();
|
||||||
|
SetWriteHandler(0x4120,0x7FFF,M189Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper189_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC3_Init(info, 256, 256, 0, 0);
|
||||||
|
pwrap=M189PW;
|
||||||
|
info->Power=M189Power;
|
||||||
|
AddExState(EXPREGS, 2, 0, "EXPR");
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
#include "mmc3.h"
|
||||||
|
|
||||||
|
static uint8 lut[256]={
|
||||||
|
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,0x59, 0x49, 0x19, 0x09, 0x59, 0x49, 0x19, 0x09,
|
||||||
|
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,0x51, 0x41, 0x11, 0x01, 0x51, 0x41, 0x11, 0x01,
|
||||||
|
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,0x59, 0x49, 0x19, 0x09, 0x59, 0x49, 0x19, 0x09,
|
||||||
|
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,0x51, 0x41, 0x11, 0x01, 0x51, 0x41, 0x11, 0x01,
|
||||||
|
0x00, 0x10, 0x40, 0x50, 0x00, 0x10, 0x40, 0x50,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x18, 0x48, 0x58, 0x08, 0x18, 0x48, 0x58,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x40, 0x50, 0x00, 0x10, 0x40, 0x50,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x18, 0x48, 0x58, 0x08, 0x18, 0x48, 0x58,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,0x58, 0x48, 0x18, 0x08, 0x58, 0x48, 0x18, 0x08,
|
||||||
|
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,0x50, 0x40, 0x10, 0x00, 0x50, 0x40, 0x10, 0x00,
|
||||||
|
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,0x58, 0x48, 0x18, 0x08, 0x58, 0x48, 0x18, 0x08,
|
||||||
|
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,0x50, 0x40, 0x10, 0x00, 0x50, 0x40, 0x10, 0x00,
|
||||||
|
0x01, 0x11, 0x41, 0x51, 0x01, 0x11, 0x41, 0x51,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x09, 0x19, 0x49, 0x59, 0x09, 0x19, 0x49, 0x59,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x11, 0x41, 0x51, 0x01, 0x11, 0x41, 0x51,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x09, 0x19, 0x49, 0x59, 0x09, 0x19, 0x49, 0x59,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static void M208PW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,EXPREGS[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M208Write)
|
||||||
|
{
|
||||||
|
EXPREGS[5]=(V&0x1)|((V>>3)&0x2);
|
||||||
|
FixMMC3PRG(MMC3_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M208ProtWrite)
|
||||||
|
{
|
||||||
|
if(A<=0x57FF)
|
||||||
|
EXPREGS[4]=V;
|
||||||
|
else
|
||||||
|
EXPREGS[(A&0x03)]=V^lut[EXPREGS[4]];
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(M208ProtRead)
|
||||||
|
{
|
||||||
|
return(EXPREGS[(A&0x3)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M208Power(void)
|
||||||
|
{
|
||||||
|
EXPREGS[5]=3;
|
||||||
|
GenMMC3Power();
|
||||||
|
SetWriteHandler(0x4800,0x4FFF,M208Write);
|
||||||
|
SetWriteHandler(0x5000,0x5fff,M208ProtWrite);
|
||||||
|
SetReadHandler(0x5800,0x5FFF,M208ProtRead);
|
||||||
|
SetReadHandler(0x8000,0xffff,CartBR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper208_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC3_Init(info, 128, 256, 0, 0);
|
||||||
|
pwrap=M208PW;
|
||||||
|
info->Power=M208Power;
|
||||||
|
AddExState(EXPREGS, 6, 0, "EXPR");
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint16 IRQCount;
|
||||||
|
static uint8 IRQa;
|
||||||
|
static uint8 prg_reg[2];
|
||||||
|
static uint8 chr_reg[8];
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&IRQCount, 2, "IRQC"},
|
||||||
|
{&IRQa, 2, "IRQA"},
|
||||||
|
{prg_reg, 2, "PRG"},
|
||||||
|
{chr_reg, 8, "CHR"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void M222IRQ(void)
|
||||||
|
{
|
||||||
|
if(IRQa)
|
||||||
|
{
|
||||||
|
IRQCount++;
|
||||||
|
if(IRQCount>=240)
|
||||||
|
{
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
IRQa=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setprg8(0x8000,prg_reg[0]);
|
||||||
|
setprg8(0xA000,prg_reg[1]);
|
||||||
|
int i;
|
||||||
|
for(i=0; i<8; i++)
|
||||||
|
setchr1(i<<10,chr_reg[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M222Write)
|
||||||
|
{
|
||||||
|
switch(A&0xF003)
|
||||||
|
{
|
||||||
|
case 0x8000: prg_reg[0]=V; break;
|
||||||
|
case 0xA000: prg_reg[1]=V; break;
|
||||||
|
case 0xB000: chr_reg[0]=V; break;
|
||||||
|
case 0xB002: chr_reg[1]=V; break;
|
||||||
|
case 0xC000: chr_reg[2]=V; break;
|
||||||
|
case 0xC002: chr_reg[3]=V; break;
|
||||||
|
case 0xD000: chr_reg[4]=V; break;
|
||||||
|
case 0xD002: chr_reg[5]=V; break;
|
||||||
|
case 0xE000: chr_reg[6]=V; break;
|
||||||
|
case 0xE002: chr_reg[7]=V; break;
|
||||||
|
case 0xF000: IRQCount=IRQa=V;
|
||||||
|
X6502_IRQEnd(FCEU_IQEXT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M222Power(void)
|
||||||
|
{
|
||||||
|
setprg16(0xC000,~0);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,M222Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper222_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=M222Power;
|
||||||
|
GameHBIRQHook=M222IRQ;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint16 cmdreg;
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&cmdreg, 2, "CMDREG"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
if(cmdreg&0x400)
|
||||||
|
setmirror(MI_0);
|
||||||
|
else
|
||||||
|
setmirror(((cmdreg>>13)&1)^1);
|
||||||
|
if(cmdreg&0x800)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,((cmdreg&0x300)>>3)|((cmdreg&0x1F)<<1)|((cmdreg>>12)&1));
|
||||||
|
setprg16(0xC000,((cmdreg&0x300)>>3)|((cmdreg&0x1F)<<1)|((cmdreg>>12)&1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setprg32(0x8000,((cmdreg&0x300)>>4)|(cmdreg&0x1F));
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M235Write)
|
||||||
|
{
|
||||||
|
cmdreg=A;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M235Power(void)
|
||||||
|
{
|
||||||
|
setchr8(0);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,M235Write);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
cmdreg=0;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M235Restore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper235_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=M235Power;
|
||||||
|
GameStateRestore=M235Restore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 prg_reg;
|
||||||
|
static uint8 chr_reg;
|
||||||
|
static uint8 hrd_flag;
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&prg_reg, 1, "PRG"},
|
||||||
|
{&chr_reg, 1, "CHR"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
if(prg_reg&0x80)
|
||||||
|
setprg32(0x8000,prg_reg>>6);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setprg16(0x8000,(prg_reg>>5)&3);
|
||||||
|
setprg16(0xC000,(prg_reg>>5)&3);
|
||||||
|
}
|
||||||
|
setmirror((prg_reg&8)>>3);
|
||||||
|
setchr8((chr_reg&3)|(prg_reg&7)|((prg_reg&0x10)>>1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(M57Read)
|
||||||
|
{
|
||||||
|
return hrd_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M57Write)
|
||||||
|
{
|
||||||
|
if((A&0x8800)==0x8800)
|
||||||
|
prg_reg=V;
|
||||||
|
else
|
||||||
|
chr_reg=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M57Power(void)
|
||||||
|
{
|
||||||
|
prg_reg=0;
|
||||||
|
chr_reg=0;
|
||||||
|
hrd_flag=0;
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,M57Write);
|
||||||
|
SetReadHandler(0x6000,0x6000,M57Read);
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M57Reset()
|
||||||
|
{
|
||||||
|
if(hrd_flag==3)
|
||||||
|
hrd_flag=0;
|
||||||
|
else
|
||||||
|
hrd_flag++;
|
||||||
|
FCEU_printf("Select Register = %02x\n",hrd_flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper57_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=M57Power;
|
||||||
|
info->Reset=M57Reset;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint16 cmdreg;
|
||||||
|
static uint8 invalid_data;
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&cmdreg, 2, "CMDREG"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setprg16r((cmdreg&0x060)>>5,0x8000,(cmdreg&0x01C)>>2);
|
||||||
|
setprg16r((cmdreg&0x060)>>5,0xC000,(cmdreg&0x200)?(~0):0);
|
||||||
|
setmirror(((cmdreg&2)>>1)^1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(UNL8157Read)
|
||||||
|
{
|
||||||
|
if(invalid_data&&cmdreg&0x100)
|
||||||
|
return 0xFF;
|
||||||
|
else
|
||||||
|
return CartBR(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(UNL8157Write)
|
||||||
|
{
|
||||||
|
cmdreg=A;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNL8157Power(void)
|
||||||
|
{
|
||||||
|
setchr8(0);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,UNL8157Write);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,UNL8157Read);
|
||||||
|
cmdreg=0x200;
|
||||||
|
invalid_data=1;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNL8157Reset(void)
|
||||||
|
{
|
||||||
|
cmdreg=0;
|
||||||
|
invalid_data^=1;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNL8157Restore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNL8157_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=UNL8157Power;
|
||||||
|
info->Reset=UNL8157Reset;
|
||||||
|
GameStateRestore=UNL8157Restore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
#include "mmc3.h"
|
||||||
|
|
||||||
|
static uint8 cmdin;
|
||||||
|
static uint8 UNL8237_perm[8] = {0, 2, 6, 1, 7, 3, 4, 5};
|
||||||
|
|
||||||
|
static void UNL8237CW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
setchr1(A,((EXPREGS[1]&4)<<6)|V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNL8237PW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&0x80)
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&0x20)
|
||||||
|
setprg32(0x8000,(EXPREGS[0]&0xF)>>1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setprg16(0x8000,(EXPREGS[0]&0x1F));
|
||||||
|
setprg16(0xC000,(EXPREGS[0]&0x1F));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setprg8(A,V&0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(UNL8237Write)
|
||||||
|
{
|
||||||
|
if((A&0xF000)==0xF000)
|
||||||
|
IRQCount=V;
|
||||||
|
else if((A&0xF000)==0xE000)
|
||||||
|
X6502_IRQEnd(FCEU_IQEXT);
|
||||||
|
else switch(A&0xE001)
|
||||||
|
{
|
||||||
|
case 0x8000: setmirror(((V|(V>>7))&1)^1); break;
|
||||||
|
case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(UNL8237_perm[V&7])); cmdin=1; break;
|
||||||
|
case 0xC000: if(cmdin)
|
||||||
|
{
|
||||||
|
MMC3_CMDWrite(0x8001,V);
|
||||||
|
cmdin=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(UNL8237ExWrite)
|
||||||
|
{
|
||||||
|
switch(A)
|
||||||
|
{
|
||||||
|
case 0x5000: EXPREGS[0]=V; FixMMC3PRG(MMC3_cmd); break;
|
||||||
|
case 0x5001: EXPREGS[1]=V; FixMMC3CHR(MMC3_cmd); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNL8237Power(void)
|
||||||
|
{
|
||||||
|
IRQa=1;
|
||||||
|
EXPREGS[0]=EXPREGS[1]=0;
|
||||||
|
GenMMC3Power();
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,UNL8237Write);
|
||||||
|
SetWriteHandler(0x5000,0x7FFF,UNL8237ExWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNL8237_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC3_Init(info, 256, 256, 0, 0);
|
||||||
|
cwrap=UNL8237CW;
|
||||||
|
pwrap=UNL8237PW;
|
||||||
|
info->Power=UNL8237Power;
|
||||||
|
AddExState(EXPREGS, 3, 0, "EXPR");
|
||||||
|
AddExState(&cmdin, 1, 0, "CMDIN");
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 reg[8];
|
||||||
|
static uint8 mirror, cmd, is154;
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&cmd, 1, "CMD"},
|
||||||
|
{&mirror, 1, "MIRR"},
|
||||||
|
{reg, 8, "REGS"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setchr2(0x0000,reg[0]>>1);
|
||||||
|
setchr2(0x0800,reg[1]>>1);
|
||||||
|
setchr1(0x1000,reg[2]|0x40);
|
||||||
|
setchr1(0x1400,reg[3]|0x40);
|
||||||
|
setchr1(0x1800,reg[4]|0x40);
|
||||||
|
setchr1(0x1C00,reg[5]|0x40);
|
||||||
|
setprg8(0x8000,reg[6]);
|
||||||
|
setprg8(0xA000,reg[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MSync(void)
|
||||||
|
{
|
||||||
|
if(is154)setmirror(MI_0+(mirror&1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M88Write)
|
||||||
|
{
|
||||||
|
switch(A&0x8001)
|
||||||
|
{
|
||||||
|
case 0x8000: cmd=V&7; mirror=V>>6; MSync(); break;
|
||||||
|
case 0x8001: reg[cmd]=V; Sync(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M88Power(void)
|
||||||
|
{
|
||||||
|
setprg16(0xC000,~0);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,M88Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
MSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper88_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
is154=0;
|
||||||
|
info->Power=M88Power;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper154_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
is154=1;
|
||||||
|
info->Power=M88Power;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,466 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
//#define DEBUG90
|
||||||
|
|
||||||
|
static int is209;
|
||||||
|
static int is211;
|
||||||
|
|
||||||
|
static uint8 IRQMode; // from $c001
|
||||||
|
static uint8 IRQPre; // from $c004
|
||||||
|
static uint8 IRQPreSize; // from $c007
|
||||||
|
static uint8 IRQCount; // from $c005
|
||||||
|
static uint8 IRQXOR; // Loaded from $C006
|
||||||
|
static uint8 IRQa; // $c002, $c003, and $c000
|
||||||
|
|
||||||
|
static uint8 mul[2];
|
||||||
|
static uint8 regie;
|
||||||
|
|
||||||
|
static uint8 tkcom[4];
|
||||||
|
static uint8 prgb[4];
|
||||||
|
static uint8 chrlow[8];
|
||||||
|
static uint8 chrhigh[8];
|
||||||
|
|
||||||
|
static uint16 names[4];
|
||||||
|
static uint8 tekker;
|
||||||
|
|
||||||
|
static SFORMAT Tek_StateRegs[]={
|
||||||
|
{&IRQMode, 1, "IRQMODE"},
|
||||||
|
{&IRQPre, 1, "IRQPRE"},
|
||||||
|
{&IRQPreSize, 1, "IRQPRESIZE"},
|
||||||
|
{&IRQCount, 1, "IRQC"},
|
||||||
|
{&IRQXOR, 1, "IRQXOR"},
|
||||||
|
{&IRQa, 1, "IRQa"},
|
||||||
|
{mul, 2, "MUL"},
|
||||||
|
{®ie, 1, "REGI"},
|
||||||
|
{tkcom, 4, "TKCO"},
|
||||||
|
{prgb, 4, "PRGB"},
|
||||||
|
{chrlow, 4, "CHRL"},
|
||||||
|
{chrhigh, 8, "CHRH"},
|
||||||
|
{&names[0], 2|FCEUSTATE_RLSB, "NMS0"},
|
||||||
|
{&names[1], 2|FCEUSTATE_RLSB, "NMS1"},
|
||||||
|
{&names[2], 2|FCEUSTATE_RLSB, "NMS2"},
|
||||||
|
{&names[3], 2|FCEUSTATE_RLSB, "NMS3"},
|
||||||
|
{&tekker, 1, "TEKR"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void mira(void)
|
||||||
|
{
|
||||||
|
if((tkcom[0]&0x20&&is209)||is211)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
if(tkcom[0]&0x40) // Name tables are ROM-only
|
||||||
|
{
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
setntamem(CHRptr[0]+(((names[x])&CHRmask1[0])<<10),0,x);
|
||||||
|
}
|
||||||
|
else // Name tables can be RAM or ROM.
|
||||||
|
{
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
{
|
||||||
|
if((tkcom[1]&0x80)==(names[x]&0x80)) // RAM selected.
|
||||||
|
setntamem(NTARAM+((names[x]&0x1)<<10),1,x);
|
||||||
|
else
|
||||||
|
setntamem(CHRptr[0]+(((names[x])&CHRmask1[0])<<10),0,x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(tkcom[1]&3)
|
||||||
|
{
|
||||||
|
case 0: setmirror(MI_V); break;
|
||||||
|
case 1: setmirror(MI_H); break;
|
||||||
|
case 2: setmirror(MI_0); break;
|
||||||
|
case 3: setmirror(MI_1); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tekprom(void)
|
||||||
|
{
|
||||||
|
uint32 bankmode=((tkcom[3]&6)<<5);
|
||||||
|
switch(tkcom[0]&7)
|
||||||
|
{
|
||||||
|
case 00: if(tkcom[0]&0x80)
|
||||||
|
setprg8(0x6000,(((prgb[3]<<2)+3)&0x3F)|bankmode);
|
||||||
|
setprg32(0x8000,0x0F|((tkcom[3]&6)<<3));
|
||||||
|
break;
|
||||||
|
case 01: if(tkcom[0]&0x80)
|
||||||
|
setprg8(0x6000,(((prgb[3]<<1)+1)&0x3F)|bankmode);
|
||||||
|
setprg16(0x8000,(prgb[1]&0x1F)|((tkcom[3]&6)<<4));
|
||||||
|
setprg16(0xC000,0x1F|((tkcom[3]&6)<<4));
|
||||||
|
break;
|
||||||
|
case 03: // bit reversion
|
||||||
|
case 02: if(tkcom[0]&0x80)
|
||||||
|
setprg8(0x6000,(prgb[3]&0x3F)|bankmode);
|
||||||
|
setprg8(0x8000,(prgb[0]&0x3F)|bankmode);
|
||||||
|
setprg8(0xa000,(prgb[1]&0x3F)|bankmode);
|
||||||
|
setprg8(0xc000,(prgb[2]&0x3F)|bankmode);
|
||||||
|
setprg8(0xe000,0x3F|bankmode);
|
||||||
|
break;
|
||||||
|
case 04: if(tkcom[0]&0x80)
|
||||||
|
setprg8(0x6000,(((prgb[3]<<2)+3)&0x3F)|bankmode);
|
||||||
|
setprg32(0x8000,(prgb[3]&0x0F)|((tkcom[3]&6)<<3));
|
||||||
|
break;
|
||||||
|
case 05: if(tkcom[0]&0x80)
|
||||||
|
setprg8(0x6000,(((prgb[3]<<1)+1)&0x3F)|bankmode);
|
||||||
|
setprg16(0x8000,(prgb[1]&0x1F)|((tkcom[3]&6)<<4));
|
||||||
|
setprg16(0xC000,(prgb[3]&0x1F)|((tkcom[3]&6)<<4));
|
||||||
|
break;
|
||||||
|
case 07: // bit reversion
|
||||||
|
case 06: if(tkcom[0]&0x80)
|
||||||
|
setprg8(0x6000,(prgb[3]&0x3F)|bankmode);
|
||||||
|
setprg8(0x8000,(prgb[0]&0x3F)|bankmode);
|
||||||
|
setprg8(0xa000,(prgb[1]&0x3F)|bankmode);
|
||||||
|
setprg8(0xc000,(prgb[2]&0x3F)|bankmode);
|
||||||
|
setprg8(0xe000,(prgb[3]&0x3F)|bankmode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tekvrom(void)
|
||||||
|
{
|
||||||
|
int x, bank=0, mask=0xFFFF;
|
||||||
|
if(!(tkcom[3]&0x20))
|
||||||
|
{
|
||||||
|
bank=(tkcom[3]&1)|((tkcom[3]&0x18)>>2);
|
||||||
|
switch (tkcom[0]&0x18)
|
||||||
|
{
|
||||||
|
case 0x00: bank<<=5; mask=0x1F; break;
|
||||||
|
case 0x08: bank<<=6; mask=0x3F; break;
|
||||||
|
case 0x10: bank<<=7; mask=0x7F; break;
|
||||||
|
case 0x18: bank<<=8; mask=0xFF; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch(tkcom[0]&0x18)
|
||||||
|
{
|
||||||
|
case 0x00: // 8KB
|
||||||
|
setchr8(((chrlow[0]|(chrhigh[0]<<8))&mask)|bank);
|
||||||
|
break;
|
||||||
|
case 0x08: // 4KB
|
||||||
|
for(x=0;x<8;x+=4)
|
||||||
|
setchr4(x<<10,((chrlow[x]|(chrhigh[x]<<8))&mask)|bank);
|
||||||
|
break;
|
||||||
|
case 0x10: // 2KB
|
||||||
|
for(x=0;x<8;x+=2)
|
||||||
|
setchr2(x<<10,((chrlow[x]|(chrhigh[x]<<8))&mask)|bank);
|
||||||
|
break;
|
||||||
|
case 0x18: // 1KB
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
setchr1(x<<10,((chrlow[x]|(chrhigh[x]<<8))&mask)|bank);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M90TekWrite)
|
||||||
|
{
|
||||||
|
switch(A)
|
||||||
|
{
|
||||||
|
case 0x5800: mul[0]=V; break;
|
||||||
|
case 0x5801: mul[1]=V; break;
|
||||||
|
case 0x5803: regie=V; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(M90TekRead)
|
||||||
|
{
|
||||||
|
switch(A)
|
||||||
|
{
|
||||||
|
case 0x5800: return (mul[0]*mul[1]);
|
||||||
|
case 0x5801: return((mul[0]*mul[1])>>8);
|
||||||
|
case 0x5803: return (regie);
|
||||||
|
}
|
||||||
|
return(tekker);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M90PRGWrite)
|
||||||
|
{
|
||||||
|
prgb[A&3]=V;
|
||||||
|
tekprom();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M90CHRlowWrite)
|
||||||
|
{
|
||||||
|
chrlow[A&7]=V;
|
||||||
|
tekvrom();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M90CHRhiWrite)
|
||||||
|
{
|
||||||
|
chrhigh[A&7]=V;
|
||||||
|
tekvrom();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M90NTWrite)
|
||||||
|
{
|
||||||
|
if(A&4)
|
||||||
|
{
|
||||||
|
names[A&3]&=0x00FF;
|
||||||
|
names[A&3]|=V<<8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
names[A&3]&=0xFF00;
|
||||||
|
names[A&3]|=V;
|
||||||
|
}
|
||||||
|
mira();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M90IRQWrite)
|
||||||
|
{
|
||||||
|
switch(A&7)
|
||||||
|
{
|
||||||
|
case 00: //FCEU_printf("%s IRQ (C000)\n",V&1?"Enable":"Disable");
|
||||||
|
IRQa=V&1;if(!(V&1)) X6502_IRQEnd(FCEU_IQEXT);break;
|
||||||
|
case 02: //FCEU_printf("Disable IRQ (C002) scanline=%d\n", scanline);
|
||||||
|
IRQa=0;X6502_IRQEnd(FCEU_IQEXT);break;
|
||||||
|
case 03: //FCEU_printf("Enable IRQ (C003) scanline=%d\n", scanline);
|
||||||
|
IRQa=1;break;
|
||||||
|
case 01: IRQMode=V;
|
||||||
|
/* FCEU_printf("IRQ Count method: ");
|
||||||
|
switch (IRQMode&3)
|
||||||
|
{
|
||||||
|
case 00: FCEU_printf("M2 cycles\n");break;
|
||||||
|
case 01: FCEU_printf("PPU A12 toggles\n");break;
|
||||||
|
case 02: FCEU_printf("PPU reads\n");break;
|
||||||
|
case 03: FCEU_printf("Writes to CPU space\n");break;
|
||||||
|
}
|
||||||
|
FCEU_printf("Counter prescaler size: %s\n",(IRQMode&4)?"3 bits":"8 bits");
|
||||||
|
FCEU_printf("Counter prescaler size adjust: %s\n",(IRQMode&8)?"Used C007":"Normal Operation");
|
||||||
|
if((IRQMode>>6)==2) FCEU_printf("Counter Down\n");
|
||||||
|
else if((IRQMode>>6)==1) FCEU_printf("Counter Up\n");
|
||||||
|
else FCEU_printf("Counter Stopped\n");
|
||||||
|
*/ break;
|
||||||
|
case 04: //FCEU_printf("Pre Counter Loaded and Xored wiht C006: %d\n",V^IRQXOR);
|
||||||
|
IRQPre=V^IRQXOR;break;
|
||||||
|
case 05: //FCEU_printf("Main Counter Loaded and Xored wiht C006: %d\n",V^IRQXOR);
|
||||||
|
IRQCount=V^IRQXOR;break;
|
||||||
|
case 06: //FCEU_printf("Xor Value: %d\n",V);
|
||||||
|
IRQXOR=V;break;
|
||||||
|
case 07: //if(!(IRQMode&8)) FCEU_printf("C001 is clear, no effect applied\n");
|
||||||
|
// else if(V==0xFF) FCEU_printf("Prescaler is changed for 12bits\n");
|
||||||
|
// else FCEU_printf("Counter Stopped\n");
|
||||||
|
IRQPreSize=V;break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M90ModeWrite)
|
||||||
|
{
|
||||||
|
tkcom[A&3]=V;
|
||||||
|
tekprom();
|
||||||
|
tekvrom();
|
||||||
|
mira();
|
||||||
|
|
||||||
|
#ifdef DEBUG90
|
||||||
|
switch (A&3)
|
||||||
|
{
|
||||||
|
case 00: FCEU_printf("Main Control Register:\n");
|
||||||
|
FCEU_printf(" PGR Banking mode: %d\n",V&7);
|
||||||
|
FCEU_printf(" CHR Banking mode: %d\n",(V>>3)&3);
|
||||||
|
FCEU_printf(" 6000-7FFF addresses mapping: %s\n",(V&0x80)?"Yes":"No");
|
||||||
|
FCEU_printf(" Nametable control: %s\n",(V&0x20)?"Enabled":"Disabled");
|
||||||
|
if(V&0x20)
|
||||||
|
FCEU_printf(" Nametable can be: %s\n",(V&0x40)?"ROM Only":"RAM or ROM");
|
||||||
|
break;
|
||||||
|
case 01: FCEU_printf("Mirroring mode: ");
|
||||||
|
switch (V&3)
|
||||||
|
{
|
||||||
|
case 0: FCEU_printf("Vertical\n");break;
|
||||||
|
case 1: FCEU_printf("Horizontal\n");break;
|
||||||
|
case 2: FCEU_printf("Nametable 0 only\n");break;
|
||||||
|
case 3: FCEU_printf("Nametable 1 only\n");break;
|
||||||
|
}
|
||||||
|
FCEU_printf("Mirroring flag: %s\n",(V&0x80)?"On":"Off");
|
||||||
|
break;
|
||||||
|
case 02: if((((tkcom[0])>>5)&3)==1)
|
||||||
|
FCEU_printf("Nametable ROM/RAM select mode: %d\n",V>>7);
|
||||||
|
break;
|
||||||
|
case 03:
|
||||||
|
FCEU_printf("CHR Banking mode: %s\n",(V&0x20)?"Entire CHR ROM":"256Kb Switching mode");
|
||||||
|
if(!(V&0x20)) FCEU_printf("256K CHR bank number: %02x\n",(V&1)|((V&0x18)>>2));
|
||||||
|
FCEU_printf("512K PRG bank number: %d\n",(V&6)>>1);
|
||||||
|
FCEU_printf("CHR Bank mirroring: %s\n",(V&0x80)?"Swapped":"Normal operate");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CCL(void)
|
||||||
|
{
|
||||||
|
if((IRQMode>>6) == 1) // Count Up
|
||||||
|
{
|
||||||
|
IRQCount++;
|
||||||
|
if((IRQCount == 0) && IRQa)
|
||||||
|
{
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if((IRQMode>>6) == 2) // Count down
|
||||||
|
{
|
||||||
|
IRQCount--;
|
||||||
|
if((IRQCount == 0xFF) && IRQa)
|
||||||
|
{
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ClockCounter(void)
|
||||||
|
{
|
||||||
|
uint8 premask;
|
||||||
|
|
||||||
|
if(IRQMode & 0x4)
|
||||||
|
premask = 0x7;
|
||||||
|
else
|
||||||
|
premask = 0xFF;
|
||||||
|
if((IRQMode>>6) == 1) // Count up
|
||||||
|
{
|
||||||
|
IRQPre++;
|
||||||
|
if((IRQPre & premask) == 0) CCL();
|
||||||
|
}
|
||||||
|
else if((IRQMode>>6) == 2) // Count down
|
||||||
|
{
|
||||||
|
IRQPre--;
|
||||||
|
if((IRQPre & premask) == premask) CCL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FP_FASTAPASS(1) CPUWrap(int a)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
if((IRQMode&3)==0) for(x=0;x<a;x++) ClockCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SLWrap(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
if((IRQMode&3)==1) for(x=0;x<8;x++) ClockCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 lastread;
|
||||||
|
static void FP_FASTAPASS(1) M90PPU(uint32 A)
|
||||||
|
{
|
||||||
|
if((IRQMode&3)==2)
|
||||||
|
{
|
||||||
|
if(lastread!=A)
|
||||||
|
{
|
||||||
|
ClockCounter();
|
||||||
|
ClockCounter();
|
||||||
|
}
|
||||||
|
lastread=A;
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// if((!lastread)&&(A&0x1000))
|
||||||
|
// ClockCounter();
|
||||||
|
// lastread=A&0x1000;
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void togglie()
|
||||||
|
{
|
||||||
|
tekker>>=6;
|
||||||
|
if(tekker>3)
|
||||||
|
tekker=0;
|
||||||
|
else
|
||||||
|
tekker++;
|
||||||
|
tekker<<=6;
|
||||||
|
FCEU_printf("tekker=%04x\n",tekker);
|
||||||
|
memset(tkcom,0x00,sizeof(tkcom));
|
||||||
|
memset(prgb,0xff,sizeof(prgb));
|
||||||
|
tekprom();
|
||||||
|
tekvrom();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M90Restore(int version)
|
||||||
|
{
|
||||||
|
tekprom();
|
||||||
|
tekvrom();
|
||||||
|
mira();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M90Power(void)
|
||||||
|
{
|
||||||
|
SetWriteHandler(0x5000,0x5fff,M90TekWrite);
|
||||||
|
SetWriteHandler(0x8000,0x8fff,M90PRGWrite);
|
||||||
|
SetWriteHandler(0x9000,0x9fff,M90CHRlowWrite);
|
||||||
|
SetWriteHandler(0xA000,0xAfff,M90CHRhiWrite);
|
||||||
|
SetWriteHandler(0xB000,0xBfff,M90NTWrite);
|
||||||
|
SetWriteHandler(0xC000,0xCfff,M90IRQWrite);
|
||||||
|
SetWriteHandler(0xD000,0xDfff,M90ModeWrite);
|
||||||
|
|
||||||
|
SetReadHandler(0x5000,0x5fff,M90TekRead);
|
||||||
|
SetReadHandler(0x6000,0xffff,CartBR);
|
||||||
|
|
||||||
|
mul[0]=mul[1]=regie=0xFF;
|
||||||
|
|
||||||
|
memset(tkcom,0x00,sizeof(tkcom));
|
||||||
|
memset(prgb,0xff,sizeof(prgb));
|
||||||
|
memset(chrlow,0xff,sizeof(chrlow));
|
||||||
|
memset(chrhigh,0xff,sizeof(chrhigh));
|
||||||
|
memset(names,0x00,sizeof(names));
|
||||||
|
|
||||||
|
if(is211)
|
||||||
|
tekker=0xC0;
|
||||||
|
else
|
||||||
|
tekker=0x00;
|
||||||
|
|
||||||
|
tekprom();
|
||||||
|
tekvrom();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Mapper90_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
is211=0;
|
||||||
|
is209=0;
|
||||||
|
info->Reset=togglie;
|
||||||
|
info->Power=M90Power;
|
||||||
|
PPU_hook=M90PPU;
|
||||||
|
GameHBIRQHook2=SLWrap;
|
||||||
|
MapIRQHook=CPUWrap;
|
||||||
|
GameStateRestore=M90Restore;
|
||||||
|
AddExState(Tek_StateRegs, ~0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper209_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
is211=0;
|
||||||
|
is209=1;
|
||||||
|
info->Reset=togglie;
|
||||||
|
info->Power=M90Power;
|
||||||
|
GameHBIRQHook2=SLWrap;
|
||||||
|
GameStateRestore=M90Restore;
|
||||||
|
AddExState(Tek_StateRegs, ~0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper211_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
is211=1;
|
||||||
|
info->Reset=togglie;
|
||||||
|
info->Power=M90Power;
|
||||||
|
GameHBIRQHook2=SLWrap;
|
||||||
|
GameStateRestore=M90Restore;
|
||||||
|
AddExState(Tek_StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 lastA;
|
||||||
|
static uint8 DRegs[8];
|
||||||
|
static uint8 cmd;
|
||||||
|
static uint8 MirCache[8];
|
||||||
|
|
||||||
|
static SFORMAT DB_StateRegs[]={
|
||||||
|
{DRegs, 8, "DREG"},
|
||||||
|
{&cmd, 1, "CMD"},
|
||||||
|
{&lastA, 1, "LAST"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void toot(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
MirCache[0]=MirCache[1]=(DRegs[0]>>4)&1;
|
||||||
|
MirCache[2]=MirCache[3]=(DRegs[1]>>4)&1;
|
||||||
|
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
MirCache[4+x]=(DRegs[2+x]>>5)&1;
|
||||||
|
onemir(MirCache[lastA]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Sync()
|
||||||
|
{
|
||||||
|
setchr2(0x0000,DRegs[0]&0x1F);
|
||||||
|
setchr2(0x0800,DRegs[1]&0x1F);
|
||||||
|
setchr1(0x1000,DRegs[2]&0x1F);
|
||||||
|
setchr1(0x1400,DRegs[3]&0x1F);
|
||||||
|
setchr1(0x1800,DRegs[4]&0x1F);
|
||||||
|
setchr1(0x1C00,DRegs[5]&0x1F);
|
||||||
|
setprg8(0x8000,DRegs[6]&0x1F);
|
||||||
|
setprg8(0xa000,DRegs[7]&0x1F);
|
||||||
|
toot();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(Mapper95_write)
|
||||||
|
{
|
||||||
|
switch(A&0xF001)
|
||||||
|
{
|
||||||
|
case 0x8000: cmd = V; break;
|
||||||
|
case 0x8001:
|
||||||
|
switch(cmd&0x07)
|
||||||
|
{
|
||||||
|
case 0: DRegs[0]=(V&0x3F)>>1; break;
|
||||||
|
case 1: DRegs[1]=(V&0x3F)>>1; break;
|
||||||
|
case 2: DRegs[2]=V&0x3F; break;
|
||||||
|
case 3: DRegs[3]=V&0x3F; break;
|
||||||
|
case 4: DRegs[4]=V&0x3F; break;
|
||||||
|
case 5: DRegs[5]=V&0x3F; break;
|
||||||
|
case 6: DRegs[6]=V&0x3F; break;
|
||||||
|
case 7: DRegs[7]=V&0x3F; break;
|
||||||
|
}
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FP_FASTAPASS(1) dragonbust_ppu(uint32 A)
|
||||||
|
{
|
||||||
|
static int last=-1;
|
||||||
|
static uint8 z;
|
||||||
|
|
||||||
|
if(A>=0x2000) return;
|
||||||
|
|
||||||
|
A>>=10;
|
||||||
|
lastA=A;
|
||||||
|
z=MirCache[A];
|
||||||
|
if(z!=last)
|
||||||
|
{
|
||||||
|
onemir(z);
|
||||||
|
last=z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DBPower(void)
|
||||||
|
{
|
||||||
|
memset(DRegs,0x3F,8);
|
||||||
|
DRegs[0]=DRegs[1]=0x1F;
|
||||||
|
|
||||||
|
Sync();
|
||||||
|
|
||||||
|
setprg8(0xc000,0x3E);
|
||||||
|
setprg8(0xe000,0x3F);
|
||||||
|
|
||||||
|
SetReadHandler(0x8000,0xffff,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xffff,Mapper95_write);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper95_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=DBPower;
|
||||||
|
AddExState(DB_StateRegs, ~0, 0, 0);
|
||||||
|
PPU_hook=dragonbust_ppu;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
fceu_SOURCES += boards/112.c boards/117.c boards/164.c boards/183.c boards/185.c boards/186.c boards/187.c boards/189.c boards/208.c boards/222.c boards/235.c boards/57.c boards/8157.c boards/8237.c boards/88.c boards/90.c boards/95.c boards/bmc13in1jy110.c boards/bmc42in1r.c boards/bmc64in1nr.c boards/bmc70in1.c boards/bmcgk192.c boards/bonza.c boards/cc21.c boards/datalatch.c boards/deirom.c boards/dream.c boards/fk23c.c boards/h2288.c boards/karaoke.c boards/kof97.c boards/konami-qtai.c boards/malee.c boards/mmc1.c boards/mmc3.c boards/mmc5.c boards/n106.c boards/novel.c boards/sachen.c boards/sheroes.c boards/sl1632.c boards/sonic5.c boards/subor.c boards/super24.c boards/supervision.c boards/t-262.c boards/tengen.c boards/__dummy_mapper.c
|
|
@ -0,0 +1,96 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2006 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 reg[8];
|
||||||
|
/*
|
||||||
|
static uint8 *WRAM=NULL;
|
||||||
|
static uint32 WRAMSIZE;
|
||||||
|
static uint8 *CHRRAM=NULL;
|
||||||
|
static uint32 CHRRAMSIZE;
|
||||||
|
*/
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{reg, 8, "REGS"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(MNNNWrite)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MNNNPower(void)
|
||||||
|
{
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,MNNNWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MNNNReset(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static void MNNNClose(void)
|
||||||
|
{
|
||||||
|
if(WRAM)
|
||||||
|
FCEU_gfree(WRAM);
|
||||||
|
if(CHRRAM)
|
||||||
|
FCEU_gfree(CHRRAM);
|
||||||
|
WRAM=CHRRAM=NULL;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void MNNNIRQHook(void)
|
||||||
|
{
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapperNNN_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Reset=MNNNReset;
|
||||||
|
info->Power=MNNNPower;
|
||||||
|
// info->Close=MNNNClose;
|
||||||
|
GameHBIRQHook=MNNNIRQHook;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
/*
|
||||||
|
CHRRAMSIZE=8192;
|
||||||
|
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSIZE);
|
||||||
|
SetupCartPRGMapping(0x10,CHRRAM,CHRRAMSIZE,1);
|
||||||
|
AddExState(CHRRAM, CHRRAMSIZE, 0, "WRAM");
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
WRAMSIZE=8192;
|
||||||
|
WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE);
|
||||||
|
SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1);
|
||||||
|
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
|
||||||
|
*/
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*
|
||||||
|
* BMC 42-in-1 reset switch
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 bank_mode;
|
||||||
|
static uint8 bank_value;
|
||||||
|
static uint8 prgb[4];
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
FCEU_printf("%02x: %02x %02x\n", bank_mode, bank_value, prgb[0]);
|
||||||
|
switch(bank_mode&7)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
setprg32(0x8000,bank_value&7); break;
|
||||||
|
case 1:
|
||||||
|
setprg16(0x8000,((8+(bank_value&7))>>1)+prgb[1]);
|
||||||
|
setprg16(0xC000,(bank_value&7)>>1);
|
||||||
|
case 4:
|
||||||
|
setprg32(0x8000,8+(bank_value&7)); break;
|
||||||
|
case 5:
|
||||||
|
setprg16(0x8000,((8+(bank_value&7))>>1)+prgb[1]);
|
||||||
|
setprg16(0xC000,((8+(bank_value&7))>>1)+prgb[3]);
|
||||||
|
case 2:
|
||||||
|
setprg8(0x8000,prgb[0]>>2);
|
||||||
|
setprg8(0xa000,prgb[1]);
|
||||||
|
setprg8(0xc000,prgb[2]);
|
||||||
|
setprg8(0xe000,~0);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
setprg8(0x8000,prgb[0]);
|
||||||
|
setprg8(0xa000,prgb[1]);
|
||||||
|
setprg8(0xc000,prgb[2]);
|
||||||
|
setprg8(0xe000,prgb[3]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BMC13in1JY110Write)
|
||||||
|
{
|
||||||
|
FCEU_printf("%04x:%04x\n",A,V);
|
||||||
|
switch(A)
|
||||||
|
{
|
||||||
|
case 0x8000:
|
||||||
|
case 0x8001:
|
||||||
|
case 0x8002:
|
||||||
|
case 0x8003: prgb[A&3]=V; break;
|
||||||
|
case 0xD000: bank_mode=V; break;
|
||||||
|
case 0xD001: setmirror(V&3);
|
||||||
|
case 0xD002: break;
|
||||||
|
case 0xD003: bank_value=V; break;
|
||||||
|
}
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMC13in1JY110Power(void)
|
||||||
|
{
|
||||||
|
prgb[0]=prgb[1]=prgb[2]=prgb[3]=0;
|
||||||
|
bank_mode=0;
|
||||||
|
bank_value=0;
|
||||||
|
setprg32(0x8000,0);
|
||||||
|
setchr8(0);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,BMC13in1JY110Write);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BMC13in1JY110_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=BMC13in1JY110Power;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*
|
||||||
|
* BMC 42-in-1 reset switch
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 hrd_sw;
|
||||||
|
static uint8 latche;
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&latche, 1, "LATCHE"},
|
||||||
|
{&hrd_sw, 1, "HRDSW"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
if(!(latche&0x20))
|
||||||
|
setprg32r(hrd_sw,0x8000,(latche>>1)&0x0f);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setprg16r(hrd_sw,0x8000,latche&0x1f);
|
||||||
|
setprg16r(hrd_sw,0xC000,latche&0x1f);
|
||||||
|
}
|
||||||
|
switch((latche>>6)&3)
|
||||||
|
{
|
||||||
|
case 0: setmirrorw(0,0,0,1); break;
|
||||||
|
case 1: setmirror(MI_V); break;
|
||||||
|
case 2: setmirror(MI_H); break;
|
||||||
|
case 3: setmirror(MI_1); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BMC42in1rWrite)
|
||||||
|
{
|
||||||
|
latche=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMC42in1rReset(void)
|
||||||
|
{
|
||||||
|
hrd_sw^=1;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMC42in1rPower(void)
|
||||||
|
{
|
||||||
|
latche=0x00;
|
||||||
|
hrd_sw=0;
|
||||||
|
setchr8(0);
|
||||||
|
Sync();
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,BMC42in1rWrite);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BMC42in1r_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=BMC42in1rPower;
|
||||||
|
info->Reset=BMC42in1rReset;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*
|
||||||
|
* BMC 42-in-1 reset switch
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 regs[4];
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{regs, 4, "REGS"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
if(regs[0]&0x80)
|
||||||
|
{
|
||||||
|
if(regs[1]&0x80)
|
||||||
|
setprg32(0x8000,regs[1]&0x1F);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int bank=((regs[1]&0x1f)<<1)|((regs[1]>>6)&1);
|
||||||
|
setprg16(0x8000,bank);
|
||||||
|
setprg16(0xC000,bank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int bank=((regs[1]&0x1f)<<1)|((regs[1]>>6)&1);
|
||||||
|
setprg16(0xC000,bank);
|
||||||
|
}
|
||||||
|
if(regs[0]&0x20)
|
||||||
|
setmirror(MI_H);
|
||||||
|
else
|
||||||
|
setmirror(MI_V);
|
||||||
|
setchr8((regs[2]<<2)|((regs[0]>>1)&3));
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BMC64in1nrWriteLo)
|
||||||
|
{
|
||||||
|
regs[A&3]=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BMC64in1nrWriteHi)
|
||||||
|
{
|
||||||
|
regs[3]=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMC64in1nrPower(void)
|
||||||
|
{
|
||||||
|
regs[0]=0x80;
|
||||||
|
regs[1]=0x43;
|
||||||
|
regs[2]=regs[3]=0;
|
||||||
|
Sync();
|
||||||
|
SetWriteHandler(0x5000,0x5003,BMC64in1nrWriteLo);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,BMC64in1nrWriteHi);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BMC64in1nr_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=BMC64in1nrPower;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 is_large_banks;
|
||||||
|
static uint8 large_bank;
|
||||||
|
static uint8 prg_bank;
|
||||||
|
static uint8 chr_bank;
|
||||||
|
static uint8 bank_mode;
|
||||||
|
static uint8 mirroring;
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&large_bank, 1, "LB"},
|
||||||
|
{&prg_bank, 1, "PRG"},
|
||||||
|
{&chr_bank, 1, "CHR"},
|
||||||
|
{&bank_mode, 1, "BM"},
|
||||||
|
{&mirroring, 1, "MIRR"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
switch (bank_mode)
|
||||||
|
{
|
||||||
|
case 0x00:
|
||||||
|
case 0x10: setprg16(0x8000,large_bank|prg_bank);
|
||||||
|
setprg16(0xC000,large_bank|7);
|
||||||
|
break;
|
||||||
|
case 0x20: setprg32(0x8000,(large_bank|prg_bank)>>1);
|
||||||
|
break;
|
||||||
|
case 0x30: setprg16(0x8000,large_bank|prg_bank);
|
||||||
|
setprg16(0xC000,large_bank|prg_bank);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setmirror(mirroring);
|
||||||
|
if(!is_large_banks)
|
||||||
|
setchr8(chr_bank);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(BMC70in1Read)
|
||||||
|
{
|
||||||
|
if(bank_mode==0x10)
|
||||||
|
if(is_large_banks)
|
||||||
|
return CartBR((A&0xFFF0)|0x06);
|
||||||
|
else
|
||||||
|
return CartBR((A&0xFFF0)|0x0d);
|
||||||
|
else
|
||||||
|
return CartBR(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BMC70in1Write)
|
||||||
|
{
|
||||||
|
if(A&0x4000)
|
||||||
|
{
|
||||||
|
bank_mode=A&0x30;
|
||||||
|
prg_bank=A&7;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mirroring=((A&0x20)>>5)^1;
|
||||||
|
if(is_large_banks)
|
||||||
|
large_bank=(A&3)<<3;
|
||||||
|
else
|
||||||
|
chr_bank=A&7;
|
||||||
|
}
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMC70in1Power(void)
|
||||||
|
{
|
||||||
|
setchr8(0);
|
||||||
|
bank_mode=0;
|
||||||
|
large_bank=0;
|
||||||
|
Sync();
|
||||||
|
SetReadHandler(0x8000,0xFFFF,BMC70in1Read);
|
||||||
|
SetWriteHandler(0x8000,0xffff,BMC70in1Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BMC70in1_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
is_large_banks=0;
|
||||||
|
info->Power=BMC70in1Power;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BMC70in1B_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
is_large_banks=1;
|
||||||
|
info->Power=BMC70in1Power;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint16 addrlatche;
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
if(addrlatche&0x40)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,addrlatche&7);
|
||||||
|
setprg16(0xC000,addrlatche&7);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setprg32(0x8000,(addrlatche>>1)&3);
|
||||||
|
setchr8((addrlatche>>3)&7);
|
||||||
|
setmirror(((addrlatche&0x80)>>7)^1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BMCGK192Write)
|
||||||
|
{
|
||||||
|
addrlatche=A;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMCGK192Reset(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMCGK192Power(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,0);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xffff,BMCGK192Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper58_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=BMCGK192Power;
|
||||||
|
info->Reset=BMCGK192Reset;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&addrlatche, 2, 0, "ALATC");
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 prg_reg;
|
||||||
|
static uint8 chr_reg;
|
||||||
|
|
||||||
|
static uint8 sim0reg, sim0bit, sim0byte, sim0parity, sim0bcnt;
|
||||||
|
static uint16 sim0data;
|
||||||
|
static uint8 sim0array[128] =
|
||||||
|
{
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xAA,
|
||||||
|
};
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&prg_reg, 1, "PREG"},
|
||||||
|
{&chr_reg, 1, "CREG"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000, prg_reg);
|
||||||
|
setchr8(chr_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M216WriteHi)
|
||||||
|
{
|
||||||
|
// FCEU_printf("%04x:%04x\n",A,V);
|
||||||
|
prg_reg=A&1;
|
||||||
|
chr_reg=(A&0x0E)>>1;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M216Write5000)
|
||||||
|
{
|
||||||
|
// FCEU_printf("WRITE: %04x:%04x\n",A,V);
|
||||||
|
sim0reg=V;
|
||||||
|
if(!sim0reg)
|
||||||
|
{
|
||||||
|
sim0bit=sim0byte=sim0parity=0;
|
||||||
|
sim0data=sim0array[0];
|
||||||
|
sim0bcnt=0x80;
|
||||||
|
}
|
||||||
|
else if(sim0reg&0x20)
|
||||||
|
{
|
||||||
|
sim0bcnt=0x20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(M216Read5000)
|
||||||
|
{
|
||||||
|
if(sim0reg&0x60)
|
||||||
|
{
|
||||||
|
sim0reg=(sim0reg^(sim0reg<<1))&0x40;
|
||||||
|
return sim0reg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint8 sim0out=0;
|
||||||
|
if(sim0bit<8)
|
||||||
|
{
|
||||||
|
// sim0data=((sim0array[sim0byte]<<(sim0bit))&0x80)>>1;
|
||||||
|
sim0out=(sim0data&1)<<6;
|
||||||
|
sim0data>>=1;
|
||||||
|
sim0bit++;
|
||||||
|
sim0parity+=sim0data;
|
||||||
|
}
|
||||||
|
else if(sim0bit==8)
|
||||||
|
{
|
||||||
|
sim0bit++;
|
||||||
|
sim0out=sim0parity&1;
|
||||||
|
}
|
||||||
|
else if(sim0bit==9)
|
||||||
|
{
|
||||||
|
if(sim0byte==sim0bcnt)
|
||||||
|
sim0out=0x60;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sim0bit=0;
|
||||||
|
sim0byte++;
|
||||||
|
sim0data=sim0array[sim0byte];
|
||||||
|
sim0out=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// FCEU_printf("READ: %04x (%04x-%02x,%04x)\n",A,X.PC,sim0out,sim0byte);
|
||||||
|
return sim0out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Power(void)
|
||||||
|
{
|
||||||
|
prg_reg = 0;
|
||||||
|
chr_reg = 0;
|
||||||
|
Sync();
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,M216WriteHi);
|
||||||
|
SetWriteHandler(0x5000,0x5000,M216Write5000);
|
||||||
|
SetReadHandler(0x5000,0x5000,M216Read5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Mapper216_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=Power;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint16 addrlatche;
|
||||||
|
|
||||||
|
//------------------ UNLCC21 ---------------------------
|
||||||
|
|
||||||
|
static void UNLCC21Sync(void)
|
||||||
|
{
|
||||||
|
setchr8(addrlatche&1);
|
||||||
|
setmirror(MI_0+((addrlatche&2)>>1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(UNLCC21Write)
|
||||||
|
{
|
||||||
|
addrlatche=A;
|
||||||
|
UNLCC21Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNLCC21Power(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,0);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xffff,UNLCC21Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNLCC21Restore(int version)
|
||||||
|
{
|
||||||
|
UNLCC21Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNLCC21_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=UNLCC21Power;
|
||||||
|
GameStateRestore=UNLCC21Restore;
|
||||||
|
AddExState(&addrlatche, 2, 0, "ALATC");
|
||||||
|
}
|
|
@ -0,0 +1,272 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 latche, latcheinit;
|
||||||
|
static uint16 addrreg0, addrreg1;
|
||||||
|
static void(*WSync)(void);
|
||||||
|
|
||||||
|
static DECLFW(LatchWrite)
|
||||||
|
{
|
||||||
|
latche=V;
|
||||||
|
WSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LatchPower(void)
|
||||||
|
{
|
||||||
|
latche=latcheinit;
|
||||||
|
WSync();
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(addrreg0,addrreg1,LatchWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
WSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Latch_Init(CartInfo *info, void (*proc)(void), uint8 init, uint16 adr0, uint16 adr1)
|
||||||
|
{
|
||||||
|
latcheinit=init;
|
||||||
|
addrreg0=adr0;
|
||||||
|
addrreg1=adr1;
|
||||||
|
WSync=proc;
|
||||||
|
info->Power=LatchPower;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&latche, 1, 0, "LATC");
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ CPROM ---------------------------
|
||||||
|
|
||||||
|
static void CPROMSync(void)
|
||||||
|
{
|
||||||
|
setchr4(0x0000,0);
|
||||||
|
setchr4(0x1000,latche&3);
|
||||||
|
setprg16(0x8000,0);
|
||||||
|
setprg16(0xC000,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, CPROMSync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ CNROM ---------------------------
|
||||||
|
|
||||||
|
static void CNROMSync(void)
|
||||||
|
{
|
||||||
|
setchr8(latche&3);
|
||||||
|
setprg16(0x8000,0);
|
||||||
|
setprg16(0xC000,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, CNROMSync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ ANROM ---------------------------
|
||||||
|
|
||||||
|
static void ANROMSync()
|
||||||
|
{
|
||||||
|
setprg32(0x8000,latche&0xf);
|
||||||
|
setmirror(MI_0+((latche>>4)&1));
|
||||||
|
setchr8(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ANROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, ANROMSync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ Map 70 ---------------------------
|
||||||
|
|
||||||
|
static void M70Sync()
|
||||||
|
{
|
||||||
|
setprg16(0x8000,latche>>4);
|
||||||
|
setprg16(0xc000,~0);
|
||||||
|
setchr8(latche&0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper70_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, M70Sync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ Map 152 ---------------------------
|
||||||
|
|
||||||
|
static void M152Sync()
|
||||||
|
{
|
||||||
|
setprg16(0x8000,(latche>>4)&7);
|
||||||
|
setprg16(0xc000,~0);
|
||||||
|
setchr8(latche&0xf);
|
||||||
|
setmirror(MI_0+((latche>>7)&1)); /* Saint Seiya...hmm. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper152_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, M152Sync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ Map 78 ---------------------------
|
||||||
|
/* Should be two separate emulation functions for this "mapper". Sigh. URGE TO KILL RISING. */
|
||||||
|
static void M78Sync()
|
||||||
|
{
|
||||||
|
setprg16(0x8000,(latche&7));
|
||||||
|
setprg16(0xc000,~0);
|
||||||
|
setchr8(latche>>4);
|
||||||
|
setmirror(MI_0+((latche>>3)&1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper78_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, M78Sync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ MHROM ---------------------------
|
||||||
|
|
||||||
|
static void MHROMSync(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,latche>>4);
|
||||||
|
setchr8(latche&0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MHROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, MHROMSync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper140_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, MHROMSync, 0, 0x6000, 0x7FFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ Map 87 ---------------------------
|
||||||
|
|
||||||
|
static void M87Sync(void)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,0);
|
||||||
|
setprg16(0xC000,1);
|
||||||
|
setchr8(latche>>1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper87_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, M87Sync, ~0, 0x6000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ Map 11 ---------------------------
|
||||||
|
|
||||||
|
static void M11Sync(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,latche&0xf);
|
||||||
|
setchr8(latche>>4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper11_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, M11Sync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper144_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, M11Sync, 0, 0x8001, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ UNROM ---------------------------
|
||||||
|
|
||||||
|
static void UNROMSync(void)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,latche);
|
||||||
|
setprg16(0xc000,~0);
|
||||||
|
setchr8(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, UNROMSync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ Map 93 ---------------------------
|
||||||
|
|
||||||
|
static void SSUNROMSync(void)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,latche>>4);
|
||||||
|
setprg16(0xc000,~0);
|
||||||
|
setchr8(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SUNSOFT_UNROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, SSUNROMSync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ Map 94 ---------------------------
|
||||||
|
|
||||||
|
static void M94Sync(void)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,latche>>2);
|
||||||
|
setprg16(0xc000,~0);
|
||||||
|
setchr8(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper94_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, M94Sync, 0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ Map 107 ---------------------------
|
||||||
|
|
||||||
|
static void M107Sync(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,(latche>>1)&3);
|
||||||
|
setchr8(latche&7);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper107_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
Latch_Init(info, M107Sync, ~0, 0x8000, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------ NROM ---------------------------
|
||||||
|
|
||||||
|
#ifdef DEBUG_MAPPER
|
||||||
|
static DECLFW(WriteHandler)
|
||||||
|
{
|
||||||
|
FCEU_printf("$%04x:$%02x\n",A,V);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void NROMPower(void)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,0);
|
||||||
|
setprg16(0xC000,~0);
|
||||||
|
setchr8(0);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
#ifdef DEBUG_MAPPER
|
||||||
|
SetWriteHandler(0x4020,0xFFFF,WriteHandler);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void NROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=NROMPower;
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 cmd;
|
||||||
|
static uint8 DRegs[8];
|
||||||
|
|
||||||
|
static SFORMAT DEI_StateRegs[]=
|
||||||
|
{
|
||||||
|
{&cmd, 1, "CMD"},
|
||||||
|
{DRegs, 8, "DREG"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setchr2(0x0000,DRegs[0]);
|
||||||
|
setchr2(0x0800,DRegs[1]);
|
||||||
|
int x;
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
setchr1(0x1000+(x<<10),DRegs[2+x]);
|
||||||
|
setprg8(0x8000,DRegs[6]);
|
||||||
|
setprg8(0xa000,DRegs[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(DEIWrite)
|
||||||
|
{
|
||||||
|
switch(A&0x8001)
|
||||||
|
{
|
||||||
|
case 0x8000: cmd=V&0x07; break;
|
||||||
|
case 0x8001: if(cmd<=0x05)
|
||||||
|
V&=0x3F;
|
||||||
|
else
|
||||||
|
V&=0x0F;
|
||||||
|
if(cmd<=0x01) V>>=1;
|
||||||
|
DRegs[cmd&0x07]=V;
|
||||||
|
Sync();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DEIPower(void)
|
||||||
|
{
|
||||||
|
setprg8(0xc000,0xE);
|
||||||
|
setprg8(0xe000,0xF);
|
||||||
|
cmd=0;
|
||||||
|
memset(DRegs,0,8);
|
||||||
|
Sync();
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,DEIWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DEIROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=DEIPower;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&DEI_StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 latche;
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,latche);
|
||||||
|
setprg16(0xC000,8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(DREAMWrite)
|
||||||
|
{
|
||||||
|
latche=V&7;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DREAMPower(void)
|
||||||
|
{
|
||||||
|
latche=0;
|
||||||
|
Sync();
|
||||||
|
setchr8(0);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x5020,0x5020,DREAMWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Restore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DreamTech01_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GameStateRestore=Restore;
|
||||||
|
info->Power=DREAMPower;
|
||||||
|
AddExState(&latche, 1, 0, "LATCH");
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
#include "mmc3.h"
|
||||||
|
|
||||||
|
static uint8 unromchr;
|
||||||
|
|
||||||
|
static void BMCFK23CCW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&0x40)
|
||||||
|
setchr8((EXPREGS[2]&0xFC)|unromchr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint16 base=(EXPREGS[2]&0x7F)<<3;
|
||||||
|
setchr1(A,V|base);
|
||||||
|
if(EXPREGS[3]&2)
|
||||||
|
{
|
||||||
|
setchr1(0x0400,EXPREGS[6]|base);
|
||||||
|
setchr1(0x0C00,EXPREGS[7]|base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMCFK23CPW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&4)
|
||||||
|
setprg32(0x8000,EXPREGS[1]>>1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&2)
|
||||||
|
setprg8(A,(V&(0x3F>>(EXPREGS[0]&3)))|(EXPREGS[1]<<1));
|
||||||
|
else
|
||||||
|
setprg8(A,V);
|
||||||
|
if(EXPREGS[3]&2)
|
||||||
|
{
|
||||||
|
setprg8(0xC000,EXPREGS[4]);
|
||||||
|
setprg8(0xE000,EXPREGS[5]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BMCFK23C8003Write)
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&0x40)
|
||||||
|
{
|
||||||
|
unromchr=V&3;
|
||||||
|
FixMMC3CHR(MMC3_cmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((A==0x8001)&&(EXPREGS[3]&2&&MMC3_cmd&8))
|
||||||
|
{
|
||||||
|
EXPREGS[4|(MMC3_cmd&3)]=V;
|
||||||
|
FixMMC3PRG(MMC3_cmd);
|
||||||
|
FixMMC3CHR(MMC3_cmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MMC3_CMDWrite(A,V);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BMCFK23CWrite)
|
||||||
|
{
|
||||||
|
EXPREGS[A&3]=V;
|
||||||
|
FixMMC3PRG(MMC3_cmd);
|
||||||
|
FixMMC3CHR(MMC3_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMCFK23CReset(void)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=0;
|
||||||
|
EXPREGS[4]=EXPREGS[5]=EXPREGS[6]=EXPREGS[7]=0xFF;
|
||||||
|
MMC3RegReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMCFK23CPower(void)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=0;
|
||||||
|
EXPREGS[4]=EXPREGS[5]=EXPREGS[6]=EXPREGS[7]=0xFF;
|
||||||
|
GenMMC3Power();
|
||||||
|
SetWriteHandler(0x5ff0,0x5fff,BMCFK23CWrite);
|
||||||
|
SetWriteHandler(0x8000,0x8003,BMCFK23C8003Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BMCFK23C_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC3_Init(info, 512, 256, 8, 0);
|
||||||
|
cwrap=BMCFK23CCW;
|
||||||
|
pwrap=BMCFK23CPW;
|
||||||
|
info->Power=BMCFK23CPower;
|
||||||
|
info->Reset=BMCFK23CReset;
|
||||||
|
AddExState(EXPREGS, 8, 0, "EXPR");
|
||||||
|
AddExState(&unromchr, 1, 0, "UNCHR");
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
#include "mmc3.h"
|
||||||
|
|
||||||
|
extern uint8 m114_perm[8];
|
||||||
|
|
||||||
|
static void H2288PW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&0x40)
|
||||||
|
{
|
||||||
|
uint8 bank=(EXPREGS[0]&5)|((EXPREGS[0]&8)>>2)|((EXPREGS[0]&0x20)>>2);
|
||||||
|
if(EXPREGS[0]&2)
|
||||||
|
setprg32(0x8000,bank>>1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setprg16(0x8000,bank);
|
||||||
|
setprg16(0xC000,bank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setprg8(A,V&0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(H2288WriteHi)
|
||||||
|
{
|
||||||
|
switch (A&0x8001)
|
||||||
|
{
|
||||||
|
case 0x8000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m114_perm[V&7])); break;
|
||||||
|
case 0x8001: MMC3_CMDWrite(0x8001,V); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(H2288WriteLo)
|
||||||
|
{
|
||||||
|
if(A&0x800)
|
||||||
|
{
|
||||||
|
if(A&1)
|
||||||
|
EXPREGS[1]=V;
|
||||||
|
else
|
||||||
|
EXPREGS[0]=V;
|
||||||
|
FixMMC3PRG(MMC3_cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(H2288Read)
|
||||||
|
{
|
||||||
|
int bit;
|
||||||
|
bit=(A&1)^1;
|
||||||
|
bit&=((A>>8)&1);
|
||||||
|
bit^=1;
|
||||||
|
return((X.DB&0xFE)|bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void H2288Power(void)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=EXPREGS[1]=0;
|
||||||
|
GenMMC3Power();
|
||||||
|
SetReadHandler(0x5000,0x5FFF,H2288Read);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x5000,0x5FFF,H2288WriteLo);
|
||||||
|
SetWriteHandler(0x8000,0x8FFF,H2288WriteHi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNLH2288_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC3_Init(info, 256, 256, 0, 0);
|
||||||
|
pwrap=H2288PW;
|
||||||
|
info->Power=H2288Power;
|
||||||
|
AddExState(EXPREGS, 2, 0, "EXPR");
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
extern uint32 ROM_size;
|
||||||
|
static uint8 latche;
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
if(latche)
|
||||||
|
{
|
||||||
|
if(latche&0x10)
|
||||||
|
setprg16(0x8000,(latche&7));
|
||||||
|
else
|
||||||
|
setprg16(0x8000,(latche&7)|8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setprg16(0x8000,7+(ROM_size>>4));
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M188Write)
|
||||||
|
{
|
||||||
|
latche=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(ExtDev)
|
||||||
|
{
|
||||||
|
return(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Power(void)
|
||||||
|
{
|
||||||
|
latche=0;
|
||||||
|
Sync();
|
||||||
|
setchr8(0);
|
||||||
|
setprg16(0xc000,0x7);
|
||||||
|
SetReadHandler(0x6000,0x7FFF,ExtDev);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,M188Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper188_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=Power;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&latche, 1, 0, "LATCH");
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
#include "mmc3.h"
|
||||||
|
|
||||||
|
static DECLFW(UNLKOF97CMDWrite)
|
||||||
|
{
|
||||||
|
V=(V&0xD8)|((V&0x20)>>4)|((V&4)<<3)|((V&2)>>1)|((V&1)<<2); //76143502
|
||||||
|
if(A==0x9000) A=0x8001;
|
||||||
|
MMC3_CMDWrite(A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(UNLKOF97IRQWrite)
|
||||||
|
{
|
||||||
|
V=(V&0xD8)|((V&0x20)>>4)|((V&4)<<3)|((V&2)>>1)|((V&1)<<2);
|
||||||
|
if(A==0xD000) A=0xC001;
|
||||||
|
else if(A==0xF000) A=0xE001;
|
||||||
|
MMC3_IRQWrite(A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNLKOF97Power(void)
|
||||||
|
{
|
||||||
|
GenMMC3Power();
|
||||||
|
SetWriteHandler(0x8000,0xA000,UNLKOF97CMDWrite);
|
||||||
|
SetWriteHandler(0xC000,0xF000,UNLKOF97IRQWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNLKOF97_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC3_Init(info, 128, 256, 0, 0);
|
||||||
|
info->Power=UNLKOF97Power;
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*
|
||||||
|
* CAI Shogakko no Sansu
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 *CHRRAM=NULL;
|
||||||
|
static uint8 SWRAM[4096];
|
||||||
|
|
||||||
|
static uint8 regs[16];
|
||||||
|
static uint8 WRAM[4096];
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{®s, 16, "REGS"},
|
||||||
|
{WRAM, 4096, "WRAM"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
if(regs[5]&0x40)
|
||||||
|
{
|
||||||
|
setchr4r(0,0x1000,regs[5]&0x3F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setchr4r(0x10,0x0000,regs[5]);
|
||||||
|
setchr4r(0x10,0x1000,regs[5]^1);
|
||||||
|
}
|
||||||
|
setprg8r((regs[2]>>6)&1,0x8000,(regs[2]&0x3F));
|
||||||
|
setprg8r((regs[3]>>6)&1,0xA000,(regs[3]&0x3F));
|
||||||
|
setprg8r((regs[4]>>6)&1,0xC000,(regs[4]&0x3F));
|
||||||
|
setprg8r(1,0xE000,~0);
|
||||||
|
setmirror((regs[0xA]&3));
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(M190Write)
|
||||||
|
{
|
||||||
|
// FCEU_printf("write %04x:%04x %d, %d\n",A,V,scanline,timestamp);
|
||||||
|
regs[(A&0x0F00)>>8]=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(M190Read)
|
||||||
|
{
|
||||||
|
// FCEU_printf("read %04x:%04x %d, %d\n",A,regs[(A&0x0F00)>>8],scanline,timestamp);
|
||||||
|
return regs[(A&0x0F00)>>8];
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(AWRAM)
|
||||||
|
{
|
||||||
|
return(WRAM[A-0x7000]);
|
||||||
|
}
|
||||||
|
static DECLFW(BWRAM)
|
||||||
|
{
|
||||||
|
WRAM[A-0x7000]=V;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(ASWRAM)
|
||||||
|
{
|
||||||
|
return(SWRAM[A-0x6000]);
|
||||||
|
}
|
||||||
|
static DECLFW(BSWRAM)
|
||||||
|
{
|
||||||
|
SWRAM[A-0x6000]=V;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M190Power(void)
|
||||||
|
{
|
||||||
|
setvram8(CHRRAM);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,M190Write);
|
||||||
|
// SetReadHandler(0xDA00,0xDA00,M190Read);
|
||||||
|
// SetReadHandler(0xDB00,0xDB00,M190Read);
|
||||||
|
SetReadHandler(0xDC00,0xDC00,M190Read);
|
||||||
|
SetReadHandler(0xDD00,0xDD00,M190Read);
|
||||||
|
SetReadHandler(0x7000,0x7FFF,AWRAM);
|
||||||
|
SetWriteHandler(0x7000,0x7FFF,BWRAM);
|
||||||
|
SetReadHandler(0x6000,0x6FFF,ASWRAM);
|
||||||
|
SetWriteHandler(0x6000,0x6FFF,BSWRAM);
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M190Close(void)
|
||||||
|
{
|
||||||
|
if(CHRRAM)
|
||||||
|
FCEU_gfree(CHRRAM);
|
||||||
|
CHRRAM=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper190_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=M190Power;
|
||||||
|
info->Close=M190Close;
|
||||||
|
if(info->battery)
|
||||||
|
{
|
||||||
|
info->SaveGame[0]=SWRAM;
|
||||||
|
info->SaveGameLen[0]=4096;
|
||||||
|
}
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
CHRRAM=(uint8*)FCEU_gmalloc(8192);
|
||||||
|
SetupCartCHRMapping(0x10,CHRRAM,8192,1);
|
||||||
|
AddExState(CHRRAM, 8192, 0, "CHRRAM");
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 WRAM[2048];
|
||||||
|
|
||||||
|
static void MALEEReset(void)
|
||||||
|
{
|
||||||
|
setprg2r(0x10,0x7000,0);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetReadHandler(0x6000,0x67FF,CartBR);
|
||||||
|
SetReadHandler(0x7000,0x77FF,CartBR);
|
||||||
|
setprg2r(1,0x6000,0);
|
||||||
|
setprg32(0x8000,0);
|
||||||
|
setchr8(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MALEE_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=MALEEReset;
|
||||||
|
SetupCartPRGMapping(0x10, WRAM, 2048, 1);
|
||||||
|
AddExState(WRAM, 2048, 0,"RAM");
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "../types.h"
|
||||||
|
#include "../x6502.h"
|
||||||
|
#include "../fceu.h"
|
||||||
|
#include "../ppu.h"
|
||||||
|
#include "../memory.h"
|
||||||
|
#include "../sound.h"
|
||||||
|
#include "../state.h"
|
||||||
|
#include "../cart.h"
|
||||||
|
#include "../cheat.h"
|
||||||
|
#include "../unif.h"
|
||||||
|
#include <string.h>
|
|
@ -0,0 +1,423 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 1998 BERO
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static void GenMMC1Power(void);
|
||||||
|
static void GenMMC1Init(CartInfo *info, int prg, int chr, int wram, int battery);
|
||||||
|
|
||||||
|
static uint8 DRegs[4];
|
||||||
|
static uint8 Buffer,BufferShift;
|
||||||
|
|
||||||
|
static int mmc1opts;
|
||||||
|
|
||||||
|
static void (*MMC1CHRHook4)(uint32 A, uint8 V);
|
||||||
|
static void (*MMC1PRGHook16)(uint32 A, uint8 V);
|
||||||
|
|
||||||
|
static uint8 *WRAM=NULL;
|
||||||
|
static uint8 *CHRRAM=NULL;
|
||||||
|
static int is155;
|
||||||
|
|
||||||
|
static DECLFW(MBWRAM)
|
||||||
|
{
|
||||||
|
if(!(DRegs[3]&0x10)||is155)
|
||||||
|
Page[A>>11][A]=V; // WRAM is enabled.
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(MAWRAM)
|
||||||
|
{
|
||||||
|
if((DRegs[3]&0x10)&&!is155)
|
||||||
|
return X.DB; // WRAM is disabled
|
||||||
|
return(Page[A>>11][A]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MMC1CHR(void)
|
||||||
|
{
|
||||||
|
if(mmc1opts&4)
|
||||||
|
{
|
||||||
|
if(DRegs[0]&0x10)
|
||||||
|
setprg8r(0x10,0x6000,(DRegs[1]>>4)&1);
|
||||||
|
else
|
||||||
|
setprg8r(0x10,0x6000,(DRegs[1]>>3)&1);
|
||||||
|
}
|
||||||
|
if(MMC1CHRHook4)
|
||||||
|
{
|
||||||
|
if(DRegs[0]&0x10)
|
||||||
|
{
|
||||||
|
MMC1CHRHook4(0x0000,DRegs[1]);
|
||||||
|
MMC1CHRHook4(0x1000,DRegs[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMC1CHRHook4(0x0000,(DRegs[1]&0xFE));
|
||||||
|
MMC1CHRHook4(0x1000,DRegs[1]|1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(DRegs[0]&0x10)
|
||||||
|
{
|
||||||
|
setchr4(0x0000,DRegs[1]);
|
||||||
|
setchr4(0x1000,DRegs[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setchr8(DRegs[1]>>1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MMC1PRG(void)
|
||||||
|
{
|
||||||
|
uint8 offs=DRegs[1]&0x10;
|
||||||
|
if(MMC1PRGHook16)
|
||||||
|
{
|
||||||
|
switch(DRegs[0]&0xC)
|
||||||
|
{
|
||||||
|
case 0xC: MMC1PRGHook16(0x8000,(DRegs[3]+offs));
|
||||||
|
MMC1PRGHook16(0xC000,0xF+offs);
|
||||||
|
break;
|
||||||
|
case 0x8: MMC1PRGHook16(0xC000,(DRegs[3]+offs));
|
||||||
|
MMC1PRGHook16(0x8000,offs);
|
||||||
|
break;
|
||||||
|
case 0x0:
|
||||||
|
case 0x4:
|
||||||
|
MMC1PRGHook16(0x8000,((DRegs[3]&~1)+offs));
|
||||||
|
MMC1PRGHook16(0xc000,((DRegs[3]&~1)+offs+1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else switch(DRegs[0]&0xC)
|
||||||
|
{
|
||||||
|
case 0xC: setprg16(0x8000,(DRegs[3]+offs));
|
||||||
|
setprg16(0xC000,0xF+offs);
|
||||||
|
break;
|
||||||
|
case 0x8: setprg16(0xC000,(DRegs[3]+offs));
|
||||||
|
setprg16(0x8000,offs);
|
||||||
|
break;
|
||||||
|
case 0x0:
|
||||||
|
case 0x4:
|
||||||
|
setprg16(0x8000,((DRegs[3]&~1)+offs));
|
||||||
|
setprg16(0xc000,((DRegs[3]&~1)+offs+1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MMC1MIRROR(void)
|
||||||
|
{
|
||||||
|
switch(DRegs[0]&3)
|
||||||
|
{
|
||||||
|
case 2: setmirror(MI_V); break;
|
||||||
|
case 3: setmirror(MI_H); break;
|
||||||
|
case 0: setmirror(MI_0); break;
|
||||||
|
case 1: setmirror(MI_1); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64 lreset;
|
||||||
|
static DECLFW(MMC1_write)
|
||||||
|
{
|
||||||
|
int n=(A>>13)-4;
|
||||||
|
//FCEU_DispMessage("%016x",timestampbase+timestamp);
|
||||||
|
//printf("$%04x:$%02x, $%04x\n",A,V,X.PC);
|
||||||
|
//DumpMem("out",0xe000,0xffff);
|
||||||
|
|
||||||
|
/* The MMC1 is busy so ignore the write. */
|
||||||
|
/* As of version FCE Ultra 0.81, the timestamp is only
|
||||||
|
increased before each instruction is executed(in other words
|
||||||
|
precision isn't that great), but this should still work to
|
||||||
|
deal with 2 writes in a row from a single RMW instruction. */
|
||||||
|
if((timestampbase+timestamp)<(lreset+2)) return;
|
||||||
|
if(V&0x80)
|
||||||
|
{
|
||||||
|
DRegs[0]|=0xC;
|
||||||
|
BufferShift=Buffer=0;
|
||||||
|
MMC1PRG();
|
||||||
|
lreset=timestampbase+timestamp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Buffer|=(V&1)<<(BufferShift++);
|
||||||
|
if(BufferShift==5)
|
||||||
|
{
|
||||||
|
DRegs[n] = Buffer;
|
||||||
|
BufferShift = Buffer = 0;
|
||||||
|
switch(n)
|
||||||
|
{
|
||||||
|
case 0: MMC1MIRROR(); MMC1CHR(); MMC1PRG(); break;
|
||||||
|
case 1: MMC1CHR(); MMC1PRG(); break;
|
||||||
|
case 2: MMC1CHR(); break;
|
||||||
|
case 3: MMC1PRG(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MMC1_Restore(int version)
|
||||||
|
{
|
||||||
|
MMC1MIRROR();
|
||||||
|
MMC1CHR();
|
||||||
|
MMC1PRG();
|
||||||
|
lreset=0; /* timestamp(base) is not stored in save states. */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MMC1CMReset(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<4;i++)
|
||||||
|
DRegs[i]=0;
|
||||||
|
Buffer = BufferShift = 0;
|
||||||
|
DRegs[0]=0x1F;
|
||||||
|
DRegs[1]=0;
|
||||||
|
DRegs[2]=0; // Should this be something other than 0?
|
||||||
|
DRegs[3]=0;
|
||||||
|
|
||||||
|
MMC1MIRROR();
|
||||||
|
MMC1CHR();
|
||||||
|
MMC1PRG();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DetectMMC1WRAMSize(uint32 crc32)
|
||||||
|
{
|
||||||
|
switch(crc32)
|
||||||
|
{
|
||||||
|
case 0xc6182024: /* Romance of the 3 Kingdoms */
|
||||||
|
case 0x2225c20f: /* Genghis Khan */
|
||||||
|
case 0x4642dda6: /* Nobunaga's Ambition */
|
||||||
|
case 0x29449ba9: /* "" "" (J) */
|
||||||
|
case 0x2b11e0b0: /* "" "" (J) */
|
||||||
|
case 0xb8747abf: /* Best Play Pro Yakyuu Special (J) */
|
||||||
|
case 0xc9556b36: /* Final Fantasy I & II (J) [!] */
|
||||||
|
FCEU_printf(" >8KB external WRAM present. Use UNIF if you hack the ROM image.\n");
|
||||||
|
return(16);
|
||||||
|
break;
|
||||||
|
default:return(8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 NWCIRQCount;
|
||||||
|
static uint8 NWCRec;
|
||||||
|
#define NWCDIP 0xE
|
||||||
|
|
||||||
|
static void FP_FASTAPASS(1) NWCIRQHook(int a)
|
||||||
|
{
|
||||||
|
if(!(NWCRec&0x10))
|
||||||
|
{
|
||||||
|
NWCIRQCount+=a;
|
||||||
|
if((NWCIRQCount|(NWCDIP<<25))>=0x3e000000)
|
||||||
|
{
|
||||||
|
NWCIRQCount=0;
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NWCCHRHook(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if((V&0x10)) // && !(NWCRec&0x10))
|
||||||
|
{
|
||||||
|
NWCIRQCount=0;
|
||||||
|
X6502_IRQEnd(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
NWCRec=V;
|
||||||
|
if(V&0x08)
|
||||||
|
MMC1PRG();
|
||||||
|
else
|
||||||
|
setprg32(0x8000,(V>>1)&3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NWCPRGHook(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if(NWCRec&0x8)
|
||||||
|
setprg16(A,8|(V&0x7));
|
||||||
|
else
|
||||||
|
setprg32(0x8000,(NWCRec>>1)&3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NWCPower(void)
|
||||||
|
{
|
||||||
|
GenMMC1Power();
|
||||||
|
setchr8r(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper105_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 256, 256, 8, 0);
|
||||||
|
MMC1CHRHook4=NWCCHRHook;
|
||||||
|
MMC1PRGHook16=NWCPRGHook;
|
||||||
|
MapIRQHook=NWCIRQHook;
|
||||||
|
info->Power=NWCPower;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenMMC1Power(void)
|
||||||
|
{
|
||||||
|
lreset=0;
|
||||||
|
if(mmc1opts&1)
|
||||||
|
{
|
||||||
|
FCEU_CheatAddRAM(8,0x6000,WRAM);
|
||||||
|
if(mmc1opts&4)
|
||||||
|
FCEU_dwmemset(WRAM,0,8192)
|
||||||
|
else if(!(mmc1opts&2))
|
||||||
|
FCEU_dwmemset(WRAM,0,8192);
|
||||||
|
}
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,MMC1_write);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
|
||||||
|
if(mmc1opts&1)
|
||||||
|
{
|
||||||
|
SetReadHandler(0x6000,0x7FFF,MAWRAM);
|
||||||
|
SetWriteHandler(0x6000,0x7FFF,MBWRAM);
|
||||||
|
setprg8r(0x10,0x6000,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
MMC1CMReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenMMC1Close(void)
|
||||||
|
{
|
||||||
|
if(CHRRAM)
|
||||||
|
FCEU_gfree(CHRRAM);
|
||||||
|
if(WRAM)
|
||||||
|
FCEU_gfree(WRAM);
|
||||||
|
CHRRAM=WRAM=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenMMC1Init(CartInfo *info, int prg, int chr, int wram, int battery)
|
||||||
|
{
|
||||||
|
is155=0;
|
||||||
|
|
||||||
|
info->Close=GenMMC1Close;
|
||||||
|
MMC1PRGHook16=MMC1CHRHook4=0;
|
||||||
|
mmc1opts=0;
|
||||||
|
PRGmask16[0]&=(prg>>14)-1;
|
||||||
|
CHRmask4[0]&=(chr>>12)-1;
|
||||||
|
CHRmask8[0]&=(chr>>13)-1;
|
||||||
|
|
||||||
|
if(wram)
|
||||||
|
{
|
||||||
|
WRAM=(uint8*)FCEU_gmalloc(wram*1024);
|
||||||
|
mmc1opts|=1;
|
||||||
|
if(wram>8) mmc1opts|=4;
|
||||||
|
SetupCartPRGMapping(0x10,WRAM,wram*1024,1);
|
||||||
|
AddExState(WRAM, wram*1024, 0, "WRAM");
|
||||||
|
if(battery)
|
||||||
|
{
|
||||||
|
mmc1opts|=2;
|
||||||
|
info->SaveGame[0]=WRAM+((mmc1opts&4)?8192:0);
|
||||||
|
info->SaveGameLen[0]=8192;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!chr)
|
||||||
|
{
|
||||||
|
CHRRAM=(uint8*)FCEU_gmalloc(8192);
|
||||||
|
SetupCartCHRMapping(0, CHRRAM, 8192, 1);
|
||||||
|
AddExState(CHRRAM, 8192, 0, "CHRR");
|
||||||
|
}
|
||||||
|
AddExState(DRegs, 4, 0, "DREG");
|
||||||
|
|
||||||
|
info->Power=GenMMC1Power;
|
||||||
|
GameStateRestore=MMC1_Restore;
|
||||||
|
AddExState(&lreset, 8, 1, "LRST");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper1_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
int ws=DetectMMC1WRAMSize(info->CRC32);
|
||||||
|
GenMMC1Init(info, 512, 256, ws, info->battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Same as mapper 1, without respect for WRAM enable bit. */
|
||||||
|
void Mapper155_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info,512,256,8,info->battery);
|
||||||
|
is155=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SAROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 128, 64, 8, info->battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 128, 64, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SCROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 128, 128, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SEROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 32, 64, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SGROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 256, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SKROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 256, 64, 8, info->battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SLROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 256, 128, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SL1ROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 128, 128, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Begin unknown - may be wrong - perhaps they use different MMC1s from the
|
||||||
|
similarly functioning boards?
|
||||||
|
*/
|
||||||
|
|
||||||
|
void SL2ROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 256, 256, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SFROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 256, 256, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 256, 256, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End unknown */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
void SNROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 256, 0, 8, info->battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SOROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC1Init(info, 256, 0, 16, info->battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
||||||
|
extern uint8 MMC3_cmd;
|
||||||
|
extern uint8 *WRAM;
|
||||||
|
extern uint8 *CHRRAM;
|
||||||
|
extern uint8 EXPREGS[8];
|
||||||
|
#undef IRQCount
|
||||||
|
#undef IRQLatch
|
||||||
|
#undef IRQa
|
||||||
|
extern uint8 IRQCount,IRQLatch,IRQa;
|
||||||
|
extern uint8 IRQReload;
|
||||||
|
|
||||||
|
extern void (*pwrap)(uint32 A, uint8 V);
|
||||||
|
extern void (*cwrap)(uint32 A, uint8 V);
|
||||||
|
extern void (*mwrap)(uint8 V);
|
||||||
|
|
||||||
|
void GenMMC3Power(void);
|
||||||
|
void GenMMC3Restore(int version);
|
||||||
|
void MMC3RegReset(void);
|
||||||
|
void FixMMC3PRG(int V);
|
||||||
|
void FixMMC3CHR(int V);
|
||||||
|
DECLFW(MMC3_CMDWrite);
|
||||||
|
DECLFW(MMC3_IRQWrite);
|
||||||
|
|
||||||
|
void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery);
|
|
@ -0,0 +1,834 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* None of this code should use any of the iNES bank switching wrappers. */
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static void (*sfun)(int P);
|
||||||
|
static void (*psfun)(void);
|
||||||
|
|
||||||
|
void MMC5RunSound(int Count);
|
||||||
|
void MMC5RunSoundHQ(void);
|
||||||
|
|
||||||
|
static INLINE void MMC5SPRVROM_BANK1(uint32 A,uint32 V)
|
||||||
|
{
|
||||||
|
if(CHRptr[0])
|
||||||
|
{
|
||||||
|
V&=CHRmask1[0];
|
||||||
|
MMC5SPRVPage[(A)>>10]=&CHRptr[0][(V)<<10]-(A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE void MMC5BGVROM_BANK1(uint32 A,uint32 V) {if(CHRptr[0]){V&=CHRmask1[0];MMC5BGVPage[(A)>>10]=&CHRptr[0][(V)<<10]-(A);}}
|
||||||
|
|
||||||
|
static INLINE void MMC5SPRVROM_BANK2(uint32 A,uint32 V) {if(CHRptr[0]){V&=CHRmask2[0];MMC5SPRVPage[(A)>>10]=MMC5SPRVPage[((A)>>10)+1]=&CHRptr[0][(V)<<11]-(A);}}
|
||||||
|
static INLINE void MMC5BGVROM_BANK2(uint32 A,uint32 V) {if(CHRptr[0]){V&=CHRmask2[0];MMC5BGVPage[(A)>>10]=MMC5BGVPage[((A)>>10)+1]=&CHRptr[0][(V)<<11]-(A);}}
|
||||||
|
|
||||||
|
static INLINE void MMC5SPRVROM_BANK4(uint32 A,uint32 V) {if(CHRptr[0]){V&=CHRmask4[0];MMC5SPRVPage[(A)>>10]=MMC5SPRVPage[((A)>>10)+1]= MMC5SPRVPage[((A)>>10)+2]=MMC5SPRVPage[((A)>>10)+3]=&CHRptr[0][(V)<<12]-(A);}}
|
||||||
|
static INLINE void MMC5BGVROM_BANK4(uint32 A,uint32 V) {if(CHRptr[0]){V&=CHRmask4[0];MMC5BGVPage[(A)>>10]=MMC5BGVPage[((A)>>10)+1]=MMC5BGVPage[((A)>>10)+2]=MMC5BGVPage[((A)>>10)+3]=&CHRptr[0][(V)<<12]-(A);}}
|
||||||
|
|
||||||
|
static INLINE void MMC5SPRVROM_BANK8(uint32 V) {if(CHRptr[0]){V&=CHRmask8[0];MMC5SPRVPage[0]=MMC5SPRVPage[1]=MMC5SPRVPage[2]=MMC5SPRVPage[3]=MMC5SPRVPage[4]=MMC5SPRVPage[5]=MMC5SPRVPage[6]=MMC5SPRVPage[7]=&CHRptr[0][(V)<<13];}}
|
||||||
|
static INLINE void MMC5BGVROM_BANK8(uint32 V) {if(CHRptr[0]){V&=CHRmask8[0];MMC5BGVPage[0]=MMC5BGVPage[1]=MMC5BGVPage[2]=MMC5BGVPage[3]=MMC5BGVPage[4]=MMC5BGVPage[5]=MMC5BGVPage[6]=MMC5BGVPage[7]=&CHRptr[0][(V)<<13];}}
|
||||||
|
|
||||||
|
static uint8 PRGBanks[4];
|
||||||
|
static uint8 WRAMPage;
|
||||||
|
static uint8 CHRBanksA[8], CHRBanksB[4];
|
||||||
|
static uint8 WRAMMaskEnable[2];
|
||||||
|
static uint8 ABMode; /* A=0, B=1 */
|
||||||
|
|
||||||
|
static uint8 IRQScanline,IRQEnable;
|
||||||
|
static uint8 CHRMode, NTAMirroring, NTFill, ATFill;
|
||||||
|
|
||||||
|
static uint8 MMC5IRQR;
|
||||||
|
static uint8 MMC5LineCounter;
|
||||||
|
static uint8 mmc5psize, mmc5vsize;
|
||||||
|
static uint8 mul[2];
|
||||||
|
|
||||||
|
static uint8 *WRAM=NULL;
|
||||||
|
static uint8 *MMC5fill=NULL;
|
||||||
|
static uint8 *ExRAM=NULL;
|
||||||
|
|
||||||
|
static uint8 MMC5WRAMsize;
|
||||||
|
static uint8 MMC5WRAMIndex[8];
|
||||||
|
|
||||||
|
static uint8 MMC5ROMWrProtect[4];
|
||||||
|
static uint8 MMC5MemIn[5];
|
||||||
|
|
||||||
|
static void MMC5CHRA(void);
|
||||||
|
static void MMC5CHRB(void);
|
||||||
|
|
||||||
|
typedef struct __cartdata {
|
||||||
|
uint32 crc32;
|
||||||
|
uint8 size;
|
||||||
|
} cartdata;
|
||||||
|
|
||||||
|
|
||||||
|
// ETROM seems to have 16KB of WRAM, ELROM seems to have 8KB
|
||||||
|
// EWROM seems to have 32KB of WRAM
|
||||||
|
|
||||||
|
#define MMC5_NOCARTS 14
|
||||||
|
cartdata MMC5CartList[MMC5_NOCARTS]=
|
||||||
|
{
|
||||||
|
{0x9c18762b,2}, /* L'Empereur */
|
||||||
|
{0x26533405,2},
|
||||||
|
{0x6396b988,2},
|
||||||
|
|
||||||
|
{0xaca15643,2}, /* Uncharted Waters */
|
||||||
|
{0xfe3488d1,2}, /* Dai Koukai Jidai */
|
||||||
|
|
||||||
|
{0x15fe6d0f,2}, /* BKAC */
|
||||||
|
{0x39f2ce4b,2}, /* Suikoden */
|
||||||
|
|
||||||
|
{0x8ce478db,2}, /* Nobunaga's Ambition 2 */
|
||||||
|
{0xeee9a682,2},
|
||||||
|
|
||||||
|
{0x1ced086f,2}, /* Ishin no Arashi */
|
||||||
|
|
||||||
|
{0xf540677b,4}, /* Nobunaga...Bushou Fuuun Roku */
|
||||||
|
|
||||||
|
{0x6f4e4312,4}, /* Aoki Ookami..Genchou */
|
||||||
|
|
||||||
|
{0xf011e490,4}, /* Romance of the 3 Kingdoms 2 */
|
||||||
|
{0x184c2124,4}, /* Sangokushi 2 */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int DetectMMC5WRAMSize(uint32 crc32)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=0;x<MMC5_NOCARTS;x++)
|
||||||
|
if(crc32==MMC5CartList[x].crc32)
|
||||||
|
{
|
||||||
|
FCEU_printf(" >8KB external WRAM present. Use UNIF if you hack the ROM image.\n");
|
||||||
|
return(MMC5CartList[x].size*8);
|
||||||
|
}
|
||||||
|
return(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildWRAMSizeTable(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
{
|
||||||
|
switch(MMC5WRAMsize)
|
||||||
|
{
|
||||||
|
case 0: MMC5WRAMIndex[x]=255; break;
|
||||||
|
case 1: MMC5WRAMIndex[x]=(x>3)?255:0; break;
|
||||||
|
case 2: MMC5WRAMIndex[x]=(x&4)>>2; break;
|
||||||
|
case 4: MMC5WRAMIndex[x]=(x>3)?255:(x&3); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MMC5CHRA(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
switch(mmc5vsize&3)
|
||||||
|
{
|
||||||
|
case 0: setchr8(CHRBanksA[7]);
|
||||||
|
MMC5SPRVROM_BANK8(CHRBanksA[7]);
|
||||||
|
break;
|
||||||
|
case 1: setchr4(0x0000,CHRBanksA[3]);
|
||||||
|
setchr4(0x1000,CHRBanksA[7]);
|
||||||
|
MMC5SPRVROM_BANK4(0x0000,CHRBanksA[3]);
|
||||||
|
MMC5SPRVROM_BANK4(0x1000,CHRBanksA[7]);
|
||||||
|
break;
|
||||||
|
case 2: setchr2(0x0000,CHRBanksA[1]);
|
||||||
|
setchr2(0x0800,CHRBanksA[3]);
|
||||||
|
setchr2(0x1000,CHRBanksA[5]);
|
||||||
|
setchr2(0x1800,CHRBanksA[7]);
|
||||||
|
MMC5SPRVROM_BANK2(0x0000,CHRBanksA[1]);
|
||||||
|
MMC5SPRVROM_BANK2(0x0800,CHRBanksA[3]);
|
||||||
|
MMC5SPRVROM_BANK2(0x1000,CHRBanksA[5]);
|
||||||
|
MMC5SPRVROM_BANK2(0x1800,CHRBanksA[7]);
|
||||||
|
break;
|
||||||
|
case 3: for(x=0;x<8;x++)
|
||||||
|
{
|
||||||
|
setchr1(x<<10,CHRBanksA[x]);
|
||||||
|
MMC5SPRVROM_BANK1(x<<10,CHRBanksA[x]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MMC5CHRB(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
switch(mmc5vsize&3)
|
||||||
|
{
|
||||||
|
case 0: setchr8(CHRBanksB[3]);
|
||||||
|
MMC5BGVROM_BANK8(CHRBanksB[3]);
|
||||||
|
break;
|
||||||
|
case 1: setchr4(0x0000,CHRBanksB[3]);
|
||||||
|
setchr4(0x1000,CHRBanksB[3]);
|
||||||
|
MMC5BGVROM_BANK4(0x0000,CHRBanksB[3]);
|
||||||
|
MMC5BGVROM_BANK4(0x1000,CHRBanksB[3]);
|
||||||
|
break;
|
||||||
|
case 2: setchr2(0x0000,CHRBanksB[1]);
|
||||||
|
setchr2(0x0800,CHRBanksB[3]);
|
||||||
|
setchr2(0x1000,CHRBanksB[1]);
|
||||||
|
setchr2(0x1800,CHRBanksB[3]);
|
||||||
|
MMC5BGVROM_BANK2(0x0000,CHRBanksB[1]);
|
||||||
|
MMC5BGVROM_BANK2(0x0800,CHRBanksB[3]);
|
||||||
|
MMC5BGVROM_BANK2(0x1000,CHRBanksB[1]);
|
||||||
|
MMC5BGVROM_BANK2(0x1800,CHRBanksB[3]);
|
||||||
|
break;
|
||||||
|
case 3: for(x=0;x<8;x++)
|
||||||
|
{
|
||||||
|
setchr1(x<<10,CHRBanksB[x&3]);
|
||||||
|
MMC5BGVROM_BANK1(x<<10,CHRBanksB[x&3]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FASTAPASS(2) MMC5WRAM(uint32 A, uint32 V)
|
||||||
|
{
|
||||||
|
//printf("%02x\n",V);
|
||||||
|
V=MMC5WRAMIndex[V&7];
|
||||||
|
if(V!=255)
|
||||||
|
{
|
||||||
|
setprg8r(0x10,A,V);
|
||||||
|
MMC5MemIn[(A-0x6000)>>13]=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MMC5MemIn[(A-0x6000)>>13]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MMC5PRG(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
switch(mmc5psize&3)
|
||||||
|
{
|
||||||
|
case 0: MMC5ROMWrProtect[0]=MMC5ROMWrProtect[1]=
|
||||||
|
MMC5ROMWrProtect[2]=MMC5ROMWrProtect[3]=1;
|
||||||
|
setprg32(0x8000,((PRGBanks[1]&0x7F)>>2));
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
MMC5MemIn[1+x]=1;
|
||||||
|
break;
|
||||||
|
case 1: if(PRGBanks[1]&0x80)
|
||||||
|
{
|
||||||
|
MMC5ROMWrProtect[0]=MMC5ROMWrProtect[1]=1;
|
||||||
|
setprg16(0x8000,(PRGBanks[1]>>1));
|
||||||
|
MMC5MemIn[1]=MMC5MemIn[2]=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMC5ROMWrProtect[0]=MMC5ROMWrProtect[1]=0;
|
||||||
|
MMC5WRAM(0x8000,PRGBanks[1]&7&0xFE);
|
||||||
|
MMC5WRAM(0xA000,(PRGBanks[1]&7&0xFE)+1);
|
||||||
|
}
|
||||||
|
MMC5MemIn[3]=MMC5MemIn[4]=1;
|
||||||
|
MMC5ROMWrProtect[2]=MMC5ROMWrProtect[3]=1;
|
||||||
|
setprg16(0xC000,(PRGBanks[3]&0x7F)>>1);
|
||||||
|
break;
|
||||||
|
case 2: if(PRGBanks[1]&0x80)
|
||||||
|
{
|
||||||
|
MMC5MemIn[1]=MMC5MemIn[2]=1;
|
||||||
|
MMC5ROMWrProtect[0]=MMC5ROMWrProtect[1]=1;
|
||||||
|
setprg16(0x8000,(PRGBanks[1]&0x7F)>>1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMC5ROMWrProtect[0]=MMC5ROMWrProtect[1]=0;
|
||||||
|
MMC5WRAM(0x8000,PRGBanks[1]&7&0xFE);
|
||||||
|
MMC5WRAM(0xA000,(PRGBanks[1]&7&0xFE)+1);
|
||||||
|
}
|
||||||
|
if(PRGBanks[2]&0x80)
|
||||||
|
{
|
||||||
|
MMC5ROMWrProtect[2]=1;
|
||||||
|
MMC5MemIn[3]=1;
|
||||||
|
setprg8(0xC000,PRGBanks[2]&0x7F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMC5ROMWrProtect[2]=0;
|
||||||
|
MMC5WRAM(0xC000,PRGBanks[2]&7);
|
||||||
|
}
|
||||||
|
MMC5MemIn[4]=1;
|
||||||
|
MMC5ROMWrProtect[3]=1;
|
||||||
|
setprg8(0xE000,PRGBanks[3]&0x7F);
|
||||||
|
break;
|
||||||
|
case 3: for(x=0;x<3;x++)
|
||||||
|
if(PRGBanks[x]&0x80)
|
||||||
|
{
|
||||||
|
MMC5ROMWrProtect[x]=1;
|
||||||
|
setprg8(0x8000+(x<<13),PRGBanks[x]&0x7F);
|
||||||
|
MMC5MemIn[1+x]=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMC5ROMWrProtect[x]=0;
|
||||||
|
MMC5WRAM(0x8000+(x<<13),PRGBanks[x]&7);
|
||||||
|
}
|
||||||
|
MMC5MemIn[4]=1;
|
||||||
|
MMC5ROMWrProtect[3]=1;
|
||||||
|
setprg8(0xE000,PRGBanks[3]&0x7F);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(Mapper5_write)
|
||||||
|
{
|
||||||
|
if(A>=0x5120&&A<=0x5127)
|
||||||
|
{
|
||||||
|
ABMode = 0;
|
||||||
|
CHRBanksA[A&7]=V;
|
||||||
|
MMC5CHRA();
|
||||||
|
}
|
||||||
|
else switch(A)
|
||||||
|
{
|
||||||
|
case 0x5105: {
|
||||||
|
int x;
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
{
|
||||||
|
switch((V>>(x<<1))&3)
|
||||||
|
{
|
||||||
|
case 0:PPUNTARAM|=1<<x;vnapage[x]=NTARAM;break;
|
||||||
|
case 1:PPUNTARAM|=1<<x;vnapage[x]=NTARAM+0x400;break;
|
||||||
|
case 2:PPUNTARAM|=1<<x;vnapage[x]=ExRAM;break;
|
||||||
|
case 3:PPUNTARAM&=~(1<<x);vnapage[x]=MMC5fill;break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NTAMirroring=V;
|
||||||
|
break;
|
||||||
|
case 0x5113: WRAMPage=V;MMC5WRAM(0x6000,V&7);break;
|
||||||
|
case 0x5100: mmc5psize=V;MMC5PRG();break;
|
||||||
|
case 0x5101: mmc5vsize=V;
|
||||||
|
if(!ABMode)
|
||||||
|
{ MMC5CHRB();MMC5CHRA();}
|
||||||
|
else
|
||||||
|
{ MMC5CHRA();MMC5CHRB();}
|
||||||
|
break;
|
||||||
|
case 0x5114:
|
||||||
|
case 0x5115:
|
||||||
|
case 0x5116:
|
||||||
|
case 0x5117: PRGBanks[A&3]=V;MMC5PRG();break;
|
||||||
|
case 0x5128:
|
||||||
|
case 0x5129:
|
||||||
|
case 0x512a:
|
||||||
|
case 0x512b: ABMode=1;
|
||||||
|
CHRBanksB[A&3]=V;
|
||||||
|
MMC5CHRB();
|
||||||
|
break;
|
||||||
|
case 0x5102: WRAMMaskEnable[0]=V;break;
|
||||||
|
case 0x5103: WRAMMaskEnable[1]=V;break;
|
||||||
|
case 0x5104: CHRMode=V;MMC5HackCHRMode=V&3;break;
|
||||||
|
case 0x5106: if(V!=NTFill)
|
||||||
|
{
|
||||||
|
uint32 t;
|
||||||
|
t=V|(V<<8)|(V<<16)|(V<<24);
|
||||||
|
FCEU_dwmemset(MMC5fill,t,0x3c0);
|
||||||
|
}
|
||||||
|
NTFill=V;
|
||||||
|
break;
|
||||||
|
case 0x5107: if(V!=ATFill)
|
||||||
|
{
|
||||||
|
unsigned char moop;
|
||||||
|
uint32 t;
|
||||||
|
moop=V|(V<<2)|(V<<4)|(V<<6);
|
||||||
|
t=moop|(moop<<8)|(moop<<16)|(moop<<24);
|
||||||
|
FCEU_dwmemset(MMC5fill+0x3c0,t,0x40);
|
||||||
|
}
|
||||||
|
ATFill=V;
|
||||||
|
break;
|
||||||
|
case 0x5200: MMC5HackSPMode=V;break;
|
||||||
|
case 0x5201: MMC5HackSPScroll=(V>>3)&0x1F;break;
|
||||||
|
case 0x5202: MMC5HackSPPage=V&0x3F;break;
|
||||||
|
case 0x5203: X6502_IRQEnd(FCEU_IQEXT);IRQScanline=V;break;
|
||||||
|
case 0x5204: X6502_IRQEnd(FCEU_IQEXT);IRQEnable=V&0x80;break;
|
||||||
|
case 0x5205: mul[0]=V;break;
|
||||||
|
case 0x5206: mul[1]=V;break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(MMC5_ReadROMRAM)
|
||||||
|
{
|
||||||
|
if(MMC5MemIn[(A-0x6000)>>13])
|
||||||
|
return Page[A>>11][A];
|
||||||
|
else
|
||||||
|
return X.DB;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(MMC5_WriteROMRAM)
|
||||||
|
{
|
||||||
|
if(A>=0x8000)
|
||||||
|
if(MMC5ROMWrProtect[(A-0x8000)>>13]) return;
|
||||||
|
if(MMC5MemIn[(A-0x6000)>>13])
|
||||||
|
if(((WRAMMaskEnable[0]&3)|((WRAMMaskEnable[1]&3)<<2)) == 6) Page[A>>11][A]=V;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(MMC5_ExRAMWr)
|
||||||
|
{
|
||||||
|
if(MMC5HackCHRMode!=3)
|
||||||
|
ExRAM[A&0x3ff]=V;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(MMC5_ExRAMRd)
|
||||||
|
{
|
||||||
|
/* Not sure if this is correct, so I'll comment it out for now. */
|
||||||
|
//if(MMC5HackCHRMode>=2)
|
||||||
|
return ExRAM[A&0x3ff];
|
||||||
|
//else
|
||||||
|
// return(X.DB);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(MMC5_read)
|
||||||
|
{
|
||||||
|
switch(A)
|
||||||
|
{
|
||||||
|
case 0x5204: X6502_IRQEnd(FCEU_IQEXT);
|
||||||
|
{
|
||||||
|
uint8 x;
|
||||||
|
x=MMC5IRQR;
|
||||||
|
if(!fceuindbg)
|
||||||
|
MMC5IRQR&=0x40;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
case 0x5205: return (mul[0]*mul[1]);
|
||||||
|
case 0x5206: return ((mul[0]*mul[1])>>8);
|
||||||
|
}
|
||||||
|
return(X.DB);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMC5Synco(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
MMC5PRG();
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
{
|
||||||
|
switch((NTAMirroring>>(x<<1))&3)
|
||||||
|
{
|
||||||
|
case 0:PPUNTARAM|=1<<x;vnapage[x]=NTARAM;break;
|
||||||
|
case 1:PPUNTARAM|=1<<x;vnapage[x]=NTARAM+0x400;break;
|
||||||
|
case 2:PPUNTARAM|=1<<x;vnapage[x]=ExRAM;break;
|
||||||
|
case 3:PPUNTARAM&=~(1<<x);vnapage[x]=MMC5fill;break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MMC5WRAM(0x6000,WRAMPage&7);
|
||||||
|
if(!ABMode)
|
||||||
|
{
|
||||||
|
MMC5CHRB();
|
||||||
|
MMC5CHRA();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMC5CHRA();
|
||||||
|
MMC5CHRB();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
uint32 t;
|
||||||
|
t=NTFill|(NTFill<<8)|(NTFill<<16)|(NTFill<<24);
|
||||||
|
FCEU_dwmemset(MMC5fill,t,0x3c0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
unsigned char moop;
|
||||||
|
uint32 t;
|
||||||
|
moop=ATFill|(ATFill<<2)|(ATFill<<4)|(ATFill<<6);
|
||||||
|
t=moop|(moop<<8)|(moop<<16)|(moop<<24);
|
||||||
|
FCEU_dwmemset(MMC5fill+0x3c0,t,0x40);
|
||||||
|
}
|
||||||
|
X6502_IRQEnd(FCEU_IQEXT);
|
||||||
|
MMC5HackCHRMode=CHRMode&3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMC5_hb(int scanline)
|
||||||
|
{
|
||||||
|
if(scanline==240)
|
||||||
|
{
|
||||||
|
MMC5LineCounter=0;
|
||||||
|
MMC5IRQR=0x40;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(MMC5LineCounter<240)
|
||||||
|
{
|
||||||
|
if(MMC5LineCounter==IRQScanline)
|
||||||
|
{
|
||||||
|
MMC5IRQR|=0x80;
|
||||||
|
if(IRQEnable&0x80)
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
MMC5LineCounter++;
|
||||||
|
}
|
||||||
|
if(MMC5LineCounter==240)
|
||||||
|
MMC5IRQR=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMC5_StateRestore(int version)
|
||||||
|
{
|
||||||
|
MMC5Synco();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16 wl[2];
|
||||||
|
uint8 env[2];
|
||||||
|
uint8 enable;
|
||||||
|
uint8 running;
|
||||||
|
uint8 raw;
|
||||||
|
uint8 rawcontrol;
|
||||||
|
int32 dcount[2];
|
||||||
|
int32 BC[3];
|
||||||
|
int32 vcount[2];
|
||||||
|
} MMC5APU;
|
||||||
|
|
||||||
|
static MMC5APU MMC5Sound;
|
||||||
|
|
||||||
|
|
||||||
|
static void Do5PCM()
|
||||||
|
{
|
||||||
|
int32 V;
|
||||||
|
int32 start,end;
|
||||||
|
|
||||||
|
start=MMC5Sound.BC[2];
|
||||||
|
end=(SOUNDTS<<16)/soundtsinc;
|
||||||
|
if(end<=start) return;
|
||||||
|
MMC5Sound.BC[2]=end;
|
||||||
|
|
||||||
|
if(!(MMC5Sound.rawcontrol&0x40) && MMC5Sound.raw)
|
||||||
|
for(V=start;V<end;V++)
|
||||||
|
Wave[V>>4]+=MMC5Sound.raw<<1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Do5PCMHQ()
|
||||||
|
{
|
||||||
|
int32 V;
|
||||||
|
if(!(MMC5Sound.rawcontrol&0x40) && MMC5Sound.raw)
|
||||||
|
for(V=MMC5Sound.BC[2];V<SOUNDTS;V++)
|
||||||
|
WaveHi[V]+=MMC5Sound.raw<<5;
|
||||||
|
MMC5Sound.BC[2]=SOUNDTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DECLFW(Mapper5_SW)
|
||||||
|
{
|
||||||
|
A&=0x1F;
|
||||||
|
|
||||||
|
GameExpSound.Fill=MMC5RunSound;
|
||||||
|
GameExpSound.HiFill=MMC5RunSoundHQ;
|
||||||
|
|
||||||
|
switch(A)
|
||||||
|
{
|
||||||
|
case 0x10:if(psfun) psfun();MMC5Sound.rawcontrol=V;break;
|
||||||
|
case 0x11:if(psfun) psfun();MMC5Sound.raw=V;break;
|
||||||
|
|
||||||
|
case 0x0:
|
||||||
|
case 0x4://printf("%04x:$%02x\n",A,V&0x30);
|
||||||
|
if(sfun) sfun(A>>2);
|
||||||
|
MMC5Sound.env[A>>2]=V;
|
||||||
|
break;
|
||||||
|
case 0x2:
|
||||||
|
case 0x6: if(sfun) sfun(A>>2);
|
||||||
|
MMC5Sound.wl[A>>2]&=~0x00FF;
|
||||||
|
MMC5Sound.wl[A>>2]|=V&0xFF;
|
||||||
|
break;
|
||||||
|
case 0x3:
|
||||||
|
case 0x7://printf("%04x:$%02x\n",A,V>>3);
|
||||||
|
MMC5Sound.wl[A>>2]&=~0x0700;
|
||||||
|
MMC5Sound.wl[A>>2]|=(V&0x07)<<8;
|
||||||
|
MMC5Sound.running|=1<<(A>>2);
|
||||||
|
break;
|
||||||
|
case 0x15:if(sfun)
|
||||||
|
{
|
||||||
|
sfun(0);
|
||||||
|
sfun(1);
|
||||||
|
}
|
||||||
|
MMC5Sound.running&=V;
|
||||||
|
MMC5Sound.enable=V;
|
||||||
|
//printf("%02x\n",V);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Do5SQ(int P)
|
||||||
|
{
|
||||||
|
static int tal[4]={1,2,4,6};
|
||||||
|
int32 V,amp,rthresh,wl;
|
||||||
|
int32 start,end;
|
||||||
|
|
||||||
|
start=MMC5Sound.BC[P];
|
||||||
|
end=(SOUNDTS<<16)/soundtsinc;
|
||||||
|
if(end<=start) return;
|
||||||
|
MMC5Sound.BC[P]=end;
|
||||||
|
|
||||||
|
wl=MMC5Sound.wl[P]+1;
|
||||||
|
amp=(MMC5Sound.env[P]&0xF)<<4;
|
||||||
|
rthresh=tal[(MMC5Sound.env[P]&0xC0)>>6];
|
||||||
|
|
||||||
|
if(wl>=8 && (MMC5Sound.running&(P+1)))
|
||||||
|
{
|
||||||
|
int dc,vc;
|
||||||
|
|
||||||
|
wl<<=18;
|
||||||
|
dc=MMC5Sound.dcount[P];
|
||||||
|
vc=MMC5Sound.vcount[P];
|
||||||
|
|
||||||
|
for(V=start;V<end;V++)
|
||||||
|
{
|
||||||
|
if(dc<rthresh)
|
||||||
|
Wave[V>>4]+=amp;
|
||||||
|
vc-=nesincsize;
|
||||||
|
while(vc<=0)
|
||||||
|
{
|
||||||
|
vc+=wl;
|
||||||
|
dc=(dc+1)&7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MMC5Sound.dcount[P]=dc;
|
||||||
|
MMC5Sound.vcount[P]=vc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Do5SQHQ(int P)
|
||||||
|
{
|
||||||
|
static int tal[4]={1,2,4,6};
|
||||||
|
int32 V,amp,rthresh,wl;
|
||||||
|
|
||||||
|
wl=MMC5Sound.wl[P]+1;
|
||||||
|
amp=((MMC5Sound.env[P]&0xF)<<8);
|
||||||
|
rthresh=tal[(MMC5Sound.env[P]&0xC0)>>6];
|
||||||
|
|
||||||
|
if(wl>=8 && (MMC5Sound.running&(P+1)))
|
||||||
|
{
|
||||||
|
int dc,vc;
|
||||||
|
|
||||||
|
wl<<=1;
|
||||||
|
|
||||||
|
dc=MMC5Sound.dcount[P];
|
||||||
|
vc=MMC5Sound.vcount[P];
|
||||||
|
for(V=MMC5Sound.BC[P];V<SOUNDTS;V++)
|
||||||
|
{
|
||||||
|
if(dc<rthresh)
|
||||||
|
WaveHi[V]+=amp;
|
||||||
|
vc--;
|
||||||
|
if(vc<=0) /* Less than zero when first started. */
|
||||||
|
{
|
||||||
|
vc=wl;
|
||||||
|
dc=(dc+1)&7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MMC5Sound.dcount[P]=dc;
|
||||||
|
MMC5Sound.vcount[P]=vc;
|
||||||
|
}
|
||||||
|
MMC5Sound.BC[P]=SOUNDTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMC5RunSoundHQ(void)
|
||||||
|
{
|
||||||
|
Do5SQHQ(0);
|
||||||
|
Do5SQHQ(1);
|
||||||
|
Do5PCMHQ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMC5HiSync(int32 ts)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=0;x<3;x++) MMC5Sound.BC[x]=ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMC5RunSound(int Count)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
Do5SQ(0);
|
||||||
|
Do5SQ(1);
|
||||||
|
Do5PCM();
|
||||||
|
for(x=0;x<3;x++)
|
||||||
|
MMC5Sound.BC[x]=Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper5_ESI(void)
|
||||||
|
{
|
||||||
|
GameExpSound.RChange=Mapper5_ESI;
|
||||||
|
if(FSettings.SndRate)
|
||||||
|
{
|
||||||
|
if(FSettings.soundq>=1)
|
||||||
|
{
|
||||||
|
sfun=Do5SQHQ;
|
||||||
|
psfun=Do5PCMHQ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sfun=Do5SQ;
|
||||||
|
psfun=Do5PCM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sfun=0;
|
||||||
|
psfun=0;
|
||||||
|
}
|
||||||
|
memset(MMC5Sound.BC,0,sizeof(MMC5Sound.BC));
|
||||||
|
memset(MMC5Sound.vcount,0,sizeof(MMC5Sound.vcount));
|
||||||
|
GameExpSound.HiSync=MMC5HiSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NSFMMC5_Init(void)
|
||||||
|
{
|
||||||
|
memset(&MMC5Sound,0,sizeof(MMC5Sound));
|
||||||
|
mul[0]=mul[1]=0;
|
||||||
|
ExRAM=(uint8*)FCEU_gmalloc(1024);
|
||||||
|
Mapper5_ESI();
|
||||||
|
SetWriteHandler(0x5c00,0x5fef,MMC5_ExRAMWr);
|
||||||
|
SetReadHandler(0x5c00,0x5fef,MMC5_ExRAMRd);
|
||||||
|
MMC5HackCHRMode=2;
|
||||||
|
SetWriteHandler(0x5000,0x5015,Mapper5_SW);
|
||||||
|
SetWriteHandler(0x5205,0x5206,Mapper5_write);
|
||||||
|
SetReadHandler(0x5205,0x5206,MMC5_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NSFMMC5_Close(void)
|
||||||
|
{
|
||||||
|
FCEU_gfree(ExRAM);
|
||||||
|
ExRAM=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenMMC5Reset(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<4;x++) PRGBanks[x]=~0;
|
||||||
|
for(x=0;x<8;x++) CHRBanksA[x]=~0;
|
||||||
|
for(x=0;x<4;x++) CHRBanksB[x]=~0;
|
||||||
|
WRAMMaskEnable[0]=WRAMMaskEnable[1]=~0;
|
||||||
|
|
||||||
|
mmc5psize=mmc5vsize=3;
|
||||||
|
CHRMode=0;
|
||||||
|
|
||||||
|
NTAMirroring=NTFill=ATFill=0xFF;
|
||||||
|
|
||||||
|
MMC5Synco();
|
||||||
|
|
||||||
|
SetWriteHandler(0x4020,0x5bff,Mapper5_write);
|
||||||
|
SetReadHandler(0x4020,0x5bff,MMC5_read);
|
||||||
|
|
||||||
|
SetWriteHandler(0x5c00,0x5fff,MMC5_ExRAMWr);
|
||||||
|
SetReadHandler(0x5c00,0x5fff,MMC5_ExRAMRd);
|
||||||
|
|
||||||
|
SetWriteHandler(0x6000,0xFFFF,MMC5_WriteROMRAM);
|
||||||
|
SetReadHandler(0x6000,0xFFFF,MMC5_ReadROMRAM);
|
||||||
|
|
||||||
|
SetWriteHandler(0x5000,0x5015,Mapper5_SW);
|
||||||
|
SetWriteHandler(0x5205,0x5206,Mapper5_write);
|
||||||
|
SetReadHandler(0x5205,0x5206,MMC5_read);
|
||||||
|
|
||||||
|
//GameHBIRQHook=MMC5_hb;
|
||||||
|
FCEU_CheatAddRAM(8,0x6000,WRAM);
|
||||||
|
FCEU_CheatAddRAM(1,0x5c00,ExRAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SFORMAT MMC5_StateRegs[]={
|
||||||
|
{ PRGBanks, 4, "PRGB"},
|
||||||
|
{ CHRBanksA, 8, "CHRA"},
|
||||||
|
{ CHRBanksB, 4, "CHRB"},
|
||||||
|
{ &WRAMPage, 1, "WRMP"},
|
||||||
|
{ WRAMMaskEnable, 2, "WRME"},
|
||||||
|
{ &ABMode, 1, "ABMD"},
|
||||||
|
{ &IRQScanline, 1, "IRQS"},
|
||||||
|
{ &IRQEnable, 1, "IRQE"},
|
||||||
|
{ &CHRMode, 1, "CHRM"},
|
||||||
|
{ &NTAMirroring, 1, "NTAM"},
|
||||||
|
{ &NTFill, 1, "NTFL"},
|
||||||
|
{ &ATFill, 1, "ATFL"},
|
||||||
|
|
||||||
|
{ &MMC5Sound.wl[0], 2|FCEUSTATE_RLSB, "SDW0"},
|
||||||
|
{ &MMC5Sound.wl[1], 2|FCEUSTATE_RLSB, "SDW1"},
|
||||||
|
{ MMC5Sound.env, 2, "SDEV"},
|
||||||
|
{ &MMC5Sound.enable, 1, "SDEN"},
|
||||||
|
{ &MMC5Sound.running, 1, "SDRU"},
|
||||||
|
{ &MMC5Sound.raw, 1, "SDRW"},
|
||||||
|
{ &MMC5Sound.rawcontrol, 1, "SDRC"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void GenMMC5_Init(CartInfo *info, int wsize, int battery)
|
||||||
|
{
|
||||||
|
if(wsize)
|
||||||
|
{
|
||||||
|
WRAM=(uint8*)FCEU_gmalloc(wsize*1024);
|
||||||
|
SetupCartPRGMapping(0x10,WRAM,wsize*1024,1);
|
||||||
|
AddExState(WRAM, wsize*1024, 0, "WRAM");
|
||||||
|
}
|
||||||
|
|
||||||
|
MMC5fill=(uint8*)FCEU_gmalloc(1024);
|
||||||
|
ExRAM=(uint8*)FCEU_gmalloc(1024);
|
||||||
|
|
||||||
|
AddExState(MMC5_StateRegs, ~0, 0, 0);
|
||||||
|
AddExState(WRAM, wsize*1024, 0, "WRAM");
|
||||||
|
AddExState(ExRAM, 1024, 0, "ERAM");
|
||||||
|
AddExState(&MMC5HackSPMode, 1, 0, "SPLM");
|
||||||
|
AddExState(&MMC5HackSPScroll, 1, 0, "SPLS");
|
||||||
|
AddExState(&MMC5HackSPPage, 1, 0, "SPLP");
|
||||||
|
|
||||||
|
MMC5WRAMsize=wsize/8;
|
||||||
|
BuildWRAMSizeTable();
|
||||||
|
GameStateRestore=MMC5_StateRestore;
|
||||||
|
info->Power=GenMMC5Reset;
|
||||||
|
|
||||||
|
if(battery)
|
||||||
|
{
|
||||||
|
info->SaveGame[0]=WRAM;
|
||||||
|
if(wsize<=16)
|
||||||
|
info->SaveGameLen[0]=8192;
|
||||||
|
else
|
||||||
|
info->SaveGameLen[0]=32768;
|
||||||
|
}
|
||||||
|
|
||||||
|
MMC5HackVROMMask=CHRmask4[0];
|
||||||
|
MMC5HackExNTARAMPtr=ExRAM;
|
||||||
|
MMC5Hack=1;
|
||||||
|
MMC5HackVROMPTR=CHRptr[0];
|
||||||
|
MMC5HackCHRMode=0;
|
||||||
|
MMC5HackSPMode=MMC5HackSPScroll=MMC5HackSPPage=0;
|
||||||
|
Mapper5_ESI();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper5_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC5_Init(info, DetectMMC5WRAMSize(info->CRC32), info->battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELROM seems to have 0KB of WRAM
|
||||||
|
// EKROM seems to have 8KB of WRAM
|
||||||
|
// ETROM seems to have 16KB of WRAM
|
||||||
|
// EWROM seems to have 32KB of WRAM
|
||||||
|
|
||||||
|
// ETROM and EWROM are battery-backed, EKROM isn't.
|
||||||
|
|
||||||
|
void ETROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC5_Init(info, 16,info->battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ELROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC5_Init(info,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EWROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC5_Init(info,32,info->battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EKROM_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC5_Init(info,8,info->battery);
|
||||||
|
}
|
|
@ -0,0 +1,469 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint16 IRQCount;
|
||||||
|
static uint8 IRQa;
|
||||||
|
|
||||||
|
static uint8 WRAM[8192];
|
||||||
|
static uint8 IRAM[128];
|
||||||
|
|
||||||
|
static DECLFR(AWRAM)
|
||||||
|
{
|
||||||
|
return(WRAM[A-0x6000]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BWRAM)
|
||||||
|
{
|
||||||
|
WRAM[A-0x6000]=V;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper19_ESI(void);
|
||||||
|
|
||||||
|
static uint8 NTAPage[4];
|
||||||
|
|
||||||
|
static uint8 dopol;
|
||||||
|
static uint8 gorfus;
|
||||||
|
static uint8 gorko;
|
||||||
|
|
||||||
|
static void NamcoSound(int Count);
|
||||||
|
static void NamcoSoundHack(void);
|
||||||
|
static void DoNamcoSound(int32 *Wave, int Count);
|
||||||
|
static void DoNamcoSoundHQ(void);
|
||||||
|
static void SyncHQ(int32 ts);
|
||||||
|
|
||||||
|
static int is210; /* Lesser mapper. */
|
||||||
|
|
||||||
|
static uint8 PRG[3];
|
||||||
|
static uint8 CHR[8];
|
||||||
|
|
||||||
|
static SFORMAT N106_StateRegs[]={
|
||||||
|
{PRG,3,"PRG"},
|
||||||
|
{CHR,8,"CHR"},
|
||||||
|
{NTAPage,4,"NTA"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void SyncPRG(void)
|
||||||
|
{
|
||||||
|
setprg8(0x8000,PRG[0]);
|
||||||
|
setprg8(0xa000,PRG[1]);
|
||||||
|
setprg8(0xc000,PRG[2]);
|
||||||
|
setprg8(0xe000,0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FP_FASTAPASS(1) NamcoIRQHook(int a)
|
||||||
|
{
|
||||||
|
if(IRQa)
|
||||||
|
{
|
||||||
|
IRQCount+=a;
|
||||||
|
if(IRQCount>=0x7FFF)
|
||||||
|
{
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
IRQa=0;
|
||||||
|
IRQCount=0x7FFF; //7FFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(Namco_Read4800)
|
||||||
|
{
|
||||||
|
uint8 ret=IRAM[dopol&0x7f];
|
||||||
|
/* Maybe I should call NamcoSoundHack() here? */
|
||||||
|
if(!fceuindbg)
|
||||||
|
if(dopol&0x80)
|
||||||
|
dopol=(dopol&0x80)|((dopol+1)&0x7f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(Namco_Read5000)
|
||||||
|
{
|
||||||
|
return(IRQCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(Namco_Read5800)
|
||||||
|
{
|
||||||
|
return(IRQCount>>8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FASTAPASS(2) DoNTARAMROM(int w, uint8 V)
|
||||||
|
{
|
||||||
|
NTAPage[w]=V;
|
||||||
|
if(V>=0xE0)
|
||||||
|
setntamem(NTARAM+((V&1)<<10), 1, w);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
V&=CHRmask1[0];
|
||||||
|
setntamem(CHRptr[0]+(V<<10), 0, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FixNTAR(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
DoNTARAMROM(x,NTAPage[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FASTAPASS(2) DoCHRRAMROM(int x, uint8 V)
|
||||||
|
{
|
||||||
|
CHR[x]=V;
|
||||||
|
if(!is210 && !((gorfus>>((x>>2)+6))&1) && (V>=0xE0))
|
||||||
|
{
|
||||||
|
// printf("BLAHAHA: %d, %02x\n",x,V);
|
||||||
|
//setchr1r(0x10,x<<10,V&7);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setchr1(x<<10,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FixCRR(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
DoCHRRAMROM(x,CHR[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(Mapper19C0D8_write)
|
||||||
|
{
|
||||||
|
DoNTARAMROM((A-0xC000)>>11,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 FreqCache[8];
|
||||||
|
static uint32 EnvCache[8];
|
||||||
|
static uint32 LengthCache[8];
|
||||||
|
|
||||||
|
static void FixCache(int a,int V)
|
||||||
|
{
|
||||||
|
int w=(a>>3)&0x7;
|
||||||
|
switch(a&0x07)
|
||||||
|
{
|
||||||
|
case 0x00:FreqCache[w]&=~0x000000FF;FreqCache[w]|=V;break;
|
||||||
|
case 0x02:FreqCache[w]&=~0x0000FF00;FreqCache[w]|=V<<8;break;
|
||||||
|
case 0x04:FreqCache[w]&=~0x00030000;FreqCache[w]|=(V&3)<<16;
|
||||||
|
LengthCache[w]=(8-((V>>2)&7))<<2;
|
||||||
|
break;
|
||||||
|
case 0x07:EnvCache[w]=(double)(V&0xF)*576716;break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(Mapper19_write)
|
||||||
|
{
|
||||||
|
A&=0xF800;
|
||||||
|
if(A>=0x8000 && A<=0xb800)
|
||||||
|
DoCHRRAMROM((A-0x8000)>>11,V);
|
||||||
|
else switch(A)
|
||||||
|
{
|
||||||
|
case 0x4800:
|
||||||
|
if(dopol&0x40)
|
||||||
|
{
|
||||||
|
if(FSettings.SndRate)
|
||||||
|
{
|
||||||
|
NamcoSoundHack();
|
||||||
|
GameExpSound.Fill=NamcoSound;
|
||||||
|
GameExpSound.HiFill=DoNamcoSoundHQ;
|
||||||
|
GameExpSound.HiSync=SyncHQ;
|
||||||
|
}
|
||||||
|
FixCache(dopol,V);
|
||||||
|
}
|
||||||
|
IRAM[dopol&0x7f]=V;
|
||||||
|
if(dopol&0x80)
|
||||||
|
dopol=(dopol&0x80)|((dopol+1)&0x7f);
|
||||||
|
break;
|
||||||
|
case 0xf800:
|
||||||
|
dopol=V;break;
|
||||||
|
case 0x5000:
|
||||||
|
IRQCount&=0xFF00;IRQCount|=V;X6502_IRQEnd(FCEU_IQEXT);break;
|
||||||
|
case 0x5800:
|
||||||
|
IRQCount&=0x00ff;IRQCount|=(V&0x7F)<<8;
|
||||||
|
IRQa=V&0x80;
|
||||||
|
X6502_IRQEnd(FCEU_IQEXT);
|
||||||
|
break;
|
||||||
|
case 0xE000:
|
||||||
|
gorko=V&0xC0;
|
||||||
|
PRG[0]=V&0x3F;
|
||||||
|
SyncPRG();
|
||||||
|
break;
|
||||||
|
case 0xE800:
|
||||||
|
gorfus=V&0xC0;
|
||||||
|
FixCRR();
|
||||||
|
PRG[1]=V&0x3F;
|
||||||
|
SyncPRG();
|
||||||
|
break;
|
||||||
|
case 0xF000:
|
||||||
|
PRG[2]=V&0x3F;
|
||||||
|
SyncPRG();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dwave=0;
|
||||||
|
|
||||||
|
static void NamcoSoundHack(void)
|
||||||
|
{
|
||||||
|
int32 z,a;
|
||||||
|
if(FSettings.soundq>=1)
|
||||||
|
{
|
||||||
|
DoNamcoSoundHQ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
z=((SOUNDTS<<16)/soundtsinc)>>4;
|
||||||
|
a=z-dwave;
|
||||||
|
if(a) DoNamcoSound(&Wave[dwave], a);
|
||||||
|
dwave+=a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NamcoSound(int Count)
|
||||||
|
{
|
||||||
|
int32 z,a;
|
||||||
|
z=((SOUNDTS<<16)/soundtsinc)>>4;
|
||||||
|
a=z-dwave;
|
||||||
|
if(a) DoNamcoSound(&Wave[dwave], a);
|
||||||
|
dwave=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 PlayIndex[8];
|
||||||
|
static int32 vcount[8];
|
||||||
|
static int32 CVBC;
|
||||||
|
|
||||||
|
#define TOINDEX (16+1)
|
||||||
|
|
||||||
|
// 16:15
|
||||||
|
static void SyncHQ(int32 ts)
|
||||||
|
{
|
||||||
|
CVBC=ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Things to do:
|
||||||
|
1 Read freq low
|
||||||
|
2 Read freq mid
|
||||||
|
3 Read freq high
|
||||||
|
4 Read envelope
|
||||||
|
...?
|
||||||
|
*/
|
||||||
|
|
||||||
|
static INLINE uint32 FetchDuff(uint32 P, uint32 envelope)
|
||||||
|
{
|
||||||
|
uint32 duff;
|
||||||
|
duff=IRAM[((IRAM[0x46+(P<<3)]+(PlayIndex[P]>>TOINDEX))&0xFF)>>1];
|
||||||
|
if((IRAM[0x46+(P<<3)]+(PlayIndex[P]>>TOINDEX))&1)
|
||||||
|
duff>>=4;
|
||||||
|
duff&=0xF;
|
||||||
|
duff=(duff*envelope)>>16;
|
||||||
|
return(duff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DoNamcoSoundHQ(void)
|
||||||
|
{
|
||||||
|
int32 P,V;
|
||||||
|
int32 cyclesuck=(((IRAM[0x7F]>>4)&7)+1)*15;
|
||||||
|
|
||||||
|
for(P=7;P>=(7-((IRAM[0x7F]>>4)&7));P--)
|
||||||
|
{
|
||||||
|
if((IRAM[0x44+(P<<3)]&0xE0) && (IRAM[0x47+(P<<3)]&0xF))
|
||||||
|
{
|
||||||
|
uint32 freq;
|
||||||
|
int32 vco;
|
||||||
|
uint32 duff2,lengo,envelope;
|
||||||
|
|
||||||
|
vco=vcount[P];
|
||||||
|
freq=FreqCache[P];
|
||||||
|
envelope=EnvCache[P];
|
||||||
|
lengo=LengthCache[P];
|
||||||
|
|
||||||
|
duff2=FetchDuff(P,envelope);
|
||||||
|
for(V=CVBC<<1;V<SOUNDTS<<1;V++)
|
||||||
|
{
|
||||||
|
WaveHi[V>>1]+=duff2;
|
||||||
|
if(!vco)
|
||||||
|
{
|
||||||
|
PlayIndex[P]+=freq;
|
||||||
|
while((PlayIndex[P]>>TOINDEX)>=lengo) PlayIndex[P]-=lengo<<TOINDEX;
|
||||||
|
duff2=FetchDuff(P,envelope);
|
||||||
|
vco=cyclesuck;
|
||||||
|
}
|
||||||
|
vco--;
|
||||||
|
}
|
||||||
|
vcount[P]=vco;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CVBC=SOUNDTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void DoNamcoSound(int32 *Wave, int Count)
|
||||||
|
{
|
||||||
|
int P,V;
|
||||||
|
for(P=7;P>=7-((IRAM[0x7F]>>4)&7);P--)
|
||||||
|
{
|
||||||
|
if((IRAM[0x44+(P<<3)]&0xE0) && (IRAM[0x47+(P<<3)]&0xF))
|
||||||
|
{
|
||||||
|
int32 inc;
|
||||||
|
uint32 freq;
|
||||||
|
int32 vco;
|
||||||
|
uint32 duff,duff2,lengo,envelope;
|
||||||
|
|
||||||
|
vco=vcount[P];
|
||||||
|
freq=FreqCache[P];
|
||||||
|
envelope=EnvCache[P];
|
||||||
|
lengo=LengthCache[P];
|
||||||
|
|
||||||
|
if(!freq) {/*printf("Ack");*/ continue;}
|
||||||
|
|
||||||
|
{
|
||||||
|
int c=((IRAM[0x7F]>>4)&7)+1;
|
||||||
|
inc=(long double)(FSettings.SndRate<<15)/((long double)freq*21477272/((long double)0x400000*c*45));
|
||||||
|
}
|
||||||
|
|
||||||
|
duff=IRAM[(((IRAM[0x46+(P<<3)]+PlayIndex[P])&0xFF)>>1)];
|
||||||
|
if((IRAM[0x46+(P<<3)]+PlayIndex[P])&1)
|
||||||
|
duff>>=4;
|
||||||
|
duff&=0xF;
|
||||||
|
duff2=(duff*envelope)>>19;
|
||||||
|
for(V=0;V<Count*16;V++)
|
||||||
|
{
|
||||||
|
if(vco>=inc)
|
||||||
|
{
|
||||||
|
PlayIndex[P]++;
|
||||||
|
if(PlayIndex[P]>=lengo)
|
||||||
|
PlayIndex[P]=0;
|
||||||
|
vco-=inc;
|
||||||
|
duff=IRAM[(((IRAM[0x46+(P<<3)]+PlayIndex[P])&0xFF)>>1)];
|
||||||
|
if((IRAM[0x46+(P<<3)]+PlayIndex[P])&1)
|
||||||
|
duff>>=4;
|
||||||
|
duff&=0xF;
|
||||||
|
duff2=(duff*envelope)>>19;
|
||||||
|
}
|
||||||
|
Wave[V>>4]+=duff2;
|
||||||
|
vco+=0x8000;
|
||||||
|
}
|
||||||
|
vcount[P]=vco;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Mapper19_StateRestore(int version)
|
||||||
|
{
|
||||||
|
SyncPRG();
|
||||||
|
FixNTAR();
|
||||||
|
FixCRR();
|
||||||
|
int x;
|
||||||
|
for(x=0x40;x<0x80;x++)
|
||||||
|
FixCache(x,IRAM[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M19SC(void)
|
||||||
|
{
|
||||||
|
if(FSettings.SndRate)
|
||||||
|
Mapper19_ESI();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper19_ESI(void)
|
||||||
|
{
|
||||||
|
GameExpSound.RChange=M19SC;
|
||||||
|
memset(vcount,0,sizeof(vcount));
|
||||||
|
memset(PlayIndex,0,sizeof(PlayIndex));
|
||||||
|
CVBC=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NSFN106_Init(void)
|
||||||
|
{
|
||||||
|
SetWriteHandler(0xf800,0xffff,Mapper19_write);
|
||||||
|
SetWriteHandler(0x4800,0x4fff,Mapper19_write);
|
||||||
|
SetReadHandler(0x4800,0x4fff,Namco_Read4800);
|
||||||
|
Mapper19_ESI();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int battery=0;
|
||||||
|
|
||||||
|
static void N106_Power(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xffff,Mapper19_write);
|
||||||
|
SetWriteHandler(0x4020,0x5fff,Mapper19_write);
|
||||||
|
if(!is210)
|
||||||
|
{
|
||||||
|
SetWriteHandler(0xc000,0xdfff,Mapper19C0D8_write);
|
||||||
|
SetReadHandler(0x4800,0x4fff,Namco_Read4800);
|
||||||
|
SetReadHandler(0x5000,0x57ff,Namco_Read5000);
|
||||||
|
SetReadHandler(0x5800,0x5fff,Namco_Read5800);
|
||||||
|
NTAPage[0]=NTAPage[1]=NTAPage[2]=NTAPage[3]=0xFF;
|
||||||
|
FixNTAR();
|
||||||
|
}
|
||||||
|
|
||||||
|
SetReadHandler(0x6000,0x7FFF,AWRAM);
|
||||||
|
SetWriteHandler(0x6000,0x7FFF,BWRAM);
|
||||||
|
FCEU_CheatAddRAM(8,0x6000,WRAM);
|
||||||
|
|
||||||
|
gorfus=0xFF;
|
||||||
|
SyncPRG();
|
||||||
|
FixCRR();
|
||||||
|
|
||||||
|
if(!battery)
|
||||||
|
{
|
||||||
|
FCEU_dwmemset(WRAM,0,8192);
|
||||||
|
FCEU_dwmemset(IRAM,0,128);
|
||||||
|
}
|
||||||
|
for(x=0x40;x<0x80;x++)
|
||||||
|
FixCache(x,IRAM[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper19_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
is210=0;
|
||||||
|
battery=info->battery;
|
||||||
|
info->Power=N106_Power;
|
||||||
|
|
||||||
|
MapIRQHook=NamcoIRQHook;
|
||||||
|
GameStateRestore=Mapper19_StateRestore;
|
||||||
|
GameExpSound.RChange=M19SC;
|
||||||
|
|
||||||
|
if(FSettings.SndRate)
|
||||||
|
Mapper19_ESI();
|
||||||
|
|
||||||
|
AddExState(WRAM, 8192, 0, "WRAM");
|
||||||
|
AddExState(IRAM, 128, 0, "WRAM");
|
||||||
|
AddExState(N106_StateRegs, ~0, 0, 0);
|
||||||
|
|
||||||
|
if(info->battery)
|
||||||
|
{
|
||||||
|
info->SaveGame[0]=WRAM;
|
||||||
|
info->SaveGameLen[0]=8192;
|
||||||
|
info->SaveGame[1]=IRAM;
|
||||||
|
info->SaveGameLen[1]=128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Mapper210_StateRestore(int version)
|
||||||
|
{
|
||||||
|
SyncPRG();
|
||||||
|
FixCRR();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper210_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
is210=1;
|
||||||
|
GameStateRestore=Mapper210_StateRestore;
|
||||||
|
info->Power=N106_Power;
|
||||||
|
AddExState(WRAM, 8192, 0, "WRAM");
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 latch;
|
||||||
|
|
||||||
|
static void DoNovel(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,latch&3);
|
||||||
|
setchr8(latch&7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(NovelWrite)
|
||||||
|
{
|
||||||
|
latch=A&0xFF;
|
||||||
|
DoNovel();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NovelReset(void)
|
||||||
|
{
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,NovelWrite);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
setprg32(0x8000,0);
|
||||||
|
setchr8(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NovelRestore(int version)
|
||||||
|
{
|
||||||
|
DoNovel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Novel_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
AddExState(&latch, 1, 0,"L1");
|
||||||
|
info->Power=NovelReset;
|
||||||
|
GameStateRestore=NovelRestore;
|
||||||
|
}
|
|
@ -0,0 +1,398 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 cmd;
|
||||||
|
static uint8 latch[8];
|
||||||
|
|
||||||
|
static void S74LS374MSync(uint8 mirr)
|
||||||
|
{
|
||||||
|
switch(mirr&3)
|
||||||
|
{
|
||||||
|
case 0:setmirror(MI_V);break;
|
||||||
|
case 1:setmirror(MI_H);break;
|
||||||
|
case 2:setmirrorw(0,1,1,1);break;
|
||||||
|
case 3:setmirror(MI_0);break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void S74LS374NSynco(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,latch[0]);
|
||||||
|
setchr8(latch[1]|latch[3]|latch[4]);
|
||||||
|
S74LS374MSync(latch[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(S74LS374NWrite)
|
||||||
|
{
|
||||||
|
A&=0x4101;
|
||||||
|
if(A==0x4100)
|
||||||
|
cmd=V&7;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(cmd)
|
||||||
|
{
|
||||||
|
case 2:latch[0]=V&1; latch[3]=(V&1)<<3;break;
|
||||||
|
case 4:latch[4]=(V&1)<<2;break;
|
||||||
|
case 5:latch[0]=V&7;break;
|
||||||
|
case 6:latch[1]=V&3;break;
|
||||||
|
case 7:latch[2]=V>>1;break;
|
||||||
|
}
|
||||||
|
S74LS374NSynco();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(S74LS374NRead)
|
||||||
|
{
|
||||||
|
uint8 ret;
|
||||||
|
if((A&0x4100)==0x4100)
|
||||||
|
ret=(X.DB&0xC0)|((~cmd)&0x3F);
|
||||||
|
else
|
||||||
|
ret=X.DB;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void S74LS374NPower(void)
|
||||||
|
{
|
||||||
|
latch[0]=latch[1]=latch[2]=latch[3]=latch[4]=0;
|
||||||
|
S74LS374NSynco();
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x4100,0x7FFF,S74LS374NWrite);
|
||||||
|
SetReadHandler(0x4100,0x5fff,S74LS374NRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void S74LS374NRestore(int version)
|
||||||
|
{
|
||||||
|
S74LS374NSynco();
|
||||||
|
}
|
||||||
|
|
||||||
|
void S74LS374N_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=S74LS374NPower;
|
||||||
|
GameStateRestore=S74LS374NRestore;
|
||||||
|
AddExState(latch, 5, 0, "LATC");
|
||||||
|
AddExState(&cmd, 1, 0, "CMD");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void S74LS374NASynco(void)
|
||||||
|
{
|
||||||
|
setprg32(0x8000,latch[0]);
|
||||||
|
setchr8(latch[1]);
|
||||||
|
S74LS374MSync(latch[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(S74LS374NAWrite)
|
||||||
|
{
|
||||||
|
A&=0x4101;
|
||||||
|
if(A==0x4100)
|
||||||
|
cmd=V&7;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(cmd)
|
||||||
|
{
|
||||||
|
case 0:latch[0]=0;latch[1]=3;break;
|
||||||
|
case 2:latch[3]=(V&1)<<3;break;
|
||||||
|
case 4:latch[1]=(latch[1]&6)|(V&3);break;
|
||||||
|
case 5:latch[0]=V&1;break;
|
||||||
|
case 6:latch[1]=(latch[1]&1)|latch[3]|((V&3)<<1);break;
|
||||||
|
case 7:latch[2]=V&1;break;
|
||||||
|
}
|
||||||
|
S74LS374NASynco();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void S74LS374NAPower(void)
|
||||||
|
{
|
||||||
|
latch[0]=latch[2]=latch[3]=latch[4]=0;
|
||||||
|
latch[1]=3;
|
||||||
|
S74LS374NASynco();
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x4100,0x7FFF,S74LS374NAWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void S74LS374NA_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=S74LS374NAPower;
|
||||||
|
GameStateRestore=S74LS374NRestore;
|
||||||
|
AddExState(latch, 5, 0, "LATC");
|
||||||
|
AddExState(&cmd, 1, 0, "CMD");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int type;
|
||||||
|
static void S8259Synco(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
setprg32(0x8000,latch[5]&7);
|
||||||
|
|
||||||
|
if(!UNIFchrrama) // No CHR RAM? Then BS'ing is ok.
|
||||||
|
{
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
{
|
||||||
|
int bank;
|
||||||
|
if(latch[7]&1)
|
||||||
|
bank=(latch[0]&0x7)|((latch[4]&7)<<3);
|
||||||
|
else
|
||||||
|
bank=(latch[x]&0x7)|((latch[4]&7)<<3);
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 00: bank=(bank<<1)|(x&1); setchr2(0x800*x,bank); break;
|
||||||
|
case 01: setchr2(0x800*x,bank); break;
|
||||||
|
case 02: bank=(bank<<2)|(x&3); setchr2(0x800*x,bank); break;
|
||||||
|
case 03: bank=latch[x]&7;
|
||||||
|
switch (x&3)
|
||||||
|
{
|
||||||
|
case 01: bank|=(latch[4]&1)<<4;break;
|
||||||
|
case 02: bank|=(latch[4]&2)<<3;break;
|
||||||
|
case 03: bank|=((latch[4]&4)<<2)|((latch[6]&1)<<3);break;
|
||||||
|
}
|
||||||
|
setchr1(0x400*x,bank);
|
||||||
|
setchr4(0x1000,~0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!(latch[7]&1))
|
||||||
|
S74LS374MSync(latch[7]>>1);
|
||||||
|
else
|
||||||
|
setmirror(MI_V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(S8259Write)
|
||||||
|
{
|
||||||
|
A&=0x4101;
|
||||||
|
if(A==0x4100)
|
||||||
|
cmd=V;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
latch[cmd&7]=V;
|
||||||
|
S8259Synco();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void S8259Reset(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
cmd=0;
|
||||||
|
|
||||||
|
for(x=0;x<8;x++) latch[x]=0;
|
||||||
|
setchr8(0);
|
||||||
|
|
||||||
|
S8259Synco();
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x4100,0x7FFF,S8259Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void S8259Restore(int version)
|
||||||
|
{
|
||||||
|
S8259Synco();
|
||||||
|
}
|
||||||
|
|
||||||
|
void S8259A_Init(CartInfo *info) // Kevin's Horton 141 mapper
|
||||||
|
{
|
||||||
|
info->Power=S8259Reset;
|
||||||
|
GameStateRestore=S8259Restore;
|
||||||
|
AddExState(latch, 8, 0, "LATC");
|
||||||
|
AddExState(&cmd, 1, 0, "CMD");
|
||||||
|
type=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void S8259B_Init(CartInfo *info) // Kevin's Horton 138 mapper
|
||||||
|
{
|
||||||
|
info->Power=S8259Reset;
|
||||||
|
GameStateRestore=S8259Restore;
|
||||||
|
AddExState(latch, 8, 0, "LATC");
|
||||||
|
AddExState(&cmd, 1, 0, "CMD");
|
||||||
|
type=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void S8259C_Init(CartInfo *info) // Kevin's Horton 139 mapper
|
||||||
|
{
|
||||||
|
info->Power=S8259Reset;
|
||||||
|
GameStateRestore=S8259Restore;
|
||||||
|
AddExState(latch, 8, 0, "LATC");
|
||||||
|
AddExState(&cmd, 1, 0, "CMD");
|
||||||
|
type=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void S8259D_Init(CartInfo *info) // Kevin's Horton 137 mapper
|
||||||
|
{
|
||||||
|
info->Power=S8259Reset;
|
||||||
|
GameStateRestore=S8259Restore;
|
||||||
|
AddExState(latch, 8, 0, "LATC");
|
||||||
|
AddExState(&cmd, 1, 0, "CMD");
|
||||||
|
type=3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void(*WSync)(void);
|
||||||
|
|
||||||
|
static DECLFW(SAWrite)
|
||||||
|
{
|
||||||
|
if(A&0x100)
|
||||||
|
{
|
||||||
|
latch[0]=V;
|
||||||
|
WSync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SAPower(void)
|
||||||
|
{
|
||||||
|
latch[0]=0;
|
||||||
|
WSync();
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x4100,0x5FFF,SAWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SARestore(int version)
|
||||||
|
{
|
||||||
|
WSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(SADWrite)
|
||||||
|
{
|
||||||
|
latch[0]=V;
|
||||||
|
WSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SADPower(void)
|
||||||
|
{
|
||||||
|
latch[0]=0;
|
||||||
|
WSync();
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,SADWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SA0161MSynco()
|
||||||
|
{
|
||||||
|
setprg32(0x8000,(latch[0]>>3)&1);
|
||||||
|
setchr8(latch[0]&7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SA72007Synco()
|
||||||
|
{
|
||||||
|
setprg32(0x8000,0);
|
||||||
|
setchr8(latch[0]>>7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SA72008Synco()
|
||||||
|
{
|
||||||
|
setprg32(0x8000,(latch[0]>>2)&1);
|
||||||
|
setchr8(latch[0]&3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA0161M_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
WSync=SA0161MSynco;
|
||||||
|
GameStateRestore=SARestore;
|
||||||
|
info->Power=SAPower;
|
||||||
|
AddExState(&latch[0], 1, 0, "LATC");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA72007_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
WSync=SA72007Synco;
|
||||||
|
GameStateRestore=SARestore;
|
||||||
|
info->Power=SAPower;
|
||||||
|
AddExState(&latch[0], 1, 0, "LATC");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA72008_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
WSync=SA72008Synco;
|
||||||
|
GameStateRestore=SARestore;
|
||||||
|
info->Power=SAPower;
|
||||||
|
AddExState(&latch[0], 1, 0, "LATC");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA0036_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
WSync=SA72007Synco;
|
||||||
|
GameStateRestore=SARestore;
|
||||||
|
info->Power=SADPower;
|
||||||
|
AddExState(&latch[0], 1, 0, "LATC");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA0037_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
WSync=SA0161MSynco;
|
||||||
|
GameStateRestore=SARestore;
|
||||||
|
info->Power=SADPower;
|
||||||
|
AddExState(&latch[0], 1, 0, "LATC");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TCU01Synco()
|
||||||
|
{
|
||||||
|
setprg32(0x8000,(latch[0]>>2)&1);
|
||||||
|
setchr8((latch[0]>>3)&0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(TCWrite)
|
||||||
|
{
|
||||||
|
if((A&0x103)==0x102)
|
||||||
|
{
|
||||||
|
latch[0]=V;
|
||||||
|
TCU01Synco();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TCU01Reset(void)
|
||||||
|
{
|
||||||
|
latch[0]=0;
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x4100,0xFFFF,TCWrite);
|
||||||
|
TCU01Synco();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TCU01Restore(int version)
|
||||||
|
{
|
||||||
|
TCU01Synco();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCU01_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GameStateRestore=TCU01Restore;
|
||||||
|
info->Power=TCU01Reset;
|
||||||
|
AddExState(&latch[0], 1, 0, "LATC");
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(TCA01Read)
|
||||||
|
{
|
||||||
|
uint8 ret;
|
||||||
|
if((A&0x4100)==0x4100)
|
||||||
|
ret=(X.DB&0xC0)|((~A)&0x3F);
|
||||||
|
else
|
||||||
|
ret=X.DB;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TCA01Reset(void)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,0);
|
||||||
|
setprg16(0xC000,1);
|
||||||
|
setchr8(0);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetReadHandler(0x4100,0x5FFF,TCA01Read);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCA01_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=TCA01Reset;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2006 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
#include "mmc3.h"
|
||||||
|
|
||||||
|
static uint8 *CHRRAM;
|
||||||
|
static uint8 tekker;
|
||||||
|
|
||||||
|
static void MSHCW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&0x40)
|
||||||
|
setchr8r(0x10,0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(A<0x800)
|
||||||
|
setchr1(A,V|((EXPREGS[0]&8)<<5));
|
||||||
|
else if(A<0x1000)
|
||||||
|
setchr1(A,V|((EXPREGS[0]&4)<<6));
|
||||||
|
else if(A<0x1800)
|
||||||
|
setchr1(A,V|((EXPREGS[0]&1)<<8));
|
||||||
|
else
|
||||||
|
setchr1(A,V|((EXPREGS[0]&2)<<7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(MSHWrite)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=V;
|
||||||
|
FixMMC3CHR(MMC3_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(MSHRead)
|
||||||
|
{
|
||||||
|
return(tekker);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MSHReset(void)
|
||||||
|
{
|
||||||
|
MMC3RegReset();
|
||||||
|
tekker^=0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MSHPower(void)
|
||||||
|
{
|
||||||
|
tekker=0x00;
|
||||||
|
GenMMC3Power();
|
||||||
|
SetWriteHandler(0x4100,0x4100,MSHWrite);
|
||||||
|
SetReadHandler(0x4100,0x4100,MSHRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MSHClose(void)
|
||||||
|
{
|
||||||
|
if(CHRRAM)
|
||||||
|
FCEU_gfree(CHRRAM);
|
||||||
|
CHRRAM=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNLSHeroes_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC3_Init(info, 256, 512, 0, 0);
|
||||||
|
cwrap=MSHCW;
|
||||||
|
info->Power=MSHPower;
|
||||||
|
info->Reset=MSHReset;
|
||||||
|
info->Close=MSHClose;
|
||||||
|
CHRRAM = (uint8*)FCEU_gmalloc(8192);
|
||||||
|
SetupCartCHRMapping(0x10, CHRRAM, 8192, 1);
|
||||||
|
AddExState(EXPREGS, 4, 0, "EXPR");
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 chrcmd[8], prg0, prg1, brk, mirr;
|
||||||
|
static uint8 reg[8], cmd;
|
||||||
|
static uint8 IRQCount,IRQLatch,IRQa;
|
||||||
|
static uint8 IRQReload;
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{reg, 8, "MMCREG"},
|
||||||
|
{&cmd, 1, "MMCCMD"},
|
||||||
|
{chrcmd, 8, "CHRCMD"},
|
||||||
|
{&prg0, 1, "PRG0"},
|
||||||
|
{&prg1, 1, "PRG1"},
|
||||||
|
{&brk, 1, "BRK"},
|
||||||
|
{&mirr, 1, "MIRR"},
|
||||||
|
{&IRQReload, 1, "IRQR"},
|
||||||
|
{&IRQCount, 1, "IRQC"},
|
||||||
|
{&IRQLatch, 1, "IRQL"},
|
||||||
|
{&IRQa, 1, "IRQA"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
// if(brk&2)
|
||||||
|
// {
|
||||||
|
// setprg16(0x8000,~0);
|
||||||
|
// setprg16(0xC000,~0);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
{
|
||||||
|
setprg8(0x8000,prg0);
|
||||||
|
setprg8(0xA000,prg1);
|
||||||
|
}
|
||||||
|
int i;
|
||||||
|
for(i=0; i<8; i++)
|
||||||
|
setchr1(i<<10,chrcmd[i]);
|
||||||
|
setmirror(mirr^1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Sync2(void)
|
||||||
|
{
|
||||||
|
setprg8(0x8000,reg[6]&0x3F);
|
||||||
|
setprg8(0xA000,reg[7]&0x3F);
|
||||||
|
setchr2(0x0000,reg[0]>>1);
|
||||||
|
setchr2(0x8000,reg[1]>>1);
|
||||||
|
setchr1(0x1000,reg[2]);
|
||||||
|
setchr1(0x1400,reg[3]);
|
||||||
|
setchr1(0x1800,reg[4]);
|
||||||
|
setchr1(0x1C00,reg[5]);
|
||||||
|
setmirror(mirr^1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(UNLSL1632CMDWrite)
|
||||||
|
{
|
||||||
|
FCEU_printf("bs %04x %02x\n",A,V);
|
||||||
|
// if((A&0xA131)==0xA131) brk=V;
|
||||||
|
if((A&0xA131)==0xA131) brk=V;
|
||||||
|
if(brk==2)
|
||||||
|
{
|
||||||
|
switch(A&0xE001)
|
||||||
|
{
|
||||||
|
case 0x8000: cmd=V&7; break;
|
||||||
|
case 0x8001: reg[cmd]=V; Sync(); break;
|
||||||
|
case 0xA000: mirr=V&1; break;
|
||||||
|
case 0xC000: IRQLatch=V; break;
|
||||||
|
case 0xC001: IRQReload=1; break;
|
||||||
|
case 0xE000: X6502_IRQEnd(FCEU_IQEXT); IRQa=0; break;
|
||||||
|
case 0xE001: IRQa=1; break;
|
||||||
|
}
|
||||||
|
Sync2();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(A&0xF003)
|
||||||
|
{
|
||||||
|
case 0x8000: prg0=V; break;
|
||||||
|
case 0xA000: prg1=V; break;
|
||||||
|
case 0x9000: mirr=V&1; break;
|
||||||
|
case 0xB000: chrcmd[0]=(chrcmd[0]&0xF0)|(V&0x0F); break;
|
||||||
|
case 0xB001: chrcmd[0]=(chrcmd[0]&0x0F)|(V<<4); break;
|
||||||
|
case 0xB002: chrcmd[1]=(chrcmd[1]&0xF0)|(V&0x0F); break;
|
||||||
|
case 0xB003: chrcmd[1]=(chrcmd[1]&0x0F)|(V<<4); break;
|
||||||
|
case 0xC000: chrcmd[2]=(chrcmd[2]&0xF0)|(V&0x0F); break;
|
||||||
|
case 0xC001: chrcmd[2]=(chrcmd[2]&0x0F)|(V<<4); break;
|
||||||
|
case 0xC002: chrcmd[3]=(chrcmd[3]&0xF0)|(V&0x0F); break;
|
||||||
|
case 0xC003: chrcmd[3]=(chrcmd[3]&0x0F)|(V<<4); break;
|
||||||
|
case 0xD000: chrcmd[4]=(chrcmd[4]&0xF0)|(V&0x0F); break;
|
||||||
|
case 0xD001: chrcmd[4]=(chrcmd[4]&0x0F)|(V<<4); break;
|
||||||
|
case 0xD002: chrcmd[5]=(chrcmd[5]&0xF0)|(V&0x0F); break;
|
||||||
|
case 0xD003: chrcmd[5]=(chrcmd[5]&0x0F)|(V<<4); break;
|
||||||
|
case 0xE000: chrcmd[6]=(chrcmd[6]&0xF0)|(V&0x0F); break;
|
||||||
|
case 0xE001: chrcmd[6]=(chrcmd[6]&0x0F)|(V<<4); break;
|
||||||
|
case 0xE002: chrcmd[7]=(chrcmd[7]&0xF0)|(V&0x0F); break;
|
||||||
|
case 0xE003: chrcmd[7]=(chrcmd[7]&0x0F)|(V<<4); break;
|
||||||
|
}
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNLSL1632IRQHook(void)
|
||||||
|
{
|
||||||
|
int count = IRQCount;
|
||||||
|
if((scanline==128)&&IRQa)X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
if(!count || IRQReload)
|
||||||
|
{
|
||||||
|
IRQCount = IRQLatch;
|
||||||
|
IRQReload = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
IRQCount--;
|
||||||
|
if(!IRQCount)
|
||||||
|
{
|
||||||
|
if(IRQa)
|
||||||
|
{
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNLSL1632Power(void)
|
||||||
|
{
|
||||||
|
setprg16(0xC000,~0);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,UNLSL1632CMDWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNLSL1632_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=UNLSL1632Power;
|
||||||
|
GameHBIRQHook2=UNLSL1632IRQHook;
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
#include "mmc3.h"
|
||||||
|
|
||||||
|
static uint8 m_perm[8] = {0, 1, 0, 3, 0, 5, 6, 7};
|
||||||
|
|
||||||
|
static void UNLSonicPW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&0x80)
|
||||||
|
{
|
||||||
|
uint8 bank=EXPREGS[0]&0x1F;
|
||||||
|
if(EXPREGS[0]&0x20)
|
||||||
|
setprg32(0x8000,bank>>2);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setprg16(0x8000,bank);
|
||||||
|
setprg16(0xC000,bank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setprg8(A,V&0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(UNLSonicWrite8000)
|
||||||
|
{
|
||||||
|
if(V&0x80)
|
||||||
|
MMC3_CMDWrite(A,V);
|
||||||
|
else
|
||||||
|
MMC3_CMDWrite(A,m_perm[V&7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(UNLSonicWriteLo)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=V;
|
||||||
|
FixMMC3PRG(MMC3_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UNLSonicPower(void)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=0;
|
||||||
|
GenMMC3Power();
|
||||||
|
SetWriteHandler(0x5000,0x5FFF,UNLSonicWriteLo);
|
||||||
|
// SetWriteHandler(0x8000,0x8000,UNLSonicWrite8000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNLSonic_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC3_Init(info, 256, 256, 0, 0);
|
||||||
|
pwrap=UNLSonicPW;
|
||||||
|
info->Power=UNLSonicPower;
|
||||||
|
AddExState(EXPREGS, 3, 0, "EXPR");
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 mode;
|
||||||
|
static uint8 DRegs[4];
|
||||||
|
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{DRegs, 4, "DREG"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
int base, bank;
|
||||||
|
base = ((DRegs[0]^DRegs[1])&0x10)<<1;
|
||||||
|
bank = (DRegs[2]^DRegs[3])&0x1f;
|
||||||
|
|
||||||
|
if(DRegs[1]&0x08)
|
||||||
|
{
|
||||||
|
bank &= 0xfe;
|
||||||
|
if(mode==0)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,base+bank+1);
|
||||||
|
setprg16(0xC000,base+bank+0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setprg16(0x8000,base+bank+0);
|
||||||
|
setprg16(0xC000,base+bank+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(DRegs[1]&0x04)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,0x1f);
|
||||||
|
setprg16(0xC000,base+bank);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setprg16(0x8000,base+bank);
|
||||||
|
if(mode==0)
|
||||||
|
setprg16(0xC000,0x20);
|
||||||
|
else
|
||||||
|
setprg16(0xC000,0x07);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(Mapper167_write)
|
||||||
|
{
|
||||||
|
DRegs[(A>>13)&0x03]=V;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StateRestore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper166_init(void)
|
||||||
|
{
|
||||||
|
mode=1;
|
||||||
|
DRegs[0]=DRegs[1]=DRegs[2]=DRegs[3]=0;
|
||||||
|
Sync();
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,Mapper167_write);
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper167_init(void)
|
||||||
|
{
|
||||||
|
mode=0;
|
||||||
|
DRegs[0]=DRegs[1]=DRegs[2]=DRegs[3]=0;
|
||||||
|
Sync();
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,Mapper167_write);
|
||||||
|
GameStateRestore=StateRestore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
#include "mmc3.h"
|
||||||
|
|
||||||
|
static uint8 *CHRRAM = NULL;
|
||||||
|
static int masko8[8]={63,31,15,1,3,0,0,0};
|
||||||
|
|
||||||
|
static void Super24PW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
uint32 NV=V&masko8[EXPREGS[0]&7];
|
||||||
|
NV|=(EXPREGS[1]<<1);
|
||||||
|
setprg8r((NV>>6)&0xF,A,NV);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Super24CW(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
if(EXPREGS[0]&0x20)
|
||||||
|
setchr1r(0x10,A,V);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32 NV=V|(EXPREGS[2]<<3);
|
||||||
|
setchr1r((NV>>9)&0xF,A,NV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(Super24Write)
|
||||||
|
{
|
||||||
|
switch(A)
|
||||||
|
{
|
||||||
|
case 0x5FF0: EXPREGS[0]=V;
|
||||||
|
FixMMC3PRG(MMC3_cmd);
|
||||||
|
FixMMC3CHR(MMC3_cmd);
|
||||||
|
break;
|
||||||
|
case 0x5FF1: EXPREGS[1]=V;
|
||||||
|
FixMMC3PRG(MMC3_cmd);
|
||||||
|
break;
|
||||||
|
case 0x5FF2: EXPREGS[2]=V;
|
||||||
|
FixMMC3CHR(MMC3_cmd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Super24Power(void)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=0x24;
|
||||||
|
EXPREGS[1]=159;
|
||||||
|
EXPREGS[2]=0;
|
||||||
|
GenMMC3Power();
|
||||||
|
SetWriteHandler(0x5000,0x7FFF,Super24Write);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Super24Reset(void)
|
||||||
|
{
|
||||||
|
EXPREGS[0]=0x24;
|
||||||
|
EXPREGS[1]=159;
|
||||||
|
EXPREGS[2]=0;
|
||||||
|
MMC3RegReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Super24Close(void)
|
||||||
|
{
|
||||||
|
if(CHRRAM)
|
||||||
|
FCEU_gfree(CHRRAM);
|
||||||
|
CHRRAM = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Super24_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
GenMMC3_Init(info, 128, 256, 0, 0);
|
||||||
|
info->Power=Super24Power;
|
||||||
|
info->Reset=Super24Reset;
|
||||||
|
info->Close=Super24Close;
|
||||||
|
cwrap=Super24CW;
|
||||||
|
pwrap=Super24PW;
|
||||||
|
CHRRAM=(uint8*)FCEU_gmalloc(8192);
|
||||||
|
SetupCartCHRMapping(0x10, CHRRAM, 8192, 1);
|
||||||
|
AddExState(CHRRAM, 8192, 0, "CHRR");
|
||||||
|
AddExState(EXPREGS, 3, 0, "BIG2");
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 cmd0, cmd1;
|
||||||
|
|
||||||
|
static void DoSuper(void)
|
||||||
|
{
|
||||||
|
setprg8r((cmd0&0xC)>>2,0x6000,((cmd0&0x3)<<4)|0xF);
|
||||||
|
if(cmd0&0x10)
|
||||||
|
{
|
||||||
|
setprg16r((cmd0&0xC)>>2,0x8000,((cmd0&0x3)<<3)|(cmd1&7));
|
||||||
|
setprg16r((cmd0&0xC)>>2,0xc000,((cmd0&0x3)<<3)|7);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setprg32r(4,0x8000,0);
|
||||||
|
setmirror(((cmd0&0x20)>>5)^1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(SuperWrite)
|
||||||
|
{
|
||||||
|
if(!(cmd0&0x10))
|
||||||
|
{
|
||||||
|
cmd0=V;
|
||||||
|
DoSuper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(SuperHi)
|
||||||
|
{
|
||||||
|
cmd1=V;
|
||||||
|
DoSuper();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SuperReset(void)
|
||||||
|
{
|
||||||
|
SetWriteHandler(0x6000,0x7FFF,SuperWrite);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,SuperHi);
|
||||||
|
SetReadHandler(0x6000,0xFFFF,CartBR);
|
||||||
|
cmd0=cmd1=0;
|
||||||
|
setprg32r(4,0x8000,0);
|
||||||
|
setchr8(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SuperRestore(int version)
|
||||||
|
{
|
||||||
|
DoSuper();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Supervision16_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
AddExState(&cmd0, 1, 0,"L1");
|
||||||
|
AddExState(&cmd1, 1, 0,"L2");
|
||||||
|
info->Power=SuperReset;
|
||||||
|
GameStateRestore=SuperRestore;
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2005 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint16 addrreg;
|
||||||
|
static uint8 datareg;
|
||||||
|
static uint8 busy;
|
||||||
|
static SFORMAT StateRegs[]=
|
||||||
|
{
|
||||||
|
{&addrreg, 2, "ADDRREG"},
|
||||||
|
{&datareg, 1, "DATAREG"},
|
||||||
|
{&busy, 1, "BUSY"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sync(void)
|
||||||
|
{
|
||||||
|
setprg16(0x8000,(datareg&7)|((addrreg&0x60)>>2)|((addrreg&0x100)>>3));
|
||||||
|
setprg16(0xC000,7|((addrreg&0x60)>>2)|((addrreg&0x100)>>3));
|
||||||
|
setmirror(((addrreg&2)>>1)^1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(BMCT262Write)
|
||||||
|
{
|
||||||
|
if(busy||(A==0x8000))
|
||||||
|
datareg=V;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addrreg=A;
|
||||||
|
busy=1;
|
||||||
|
}
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMCT262Power(void)
|
||||||
|
{
|
||||||
|
setchr8(0);
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,BMCT262Write);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,CartBR);
|
||||||
|
busy=0;
|
||||||
|
addrreg=0;
|
||||||
|
datareg=0;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMCT262Reset(void)
|
||||||
|
{
|
||||||
|
busy=0;
|
||||||
|
addrreg=0;
|
||||||
|
datareg=0;
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMCT262Restore(int version)
|
||||||
|
{
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BMCT262_Init(CartInfo *info)
|
||||||
|
{
|
||||||
|
info->Power=BMCT262Power;
|
||||||
|
info->Reset=BMCT262Reset;
|
||||||
|
GameStateRestore=BMCT262Restore;
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
|
@ -0,0 +1,198 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mapinc.h"
|
||||||
|
|
||||||
|
static uint8 cmd,mir,rmode,IRQmode;
|
||||||
|
static uint8 DRegs[11];
|
||||||
|
static uint8 IRQCount,IRQa,IRQLatch;
|
||||||
|
|
||||||
|
static SFORMAT Rambo_StateRegs[]={
|
||||||
|
{&cmd, 1, "CMD"},
|
||||||
|
{&mir, 1, "MIR"},
|
||||||
|
{&rmode, 1, "RMOD"},
|
||||||
|
{&IRQmode, 1, "IRQM"},
|
||||||
|
{&IRQCount, 1, "IRQC"},
|
||||||
|
{&IRQa, 1, "IRQA"},
|
||||||
|
{&IRQLatch, 1, "IRQL"},
|
||||||
|
{DRegs, 11, "DREG"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void FP_FASTAPASS(2) (*setchr1wrap)(unsigned int A, unsigned int V);
|
||||||
|
static int nomirror;
|
||||||
|
|
||||||
|
static void FP_FASTAPASS(1) RAMBO1_IRQHook(int a)
|
||||||
|
{
|
||||||
|
static int smallcount;
|
||||||
|
if(!IRQmode) return;
|
||||||
|
|
||||||
|
smallcount+=a;
|
||||||
|
while(smallcount>=4)
|
||||||
|
{
|
||||||
|
smallcount-=4;
|
||||||
|
IRQCount--;
|
||||||
|
if(IRQCount==0xFF)
|
||||||
|
if(IRQa) X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RAMBO1_hb(void)
|
||||||
|
{
|
||||||
|
if(IRQmode) return;
|
||||||
|
if(scanline==240) return; /* hmm. Maybe that should be an mmc3-only call in fce.c. */
|
||||||
|
rmode=0;
|
||||||
|
IRQCount--;
|
||||||
|
if(IRQCount==0xFF)
|
||||||
|
{
|
||||||
|
if(IRQa)
|
||||||
|
{
|
||||||
|
rmode = 1;
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Synco(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
if(cmd&0x20)
|
||||||
|
{
|
||||||
|
setchr1wrap(0x0000,DRegs[0]);
|
||||||
|
setchr1wrap(0x0800,DRegs[1]);
|
||||||
|
setchr1wrap(0x0400,DRegs[8]);
|
||||||
|
setchr1wrap(0x0c00,DRegs[9]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setchr1wrap(0x0000,(DRegs[0]&0xFE));
|
||||||
|
setchr1wrap(0x0400,(DRegs[0]&0xFE)|1);
|
||||||
|
setchr1wrap(0x0800,(DRegs[1]&0xFE));
|
||||||
|
setchr1wrap(0x0C00,(DRegs[1]&0xFE)|1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
setchr1wrap(0x1000+x*0x400,DRegs[2+x]);
|
||||||
|
|
||||||
|
setprg8(0x8000,DRegs[6]);
|
||||||
|
setprg8(0xA000,DRegs[7]);
|
||||||
|
|
||||||
|
setprg8(0xC000,DRegs[10]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DECLFW(RAMBO1_write)
|
||||||
|
{
|
||||||
|
switch(A&0xF001)
|
||||||
|
{
|
||||||
|
case 0xa000: mir=V&1;
|
||||||
|
if(!nomirror)
|
||||||
|
setmirror(mir^1);
|
||||||
|
break;
|
||||||
|
case 0x8000: cmd = V;
|
||||||
|
break;
|
||||||
|
case 0x8001: if((cmd&0xF)<10)
|
||||||
|
DRegs[cmd&0xF]=V;
|
||||||
|
else if((cmd&0xF)==0xF)
|
||||||
|
DRegs[10]=V;
|
||||||
|
Synco();
|
||||||
|
break;
|
||||||
|
case 0xc000: IRQLatch=V;
|
||||||
|
if(rmode==1)
|
||||||
|
IRQCount=IRQLatch;
|
||||||
|
break;
|
||||||
|
case 0xc001: rmode=1;
|
||||||
|
IRQCount=IRQLatch;
|
||||||
|
IRQmode=V&1;
|
||||||
|
break;
|
||||||
|
case 0xE000: IRQa=0;
|
||||||
|
X6502_IRQEnd(FCEU_IQEXT);
|
||||||
|
if(rmode==1)
|
||||||
|
IRQCount=IRQLatch;
|
||||||
|
break;
|
||||||
|
case 0xE001: IRQa=1;
|
||||||
|
if(rmode==1)
|
||||||
|
IRQCount=IRQLatch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RAMBO1_Restore(int version)
|
||||||
|
{
|
||||||
|
Synco();
|
||||||
|
if(!nomirror)
|
||||||
|
setmirror(mir^1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RAMBO1_init(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=0;x<11;x++)
|
||||||
|
DRegs[x]=~0;
|
||||||
|
cmd=mir=0;
|
||||||
|
if(!nomirror)
|
||||||
|
setmirror(1);
|
||||||
|
Synco();
|
||||||
|
GameHBIRQHook=RAMBO1_hb;
|
||||||
|
MapIRQHook=RAMBO1_IRQHook;
|
||||||
|
GameStateRestore=RAMBO1_Restore;
|
||||||
|
SetWriteHandler(0x8000,0xffff,RAMBO1_write);
|
||||||
|
AddExState(Rambo_StateRegs, ~0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FP_FASTAPASS(2) CHRWrap(unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
setchr1(A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper64_init(void)
|
||||||
|
{
|
||||||
|
setchr1wrap=CHRWrap;
|
||||||
|
nomirror=0;
|
||||||
|
RAMBO1_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int MirCache[8];
|
||||||
|
static unsigned int PPUCHRBus;
|
||||||
|
|
||||||
|
static void FP_FASTAPASS(2) MirWrap(unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
MirCache[A>>10]=(V>>7)&1;
|
||||||
|
if(PPUCHRBus==(A>>10))
|
||||||
|
setmirror(MI_0+((V>>7)&1));
|
||||||
|
setchr1(A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FP_FASTAPASS(1) MirrorFear(uint32 A)
|
||||||
|
{
|
||||||
|
A&=0x1FFF;
|
||||||
|
A>>=10;
|
||||||
|
PPUCHRBus=A;
|
||||||
|
setmirror(MI_0+MirCache[A]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper158_init(void)
|
||||||
|
{
|
||||||
|
setchr1wrap=MirWrap;
|
||||||
|
PPU_hook=MirrorFear;
|
||||||
|
nomirror=1;
|
||||||
|
RAMBO1_init();
|
||||||
|
}
|
|
@ -0,0 +1,685 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "fceu.h"
|
||||||
|
#include "ppu.h"
|
||||||
|
|
||||||
|
#include "cart.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "x6502.h"
|
||||||
|
|
||||||
|
#include "general.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file contains all code for coordinating the mapping in of the
|
||||||
|
address space external to the NES.
|
||||||
|
It's also (ab)used by the NSF code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint8 *Page[32],*VPage[8];
|
||||||
|
uint8 **VPageR=VPage;
|
||||||
|
uint8 *VPageG[8];
|
||||||
|
uint8 *MMC5SPRVPage[8];
|
||||||
|
uint8 *MMC5BGVPage[8];
|
||||||
|
|
||||||
|
static uint8 PRGIsRAM[32]; /* This page is/is not PRG RAM. */
|
||||||
|
|
||||||
|
/* 16 are (sort of) reserved for UNIF/iNES and 16 to map other stuff. */
|
||||||
|
static int CHRram[32];
|
||||||
|
static int PRGram[32];
|
||||||
|
|
||||||
|
uint8 *PRGptr[32];
|
||||||
|
uint8 *CHRptr[32];
|
||||||
|
|
||||||
|
uint32 PRGsize[32];
|
||||||
|
uint32 CHRsize[32];
|
||||||
|
|
||||||
|
uint32 PRGmask2[32];
|
||||||
|
uint32 PRGmask4[32];
|
||||||
|
uint32 PRGmask8[32];
|
||||||
|
uint32 PRGmask16[32];
|
||||||
|
uint32 PRGmask32[32];
|
||||||
|
|
||||||
|
uint32 CHRmask1[32];
|
||||||
|
uint32 CHRmask2[32];
|
||||||
|
uint32 CHRmask4[32];
|
||||||
|
uint32 CHRmask8[32];
|
||||||
|
|
||||||
|
int geniestage=0;
|
||||||
|
|
||||||
|
int modcon;
|
||||||
|
|
||||||
|
uint8 genieval[3];
|
||||||
|
uint8 geniech[3];
|
||||||
|
|
||||||
|
uint32 genieaddr[3];
|
||||||
|
|
||||||
|
static INLINE void setpageptr(int s, uint32 A, uint8 *p, int ram)
|
||||||
|
{
|
||||||
|
uint32 AB=A>>11;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
if(p)
|
||||||
|
for(x=(s>>1)-1;x>=0;x--)
|
||||||
|
{
|
||||||
|
PRGIsRAM[AB+x]=ram;
|
||||||
|
Page[AB+x]=p-A;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for(x=(s>>1)-1;x>=0;x--)
|
||||||
|
{
|
||||||
|
PRGIsRAM[AB+x]=0;
|
||||||
|
Page[AB+x]=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 nothing[8192];
|
||||||
|
void ResetCartMapping(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<32;x++)
|
||||||
|
{
|
||||||
|
Page[x]=nothing-x*2048;
|
||||||
|
PRGptr[x]=CHRptr[x]=0;
|
||||||
|
PRGsize[x]=CHRsize[x]=0;
|
||||||
|
}
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
{
|
||||||
|
MMC5SPRVPage[x]=MMC5BGVPage[x]=VPageR[x]=nothing-0x400*x;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupCartPRGMapping(int chip, uint8 *p, uint32 size, int ram)
|
||||||
|
{
|
||||||
|
PRGptr[chip]=p;
|
||||||
|
PRGsize[chip]=size;
|
||||||
|
|
||||||
|
PRGmask2[chip]=(size>>11)-1;
|
||||||
|
PRGmask4[chip]=(size>>12)-1;
|
||||||
|
PRGmask8[chip]=(size>>13)-1;
|
||||||
|
PRGmask16[chip]=(size>>14)-1;
|
||||||
|
PRGmask32[chip]=(size>>15)-1;
|
||||||
|
|
||||||
|
PRGram[chip]=ram?1:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupCartCHRMapping(int chip, uint8 *p, uint32 size, int ram)
|
||||||
|
{
|
||||||
|
CHRptr[chip]=p;
|
||||||
|
CHRsize[chip]=size;
|
||||||
|
|
||||||
|
CHRmask1[chip]=(size>>10)-1;
|
||||||
|
CHRmask2[chip]=(size>>11)-1;
|
||||||
|
CHRmask4[chip]=(size>>12)-1;
|
||||||
|
CHRmask8[chip]=(size>>13)-1;
|
||||||
|
|
||||||
|
CHRram[chip]=ram;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLFR(CartBR)
|
||||||
|
{
|
||||||
|
return Page[A>>11][A];
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLFW(CartBW)
|
||||||
|
{
|
||||||
|
//printf("Ok: %04x:%02x, %d\n",A,V,PRGIsRAM[A>>11]);
|
||||||
|
if(PRGIsRAM[A>>11] && Page[A>>11])
|
||||||
|
Page[A>>11][A]=V;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLFR(CartBROB)
|
||||||
|
{
|
||||||
|
if(!Page[A>>11]) return(X.DB);
|
||||||
|
return Page[A>>11][A];
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setprg2r(int r, unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
V&=PRGmask2[r];
|
||||||
|
setpageptr(2,A,PRGptr[r]?(&PRGptr[r][V<<11]):0,PRGram[r]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setprg2(uint32 A, uint32 V)
|
||||||
|
{
|
||||||
|
setprg2r(0,A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setprg4r(int r, unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
V&=PRGmask4[r];
|
||||||
|
setpageptr(4,A,PRGptr[r]?(&PRGptr[r][V<<12]):0,PRGram[r]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setprg4(uint32 A, uint32 V)
|
||||||
|
{
|
||||||
|
setprg4r(0,A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setprg8r(int r, unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
if(PRGsize[r]>=8192)
|
||||||
|
{
|
||||||
|
V&=PRGmask8[r];
|
||||||
|
setpageptr(8,A,PRGptr[r]?(&PRGptr[r][V<<13]):0,PRGram[r]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32 VA=V<<2;
|
||||||
|
int x;
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
setpageptr(2,A+(x<<11),PRGptr[r]?(&PRGptr[r][((VA+x)&PRGmask2[r])<<11]):0,PRGram[r]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setprg8(uint32 A, uint32 V)
|
||||||
|
{
|
||||||
|
setprg8r(0,A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setprg16r(int r, unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
if(PRGsize[r]>=16384)
|
||||||
|
{
|
||||||
|
V&=PRGmask16[r];
|
||||||
|
setpageptr(16,A,PRGptr[r]?(&PRGptr[r][V<<14]):0,PRGram[r]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32 VA=V<<3;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
setpageptr(2,A+(x<<11),PRGptr[r]?(&PRGptr[r][((VA+x)&PRGmask2[r])<<11]):0,PRGram[r]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setprg16(uint32 A, uint32 V)
|
||||||
|
{
|
||||||
|
setprg16r(0,A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setprg32r(int r,unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
if(PRGsize[r]>=32768)
|
||||||
|
{
|
||||||
|
V&=PRGmask32[r];
|
||||||
|
setpageptr(32,A,PRGptr[r]?(&PRGptr[r][V<<15]):0,PRGram[r]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32 VA=V<<4;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<16;x++)
|
||||||
|
setpageptr(2,A+(x<<11),PRGptr[r]?(&PRGptr[r][((VA+x)&PRGmask2[r])<<11]):0,PRGram[r]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setprg32(uint32 A, uint32 V)
|
||||||
|
{
|
||||||
|
setprg32r(0,A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setchr1r(int r, unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
if(!CHRptr[r]) return;
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
V&=CHRmask1[r];
|
||||||
|
if(CHRram[r])
|
||||||
|
PPUCHRRAM|=(1<<(A>>10));
|
||||||
|
else
|
||||||
|
PPUCHRRAM&=~(1<<(A>>10));
|
||||||
|
VPageR[(A)>>10]=&CHRptr[r][(V)<<10]-(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setchr2r(int r, unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
if(!CHRptr[r]) return;
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
V&=CHRmask2[r];
|
||||||
|
VPageR[(A)>>10]=VPageR[((A)>>10)+1]=&CHRptr[r][(V)<<11]-(A);
|
||||||
|
if(CHRram[r])
|
||||||
|
PPUCHRRAM|=(3<<(A>>10));
|
||||||
|
else
|
||||||
|
PPUCHRRAM&=~(3<<(A>>10));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setchr4r(int r, unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
if(!CHRptr[r]) return;
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
V&=CHRmask4[r];
|
||||||
|
VPageR[(A)>>10]=VPageR[((A)>>10)+1]=
|
||||||
|
VPageR[((A)>>10)+2]=VPageR[((A)>>10)+3]=&CHRptr[r][(V)<<12]-(A);
|
||||||
|
if(CHRram[r])
|
||||||
|
PPUCHRRAM|=(15<<(A>>10));
|
||||||
|
else
|
||||||
|
PPUCHRRAM&=~(15<<(A>>10));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setchr8r(int r, unsigned int V)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
if(!CHRptr[r]) return;
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
V&=CHRmask8[r];
|
||||||
|
for(x=7;x>=0;x--)
|
||||||
|
VPageR[x]=&CHRptr[r][V<<13];
|
||||||
|
if(CHRram[r])
|
||||||
|
PPUCHRRAM|=(255);
|
||||||
|
else
|
||||||
|
PPUCHRRAM&=~(255);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setchr1(unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
setchr1r(0,A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setchr2(unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
setchr2r(0,A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setchr4(unsigned int A, unsigned int V)
|
||||||
|
{
|
||||||
|
setchr4r(0,A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(1) setchr8(unsigned int V)
|
||||||
|
{
|
||||||
|
setchr8r(0,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(1) setvram8(uint8 *p)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=7;x>=0;x--)
|
||||||
|
VPageR[x]=p;
|
||||||
|
PPUCHRRAM|=255;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setvram4(uint32 A, uint8 *p)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=3;x>=0;x--)
|
||||||
|
VPageR[(A>>10)+x]=p-A;
|
||||||
|
PPUCHRRAM|=(15<<(A>>10));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setvramb1(uint8 *p, uint32 A, uint32 b)
|
||||||
|
{
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
VPageR[A>>10]=p-A+(b<<10);
|
||||||
|
PPUCHRRAM|=(1<<(A>>10));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setvramb2(uint8 *p, uint32 A, uint32 b)
|
||||||
|
{
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
VPageR[(A>>10)]=VPageR[(A>>10)+1]=p-A+(b<<11);
|
||||||
|
PPUCHRRAM|=(3<<(A>>10));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(3) setvramb4(uint8 *p, uint32 A, uint32 b)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
for(x=3;x>=0;x--)
|
||||||
|
VPageR[(A>>10)+x]=p-A+(b<<12);
|
||||||
|
PPUCHRRAM|=(15<<(A>>10));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(2) setvramb8(uint8 *p, uint32 b)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
for(x=7;x>=0;x--)
|
||||||
|
VPageR[x]=p+(b<<13);
|
||||||
|
PPUCHRRAM|=255;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function can be called without calling SetupCartMirroring(). */
|
||||||
|
|
||||||
|
void FASTAPASS(3) setntamem(uint8 *p, int ram, uint32 b)
|
||||||
|
{
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
vnapage[b]=p;
|
||||||
|
PPUNTARAM&=~(1<<b);
|
||||||
|
if(ram)
|
||||||
|
PPUNTARAM|=1<<b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mirrorhard=0;
|
||||||
|
void setmirrorw(int a, int b, int c, int d)
|
||||||
|
{
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
vnapage[0]=NTARAM+a*0x400;
|
||||||
|
vnapage[1]=NTARAM+b*0x400;
|
||||||
|
vnapage[2]=NTARAM+c*0x400;
|
||||||
|
vnapage[3]=NTARAM+d*0x400;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FASTAPASS(1) setmirror(int t)
|
||||||
|
{
|
||||||
|
FCEUPPU_LineUpdate();
|
||||||
|
if(!mirrorhard)
|
||||||
|
{
|
||||||
|
switch(t)
|
||||||
|
{
|
||||||
|
case MI_H:
|
||||||
|
vnapage[0]=vnapage[1]=NTARAM;vnapage[2]=vnapage[3]=NTARAM+0x400;
|
||||||
|
break;
|
||||||
|
case MI_V:
|
||||||
|
vnapage[0]=vnapage[2]=NTARAM;vnapage[1]=vnapage[3]=NTARAM+0x400;
|
||||||
|
break;
|
||||||
|
case MI_0:
|
||||||
|
vnapage[0]=vnapage[1]=vnapage[2]=vnapage[3]=NTARAM;
|
||||||
|
break;
|
||||||
|
case MI_1:
|
||||||
|
vnapage[0]=vnapage[1]=vnapage[2]=vnapage[3]=NTARAM+0x400;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PPUNTARAM=0xF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupCartMirroring(int m, int hard, uint8 *extra)
|
||||||
|
{
|
||||||
|
if(m<4)
|
||||||
|
{
|
||||||
|
mirrorhard = 0;
|
||||||
|
setmirror(m);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vnapage[0]=NTARAM;
|
||||||
|
vnapage[1]=NTARAM+0x400;
|
||||||
|
vnapage[2]=extra;
|
||||||
|
vnapage[3]=extra+0x400;
|
||||||
|
PPUNTARAM=0xF;
|
||||||
|
}
|
||||||
|
mirrorhard=hard;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 *GENIEROM=0;
|
||||||
|
|
||||||
|
void FixGenieMap(void);
|
||||||
|
|
||||||
|
/* Called when a game(file) is opened successfully. */
|
||||||
|
void OpenGenie(void)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
if(!GENIEROM)
|
||||||
|
{
|
||||||
|
char *fn;
|
||||||
|
|
||||||
|
if(!(GENIEROM=(uint8 *)FCEU_malloc(4096+1024))) return;
|
||||||
|
|
||||||
|
fn=FCEU_MakeFName(FCEUMKF_GGROM,0,0);
|
||||||
|
fp=FCEUD_UTF8fopen(fn,"rb");
|
||||||
|
if(!fp)
|
||||||
|
{
|
||||||
|
FCEU_PrintError("Error opening Game Genie ROM image!");
|
||||||
|
free(GENIEROM);
|
||||||
|
GENIEROM=0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(fread(GENIEROM,1,16,fp)!=16)
|
||||||
|
{
|
||||||
|
grerr:
|
||||||
|
FCEU_PrintError("Error reading from Game Genie ROM image!");
|
||||||
|
free(GENIEROM);
|
||||||
|
GENIEROM=0;
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(GENIEROM[0]==0x4E) /* iNES ROM image */
|
||||||
|
{
|
||||||
|
if(fread(GENIEROM,1,4096,fp)!=4096)
|
||||||
|
goto grerr;
|
||||||
|
if(fseek(fp,16384-4096,SEEK_CUR))
|
||||||
|
goto grerr;
|
||||||
|
if(fread(GENIEROM+4096,1,256,fp)!=256)
|
||||||
|
goto grerr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fread(GENIEROM+16,1,4352-16,fp)!=(4352-16))
|
||||||
|
goto grerr;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
/* Workaround for the FCE Ultra CHR page size only being 1KB */
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
memcpy(GENIEROM+4096+(x<<8),GENIEROM+4096,256);
|
||||||
|
}
|
||||||
|
|
||||||
|
geniestage=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when a game is closed. */
|
||||||
|
void CloseGenie(void)
|
||||||
|
{
|
||||||
|
/* No good reason to free() the Game Genie ROM image data. */
|
||||||
|
geniestage=0;
|
||||||
|
FlushGenieRW();
|
||||||
|
VPageR=VPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEU_KillGenie(void)
|
||||||
|
{
|
||||||
|
if(GENIEROM)
|
||||||
|
{
|
||||||
|
free(GENIEROM);
|
||||||
|
GENIEROM=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(GenieRead)
|
||||||
|
{
|
||||||
|
return GENIEROM[A&4095];
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFW(GenieWrite)
|
||||||
|
{
|
||||||
|
switch(A)
|
||||||
|
{
|
||||||
|
case 0x800c:
|
||||||
|
case 0x8008:
|
||||||
|
case 0x8004:genieval[((A-4)&0xF)>>2]=V;break;
|
||||||
|
|
||||||
|
case 0x800b:
|
||||||
|
case 0x8007:
|
||||||
|
case 0x8003:geniech[((A-3)&0xF)>>2]=V;break;
|
||||||
|
|
||||||
|
case 0x800a:
|
||||||
|
case 0x8006:
|
||||||
|
case 0x8002:genieaddr[((A-2)&0xF)>>2]&=0xFF00;genieaddr[((A-2)&0xF)>>2]|=V;break;
|
||||||
|
|
||||||
|
case 0x8009:
|
||||||
|
case 0x8005:
|
||||||
|
case 0x8001:genieaddr[((A-1)&0xF)>>2]&=0xFF;genieaddr[((A-1)&0xF)>>2]|=(V|0x80)<<8;break;
|
||||||
|
|
||||||
|
case 0x8000:if(!V)
|
||||||
|
FixGenieMap();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modcon=V^0xFF;
|
||||||
|
if(V==0x71)
|
||||||
|
modcon=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static readfunc GenieBackup[3];
|
||||||
|
|
||||||
|
static DECLFR(GenieFix1)
|
||||||
|
{
|
||||||
|
uint8 r=GenieBackup[0](A);
|
||||||
|
|
||||||
|
if((modcon>>1)&1) // No check
|
||||||
|
return genieval[0];
|
||||||
|
else if(r==geniech[0])
|
||||||
|
return genieval[0];
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(GenieFix2)
|
||||||
|
{
|
||||||
|
uint8 r=GenieBackup[1](A);
|
||||||
|
|
||||||
|
if((modcon>>2)&1) // No check
|
||||||
|
return genieval[1];
|
||||||
|
else if(r==geniech[1])
|
||||||
|
return genieval[1];
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLFR(GenieFix3)
|
||||||
|
{
|
||||||
|
uint8 r=GenieBackup[2](A);
|
||||||
|
|
||||||
|
if((modcon>>3)&1) // No check
|
||||||
|
return genieval[2];
|
||||||
|
else if(r==geniech[2])
|
||||||
|
return genieval[2];
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FixGenieMap(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
geniestage=2;
|
||||||
|
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
VPage[x]=VPageG[x];
|
||||||
|
|
||||||
|
VPageR=VPage;
|
||||||
|
FlushGenieRW();
|
||||||
|
//printf("Rightyo\n");
|
||||||
|
for(x=0;x<3;x++)
|
||||||
|
if((modcon>>(4+x))&1)
|
||||||
|
{
|
||||||
|
readfunc tmp[3]={GenieFix1,GenieFix2,GenieFix3};
|
||||||
|
GenieBackup[x]=GetReadHandler(genieaddr[x]);
|
||||||
|
SetReadHandler(genieaddr[x],genieaddr[x],tmp[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeniePower(void)
|
||||||
|
{
|
||||||
|
uint32 x;
|
||||||
|
|
||||||
|
if(!geniestage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
geniestage=1;
|
||||||
|
for(x=0;x<3;x++)
|
||||||
|
{
|
||||||
|
genieval[x]=0xFF;
|
||||||
|
geniech[x]=0xFF;
|
||||||
|
genieaddr[x]=0xFFFF;
|
||||||
|
}
|
||||||
|
modcon=0;
|
||||||
|
|
||||||
|
SetWriteHandler(0x8000,0xFFFF,GenieWrite);
|
||||||
|
SetReadHandler(0x8000,0xFFFF,GenieRead);
|
||||||
|
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
VPage[x]=GENIEROM+4096-0x400*x;
|
||||||
|
|
||||||
|
if(AllocGenieRW())
|
||||||
|
VPageR=VPageG;
|
||||||
|
else
|
||||||
|
geniestage=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FCEU_SaveGameSave(CartInfo *LocalHWInfo)
|
||||||
|
{
|
||||||
|
if(LocalHWInfo->battery && LocalHWInfo->SaveGame[0])
|
||||||
|
{
|
||||||
|
FILE *sp;
|
||||||
|
char *soot;
|
||||||
|
|
||||||
|
soot=FCEU_MakeFName(FCEUMKF_SAV,0,"sav");
|
||||||
|
if((sp=FCEUD_UTF8fopen(soot,"wb"))==NULL)
|
||||||
|
{
|
||||||
|
FCEU_PrintError("WRAM file \"%s\" cannot be written to.\n",soot);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
if(LocalHWInfo->SaveGame[x])
|
||||||
|
{
|
||||||
|
fwrite(LocalHWInfo->SaveGame[x],1,
|
||||||
|
LocalHWInfo->SaveGameLen[x],sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(soot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// hack, movie.c has to communicate with this function somehow
|
||||||
|
int disableBatteryLoading=0;
|
||||||
|
|
||||||
|
void FCEU_LoadGameSave(CartInfo *LocalHWInfo)
|
||||||
|
{
|
||||||
|
if(LocalHWInfo->battery && LocalHWInfo->SaveGame[0] && !disableBatteryLoading)
|
||||||
|
{
|
||||||
|
FILE *sp;
|
||||||
|
char *soot;
|
||||||
|
|
||||||
|
soot=FCEU_MakeFName(FCEUMKF_SAV,0,"sav");
|
||||||
|
sp=FCEUD_UTF8fopen(soot,"rb");
|
||||||
|
if(sp!=NULL)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
if(LocalHWInfo->SaveGame[x])
|
||||||
|
fread(LocalHWInfo->SaveGame[x],1,LocalHWInfo->SaveGameLen[x],sp);
|
||||||
|
}
|
||||||
|
free(soot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
typedef struct {
|
||||||
|
/* Set by mapper/board code: */
|
||||||
|
void (*Power)(void);
|
||||||
|
void (*Reset)(void);
|
||||||
|
void (*Close)(void);
|
||||||
|
uint8 *SaveGame[4]; /* Pointers to memory to save/load. */
|
||||||
|
uint32 SaveGameLen[4]; /* How much memory to save/load. */
|
||||||
|
|
||||||
|
/* Set by iNES/UNIF loading code. */
|
||||||
|
int mirror; /* As set in the header or chunk.
|
||||||
|
iNES/UNIF specific. Intended
|
||||||
|
to help support games like "Karnov"
|
||||||
|
that are not really MMC3 but are
|
||||||
|
set to mapper 4.
|
||||||
|
*/
|
||||||
|
int battery; /* Presence of an actual battery. */
|
||||||
|
uint8 MD5[16];
|
||||||
|
uint32 CRC32; /* Should be set by the iNES/UNIF loading
|
||||||
|
code, used by mapper/board code, maybe
|
||||||
|
other code in the future.
|
||||||
|
*/
|
||||||
|
} CartInfo;
|
||||||
|
|
||||||
|
void FCEU_SaveGameSave(CartInfo *LocalHWInfo);
|
||||||
|
void FCEU_LoadGameSave(CartInfo *LocalHWInfo);
|
||||||
|
|
||||||
|
extern uint8 *Page[32],*VPage[8],*MMC5SPRVPage[8],*MMC5BGVPage[8];
|
||||||
|
|
||||||
|
void ResetCartMapping(void);
|
||||||
|
void SetupCartPRGMapping(int chip, uint8 *p, uint32 size, int ram);
|
||||||
|
void SetupCartCHRMapping(int chip, uint8 *p, uint32 size, int ram);
|
||||||
|
void SetupCartMirroring(int m, int hard, uint8 *extra);
|
||||||
|
|
||||||
|
DECLFR(CartBROB);
|
||||||
|
DECLFR(CartBR);
|
||||||
|
DECLFW(CartBW);
|
||||||
|
|
||||||
|
extern uint8 *PRGptr[32];
|
||||||
|
extern uint8 *CHRptr[32];
|
||||||
|
|
||||||
|
extern uint32 PRGsize[32];
|
||||||
|
extern uint32 CHRsize[32];
|
||||||
|
|
||||||
|
extern uint32 PRGmask2[32];
|
||||||
|
extern uint32 PRGmask4[32];
|
||||||
|
extern uint32 PRGmask8[32];
|
||||||
|
extern uint32 PRGmask16[32];
|
||||||
|
extern uint32 PRGmask32[32];
|
||||||
|
|
||||||
|
extern uint32 CHRmask1[32];
|
||||||
|
extern uint32 CHRmask2[32];
|
||||||
|
extern uint32 CHRmask4[32];
|
||||||
|
extern uint32 CHRmask8[32];
|
||||||
|
|
||||||
|
void FASTAPASS(2) setprg2(uint32 A, uint32 V);
|
||||||
|
void FASTAPASS(2) setprg4(uint32 A, uint32 V);
|
||||||
|
void FASTAPASS(2) setprg8(uint32 A, uint32 V);
|
||||||
|
void FASTAPASS(2) setprg16(uint32 A, uint32 V);
|
||||||
|
void FASTAPASS(2) setprg32(uint32 A, uint32 V);
|
||||||
|
|
||||||
|
void FASTAPASS(3) setprg2r(int r, unsigned int A, unsigned int V);
|
||||||
|
void FASTAPASS(3) setprg4r(int r, unsigned int A, unsigned int V);
|
||||||
|
void FASTAPASS(3) setprg8r(int r, unsigned int A, unsigned int V);
|
||||||
|
void FASTAPASS(3) setprg16r(int r, unsigned int A, unsigned int V);
|
||||||
|
void FASTAPASS(3) setprg32r(int r, unsigned int A, unsigned int V);
|
||||||
|
|
||||||
|
void FASTAPASS(3) setchr1r(int r, unsigned int A, unsigned int V);
|
||||||
|
void FASTAPASS(3) setchr2r(int r, unsigned int A, unsigned int V);
|
||||||
|
void FASTAPASS(3) setchr4r(int r, unsigned int A, unsigned int V);
|
||||||
|
void FASTAPASS(2) setchr8r(int r, unsigned int V);
|
||||||
|
|
||||||
|
void FASTAPASS(2) setchr1(unsigned int A, unsigned int V);
|
||||||
|
void FASTAPASS(2) setchr2(unsigned int A, unsigned int V);
|
||||||
|
void FASTAPASS(2) setchr4(unsigned int A, unsigned int V);
|
||||||
|
void FASTAPASS(1) setchr8(unsigned int V);
|
||||||
|
|
||||||
|
void FASTAPASS(2) setvram4(uint32 A, uint8 *p);
|
||||||
|
void FASTAPASS(1) setvram8(uint8 *p);
|
||||||
|
|
||||||
|
void FASTAPASS(3) setvramb1(uint8 *p, uint32 A, uint32 b);
|
||||||
|
void FASTAPASS(3) setvramb2(uint8 *p, uint32 A, uint32 b);
|
||||||
|
void FASTAPASS(3) setvramb4(uint8 *p, uint32 A, uint32 b);
|
||||||
|
void FASTAPASS(2) setvramb8(uint8 *p, uint32 b);
|
||||||
|
|
||||||
|
void FASTAPASS(1) setmirror(int t);
|
||||||
|
void setmirrorw(int a, int b, int c, int d);
|
||||||
|
void FASTAPASS(3) setntamem(uint8 *p, int ram, uint32 b);
|
||||||
|
|
||||||
|
#define MI_H 0
|
||||||
|
#define MI_V 1
|
||||||
|
#define MI_0 2
|
||||||
|
#define MI_1 3
|
||||||
|
|
||||||
|
extern int geniestage;
|
||||||
|
|
||||||
|
void GeniePower(void);
|
||||||
|
|
||||||
|
void OpenGenie(void);
|
||||||
|
void CloseGenie(void);
|
||||||
|
void FCEU_KillGenie(void);
|
|
@ -0,0 +1,855 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "x6502.h"
|
||||||
|
#include "cheat.h"
|
||||||
|
#include "fceu.h"
|
||||||
|
#include "general.h"
|
||||||
|
#include "cart.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
static uint8 *CheatRPtrs[64];
|
||||||
|
|
||||||
|
void FCEU_CheatResetRAM(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<64;x++)
|
||||||
|
CheatRPtrs[x]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p)
|
||||||
|
{
|
||||||
|
uint32 AB=A>>10;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=s-1;x>=0;x--)
|
||||||
|
CheatRPtrs[AB+x]=p-A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct CHEATF {
|
||||||
|
struct CHEATF *next;
|
||||||
|
char *name;
|
||||||
|
uint16 addr;
|
||||||
|
uint8 val;
|
||||||
|
int compare; /* -1 for no compare. */
|
||||||
|
int type; /* 0 for replace, 1 for substitute(GG). */
|
||||||
|
int status;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16 addr;
|
||||||
|
uint8 val;
|
||||||
|
int compare;
|
||||||
|
readfunc PrevRead;
|
||||||
|
} CHEATF_SUBFAST;
|
||||||
|
|
||||||
|
|
||||||
|
static CHEATF_SUBFAST SubCheats[256];
|
||||||
|
static int numsubcheats=0;
|
||||||
|
struct CHEATF *cheats=0,*cheatsl=0;
|
||||||
|
|
||||||
|
|
||||||
|
#define CHEATC_NONE 0x8000
|
||||||
|
#define CHEATC_EXCLUDED 0x4000
|
||||||
|
#define CHEATC_NOSHOW 0xC000
|
||||||
|
|
||||||
|
static uint16 *CheatComp=0;
|
||||||
|
static int savecheats;
|
||||||
|
|
||||||
|
static DECLFR(SubCheatsRead)
|
||||||
|
{
|
||||||
|
CHEATF_SUBFAST *s=SubCheats;
|
||||||
|
int x=numsubcheats;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(s->addr==A)
|
||||||
|
{
|
||||||
|
if(s->compare>=0)
|
||||||
|
{
|
||||||
|
uint8 pv=s->PrevRead(A);
|
||||||
|
|
||||||
|
if(pv==s->compare)
|
||||||
|
return(s->val);
|
||||||
|
else return(pv);
|
||||||
|
}
|
||||||
|
else return(s->val);
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
} while(--x);
|
||||||
|
return(0); /* We should never get here. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void RebuildSubCheats(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
struct CHEATF *c=cheats;
|
||||||
|
|
||||||
|
for(x=0;x<numsubcheats;x++)
|
||||||
|
SetReadHandler(SubCheats[x].addr,SubCheats[x].addr,SubCheats[x].PrevRead);
|
||||||
|
|
||||||
|
numsubcheats=0;
|
||||||
|
while(c)
|
||||||
|
{
|
||||||
|
if(c->type==1 && c->status)
|
||||||
|
{
|
||||||
|
if(GetReadHandler(c->addr)==SubCheatsRead)
|
||||||
|
{
|
||||||
|
/* Prevent a catastrophe by this check. */
|
||||||
|
//FCEU_DispMessage("oops");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SubCheats[numsubcheats].PrevRead=GetReadHandler(c->addr);
|
||||||
|
SubCheats[numsubcheats].addr=c->addr;
|
||||||
|
SubCheats[numsubcheats].val=c->val;
|
||||||
|
SubCheats[numsubcheats].compare=c->compare;
|
||||||
|
SetReadHandler(c->addr,c->addr,SubCheatsRead);
|
||||||
|
numsubcheats++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c=c->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEU_PowerCheats()
|
||||||
|
{
|
||||||
|
numsubcheats=0; /* Quick hack to prevent setting of ancient read addresses. */
|
||||||
|
RebuildSubCheats();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int AddCheatEntry(char *name, uint32 addr, uint8 val, int compare, int status, int type);
|
||||||
|
static void CheatMemErr(void)
|
||||||
|
{
|
||||||
|
FCEUD_PrintError("Error allocating memory for cheat data.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function doesn't allocate any memory for "name" */
|
||||||
|
static int AddCheatEntry(char *name, uint32 addr, uint8 val, int compare, int status, int type)
|
||||||
|
{
|
||||||
|
struct CHEATF *temp;
|
||||||
|
if(!(temp=(struct CHEATF *)malloc(sizeof(struct CHEATF))))
|
||||||
|
{
|
||||||
|
CheatMemErr();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
temp->name=name;
|
||||||
|
temp->addr=addr;
|
||||||
|
temp->val=val;
|
||||||
|
temp->status=status;
|
||||||
|
temp->compare=compare;
|
||||||
|
temp->type=type;
|
||||||
|
temp->next=0;
|
||||||
|
|
||||||
|
if(cheats)
|
||||||
|
{
|
||||||
|
cheatsl->next=temp;
|
||||||
|
cheatsl=temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cheats=cheatsl=temp;
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEU_LoadGameCheats(FILE *override)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
unsigned int addr;
|
||||||
|
unsigned int val;
|
||||||
|
unsigned int status;
|
||||||
|
unsigned int type;
|
||||||
|
unsigned int compare;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
char linebuf[2048];
|
||||||
|
char *namebuf;
|
||||||
|
int tc=0;
|
||||||
|
char *fn;
|
||||||
|
|
||||||
|
numsubcheats=savecheats=0;
|
||||||
|
|
||||||
|
if(override)
|
||||||
|
fp = override;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fn=FCEU_MakeFName(FCEUMKF_CHEAT,0,0);
|
||||||
|
fp=FCEUD_UTF8fopen(fn,"rb");
|
||||||
|
free(fn);
|
||||||
|
if(!fp) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(fgets(linebuf,2048,fp)>0)
|
||||||
|
{
|
||||||
|
char *tbuf=linebuf;
|
||||||
|
int doc=0;
|
||||||
|
|
||||||
|
addr=val=compare=status=type=0;
|
||||||
|
|
||||||
|
if(tbuf[0]=='S')
|
||||||
|
{
|
||||||
|
tbuf++;
|
||||||
|
type=1;
|
||||||
|
}
|
||||||
|
else type=0;
|
||||||
|
|
||||||
|
if(tbuf[0]=='C')
|
||||||
|
{
|
||||||
|
tbuf++;
|
||||||
|
doc=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tbuf[0]==':')
|
||||||
|
{
|
||||||
|
tbuf++;
|
||||||
|
status=0;
|
||||||
|
}
|
||||||
|
else status=1;
|
||||||
|
|
||||||
|
if(doc)
|
||||||
|
{
|
||||||
|
char *neo=&tbuf[4+2+2+1+1+1];
|
||||||
|
if(sscanf(tbuf,"%04x%*[:]%02x%*[:]%02x",&addr,&val,&compare)!=3)
|
||||||
|
continue;
|
||||||
|
namebuf=malloc(strlen(neo)+1);
|
||||||
|
strcpy(namebuf,neo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *neo=&tbuf[4+2+1+1];
|
||||||
|
if(sscanf(tbuf,"%04x%*[:]%02x",&addr,&val)!=2)
|
||||||
|
continue;
|
||||||
|
namebuf=malloc(strlen(neo)+1);
|
||||||
|
strcpy(namebuf,neo);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(x=0;x<strlen(namebuf);x++)
|
||||||
|
{
|
||||||
|
if(namebuf[x]==10 || namebuf[x]==13)
|
||||||
|
{
|
||||||
|
namebuf[x]=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(namebuf[x]<0x20) namebuf[x]=' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
AddCheatEntry(namebuf,addr,val,doc?compare:-1,status,type);
|
||||||
|
tc++;
|
||||||
|
}
|
||||||
|
RebuildSubCheats();
|
||||||
|
if(!override)
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEU_FlushGameCheats(FILE *override, int nosave)
|
||||||
|
{
|
||||||
|
if(CheatComp)
|
||||||
|
{
|
||||||
|
free(CheatComp);
|
||||||
|
CheatComp=0;
|
||||||
|
}
|
||||||
|
if((!savecheats || nosave) && !override) /* Always save cheats if we're being overridden. */
|
||||||
|
{
|
||||||
|
if(cheats)
|
||||||
|
{
|
||||||
|
struct CHEATF *next=cheats;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
struct CHEATF *last=next;
|
||||||
|
next=next->next;
|
||||||
|
free(last->name);
|
||||||
|
free(last);
|
||||||
|
if(!next) break;
|
||||||
|
}
|
||||||
|
cheats=cheatsl=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *fn = 0;
|
||||||
|
|
||||||
|
if(!override)
|
||||||
|
fn = FCEU_MakeFName(FCEUMKF_CHEAT,0,0);
|
||||||
|
|
||||||
|
if(cheats)
|
||||||
|
{
|
||||||
|
struct CHEATF *next=cheats;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if(override)
|
||||||
|
fp = override;
|
||||||
|
else
|
||||||
|
fp=FCEUD_UTF8fopen(fn,"wb");
|
||||||
|
|
||||||
|
if(fp)
|
||||||
|
{
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
struct CHEATF *t;
|
||||||
|
if(next->type)
|
||||||
|
fputc('S',fp);
|
||||||
|
if(next->compare>=0)
|
||||||
|
fputc('C',fp);
|
||||||
|
|
||||||
|
if(!next->status)
|
||||||
|
fputc(':',fp);
|
||||||
|
|
||||||
|
if(next->compare>=0)
|
||||||
|
fprintf(fp,"%04x:%02x:%02x:%s\n",next->addr,next->val,next->compare,next->name);
|
||||||
|
else
|
||||||
|
fprintf(fp,"%04x:%02x:%s\n",next->addr,next->val,next->name);
|
||||||
|
|
||||||
|
free(next->name);
|
||||||
|
t=next;
|
||||||
|
next=next->next;
|
||||||
|
free(t);
|
||||||
|
if(!next) break;
|
||||||
|
}
|
||||||
|
if(!override)
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FCEUD_PrintError("Error saving cheats.");
|
||||||
|
cheats=cheatsl=0;
|
||||||
|
}
|
||||||
|
else if(!override)
|
||||||
|
remove(fn);
|
||||||
|
if(!override)
|
||||||
|
free(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
RebuildSubCheats(); /* Remove memory handlers. */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int FCEUI_AddCheat(const char *name, uint32 addr, uint8 val, int compare, int type)
|
||||||
|
{
|
||||||
|
char *t;
|
||||||
|
|
||||||
|
if(!(t=(char *)malloc(strlen(name)+1)))
|
||||||
|
{
|
||||||
|
CheatMemErr();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
strcpy(t,name);
|
||||||
|
if(!AddCheatEntry(t,addr,val,compare,1,type))
|
||||||
|
{
|
||||||
|
free(t);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
savecheats=1;
|
||||||
|
RebuildSubCheats();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUI_DelCheat(uint32 which)
|
||||||
|
{
|
||||||
|
struct CHEATF *prev;
|
||||||
|
struct CHEATF *cur;
|
||||||
|
uint32 x=0;
|
||||||
|
|
||||||
|
for(prev=0,cur=cheats;;)
|
||||||
|
{
|
||||||
|
if(x==which) // Remove this cheat.
|
||||||
|
{
|
||||||
|
if(prev) // Update pointer to this cheat.
|
||||||
|
{
|
||||||
|
if(cur->next) // More cheats.
|
||||||
|
prev->next=cur->next;
|
||||||
|
else // No more.
|
||||||
|
{
|
||||||
|
prev->next=0;
|
||||||
|
cheatsl=prev; // Set the previous cheat as the last cheat.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // This is the first cheat.
|
||||||
|
{
|
||||||
|
if(cur->next) // More cheats
|
||||||
|
cheats=cur->next;
|
||||||
|
else
|
||||||
|
cheats=cheatsl=0; // No (more) cheats.
|
||||||
|
}
|
||||||
|
free(cur->name); // Now that all references to this cheat are removed,
|
||||||
|
free(cur); // free the memory.
|
||||||
|
break;
|
||||||
|
} // *END REMOVE THIS CHEAT*
|
||||||
|
|
||||||
|
|
||||||
|
if(!cur->next) // No more cheats to go through(this shouldn't ever happen...)
|
||||||
|
return(0);
|
||||||
|
prev=cur;
|
||||||
|
cur=prev->next;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
savecheats=1;
|
||||||
|
RebuildSubCheats();
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEU_ApplyPeriodicCheats(void)
|
||||||
|
{
|
||||||
|
struct CHEATF *cur=cheats;
|
||||||
|
if(!cur) return;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(cur->status && !(cur->type))
|
||||||
|
if(CheatRPtrs[cur->addr>>10])
|
||||||
|
CheatRPtrs[cur->addr>>10][cur->addr]=cur->val;
|
||||||
|
if(cur->next)
|
||||||
|
cur=cur->next;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FCEUI_ListCheats(int (*callb)(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data)
|
||||||
|
{
|
||||||
|
struct CHEATF *next=cheats;
|
||||||
|
|
||||||
|
while(next)
|
||||||
|
{
|
||||||
|
if(!callb(next->name,next->addr,next->val,next->compare,next->status,next->type,data)) break;
|
||||||
|
next=next->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUI_GetCheat(uint32 which, char **name, uint32 *a, uint8 *v, int *compare, int *s, int *type)
|
||||||
|
{
|
||||||
|
struct CHEATF *next=cheats;
|
||||||
|
uint32 x=0;
|
||||||
|
|
||||||
|
while(next)
|
||||||
|
{
|
||||||
|
if(x==which)
|
||||||
|
{
|
||||||
|
if(name)
|
||||||
|
*name=next->name;
|
||||||
|
if(a)
|
||||||
|
*a=next->addr;
|
||||||
|
if(v)
|
||||||
|
*v=next->val;
|
||||||
|
if(s)
|
||||||
|
*s=next->status;
|
||||||
|
if(compare)
|
||||||
|
*compare=next->compare;
|
||||||
|
if(type)
|
||||||
|
*type=next->type;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
next=next->next;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GGtobin(char c)
|
||||||
|
{
|
||||||
|
static char lets[16]={'A','P','Z','L','G','I','T','Y','E','O','X','U','K','S','V','N'};
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<16;x++)
|
||||||
|
if(lets[x] == toupper(c)) return(x);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns 1 on success, 0 on failure. Sets *a,*v,*c. */
|
||||||
|
int FCEUI_DecodeGG(const char *str, uint16 *a, uint8 *v, int *c)
|
||||||
|
{
|
||||||
|
uint16 A;
|
||||||
|
uint8 V,C;
|
||||||
|
uint8 t;
|
||||||
|
int s;
|
||||||
|
|
||||||
|
A=0x8000;
|
||||||
|
V=0;
|
||||||
|
C=0;
|
||||||
|
|
||||||
|
s=strlen(str);
|
||||||
|
if(s!=6 && s!=8) return(0);
|
||||||
|
|
||||||
|
t=GGtobin(*str++);
|
||||||
|
V|=(t&0x07);
|
||||||
|
V|=(t&0x08)<<4;
|
||||||
|
|
||||||
|
t=GGtobin(*str++);
|
||||||
|
V|=(t&0x07)<<4;
|
||||||
|
A|=(t&0x08)<<4;
|
||||||
|
|
||||||
|
t=GGtobin(*str++);
|
||||||
|
A|=(t&0x07)<<4;
|
||||||
|
//if(t&0x08) return(0); /* 8-character code?! */
|
||||||
|
|
||||||
|
t=GGtobin(*str++);
|
||||||
|
A|=(t&0x07)<<12;
|
||||||
|
A|=(t&0x08);
|
||||||
|
|
||||||
|
t=GGtobin(*str++);
|
||||||
|
A|=(t&0x07);
|
||||||
|
A|=(t&0x08)<<8;
|
||||||
|
|
||||||
|
if(s==6)
|
||||||
|
{
|
||||||
|
t=GGtobin(*str++);
|
||||||
|
A|=(t&0x07)<<8;
|
||||||
|
V|=(t&0x08);
|
||||||
|
|
||||||
|
*a=A;
|
||||||
|
*v=V;
|
||||||
|
*c=-1;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t=GGtobin(*str++);
|
||||||
|
A|=(t&0x07)<<8;
|
||||||
|
C|=(t&0x08);
|
||||||
|
|
||||||
|
t=GGtobin(*str++);
|
||||||
|
C|=(t&0x07);
|
||||||
|
C|=(t&0x08)<<4;
|
||||||
|
|
||||||
|
t=GGtobin(*str++);
|
||||||
|
C|=(t&0x07)<<4;
|
||||||
|
V|=(t&0x08);
|
||||||
|
*a=A;
|
||||||
|
*v=V;
|
||||||
|
*c=C;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUI_DecodePAR(const char *str, uint16 *a, uint8 *v, int *c, int *type)
|
||||||
|
{
|
||||||
|
int boo[4];
|
||||||
|
if(strlen(str)!=8) return(0);
|
||||||
|
|
||||||
|
sscanf(str,"%02x%02x%02x%02x",boo,boo+1,boo+2,boo+3);
|
||||||
|
|
||||||
|
*c=-1;
|
||||||
|
|
||||||
|
if(1)
|
||||||
|
{
|
||||||
|
*a=(boo[3]<<8)|(boo[2]+0x7F);
|
||||||
|
*v=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*v=boo[3];
|
||||||
|
*a=boo[2]|(boo[1]<<8);
|
||||||
|
}
|
||||||
|
/* Zero-page addressing modes don't go through the normal read/write handlers in FCEU, so
|
||||||
|
we must do the old hacky method of RAM cheats.
|
||||||
|
*/
|
||||||
|
if(*a<0x0100)
|
||||||
|
*type=0;
|
||||||
|
else
|
||||||
|
*type=1;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* name can be NULL if the name isn't going to be changed. */
|
||||||
|
/* same goes for a, v, and s(except the values of each one must be <0) */
|
||||||
|
|
||||||
|
int FCEUI_SetCheat(uint32 which, const char *name, int32 a, int32 v, int compare,int s, int type)
|
||||||
|
{
|
||||||
|
struct CHEATF *next=cheats;
|
||||||
|
uint32 x=0;
|
||||||
|
|
||||||
|
while(next)
|
||||||
|
{
|
||||||
|
if(x==which)
|
||||||
|
{
|
||||||
|
if(name)
|
||||||
|
{
|
||||||
|
char *t;
|
||||||
|
|
||||||
|
if((t=(char *)realloc(next->name,strlen(name+1))))
|
||||||
|
{
|
||||||
|
next->name=t;
|
||||||
|
strcpy(next->name,name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
if(a>=0)
|
||||||
|
next->addr=a;
|
||||||
|
if(v>=0)
|
||||||
|
next->val=v;
|
||||||
|
if(s>=0)
|
||||||
|
next->status=s;
|
||||||
|
next->compare=compare;
|
||||||
|
next->type=type;
|
||||||
|
|
||||||
|
savecheats=1;
|
||||||
|
RebuildSubCheats();
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
next=next->next;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convenience function. */
|
||||||
|
int FCEUI_ToggleCheat(uint32 which)
|
||||||
|
{
|
||||||
|
struct CHEATF *next=cheats;
|
||||||
|
uint32 x=0;
|
||||||
|
|
||||||
|
while(next)
|
||||||
|
{
|
||||||
|
if(x==which)
|
||||||
|
{
|
||||||
|
next->status=!next->status;
|
||||||
|
savecheats=1;
|
||||||
|
RebuildSubCheats();
|
||||||
|
return(next->status);
|
||||||
|
}
|
||||||
|
next=next->next;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InitCheatComp(void)
|
||||||
|
{
|
||||||
|
uint32 x;
|
||||||
|
|
||||||
|
CheatComp=(uint16*)malloc(65536*sizeof(uint16));
|
||||||
|
if(!CheatComp)
|
||||||
|
{
|
||||||
|
CheatMemErr();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
for(x=0;x<65536;x++)
|
||||||
|
CheatComp[x]=CHEATC_NONE;
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUI_CheatSearchSetCurrentAsOriginal(void)
|
||||||
|
{
|
||||||
|
uint32 x;
|
||||||
|
for(x=0x000;x<0x10000;x++)
|
||||||
|
if(!(CheatComp[x]&CHEATC_NOSHOW))
|
||||||
|
{
|
||||||
|
if(CheatRPtrs[x>>10])
|
||||||
|
CheatComp[x]=CheatRPtrs[x>>10][x];
|
||||||
|
else
|
||||||
|
CheatComp[x]|=CHEATC_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUI_CheatSearchShowExcluded(void)
|
||||||
|
{
|
||||||
|
uint32 x;
|
||||||
|
|
||||||
|
for(x=0x000;x<0x10000;x++)
|
||||||
|
CheatComp[x]&=~CHEATC_EXCLUDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32 FCEUI_CheatSearchGetCount(void)
|
||||||
|
{
|
||||||
|
uint32 x,c=0;
|
||||||
|
|
||||||
|
if(CheatComp)
|
||||||
|
{
|
||||||
|
for(x=0x0000;x<0x10000;x++)
|
||||||
|
if(!(CheatComp[x]&CHEATC_NOSHOW) && CheatRPtrs[x>>10])
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
/* This function will give the initial value of the search and the current value at a location. */
|
||||||
|
|
||||||
|
void FCEUI_CheatSearchGet(int (*callb)(uint32 a, uint8 last, uint8 current, void *data),void *data)
|
||||||
|
{
|
||||||
|
uint32 x;
|
||||||
|
|
||||||
|
if(!CheatComp)
|
||||||
|
{
|
||||||
|
if(!InitCheatComp())
|
||||||
|
CheatMemErr();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(x=0;x<0x10000;x++)
|
||||||
|
if(!(CheatComp[x]&CHEATC_NOSHOW) && CheatRPtrs[x>>10])
|
||||||
|
if(!callb(x,CheatComp[x],CheatRPtrs[x>>10][x],data))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUI_CheatSearchGetRange(uint32 first, uint32 last, int (*callb)(uint32 a, uint8 last, uint8 current))
|
||||||
|
{
|
||||||
|
uint32 x;
|
||||||
|
uint32 in=0;
|
||||||
|
|
||||||
|
if(!CheatComp)
|
||||||
|
{
|
||||||
|
if(!InitCheatComp())
|
||||||
|
CheatMemErr();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(x=0;x<0x10000;x++)
|
||||||
|
if(!(CheatComp[x]&CHEATC_NOSHOW) && CheatRPtrs[x>>10])
|
||||||
|
{
|
||||||
|
if(in>=first)
|
||||||
|
if(!callb(x,CheatComp[x],CheatRPtrs[x>>10][x]))
|
||||||
|
break;
|
||||||
|
in++;
|
||||||
|
if(in>last) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUI_CheatSearchBegin(void)
|
||||||
|
{
|
||||||
|
uint32 x;
|
||||||
|
|
||||||
|
if(!CheatComp)
|
||||||
|
{
|
||||||
|
if(!InitCheatComp())
|
||||||
|
{
|
||||||
|
CheatMemErr();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(x=0;x<0x10000;x++)
|
||||||
|
{
|
||||||
|
if(CheatRPtrs[x>>10])
|
||||||
|
CheatComp[x]=CheatRPtrs[x>>10][x];
|
||||||
|
else
|
||||||
|
CheatComp[x]=CHEATC_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int INLINE CAbs(int x)
|
||||||
|
{
|
||||||
|
if(x<0)
|
||||||
|
return(0-x);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUI_CheatSearchEnd(int type, uint8 v1, uint8 v2)
|
||||||
|
{
|
||||||
|
uint32 x;
|
||||||
|
|
||||||
|
if(!CheatComp)
|
||||||
|
{
|
||||||
|
if(!InitCheatComp())
|
||||||
|
{
|
||||||
|
CheatMemErr();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(!type) // Change to a specific value.
|
||||||
|
{
|
||||||
|
for(x=0;x<0x10000;x++)
|
||||||
|
if(!(CheatComp[x]&CHEATC_NOSHOW))
|
||||||
|
{
|
||||||
|
if(CheatComp[x]==v1 && CheatRPtrs[x>>10][x]==v2)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CheatComp[x]|=CHEATC_EXCLUDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(type==1) // Search for relative change(between values).
|
||||||
|
{
|
||||||
|
for(x=0;x<0x10000;x++)
|
||||||
|
if(!(CheatComp[x]&CHEATC_NOSHOW))
|
||||||
|
{
|
||||||
|
if(CheatComp[x]==v1 && CAbs(CheatComp[x]-CheatRPtrs[x>>10][x])==v2)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CheatComp[x]|=CHEATC_EXCLUDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(type==2) // Purely relative change.
|
||||||
|
{
|
||||||
|
for(x=0x000;x<0x10000;x++)
|
||||||
|
if(!(CheatComp[x]&CHEATC_NOSHOW))
|
||||||
|
{
|
||||||
|
if(CAbs(CheatComp[x]-CheatRPtrs[x>>10][x])==v2)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CheatComp[x]|=CHEATC_EXCLUDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(type==3) // Any change.
|
||||||
|
{
|
||||||
|
for(x=0;x<0x10000;x++)
|
||||||
|
if(!(CheatComp[x]&CHEATC_NOSHOW))
|
||||||
|
{
|
||||||
|
if(CheatComp[x]!=CheatRPtrs[x>>10][x])
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CheatComp[x]|=CHEATC_EXCLUDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(type==4) // Value decreased.
|
||||||
|
{
|
||||||
|
for(x=0;x<0x10000;x++)
|
||||||
|
if(!(CheatComp[x]&CHEATC_NOSHOW))
|
||||||
|
{
|
||||||
|
if(!(CheatRPtrs[x>>10][x]<CheatComp[x]))
|
||||||
|
CheatComp[x]|=CHEATC_EXCLUDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(type==5) // Value increased.
|
||||||
|
{
|
||||||
|
for(x=0;x<0x10000;x++)
|
||||||
|
if(!(CheatComp[x]&CHEATC_NOSHOW))
|
||||||
|
{
|
||||||
|
if(!(CheatRPtrs[x>>10][x]>CheatComp[x]))
|
||||||
|
CheatComp[x]|=CHEATC_EXCLUDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(type>4)
|
||||||
|
FCEUI_CheatSearchSetCurrentAsOriginal();
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
void FCEU_CheatResetRAM(void);
|
||||||
|
void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p);
|
||||||
|
|
||||||
|
void FCEU_LoadGameCheats(FILE *override);
|
||||||
|
void FCEU_FlushGameCheats(FILE *override, int nosave);
|
||||||
|
void FCEU_ApplyPeriodicCheats(void);
|
||||||
|
void FCEU_PowerCheats(void);
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "crc32.h"
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
uint32 CalcCRC32(uint32 crc, uint8 *buf, uint32 len)
|
||||||
|
{
|
||||||
|
return(crc32(crc,buf,len));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 FCEUI_CRC32(uint32 crc, uint8 *buf, uint32 len)
|
||||||
|
{
|
||||||
|
return(CalcCRC32(crc,buf,len));
|
||||||
|
}
|
|
@ -0,0 +1,535 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2003 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "x6502.h"
|
||||||
|
#include "fceu.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "cart.h"
|
||||||
|
|
||||||
|
|
||||||
|
void FCEUI_DumpVid(const char *fname, uint32 start, uint32 end)
|
||||||
|
{
|
||||||
|
FILE *fp=FCEUD_UTF8fopen(fname,"wb");
|
||||||
|
fceuindbg=1;
|
||||||
|
start&=0x1FFF;
|
||||||
|
end&=0x1FFF;
|
||||||
|
for(;start<=end;start++)
|
||||||
|
fputc(VPage[start>>10][start],fp);
|
||||||
|
fclose(fp);
|
||||||
|
fceuindbg=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUI_DumpMem(const char *fname, uint32 start, uint32 end)
|
||||||
|
{
|
||||||
|
FILE *fp=FCEUD_UTF8fopen(fname,"wb");
|
||||||
|
fceuindbg=1;
|
||||||
|
for(;start<=end;start++)
|
||||||
|
fputc(ARead[start](start),fp);
|
||||||
|
fclose(fp);
|
||||||
|
fceuindbg=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUI_LoadMem(const char *fname, uint32 start, int hl)
|
||||||
|
{
|
||||||
|
int t;
|
||||||
|
|
||||||
|
FILE *fp=FCEUD_UTF8fopen(fname,"rb");
|
||||||
|
while((t=fgetc(fp))>=0)
|
||||||
|
{
|
||||||
|
if(start>0xFFFF) break;
|
||||||
|
if(hl)
|
||||||
|
{
|
||||||
|
extern uint8 *Page[32];
|
||||||
|
if(Page[start/2048])
|
||||||
|
Page[start/2048][start]=t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
BWrite[start](start,t);
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef FCEUDEF_DEBUGGER
|
||||||
|
|
||||||
|
static char *fstrings[12]=
|
||||||
|
{
|
||||||
|
"#$%02X", // immediate
|
||||||
|
"$%04X", // RELATIVE(jump)
|
||||||
|
"$%02X", // Z
|
||||||
|
"$%02X,X", // Z,x
|
||||||
|
"$%02X,Y", // Z,y
|
||||||
|
"$%04X", //ABS
|
||||||
|
"$%04X,X", // ABS,x
|
||||||
|
"$%04X,Y", // ABS,y
|
||||||
|
"($%04X)", // IND
|
||||||
|
"($%02X,X)", // INX
|
||||||
|
"($%02X),Y", // INY
|
||||||
|
""
|
||||||
|
};
|
||||||
|
static int flengths[12]={1,1,1,1,1,2,2,2,2,1,1,0};
|
||||||
|
|
||||||
|
#define IMD(x) ((0<<16)|x)
|
||||||
|
#define REL(x) ((1<<16)|x)
|
||||||
|
#define ZP(x) ((2<<16)|x)
|
||||||
|
#define ZPX(x) ((3<<16)|x)
|
||||||
|
#define ZPY(x) ((4<<16)|x)
|
||||||
|
#define ABS(x) ((5<<16)|x)
|
||||||
|
#define ABX(x) ((6<<16)|x)
|
||||||
|
#define ABY(x) ((7<<16)|x)
|
||||||
|
#define IND(x) ((8<<16)|x)
|
||||||
|
#define INX(x) ((9<<16)|x)
|
||||||
|
#define INY(x) ((10<<16)|x)
|
||||||
|
#define IMP(x) ((11<<16)|x)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
int type; /* 1 for read, 2 for write, 3 for r then write. */
|
||||||
|
int32 modes[10];
|
||||||
|
} OPS;
|
||||||
|
#define NUMOPS 56
|
||||||
|
static OPS optable[NUMOPS]=
|
||||||
|
{
|
||||||
|
{"BRK",0,{IMP(0x00),-1}},
|
||||||
|
{"RTI",0,{IMP(0x40),-1}},
|
||||||
|
{"RTS",0,{IMP(0x60),-1}},
|
||||||
|
{"PHA",2,{IMP(0x48),-1}},
|
||||||
|
{"PHP",2,{IMP(0x08),-1}},
|
||||||
|
{"PLA",1,{IMP(0x68),-1}},
|
||||||
|
{"PLP",1,{IMP(0x28),-1}},
|
||||||
|
{"JMP",0,{ABS(0x4C),IND(0x6C),-1}},
|
||||||
|
{"JSR",0,{ABS(0x20),-1}},
|
||||||
|
{"TAX",0,{IMP(0xAA),-1}},
|
||||||
|
{"TXA",0,{IMP(0x8A),-1}},
|
||||||
|
{"TAY",0,{IMP(0xA8),-1}},
|
||||||
|
{"TYA",0,{IMP(0x98),-1}},
|
||||||
|
{"TSX",0,{IMP(0xBA),-1}},
|
||||||
|
{"TXS",0,{IMP(0x9A),-1}},
|
||||||
|
{"DEX",0,{IMP(0xCA),-1}},
|
||||||
|
{"DEY",0,{IMP(0x88),-1}},
|
||||||
|
{"INX",0,{IMP(0xE8),-1}},
|
||||||
|
{"INY",0,{IMP(0xC8),-1}},
|
||||||
|
{"CLC",0,{IMP(0x18),-1}},
|
||||||
|
{"CLD",0,{IMP(0xD8),-1}},
|
||||||
|
{"CLI",0,{IMP(0x58),-1}},
|
||||||
|
{"CLV",0,{IMP(0xB8),-1}},
|
||||||
|
{"SEC",0,{IMP(0x38),-1}},
|
||||||
|
{"SED",0,{IMP(0xF8),-1}},
|
||||||
|
{"SEI",0,{IMP(0x78),-1}},
|
||||||
|
{"NOP",0,{IMP(0xEA),-1}},
|
||||||
|
{"ASL",1,{IMP(0x0a),ZP(0x06),ZPX(0x16),ABS(0x0E),ABX(0x1E),-1}},
|
||||||
|
{"DEC",3,{ZP(0xc6),ZPX(0xd6),ABS(0xcE),ABX(0xdE),-1}},
|
||||||
|
{"INC",3,{ZP(0xe6),ZPX(0xf6),ABS(0xeE),ABX(0xfE),-1}},
|
||||||
|
{"LSR",3,{IMP(0x4a),ZP(0x46),ZPX(0x56),ABS(0x4E),ABX(0x5E),-1}},
|
||||||
|
{"ROL",3,{IMP(0x2a),ZP(0x26),ZPX(0x36),ABS(0x2E),ABX(0x3E),-1}},
|
||||||
|
{"ROR",3,{IMP(0x6a),ZP(0x66),ZPX(0x76),ABS(0x6E),ABX(0x7E),-1}},
|
||||||
|
{"ADC",1,{IMD(0x69),ZP(0x65),ZPX(0x75),ABS(0x6D),ABX(0x7d),ABY(0x79),
|
||||||
|
INX(0x61),INY(0x71),-1}},
|
||||||
|
{"AND",1,{IMD(0x29),ZP(0x25),ZPX(0x35),ABS(0x2D),ABX(0x3d),ABY(0x39),
|
||||||
|
INX(0x21),INY(0x31),-1}},
|
||||||
|
{"BIT",1,{ZP(0x24),ABS(0x2c),-1}},
|
||||||
|
{"CMP",1,{IMD(0xc9),ZP(0xc5),ZPX(0xd5),ABS(0xcD),ABX(0xdd),ABY(0xd9),
|
||||||
|
INX(0xc1),INY(0xd1),-1}},
|
||||||
|
{"CPX",1,{IMD(0xe0),ZP(0xe4),ABS(0xec),-1}},
|
||||||
|
{"CPY",1,{IMD(0xc0),ZP(0xc4),ABS(0xcc),-1}},
|
||||||
|
{"EOR",1,{IMD(0x49),ZP(0x45),ZPX(0x55),ABS(0x4D),ABX(0x5d),ABY(0x59),
|
||||||
|
INX(0x41),INY(0x51),-1}},
|
||||||
|
{"LDA",1,{IMD(0xa9),ZP(0xa5),ZPX(0xb5),ABS(0xaD),ABX(0xbd),ABY(0xb9),
|
||||||
|
INX(0xa1),INY(0xb1),-1}},
|
||||||
|
{"LDX",1,{IMD(0xa2),ZP(0xa6),ZPY(0xB6),ABS(0xae),ABY(0xbe),-1}},
|
||||||
|
{"LDY",1,{IMD(0xa0),ZP(0xa4),ZPX(0xB4),ABS(0xac),ABX(0xbc),-1}},
|
||||||
|
{"ORA",1,{IMD(0x09),ZP(0x05),ZPX(0x15),ABS(0x0D),ABX(0x1d),ABY(0x19),
|
||||||
|
INX(0x01),INY(0x11),-1}},
|
||||||
|
{"SBC",1,{IMD(0xEB),IMD(0xe9),ZP(0xe5),ZPX(0xf5),ABS(0xeD),ABX(0xfd),ABY(0xf9),
|
||||||
|
INX(0xe1),INY(0xf1),-1}},
|
||||||
|
{"STA",2,{ZP(0x85),ZPX(0x95),ABS(0x8D),ABX(0x9d),ABY(0x99),
|
||||||
|
INX(0x81),INY(0x91),-1}},
|
||||||
|
{"STX",2,{ZP(0x86),ZPY(0x96),ABS(0x8E),-1}},
|
||||||
|
{"STY",2,{ZP(0x84),ZPX(0x94),ABS(0x8C),-1}},
|
||||||
|
{"BCC",1,{REL(0x90),-1}},
|
||||||
|
{"BCS",1,{REL(0xb0),-1}},
|
||||||
|
{"BEQ",1,{REL(0xf0),-1}},
|
||||||
|
{"BNE",1,{REL(0xd0),-1}},
|
||||||
|
{"BMI",1,{REL(0x30),-1}},
|
||||||
|
{"BPL",1,{REL(0x10),-1}},
|
||||||
|
{"BVC",1,{REL(0x50),-1}},
|
||||||
|
{"BVS",1,{REL(0x70),-1}},
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16 FCEUI_Disassemble(void *XA, uint16 a, char *stringo)
|
||||||
|
{
|
||||||
|
X6502 *X=XA;
|
||||||
|
uint8 buf;
|
||||||
|
unsigned int arg;
|
||||||
|
int32 info;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
info=-1;
|
||||||
|
fceuindbg=1;
|
||||||
|
|
||||||
|
buf=ARead[a](a);
|
||||||
|
a++;
|
||||||
|
|
||||||
|
for(x=0;x<NUMOPS;x++)
|
||||||
|
{
|
||||||
|
y=0;
|
||||||
|
while(optable[x].modes[y]>=0)
|
||||||
|
{
|
||||||
|
if((optable[x].modes[y]&0xFF)==buf)
|
||||||
|
{
|
||||||
|
info=optable[x].modes[y];
|
||||||
|
goto endy;
|
||||||
|
}
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endy:
|
||||||
|
sprintf(stringo,"%02X ",buf);
|
||||||
|
if(info>=0)
|
||||||
|
{
|
||||||
|
int z=flengths[(info>>16)];
|
||||||
|
|
||||||
|
if(z)
|
||||||
|
{
|
||||||
|
arg=ARead[a](a);
|
||||||
|
sprintf(stringo+strlen(stringo),"%02X ",arg);
|
||||||
|
a++;
|
||||||
|
if(z==2) {arg|=ARead[a](a)<<8;sprintf(stringo+strlen(stringo),"%02X ",arg>>8);a++;}
|
||||||
|
else
|
||||||
|
strcat(stringo," ");
|
||||||
|
|
||||||
|
if((info>>16)==1) /* Relative branch */
|
||||||
|
arg=a+(char)arg;
|
||||||
|
sprintf(stringo+strlen(stringo),"%s ",optable[x].name);
|
||||||
|
sprintf(stringo+strlen(stringo),fstrings[info>>16],arg);
|
||||||
|
/*
|
||||||
|
0 "#$%02X", // immediate
|
||||||
|
1 "$%04X", // RELATIVE(jump)
|
||||||
|
2 "$%02X", // Z
|
||||||
|
3 "$%02X,X", // Z,x
|
||||||
|
4 "$%02X,Y", // Z,y
|
||||||
|
5 "$%04X", //ABS
|
||||||
|
6 "$%04X,X", // ABS,x
|
||||||
|
7 "$%04X,Y", // ABS,y
|
||||||
|
8 "($%04X)", // IND
|
||||||
|
9 "($%02X,X)", // INX
|
||||||
|
10 "($%02X),Y", // INY
|
||||||
|
11 #define IMP(x) ((11<<16)|x)
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned int tmp;
|
||||||
|
switch(info>>16)
|
||||||
|
{
|
||||||
|
case 2:tmp=arg;
|
||||||
|
if(optable[x].type&1)
|
||||||
|
{
|
||||||
|
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||||
|
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:tmp=(arg+X->X)&0xff;
|
||||||
|
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||||
|
if(optable[x].type&1)
|
||||||
|
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||||
|
break;
|
||||||
|
case 4:tmp=(arg+X->Y)&0xff;
|
||||||
|
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||||
|
if(optable[x].type&1)
|
||||||
|
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||||
|
break;
|
||||||
|
case 5:tmp=arg;
|
||||||
|
if(optable[x].type&1)
|
||||||
|
{
|
||||||
|
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||||
|
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 6:tmp=(arg+X->X)&0xffff;
|
||||||
|
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||||
|
if(optable[x].type&1)
|
||||||
|
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||||
|
break;
|
||||||
|
case 7:tmp=(arg+X->Y)&0xffff;
|
||||||
|
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||||
|
if(optable[x].type&1)
|
||||||
|
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||||
|
break;
|
||||||
|
case 8:tmp=ARead[arg](arg)|(ARead[(arg+1)&0xffff]((arg+1)&0xffff)<<8);
|
||||||
|
sprintf(stringo+strlen(stringo)," $%04X",tmp);
|
||||||
|
break;
|
||||||
|
case 9:tmp=(arg+X->X)&0xFF;
|
||||||
|
tmp=ARead[tmp](tmp) | (ARead[(tmp+1)&0xFF]((tmp+1)&0xFF)<<8);
|
||||||
|
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||||
|
if(optable[x].type&1)
|
||||||
|
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||||
|
break;
|
||||||
|
case 10:tmp=ARead[arg](arg) | (ARead[(arg+1)&0xFF]((arg+1)&0xFF)<<8);
|
||||||
|
tmp=(tmp+X->Y)&0xFFFF;
|
||||||
|
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||||
|
if(optable[x].type&1)
|
||||||
|
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcat(stringo," ");
|
||||||
|
strcat(stringo,optable[x].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sprintf(stringo+strlen(stringo)," .db $%02X",buf);
|
||||||
|
fceuindbg=0;
|
||||||
|
return(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUI_MemDump(uint16 a, int32 len, void (*callb)(uint16 a, uint8 v))
|
||||||
|
{
|
||||||
|
fceuindbg=1;
|
||||||
|
while(len)
|
||||||
|
{
|
||||||
|
callb(a,ARead[a](a));
|
||||||
|
a++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
fceuindbg=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 FCEUI_MemSafePeek(uint16 A)
|
||||||
|
{
|
||||||
|
uint8 ret;
|
||||||
|
|
||||||
|
fceuindbg=1;
|
||||||
|
ret=ARead[A](A);
|
||||||
|
fceuindbg=0;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUI_MemPoke(uint16 a, uint8 v, int hl)
|
||||||
|
{
|
||||||
|
extern uint8 *Page[32];
|
||||||
|
if(hl)
|
||||||
|
{
|
||||||
|
if(Page[a/2048])
|
||||||
|
Page[a/2048][a]=v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
BWrite[a](a,v);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct __BPOINT {
|
||||||
|
struct __BPOINT *next;
|
||||||
|
void (*Handler)(X6502 *X, int type, unsigned int A);
|
||||||
|
unsigned int A[2];
|
||||||
|
int type;
|
||||||
|
} BPOINT;
|
||||||
|
|
||||||
|
static BPOINT *BreakPoints=NULL;
|
||||||
|
static BPOINT *LastBP=NULL;
|
||||||
|
|
||||||
|
static void (*CPUHook)(X6502 *)=NULL;
|
||||||
|
|
||||||
|
static int FindBPoint(X6502 *X, int who, unsigned int A)
|
||||||
|
{
|
||||||
|
BPOINT *tmp;
|
||||||
|
|
||||||
|
tmp=BreakPoints;
|
||||||
|
while(tmp)
|
||||||
|
{
|
||||||
|
if(tmp->type&who)
|
||||||
|
{
|
||||||
|
if(tmp->type&BPOINT_PC)
|
||||||
|
if(X->PC!=A) goto don; /* Doesn't match, so go on. */
|
||||||
|
|
||||||
|
if((A>=tmp->A[0]) && (A<=tmp->A[1])) /* Whee, match. */
|
||||||
|
{
|
||||||
|
tmp->Handler(X,tmp->type,A);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
don:
|
||||||
|
tmp=tmp->next;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 ReadHandler(X6502 *X, unsigned int A)
|
||||||
|
{
|
||||||
|
extern X6502 XSave;
|
||||||
|
|
||||||
|
if(X->preexec)
|
||||||
|
FindBPoint(&XSave,BPOINT_READ,A);
|
||||||
|
return(ARead[A](A));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteHandler(X6502 *X, unsigned int A, uint8 V)
|
||||||
|
{
|
||||||
|
extern X6502 XSave;
|
||||||
|
|
||||||
|
if(X->preexec)
|
||||||
|
FindBPoint(&XSave,BPOINT_WRITE,A);
|
||||||
|
else
|
||||||
|
BWrite[A](A,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUI_AddBreakPoint(int type, unsigned int A1, unsigned int A2,
|
||||||
|
void (*Handler)(X6502 *, int type, unsigned int A))
|
||||||
|
{
|
||||||
|
BPOINT *tmp;
|
||||||
|
|
||||||
|
tmp=(BPOINT *)malloc(sizeof(BPOINT));
|
||||||
|
|
||||||
|
tmp->A[0]=A1;
|
||||||
|
tmp->A[1]=A2;
|
||||||
|
tmp->Handler=Handler;
|
||||||
|
tmp->type=type;
|
||||||
|
tmp->next=0;
|
||||||
|
|
||||||
|
if(BreakPoints==NULL)
|
||||||
|
BreakPoints=tmp;
|
||||||
|
else
|
||||||
|
LastBP->next=tmp;
|
||||||
|
|
||||||
|
LastBP=tmp;
|
||||||
|
|
||||||
|
X6502_Debug(CPUHook,ReadHandler,WriteHandler);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUI_SetBreakPoint(uint32 w, int type, unsigned int A1, unsigned int A2,
|
||||||
|
void (*Handler)(X6502 *, int type, unsigned int A))
|
||||||
|
{
|
||||||
|
uint32 x=0;
|
||||||
|
BPOINT *tmp;
|
||||||
|
|
||||||
|
tmp=BreakPoints;
|
||||||
|
|
||||||
|
while(tmp)
|
||||||
|
{
|
||||||
|
if(w==x)
|
||||||
|
{
|
||||||
|
tmp->type=type;
|
||||||
|
tmp->A[0]=A1;
|
||||||
|
tmp->A[1]=A2;
|
||||||
|
tmp->Handler=Handler;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
tmp=tmp->next;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUI_GetBreakPoint(uint32 w, int *type, unsigned int *A1, unsigned int *A2,
|
||||||
|
void (**Handler)(X6502 *, int type, unsigned int A))
|
||||||
|
{
|
||||||
|
uint32 x=0;
|
||||||
|
BPOINT *tmp;
|
||||||
|
|
||||||
|
tmp=BreakPoints;
|
||||||
|
|
||||||
|
while(tmp)
|
||||||
|
{
|
||||||
|
if(w==x)
|
||||||
|
{
|
||||||
|
*type=tmp->type;
|
||||||
|
*A1=tmp->A[0];
|
||||||
|
*A2=tmp->A[1];
|
||||||
|
*Handler=tmp->Handler;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
tmp=tmp->next;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUI_ListBreakPoints(int (*callb)(int type, unsigned int A1, unsigned int A2,
|
||||||
|
void (*Handler)(X6502 *, int type, unsigned int A) ))
|
||||||
|
{
|
||||||
|
BPOINT *tmp;
|
||||||
|
tmp=BreakPoints;
|
||||||
|
while(tmp)
|
||||||
|
{
|
||||||
|
callb(tmp->type,tmp->A[0],tmp->A[1],tmp->Handler);
|
||||||
|
tmp=tmp->next;
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUI_DeleteBreakPoint(uint32 w)
|
||||||
|
{
|
||||||
|
BPOINT *tmp,*prev=NULL;
|
||||||
|
uint32 x=0;
|
||||||
|
|
||||||
|
tmp=BreakPoints;
|
||||||
|
|
||||||
|
while(tmp)
|
||||||
|
{
|
||||||
|
if(w==x)
|
||||||
|
{
|
||||||
|
if(prev) /* Not the first breakpoint. */
|
||||||
|
{
|
||||||
|
if(tmp->next) /* More breakpoints. */
|
||||||
|
prev->next=tmp->next;
|
||||||
|
else /* This is the last breakpoint. */
|
||||||
|
{
|
||||||
|
prev->next=0;
|
||||||
|
LastBP=prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* The first breakpoint. */
|
||||||
|
{
|
||||||
|
if(tmp->next) /* More breakpoints. */
|
||||||
|
BreakPoints=tmp->next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BreakPoints=LastBP=0; /* No more breakpoints. */
|
||||||
|
/* Update the CPU hooks. */
|
||||||
|
X6502_Debug(CPUHook,BreakPoints?ReadHandler:0,BreakPoints?WriteHandler:0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(tmp);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
prev=tmp;
|
||||||
|
tmp=tmp->next;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUI_SetCPUCallback(void (*callb)(X6502 *X))
|
||||||
|
{
|
||||||
|
CPUHook=callb;
|
||||||
|
X6502_Debug(CPUHook,BreakPoints?ReadHandler:0,BreakPoints?WriteHandler:0);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,24 @@
|
||||||
|
void FCEUI_DumpMem(const char *fname, uint32 start, uint32 end);
|
||||||
|
void FCEUI_DumpVid(const char *fname, uint32 start, uint32 end);
|
||||||
|
void FCEUI_LoadMem(const char *fname, uint32 start, int hl);
|
||||||
|
|
||||||
|
#ifdef FCEUDEF_DEBUGGER
|
||||||
|
|
||||||
|
/* Type attributes, you can OR them together. */
|
||||||
|
#define BPOINT_READ 1
|
||||||
|
#define BPOINT_WRITE 2
|
||||||
|
#define BPOINT_PC 4
|
||||||
|
|
||||||
|
#include "x6502struct.h"
|
||||||
|
|
||||||
|
void FCEUI_SetCPUCallback(void (*callb)(X6502 *X));
|
||||||
|
int FCEUI_DeleteBreakPoint(uint32 w);
|
||||||
|
int FCEUI_ListBreakPoints(int (*callb)(int type, unsigned int A1, unsigned int A2,
|
||||||
|
void (*Handler)(X6502 *, int type, unsigned int A) ));
|
||||||
|
int FCEUI_GetBreakPoint(uint32 w, int *type, unsigned int *A1, unsigned int *A2,
|
||||||
|
void (**Handler)(X6502 *, int type, unsigned int A));
|
||||||
|
int FCEUI_SetBreakPoint(uint32 w, int type, unsigned int A1, unsigned int A2,
|
||||||
|
void (*Handler)(X6502 *, int type, unsigned int A));
|
||||||
|
int FCEUI_AddBreakPoint(int type, unsigned int A1, unsigned int A2,
|
||||||
|
void (*Handler)(X6502 *, int type, unsigned int A));
|
||||||
|
#endif
|
|
@ -0,0 +1,228 @@
|
||||||
|
void DrawTextLineBG(uint8 *dest)
|
||||||
|
{
|
||||||
|
int x,y;
|
||||||
|
static int otable[7]={81,49,30,17,8,3,0};
|
||||||
|
//100,40,15,10,7,5,2};
|
||||||
|
for(y=0;y<14;y++)
|
||||||
|
{
|
||||||
|
int offs;
|
||||||
|
|
||||||
|
if(y>=7) offs=otable[13-y];
|
||||||
|
else offs=otable[y];
|
||||||
|
|
||||||
|
for(x=offs;x<(256-offs);x++)
|
||||||
|
dest[y*256+x]=(dest[y*256+x]&0x0f)|0xC0;//&=0xe0; //0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawMessage(void)
|
||||||
|
{
|
||||||
|
if(howlong)
|
||||||
|
{
|
||||||
|
uint8 *t;
|
||||||
|
howlong--;
|
||||||
|
t=XBuf+(FSettings.LastSLine-20)*256;
|
||||||
|
if(t>=XBuf)
|
||||||
|
{
|
||||||
|
DrawTextLineBG(t);
|
||||||
|
DrawTextTrans(t+256*3+(128-strlen(errmsg)*4),256,(uint8 *)errmsg,4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 fontdata2[2048] =
|
||||||
|
{
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x81,0xa5,0x81,0xbd,0x99,0x81,0x7e,0x7e,0xff,0xdb,0xff,0xc3,0xe7,0xff,0x7e,0x36,0x7f,0x7f,0x7f,0x3e,0x1c,0x08,0x00,0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x08,0x00,0x1c,0x3e,0x1c,0x7f,0x7f,0x3e,0x1c,0x3e,0x08,0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x3e,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xf0,0xe0,0xf0,0xbe,0x33,0x33,0x33,0x1e,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0xfc,0xcc,0xfc,0x0c,0x0c,0x0e,0x0f,0x07,0xfe,0xc6,0xfe,0xc6,0xc6,0xe6,0x67,0x03,0x99,0x5a,0x3c,0xe7,0xe7,0x3c,0x5a,0x99,0x01,0x07,0x1f,0x7f,0x1f,0x07,0x01,0x00,0x40,0x70,0x7c,0x7f,0x7c,0x70,0x40,0x00,0x18,0x3c,0x7e,0x18,0x18,0x7e,0x3c,0x18,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x00,0xfe,0xdb,0xdb,0xde,0xd8,0xd8,0xd8,0x00,0x7c,0xc6,0x1c,0x36,0x36,0x1c,0x33,0x1e,0x00,0x00,0x00,0x00,0x7e,0x7e,0x7e,0x00,0x18,0x3c,0x7e,0x18,0x7e,0x3c,0x18,0xff,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x18,0x30,0x7f,0x30,0x18,0x00,0x00,0x00,0x0c,0x06,0x7f,0x06,0x0c,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x7f,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0x7e,0x3c,0x18,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x1e,0x1e,0x0c,0x0c,0x00,0x0c,0x00,0x36,0x36,0x36,0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x7f,0x36,0x7f,0x36,0x36,0x00,0x0c,0x3e,0x03,0x1e,0x30,0x1f,0x0c,0x00,0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00,0x1c,0x36,0x1c,0x6e,0x3b,0x33,0x6e,0x00,0x06,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0x06,0x06,0x06,0x0c,0x18,0x00,0x06,0x0c,0x18,0x18,0x18,0x0c,0x06,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x0c,0x0c,0x3f,0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x06,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x00,0x60,0x30,0x18,0x0c,0x06,0x03,0x01,0x00,0x3e,0x63,0x73,0x7b,0x6f,0x67,0x3e,0x00,0x0c,0x0e,0x0c,0x0c,0x0c,0x0c,0x3f,0x00,0x1e,0x33,0x30,0x1c,0x06,0x33,0x3f,0x00,0x1e,0x33,0x30,0x1c,0x30,0x33,0x1e,0x00,0x38,0x3c,0x36,0x33,0x7f,0x30,0x78,0x00,0x3f,0x03,0x1f,0x30,0x30,0x33,0x1e,0x00,0x1c,0x06,0x03,0x1f,0x33,0x33,0x1e,0x00,0x3f,0x33,0x30,0x18,0x0c,0x0c,0x0c,0x00,0x1e,0x33,0x33,0x1e,0x33,0x33,0x1e,0x00,0x1e,0x33,0x33,0x3e,0x30,0x18,0x0e,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x06,0x18,0x0c,0x06,0x03,0x06,0x0c,0x18,0x00,0x00,0x00,0x3f,0x00,0x00,0x3f,0x00,0x00,0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00,0x1e,0x33,0x30,0x18,0x0c,0x00,0x0c,0x00,
|
||||||
|
0x3e,0x63,0x7b,0x7b,0x7b,0x03,0x1e,0x00,0x0c,0x1e,0x33,0x33,0x3f,0x33,0x33,0x00,0x3f,0x66,0x66,0x3e,0x66,0x66,0x3f,0x00,0x3c,0x66,0x03,0x03,0x03,0x66,0x3c,0x00,0x1f,0x36,0x66,0x66,0x66,0x36,0x1f,0x00,0x7f,0x46,0x16,0x1e,0x16,0x46,0x7f,0x00,0x7f,0x46,0x16,0x1e,0x16,0x06,0x0f,0x00,0x3c,0x66,0x03,0x03,0x73,0x66,0x7c,0x00,0x33,0x33,0x33,0x3f,0x33,0x33,0x33,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x78,0x30,0x30,0x30,0x33,0x33,0x1e,0x00,0x67,0x66,0x36,0x1e,0x36,0x66,0x67,0x00,0x0f,0x06,0x06,0x06,0x46,0x66,0x7f,0x00,0x63,0x77,0x7f,0x7f,0x6b,0x63,0x63,0x00,0x63,0x67,0x6f,0x7b,0x73,0x63,0x63,0x00,0x1c,0x36,0x63,0x63,0x63,0x36,0x1c,0x00,0x3f,0x66,0x66,0x3e,0x06,0x06,0x0f,0x00,0x1e,0x33,0x33,0x33,0x3b,0x1e,0x38,0x00,0x3f,0x66,0x66,0x3e,0x36,0x66,0x67,0x00,0x1e,0x33,0x07,0x0e,0x38,0x33,0x1e,0x00,0x3f,0x2d,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x33,0x33,0x33,0x33,0x33,0x33,0x3f,0x00,0x33,0x33,0x33,0x33,0x33,0x1e,0x0c,0x00,0x63,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00,0x63,0x63,0x36,0x1c,0x1c,0x36,0x63,0x00,0x33,0x33,0x33,0x1e,0x0c,0x0c,0x1e,0x00,0x7f,0x63,0x31,0x18,0x4c,0x66,0x7f,0x00,0x1e,0x06,0x06,0x06,0x06,0x06,0x1e,0x00,0x03,0x06,0x0c,0x18,0x30,0x60,0x40,0x00,0x1e,0x18,0x18,0x18,0x18,0x18,0x1e,0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
|
||||||
|
0x0c,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x30,0x3e,0x33,0x6e,0x00,0x07,0x06,0x06,0x3e,0x66,0x66,0x3b,0x00,0x00,0x00,0x1e,0x33,0x03,0x33,0x1e,0x00,0x38,0x30,0x30,0x3e,0x33,0x33,0x6e,0x00,0x00,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x1c,0x36,0x06,0x0f,0x06,0x06,0x0f,0x00,0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x1f,0x07,0x06,0x36,0x6e,0x66,0x66,0x67,0x00,0x0c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x30,0x00,0x30,0x30,0x30,0x33,0x33,0x1e,0x07,0x06,0x66,0x36,0x1e,0x36,0x67,0x00,0x0e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x33,0x7f,0x7f,0x6b,0x63,0x00,0x00,0x00,0x1f,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x1e,0x33,0x33,0x33,0x1e,0x00,0x00,0x00,0x3b,0x66,0x66,0x3e,0x06,0x0f,0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x78,0x00,0x00,0x3b,0x6e,0x66,0x06,0x0f,0x00,0x00,0x00,0x3e,0x03,0x1e,0x30,0x1f,0x00,0x08,0x0c,0x3e,0x0c,0x0c,0x2c,0x18,0x00,0x00,0x00,0x33,0x33,0x33,0x33,0x6e,0x00,0x00,0x00,0x33,0x33,0x33,0x1e,0x0c,0x00,0x00,0x00,0x63,0x6b,0x7f,0x7f,0x36,0x00,0x00,0x00,0x63,0x36,0x1c,0x36,0x63,0x00,0x00,0x00,0x33,0x33,0x33,0x3e,0x30,0x1f,0x00,0x00,0x3f,0x19,0x0c,0x26,0x3f,0x00,0x38,0x0c,0x0c,0x07,0x0c,0x0c,0x38,0x00,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x07,0x0c,0x0c,0x38,0x0c,0x0c,0x07,0x00,0x6e,0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1c,0x36,0x63,0x63,0x7f,0x00,
|
||||||
|
0x1e,0x33,0x03,0x33,0x1e,0x18,0x30,0x1e,0x00,0x33,0x00,0x33,0x33,0x33,0x7e,0x00,0x38,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x7e,0xc3,0x3c,0x60,0x7c,0x66,0xfc,0x00,0x33,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x07,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x0c,0x0c,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x00,0x00,0x1e,0x03,0x03,0x1e,0x30,0x1c,0x7e,0xc3,0x3c,0x66,0x7e,0x06,0x3c,0x00,0x33,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x07,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x33,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x3e,0x63,0x1c,0x18,0x18,0x18,0x3c,0x00,0x07,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x63,0x1c,0x36,0x63,0x7f,0x63,0x63,0x00,0x0c,0x0c,0x00,0x1e,0x33,0x3f,0x33,0x00,0x38,0x00,0x3f,0x06,0x1e,0x06,0x3f,0x00,0x00,0x00,0xfe,0x30,0xfe,0x33,0xfe,0x00,0x7c,0x36,0x33,0x7f,0x33,0x33,0x73,0x00,0x1e,0x33,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x33,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x07,0x00,0x1e,0x33,0x33,0x1e,0x00,0x1e,0x33,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x07,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x33,0x00,0x33,0x33,0x3e,0x30,0x1f,0xc3,0x18,0x3c,0x66,0x66,0x3c,0x18,0x00,0x33,0x00,0x33,0x33,0x33,0x33,0x1e,0x00,0x18,0x18,0x7e,0x03,0x03,0x7e,0x18,0x18,0x1c,0x36,0x26,0x0f,0x06,0x67,0x3f,0x00,0x33,0x33,0x1e,0x3f,0x0c,0x3f,0x0c,0x0c,0x1f,0x33,0x33,0x5f,0x63,0xf3,0x63,0xe3,0x70,0xd8,0x18,0x3c,0x18,0x18,0x1b,0x0e,
|
||||||
|
0x38,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x1c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x38,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x38,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x1f,0x00,0x1f,0x33,0x33,0x33,0x00,0x3f,0x00,0x33,0x37,0x3f,0x3b,0x33,0x00,0x3c,0x36,0x36,0x7c,0x00,0x7e,0x00,0x00,0x1c,0x36,0x36,0x1c,0x00,0x3e,0x00,0x00,0x0c,0x00,0x0c,0x06,0x03,0x33,0x1e,0x00,0x00,0x00,0x00,0x3f,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x30,0x00,0x00,0xc3,0x63,0x33,0x7b,0xcc,0x66,0x33,0xf0,0xc3,0x63,0x33,0xdb,0xec,0xf6,0xf3,0xc0,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x00,0x00,0xcc,0x66,0x33,0x66,0xcc,0x00,0x00,0x00,0x33,0x66,0xcc,0x66,0x33,0x00,0x00,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xdb,0xee,0xdb,0x77,0xdb,0xee,0xdb,0x77,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x6c,0x6c,0x6c,0x6c,0x6f,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x7f,0x6c,0x6c,0x6c,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x6c,0x6c,0x6f,0x60,0x6f,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x7f,0x60,0x6f,0x6c,0x6c,0x6c,0x6c,0x6c,0x6f,0x60,0x7f,0x00,0x00,0x00,0x6c,0x6c,0x6c,0x6c,0x7f,0x00,0x00,0x00,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,
|
||||||
|
0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x6c,0x6c,0x6c,0x6c,0xec,0x6c,0x6c,0x6c,0x6c,0x6c,0xec,0x0c,0xfc,0x00,0x00,0x00,0x00,0x00,0xfc,0x0c,0xec,0x6c,0x6c,0x6c,0x6c,0x6c,0xef,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xef,0x6c,0x6c,0x6c,0x6c,0x6c,0xec,0x0c,0xec,0x6c,0x6c,0x6c,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x6c,0x6c,0xef,0x00,0xef,0x6c,0x6c,0x6c,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x6c,0x6c,0x6c,0x6c,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xff,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0xfc,0x00,0x00,0x00,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xfc,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0xff,0x6c,0x6c,0x6c,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x6e,0x3b,0x13,0x3b,0x6e,0x00,0x00,0x1e,0x33,0x1f,0x33,0x1f,0x03,0x03,0x00,0x3f,0x33,0x03,0x03,0x03,0x03,0x00,0x00,0x7f,0x36,0x36,0x36,0x36,0x36,0x00,0x3f,0x33,0x06,0x0c,0x06,0x33,0x3f,0x00,0x00,0x00,0x7e,0x1b,0x1b,0x1b,0x0e,0x00,0x00,0x66,0x66,0x66,0x66,0x3e,0x06,0x03,0x00,0x6e,0x3b,0x18,0x18,0x18,0x18,0x00,0x3f,0x0c,0x1e,0x33,0x33,0x1e,0x0c,0x3f,0x1c,0x36,0x63,0x7f,0x63,0x36,0x1c,0x00,0x1c,0x36,0x63,0x63,0x36,0x36,0x77,0x00,0x38,0x0c,0x18,0x3e,0x33,0x33,0x1e,0x00,0x00,0x00,0x7e,0xdb,0xdb,0x7e,0x00,0x00,0x60,0x30,0x7e,0xdb,0xdb,0x7e,0x06,0x03,0x1c,0x06,0x03,0x1f,0x03,0x06,0x1c,0x00,0x1e,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x3f,0x00,0x3f,0x00,0x3f,0x00,0x00,0x0c,0x0c,0x3f,0x0c,0x0c,0x00,0x3f,0x00,0x06,0x0c,0x18,0x0c,0x06,0x00,0x3f,0x00,0x18,0x0c,0x06,0x0c,0x18,0x00,0x3f,0x00,0x70,0xd8,0xd8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x0e,0x0c,0x0c,0x00,0x3f,0x00,0x0c,0x0c,0x00,0x00,0x6e,0x3b,0x00,0x6e,0x3b,0x00,0x00,0x1c,0x36,0x36,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0xf0,0x30,0x30,0x30,0x37,0x36,0x3c,0x38,0x1e,0x36,0x36,0x36,0x36,0x00,0x00,0x00,0x0e,0x18,0x0c,0x06,0x1e,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x3c,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
void DrawTextTrans(uint8 *dest, uint32 width, uint8 *textmsg, uint8 fgcolor)
|
||||||
|
{
|
||||||
|
uint8 length=strlen((char *)textmsg);
|
||||||
|
uint8 x;
|
||||||
|
uint8 y;
|
||||||
|
uint8 z;
|
||||||
|
|
||||||
|
for(x=0;x<length;x++)
|
||||||
|
for(y=0;y<8;y++)
|
||||||
|
for(z=0;z<8;z++)
|
||||||
|
if((fontdata2[(textmsg[x]<<3)+y]>>z)&1) dest[y*width+(x<<3)+z]=fgcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 sstat[2541] =
|
||||||
|
{
|
||||||
|
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||||
|
0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
|
||||||
|
0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x83,0x83,0x83,
|
||||||
|
0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x80,0x83,
|
||||||
|
0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,
|
||||||
|
0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,
|
||||||
|
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x80,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||||
|
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x80,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||||
|
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x81,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||||
|
0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||||
|
0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x80,0x80,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x83,
|
||||||
|
0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,
|
||||||
|
0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x80,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x80,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
|
||||||
|
0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x80,0x80,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
|
||||||
|
0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x83,0x80,0x80,0x81,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x80,0x83,0x83,0x81,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x81,0x81,0x81,0x83,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
void FCEU_DrawNumberRow(uint8 *XBuf, int *nstatus, int cur)
|
||||||
|
{
|
||||||
|
uint8 *XBaf;
|
||||||
|
int z,x,y;
|
||||||
|
|
||||||
|
XBaf=XBuf - 4 + (FSettings.LastSLine-34)*256;
|
||||||
|
if(XBaf>=XBuf)
|
||||||
|
for(z=1;z<11;z++)
|
||||||
|
{
|
||||||
|
if(nstatus[z%10])
|
||||||
|
{
|
||||||
|
for(y=0;y<13;y++)
|
||||||
|
for(x=0;x<21;x++)
|
||||||
|
XBaf[y*256+x+z*21+z]=sstat[y*21+x+(z-1)*21*12]^0x80;
|
||||||
|
} else {
|
||||||
|
for(y=0;y<13;y++)
|
||||||
|
for(x=0;x<21;x++)
|
||||||
|
if(sstat[y*21+x+(z-1)*21*12]!=0x83)
|
||||||
|
XBaf[y*256+x+z*21+z]=sstat[y*21+x+(z-1)*21*12]^0x80;
|
||||||
|
|
||||||
|
else
|
||||||
|
XBaf[y*256+x+z*21+z]=(XBaf[y*256+x+z*21+z]&0xF)|0xC0;
|
||||||
|
}
|
||||||
|
if(cur==z%10)
|
||||||
|
{
|
||||||
|
for(x=0;x<21;x++)
|
||||||
|
XBaf[x+z*21+z*1]=4;
|
||||||
|
for(x=1;x<12;x++)
|
||||||
|
{
|
||||||
|
XBaf[256*x+z*21+z*1]=
|
||||||
|
XBaf[256*x+z*21+z*1+20]=4;
|
||||||
|
}
|
||||||
|
for(x=0;x<21;x++)
|
||||||
|
XBaf[12*256+x+z*21+z*1]=4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 play_slines[]=
|
||||||
|
{
|
||||||
|
0, 0, 1,
|
||||||
|
1, 0, 2,
|
||||||
|
2, 0, 3,
|
||||||
|
3, 0, 4,
|
||||||
|
4, 0, 5,
|
||||||
|
5, 0, 6,
|
||||||
|
6, 0, 7,
|
||||||
|
7, 0, 8,
|
||||||
|
8, 0, 7,
|
||||||
|
9, 0, 6,
|
||||||
|
10, 0, 5,
|
||||||
|
11, 0, 4,
|
||||||
|
12, 0, 3,
|
||||||
|
13, 0, 2,
|
||||||
|
14, 0, 1,
|
||||||
|
99,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8 record_slines[]=
|
||||||
|
{
|
||||||
|
0, 5, 9,
|
||||||
|
1, 3, 11,
|
||||||
|
2, 2, 12,
|
||||||
|
3, 1, 13,
|
||||||
|
4, 1, 13,
|
||||||
|
5, 0, 14,
|
||||||
|
6, 0, 14,
|
||||||
|
7, 0, 14,
|
||||||
|
8, 0, 14,
|
||||||
|
9, 0, 14,
|
||||||
|
10, 1, 13,
|
||||||
|
11, 1, 13,
|
||||||
|
12, 2, 12,
|
||||||
|
13, 3, 11,
|
||||||
|
14, 5, 9,
|
||||||
|
99,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8 pause_slines[]=
|
||||||
|
{
|
||||||
|
0, 2, 6,
|
||||||
|
1, 2, 6,
|
||||||
|
2, 2, 6,
|
||||||
|
3, 2, 6,
|
||||||
|
4, 2, 6,
|
||||||
|
5, 2, 6,
|
||||||
|
6, 2, 6,
|
||||||
|
7, 2, 6,
|
||||||
|
8, 2, 6,
|
||||||
|
9, 2, 6,
|
||||||
|
10, 2, 6,
|
||||||
|
11, 2, 6,
|
||||||
|
12, 2, 6,
|
||||||
|
13, 2, 6,
|
||||||
|
14, 2, 6,
|
||||||
|
|
||||||
|
0, 9, 13,
|
||||||
|
1, 9, 13,
|
||||||
|
2, 9, 13,
|
||||||
|
3, 9, 13,
|
||||||
|
4, 9, 13,
|
||||||
|
5, 9, 13,
|
||||||
|
6, 9, 13,
|
||||||
|
7, 9, 13,
|
||||||
|
8, 9, 13,
|
||||||
|
9, 9, 13,
|
||||||
|
10, 9, 13,
|
||||||
|
11, 9, 13,
|
||||||
|
12, 9, 13,
|
||||||
|
13, 9, 13,
|
||||||
|
14, 9, 13,
|
||||||
|
99,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8 no_slines[]=
|
||||||
|
{
|
||||||
|
99
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8* sline_icons[4]=
|
||||||
|
{
|
||||||
|
no_slines,
|
||||||
|
play_slines,
|
||||||
|
record_slines,
|
||||||
|
pause_slines
|
||||||
|
};
|
||||||
|
|
||||||
|
void FCEU_DrawRecordingStatusN(uint8* XBuf, int n)
|
||||||
|
{
|
||||||
|
uint8* slines=sline_icons[n];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
XBuf += (FSettings.LastSLine-28)*256 + 240 + 255;
|
||||||
|
for(i=0; slines[i]!=99; i+=3)
|
||||||
|
{
|
||||||
|
int y=slines[i];
|
||||||
|
uint8* dest=XBuf+(y*256);
|
||||||
|
int x;
|
||||||
|
for(x=slines[i+1]; x!=slines[i+2]; ++x)
|
||||||
|
dest[x]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XBuf -= 255;
|
||||||
|
for(i=0; slines[i]!=99; i+=3)
|
||||||
|
{
|
||||||
|
int y=slines[i];
|
||||||
|
uint8* dest=XBuf+(y*256);
|
||||||
|
int x;
|
||||||
|
for(x=slines[i+1]; x!=slines[i+2]; ++x)
|
||||||
|
dest[x]=4;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,317 @@
|
||||||
|
#ifndef __DRIVER_H_
|
||||||
|
#define __DRIVER_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "git.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode);
|
||||||
|
|
||||||
|
/* This makes me feel dirty for some reason. */
|
||||||
|
void FCEU_printf(char *format, ...);
|
||||||
|
#define FCEUI_printf FCEU_printf
|
||||||
|
|
||||||
|
/* Video interface */
|
||||||
|
void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b);
|
||||||
|
void FCEUD_GetPalette(uint8 i,uint8 *r, uint8 *g, uint8 *b);
|
||||||
|
|
||||||
|
/* Displays an error. Can block or not. */
|
||||||
|
void FCEUD_PrintError(char *s);
|
||||||
|
void FCEUD_Message(char *s);
|
||||||
|
|
||||||
|
#ifdef NETWORK
|
||||||
|
/* Network interface */
|
||||||
|
|
||||||
|
/* Call only when a game is loaded. */
|
||||||
|
int FCEUI_NetplayStart(int nlocal, int divisor);
|
||||||
|
|
||||||
|
/* Call when network play needs to stop. */
|
||||||
|
void FCEUI_NetplayStop(void);
|
||||||
|
|
||||||
|
/* Note: YOU MUST NOT CALL ANY FCEUI_* FUNCTIONS WHILE IN FCEUD_SendData() or
|
||||||
|
FCEUD_RecvData().
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Return 0 on failure, 1 on success. */
|
||||||
|
int FCEUD_SendData(void *data, uint32 len);
|
||||||
|
int FCEUD_RecvData(void *data, uint32 len);
|
||||||
|
|
||||||
|
/* Display text received over the network. */
|
||||||
|
void FCEUD_NetplayText(uint8 *text);
|
||||||
|
|
||||||
|
/* Encode and send text over the network. */
|
||||||
|
void FCEUI_NetplayText(uint8 *text);
|
||||||
|
|
||||||
|
/* Called when a fatal error occurred and network play can't continue. This function
|
||||||
|
should call FCEUI_NetplayStop() after it has deinitialized the network on the driver
|
||||||
|
side.
|
||||||
|
*/
|
||||||
|
void FCEUD_NetworkClose(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int FCEUI_BeginWaveRecord(char *fn);
|
||||||
|
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);
|
||||||
|
|
||||||
|
#define SI_NONE 0
|
||||||
|
#define SI_GAMEPAD 1
|
||||||
|
#define SI_ZAPPER 2
|
||||||
|
#define SI_POWERPADA 3
|
||||||
|
#define SI_POWERPADB 4
|
||||||
|
#define SI_ARKANOID 5
|
||||||
|
|
||||||
|
#define SIFC_NONE 0
|
||||||
|
#define SIFC_ARKANOID 1
|
||||||
|
#define SIFC_SHADOW 2
|
||||||
|
#define SIFC_4PLAYER 3
|
||||||
|
#define SIFC_FKB 4
|
||||||
|
#define SIFC_SUBORKB 5
|
||||||
|
#define SIFC_HYPERSHOT 6
|
||||||
|
#define SIFC_MAHJONG 7
|
||||||
|
#define SIFC_QUIZKING 8
|
||||||
|
#define SIFC_FTRAINERA 9
|
||||||
|
#define SIFC_FTRAINERB 10
|
||||||
|
#define SIFC_OEKAKIDS 11
|
||||||
|
#define SIFC_BWORLD 12
|
||||||
|
#define SIFC_TOPRIDER 13
|
||||||
|
|
||||||
|
#define SIS_NONE 0
|
||||||
|
#define SIS_DATACH 1
|
||||||
|
#define SIS_NWC 2
|
||||||
|
#define SIS_VSUNISYSTEM 3
|
||||||
|
#define SIS_NSF 4
|
||||||
|
|
||||||
|
/* New interface functions */
|
||||||
|
|
||||||
|
/* 0 to order screen snapshots numerically(0.png), 1 to order them file base-numerically(smb3-0.png). */
|
||||||
|
void FCEUI_SetSnapName(int a);
|
||||||
|
|
||||||
|
/* 0 to keep 8-sprites limitation, 1 to remove it */
|
||||||
|
void FCEUI_DisableSpriteLimitation(int a);
|
||||||
|
|
||||||
|
/* -1 = no change, 0 = show, 1 = hide, 2 = internal toggle */
|
||||||
|
void FCEUI_SetRenderDisable(int sprites, int bg);
|
||||||
|
|
||||||
|
/* name=path and file to load. returns 0 on failure, 1 on success */
|
||||||
|
FCEUGI *FCEUI_LoadGame(const char *name, int OverwriteVidMode);
|
||||||
|
|
||||||
|
/* allocates memory. 0 on failure, 1 on success. */
|
||||||
|
int FCEUI_Initialize(void);
|
||||||
|
|
||||||
|
/* Emulates a frame. */
|
||||||
|
void FCEUI_Emulate(uint8 **, int32 **, int32 *, int);
|
||||||
|
|
||||||
|
/* Closes currently loaded game */
|
||||||
|
void FCEUI_CloseGame(void);
|
||||||
|
|
||||||
|
/* Deallocates all allocated memory. Call after FCEUI_Emulate() returns. */
|
||||||
|
void FCEUI_Kill(void);
|
||||||
|
|
||||||
|
/* Enable/Disable game genie. a=0 disable, a=1 enable */
|
||||||
|
void FCEUI_SetGameGenie(int a);
|
||||||
|
|
||||||
|
/* Set video system a=0 NTSC, a=1 PAL */
|
||||||
|
void FCEUI_SetVidSystem(int a);
|
||||||
|
|
||||||
|
/* Convenience function; returns currently emulated video system(0=NTSC, 1=PAL). */
|
||||||
|
int FCEUI_GetCurrentVidSystem(int *slstart, int *slend);
|
||||||
|
|
||||||
|
#ifdef FRAMESKIP
|
||||||
|
/* Should be called from FCEUD_BlitScreen(). Specifies how many frames
|
||||||
|
to skip until FCEUD_BlitScreen() is called. FCEUD_BlitScreenDummy()
|
||||||
|
will be called instead of FCEUD_BlitScreen() when when a frame is skipped.
|
||||||
|
*/
|
||||||
|
void FCEUI_FrameSkip(int x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* First and last scanlines to render, for ntsc and pal emulation. */
|
||||||
|
void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall);
|
||||||
|
|
||||||
|
/* Sets the base directory(save states, snapshots, etc. are saved in directories
|
||||||
|
below this directory. */
|
||||||
|
void FCEUI_SetBaseDirectory(char *dir);
|
||||||
|
|
||||||
|
/* Tells FCE Ultra to copy the palette data pointed to by pal and use it.
|
||||||
|
Data pointed to by pal needs to be 64*3 bytes in length.
|
||||||
|
*/
|
||||||
|
void FCEUI_SetPaletteArray(uint8 *pal);
|
||||||
|
|
||||||
|
/* Sets up sound code to render sound at the specified rate, in samples
|
||||||
|
per second. Only sample rates of 44100, 48000, and 96000 are currently
|
||||||
|
supported.
|
||||||
|
If "Rate" equals 0, sound is disabled.
|
||||||
|
*/
|
||||||
|
void FCEUI_Sound(int Rate);
|
||||||
|
void FCEUI_SetSoundVolume(uint32 volume);
|
||||||
|
void FCEUI_SetSoundQuality(int quality);
|
||||||
|
|
||||||
|
void FCEUD_SoundToggle(void);
|
||||||
|
void FCEUD_SoundVolumeAdjust(int);
|
||||||
|
|
||||||
|
int FCEUI_SelectState(int, int);
|
||||||
|
|
||||||
|
/* "fname" overrides the default save state filename code if non-NULL. */
|
||||||
|
void FCEUI_SaveState(char *fname);
|
||||||
|
void FCEUI_LoadState(char *fname);
|
||||||
|
|
||||||
|
void FCEUD_SaveStateAs(void);
|
||||||
|
void FCEUD_LoadStateFrom(void);
|
||||||
|
|
||||||
|
#define MOVIE_FLAG_FROM_RESET (1<<1)
|
||||||
|
#define MOVIE_FLAG_PAL (1<<2)
|
||||||
|
#define MOVIE_FLAG_FROM_POWERON (1<<3) // value is temporary onle, gets converted to reset
|
||||||
|
#define MOVIE_MAX_METADATA 512
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int movie_version; // version of the movie format in the file
|
||||||
|
uint32 num_frames;
|
||||||
|
uint32 rerecord_count;
|
||||||
|
uint8 flags;
|
||||||
|
int read_only;
|
||||||
|
uint32 emu_version_used; // 9813 = 0.98.13
|
||||||
|
char* metadata; // caller-supplied buffer to store metadata. can be NULL.
|
||||||
|
int metadata_size; // size of the buffer pointed to by metadata
|
||||||
|
uint8 md5_of_rom_used[16];
|
||||||
|
int md5_of_rom_used_present; // v1 movies don't have md5 info available
|
||||||
|
char* name_of_rom_used; // caller-supplied buffer to store metadata. can be NULL.
|
||||||
|
int name_of_rom_used_size; // size of the buffer pointer to by name_of_rom_used
|
||||||
|
} MOVIE_INFO;
|
||||||
|
|
||||||
|
int FCEUI_SelectMovie(int, int);
|
||||||
|
void FCEUI_SaveMovie(char *fname, uint8 flags, const char* metadata);
|
||||||
|
void FCEUI_LoadMovie(char *fname, int read_only, int _stopframe);
|
||||||
|
void FCEUI_StopMovie(void);
|
||||||
|
int FCEUI_IsMovieActive(void);
|
||||||
|
int FCEUI_MovieGetInfo(const char* fname, MOVIE_INFO* /* [in, out] */ info);
|
||||||
|
char* FCEUI_MovieGetCurrentName(int addSlotNumber);
|
||||||
|
void FCEUI_MovieToggleReadOnly(void);
|
||||||
|
void FCEUI_MovieToggleFrameDisplay(void);
|
||||||
|
void FCEUI_ToggleInputDisplay(void);
|
||||||
|
|
||||||
|
void FCEUD_MovieRecordTo(void);
|
||||||
|
void FCEUD_MovieReplayFrom(void);
|
||||||
|
|
||||||
|
int32 FCEUI_GetDesiredFPS(void);
|
||||||
|
void FCEUI_SaveSnapshot(void);
|
||||||
|
void FCEU_DispMessage(char *format, ...);
|
||||||
|
#define FCEUI_DispMessage FCEU_DispMessage
|
||||||
|
|
||||||
|
int FCEUI_DecodePAR(const char *code, uint16 *a, uint8 *v, int *c, int *type);
|
||||||
|
int FCEUI_DecodeGG(const char *str, uint16 *a, uint8 *v, int *c);
|
||||||
|
int FCEUI_AddCheat(const char *name, uint32 addr, uint8 val, int compare, int type);
|
||||||
|
int FCEUI_DelCheat(uint32 which);
|
||||||
|
int FCEUI_ToggleCheat(uint32 which);
|
||||||
|
|
||||||
|
int32 FCEUI_CheatSearchGetCount(void);
|
||||||
|
void FCEUI_CheatSearchGetRange(uint32 first, uint32 last, int (*callb)(uint32 a, uint8 last, uint8 current));
|
||||||
|
void FCEUI_CheatSearchGet(int (*callb)(uint32 a, uint8 last, uint8 current, void *data), void *data);
|
||||||
|
void FCEUI_CheatSearchBegin(void);
|
||||||
|
void FCEUI_CheatSearchEnd(int type, uint8 v1, uint8 v2);
|
||||||
|
void FCEUI_ListCheats(int (*callb)(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data);
|
||||||
|
|
||||||
|
int FCEUI_GetCheat(uint32 which, char **name, uint32 *a, uint8 *v, int *compare, int *s, int *type);
|
||||||
|
int FCEUI_SetCheat(uint32 which, const char *name, int32 a, int32 v, int compare,int s, int type);
|
||||||
|
|
||||||
|
void FCEUI_CheatSearchShowExcluded(void);
|
||||||
|
void FCEUI_CheatSearchSetCurrentAsOriginal(void);
|
||||||
|
|
||||||
|
#define FCEUIOD_STATE 0
|
||||||
|
#define FCEUIOD_SNAPS 1
|
||||||
|
#define FCEUIOD_NV 2
|
||||||
|
#define FCEUIOD_CHEATS 3
|
||||||
|
#define FCEUIOD_MISC 4
|
||||||
|
|
||||||
|
#define FCEUIOD__COUNT 5
|
||||||
|
|
||||||
|
void FCEUI_SetDirOverride(int which, char *n);
|
||||||
|
|
||||||
|
void FCEUI_MemDump(uint16 a, int32 len, void (*callb)(uint16 a, uint8 v));
|
||||||
|
uint8 FCEUI_MemSafePeek(uint16 A);
|
||||||
|
void FCEUI_MemPoke(uint16 a, uint8 v, int hl);
|
||||||
|
void FCEUI_NMI(void);
|
||||||
|
void FCEUI_IRQ(void);
|
||||||
|
uint16 FCEUI_Disassemble(void *XA, uint16 a, char *stringo);
|
||||||
|
void FCEUI_GetIVectors(uint16 *reset, uint16 *irq, uint16 *nmi);
|
||||||
|
|
||||||
|
uint32 FCEUI_CRC32(uint32 crc, uint8 *buf, uint32 len);
|
||||||
|
|
||||||
|
void FCEUI_ToggleTileView(void);
|
||||||
|
void FCEUI_SetLowPass(int q);
|
||||||
|
|
||||||
|
void FCEUI_NSFSetVis(int mode);
|
||||||
|
int FCEUI_NSFChange(int amount);
|
||||||
|
int FCEUI_NSFGetInfo(uint8 *name, uint8 *artist, uint8 *copyright, int maxlen);
|
||||||
|
|
||||||
|
void FCEUI_VSUniToggleDIPView(void);
|
||||||
|
void FCEUI_VSUniToggleDIP(int w);
|
||||||
|
uint8 FCEUI_VSUniGetDIPs(void);
|
||||||
|
void FCEUI_VSUniSetDIP(int w, int state);
|
||||||
|
void FCEUI_VSUniCoin(void);
|
||||||
|
|
||||||
|
int FCEUI_FDSInsert(void);
|
||||||
|
//int FCEUI_FDSEject(void);
|
||||||
|
void FCEUI_FDSSelect(void);
|
||||||
|
|
||||||
|
int FCEUI_DatachSet(const uint8 *rcode);
|
||||||
|
|
||||||
|
int FCEUI_EmulationPaused(void);
|
||||||
|
void FCEUI_ToggleEmulationPause(void);
|
||||||
|
void FCEUI_FrameAdvance(void);
|
||||||
|
|
||||||
|
/* AVI Output */
|
||||||
|
int FCEUI_AviBegin(const char* fname);
|
||||||
|
void FCEUI_AviEnd(void);
|
||||||
|
void FCEUI_AviVideoUpdate(const unsigned char* buffer);
|
||||||
|
void FCEUI_AviSoundUpdate(void* soundData, int soundLen);
|
||||||
|
int FCEUI_AviIsRecording(void);
|
||||||
|
|
||||||
|
void FCEUD_AviRecordTo(void);
|
||||||
|
void FCEUD_AviStop(void);
|
||||||
|
|
||||||
|
/* Command input mapping */
|
||||||
|
typedef int TestCommandState(int cmd);
|
||||||
|
void FCEUI_HandleEmuCommands(TestCommandState* testfn);
|
||||||
|
void FCEUD_CmdOpen(void);
|
||||||
|
|
||||||
|
/* Emulation speed */
|
||||||
|
enum EMUSPEED_SET
|
||||||
|
{
|
||||||
|
EMUSPEED_SLOWEST=0,
|
||||||
|
EMUSPEED_SLOWER,
|
||||||
|
EMUSPEED_NORMAL,
|
||||||
|
EMUSPEED_FASTER,
|
||||||
|
EMUSPEED_FASTEST
|
||||||
|
};
|
||||||
|
void FCEUD_SetEmulationSpeed(int cmd);
|
||||||
|
void FCEUD_TurboOn(void);
|
||||||
|
void FCEUD_TurboOff(void);
|
||||||
|
|
||||||
|
int FCEUD_ShowStatusIcon(void);
|
||||||
|
void FCEUD_ToggleStatusIcon(void);
|
||||||
|
void FCEUD_HideMenuToggle(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __DRIVER_H_ */
|
|
@ -0,0 +1 @@
|
||||||
|
fceu_SOURCES += drivers/common/args.c drivers/common/cheat.c drivers/common/config.c drivers/common/vidblit.c drivers/common/hq2x.c drivers/common/hq3x.c drivers/common/scale2x.c drivers/common/scale3x.c drivers/common/scalebit.c
|
|
@ -0,0 +1,98 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
/* FCE Ultra */
|
||||||
|
/* */
|
||||||
|
/* This file contains code for parsing command-line */
|
||||||
|
/* options. */
|
||||||
|
/* */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../../types.h"
|
||||||
|
#include "args.h"
|
||||||
|
|
||||||
|
void ParseEA(int x, int argc, char *argv[], ARGPSTRUCT *argsps)
|
||||||
|
{
|
||||||
|
int y=0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(!argsps[y].name)
|
||||||
|
{
|
||||||
|
ParseEA(x,argc,argv,(ARGPSTRUCT*)argsps[y].var);
|
||||||
|
y++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!strcmp(argv[x],argsps[y].name)) // A match.
|
||||||
|
{
|
||||||
|
if(argsps[y].subs)
|
||||||
|
{
|
||||||
|
if((x+1)>=argc)
|
||||||
|
break;
|
||||||
|
if(argsps[y].substype&0x2000)
|
||||||
|
{
|
||||||
|
((void (*)(char *))argsps[y].subs)(argv[x+1]);
|
||||||
|
}
|
||||||
|
else if(argsps[y].substype&0x8000)
|
||||||
|
{
|
||||||
|
*(int *)argsps[y].subs&=~(argsps[y].substype&(~0x8000));
|
||||||
|
*(int *)argsps[y].subs|=atoi(argv[x+1])?(argsps[y].substype&(~0x8000)):0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
switch(argsps[y].substype&(~0x4000))
|
||||||
|
{
|
||||||
|
case 0: // Integer
|
||||||
|
*(int *)argsps[y].subs=atoi(argv[x+1]);
|
||||||
|
break;
|
||||||
|
case 2: // Double float
|
||||||
|
*(double *)argsps[y].subs=atof(argv[x+1]);
|
||||||
|
break;
|
||||||
|
case 1: // String
|
||||||
|
if(argsps[y].substype&0x4000)
|
||||||
|
{
|
||||||
|
if(*(char **)argsps[y].subs)
|
||||||
|
free(*(char **)argsps[y].subs);
|
||||||
|
if(!( *(char **)argsps[y].subs=(char*)malloc(strlen(argv[x+1])+1) ))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strcpy(*(char **)argsps[y].subs,argv[x+1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(argsps[y].var)
|
||||||
|
*argsps[y].var=1;
|
||||||
|
}
|
||||||
|
y++;
|
||||||
|
} while(argsps[y].var || argsps[y].subs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseArguments(int argc, char *argv[], ARGPSTRUCT *argsps)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<argc;x++)
|
||||||
|
ParseEA(x,argc,argv,argsps);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef _DRIVERS_ARGH
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
int *var;
|
||||||
|
|
||||||
|
void *subs;
|
||||||
|
int substype;
|
||||||
|
} ARGPSTRUCT;
|
||||||
|
|
||||||
|
void ParseArguments(int argc, char *argv[], ARGPSTRUCT *argsps);
|
||||||
|
#define _DRIVERS_ARGH
|
||||||
|
#endif
|
|
@ -0,0 +1,523 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "../../driver.h"
|
||||||
|
|
||||||
|
static void GetString(char *s, int max)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
fgets(s,max,stdin);
|
||||||
|
|
||||||
|
for(x=0;x<max;x++)
|
||||||
|
if(s[x]=='\n')
|
||||||
|
{
|
||||||
|
s[x]=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get unsigned 16-bit integer from stdin in hex. */
|
||||||
|
static uint32 GetH16(unsigned int def)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
fgets(buf,32,stdin);
|
||||||
|
if(buf[0]=='\n')
|
||||||
|
return(def);
|
||||||
|
if(buf[0]=='$')
|
||||||
|
sscanf(buf+1,"%04x",&def);
|
||||||
|
else
|
||||||
|
sscanf(buf,"%04x",&def);
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get unsigned 8-bit integer from stdin in decimal. */
|
||||||
|
static uint8 Get8(unsigned int def)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
fgets(buf,32,stdin);
|
||||||
|
if(buf[0]=='\n')
|
||||||
|
return(def);
|
||||||
|
sscanf(buf,"%u",&def);
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetI(int def)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
fgets(buf,32,stdin);
|
||||||
|
if(buf[0]=='\n')
|
||||||
|
return(def);
|
||||||
|
sscanf(buf,"%d",&def);
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetYN(int def)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
printf("(Y/N)[%s]: ",def?"Y":"N");
|
||||||
|
fgets(buf,32,stdin);
|
||||||
|
if(buf[0]=='y' || buf[0]=='Y')
|
||||||
|
return(1);
|
||||||
|
if(buf[0]=='n' || buf[0]=='N')
|
||||||
|
return(0);
|
||||||
|
return(def);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Begin list code.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
static int listcount;
|
||||||
|
static int listids[16];
|
||||||
|
static int listsel;
|
||||||
|
static int mordoe;
|
||||||
|
|
||||||
|
void BeginListShow(void)
|
||||||
|
{
|
||||||
|
listcount=0;
|
||||||
|
listsel=-1;
|
||||||
|
mordoe=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hmm =0 for in list choices, hmm=1 for end of list choices. */
|
||||||
|
/* Return equals 0 to continue, -1 to stop, otherwise a number. */
|
||||||
|
int ListChoice(int hmm)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
if(!hmm)
|
||||||
|
{
|
||||||
|
int num=0;
|
||||||
|
|
||||||
|
tryagain:
|
||||||
|
printf(" <'Enter' to continue, (S)top, or enter a number.> ");
|
||||||
|
fgets(buf,32,stdin);
|
||||||
|
if(buf[0]=='s' || buf[0]=='S') return(-1);
|
||||||
|
if(buf[0]=='\n') return(0);
|
||||||
|
if(!sscanf(buf,"%d",&num))
|
||||||
|
return(0);
|
||||||
|
if(num<1) goto tryagain;
|
||||||
|
return(num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int num=0;
|
||||||
|
|
||||||
|
tryagain2:
|
||||||
|
printf(" <'Enter' to make no selection or enter a number.> ");
|
||||||
|
fgets(buf,32,stdin);
|
||||||
|
if(buf[0]=='\n') return(0);
|
||||||
|
if(!sscanf(buf,"%d",&num))
|
||||||
|
return(0);
|
||||||
|
if(num<1) goto tryagain2;
|
||||||
|
return(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int EndListShow(void)
|
||||||
|
{
|
||||||
|
if(mordoe)
|
||||||
|
{
|
||||||
|
int r=ListChoice(1);
|
||||||
|
if(r>0 && r<=listcount)
|
||||||
|
listsel=listids[r-1];
|
||||||
|
}
|
||||||
|
return(listsel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns 0 to stop listing, 1 to continue. */
|
||||||
|
int AddToList(char *text, uint32 id)
|
||||||
|
{
|
||||||
|
if(listcount==16)
|
||||||
|
{
|
||||||
|
int t=ListChoice(0);
|
||||||
|
mordoe=0;
|
||||||
|
if(t==-1) return(0); // Stop listing.
|
||||||
|
else if(t>0 && t<17)
|
||||||
|
{
|
||||||
|
listsel=listids[t-1];
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
listcount=0;
|
||||||
|
}
|
||||||
|
mordoe=1;
|
||||||
|
listids[listcount]=id;
|
||||||
|
printf("%2d) %s\n",listcount+1,text);
|
||||||
|
listcount++;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** End list code.
|
||||||
|
**/
|
||||||
|
|
||||||
|
typedef struct MENU {
|
||||||
|
char *text;
|
||||||
|
void *action;
|
||||||
|
int type; // 0 for menu, 1 for function.
|
||||||
|
} MENU;
|
||||||
|
|
||||||
|
static void SetOC(void)
|
||||||
|
{
|
||||||
|
FCEUI_CheatSearchSetCurrentAsOriginal();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UnhideEx(void)
|
||||||
|
{
|
||||||
|
FCEUI_CheatSearchShowExcluded();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ToggleCheat(int num)
|
||||||
|
{
|
||||||
|
printf("Cheat %d %sabled.\n",1+num,
|
||||||
|
FCEUI_ToggleCheat(num)?"en":"dis");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ModifyCheat(int num)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char buf[256];
|
||||||
|
uint32 A;
|
||||||
|
uint8 V;
|
||||||
|
int compare;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
int s;
|
||||||
|
int t;
|
||||||
|
|
||||||
|
FCEUI_GetCheat(num, &name, &A, &V, &compare, &s, &type);
|
||||||
|
|
||||||
|
printf("Name [%s]: ",name);
|
||||||
|
GetString(buf,256);
|
||||||
|
|
||||||
|
/* This obviously doesn't allow for cheats with no names. Bah. Who wants
|
||||||
|
nameless cheats anyway...
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(buf[0])
|
||||||
|
name=buf; // Change name when FCEUI_SetCheat() is called.
|
||||||
|
else
|
||||||
|
name=0; // Don't change name when FCEUI_SetCheat() is called.
|
||||||
|
|
||||||
|
printf("Address [$%04x]: ",(unsigned int)A);
|
||||||
|
A=GetH16(A);
|
||||||
|
|
||||||
|
printf("Value [%03d]: ",(unsigned int)V);
|
||||||
|
V=Get8(V);
|
||||||
|
|
||||||
|
printf("Compare [%3d]: ",compare);
|
||||||
|
compare=GetI(compare);
|
||||||
|
|
||||||
|
printf("Type(0=Old Style, 1=Read Substitute) [%1d]: ",type);
|
||||||
|
type=GetI(type)?1:0;
|
||||||
|
|
||||||
|
printf("Enable [%s]: ",s?"Y":"N");
|
||||||
|
t=getchar();
|
||||||
|
if(t=='Y' || t=='y') s=1;
|
||||||
|
else if(t=='N' || t=='n') s=0;
|
||||||
|
|
||||||
|
FCEUI_SetCheat(num,name,A,V,compare,s,type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void AddCheatGGPAR(int which)
|
||||||
|
{
|
||||||
|
uint16 A;
|
||||||
|
uint8 V;
|
||||||
|
int C;
|
||||||
|
int type;
|
||||||
|
char name[256],code[256];
|
||||||
|
|
||||||
|
printf("Name: ");
|
||||||
|
GetString(name,256);
|
||||||
|
|
||||||
|
printf("Code: ");
|
||||||
|
GetString(code,256);
|
||||||
|
|
||||||
|
printf("Add cheat \"%s\" for code \"%s\"?",name,code);
|
||||||
|
if(GetYN(0))
|
||||||
|
{
|
||||||
|
if(which)
|
||||||
|
{
|
||||||
|
if(!FCEUI_DecodePAR(code,&A,&V,&C,&type))
|
||||||
|
{
|
||||||
|
puts("Invalid Game Genie code.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!FCEUI_DecodeGG(code,&A,&V,&C))
|
||||||
|
{
|
||||||
|
puts("Invalid Game Genie code.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
type=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(FCEUI_AddCheat(name,A,V,C,type))
|
||||||
|
puts("Cheat added.");
|
||||||
|
else
|
||||||
|
puts("Error adding cheat.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddCheatGG(void)
|
||||||
|
{
|
||||||
|
AddCheatGGPAR(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddCheatPAR(void)
|
||||||
|
{
|
||||||
|
AddCheatGGPAR(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddCheatParam(uint32 A, uint8 V)
|
||||||
|
{
|
||||||
|
char name[256];
|
||||||
|
|
||||||
|
printf("Name: ");
|
||||||
|
GetString(name,256);
|
||||||
|
printf("Address [$%04x]: ",(unsigned int)A);
|
||||||
|
A=GetH16(A);
|
||||||
|
printf("Value [%03d]: ",(unsigned int)V);
|
||||||
|
V=Get8(V);
|
||||||
|
printf("Add cheat \"%s\" for address $%04x with value %03d?",name,(unsigned int)A,(unsigned int)V);
|
||||||
|
if(GetYN(0))
|
||||||
|
{
|
||||||
|
if(FCEUI_AddCheat(name,A,V,-1,0))
|
||||||
|
puts("Cheat added.");
|
||||||
|
else
|
||||||
|
puts("Error adding cheat.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddCheat(void)
|
||||||
|
{
|
||||||
|
AddCheatParam(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lid;
|
||||||
|
static int clistcallb(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data)
|
||||||
|
{
|
||||||
|
char tmp[512];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(compare>=0)
|
||||||
|
sprintf(tmp,"%s $%04x:%03d:%03d - %s",s?"*":" ",(unsigned int)a,(unsigned int)v,compare,name);
|
||||||
|
else
|
||||||
|
sprintf(tmp,"%s $%04x:%03d - %s",s?"*":" ",(unsigned int)a,(unsigned int)v,name);
|
||||||
|
if(type==1)
|
||||||
|
tmp[2]='S';
|
||||||
|
ret=AddToList(tmp,lid);
|
||||||
|
lid++;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ListCheats(void)
|
||||||
|
{
|
||||||
|
int which;
|
||||||
|
lid=0;
|
||||||
|
|
||||||
|
BeginListShow();
|
||||||
|
FCEUI_ListCheats(clistcallb,0);
|
||||||
|
which=EndListShow();
|
||||||
|
if(which>=0)
|
||||||
|
{
|
||||||
|
char tmp[32];
|
||||||
|
printf(" <(T)oggle status, (M)odify, or (D)elete this cheat.> ");
|
||||||
|
fgets(tmp,32,stdin);
|
||||||
|
switch(tolower(tmp[0]))
|
||||||
|
{
|
||||||
|
case 't':ToggleCheat(which);
|
||||||
|
break;
|
||||||
|
case 'd':if(!FCEUI_DelCheat(which))
|
||||||
|
puts("Error deleting cheat!");
|
||||||
|
else
|
||||||
|
puts("Cheat has been deleted.");
|
||||||
|
break;
|
||||||
|
case 'm':ModifyCheat(which);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResetSearch(void)
|
||||||
|
{
|
||||||
|
FCEUI_CheatSearchBegin();
|
||||||
|
puts("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int srescallb(uint32 a, uint8 last, uint8 current, void *data)
|
||||||
|
{
|
||||||
|
char tmp[13];
|
||||||
|
sprintf(tmp, "$%04x:%03d:%03d",(unsigned int)a,(unsigned int)last,(unsigned int)current);
|
||||||
|
return(AddToList(tmp,a));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ShowRes(void)
|
||||||
|
{
|
||||||
|
int n=FCEUI_CheatSearchGetCount();
|
||||||
|
printf(" %d results:\n",n);
|
||||||
|
if(n)
|
||||||
|
{
|
||||||
|
int which;
|
||||||
|
BeginListShow();
|
||||||
|
FCEUI_CheatSearchGet(srescallb,0);
|
||||||
|
which=EndListShow();
|
||||||
|
if(which>=0)
|
||||||
|
AddCheatParam(which,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ShowShortList(char *moe[], int n, int def)
|
||||||
|
{
|
||||||
|
int x,c;
|
||||||
|
unsigned int baa;
|
||||||
|
char tmp[16];
|
||||||
|
|
||||||
|
red:
|
||||||
|
for(x=0;x<n;x++)
|
||||||
|
printf("%d) %s\n",x+1,moe[x]);
|
||||||
|
puts("D) Display List");
|
||||||
|
clo:
|
||||||
|
|
||||||
|
printf("\nSelection [%d]> ",def+1);
|
||||||
|
fgets(tmp,256,stdin);
|
||||||
|
if(tmp[0]=='\n')
|
||||||
|
return def;
|
||||||
|
c=tolower(tmp[0]);
|
||||||
|
baa=c-'1';
|
||||||
|
|
||||||
|
if(baa<n)
|
||||||
|
return baa;
|
||||||
|
else if(c=='d')
|
||||||
|
goto red;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("Invalid selection.");
|
||||||
|
goto clo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DoSearch(void)
|
||||||
|
{
|
||||||
|
static int v1=0,v2=0;
|
||||||
|
static int method=0;
|
||||||
|
char *m[6]={"O==V1 && C==V2","O==V1 && |O-C|==V2","|O-C|==V2","O!=C","Value decreased","Value increased"};
|
||||||
|
printf("\nSearch Filter:\n");
|
||||||
|
|
||||||
|
method=ShowShortList(m,6,method);
|
||||||
|
if(method<=1)
|
||||||
|
{
|
||||||
|
printf("V1 [%03d]: ",v1);
|
||||||
|
v1=Get8(v1);
|
||||||
|
}
|
||||||
|
if(method<=2)
|
||||||
|
{
|
||||||
|
printf("V2 [%03d]: ",v2);
|
||||||
|
v2=Get8(v2);
|
||||||
|
}
|
||||||
|
FCEUI_CheatSearchEnd(method,v1,v2);
|
||||||
|
puts("Search completed.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static MENU NewCheatsMenu[]={
|
||||||
|
{"Add Cheat",(void *)AddCheat,1},
|
||||||
|
{"Reset Search",(void *)ResetSearch,1},
|
||||||
|
{"Do Search",(void *)DoSearch,1},
|
||||||
|
{"Set Original to Current",(void *)SetOC,1},
|
||||||
|
{"Unhide Excluded",(void *)UnhideEx,1},
|
||||||
|
{"Show Results",(void *)ShowRes,1},
|
||||||
|
{"Add Game Genie Cheat",(void *)AddCheatGG,1},
|
||||||
|
{"Add PAR Cheat",(void *)AddCheatPAR,1},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static MENU MainMenu[]={
|
||||||
|
{"List Cheats",(void *)ListCheats,1},
|
||||||
|
{"New Cheats...",(void *)NewCheatsMenu,0},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void DoMenu(MENU *men)
|
||||||
|
{
|
||||||
|
int x=0;
|
||||||
|
|
||||||
|
redisplay:
|
||||||
|
x=0;
|
||||||
|
puts("");
|
||||||
|
while(men[x].text)
|
||||||
|
{
|
||||||
|
printf("%d) %s\n",x+1,men[x].text);
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
puts("D) Display Menu\nX) Return to Previous\n");
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
int c;
|
||||||
|
|
||||||
|
recommand:
|
||||||
|
printf("Command> ");
|
||||||
|
fgets(buf,32,stdin);
|
||||||
|
c=tolower(buf[0]);
|
||||||
|
if(c=='\n')
|
||||||
|
goto recommand;
|
||||||
|
else if(c=='d')
|
||||||
|
goto redisplay;
|
||||||
|
else if(c=='x')
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(sscanf(buf,"%d",&c))
|
||||||
|
{
|
||||||
|
if(c>x) goto invalid;
|
||||||
|
if(men[c-1].type)
|
||||||
|
{
|
||||||
|
void (*func)(void)=(void(*)())men[c-1].action;
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoMenu((MENU*)men[c-1].action); /* Mmm...recursivey goodness. */
|
||||||
|
goto redisplay;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
invalid:
|
||||||
|
puts("Invalid command.\n");
|
||||||
|
goto recommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoConsoleCheatConfig(void)
|
||||||
|
{
|
||||||
|
MENU *curmenu=MainMenu;
|
||||||
|
|
||||||
|
DoMenu(curmenu);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
void DoConsoleCheatConfig(void);
|
|
@ -0,0 +1,152 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
/* FCE Ultra */
|
||||||
|
/* */
|
||||||
|
/* This file contains routines for reading/writing the */
|
||||||
|
/* configuration file. */
|
||||||
|
/* */
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../../types.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
static int FReadString(FILE *fp, char *str, int n)
|
||||||
|
{
|
||||||
|
int x=0,z;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
z=fgetc(fp);
|
||||||
|
str[x]=z;
|
||||||
|
x++;
|
||||||
|
if(z<=0) break;
|
||||||
|
if(x>=n) return 0;
|
||||||
|
}
|
||||||
|
if(z<0) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetValueR(FILE *fp, char *str, void *v, int c)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
int s;
|
||||||
|
|
||||||
|
while(FReadString(fp,buf,256))
|
||||||
|
{
|
||||||
|
fread(&s,1,4,fp);
|
||||||
|
if(!strcmp(str, buf))
|
||||||
|
{
|
||||||
|
if(!c) // String, allocate some memory.
|
||||||
|
{
|
||||||
|
if(!(*(char **)v=(char*)malloc(s)))
|
||||||
|
goto gogl;
|
||||||
|
fread(*(char **)v,1,s,fp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if(s>c || s<c)
|
||||||
|
{
|
||||||
|
gogl:
|
||||||
|
fseek(fp,s,SEEK_CUR);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fread((uint8*)v,1,c,fp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fseek(fp,s,SEEK_CUR);
|
||||||
|
}
|
||||||
|
fseek(fp,4,SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetValueR(FILE *fp, char *str, void *v, int c)
|
||||||
|
{
|
||||||
|
fwrite(str,1,strlen(str)+1,fp);
|
||||||
|
fwrite((uint8*)&c,1,4,fp);
|
||||||
|
fwrite((uint8*)v,1,c,fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SaveParse(CFGSTRUCT *cfgst, FILE *fp)
|
||||||
|
{
|
||||||
|
int x=0;
|
||||||
|
|
||||||
|
while(cfgst[x].ptr)
|
||||||
|
{
|
||||||
|
if(!cfgst[x].name) // Link to new config structure
|
||||||
|
{
|
||||||
|
SaveParse((CFGSTRUCT*)cfgst[x].ptr,fp); // Recursion is sexy. I could
|
||||||
|
// save a little stack space if I made
|
||||||
|
// the file pointer a non-local
|
||||||
|
// variable...
|
||||||
|
x++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cfgst[x].len) // Plain data
|
||||||
|
SetValueR(fp,cfgst[x].name,cfgst[x].ptr,cfgst[x].len);
|
||||||
|
else // String
|
||||||
|
if(*(char **)cfgst[x].ptr) // Only save it if there IS a string.
|
||||||
|
SetValueR(fp,cfgst[x].name,*(char **)cfgst[x].ptr,
|
||||||
|
strlen(*(char **)cfgst[x].ptr)+1);
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveFCEUConfig(char *filename, CFGSTRUCT *cfgst)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp=fopen(filename,"wb");
|
||||||
|
if(fp==NULL) return;
|
||||||
|
|
||||||
|
SaveParse(cfgst,fp);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LoadParse(CFGSTRUCT *cfgst, FILE *fp)
|
||||||
|
{
|
||||||
|
int x=0;
|
||||||
|
|
||||||
|
while(cfgst[x].ptr)
|
||||||
|
{
|
||||||
|
if(!cfgst[x].name) // Link to new config structure
|
||||||
|
{
|
||||||
|
LoadParse((CFGSTRUCT*)cfgst[x].ptr,fp);
|
||||||
|
x++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
GetValueR(fp,cfgst[x].name,cfgst[x].ptr,cfgst[x].len);
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadFCEUConfig(char *filename, CFGSTRUCT *cfgst)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp=fopen(filename,"rb");
|
||||||
|
if(fp==NULL) return;
|
||||||
|
LoadParse(cfgst,fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef _DRIVERS_CONFIGH
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
void *ptr;
|
||||||
|
int len;
|
||||||
|
} CFGSTRUCT;
|
||||||
|
|
||||||
|
void SaveFCEUConfig(char *filename, CFGSTRUCT *cfgst);
|
||||||
|
void LoadFCEUConfig(char *filename, CFGSTRUCT *cfgst);
|
||||||
|
|
||||||
|
/* Macros for building CFGSTRUCT structures. */
|
||||||
|
|
||||||
|
/* CFGSTRUCT structures must always end with ENDCFGSTRUCT */
|
||||||
|
#define ENDCFGSTRUCT { 0,0,0 }
|
||||||
|
|
||||||
|
/* When this macro is used, the config loading/saving code will parse
|
||||||
|
the new config structure until the end of it is detected, then it
|
||||||
|
will continue parsing the original config structure.
|
||||||
|
*/
|
||||||
|
#define ADDCFGSTRUCT(x) { 0,&x,0 }
|
||||||
|
|
||||||
|
/* Oops. The NAC* macros shouldn't have the # in front of the w, but
|
||||||
|
fixing this would break configuration files of previous versions and it
|
||||||
|
isn't really hurting much.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Single piece of data(integer). */
|
||||||
|
#define AC(x) { #x,&x,sizeof(x)}
|
||||||
|
#define NAC(w,x) { #w,&x,sizeof(x)}
|
||||||
|
|
||||||
|
/* Array. */
|
||||||
|
#define ACA(x) {#x,x,sizeof(x)}
|
||||||
|
#define NACA(w,x) {#w,x,sizeof(x)}
|
||||||
|
|
||||||
|
/* String(pointer) with automatic memory allocation. */
|
||||||
|
#define ACS(x) {#x,&x,0}
|
||||||
|
#define NACS(w,x) {#w,&x,0}
|
||||||
|
|
||||||
|
#define _DRIVERS_CONFIGH
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,4 @@
|
||||||
|
void hq2x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL);
|
||||||
|
int hq2x_InitLUTs(void);
|
||||||
|
void hq2x_Kill(void);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,4 @@
|
||||||
|
void hq3x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL);
|
||||||
|
int hq3x_InitLUTs(void);
|
||||||
|
void hq3x_Kill(void);
|
||||||
|
|
|
@ -0,0 +1,923 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Scale2x project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||||
|
*
|
||||||
|
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains a C and MMX implementation of the Scale2x effect.
|
||||||
|
*
|
||||||
|
* You can find an high level description of the effect at :
|
||||||
|
*
|
||||||
|
* http://scale2x.sourceforge.net/
|
||||||
|
*
|
||||||
|
* Alternatively at the previous license terms, you are allowed to use this
|
||||||
|
* code in your program with these conditions:
|
||||||
|
* - the program is not used in commercial activities.
|
||||||
|
* - the whole source code of the program is released with the binary.
|
||||||
|
* - derivative works of the program are allowed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "scale2x.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Scale2x C implementation */
|
||||||
|
|
||||||
|
static inline void scale2x_8_def_single(scale2x_uint8* __restrict__ dst, const scale2x_uint8* __restrict__ src0, const scale2x_uint8* __restrict__ src1, const scale2x_uint8* __restrict__ src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
/* first pixel */
|
||||||
|
dst[0] = src1[0];
|
||||||
|
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[1] = src0[0];
|
||||||
|
else
|
||||||
|
dst[1] = src1[0];
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 2;
|
||||||
|
|
||||||
|
/* central pixels */
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||||
|
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||||
|
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 2;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last pixel */
|
||||||
|
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[0] = src0[0];
|
||||||
|
else
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scale2x_16_def_single(scale2x_uint16* __restrict__ dst, const scale2x_uint16* __restrict__ src0, const scale2x_uint16* __restrict__ src1, const scale2x_uint16* __restrict__ src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
/* first pixel */
|
||||||
|
dst[0] = src1[0];
|
||||||
|
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[1] = src0[0];
|
||||||
|
else
|
||||||
|
dst[1] = src1[0];
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 2;
|
||||||
|
|
||||||
|
/* central pixels */
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||||
|
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||||
|
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 2;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last pixel */
|
||||||
|
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[0] = src0[0];
|
||||||
|
else
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scale2x_32_def_single(scale2x_uint32* __restrict__ dst, const scale2x_uint32* __restrict__ src0, const scale2x_uint32* __restrict__ src1, const scale2x_uint32* __restrict__ src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
/* first pixel */
|
||||||
|
dst[0] = src1[0];
|
||||||
|
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[1] = src0[0];
|
||||||
|
else
|
||||||
|
dst[1] = src1[0];
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 2;
|
||||||
|
|
||||||
|
/* central pixels */
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||||
|
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||||
|
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 2;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last pixel */
|
||||||
|
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[0] = src0[0];
|
||||||
|
else
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale by a factor of 2 a row of pixels of 8 bits.
|
||||||
|
* The function is implemented in C.
|
||||||
|
* The pixels over the left and right borders are assumed of the same color of
|
||||||
|
* the pixels on the border.
|
||||||
|
* \param src0 Pointer at the first pixel of the previous row.
|
||||||
|
* \param src1 Pointer at the first pixel of the current row.
|
||||||
|
* \param src2 Pointer at the first pixel of the next row.
|
||||||
|
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||||
|
* It must be at least 2.
|
||||||
|
* \param dst0 First destination row, double length in pixels.
|
||||||
|
* \param dst1 Second destination row, double length in pixels.
|
||||||
|
*/
|
||||||
|
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
scale2x_8_def_single(dst0, src0, src1, src2, count);
|
||||||
|
scale2x_8_def_single(dst1, src2, src1, src0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale by a factor of 2 a row of pixels of 16 bits.
|
||||||
|
* This function operates like scale2x_8_def() but for 16 bits pixels.
|
||||||
|
* \param src0 Pointer at the first pixel of the previous row.
|
||||||
|
* \param src1 Pointer at the first pixel of the current row.
|
||||||
|
* \param src2 Pointer at the first pixel of the next row.
|
||||||
|
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||||
|
* It must be at least 2.
|
||||||
|
* \param dst0 First destination row, double length in pixels.
|
||||||
|
* \param dst1 Second destination row, double length in pixels.
|
||||||
|
*/
|
||||||
|
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
scale2x_16_def_single(dst0, src0, src1, src2, count);
|
||||||
|
scale2x_16_def_single(dst1, src2, src1, src0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale by a factor of 2 a row of pixels of 32 bits.
|
||||||
|
* This function operates like scale2x_8_def() but for 32 bits pixels.
|
||||||
|
* \param src0 Pointer at the first pixel of the previous row.
|
||||||
|
* \param src1 Pointer at the first pixel of the current row.
|
||||||
|
* \param src2 Pointer at the first pixel of the next row.
|
||||||
|
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||||
|
* It must be at least 2.
|
||||||
|
* \param dst0 First destination row, double length in pixels.
|
||||||
|
* \param dst1 Second destination row, double length in pixels.
|
||||||
|
*/
|
||||||
|
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
scale2x_32_def_single(dst0, src0, src1, src2, count);
|
||||||
|
scale2x_32_def_single(dst1, src2, src1, src0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Scale2x MMX implementation */
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__i386__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apply the Scale2x effect at a single row.
|
||||||
|
* This function must be called only by the other scale2x functions.
|
||||||
|
*
|
||||||
|
* Considering the pixel map :
|
||||||
|
*
|
||||||
|
* ABC (src0)
|
||||||
|
* DEF (src1)
|
||||||
|
* GHI (src2)
|
||||||
|
*
|
||||||
|
* this functions compute 2 new pixels in substitution of the source pixel E
|
||||||
|
* like this map :
|
||||||
|
*
|
||||||
|
* ab (dst)
|
||||||
|
*
|
||||||
|
* with these variables :
|
||||||
|
*
|
||||||
|
* ¤t -> E
|
||||||
|
* ¤t_left -> D
|
||||||
|
* ¤t_right -> F
|
||||||
|
* ¤t_upper -> B
|
||||||
|
* ¤t_lower -> H
|
||||||
|
*
|
||||||
|
* %0 -> current_upper
|
||||||
|
* %1 -> current
|
||||||
|
* %2 -> current_lower
|
||||||
|
* %3 -> dst
|
||||||
|
* %4 -> counter
|
||||||
|
*
|
||||||
|
* %mm0 -> *current_left
|
||||||
|
* %mm1 -> *current_next
|
||||||
|
* %mm2 -> tmp0
|
||||||
|
* %mm3 -> tmp1
|
||||||
|
* %mm4 -> tmp2
|
||||||
|
* %mm5 -> tmp3
|
||||||
|
* %mm6 -> *current_upper
|
||||||
|
* %mm7 -> *current
|
||||||
|
*/
|
||||||
|
static inline void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 16);
|
||||||
|
assert(count % 8 == 0);
|
||||||
|
|
||||||
|
/* always do the first and last run */
|
||||||
|
count -= 2*8;
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
/* first run */
|
||||||
|
/* set the current, current_pre, current_next registers */
|
||||||
|
"movq 0(%1), %%mm0\n"
|
||||||
|
"movq 0(%1), %%mm7\n"
|
||||||
|
"movq 8(%1), %%mm1\n"
|
||||||
|
"psllq $56, %%mm0\n"
|
||||||
|
"psllq $56, %%mm1\n"
|
||||||
|
"psrlq $56, %%mm0\n"
|
||||||
|
"movq %%mm7, %%mm2\n"
|
||||||
|
"movq %%mm7, %%mm3\n"
|
||||||
|
"psllq $8, %%mm2\n"
|
||||||
|
"psrlq $8, %%mm3\n"
|
||||||
|
"por %%mm2, %%mm0\n"
|
||||||
|
"por %%mm3, %%mm1\n"
|
||||||
|
|
||||||
|
/* current_upper */
|
||||||
|
"movq (%0), %%mm6\n"
|
||||||
|
|
||||||
|
/* compute the upper-left pixel for dst on %%mm2 */
|
||||||
|
/* compute the upper-right pixel for dst on %%mm4 */
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"movq %%mm0, %%mm3\n"
|
||||||
|
"movq %%mm1, %%mm5\n"
|
||||||
|
"pcmpeqb %%mm6, %%mm2\n"
|
||||||
|
"pcmpeqb %%mm6, %%mm4\n"
|
||||||
|
"pcmpeqb (%2), %%mm3\n"
|
||||||
|
"pcmpeqb (%2), %%mm5\n"
|
||||||
|
"pandn %%mm2, %%mm3\n"
|
||||||
|
"pandn %%mm4, %%mm5\n"
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"pcmpeqb %%mm1, %%mm2\n"
|
||||||
|
"pcmpeqb %%mm0, %%mm4\n"
|
||||||
|
"pandn %%mm3, %%mm2\n"
|
||||||
|
"pandn %%mm5, %%mm4\n"
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"movq %%mm4, %%mm5\n"
|
||||||
|
"pand %%mm6, %%mm2\n"
|
||||||
|
"pand %%mm6, %%mm4\n"
|
||||||
|
"pandn %%mm7, %%mm3\n"
|
||||||
|
"pandn %%mm7, %%mm5\n"
|
||||||
|
"por %%mm3, %%mm2\n"
|
||||||
|
"por %%mm5, %%mm4\n"
|
||||||
|
|
||||||
|
/* set *dst */
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"punpcklbw %%mm4, %%mm2\n"
|
||||||
|
"punpckhbw %%mm4, %%mm3\n"
|
||||||
|
"movq %%mm2, (%3)\n"
|
||||||
|
"movq %%mm3, 8(%3)\n"
|
||||||
|
|
||||||
|
/* next */
|
||||||
|
"addl $8, %0\n"
|
||||||
|
"addl $8, %1\n"
|
||||||
|
"addl $8, %2\n"
|
||||||
|
"addl $16, %3\n"
|
||||||
|
|
||||||
|
/* central runs */
|
||||||
|
"shrl $3, %4\n"
|
||||||
|
"jz 1f\n"
|
||||||
|
|
||||||
|
"0:\n"
|
||||||
|
|
||||||
|
/* set the current, current_pre, current_next registers */
|
||||||
|
"movq -8(%1), %%mm0\n"
|
||||||
|
"movq (%1), %%mm7\n"
|
||||||
|
"movq 8(%1), %%mm1\n"
|
||||||
|
"psrlq $56, %%mm0\n"
|
||||||
|
"psllq $56, %%mm1\n"
|
||||||
|
"movq %%mm7, %%mm2\n"
|
||||||
|
"movq %%mm7, %%mm3\n"
|
||||||
|
"psllq $8, %%mm2\n"
|
||||||
|
"psrlq $8, %%mm3\n"
|
||||||
|
"por %%mm2, %%mm0\n"
|
||||||
|
"por %%mm3, %%mm1\n"
|
||||||
|
|
||||||
|
/* current_upper */
|
||||||
|
"movq (%0), %%mm6\n"
|
||||||
|
|
||||||
|
/* compute the upper-left pixel for dst on %%mm2 */
|
||||||
|
/* compute the upper-right pixel for dst on %%mm4 */
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"movq %%mm0, %%mm3\n"
|
||||||
|
"movq %%mm1, %%mm5\n"
|
||||||
|
"pcmpeqb %%mm6, %%mm2\n"
|
||||||
|
"pcmpeqb %%mm6, %%mm4\n"
|
||||||
|
"pcmpeqb (%2), %%mm3\n"
|
||||||
|
"pcmpeqb (%2), %%mm5\n"
|
||||||
|
"pandn %%mm2, %%mm3\n"
|
||||||
|
"pandn %%mm4, %%mm5\n"
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"pcmpeqb %%mm1, %%mm2\n"
|
||||||
|
"pcmpeqb %%mm0, %%mm4\n"
|
||||||
|
"pandn %%mm3, %%mm2\n"
|
||||||
|
"pandn %%mm5, %%mm4\n"
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"movq %%mm4, %%mm5\n"
|
||||||
|
"pand %%mm6, %%mm2\n"
|
||||||
|
"pand %%mm6, %%mm4\n"
|
||||||
|
"pandn %%mm7, %%mm3\n"
|
||||||
|
"pandn %%mm7, %%mm5\n"
|
||||||
|
"por %%mm3, %%mm2\n"
|
||||||
|
"por %%mm5, %%mm4\n"
|
||||||
|
|
||||||
|
/* set *dst */
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"punpcklbw %%mm4, %%mm2\n"
|
||||||
|
"punpckhbw %%mm4, %%mm3\n"
|
||||||
|
"movq %%mm2, (%3)\n"
|
||||||
|
"movq %%mm3, 8(%3)\n"
|
||||||
|
|
||||||
|
/* next */
|
||||||
|
"addl $8, %0\n"
|
||||||
|
"addl $8, %1\n"
|
||||||
|
"addl $8, %2\n"
|
||||||
|
"addl $16, %3\n"
|
||||||
|
|
||||||
|
"decl %4\n"
|
||||||
|
"jnz 0b\n"
|
||||||
|
"1:\n"
|
||||||
|
|
||||||
|
/* final run */
|
||||||
|
/* set the current, current_pre, current_next registers */
|
||||||
|
"movq (%1), %%mm1\n"
|
||||||
|
"movq (%1), %%mm7\n"
|
||||||
|
"movq -8(%1), %%mm0\n"
|
||||||
|
"psrlq $56, %%mm1\n"
|
||||||
|
"psrlq $56, %%mm0\n"
|
||||||
|
"psllq $56, %%mm1\n"
|
||||||
|
"movq %%mm7, %%mm2\n"
|
||||||
|
"movq %%mm7, %%mm3\n"
|
||||||
|
"psllq $8, %%mm2\n"
|
||||||
|
"psrlq $8, %%mm3\n"
|
||||||
|
"por %%mm2, %%mm0\n"
|
||||||
|
"por %%mm3, %%mm1\n"
|
||||||
|
|
||||||
|
/* current_upper */
|
||||||
|
"movq (%0), %%mm6\n"
|
||||||
|
|
||||||
|
/* compute the upper-left pixel for dst on %%mm2 */
|
||||||
|
/* compute the upper-right pixel for dst on %%mm4 */
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"movq %%mm0, %%mm3\n"
|
||||||
|
"movq %%mm1, %%mm5\n"
|
||||||
|
"pcmpeqb %%mm6, %%mm2\n"
|
||||||
|
"pcmpeqb %%mm6, %%mm4\n"
|
||||||
|
"pcmpeqb (%2), %%mm3\n"
|
||||||
|
"pcmpeqb (%2), %%mm5\n"
|
||||||
|
"pandn %%mm2, %%mm3\n"
|
||||||
|
"pandn %%mm4, %%mm5\n"
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"pcmpeqb %%mm1, %%mm2\n"
|
||||||
|
"pcmpeqb %%mm0, %%mm4\n"
|
||||||
|
"pandn %%mm3, %%mm2\n"
|
||||||
|
"pandn %%mm5, %%mm4\n"
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"movq %%mm4, %%mm5\n"
|
||||||
|
"pand %%mm6, %%mm2\n"
|
||||||
|
"pand %%mm6, %%mm4\n"
|
||||||
|
"pandn %%mm7, %%mm3\n"
|
||||||
|
"pandn %%mm7, %%mm5\n"
|
||||||
|
"por %%mm3, %%mm2\n"
|
||||||
|
"por %%mm5, %%mm4\n"
|
||||||
|
|
||||||
|
/* set *dst */
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"punpcklbw %%mm4, %%mm2\n"
|
||||||
|
"punpckhbw %%mm4, %%mm3\n"
|
||||||
|
"movq %%mm2, (%3)\n"
|
||||||
|
"movq %%mm3, 8(%3)\n"
|
||||||
|
|
||||||
|
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
|
||||||
|
:
|
||||||
|
: "cc"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scale2x_16_mmx_single(scale2x_uint16* dst, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 8);
|
||||||
|
assert(count % 4 == 0);
|
||||||
|
|
||||||
|
/* always do the first and last run */
|
||||||
|
count -= 2*4;
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
/* first run */
|
||||||
|
/* set the current, current_pre, current_next registers */
|
||||||
|
"movq 0(%1), %%mm0\n"
|
||||||
|
"movq 0(%1), %%mm7\n"
|
||||||
|
"movq 8(%1), %%mm1\n"
|
||||||
|
"psllq $48, %%mm0\n"
|
||||||
|
"psllq $48, %%mm1\n"
|
||||||
|
"psrlq $48, %%mm0\n"
|
||||||
|
"movq %%mm7, %%mm2\n"
|
||||||
|
"movq %%mm7, %%mm3\n"
|
||||||
|
"psllq $16, %%mm2\n"
|
||||||
|
"psrlq $16, %%mm3\n"
|
||||||
|
"por %%mm2, %%mm0\n"
|
||||||
|
"por %%mm3, %%mm1\n"
|
||||||
|
|
||||||
|
/* current_upper */
|
||||||
|
"movq (%0), %%mm6\n"
|
||||||
|
|
||||||
|
/* compute the upper-left pixel for dst on %%mm2 */
|
||||||
|
/* compute the upper-right pixel for dst on %%mm4 */
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"movq %%mm0, %%mm3\n"
|
||||||
|
"movq %%mm1, %%mm5\n"
|
||||||
|
"pcmpeqw %%mm6, %%mm2\n"
|
||||||
|
"pcmpeqw %%mm6, %%mm4\n"
|
||||||
|
"pcmpeqw (%2), %%mm3\n"
|
||||||
|
"pcmpeqw (%2), %%mm5\n"
|
||||||
|
"pandn %%mm2, %%mm3\n"
|
||||||
|
"pandn %%mm4, %%mm5\n"
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"pcmpeqw %%mm1, %%mm2\n"
|
||||||
|
"pcmpeqw %%mm0, %%mm4\n"
|
||||||
|
"pandn %%mm3, %%mm2\n"
|
||||||
|
"pandn %%mm5, %%mm4\n"
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"movq %%mm4, %%mm5\n"
|
||||||
|
"pand %%mm6, %%mm2\n"
|
||||||
|
"pand %%mm6, %%mm4\n"
|
||||||
|
"pandn %%mm7, %%mm3\n"
|
||||||
|
"pandn %%mm7, %%mm5\n"
|
||||||
|
"por %%mm3, %%mm2\n"
|
||||||
|
"por %%mm5, %%mm4\n"
|
||||||
|
|
||||||
|
/* set *dst */
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"punpcklwd %%mm4, %%mm2\n"
|
||||||
|
"punpckhwd %%mm4, %%mm3\n"
|
||||||
|
"movq %%mm2, (%3)\n"
|
||||||
|
"movq %%mm3, 8(%3)\n"
|
||||||
|
|
||||||
|
/* next */
|
||||||
|
"addl $8, %0\n"
|
||||||
|
"addl $8, %1\n"
|
||||||
|
"addl $8, %2\n"
|
||||||
|
"addl $16, %3\n"
|
||||||
|
|
||||||
|
/* central runs */
|
||||||
|
"shrl $2, %4\n"
|
||||||
|
"jz 1f\n"
|
||||||
|
|
||||||
|
"0:\n"
|
||||||
|
|
||||||
|
/* set the current, current_pre, current_next registers */
|
||||||
|
"movq -8(%1), %%mm0\n"
|
||||||
|
"movq (%1), %%mm7\n"
|
||||||
|
"movq 8(%1), %%mm1\n"
|
||||||
|
"psrlq $48, %%mm0\n"
|
||||||
|
"psllq $48, %%mm1\n"
|
||||||
|
"movq %%mm7, %%mm2\n"
|
||||||
|
"movq %%mm7, %%mm3\n"
|
||||||
|
"psllq $16, %%mm2\n"
|
||||||
|
"psrlq $16, %%mm3\n"
|
||||||
|
"por %%mm2, %%mm0\n"
|
||||||
|
"por %%mm3, %%mm1\n"
|
||||||
|
|
||||||
|
/* current_upper */
|
||||||
|
"movq (%0), %%mm6\n"
|
||||||
|
|
||||||
|
/* compute the upper-left pixel for dst on %%mm2 */
|
||||||
|
/* compute the upper-right pixel for dst on %%mm4 */
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"movq %%mm0, %%mm3\n"
|
||||||
|
"movq %%mm1, %%mm5\n"
|
||||||
|
"pcmpeqw %%mm6, %%mm2\n"
|
||||||
|
"pcmpeqw %%mm6, %%mm4\n"
|
||||||
|
"pcmpeqw (%2), %%mm3\n"
|
||||||
|
"pcmpeqw (%2), %%mm5\n"
|
||||||
|
"pandn %%mm2, %%mm3\n"
|
||||||
|
"pandn %%mm4, %%mm5\n"
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"pcmpeqw %%mm1, %%mm2\n"
|
||||||
|
"pcmpeqw %%mm0, %%mm4\n"
|
||||||
|
"pandn %%mm3, %%mm2\n"
|
||||||
|
"pandn %%mm5, %%mm4\n"
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"movq %%mm4, %%mm5\n"
|
||||||
|
"pand %%mm6, %%mm2\n"
|
||||||
|
"pand %%mm6, %%mm4\n"
|
||||||
|
"pandn %%mm7, %%mm3\n"
|
||||||
|
"pandn %%mm7, %%mm5\n"
|
||||||
|
"por %%mm3, %%mm2\n"
|
||||||
|
"por %%mm5, %%mm4\n"
|
||||||
|
|
||||||
|
/* set *dst */
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"punpcklwd %%mm4, %%mm2\n"
|
||||||
|
"punpckhwd %%mm4, %%mm3\n"
|
||||||
|
"movq %%mm2, (%3)\n"
|
||||||
|
"movq %%mm3, 8(%3)\n"
|
||||||
|
|
||||||
|
/* next */
|
||||||
|
"addl $8, %0\n"
|
||||||
|
"addl $8, %1\n"
|
||||||
|
"addl $8, %2\n"
|
||||||
|
"addl $16, %3\n"
|
||||||
|
|
||||||
|
"decl %4\n"
|
||||||
|
"jnz 0b\n"
|
||||||
|
"1:\n"
|
||||||
|
|
||||||
|
/* final run */
|
||||||
|
/* set the current, current_pre, current_next registers */
|
||||||
|
"movq (%1), %%mm1\n"
|
||||||
|
"movq (%1), %%mm7\n"
|
||||||
|
"movq -8(%1), %%mm0\n"
|
||||||
|
"psrlq $48, %%mm1\n"
|
||||||
|
"psrlq $48, %%mm0\n"
|
||||||
|
"psllq $48, %%mm1\n"
|
||||||
|
"movq %%mm7, %%mm2\n"
|
||||||
|
"movq %%mm7, %%mm3\n"
|
||||||
|
"psllq $16, %%mm2\n"
|
||||||
|
"psrlq $16, %%mm3\n"
|
||||||
|
"por %%mm2, %%mm0\n"
|
||||||
|
"por %%mm3, %%mm1\n"
|
||||||
|
|
||||||
|
/* current_upper */
|
||||||
|
"movq (%0), %%mm6\n"
|
||||||
|
|
||||||
|
/* compute the upper-left pixel for dst on %%mm2 */
|
||||||
|
/* compute the upper-right pixel for dst on %%mm4 */
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"movq %%mm0, %%mm3\n"
|
||||||
|
"movq %%mm1, %%mm5\n"
|
||||||
|
"pcmpeqw %%mm6, %%mm2\n"
|
||||||
|
"pcmpeqw %%mm6, %%mm4\n"
|
||||||
|
"pcmpeqw (%2), %%mm3\n"
|
||||||
|
"pcmpeqw (%2), %%mm5\n"
|
||||||
|
"pandn %%mm2, %%mm3\n"
|
||||||
|
"pandn %%mm4, %%mm5\n"
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"pcmpeqw %%mm1, %%mm2\n"
|
||||||
|
"pcmpeqw %%mm0, %%mm4\n"
|
||||||
|
"pandn %%mm3, %%mm2\n"
|
||||||
|
"pandn %%mm5, %%mm4\n"
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"movq %%mm4, %%mm5\n"
|
||||||
|
"pand %%mm6, %%mm2\n"
|
||||||
|
"pand %%mm6, %%mm4\n"
|
||||||
|
"pandn %%mm7, %%mm3\n"
|
||||||
|
"pandn %%mm7, %%mm5\n"
|
||||||
|
"por %%mm3, %%mm2\n"
|
||||||
|
"por %%mm5, %%mm4\n"
|
||||||
|
|
||||||
|
/* set *dst */
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"punpcklwd %%mm4, %%mm2\n"
|
||||||
|
"punpckhwd %%mm4, %%mm3\n"
|
||||||
|
"movq %%mm2, (%3)\n"
|
||||||
|
"movq %%mm3, 8(%3)\n"
|
||||||
|
|
||||||
|
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
|
||||||
|
:
|
||||||
|
: "cc"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scale2x_32_mmx_single(scale2x_uint32* dst, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 4);
|
||||||
|
assert(count % 2 == 0);
|
||||||
|
|
||||||
|
/* always do the first and last run */
|
||||||
|
count -= 2*2;
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
/* first run */
|
||||||
|
/* set the current, current_pre, current_next registers */
|
||||||
|
"movq 0(%1), %%mm0\n"
|
||||||
|
"movq 0(%1), %%mm7\n"
|
||||||
|
"movq 8(%1), %%mm1\n"
|
||||||
|
"psllq $32, %%mm0\n"
|
||||||
|
"psllq $32, %%mm1\n"
|
||||||
|
"psrlq $32, %%mm0\n"
|
||||||
|
"movq %%mm7, %%mm2\n"
|
||||||
|
"movq %%mm7, %%mm3\n"
|
||||||
|
"psllq $32, %%mm2\n"
|
||||||
|
"psrlq $32, %%mm3\n"
|
||||||
|
"por %%mm2, %%mm0\n"
|
||||||
|
"por %%mm3, %%mm1\n"
|
||||||
|
|
||||||
|
/* current_upper */
|
||||||
|
"movq (%0), %%mm6\n"
|
||||||
|
|
||||||
|
/* compute the upper-left pixel for dst on %%mm2 */
|
||||||
|
/* compute the upper-right pixel for dst on %%mm4 */
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"movq %%mm0, %%mm3\n"
|
||||||
|
"movq %%mm1, %%mm5\n"
|
||||||
|
"pcmpeqd %%mm6, %%mm2\n"
|
||||||
|
"pcmpeqd %%mm6, %%mm4\n"
|
||||||
|
"pcmpeqd (%2), %%mm3\n"
|
||||||
|
"pcmpeqd (%2), %%mm5\n"
|
||||||
|
"pandn %%mm2, %%mm3\n"
|
||||||
|
"pandn %%mm4, %%mm5\n"
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"pcmpeqd %%mm1, %%mm2\n"
|
||||||
|
"pcmpeqd %%mm0, %%mm4\n"
|
||||||
|
"pandn %%mm3, %%mm2\n"
|
||||||
|
"pandn %%mm5, %%mm4\n"
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"movq %%mm4, %%mm5\n"
|
||||||
|
"pand %%mm6, %%mm2\n"
|
||||||
|
"pand %%mm6, %%mm4\n"
|
||||||
|
"pandn %%mm7, %%mm3\n"
|
||||||
|
"pandn %%mm7, %%mm5\n"
|
||||||
|
"por %%mm3, %%mm2\n"
|
||||||
|
"por %%mm5, %%mm4\n"
|
||||||
|
|
||||||
|
/* set *dst */
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"punpckldq %%mm4, %%mm2\n"
|
||||||
|
"punpckhdq %%mm4, %%mm3\n"
|
||||||
|
"movq %%mm2, (%3)\n"
|
||||||
|
"movq %%mm3, 8(%3)\n"
|
||||||
|
|
||||||
|
/* next */
|
||||||
|
"addl $8, %0\n"
|
||||||
|
"addl $8, %1\n"
|
||||||
|
"addl $8, %2\n"
|
||||||
|
"addl $16, %3\n"
|
||||||
|
|
||||||
|
/* central runs */
|
||||||
|
"shrl $1, %4\n"
|
||||||
|
"jz 1f\n"
|
||||||
|
|
||||||
|
"0:\n"
|
||||||
|
|
||||||
|
/* set the current, current_pre, current_next registers */
|
||||||
|
"movq -8(%1), %%mm0\n"
|
||||||
|
"movq (%1), %%mm7\n"
|
||||||
|
"movq 8(%1), %%mm1\n"
|
||||||
|
"psrlq $32, %%mm0\n"
|
||||||
|
"psllq $32, %%mm1\n"
|
||||||
|
"movq %%mm7, %%mm2\n"
|
||||||
|
"movq %%mm7, %%mm3\n"
|
||||||
|
"psllq $32, %%mm2\n"
|
||||||
|
"psrlq $32, %%mm3\n"
|
||||||
|
"por %%mm2, %%mm0\n"
|
||||||
|
"por %%mm3, %%mm1\n"
|
||||||
|
|
||||||
|
/* current_upper */
|
||||||
|
"movq (%0), %%mm6\n"
|
||||||
|
|
||||||
|
/* compute the upper-left pixel for dst on %%mm2 */
|
||||||
|
/* compute the upper-right pixel for dst on %%mm4 */
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"movq %%mm0, %%mm3\n"
|
||||||
|
"movq %%mm1, %%mm5\n"
|
||||||
|
"pcmpeqd %%mm6, %%mm2\n"
|
||||||
|
"pcmpeqd %%mm6, %%mm4\n"
|
||||||
|
"pcmpeqd (%2), %%mm3\n"
|
||||||
|
"pcmpeqd (%2), %%mm5\n"
|
||||||
|
"pandn %%mm2, %%mm3\n"
|
||||||
|
"pandn %%mm4, %%mm5\n"
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"pcmpeqd %%mm1, %%mm2\n"
|
||||||
|
"pcmpeqd %%mm0, %%mm4\n"
|
||||||
|
"pandn %%mm3, %%mm2\n"
|
||||||
|
"pandn %%mm5, %%mm4\n"
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"movq %%mm4, %%mm5\n"
|
||||||
|
"pand %%mm6, %%mm2\n"
|
||||||
|
"pand %%mm6, %%mm4\n"
|
||||||
|
"pandn %%mm7, %%mm3\n"
|
||||||
|
"pandn %%mm7, %%mm5\n"
|
||||||
|
"por %%mm3, %%mm2\n"
|
||||||
|
"por %%mm5, %%mm4\n"
|
||||||
|
|
||||||
|
/* set *dst */
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"punpckldq %%mm4, %%mm2\n"
|
||||||
|
"punpckhdq %%mm4, %%mm3\n"
|
||||||
|
"movq %%mm2, (%3)\n"
|
||||||
|
"movq %%mm3, 8(%3)\n"
|
||||||
|
|
||||||
|
/* next */
|
||||||
|
"addl $8, %0\n"
|
||||||
|
"addl $8, %1\n"
|
||||||
|
"addl $8, %2\n"
|
||||||
|
"addl $16, %3\n"
|
||||||
|
|
||||||
|
"decl %4\n"
|
||||||
|
"jnz 0b\n"
|
||||||
|
"1:\n"
|
||||||
|
|
||||||
|
/* final run */
|
||||||
|
/* set the current, current_pre, current_next registers */
|
||||||
|
"movq (%1), %%mm1\n"
|
||||||
|
"movq (%1), %%mm7\n"
|
||||||
|
"movq -8(%1), %%mm0\n"
|
||||||
|
"psrlq $32, %%mm1\n"
|
||||||
|
"psrlq $32, %%mm0\n"
|
||||||
|
"psllq $32, %%mm1\n"
|
||||||
|
"movq %%mm7, %%mm2\n"
|
||||||
|
"movq %%mm7, %%mm3\n"
|
||||||
|
"psllq $32, %%mm2\n"
|
||||||
|
"psrlq $32, %%mm3\n"
|
||||||
|
"por %%mm2, %%mm0\n"
|
||||||
|
"por %%mm3, %%mm1\n"
|
||||||
|
|
||||||
|
/* current_upper */
|
||||||
|
"movq (%0), %%mm6\n"
|
||||||
|
|
||||||
|
/* compute the upper-left pixel for dst on %%mm2 */
|
||||||
|
/* compute the upper-right pixel for dst on %%mm4 */
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"movq %%mm0, %%mm3\n"
|
||||||
|
"movq %%mm1, %%mm5\n"
|
||||||
|
"pcmpeqd %%mm6, %%mm2\n"
|
||||||
|
"pcmpeqd %%mm6, %%mm4\n"
|
||||||
|
"pcmpeqd (%2), %%mm3\n"
|
||||||
|
"pcmpeqd (%2), %%mm5\n"
|
||||||
|
"pandn %%mm2, %%mm3\n"
|
||||||
|
"pandn %%mm4, %%mm5\n"
|
||||||
|
"movq %%mm0, %%mm2\n"
|
||||||
|
"movq %%mm1, %%mm4\n"
|
||||||
|
"pcmpeqd %%mm1, %%mm2\n"
|
||||||
|
"pcmpeqd %%mm0, %%mm4\n"
|
||||||
|
"pandn %%mm3, %%mm2\n"
|
||||||
|
"pandn %%mm5, %%mm4\n"
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"movq %%mm4, %%mm5\n"
|
||||||
|
"pand %%mm6, %%mm2\n"
|
||||||
|
"pand %%mm6, %%mm4\n"
|
||||||
|
"pandn %%mm7, %%mm3\n"
|
||||||
|
"pandn %%mm7, %%mm5\n"
|
||||||
|
"por %%mm3, %%mm2\n"
|
||||||
|
"por %%mm5, %%mm4\n"
|
||||||
|
|
||||||
|
/* set *dst */
|
||||||
|
"movq %%mm2, %%mm3\n"
|
||||||
|
"punpckldq %%mm4, %%mm2\n"
|
||||||
|
"punpckhdq %%mm4, %%mm3\n"
|
||||||
|
"movq %%mm2, (%3)\n"
|
||||||
|
"movq %%mm3, 8(%3)\n"
|
||||||
|
|
||||||
|
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
|
||||||
|
:
|
||||||
|
: "cc"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale by a factor of 2 a row of pixels of 8 bits.
|
||||||
|
* This is a very fast MMX implementation.
|
||||||
|
* The implementation uses a combination of cmp/and/not operations to
|
||||||
|
* completly remove the need of conditional jumps. This trick give the
|
||||||
|
* major speed improvement.
|
||||||
|
* Also, using the 8 bytes MMX registers more than one pixel are computed
|
||||||
|
* at the same time.
|
||||||
|
* Before calling this function you must ensure that the currenct CPU supports
|
||||||
|
* the MMX instruction set. After calling it you must be sure to call the EMMS
|
||||||
|
* instruction before any floating-point operation.
|
||||||
|
* The pixels over the left and right borders are assumed of the same color of
|
||||||
|
* the pixels on the border.
|
||||||
|
* \param src0 Pointer at the first pixel of the previous row.
|
||||||
|
* \param src1 Pointer at the first pixel of the current row.
|
||||||
|
* \param src2 Pointer at the first pixel of the next row.
|
||||||
|
* \param count Length in pixels of the src0, src1 and src2 rows. It must
|
||||||
|
* be at least 16 and a multiple of 8.
|
||||||
|
* \param dst0 First destination row, double length in pixels.
|
||||||
|
* \param dst1 Second destination row, double length in pixels.
|
||||||
|
*/
|
||||||
|
void scale2x_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||||
|
{
|
||||||
|
if (count % 8 != 0 || count < 16) {
|
||||||
|
scale2x_8_def(dst0, dst1, src0, src1, src2, count);
|
||||||
|
} else {
|
||||||
|
assert(count >= 16);
|
||||||
|
assert(count % 8 == 0);
|
||||||
|
|
||||||
|
scale2x_8_mmx_single(dst0, src0, src1, src2, count);
|
||||||
|
scale2x_8_mmx_single(dst1, src2, src1, src0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale by a factor of 2 a row of pixels of 16 bits.
|
||||||
|
* This function operates like scale2x_8_mmx() but for 16 bits pixels.
|
||||||
|
* \param src0 Pointer at the first pixel of the previous row.
|
||||||
|
* \param src1 Pointer at the first pixel of the current row.
|
||||||
|
* \param src2 Pointer at the first pixel of the next row.
|
||||||
|
* \param count Length in pixels of the src0, src1 and src2 rows. It must
|
||||||
|
* be at least 8 and a multiple of 4.
|
||||||
|
* \param dst0 First destination row, double length in pixels.
|
||||||
|
* \param dst1 Second destination row, double length in pixels.
|
||||||
|
*/
|
||||||
|
void scale2x_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||||
|
{
|
||||||
|
if (count % 4 != 0 || count < 8) {
|
||||||
|
scale2x_16_def(dst0, dst1, src0, src1, src2, count);
|
||||||
|
} else {
|
||||||
|
assert(count >= 8);
|
||||||
|
assert(count % 4 == 0);
|
||||||
|
|
||||||
|
scale2x_16_mmx_single(dst0, src0, src1, src2, count);
|
||||||
|
scale2x_16_mmx_single(dst1, src2, src1, src0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale by a factor of 2 a row of pixels of 32 bits.
|
||||||
|
* This function operates like scale2x_8_mmx() but for 32 bits pixels.
|
||||||
|
* \param src0 Pointer at the first pixel of the previous row.
|
||||||
|
* \param src1 Pointer at the first pixel of the current row.
|
||||||
|
* \param src2 Pointer at the first pixel of the next row.
|
||||||
|
* \param count Length in pixels of the src0, src1 and src2 rows. It must
|
||||||
|
* be at least 4 and a multiple of 2.
|
||||||
|
* \param dst0 First destination row, double length in pixels.
|
||||||
|
* \param dst1 Second destination row, double length in pixels.
|
||||||
|
*/
|
||||||
|
void scale2x_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||||
|
{
|
||||||
|
if (count % 2 != 0 || count < 4) {
|
||||||
|
scale2x_32_def(dst0, dst1, src0, src1, src2, count);
|
||||||
|
} else {
|
||||||
|
assert(count >= 4);
|
||||||
|
assert(count % 2 == 0);
|
||||||
|
|
||||||
|
scale2x_32_mmx_single(dst0, src0, src1, src2, count);
|
||||||
|
scale2x_32_mmx_single(dst1, src2, src1, src0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Scale2x project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||||
|
*
|
||||||
|
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SCALE2X_H
|
||||||
|
#define __SCALE2X_H
|
||||||
|
|
||||||
|
typedef unsigned char scale2x_uint8;
|
||||||
|
typedef unsigned short scale2x_uint16;
|
||||||
|
typedef unsigned scale2x_uint32;
|
||||||
|
|
||||||
|
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||||
|
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||||
|
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__i386__)
|
||||||
|
|
||||||
|
void scale2x_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||||
|
void scale2x_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||||
|
void scale2x_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End the use of the MMX instructions.
|
||||||
|
* This function must be called before using any floating-point operations.
|
||||||
|
*/
|
||||||
|
static inline void scale2x_mmx_emms(void)
|
||||||
|
{
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"emms"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,382 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Scale2x project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||||
|
*
|
||||||
|
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains a C and MMX implementation of the Scale2x effect.
|
||||||
|
*
|
||||||
|
* You can find an high level description of the effect at :
|
||||||
|
*
|
||||||
|
* http://scale2x.sourceforge.net/
|
||||||
|
*
|
||||||
|
* Alternatively at the previous license terms, you are allowed to use this
|
||||||
|
* code in your program with these conditions:
|
||||||
|
* - the program is not used in commercial activities.
|
||||||
|
* - the whole source code of the program is released with the binary.
|
||||||
|
* - derivative works of the program are allowed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "scale3x.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Scale3x C implementation */
|
||||||
|
|
||||||
|
static inline void scale3x_8_def_border(scale3x_uint8* __restrict__ dst, const scale3x_uint8* __restrict__ src0, const scale3x_uint8* __restrict__ src1, const scale3x_uint8* __restrict__ src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
/* first pixel */
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[2] = src0[0];
|
||||||
|
else
|
||||||
|
dst[2] = src1[0];
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
|
||||||
|
/* central pixels */
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||||
|
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||||
|
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||||
|
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last pixel */
|
||||||
|
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[0] = src0[0];
|
||||||
|
else
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scale3x_8_def_center(scale3x_uint8* __restrict__ dst, const scale3x_uint8* __restrict__ src0, const scale3x_uint8* __restrict__ src1, const scale3x_uint8* __restrict__ src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
/* first pixel */
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
if (src0[0] != src2[0]) {
|
||||||
|
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
|
||||||
|
/* central pixels */
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||||
|
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last pixel */
|
||||||
|
if (src0[0] != src2[0]) {
|
||||||
|
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
}
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scale3x_16_def_border(scale3x_uint16* __restrict__ dst, const scale3x_uint16* __restrict__ src0, const scale3x_uint16* __restrict__ src1, const scale3x_uint16* __restrict__ src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
/* first pixel */
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[2] = src0[0];
|
||||||
|
else
|
||||||
|
dst[2] = src1[0];
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
|
||||||
|
/* central pixels */
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||||
|
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||||
|
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||||
|
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last pixel */
|
||||||
|
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[0] = src0[0];
|
||||||
|
else
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scale3x_16_def_center(scale3x_uint16* __restrict__ dst, const scale3x_uint16* __restrict__ src0, const scale3x_uint16* __restrict__ src1, const scale3x_uint16* __restrict__ src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
/* first pixel */
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
if (src0[0] != src2[0]) {
|
||||||
|
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
|
||||||
|
/* central pixels */
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||||
|
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last pixel */
|
||||||
|
if (src0[0] != src2[0]) {
|
||||||
|
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
}
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scale3x_32_def_border(scale3x_uint32* __restrict__ dst, const scale3x_uint32* __restrict__ src0, const scale3x_uint32* __restrict__ src1, const scale3x_uint32* __restrict__ src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
/* first pixel */
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[2] = src0[0];
|
||||||
|
else
|
||||||
|
dst[2] = src1[0];
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
|
||||||
|
/* central pixels */
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||||
|
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||||
|
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||||
|
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last pixel */
|
||||||
|
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||||
|
dst[0] = src0[0];
|
||||||
|
else
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scale3x_32_def_center(scale3x_uint32* __restrict__ dst, const scale3x_uint32* __restrict__ src0, const scale3x_uint32* __restrict__ src1, const scale3x_uint32* __restrict__ src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
/* first pixel */
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
if (src0[0] != src2[0]) {
|
||||||
|
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
|
||||||
|
/* central pixels */
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||||
|
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
++src0;
|
||||||
|
++src1;
|
||||||
|
++src2;
|
||||||
|
dst += 3;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last pixel */
|
||||||
|
if (src0[0] != src2[0]) {
|
||||||
|
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||||
|
} else {
|
||||||
|
dst[0] = src1[0];
|
||||||
|
}
|
||||||
|
dst[1] = src1[0];
|
||||||
|
dst[2] = src1[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale by a factor of 3 a row of pixels of 8 bits.
|
||||||
|
* The function is implemented in C.
|
||||||
|
* The pixels over the left and right borders are assumed of the same color of
|
||||||
|
* the pixels on the border.
|
||||||
|
* \param src0 Pointer at the first pixel of the previous row.
|
||||||
|
* \param src1 Pointer at the first pixel of the current row.
|
||||||
|
* \param src2 Pointer at the first pixel of the next row.
|
||||||
|
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||||
|
* It must be at least 2.
|
||||||
|
* \param dst0 First destination row, triple length in pixels.
|
||||||
|
* \param dst1 Second destination row, triple length in pixels.
|
||||||
|
* \param dst2 Third destination row, triple length in pixels.
|
||||||
|
*/
|
||||||
|
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
scale3x_8_def_border(dst0, src0, src1, src2, count);
|
||||||
|
scale3x_8_def_center(dst1, src0, src1, src2, count);
|
||||||
|
scale3x_8_def_border(dst2, src2, src1, src0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale by a factor of 3 a row of pixels of 16 bits.
|
||||||
|
* This function operates like scale3x_8_def() but for 16 bits pixels.
|
||||||
|
* \param src0 Pointer at the first pixel of the previous row.
|
||||||
|
* \param src1 Pointer at the first pixel of the current row.
|
||||||
|
* \param src2 Pointer at the first pixel of the next row.
|
||||||
|
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||||
|
* It must be at least 2.
|
||||||
|
* \param dst0 First destination row, triple length in pixels.
|
||||||
|
* \param dst1 Second destination row, triple length in pixels.
|
||||||
|
* \param dst2 Third destination row, triple length in pixels.
|
||||||
|
*/
|
||||||
|
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
scale3x_16_def_border(dst0, src0, src1, src2, count);
|
||||||
|
scale3x_16_def_center(dst1, src0, src1, src2, count);
|
||||||
|
scale3x_16_def_border(dst2, src2, src1, src0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale by a factor of 3 a row of pixels of 32 bits.
|
||||||
|
* This function operates like scale3x_8_def() but for 32 bits pixels.
|
||||||
|
* \param src0 Pointer at the first pixel of the previous row.
|
||||||
|
* \param src1 Pointer at the first pixel of the current row.
|
||||||
|
* \param src2 Pointer at the first pixel of the next row.
|
||||||
|
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||||
|
* It must be at least 2.
|
||||||
|
* \param dst0 First destination row, triple length in pixels.
|
||||||
|
* \param dst1 Second destination row, triple length in pixels.
|
||||||
|
* \param dst2 Third destination row, triple length in pixels.
|
||||||
|
*/
|
||||||
|
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count)
|
||||||
|
{
|
||||||
|
assert(count >= 2);
|
||||||
|
|
||||||
|
scale3x_32_def_border(dst0, src0, src1, src2, count);
|
||||||
|
scale3x_32_def_center(dst1, src0, src1, src2, count);
|
||||||
|
scale3x_32_def_border(dst2, src2, src1, src0, count);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Scale2x project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||||
|
*
|
||||||
|
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SCALE3X_H
|
||||||
|
#define __SCALE3X_H
|
||||||
|
|
||||||
|
typedef unsigned char scale3x_uint8;
|
||||||
|
typedef unsigned short scale3x_uint16;
|
||||||
|
typedef unsigned scale3x_uint32;
|
||||||
|
|
||||||
|
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count);
|
||||||
|
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count);
|
||||||
|
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,385 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Scale2x project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003 Andrea Mazzoleni
|
||||||
|
*
|
||||||
|
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains an example implementation of the Scale effect
|
||||||
|
* applyed to a generic bitmap.
|
||||||
|
*
|
||||||
|
* You can find an high level description of the effect at :
|
||||||
|
*
|
||||||
|
* http://scale2x.sourceforge.net/
|
||||||
|
*
|
||||||
|
* Alternatively at the previous license terms, you are allowed to use this
|
||||||
|
* code in your program with these conditions:
|
||||||
|
* - the program is not used in commercial activities.
|
||||||
|
* - the whole source code of the program is released with the binary.
|
||||||
|
* - derivative works of the program are allowed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "scale2x.h"
|
||||||
|
#include "scale3x.h"
|
||||||
|
|
||||||
|
#if HAVE_ALLOCA_H
|
||||||
|
#include <alloca.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the Scale2x effect on a group of rows. Used internally.
|
||||||
|
*/
|
||||||
|
static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||||
|
{
|
||||||
|
switch (pixel) {
|
||||||
|
#if defined(__GNUC__) && defined(__i386__)
|
||||||
|
case 1 : scale2x_8_mmx(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||||
|
case 2 : scale2x_16_mmx(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||||
|
case 4 : scale2x_32_mmx(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||||
|
#else
|
||||||
|
case 1 : scale2x_8_def(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||||
|
case 2 : scale2x_16_def(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||||
|
case 4 : scale2x_32_def(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the Scale3x effect on a group of rows. Used internally.
|
||||||
|
*/
|
||||||
|
static inline void stage_scale3x(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||||
|
{
|
||||||
|
switch (pixel) {
|
||||||
|
case 1 : scale3x_8_def(dst0, dst1, dst2, src0, src1, src2, pixel_per_row); break;
|
||||||
|
case 2 : scale3x_16_def(dst0, dst1, dst2, src0, src1, src2, pixel_per_row); break;
|
||||||
|
case 4 : scale3x_32_def(dst0, dst1, dst2, src0, src1, src2, pixel_per_row); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the Scale4x effect on a group of rows. Used internally.
|
||||||
|
*/
|
||||||
|
static inline void stage_scale4x(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1, const void* src2, const void* src3, unsigned pixel, unsigned pixel_per_row)
|
||||||
|
{
|
||||||
|
stage_scale2x(dst0, dst1, src0, src1, src2, pixel, 2 * pixel_per_row);
|
||||||
|
stage_scale2x(dst2, dst3, src1, src2, src3, pixel, 2 * pixel_per_row);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SCDST(i) (dst+(i)*dst_slice)
|
||||||
|
#define SCSRC(i) (src+(i)*src_slice)
|
||||||
|
#define SCMID(i) (mid[(i)])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the Scale2x effect on a bitmap.
|
||||||
|
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||||
|
* The source bitmap isn't modified.
|
||||||
|
* The destination bitmap must be manually allocated before calling the function,
|
||||||
|
* note that the resulting size is exactly 2x2 times the size of the source bitmap.
|
||||||
|
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||||
|
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||||
|
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||||
|
* \param src_slice Size in bytes of a source bitmap row.
|
||||||
|
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||||
|
* \param width Horizontal size in pixels of the source bitmap.
|
||||||
|
* \param height Vertical size in pixels of the source bitmap.
|
||||||
|
*/
|
||||||
|
static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
unsigned char* dst = (unsigned char*)void_dst;
|
||||||
|
const unsigned char* src = (unsigned char*)void_src;
|
||||||
|
unsigned count;
|
||||||
|
|
||||||
|
assert(height >= 2);
|
||||||
|
|
||||||
|
count = height;
|
||||||
|
|
||||||
|
stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
|
||||||
|
|
||||||
|
dst = SCDST(2);
|
||||||
|
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||||
|
|
||||||
|
dst = SCDST(2);
|
||||||
|
src = SCSRC(1);
|
||||||
|
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
stage_scale2x(SCDST(0), SCDST(1), SCSRC(1-1), SCSRC(2-1), SCSRC(2-1), pixel, width);
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__i386__)
|
||||||
|
scale2x_mmx_emms();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the Scale32x effect on a bitmap.
|
||||||
|
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||||
|
* The source bitmap isn't modified.
|
||||||
|
* The destination bitmap must be manually allocated before calling the function,
|
||||||
|
* note that the resulting size is exactly 3x3 times the size of the source bitmap.
|
||||||
|
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||||
|
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||||
|
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||||
|
* \param src_slice Size in bytes of a source bitmap row.
|
||||||
|
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||||
|
* \param width Horizontal size in pixels of the source bitmap.
|
||||||
|
* \param height Vertical size in pixels of the source bitmap.
|
||||||
|
*/
|
||||||
|
static void scale3x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
unsigned char* dst = (unsigned char*)void_dst;
|
||||||
|
const unsigned char* src = (unsigned char*)void_src;
|
||||||
|
unsigned count;
|
||||||
|
|
||||||
|
assert(height >= 2);
|
||||||
|
|
||||||
|
count = height;
|
||||||
|
|
||||||
|
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
|
||||||
|
|
||||||
|
dst = SCDST(3);
|
||||||
|
|
||||||
|
count -= 2;
|
||||||
|
while (count) {
|
||||||
|
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||||
|
|
||||||
|
dst = SCDST(3);
|
||||||
|
src = SCSRC(1);
|
||||||
|
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(1-1), SCSRC(2-1), SCSRC(2-1), pixel, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the Scale4x effect on a bitmap.
|
||||||
|
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||||
|
* The source bitmap isn't modified.
|
||||||
|
* The destination bitmap must be manually allocated before calling the function,
|
||||||
|
* note that the resulting size is exactly 4x4 times the size of the source bitmap.
|
||||||
|
* \note This function requires also a small buffer bitmap used internally to store
|
||||||
|
* intermediate results. This bitmap must have at least an horizontal size in bytes of 2*width*pixel,
|
||||||
|
* and a vertical size of 6 rows. The memory of this buffer must not be allocated
|
||||||
|
* in video memory because it's also read and not only written. Generally
|
||||||
|
* a heap (malloc) or a stack (alloca) buffer is the best choices.
|
||||||
|
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||||
|
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||||
|
* \param void_mid Pointer at the first pixel of the buffer bitmap.
|
||||||
|
* \param mid_slice Size in bytes of a buffer bitmap row.
|
||||||
|
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||||
|
* \param src_slice Size in bytes of a source bitmap row.
|
||||||
|
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||||
|
* \param width Horizontal size in pixels of the source bitmap.
|
||||||
|
* \param height Vertical size in pixels of the source bitmap.
|
||||||
|
*/
|
||||||
|
static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsigned mid_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
unsigned char* dst = (unsigned char*)void_dst;
|
||||||
|
const unsigned char* src = (unsigned char*)void_src;
|
||||||
|
unsigned count;
|
||||||
|
unsigned char* mid[6];
|
||||||
|
|
||||||
|
assert(height >= 4);
|
||||||
|
|
||||||
|
count = height;
|
||||||
|
|
||||||
|
/* set the 6 buffer pointers */
|
||||||
|
mid[0] = (unsigned char*)void_mid;
|
||||||
|
mid[1] = mid[0] + mid_slice;
|
||||||
|
mid[2] = mid[1] + mid_slice;
|
||||||
|
mid[3] = mid[2] + mid_slice;
|
||||||
|
mid[4] = mid[3] + mid_slice;
|
||||||
|
mid[5] = mid[4] + mid_slice;
|
||||||
|
|
||||||
|
stage_scale2x(SCMID(-2+6), SCMID(-1+6), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
|
||||||
|
stage_scale2x(SCMID(0), SCMID(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||||
|
stage_scale2x(SCMID(2), SCMID(3), SCSRC(1), SCSRC(2), SCSRC(3), pixel, width);
|
||||||
|
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(-2+6), SCMID(-2+6), SCMID(-1+6), SCMID(0), pixel, width);
|
||||||
|
|
||||||
|
dst = SCDST(4);
|
||||||
|
|
||||||
|
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(-1+6), SCMID(0), SCMID(1), SCMID(2), pixel, width);
|
||||||
|
|
||||||
|
dst = SCDST(4);
|
||||||
|
|
||||||
|
count -= 4;
|
||||||
|
while (count) {
|
||||||
|
unsigned char* tmp;
|
||||||
|
|
||||||
|
stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(4), pixel, width);
|
||||||
|
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
|
||||||
|
|
||||||
|
dst = SCDST(4);
|
||||||
|
src = SCSRC(1);
|
||||||
|
|
||||||
|
tmp = SCMID(0); /* shift by 2 position */
|
||||||
|
SCMID(0) = SCMID(2);
|
||||||
|
SCMID(2) = SCMID(4);
|
||||||
|
SCMID(4) = tmp;
|
||||||
|
tmp = SCMID(1);
|
||||||
|
SCMID(1) = SCMID(3);
|
||||||
|
SCMID(3) = SCMID(5);
|
||||||
|
SCMID(5) = tmp;
|
||||||
|
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(3), pixel, width);
|
||||||
|
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
|
||||||
|
|
||||||
|
dst = SCDST(4);
|
||||||
|
|
||||||
|
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(3), SCMID(4), SCMID(5), SCMID(5), pixel, width);
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__i386__)
|
||||||
|
scale2x_mmx_emms();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the Scale4x effect on a bitmap.
|
||||||
|
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||||
|
* The source bitmap isn't modified.
|
||||||
|
* The destination bitmap must be manually allocated before calling the function,
|
||||||
|
* note that the resulting size is exactly 4x4 times the size of the source bitmap.
|
||||||
|
* \note This function operates like ::scale4x_buf() but the intermediate buffer is
|
||||||
|
* automatically allocated in the stack.
|
||||||
|
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||||
|
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||||
|
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||||
|
* \param src_slice Size in bytes of a source bitmap row.
|
||||||
|
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||||
|
* \param width Horizontal size in pixels of the source bitmap.
|
||||||
|
* \param height Vertical size in pixels of the source bitmap.
|
||||||
|
*/
|
||||||
|
static void scale4x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
unsigned mid_slice;
|
||||||
|
void* mid;
|
||||||
|
|
||||||
|
mid_slice = 2 * pixel * width; /* required space for 1 row buffer */
|
||||||
|
|
||||||
|
mid_slice = (mid_slice + 0x7) & ~0x7; /* align to 8 bytes */
|
||||||
|
|
||||||
|
#if HAVE_ALLOCA
|
||||||
|
mid = alloca(6 * mid_slice); /* allocate space for 6 row buffers */
|
||||||
|
|
||||||
|
assert(mid != 0); /* alloca should never fails */
|
||||||
|
#else
|
||||||
|
mid = malloc(6 * mid_slice); /* allocate space for 6 row buffers */
|
||||||
|
|
||||||
|
if (!mid)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
scale4x_buf(void_dst, dst_slice, mid, mid_slice, void_src, src_slice, pixel, width, height);
|
||||||
|
|
||||||
|
#if !HAVE_ALLOCA
|
||||||
|
free(mid);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the scale implementation is applicable at the given arguments.
|
||||||
|
* \param scale Scale factor. 2, 3 or 4.
|
||||||
|
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||||
|
* \param width Horizontal size in pixels of the source bitmap.
|
||||||
|
* \param height Vertical size in pixels of the source bitmap.
|
||||||
|
* \return
|
||||||
|
* - -1 on precondition violated.
|
||||||
|
* - 0 on success.
|
||||||
|
*/
|
||||||
|
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
if (scale != 2 && scale != 3 && scale != 4)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (pixel != 1 && pixel != 2 && pixel != 4)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (scale) {
|
||||||
|
case 2 :
|
||||||
|
case 3 :
|
||||||
|
if (height < 2)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case 4 :
|
||||||
|
if (height < 4)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__i386__)
|
||||||
|
switch (scale) {
|
||||||
|
case 2 :
|
||||||
|
case 4 :
|
||||||
|
if (width < (16 / pixel))
|
||||||
|
return -1;
|
||||||
|
if (width % (8 / pixel) != 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case 3 :
|
||||||
|
if (width < 2)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (width < 2)
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the Scale effect on a bitmap.
|
||||||
|
* This function is simply a common interface for ::scale2x(), ::scale3x() and ::scale4x().
|
||||||
|
* \param scale Scale factor. 2, 3 or 4.
|
||||||
|
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||||
|
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||||
|
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||||
|
* \param src_slice Size in bytes of a source bitmap row.
|
||||||
|
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||||
|
* \param width Horizontal size in pixels of the source bitmap.
|
||||||
|
* \param height Vertical size in pixels of the source bitmap.
|
||||||
|
*/
|
||||||
|
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
switch (scale) {
|
||||||
|
case 2 :
|
||||||
|
scale2x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
|
||||||
|
break;
|
||||||
|
case 3 :
|
||||||
|
scale3x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
|
||||||
|
break;
|
||||||
|
case 4 :
|
||||||
|
scale4x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Scale2x project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003 Andrea Mazzoleni
|
||||||
|
*
|
||||||
|
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains an example implementation of the Scale effect
|
||||||
|
* applyed to a generic bitmap.
|
||||||
|
*
|
||||||
|
* You can find an high level description of the effect at :
|
||||||
|
*
|
||||||
|
* http://scale2x.sourceforge.net/
|
||||||
|
*
|
||||||
|
* Alternatively at the previous license terms, you are allowed to use this
|
||||||
|
* code in your program with these conditions:
|
||||||
|
* - the program is not used in commercial activities.
|
||||||
|
* - the whole source code of the program is released with the binary.
|
||||||
|
* - derivative works of the program are allowed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SCALEBIT_H
|
||||||
|
#define __SCALEBIT_H
|
||||||
|
|
||||||
|
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height);
|
||||||
|
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,843 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "scalebit.h"
|
||||||
|
#include "hq2x.h"
|
||||||
|
#include "hq3x.h"
|
||||||
|
|
||||||
|
#include "../../types.h"
|
||||||
|
|
||||||
|
static uint32 CBM[3];
|
||||||
|
static uint32 *palettetranslate=0;
|
||||||
|
|
||||||
|
static uint16 *specbuf=NULL; // 8bpp -> 16bpp, pre hq2x/hq3x
|
||||||
|
static uint32 *specbuf32bpp = NULL; // Buffer to hold output
|
||||||
|
// of hq2x/hq3x when converting
|
||||||
|
// to 16bpp and 24bpp
|
||||||
|
static int backBpp, backshiftr[3], backshiftl[3];
|
||||||
|
//static uint32 backmask[3];
|
||||||
|
|
||||||
|
static uint8 *specbuf8bpp = NULL; // For 2xscale, 3xscale.
|
||||||
|
|
||||||
|
|
||||||
|
static int silt;
|
||||||
|
|
||||||
|
static int Bpp; // BYTES per pixel
|
||||||
|
static int highefx;
|
||||||
|
|
||||||
|
#define BLUR_RED 20
|
||||||
|
#define BLUR_GREEN 20
|
||||||
|
#define BLUR_BLUE 10
|
||||||
|
|
||||||
|
#define FVB_SCANLINES 1
|
||||||
|
|
||||||
|
/* The blur effect is only available for bpp>=16. It could be easily modified
|
||||||
|
to look like what happens on the real NES and TV, but lack of decent
|
||||||
|
synchronization to the vertical retrace period makes it look rather
|
||||||
|
blah.
|
||||||
|
*/
|
||||||
|
#define FVB_BLUR 2
|
||||||
|
|
||||||
|
static void CalculateShift(uint32 *CBM, int *cshiftr, int *cshiftl)
|
||||||
|
{
|
||||||
|
int a,x,z,y;
|
||||||
|
cshiftl[0]=cshiftl[1]=cshiftl[2]=-1;
|
||||||
|
for(a=0;a<3;a++)
|
||||||
|
{
|
||||||
|
for(x=0,y=-1,z=0;x<32;x++)
|
||||||
|
{
|
||||||
|
if(CBM[a]&(1<<x))
|
||||||
|
{
|
||||||
|
if(cshiftl[a]==-1) cshiftl[a]=x;
|
||||||
|
z++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cshiftr[a]=(8-z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int InitBlitToHigh(int b, uint32 rmask, uint32 gmask, uint32 bmask, int efx, int specfilt)
|
||||||
|
{
|
||||||
|
if(specfilt == 2 || specfilt == 4) // scale2x and scale3x
|
||||||
|
{
|
||||||
|
int multi;
|
||||||
|
|
||||||
|
if(specfilt == 2) multi = 2 * 2;
|
||||||
|
else if(specfilt == 4) multi = 3 * 3;
|
||||||
|
|
||||||
|
specbuf8bpp = malloc(256*240*multi);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(specfilt == 1 || specfilt == 3) // hq2x and hq3x
|
||||||
|
{
|
||||||
|
if(b == 1)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(b == 2 || b == 3) // 8->16->(hq2x)->32-> 24 or 16. YARGH.
|
||||||
|
{
|
||||||
|
uint32 tmpCBM[3];
|
||||||
|
backBpp = b;
|
||||||
|
tmpCBM[0]=rmask;
|
||||||
|
tmpCBM[1]=gmask;
|
||||||
|
tmpCBM[2]=bmask;
|
||||||
|
|
||||||
|
CalculateShift(tmpCBM, backshiftr, backshiftl);
|
||||||
|
|
||||||
|
if(b == 2)
|
||||||
|
{
|
||||||
|
// ark
|
||||||
|
backshiftr[0] += 16;
|
||||||
|
backshiftr[1] += 8;
|
||||||
|
backshiftr[2] += 0;
|
||||||
|
|
||||||
|
// Begin iffy code(requires 16bpp and 32bpp to have same RGB order)
|
||||||
|
//backmask[0] = (rmask>>backshiftl[0]) << (backshiftr[0]);
|
||||||
|
//backmask[1] = (gmask>>backshiftl[1]) << (backshiftr[1]);
|
||||||
|
//backmask[2] = (bmask>>backshiftl[2]) << (backshiftr[2]);
|
||||||
|
|
||||||
|
//int x;
|
||||||
|
//for(x=0;x<3;x++)
|
||||||
|
// backshiftr[x] -= backshiftl[x];
|
||||||
|
// End iffy code
|
||||||
|
}
|
||||||
|
if(specfilt == 1) specbuf32bpp = malloc(256*240*4*sizeof(uint32));
|
||||||
|
else if(specfilt == 3) specbuf32bpp = malloc(256*240*9*sizeof(uint32));
|
||||||
|
}
|
||||||
|
|
||||||
|
efx=0;
|
||||||
|
b=2;
|
||||||
|
rmask=0x1F<<11;
|
||||||
|
gmask=0x3F<<5;
|
||||||
|
bmask=0x1F;
|
||||||
|
|
||||||
|
if(specfilt == 3)
|
||||||
|
hq3x_InitLUTs();
|
||||||
|
else
|
||||||
|
hq2x_InitLUTs();
|
||||||
|
|
||||||
|
specbuf=malloc(256*240*sizeof(uint16));
|
||||||
|
}
|
||||||
|
|
||||||
|
silt = specfilt;
|
||||||
|
|
||||||
|
Bpp=b;
|
||||||
|
|
||||||
|
highefx=efx;
|
||||||
|
|
||||||
|
if(Bpp<=1 || Bpp>4)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(efx&FVB_BLUR)
|
||||||
|
{
|
||||||
|
if(Bpp==2)
|
||||||
|
palettetranslate=(uint32 *)malloc(65536*4);
|
||||||
|
else if(Bpp>=3)
|
||||||
|
palettetranslate=(uint32 *)malloc(65536*4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(Bpp==2)
|
||||||
|
palettetranslate=(uint32*)malloc(65536*4);
|
||||||
|
else if(Bpp>=3)
|
||||||
|
palettetranslate=(uint32*)malloc(256*4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!palettetranslate)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
|
||||||
|
CBM[0]=rmask;
|
||||||
|
CBM[1]=gmask;
|
||||||
|
CBM[2]=bmask;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillBlitToHigh(void)
|
||||||
|
{
|
||||||
|
if(palettetranslate)
|
||||||
|
{
|
||||||
|
free(palettetranslate);
|
||||||
|
palettetranslate=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(specbuf8bpp)
|
||||||
|
{
|
||||||
|
free(specbuf8bpp);
|
||||||
|
specbuf8bpp = NULL;
|
||||||
|
}
|
||||||
|
if(specbuf32bpp)
|
||||||
|
{
|
||||||
|
free(specbuf32bpp);
|
||||||
|
specbuf32bpp = NULL;
|
||||||
|
}
|
||||||
|
if(specbuf)
|
||||||
|
{
|
||||||
|
if(silt == 3)
|
||||||
|
hq3x_Kill();
|
||||||
|
else
|
||||||
|
hq2x_Kill();
|
||||||
|
specbuf=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetPaletteBlitToHigh(uint8 *src)
|
||||||
|
{
|
||||||
|
int cshiftr[3];
|
||||||
|
int cshiftl[3];
|
||||||
|
int x,y;
|
||||||
|
|
||||||
|
CalculateShift(CBM, cshiftr, cshiftl);
|
||||||
|
|
||||||
|
switch(Bpp)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if(highefx&FVB_BLUR)
|
||||||
|
{
|
||||||
|
for(x=0;x<256;x++)
|
||||||
|
{
|
||||||
|
uint32 r,g,b;
|
||||||
|
for(y=0;y<256;y++)
|
||||||
|
{
|
||||||
|
r=src[x<<2]*(100-BLUR_RED);
|
||||||
|
g=src[(x<<2)+1]*(100-BLUR_GREEN);
|
||||||
|
b=src[(x<<2)+2]*(100-BLUR_BLUE);
|
||||||
|
|
||||||
|
r+=src[y<<2]*BLUR_RED;
|
||||||
|
g+=src[(y<<2)+1]*BLUR_GREEN;
|
||||||
|
b+=src[(y<<2)+2]*BLUR_BLUE;
|
||||||
|
r/=100;
|
||||||
|
g/=100;
|
||||||
|
b/=100;
|
||||||
|
|
||||||
|
if(r>255) r=255; if(g>255) g=255; if(b>255) b=255;
|
||||||
|
palettetranslate[x|(y<<8)]=((r>>cshiftr[0])<<cshiftl[0])|
|
||||||
|
((g>>cshiftr[1])<<cshiftl[1])|
|
||||||
|
((b>>cshiftr[2])<<cshiftl[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for(x=0;x<65536;x++)
|
||||||
|
{
|
||||||
|
uint16 lower,upper;
|
||||||
|
|
||||||
|
lower=(src[((x&255)<<2)]>>cshiftr[0])<<cshiftl[0];
|
||||||
|
lower|=(src[((x&255)<<2)+1]>>cshiftr[1])<<cshiftl[1];
|
||||||
|
lower|=(src[((x&255)<<2)+2]>>cshiftr[2])<<cshiftl[2];
|
||||||
|
upper=(src[((x>>8)<<2)]>>cshiftr[0])<<cshiftl[0];
|
||||||
|
upper|=(src[((x>>8)<<2)+1]>>cshiftr[1])<<cshiftl[1];
|
||||||
|
upper|=(src[((x>>8)<<2)+2]>>cshiftr[2])<<cshiftl[2];
|
||||||
|
|
||||||
|
palettetranslate[x]=lower|(upper<<16);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
for(x=0;x<256;x++)
|
||||||
|
{
|
||||||
|
uint32 r,g,b;
|
||||||
|
|
||||||
|
if(!(highefx&FVB_BLUR))
|
||||||
|
{
|
||||||
|
r=src[x<<2];
|
||||||
|
g=src[(x<<2)+1];
|
||||||
|
b=src[(x<<2)+2];
|
||||||
|
palettetranslate[x]=(r<<cshiftl[0])|(g<<cshiftl[1])|(b<<cshiftl[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for(y=0;y<256;y++)
|
||||||
|
{
|
||||||
|
r=src[x<<2]*(100-BLUR_RED);
|
||||||
|
g=src[(x<<2)+1]*(100-BLUR_GREEN);
|
||||||
|
b=src[(x<<2)+2]*(100-BLUR_BLUE);
|
||||||
|
|
||||||
|
r+=src[y<<2]*BLUR_RED;
|
||||||
|
g+=src[(y<<2)+1]*BLUR_GREEN;
|
||||||
|
b+=src[(y<<2)+2]*BLUR_BLUE;
|
||||||
|
|
||||||
|
r/=100;
|
||||||
|
g/=100;
|
||||||
|
b/=100;
|
||||||
|
if(r>255) r=255; if(g>255) g=255; if(b>255) b=255;
|
||||||
|
|
||||||
|
palettetranslate[x|(y<<8)]=(r<<cshiftl[0])|(g<<cshiftl[1])|(b<<cshiftl[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Blit32to24(uint32 *src, uint8 *dest, int xr, int yr, int dpitch)
|
||||||
|
{
|
||||||
|
int x,y;
|
||||||
|
|
||||||
|
for(y=yr;y;y--)
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--)
|
||||||
|
{
|
||||||
|
uint32 tmp = *src;
|
||||||
|
*dest = tmp;
|
||||||
|
dest++;
|
||||||
|
*dest = tmp>>8;
|
||||||
|
dest++;
|
||||||
|
*dest = tmp>>16;
|
||||||
|
dest++;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
dest += dpitch / 3 - xr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void Blit32to16(uint32 *src, uint16 *dest, int xr, int yr, int dpitch,
|
||||||
|
int shiftr[3], int shiftl[3])
|
||||||
|
{
|
||||||
|
int x,y;
|
||||||
|
//printf("%d\n",shiftl[1]);
|
||||||
|
for(y=yr;y;y--)
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--)
|
||||||
|
{
|
||||||
|
uint32 tmp = *src;
|
||||||
|
uint16 dtmp;
|
||||||
|
|
||||||
|
// Begin iffy code
|
||||||
|
//dtmp = (tmp & backmask[2]) >> shiftr[2];
|
||||||
|
//dtmp |= (tmp & backmask[1]) >> shiftr[1];
|
||||||
|
//dtmp |= (tmp & backmask[0]) >> shiftr[0];
|
||||||
|
// End iffy code
|
||||||
|
|
||||||
|
// Begin non-iffy code
|
||||||
|
dtmp = ((tmp&0x0000FF) >> shiftr[2]) << shiftl[2];
|
||||||
|
dtmp |= ((tmp&0x00FF00) >> shiftr[1]) << shiftl[1];
|
||||||
|
dtmp |= ((tmp&0xFF0000) >> shiftr[0]) << shiftl[0];
|
||||||
|
// End non-iffy code
|
||||||
|
|
||||||
|
//dtmp = ((tmp&0x0000FF) >> 3);
|
||||||
|
//dtmp |= ((tmp&0x00FC00) >>5);
|
||||||
|
//dtmp |= ((tmp&0xF80000) >>8);
|
||||||
|
|
||||||
|
*dest = dtmp;
|
||||||
|
src++;
|
||||||
|
dest++;
|
||||||
|
}
|
||||||
|
dest += dpitch / 2 - xr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Blit8To8(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, int yscale, int efx, int special)
|
||||||
|
{
|
||||||
|
int x,y;
|
||||||
|
int pinc;
|
||||||
|
|
||||||
|
if(special==2)
|
||||||
|
{
|
||||||
|
if(xscale!=2 || yscale!=2) return;
|
||||||
|
|
||||||
|
scale(2,dest,pitch,src,256,1,xr,yr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(special==4)
|
||||||
|
{
|
||||||
|
if(xscale!=3 || yscale!=3) return;
|
||||||
|
scale(3,dest,pitch,src,256,1,xr,yr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pinc=pitch-(xr*xscale);
|
||||||
|
if(xscale!=1 || yscale!=1)
|
||||||
|
{
|
||||||
|
if(efx&FVB_SCANLINES)
|
||||||
|
{
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
int doo=yscale-(yscale>>1);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--,src++)
|
||||||
|
{
|
||||||
|
int too=xscale;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*(uint8 *)dest=*(uint8 *)src;
|
||||||
|
dest++;
|
||||||
|
} while(--too);
|
||||||
|
}
|
||||||
|
src-=xr;
|
||||||
|
dest+=pinc;
|
||||||
|
} while(--doo);
|
||||||
|
//src-=xr*(yscale-(yscale>>1));
|
||||||
|
dest+=pitch*(yscale>>1);
|
||||||
|
|
||||||
|
src+=xr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
int doo=yscale;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--,src++)
|
||||||
|
{
|
||||||
|
int too=xscale;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*(uint8 *)dest=*(uint8 *)src;
|
||||||
|
dest++;
|
||||||
|
} while(--too);
|
||||||
|
}
|
||||||
|
src-=xr;
|
||||||
|
dest+=pinc;
|
||||||
|
} while(--doo);
|
||||||
|
src+=xr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(y=yr;y;y--,dest+=pinc,src+=256-xr)
|
||||||
|
for(x=xr;x;x-=4,dest+=4,src+=4)
|
||||||
|
*(uint32 *)dest=*(uint32 *)src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Todo: Make sure 24bpp code works right with big-endian cpus */
|
||||||
|
|
||||||
|
void Blit8ToHigh(uint8 *src, uint8 *dest, int xr, int yr, int pitch,
|
||||||
|
int xscale, int yscale)
|
||||||
|
{
|
||||||
|
int x,y;
|
||||||
|
int pinc;
|
||||||
|
uint8 *destbackup = NULL; /* For hq2x */
|
||||||
|
int pitchbackup = 0;
|
||||||
|
|
||||||
|
//static int google=0;
|
||||||
|
//google^=1;
|
||||||
|
|
||||||
|
if(specbuf8bpp) // 2xscale/3xscale
|
||||||
|
{
|
||||||
|
int mult;
|
||||||
|
int base;
|
||||||
|
|
||||||
|
if(silt == 2) mult = 2;
|
||||||
|
else mult = 3;
|
||||||
|
|
||||||
|
Blit8To8(src, specbuf8bpp, xr, yr, 256*mult, xscale, yscale, 0, silt);
|
||||||
|
|
||||||
|
xr *= mult;
|
||||||
|
yr *= mult;
|
||||||
|
xscale=yscale=1;
|
||||||
|
src = specbuf8bpp;
|
||||||
|
base = 256*mult;
|
||||||
|
|
||||||
|
switch(Bpp)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
pinc=pitch-(xr<<2);
|
||||||
|
for(y=yr;y;y--,src+=base-xr)
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--)
|
||||||
|
{
|
||||||
|
*(uint32 *)dest=palettetranslate[(uint32)*src];
|
||||||
|
dest+=4;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
dest+=pinc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
pinc=pitch-(xr+xr+xr);
|
||||||
|
for(y=yr;y;y--,src+=base-xr)
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--)
|
||||||
|
{
|
||||||
|
uint32 tmp=palettetranslate[(uint32)*src];
|
||||||
|
*(uint8 *)dest=tmp;
|
||||||
|
*((uint8 *)dest+1)=tmp>>8;
|
||||||
|
*((uint8 *)dest+2)=tmp>>16;
|
||||||
|
dest+=3;
|
||||||
|
src++;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
dest+=pinc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pinc=pitch-(xr<<1);
|
||||||
|
|
||||||
|
for(y=yr;y;y--,src+=base-xr)
|
||||||
|
{
|
||||||
|
for(x=xr>>1;x;x--)
|
||||||
|
{
|
||||||
|
*(uint32 *)dest=palettetranslate[*(uint16 *)src];
|
||||||
|
dest+=4;
|
||||||
|
src+=2;
|
||||||
|
}
|
||||||
|
dest+=pinc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(specbuf)
|
||||||
|
{
|
||||||
|
destbackup=dest;
|
||||||
|
dest=(uint8 *)specbuf;
|
||||||
|
pitchbackup=pitch;
|
||||||
|
|
||||||
|
pitch=xr*sizeof(uint16);
|
||||||
|
xscale=1;
|
||||||
|
yscale=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(highefx&FVB_BLUR) // DONE
|
||||||
|
{
|
||||||
|
if(xscale!=1 || yscale!=1 || (highefx&FVB_SCANLINES)) // DONE
|
||||||
|
{
|
||||||
|
switch(Bpp)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
pinc=pitch-((xr*xscale)<<2);
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
int doo=yscale;
|
||||||
|
|
||||||
|
if(highefx&FVB_SCANLINES)
|
||||||
|
doo-=yscale>>1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
uint8 last=0x00;
|
||||||
|
|
||||||
|
//if(doo == 1 && google) dest+=4;
|
||||||
|
for(x=xr;x;x--,src++)
|
||||||
|
{
|
||||||
|
int too=xscale;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*(uint32 *)dest=palettetranslate[*src|(last<<8)];
|
||||||
|
dest+=4;
|
||||||
|
} while(--too);
|
||||||
|
last=*src;
|
||||||
|
}
|
||||||
|
//if(doo == 1 && google) dest-=4;
|
||||||
|
src-=xr;
|
||||||
|
dest+=pinc;
|
||||||
|
} while(--doo);
|
||||||
|
src+=xr;
|
||||||
|
if(highefx&FVB_SCANLINES)
|
||||||
|
dest+=pitch*(yscale>>1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
pinc=pitch-((xr*xscale)*3);
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
int doo=yscale;
|
||||||
|
|
||||||
|
if(highefx&FVB_SCANLINES)
|
||||||
|
doo-=yscale>>1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
uint8 last=0x00;
|
||||||
|
for(x=xr;x;x--,src++)
|
||||||
|
{
|
||||||
|
int too=xscale;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*(uint32 *)dest=palettetranslate[*src|(last<<8)];
|
||||||
|
dest+=3;
|
||||||
|
} while(--too);
|
||||||
|
last=*src;
|
||||||
|
}
|
||||||
|
src-=xr;
|
||||||
|
dest+=pinc;
|
||||||
|
} while(--doo);
|
||||||
|
src+=xr;
|
||||||
|
if(highefx&FVB_SCANLINES)
|
||||||
|
dest+=pitch*(yscale>>1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
pinc=pitch-((xr*xscale)<<1);
|
||||||
|
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
int doo=yscale;
|
||||||
|
|
||||||
|
if(highefx& FVB_SCANLINES)
|
||||||
|
doo-=yscale>>1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
uint8 last=0x00;
|
||||||
|
for(x=xr;x;x--,src++)
|
||||||
|
{
|
||||||
|
int too=xscale;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*(uint16 *)dest=palettetranslate[*src|(last<<8)];
|
||||||
|
dest+=2;
|
||||||
|
} while(--too);
|
||||||
|
last=*src;
|
||||||
|
}
|
||||||
|
src-=xr;
|
||||||
|
dest+=pinc;
|
||||||
|
} while(--doo);
|
||||||
|
src+=xr;
|
||||||
|
if(highefx&FVB_SCANLINES)
|
||||||
|
dest+=pitch*(yscale>>1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // No scaling, no scanlines, just blurring. - DONE
|
||||||
|
switch(Bpp)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
pinc=pitch-(xr<<2);
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
uint8 last=0x00;
|
||||||
|
for(x=xr;x;x--)
|
||||||
|
{
|
||||||
|
*(uint32 *)dest=palettetranslate[*src|(last<<8)];
|
||||||
|
last=*src;
|
||||||
|
dest+=4;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
dest+=pinc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
pinc=pitch-(xr+xr+xr);
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
uint8 last=0x00;
|
||||||
|
for(x=xr;x;x--)
|
||||||
|
{
|
||||||
|
uint32 tmp=palettetranslate[*src|(last<<8)];
|
||||||
|
last=*src;
|
||||||
|
*(uint8 *)dest=tmp;
|
||||||
|
*((uint8 *)dest+1)=tmp>>8;
|
||||||
|
*((uint8 *)dest+2)=tmp>>16;
|
||||||
|
dest+=3;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
dest+=pinc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pinc=pitch-(xr<<1);
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
uint8 last=0x00;
|
||||||
|
for(x=xr;x;x--)
|
||||||
|
{
|
||||||
|
*(uint16 *)dest=palettetranslate[*src|(last<<8)];
|
||||||
|
last=*src;
|
||||||
|
dest+=2;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
dest+=pinc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // No blur effects.
|
||||||
|
{
|
||||||
|
if(xscale!=1 || yscale!=1 || (highefx&FVB_SCANLINES))
|
||||||
|
{
|
||||||
|
switch(Bpp)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
pinc=pitch-((xr*xscale)<<2);
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
int doo=yscale;
|
||||||
|
|
||||||
|
if(highefx& FVB_SCANLINES)
|
||||||
|
doo-=yscale>>1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--,src++)
|
||||||
|
{
|
||||||
|
int too=xscale;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*(uint32 *)dest=palettetranslate[*src];
|
||||||
|
dest+=4;
|
||||||
|
} while(--too);
|
||||||
|
}
|
||||||
|
src-=xr;
|
||||||
|
dest+=pinc;
|
||||||
|
} while(--doo);
|
||||||
|
src+=xr;
|
||||||
|
if(highefx&FVB_SCANLINES)
|
||||||
|
dest+=pitch*(yscale>>1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
pinc=pitch-((xr*xscale)*3);
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
int doo=yscale;
|
||||||
|
|
||||||
|
if(highefx& FVB_SCANLINES)
|
||||||
|
doo-=yscale>>1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--,src++)
|
||||||
|
{
|
||||||
|
int too=xscale;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
uint32 tmp=palettetranslate[(uint32)*src];
|
||||||
|
*(uint8 *)dest=tmp;
|
||||||
|
*((uint8 *)dest+1)=tmp>>8;
|
||||||
|
*((uint8 *)dest+2)=tmp>>16;
|
||||||
|
dest+=3;
|
||||||
|
|
||||||
|
//*(uint32 *)dest=palettetranslate[*src];
|
||||||
|
//dest+=4;
|
||||||
|
} while(--too);
|
||||||
|
}
|
||||||
|
src-=xr;
|
||||||
|
dest+=pinc;
|
||||||
|
} while(--doo);
|
||||||
|
src+=xr;
|
||||||
|
if(highefx&FVB_SCANLINES)
|
||||||
|
dest+=pitch*(yscale>>1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
pinc=pitch-((xr*xscale)<<1);
|
||||||
|
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
int doo=yscale;
|
||||||
|
|
||||||
|
if(highefx& FVB_SCANLINES)
|
||||||
|
doo-=yscale>>1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--,src++)
|
||||||
|
{
|
||||||
|
int too=xscale;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*(uint16 *)dest=palettetranslate[*src];
|
||||||
|
dest+=2;
|
||||||
|
} while(--too);
|
||||||
|
}
|
||||||
|
src-=xr;
|
||||||
|
dest+=pinc;
|
||||||
|
} while(--doo);
|
||||||
|
src+=xr;
|
||||||
|
if(highefx&FVB_SCANLINES)
|
||||||
|
dest+=pitch*(yscale>>1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
switch(Bpp)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
pinc=pitch-(xr<<2);
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--)
|
||||||
|
{
|
||||||
|
*(uint32 *)dest=palettetranslate[(uint32)*src];
|
||||||
|
dest+=4;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
dest+=pinc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
pinc=pitch-(xr+xr+xr);
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
for(x=xr;x;x--)
|
||||||
|
{
|
||||||
|
uint32 tmp=palettetranslate[(uint32)*src];
|
||||||
|
*(uint8 *)dest=tmp;
|
||||||
|
*((uint8 *)dest+1)=tmp>>8;
|
||||||
|
*((uint8 *)dest+2)=tmp>>16;
|
||||||
|
dest+=3;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
dest+=pinc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pinc=pitch-(xr<<1);
|
||||||
|
|
||||||
|
for(y=yr;y;y--,src+=256-xr)
|
||||||
|
{
|
||||||
|
for(x=xr>>1;x;x--)
|
||||||
|
{
|
||||||
|
*(uint32 *)dest=palettetranslate[*(uint16 *)src];
|
||||||
|
dest+=4;
|
||||||
|
src+=2;
|
||||||
|
}
|
||||||
|
dest+=pinc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(specbuf)
|
||||||
|
{
|
||||||
|
if(specbuf32bpp)
|
||||||
|
{
|
||||||
|
int mult = (silt == 3)?3:2;
|
||||||
|
|
||||||
|
if(silt == 3)
|
||||||
|
hq3x_32((uint8 *)specbuf,(uint8*)specbuf32bpp,xr,yr,xr*3*sizeof(uint32));
|
||||||
|
else
|
||||||
|
hq2x_32((uint8 *)specbuf,(uint8*)specbuf32bpp,xr,yr,xr*2*sizeof(uint32));
|
||||||
|
|
||||||
|
if(backBpp == 2)
|
||||||
|
Blit32to16(specbuf32bpp, (uint16*)destbackup, xr*mult, yr*mult, pitchbackup, backshiftr,backshiftl);
|
||||||
|
else // == 3
|
||||||
|
Blit32to24(specbuf32bpp, (uint8*)destbackup, xr*mult, yr*mult, pitchbackup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(silt == 3)
|
||||||
|
hq3x_32((uint8 *)specbuf,destbackup,xr,yr,pitchbackup);
|
||||||
|
else
|
||||||
|
hq2x_32((uint8 *)specbuf,destbackup,xr,yr,pitchbackup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
int InitBlitToHigh(int b, uint32 rmask, uint32 gmask, uint32 bmask, int eefx, int specfilt);
|
||||||
|
void SetPaletteBlitToHigh(uint8 *src);
|
||||||
|
void KillBlitToHigh(void);
|
||||||
|
void Blit8ToHigh(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, int yscale);
|
||||||
|
void Blit8To8(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, int yscale, int efx, int special);
|
|
@ -0,0 +1,72 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#include "../common/args.h"
|
||||||
|
#include "../common/config.h"
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
extern FCEUGI *CurGame;
|
||||||
|
|
||||||
|
extern CFGSTRUCT DriverConfig[];
|
||||||
|
extern ARGPSTRUCT DriverArgs[];
|
||||||
|
extern char *DriverUsage;
|
||||||
|
|
||||||
|
void DoDriverArgs(void);
|
||||||
|
uint8 *GetBaseDirectory(void);
|
||||||
|
|
||||||
|
int InitSound(FCEUGI *gi);
|
||||||
|
void WriteSound(int32 *Buffer, int Count);
|
||||||
|
int KillSound(void);
|
||||||
|
uint32 GetMaxSound(void);
|
||||||
|
uint32 GetWriteSound(void);
|
||||||
|
|
||||||
|
void SilenceSound(int s); /* DOS and SDL */
|
||||||
|
|
||||||
|
|
||||||
|
int InitMouse(void);
|
||||||
|
void KillMouse(void);
|
||||||
|
void GetMouseData(uint32 *MouseData);
|
||||||
|
|
||||||
|
int InitJoysticks(void);
|
||||||
|
int KillJoysticks(void);
|
||||||
|
uint32 *GetJSOr(void);
|
||||||
|
|
||||||
|
int InitKeyboard(void);
|
||||||
|
int UpdateKeyboard(void);
|
||||||
|
char *GetKeyboard(void);
|
||||||
|
void KillKeyboard(void);
|
||||||
|
|
||||||
|
int InitVideo(FCEUGI *gi);
|
||||||
|
int KillVideo(void);
|
||||||
|
void BlitScreen(uint8 *XBuf);
|
||||||
|
void LockConsole(void);
|
||||||
|
void UnlockConsole(void);
|
||||||
|
void ToggleFS(); /* SDL */
|
||||||
|
|
||||||
|
int LoadGame(const char *path);
|
||||||
|
int CloseGame(void);
|
||||||
|
int GUI_Init(int argc, char **argv, int (*dofunc)(void));
|
||||||
|
int GUI_Idle(void);
|
||||||
|
int GUI_Update(void);
|
||||||
|
void GUI_Hide(int);
|
||||||
|
void GUI_RequestExit(void);
|
||||||
|
int GUI_SetVideo(int fullscreen, int width, int height);
|
||||||
|
char *GUI_GetKeyboard(void);
|
||||||
|
void GUI_GetMouseState(uint32 *b, int *x, int *y);
|
||||||
|
|
||||||
|
void UpdatePhysicalInput(void);
|
||||||
|
int DTestButton(ButtConfig *bc);
|
||||||
|
int DWaitButton(const uint8 *text, ButtConfig *bc, int wb);
|
||||||
|
int ButtonConfigBegin(void);
|
||||||
|
void ButtonConfigEnd(void);
|
||||||
|
|
||||||
|
void Giggles(int);
|
||||||
|
void DoFun(void);
|
||||||
|
|
||||||
|
int FCEUD_NetworkConnect(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <dpmi.h>
|
||||||
|
#include <sys/farptr.h>
|
||||||
|
#include <go32.h>
|
||||||
|
#include <pc.h>
|
||||||
|
|
||||||
|
#include "dos.h"
|
||||||
|
#include "dos-joystick.h"
|
||||||
|
|
||||||
|
#define JOY_A 1
|
||||||
|
#define JOY_B 2
|
||||||
|
#define JOY_SELECT 4
|
||||||
|
#define JOY_START 8
|
||||||
|
#define JOY_UP 0x10
|
||||||
|
#define JOY_DOWN 0x20
|
||||||
|
#define JOY_LEFT 0x40
|
||||||
|
#define JOY_RIGHT 0x80
|
||||||
|
|
||||||
|
int joy=0;
|
||||||
|
int joyBMap[6];
|
||||||
|
|
||||||
|
static int32 joybuttons=0;
|
||||||
|
static uint32 joyx=0;
|
||||||
|
static uint32 joyy=0;
|
||||||
|
static uint32 joyxcenter;
|
||||||
|
static uint32 joyycenter;
|
||||||
|
|
||||||
|
static void ConfigJoystick(void);
|
||||||
|
volatile int soundjoyer=0;
|
||||||
|
volatile int soundjoyeron=0;
|
||||||
|
|
||||||
|
/* Crude method to detect joystick. */
|
||||||
|
static int DetectJoystick(void)
|
||||||
|
{
|
||||||
|
uint8 b;
|
||||||
|
|
||||||
|
outportb(0x201,0);
|
||||||
|
b=inportb(0x201);
|
||||||
|
sleep(1);
|
||||||
|
if((inportb(0x201)&3)==(b&3))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateJoyData(void)
|
||||||
|
{
|
||||||
|
uint32 xc,yc;
|
||||||
|
|
||||||
|
|
||||||
|
joybuttons=((inportb(0x201)&0xF0)^0xF0)>>4;
|
||||||
|
|
||||||
|
xc=yc=0;
|
||||||
|
|
||||||
|
{
|
||||||
|
outportb(0x201,0);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
uint8 b;
|
||||||
|
|
||||||
|
b=inportb(0x201);
|
||||||
|
if(!(b&3))
|
||||||
|
break;
|
||||||
|
if(b&1) xc++;
|
||||||
|
if(b&2) yc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joyx=xc;
|
||||||
|
joyy=yc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 GetJSOr(void)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
unsigned long ret;
|
||||||
|
static int rtoggle=0;
|
||||||
|
ret=0;
|
||||||
|
|
||||||
|
rtoggle^=1;
|
||||||
|
if(!soundo)
|
||||||
|
UpdateJoyData();
|
||||||
|
for(y=0;y<6;y++)
|
||||||
|
if((y>=4 && rtoggle) || y<4)
|
||||||
|
if(joybuttons&joyBMap[y]) ret|=(1<<y&3)<<((joy-1)<<3);
|
||||||
|
|
||||||
|
if(joyx<=joyxcenter*.25) ret|=JOY_LEFT<<((joy-1)<<3);
|
||||||
|
else if(joyx>=joyxcenter*1.75) ret|=JOY_RIGHT<<((joy-1)<<3);
|
||||||
|
if(joyy<=joyycenter*.25) ret|=JOY_UP<<((joy-1)<<3);
|
||||||
|
else if(joyy>=joyycenter*1.75) ret|=JOY_DOWN<<((joy-1)<<3);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitJoysticks(void)
|
||||||
|
{
|
||||||
|
if(!joy) return(0);
|
||||||
|
if(!DetectJoystick())
|
||||||
|
{
|
||||||
|
printf("Joystick not detected!\n");
|
||||||
|
joy=0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(soundo)
|
||||||
|
{
|
||||||
|
soundjoyeron=1;
|
||||||
|
while(!soundjoyer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
UpdateJoyData();
|
||||||
|
|
||||||
|
joyxcenter=joyx;
|
||||||
|
joyycenter=joyy;
|
||||||
|
|
||||||
|
if(!(joyBMap[0]|joyBMap[1]|joyBMap[2]|joyBMap[3]))
|
||||||
|
ConfigJoystick();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BConfig(int b)
|
||||||
|
{
|
||||||
|
int c=0;
|
||||||
|
uint32 st=time(0);
|
||||||
|
|
||||||
|
while(time(0)< (st+4) )
|
||||||
|
{
|
||||||
|
if(!soundo)
|
||||||
|
UpdateJoyData();
|
||||||
|
if(joybuttons) c=joybuttons;
|
||||||
|
else if(c && !joybuttons)
|
||||||
|
{
|
||||||
|
joyBMap[b]=c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillJoysticks(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConfigJoystick(void)
|
||||||
|
{
|
||||||
|
static char *genb="** Press button for ";
|
||||||
|
|
||||||
|
printf("\n\n Joystick button configuration:\n\n");
|
||||||
|
printf(" Push and release the button to map to the virtual joystick.\n");
|
||||||
|
printf(" If you do not wish to assign a button, wait a few seconds\n");
|
||||||
|
printf(" and the configuration will continue.\n\n");
|
||||||
|
printf(" Press enter to continue...\n");
|
||||||
|
getchar();
|
||||||
|
|
||||||
|
printf("%s\"Select\".\n",genb);
|
||||||
|
BConfig(2);
|
||||||
|
|
||||||
|
printf("%s\"Start\".\n",genb);
|
||||||
|
BConfig(3);
|
||||||
|
|
||||||
|
printf("%s\"B\".\n",genb);
|
||||||
|
BConfig(1);
|
||||||
|
|
||||||
|
printf("%s\"A\".\n",genb);
|
||||||
|
BConfig(0);
|
||||||
|
|
||||||
|
printf("%s\"Rapid fire B\".\n",genb);
|
||||||
|
BConfig(5);
|
||||||
|
|
||||||
|
printf("%s\"Rapid fire A\".\n",genb);
|
||||||
|
BConfig(4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
void UpdateJoyData(void);
|
||||||
|
uint32 GetJSOr(void);
|
||||||
|
int InitJoysticks(void);
|
||||||
|
|
||||||
|
/* Variables to save in config file. */
|
||||||
|
extern int joy;
|
||||||
|
extern int joyBMap[6];
|
|
@ -0,0 +1,131 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pc.h>
|
||||||
|
#include <dpmi.h>
|
||||||
|
#include <go32.h>
|
||||||
|
#include "keyscan.h"
|
||||||
|
|
||||||
|
static unsigned char lastsc;
|
||||||
|
static char keybuf[256];
|
||||||
|
int newk;
|
||||||
|
|
||||||
|
/* Read scan code from port $60 */
|
||||||
|
/* Acknowledge interrupt( output $20 to port $20) */
|
||||||
|
|
||||||
|
static void ihandler(_go32_dpmi_registers *r)
|
||||||
|
{
|
||||||
|
unsigned char scode=inp(0x60); /* Get scan code. */
|
||||||
|
|
||||||
|
|
||||||
|
if(scode!=0xE0)
|
||||||
|
{
|
||||||
|
int offs=0;
|
||||||
|
|
||||||
|
/* I'm only interested in preserving the independent status of the
|
||||||
|
right ALT and CONTROL keys.
|
||||||
|
*/
|
||||||
|
if(lastsc==0xE0)
|
||||||
|
if((scode&0x7F)==SCAN_LEFTALT || (scode&0x7F)==SCAN_LEFTCONTROL)
|
||||||
|
offs=0x80;
|
||||||
|
|
||||||
|
|
||||||
|
keybuf[(scode&0x7f)|offs]=((scode&0x80)^0x80);
|
||||||
|
newk++;
|
||||||
|
}
|
||||||
|
lastsc=scode;
|
||||||
|
|
||||||
|
outp(0x20,0x20); /* Acknowledge interrupt. */
|
||||||
|
}
|
||||||
|
|
||||||
|
static _go32_dpmi_seginfo KBIBack,KBIBackRM;
|
||||||
|
static _go32_dpmi_seginfo KBI,KBIRM;
|
||||||
|
static _go32_dpmi_registers KBIRMRegs;
|
||||||
|
static int initdone=0;
|
||||||
|
|
||||||
|
int InitKeyboard(void)
|
||||||
|
{
|
||||||
|
/* I'll assume that the keyboard is in the correct scancode mode(translated
|
||||||
|
mode 2, I think).
|
||||||
|
*/
|
||||||
|
newk=0;
|
||||||
|
memset(keybuf,0,sizeof(keybuf));
|
||||||
|
KBIRM.pm_offset=KBI.pm_offset=(int)ihandler;
|
||||||
|
KBIRM.pm_selector=KBI.pm_selector=_my_cs();
|
||||||
|
|
||||||
|
_go32_dpmi_get_real_mode_interrupt_vector(9,&KBIBackRM);
|
||||||
|
_go32_dpmi_allocate_real_mode_callback_iret(&KBIRM, &KBIRMRegs);
|
||||||
|
_go32_dpmi_set_real_mode_interrupt_vector(9,&KBIRM);
|
||||||
|
|
||||||
|
_go32_dpmi_get_protected_mode_interrupt_vector(9,&KBIBack);
|
||||||
|
_go32_dpmi_allocate_iret_wrapper(&KBI);
|
||||||
|
_go32_dpmi_set_protected_mode_interrupt_vector(9,&KBI);
|
||||||
|
lastsc=0;
|
||||||
|
initdone=1;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillKeyboard(void)
|
||||||
|
{
|
||||||
|
if(initdone)
|
||||||
|
{
|
||||||
|
_go32_dpmi_set_protected_mode_interrupt_vector(9,&KBIBack);
|
||||||
|
_go32_dpmi_free_iret_wrapper(&KBI);
|
||||||
|
|
||||||
|
_go32_dpmi_set_real_mode_interrupt_vector(9,&KBIBackRM);
|
||||||
|
_go32_dpmi_free_real_mode_callback(&KBIRM);
|
||||||
|
initdone=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In FCE Ultra, it doesn't matter if the key states change
|
||||||
|
in the middle of the keyboard handling code. If you want
|
||||||
|
to use this code elsewhere, you may want to memcpy() keybuf
|
||||||
|
to another buffer and return that when GetKeyboard() is
|
||||||
|
called.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *GetKeyboard(void)
|
||||||
|
{
|
||||||
|
return keybuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns 1 on new scan codes generated, 0 on no new scan codes. */
|
||||||
|
int UpdateKeyboard(void)
|
||||||
|
{
|
||||||
|
int t=newk;
|
||||||
|
|
||||||
|
if(t)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"subl %%eax,_newk\n\t"
|
||||||
|
:
|
||||||
|
: "a" (t)
|
||||||
|
);
|
||||||
|
|
||||||
|
if(keybuf[SCAN_LEFTCONTROL] && keybuf[SCAN_C])
|
||||||
|
raise(SIGINT);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dpmi.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "dos.h"
|
||||||
|
|
||||||
|
int InitMouse(void)
|
||||||
|
{
|
||||||
|
__dpmi_regs regs;
|
||||||
|
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.x.ax=0;
|
||||||
|
__dpmi_int(0x33,®s);
|
||||||
|
if(regs.x.ax!=0xFFFF)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.x.ax=0x7;
|
||||||
|
regs.x.cx=0; // Min X
|
||||||
|
regs.x.dx=260; // Max X
|
||||||
|
__dpmi_int(0x33,®s);
|
||||||
|
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.x.ax=0x8;
|
||||||
|
regs.x.cx=0; // Min Y
|
||||||
|
regs.x.dx=260; // Max Y
|
||||||
|
__dpmi_int(0x33,®s);
|
||||||
|
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.x.ax=0xF;
|
||||||
|
regs.x.cx=8; // Mickey X
|
||||||
|
regs.x.dx=8; // Mickey Y
|
||||||
|
__dpmi_int(0x33,®s);
|
||||||
|
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.x.ax=0x2;
|
||||||
|
__dpmi_int(0x33,®s);
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 GetMouseData(uint32 *x, uint32 *y)
|
||||||
|
{
|
||||||
|
if(FCEUI_IsMovieActive()<0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
__dpmi_regs regs;
|
||||||
|
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.x.ax=0x3;
|
||||||
|
__dpmi_int(0x33,®s);
|
||||||
|
|
||||||
|
*x=regs.x.cx;
|
||||||
|
*y=regs.x.dx;
|
||||||
|
return(regs.x.bx&3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillMouse(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,567 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/farptr.h>
|
||||||
|
#include <pc.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <dpmi.h>
|
||||||
|
#include <go32.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "dos.h"
|
||||||
|
#include "dos-sound.h"
|
||||||
|
#include "dos-joystick.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void SBIRQHandler(_go32_dpmi_registers *r);
|
||||||
|
static uint32 LMBuffer; /* Address of low memory DMA playback buffer. */
|
||||||
|
static int LMSelector;
|
||||||
|
|
||||||
|
static uint8 *WaveBuffer;
|
||||||
|
static unsigned int IVector, SBIRQ, SBDMA, SBDMA16, SBPort;
|
||||||
|
static int DSPV,hsmode;
|
||||||
|
static int format;
|
||||||
|
static int frags, fragsize, fragtotal;
|
||||||
|
static volatile int WritePtr, ReadPtr;
|
||||||
|
static volatile int hbusy;
|
||||||
|
static volatile int whichbuf;
|
||||||
|
|
||||||
|
|
||||||
|
static uint8 PICMask;
|
||||||
|
/* Protected mode interrupt vector info. */
|
||||||
|
static _go32_dpmi_seginfo SBIH,SBIHOld;
|
||||||
|
|
||||||
|
/* Real mode interrupt vector info. */
|
||||||
|
static _go32_dpmi_seginfo SBIHRM,SBIHRMOld;
|
||||||
|
static _go32_dpmi_registers SBIHRMRegs;
|
||||||
|
|
||||||
|
static int WriteDSP(uint8 V)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=65536;x;x--)
|
||||||
|
{
|
||||||
|
if(!(inportb(SBPort+0xC)&0x80))
|
||||||
|
{
|
||||||
|
outportb(SBPort+0xC,V);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReadDSP(uint8 *V)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=65536;x;x--) /* Should be more than enough time... */
|
||||||
|
{
|
||||||
|
if(inportb(SBPort+0xE)&0x80)
|
||||||
|
{
|
||||||
|
*V=inportb(SBPort+0xA);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int SetVectors(void)
|
||||||
|
{
|
||||||
|
SBIH.pm_offset=SBIHRM.pm_offset=(int)SBIRQHandler;
|
||||||
|
SBIH.pm_selector=SBIHRM.pm_selector=_my_cs();
|
||||||
|
|
||||||
|
/* Get and set real mode interrupt vector. */
|
||||||
|
_go32_dpmi_get_real_mode_interrupt_vector(IVector,&SBIHRMOld);
|
||||||
|
_go32_dpmi_allocate_real_mode_callback_iret(&SBIHRM, &SBIHRMRegs);
|
||||||
|
_go32_dpmi_set_real_mode_interrupt_vector(IVector,&SBIHRM);
|
||||||
|
|
||||||
|
/* Get and set protected mode interrupt vector. */
|
||||||
|
_go32_dpmi_get_protected_mode_interrupt_vector(IVector,&SBIHOld);
|
||||||
|
_go32_dpmi_allocate_iret_wrapper(&SBIH);
|
||||||
|
_go32_dpmi_set_protected_mode_interrupt_vector(IVector,&SBIH);
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResetVectors(void)
|
||||||
|
{
|
||||||
|
_go32_dpmi_set_protected_mode_interrupt_vector(IVector,&SBIHOld);
|
||||||
|
_go32_dpmi_free_iret_wrapper(&SBIH);
|
||||||
|
_go32_dpmi_set_real_mode_interrupt_vector(IVector,&SBIHRMOld);
|
||||||
|
_go32_dpmi_free_real_mode_callback(&SBIHRM);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetBLASTER(void)
|
||||||
|
{
|
||||||
|
int check=0;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if(!(s=getenv("BLASTER")))
|
||||||
|
{
|
||||||
|
puts(" Error getting BLASTER environment variable.");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(*s)
|
||||||
|
{
|
||||||
|
switch(toupper(*s))
|
||||||
|
{
|
||||||
|
case 'A': check|=(sscanf(s+1,"%x",&SBPort)==1)?1:0;break;
|
||||||
|
case 'I': check|=(sscanf(s+1,"%d",&SBIRQ)==1)?2:0;break;
|
||||||
|
case 'D': check|=(sscanf(s+1,"%d",&SBDMA)==1)?4:0;break;
|
||||||
|
case 'H': check|=(sscanf(s+1,"%d",&SBDMA16)==1)?8:0;break;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((check^7)&7 || SBDMA>=4 || (SBDMA16<=4 && check&8) || SBIRQ>15)
|
||||||
|
{
|
||||||
|
puts(" Invalid or incomplete BLASTER environment variable.");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
if(!(check&8))
|
||||||
|
format=0;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ResetDSP(void)
|
||||||
|
{
|
||||||
|
uint8 b;
|
||||||
|
|
||||||
|
outportb(SBPort+0x6,0x1);
|
||||||
|
delay(10);
|
||||||
|
outportb(SBPort+0x6,0x0);
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
if(ReadDSP(&b))
|
||||||
|
if(b==0xAA)
|
||||||
|
return(1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetDSPVersion(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8 t;
|
||||||
|
|
||||||
|
if(!WriteDSP(0xE1))
|
||||||
|
return(0);
|
||||||
|
if(!ReadDSP(&t))
|
||||||
|
return(0);
|
||||||
|
ret=t<<8;
|
||||||
|
if(!ReadDSP(&t))
|
||||||
|
return(0);
|
||||||
|
ret|=t;
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void KillDMABuffer(void)
|
||||||
|
{
|
||||||
|
__dpmi_free_dos_memory(LMSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int MakeDMABuffer(void)
|
||||||
|
{
|
||||||
|
uint32 size;
|
||||||
|
int32 tmp;
|
||||||
|
|
||||||
|
size=fragsize*2; /* Two buffers in the DMA buffer. */
|
||||||
|
size<<=format; /* Twice the size for 16-bit than for 8-bit. */
|
||||||
|
|
||||||
|
size<<=1; /* Double the size in case the first 2 buffers
|
||||||
|
cross a 64KB or 128KB page boundary.
|
||||||
|
*/
|
||||||
|
size=(size+15)>>4; /* Convert to paragraphs */
|
||||||
|
|
||||||
|
if((tmp=__dpmi_allocate_dos_memory(size,&LMSelector))<0)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
LMBuffer=tmp<<=4;
|
||||||
|
|
||||||
|
if(format) /* Check for and fix 128KB page boundary crossing. */
|
||||||
|
{
|
||||||
|
if((LMBuffer&0x20000) != ((LMBuffer+fragsize*2*2-1)&0x20000))
|
||||||
|
LMBuffer+=fragsize*2*2;
|
||||||
|
}
|
||||||
|
else /* Check for and fix 64KB page boundary crossing. */
|
||||||
|
{
|
||||||
|
if((LMBuffer&0x10000) != ((LMBuffer+fragsize*2-1)&0x10000))
|
||||||
|
LMBuffer+=fragsize*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
DOSMemSet(LMBuffer, format?0:128, (fragsize*2)<<format);
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ProgramDMA(void)
|
||||||
|
{
|
||||||
|
static int PPorts[8]={0x87,0x83,0x81,0x82,0,0x8b,0x89,0x8a};
|
||||||
|
uint32 tmp;
|
||||||
|
|
||||||
|
if(format)
|
||||||
|
{
|
||||||
|
outportb(0xd4,(SBDMA16&0x3)|0x4);
|
||||||
|
outportb(0xd8,0x0);
|
||||||
|
outportb(0xd6,(SBDMA16&0x3)|0x58);
|
||||||
|
tmp=((SBDMA16&3)<<2)+0xC2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outportb(0xA,SBDMA|0x4);
|
||||||
|
outportb(0xC,0x0);
|
||||||
|
outportb(0xB,SBDMA|0x58);
|
||||||
|
tmp=(SBDMA<<1)+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Size of entire buffer. */
|
||||||
|
outportb(tmp,(fragsize*2-1));
|
||||||
|
outportb(tmp,(fragsize*2-1)>>8);
|
||||||
|
|
||||||
|
/* Page of buffer. */
|
||||||
|
outportb(PPorts[format?SBDMA16:SBDMA],LMBuffer>>16);
|
||||||
|
|
||||||
|
/* Offset of buffer within page. */
|
||||||
|
if(format)
|
||||||
|
tmp=((SBDMA16&3)<<2)+0xc0;
|
||||||
|
else
|
||||||
|
tmp=SBDMA<<1;
|
||||||
|
|
||||||
|
outportb(tmp,(LMBuffer>>format));
|
||||||
|
outportb(tmp,(LMBuffer>>(8+format)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitSB(int Rate, int bittage)
|
||||||
|
{
|
||||||
|
hsmode=hbusy=0;
|
||||||
|
whichbuf=1;
|
||||||
|
puts("Initializing Sound Blaster...");
|
||||||
|
|
||||||
|
format=bittage?1:0;
|
||||||
|
frags=8;
|
||||||
|
|
||||||
|
if(Rate<=11025)
|
||||||
|
fragsize=1<<5;
|
||||||
|
else if(Rate<=22050)
|
||||||
|
fragsize=1<<6;
|
||||||
|
else
|
||||||
|
fragsize=1<<7;
|
||||||
|
|
||||||
|
fragtotal=frags*fragsize;
|
||||||
|
WaveBuffer=malloc(fragtotal<<format);
|
||||||
|
|
||||||
|
if(format)
|
||||||
|
memset(WaveBuffer,0,fragtotal*2);
|
||||||
|
else
|
||||||
|
memset(WaveBuffer,128,fragtotal);
|
||||||
|
|
||||||
|
WritePtr=ReadPtr=0;
|
||||||
|
|
||||||
|
if((Rate<8192) || (Rate>65535))
|
||||||
|
{
|
||||||
|
printf(" Unsupported playback rate: %d samples per second\n",Rate);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!GetBLASTER())
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
/* Disable IRQ line in PIC0 or PIC1 */
|
||||||
|
if(SBIRQ>7)
|
||||||
|
{
|
||||||
|
PICMask=inportb(0xA1);
|
||||||
|
outportb(0xA1,PICMask|(1<<(SBIRQ&7)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PICMask=inportb(0x21);
|
||||||
|
outportb(0x21,PICMask|(1<<SBIRQ));
|
||||||
|
}
|
||||||
|
if(!ResetDSP())
|
||||||
|
{
|
||||||
|
puts(" Error resetting the DSP.");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(DSPV=GetDSPVersion()))
|
||||||
|
{
|
||||||
|
puts(" Error getting the DSP version.");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" DSP Version: %d.%d\n",DSPV>>8,DSPV&0xFF);
|
||||||
|
if(DSPV<0x201)
|
||||||
|
{
|
||||||
|
printf(" DSP version number is too low.\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(DSPV<0x400)
|
||||||
|
format=0;
|
||||||
|
if(!MakeDMABuffer())
|
||||||
|
{
|
||||||
|
puts(" Error creating low-memory DMA buffer.");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SBIRQ>7) IVector=SBIRQ+0x68;
|
||||||
|
else IVector=SBIRQ+0x8;
|
||||||
|
|
||||||
|
if(!SetVectors())
|
||||||
|
{
|
||||||
|
puts(" Error setting interrupt vectors.");
|
||||||
|
KillDMABuffer();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reenable IRQ line. */
|
||||||
|
if(SBIRQ>7)
|
||||||
|
outportb(0xA1,PICMask&(~(1<<(SBIRQ&7))));
|
||||||
|
else
|
||||||
|
outportb(0x21,PICMask&(~(1<<SBIRQ)));
|
||||||
|
|
||||||
|
ProgramDMA();
|
||||||
|
|
||||||
|
/* Note that the speaker must always be turned on before the mode transfer
|
||||||
|
byte is sent to the DSP if we're going into high-speed mode, since
|
||||||
|
a real Sound Blaster(at least my SBPro) won't accept DSP commands(except
|
||||||
|
for the reset "command") after it goes into high-speed mode.
|
||||||
|
*/
|
||||||
|
WriteDSP(0xD1); // Turn on DAC speaker
|
||||||
|
|
||||||
|
if(DSPV>=0x400)
|
||||||
|
{
|
||||||
|
WriteDSP(0x41); // Set sampling rate
|
||||||
|
WriteDSP(Rate>>8); // High byte
|
||||||
|
WriteDSP(Rate&0xFF); // Low byte
|
||||||
|
if(!format)
|
||||||
|
{
|
||||||
|
WriteDSP(0xC6); // 8-bit output
|
||||||
|
WriteDSP(0x00); // 8-bit mono unsigned PCM
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteDSP(0xB6); // 16-bit output
|
||||||
|
WriteDSP(0x10); // 16-bit mono signed PCM
|
||||||
|
}
|
||||||
|
WriteDSP((fragsize-1)&0xFF);// Low byte of size
|
||||||
|
WriteDSP((fragsize-1)>>8); // High byte of size
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int tc,command;
|
||||||
|
if(Rate>22050)
|
||||||
|
{
|
||||||
|
tc=(65536-(256000000/Rate))>>8;
|
||||||
|
Rate=256000000/(65536-(tc<<8));
|
||||||
|
command=0x90; // High-speed auto-initialize DMA mode transfer
|
||||||
|
hsmode=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tc=256-(1000000/Rate);
|
||||||
|
Rate=1000000/(256-tc);
|
||||||
|
command=0x1c; // Auto-initialize DMA mode transfer
|
||||||
|
}
|
||||||
|
WriteDSP(0x40); // Set DSP time constant
|
||||||
|
WriteDSP(tc); // time constant
|
||||||
|
WriteDSP(0x48); // Set DSP block transfer size
|
||||||
|
WriteDSP((fragsize-1)&0xFF);
|
||||||
|
WriteDSP((fragsize-1)>>8);
|
||||||
|
|
||||||
|
WriteDSP(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable DMA */
|
||||||
|
if(format)
|
||||||
|
outportb(0xd4,SBDMA16&3);
|
||||||
|
else
|
||||||
|
outportb(0xa,SBDMA);
|
||||||
|
|
||||||
|
printf(" %d hz, %d-bit\n",Rate,8<<format);
|
||||||
|
return(Rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern volatile int soundjoyer;
|
||||||
|
extern volatile int soundjoyeron;
|
||||||
|
static int ssilence=0;
|
||||||
|
|
||||||
|
static void SBIRQHandler(_go32_dpmi_registers *r)
|
||||||
|
{
|
||||||
|
uint32 *src;
|
||||||
|
uint32 dest;
|
||||||
|
int32 x;
|
||||||
|
|
||||||
|
|
||||||
|
if(format)
|
||||||
|
{
|
||||||
|
uint8 status;
|
||||||
|
|
||||||
|
outportb(SBPort+4,0x82);
|
||||||
|
status=inportb(SBPort+5);
|
||||||
|
if(status&2)
|
||||||
|
inportb(SBPort+0x0F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
inportb(SBPort+0x0E);
|
||||||
|
|
||||||
|
#ifdef OLD
|
||||||
|
{
|
||||||
|
uint8 status;
|
||||||
|
|
||||||
|
outportb(SBPort+4,0x82);
|
||||||
|
status=inportb(SBPort+5);
|
||||||
|
if(status&1)
|
||||||
|
inportb(SBPort+0x0E);
|
||||||
|
else if(status&2)
|
||||||
|
inportb(SBPort+0x0F);
|
||||||
|
else
|
||||||
|
return; // Mysterious interrupt source! *eerie music*
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(hbusy)
|
||||||
|
{
|
||||||
|
outportb(0x20,0x20);
|
||||||
|
if(SBIRQ>=8)
|
||||||
|
outportb(0xA0,0x20);
|
||||||
|
whichbuf^=1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hbusy=1;
|
||||||
|
|
||||||
|
{
|
||||||
|
/* This code seems to fail on many SB emulators. Bah.
|
||||||
|
SCREW SB EMULATORS. ^_^ */
|
||||||
|
uint32 count;
|
||||||
|
uint32 block;
|
||||||
|
uint32 port;
|
||||||
|
|
||||||
|
if(format)
|
||||||
|
port=((SBDMA16&3)*4)+0xc2;
|
||||||
|
else
|
||||||
|
port=(SBDMA*2)+1;
|
||||||
|
|
||||||
|
count=inportb(port);
|
||||||
|
count|=inportb(port)<<8;
|
||||||
|
|
||||||
|
if(count>=fragsize)
|
||||||
|
block=1;
|
||||||
|
else
|
||||||
|
block=0;
|
||||||
|
dest=LMBuffer+((block*fragsize)<<format);
|
||||||
|
|
||||||
|
#ifdef MOO
|
||||||
|
dest=LMBuffer+((whichbuf*fragsize)<<format);
|
||||||
|
whichbuf^=1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
_farsetsel(_dos_ds);
|
||||||
|
|
||||||
|
src=(uint32 *)(WaveBuffer+(ReadPtr<<format));
|
||||||
|
|
||||||
|
if(ssilence)
|
||||||
|
{
|
||||||
|
uint32 sby;
|
||||||
|
if(format) sby=0; /* 16-bit silence. */
|
||||||
|
else sby=0x80808080; /* 8-bit silence. */
|
||||||
|
|
||||||
|
for(x=(fragsize<<format)>>2;x;x--,dest+=4)
|
||||||
|
{
|
||||||
|
_farnspokel(dest,sby);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(x=(fragsize<<format)>>2;x;x--,dest+=4,src++)
|
||||||
|
{
|
||||||
|
_farnspokel(dest,*src);
|
||||||
|
}
|
||||||
|
ReadPtr=(ReadPtr+fragsize)&(fragtotal-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(soundjoyeron)
|
||||||
|
{
|
||||||
|
static int coot=0;
|
||||||
|
if(!coot)
|
||||||
|
{
|
||||||
|
UpdateJoyData();
|
||||||
|
soundjoyer=1;
|
||||||
|
}
|
||||||
|
coot=(coot+1)&3;
|
||||||
|
}
|
||||||
|
hbusy=0;
|
||||||
|
outportb(0x20,0x20);
|
||||||
|
if(SBIRQ>=8)
|
||||||
|
outportb(0xA0,0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SilenceSound(int s)
|
||||||
|
{
|
||||||
|
ssilence=s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSBSound(int32 *Buffer, int Count, int NoBlocking)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
if(!format)
|
||||||
|
{
|
||||||
|
for(x=0;x<Count;x++)
|
||||||
|
{
|
||||||
|
while(WritePtr==ReadPtr)
|
||||||
|
if(NoBlocking)
|
||||||
|
return;
|
||||||
|
WaveBuffer[WritePtr]=(uint8)((Buffer[x])>>8)^128;
|
||||||
|
WritePtr=(WritePtr+1)&(fragtotal-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // 16 bit
|
||||||
|
{
|
||||||
|
for(x=0;x<Count;x++)
|
||||||
|
{
|
||||||
|
while(WritePtr==ReadPtr)
|
||||||
|
if(NoBlocking)
|
||||||
|
return;
|
||||||
|
((int16 *)WaveBuffer)[WritePtr]=Buffer[x];
|
||||||
|
WritePtr=(WritePtr+1)&(fragtotal-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillSB(void)
|
||||||
|
{
|
||||||
|
if(hsmode)
|
||||||
|
ResetDSP(); /* High-speed mode requires a DSP reset. */
|
||||||
|
else
|
||||||
|
WriteDSP(format?0xD9:0xDA); /* Exit auto-init DMA transfer mode. */
|
||||||
|
WriteDSP(0xD3); /* Turn speaker off. */
|
||||||
|
|
||||||
|
outportb((SBIRQ>7)?0xA1:0x21,PICMask|(1<<(SBIRQ&7)));
|
||||||
|
ResetVectors();
|
||||||
|
outportb((SBIRQ>7)?0xA1:0x21,PICMask);
|
||||||
|
KillDMABuffer();
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
int InitSB(int Rate, int bittage);
|
||||||
|
void KillSB(void);
|
||||||
|
|
||||||
|
void WriteSBSound(int32 *Buffer, int Count, int NoBlocking);
|
||||||
|
void SilenceSound(int s);
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 1998 \Firebug\
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dpmi.h>
|
||||||
|
#include <sys/farptr.h>
|
||||||
|
#include <go32.h>
|
||||||
|
#include <pc.h>
|
||||||
|
|
||||||
|
#include "dos.h"
|
||||||
|
#include "dos-video.h"
|
||||||
|
|
||||||
|
#define TEXT 3
|
||||||
|
#define G320x200x256 0x13
|
||||||
|
|
||||||
|
static void vga_waitretrace(void)
|
||||||
|
{
|
||||||
|
while(inp(0x3da)&0x8);
|
||||||
|
while(!(inp(0x3da)&0x8));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vga_setmode(int mode)
|
||||||
|
{
|
||||||
|
__dpmi_regs regs;
|
||||||
|
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.x.ax=mode;
|
||||||
|
|
||||||
|
__dpmi_int(0x10,®s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_setpalette(int i, int r, int g, int b)
|
||||||
|
{
|
||||||
|
outp(0x3c8,i);
|
||||||
|
outp(0x3c9,r);
|
||||||
|
outp(0x3c9,g);
|
||||||
|
outp(0x3c9,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUDvmode=1;
|
||||||
|
|
||||||
|
static int vidready=0;
|
||||||
|
|
||||||
|
/* Part of the VGA low-level mass register setting code derived from
|
||||||
|
code by \Firebug\.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vgatweak.c"
|
||||||
|
|
||||||
|
void SetBorder(void)
|
||||||
|
{
|
||||||
|
inportb(0x3da);
|
||||||
|
outportb(0x3c0,(0x11|0x20));
|
||||||
|
outportb(0x3c0,0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TweakVGA(int VGAMode)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
|
||||||
|
vga_waitretrace();
|
||||||
|
|
||||||
|
outportb(0x3C8,0x00);
|
||||||
|
for(I=0;I<768;I++) outportb(0x3C9,0x00);
|
||||||
|
|
||||||
|
outportb(0x3D4,0x11);
|
||||||
|
I=inportb(0x3D5)&0x7F;
|
||||||
|
outportb(0x3D4,0x11);
|
||||||
|
outportb(0x3D5,I);
|
||||||
|
|
||||||
|
switch(VGAMode)
|
||||||
|
{
|
||||||
|
case 1: for(I=0;I<25;I++) VGAPortSet(v256x240[I]);break;
|
||||||
|
case 2: for(I=0;I<25;I++) VGAPortSet(v256x256[I]);break;
|
||||||
|
case 3: for(I=0;I<25;I++) VGAPortSet(v256x256S[I]);break;
|
||||||
|
case 6: for(I=0;I<25;I++) VGAPortSet(v256x224S[I]);break;
|
||||||
|
case 8: for(I=0;I<25;I++) VGAPortSet(v256x224_103[I]);break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
outportb(0x3da,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8 palettedbr[256],palettedbg[256],palettedbb[256];
|
||||||
|
|
||||||
|
static void FlushPalette(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=0;x<256;x++)
|
||||||
|
{
|
||||||
|
int z=x;
|
||||||
|
vga_setpalette(z,palettedbr[x]>>2,palettedbg[x]>>2,palettedbb[x]>>2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
|
||||||
|
{
|
||||||
|
palettedbr[index]=r;
|
||||||
|
palettedbg[index]=g;
|
||||||
|
palettedbb[index]=b;
|
||||||
|
if(vidready)
|
||||||
|
{
|
||||||
|
vga_setpalette(index,r>>2,g>>2,b>>2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FCEUD_GetPalette(uint8 i, uint8 *r, uint8 *g, uint8 *b)
|
||||||
|
{
|
||||||
|
*r=palettedbr[i];
|
||||||
|
*g=palettedbg[i];
|
||||||
|
*b=palettedbb[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 ScreenLoc;
|
||||||
|
|
||||||
|
int InitVideo(void)
|
||||||
|
{
|
||||||
|
vidready=0;
|
||||||
|
switch(FCEUDvmode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
vga_setmode(G320x200x256);
|
||||||
|
vidready|=1;
|
||||||
|
ScreenLoc=0xa0000;
|
||||||
|
TweakVGA(FCEUDvmode);
|
||||||
|
SetBorder();
|
||||||
|
DOSMemSet(ScreenLoc, 128, 256*256);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vidready|=2;
|
||||||
|
FlushPalette();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillVideo(void)
|
||||||
|
{
|
||||||
|
if(vidready)
|
||||||
|
{
|
||||||
|
vga_setmode(TEXT);
|
||||||
|
vidready=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void LockConsole(void){}
|
||||||
|
void UnlockConsole(void){}
|
||||||
|
void BlitScreen(uint8 *XBuf)
|
||||||
|
{
|
||||||
|
uint32 dest;
|
||||||
|
int tlines;
|
||||||
|
|
||||||
|
if(eoptions&4 && !NoWaiting)
|
||||||
|
vga_waitretrace();
|
||||||
|
|
||||||
|
tlines=erendline-srendline+1;
|
||||||
|
|
||||||
|
dest=ScreenLoc;
|
||||||
|
|
||||||
|
switch(FCEUDvmode)
|
||||||
|
{
|
||||||
|
case 1:dest+=(((240-tlines)>>1)<<8);break;
|
||||||
|
case 2:
|
||||||
|
case 3:dest+=(((256-tlines)>>1)<<8);break;
|
||||||
|
case 4:
|
||||||
|
case 5:dest+=(((240-tlines)>>1)*640+((640-512)>>1));break;
|
||||||
|
case 8:
|
||||||
|
case 6:if(tlines>224) tlines=224;dest+=(((224-tlines)>>1)<<8);break;
|
||||||
|
}
|
||||||
|
|
||||||
|
XBuf+=(srendline<<8)+(srendline<<4);
|
||||||
|
|
||||||
|
_farsetsel(_dos_ds);
|
||||||
|
if(eoptions&DO_CLIPSIDES)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"agoop1:\n\t"
|
||||||
|
"movl $30,%%eax\n\t"
|
||||||
|
"agoop2:\n\t"
|
||||||
|
"movl (%%esi),%%edx\n\t"
|
||||||
|
"movl 4(%%esi),%%ecx\n\t"
|
||||||
|
".byte 0x64 \n\t"
|
||||||
|
"movl %%edx,(%%edi)\n\t"
|
||||||
|
".byte 0x64 \n\t"
|
||||||
|
"movl %%ecx,4(%%edi)\n\t"
|
||||||
|
"addl $8,%%esi\n\t"
|
||||||
|
"addl $8,%%edi\n\t"
|
||||||
|
"decl %%eax\n\t"
|
||||||
|
"jne agoop2\n\t"
|
||||||
|
"addl $32,%%esi\n\t"
|
||||||
|
"addl $16,%%edi\n\t"
|
||||||
|
"decb %%bl\n\t"
|
||||||
|
"jne agoop1\n\t"
|
||||||
|
:
|
||||||
|
: "S" (XBuf+8), "D" (dest+8), "b" (tlines)
|
||||||
|
: "%eax","%cc","%edx","%ecx" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"goop1:\n\t"
|
||||||
|
"movl $32,%%eax\n\t"
|
||||||
|
"goop2:\n\t"
|
||||||
|
"movl (%%esi),%%edx\n\t"
|
||||||
|
"movl 4(%%esi),%%ecx\n\t"
|
||||||
|
".byte 0x64 \n\t"
|
||||||
|
"movl %%edx,(%%edi)\n\t"
|
||||||
|
".byte 0x64 \n\t"
|
||||||
|
"movl %%ecx,4(%%edi)\n\t"
|
||||||
|
"addl $8,%%esi\n\t"
|
||||||
|
"addl $8,%%edi\n\t"
|
||||||
|
"decl %%eax\n\t"
|
||||||
|
"jne goop2\n\t"
|
||||||
|
"addl $16,%%esi\n\t"
|
||||||
|
"decb %%bl\n\t"
|
||||||
|
"jne goop1\n\t"
|
||||||
|
:
|
||||||
|
: "S" (XBuf), "D" (dest), "b" (tlines)
|
||||||
|
: "%eax","%cc","%edx","%ecx" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int FCEUDvmode;
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <crt0.h>
|
||||||
|
#include <sys/farptr.h>
|
||||||
|
#include <go32.h>
|
||||||
|
|
||||||
|
#include "dos.h"
|
||||||
|
#include "dos-joystick.h"
|
||||||
|
#include "dos-video.h"
|
||||||
|
#include "dos-sound.h"
|
||||||
|
#include "../common/args.h"
|
||||||
|
#include "../common/config.h"
|
||||||
|
|
||||||
|
/* _CRT0_FLAG_LOCK_MEMORY might not always result in all memory being locked.
|
||||||
|
Bummer. I'll add code to explicitly lock the data touched by the sound
|
||||||
|
interrupt handler(and the handler itself), if necessary(though that might
|
||||||
|
be tricky...). I'll also to cover the data the keyboard
|
||||||
|
interrupt handler touches.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _crt0_startup_flags = _CRT0_FLAG_FILL_SBRK_MEMORY | _CRT0_FLAG_LOCK_MEMORY | _CRT0_FLAG_USE_DOS_SLASHES;
|
||||||
|
|
||||||
|
static int f8bit=0;
|
||||||
|
int soundo=44100;
|
||||||
|
int doptions=0;
|
||||||
|
|
||||||
|
|
||||||
|
CFGSTRUCT DriverConfig[]={
|
||||||
|
NAC("sound",soundo),
|
||||||
|
AC(doptions),
|
||||||
|
AC(f8bit),
|
||||||
|
AC(FCEUDvmode),
|
||||||
|
NACA("joybmap",joyBMap),
|
||||||
|
AC(joy),
|
||||||
|
ENDCFGSTRUCT
|
||||||
|
};
|
||||||
|
|
||||||
|
char *DriverUsage=
|
||||||
|
"-vmode x Select video mode(all are 8 bpp).\n\
|
||||||
|
1 = 256x240 6 = 256x224(with scanlines)\n\
|
||||||
|
2 = 256x256 8 = 256x224\n\
|
||||||
|
3 = 256x256(with scanlines)\n\
|
||||||
|
-vsync x Wait for the screen's vertical retrace before updating the\n\
|
||||||
|
screen. Refer to the documentation for caveats.\n\
|
||||||
|
0 = Disabled.\n\
|
||||||
|
1 = Enabled.\n\
|
||||||
|
-sound x Sound.\n\
|
||||||
|
0 = Disabled.\n\
|
||||||
|
Otherwise, x = playback rate.\n\
|
||||||
|
-f8bit x Force 8-bit sound.\n\
|
||||||
|
0 = Disabled.\n\
|
||||||
|
1 = Enabled.";
|
||||||
|
|
||||||
|
ARGPSTRUCT DriverArgs[]={
|
||||||
|
{"-vmode",0,&FCEUDvmode,0},
|
||||||
|
{"-sound",0,&soundo,0},
|
||||||
|
{"-f8bit",0,&f8bit,0},
|
||||||
|
{"-vsync",0,&doptions,DO_VSYNC},
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
void DoDriverArgs(void)
|
||||||
|
{
|
||||||
|
if(!joy) memset(joyBMap,0,sizeof(joyBMap));
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitSound(void)
|
||||||
|
{
|
||||||
|
if(soundo)
|
||||||
|
{
|
||||||
|
if(soundo==1)
|
||||||
|
soundo=44100;
|
||||||
|
soundo=InitSB(soundo,f8bit?0:1);
|
||||||
|
FCEUI_Sound(soundo);
|
||||||
|
}
|
||||||
|
return(soundo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSound(int32 *Buffer, int Count, int NoWaiting)
|
||||||
|
{
|
||||||
|
WriteSBSound(Buffer,Count,NoWaiting);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillSound(void)
|
||||||
|
{
|
||||||
|
if(soundo)
|
||||||
|
KillSB();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOSMemSet(uint32 A, uint8 V, uint32 count)
|
||||||
|
{
|
||||||
|
uint32 x;
|
||||||
|
|
||||||
|
_farsetsel(_dos_ds);
|
||||||
|
for(x=0;x<count;x++)
|
||||||
|
_farnspokeb(A+x,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *arg0;
|
||||||
|
uint8 *GetBaseDirectory(void)
|
||||||
|
{
|
||||||
|
int x=0;
|
||||||
|
uint8 *ret = 0;
|
||||||
|
|
||||||
|
if(arg0)
|
||||||
|
for(x=strlen(arg0);x>=0;x--)
|
||||||
|
{
|
||||||
|
if(arg0[x]=='/' || arg0[x]=='\\')
|
||||||
|
{
|
||||||
|
ret = malloc(x + 1);
|
||||||
|
strncpy(ret,arg0,x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ret) { x=0; ret = malloc(1); }
|
||||||
|
|
||||||
|
BaseDirectory[x]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
puts("\nStarting FCE Ultra "VERSION_STRING"...\n");
|
||||||
|
arg0=argv[0];
|
||||||
|
return(CLImain(argc,argv));
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "dface.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
void DOSMemSet(uint32 A, uint8 V, uint32 count);
|
||||||
|
#define DO_VSYNC 1
|
||||||
|
|
|
@ -0,0 +1,720 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "dface.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
#include "../common/cheat.h"
|
||||||
|
|
||||||
|
/* UsrInputType[] is user-specified. InputType[] is current
|
||||||
|
(game loading can override user settings)
|
||||||
|
*/
|
||||||
|
int UsrInputType[3]={SI_GAMEPAD,SI_GAMEPAD,SIFC_NONE};
|
||||||
|
int InputType[3]={0,0,0};
|
||||||
|
static int cspec=0;
|
||||||
|
|
||||||
|
int gametype=0;
|
||||||
|
|
||||||
|
/* Necessary for proper GUI functioning(configuring when a game isn't loaded). */
|
||||||
|
void InputUserActiveFix(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=0;x<3;x++) InputType[x]=UsrInputType[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseGIInput(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
gametype=gi->type;
|
||||||
|
|
||||||
|
InputType[0]=UsrInputType[0];
|
||||||
|
InputType[1]=UsrInputType[1];
|
||||||
|
InputType[2]=UsrInputType[2];
|
||||||
|
|
||||||
|
if(gi->input[0]>=0)
|
||||||
|
InputType[0]=gi->input[0];
|
||||||
|
if(gi->input[1]>=0)
|
||||||
|
InputType[1]=gi->input[1];
|
||||||
|
if(gi->inputfc>=0)
|
||||||
|
InputType[2]=gi->inputfc;
|
||||||
|
cspec = gi->cspecial;
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
Giggles(gi->cspecial);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8 QuizKingData=0;
|
||||||
|
static uint8 HyperShotData=0;
|
||||||
|
static uint32 MahjongData=0;
|
||||||
|
static uint32 FTrainerData=0;
|
||||||
|
static uint8 TopRiderData=0;
|
||||||
|
|
||||||
|
static uint8 BWorldData[1+13+1];
|
||||||
|
|
||||||
|
static void UpdateFKB(void);
|
||||||
|
static void UpdateGamepad(void);
|
||||||
|
static void UpdateQuizKing(void);
|
||||||
|
static void UpdateHyperShot(void);
|
||||||
|
static void UpdateMahjong(void);
|
||||||
|
static void UpdateFTrainer(void);
|
||||||
|
static void UpdateTopRider(void);
|
||||||
|
|
||||||
|
static uint32 JSreturn=0;
|
||||||
|
int NoWaiting=1;
|
||||||
|
|
||||||
|
#ifndef EXTGUI
|
||||||
|
static void DoCheatSeq(void)
|
||||||
|
{
|
||||||
|
#if defined(DOS) || defined(SDL)
|
||||||
|
SilenceSound(1);
|
||||||
|
#endif
|
||||||
|
KillKeyboard();
|
||||||
|
KillVideo();
|
||||||
|
|
||||||
|
DoConsoleCheatConfig();
|
||||||
|
InitVideo(CurGame);
|
||||||
|
InitKeyboard();
|
||||||
|
#if defined(DOS) || defined(SDL)
|
||||||
|
SilenceSound(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "keyscan.h"
|
||||||
|
static char *keys=0;
|
||||||
|
static int DIPS=0;
|
||||||
|
|
||||||
|
static uint8 keyonce[MKK_COUNT];
|
||||||
|
#define KEY(__a) keys[MKK(__a)]
|
||||||
|
|
||||||
|
static int _keyonly(int a)
|
||||||
|
{
|
||||||
|
if(keys[a])
|
||||||
|
{
|
||||||
|
if(!keyonce[a])
|
||||||
|
{
|
||||||
|
keyonce[a]=1;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
keyonce[a]=0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define keyonly(__a) _keyonly(MKK(__a))
|
||||||
|
|
||||||
|
static int cidisabled=0;
|
||||||
|
|
||||||
|
static void KeyboardCommands(void)
|
||||||
|
{
|
||||||
|
int is_shift, is_alt;
|
||||||
|
|
||||||
|
keys=GetKeyboard();
|
||||||
|
|
||||||
|
if(InputType[2]==SIFC_FKB)
|
||||||
|
{
|
||||||
|
if(keyonly(SCROLLLOCK))
|
||||||
|
{
|
||||||
|
cidisabled^=1;
|
||||||
|
FCEUI_DispMessage("Family Keyboard %sabled.",cidisabled?"en":"dis");
|
||||||
|
}
|
||||||
|
#ifdef SDL
|
||||||
|
SDL_WM_GrabInput(cidisabled?SDL_GRAB_ON:SDL_GRAB_OFF);
|
||||||
|
#endif
|
||||||
|
if(cidisabled) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_shift = KEY(LEFTSHIFT) | KEY(RIGHTSHIFT);
|
||||||
|
is_alt = KEY(LEFTALT) | KEY(RIGHTALT);
|
||||||
|
|
||||||
|
if(keyonly(F4))
|
||||||
|
{
|
||||||
|
if(is_shift) FCEUI_SetRenderDisable(-1, 2);
|
||||||
|
else FCEUI_SetRenderDisable(2, -1);
|
||||||
|
}
|
||||||
|
#ifdef SDL
|
||||||
|
if(keyonly(ENTER) && is_alt) ToggleFS();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NoWaiting&=~1;
|
||||||
|
if(KEY(GRAVE))
|
||||||
|
NoWaiting|=1;
|
||||||
|
|
||||||
|
if(gametype==GIT_FDS)
|
||||||
|
{
|
||||||
|
if(keyonly(F6)) FCEUI_FDSSelect();
|
||||||
|
if(keyonly(F8)) FCEUI_FDSInsert();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(keyonly(F9)) FCEUI_SaveSnapshot();
|
||||||
|
if(gametype!=GIT_NSF)
|
||||||
|
{
|
||||||
|
#ifndef EXTGUI
|
||||||
|
if(keyonly(F2)) DoCheatSeq();
|
||||||
|
#endif
|
||||||
|
if(keyonly(F5))
|
||||||
|
{
|
||||||
|
if(is_shift)
|
||||||
|
FCEUI_SaveMovie(NULL,0,NULL);
|
||||||
|
else
|
||||||
|
FCEUI_SaveState(NULL);
|
||||||
|
}
|
||||||
|
if(keyonly(F7))
|
||||||
|
{
|
||||||
|
if(is_shift)
|
||||||
|
FCEUI_LoadMovie(NULL,0);
|
||||||
|
else
|
||||||
|
FCEUI_LoadState(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(keyonly(F1)) FCEUI_ToggleTileView();
|
||||||
|
|
||||||
|
if(keyonly(MINUS)) DecreaseEmulationSpeed();
|
||||||
|
if(keyonly(EQUAL)) IncreaseEmulationSpeed();
|
||||||
|
if(keyonly(BACKSPACE)) FCEUI_MovieToggleFrameDisplay();
|
||||||
|
if(keyonly(BACKSLASH)) FCEUI_ToggleEmulationPause();
|
||||||
|
if(keyonly(RIGHTCONTROL)) FCEUI_FrameAdvance();
|
||||||
|
|
||||||
|
if(keyonly(F10)) FCEUI_ResetNES();
|
||||||
|
if(keyonly(F11)) FCEUI_PowerNES();
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
if(keyonly(F3)) GUI_Hide(-1);
|
||||||
|
if(KEY(F12)) GUI_RequestExit();
|
||||||
|
if(KEY(ESCAPE)) CloseGame();
|
||||||
|
#else
|
||||||
|
if(KEY(F12) || KEY(ESCAPE)) CloseGame();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(gametype==GIT_VSUNI)
|
||||||
|
{
|
||||||
|
if(keyonly(F8)) FCEUI_VSUniCoin();
|
||||||
|
if(keyonly(F6))
|
||||||
|
{
|
||||||
|
DIPS^=1;
|
||||||
|
FCEUI_VSUniToggleDIPView();
|
||||||
|
}
|
||||||
|
if(!(DIPS&1)) goto DIPSless;
|
||||||
|
if(keyonly(1)) FCEUI_VSUniToggleDIP(0);
|
||||||
|
if(keyonly(2)) FCEUI_VSUniToggleDIP(1);
|
||||||
|
if(keyonly(3)) FCEUI_VSUniToggleDIP(2);
|
||||||
|
if(keyonly(4)) FCEUI_VSUniToggleDIP(3);
|
||||||
|
if(keyonly(5)) FCEUI_VSUniToggleDIP(4);
|
||||||
|
if(keyonly(6)) FCEUI_VSUniToggleDIP(5);
|
||||||
|
if(keyonly(7)) FCEUI_VSUniToggleDIP(6);
|
||||||
|
if(keyonly(8)) FCEUI_VSUniToggleDIP(7);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static uint8 bbuf[32];
|
||||||
|
static int bbuft;
|
||||||
|
static int barcoder = 0;
|
||||||
|
|
||||||
|
if(keyonly(H)) FCEUI_NTSCSELHUE();
|
||||||
|
if(keyonly(T)) FCEUI_NTSCSELTINT();
|
||||||
|
if(KEY(KP_MINUS) || KEY(MINUS)) FCEUI_NTSCDEC();
|
||||||
|
if(KEY(KP_PLUS) || KEY(EQUAL)) FCEUI_NTSCINC();
|
||||||
|
|
||||||
|
if((InputType[2] == SIFC_BWORLD) || (cspec == SIS_DATACH))
|
||||||
|
{
|
||||||
|
if(keyonly(F8))
|
||||||
|
{
|
||||||
|
barcoder ^= 1;
|
||||||
|
if(!barcoder)
|
||||||
|
{
|
||||||
|
if(InputType[2] == SIFC_BWORLD)
|
||||||
|
{
|
||||||
|
strcpy(&BWorldData[1],bbuf);
|
||||||
|
BWorldData[0]=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FCEUI_DatachSet(bbuf);
|
||||||
|
FCEUI_DispMessage("Barcode Entered");
|
||||||
|
}
|
||||||
|
else { bbuft = 0; FCEUI_DispMessage("Enter Barcode");}
|
||||||
|
}
|
||||||
|
} else barcoder = 0;
|
||||||
|
|
||||||
|
#define SSM(x) \
|
||||||
|
{ if(barcoder) { if(bbuft < 13) {bbuf[bbuft++] = '0' + x; bbuf[bbuft] = 0;} FCEUI_DispMessage("Barcode: %s",bbuf);} \
|
||||||
|
else { \
|
||||||
|
if(is_shift) FCEUI_SelectMovie(x,1); \
|
||||||
|
else FCEUI_SelectState(x,1); \
|
||||||
|
} }
|
||||||
|
|
||||||
|
DIPSless:
|
||||||
|
if(keyonly(0)) SSM(0);
|
||||||
|
if(keyonly(1)) SSM(1);
|
||||||
|
if(keyonly(2)) SSM(2);
|
||||||
|
if(keyonly(3)) SSM(3);
|
||||||
|
if(keyonly(4)) SSM(4);
|
||||||
|
if(keyonly(5)) SSM(5);
|
||||||
|
if(keyonly(6)) SSM(6);
|
||||||
|
if(keyonly(7)) SSM(7);
|
||||||
|
if(keyonly(8)) SSM(8);
|
||||||
|
if(keyonly(9)) SSM(9);
|
||||||
|
#undef SSM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MK(x) {{BUTTC_KEYBOARD},{0},{MKK(x)},1}
|
||||||
|
#define MK2(x1,x2) {{BUTTC_KEYBOARD},{0},{MKK(x1),MKK(x2)},2}
|
||||||
|
|
||||||
|
#define MKZ() {{0},{0},{0},0}
|
||||||
|
|
||||||
|
#define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()}
|
||||||
|
|
||||||
|
ButtConfig GamePadConfig[4][10]={
|
||||||
|
/* Gamepad 1 */
|
||||||
|
{
|
||||||
|
MK(KP3), MK(KP2), MK(TAB), MK(ENTER), MK(W),MK(Z),
|
||||||
|
MK(A), MK(S), MKZ(), MKZ()
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Gamepad 2 */
|
||||||
|
GPZ(),
|
||||||
|
|
||||||
|
/* Gamepad 3 */
|
||||||
|
GPZ(),
|
||||||
|
|
||||||
|
/* Gamepad 4 */
|
||||||
|
GPZ()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void UpdateGamepad(void)
|
||||||
|
{
|
||||||
|
if(FCEUI_IsMovieActive()<0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static int rapid=0;
|
||||||
|
uint32 JS=0;
|
||||||
|
int x;
|
||||||
|
int wg;
|
||||||
|
|
||||||
|
rapid^=1;
|
||||||
|
|
||||||
|
for(wg=0;wg<4;wg++)
|
||||||
|
{
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
if(DTestButton(&GamePadConfig[wg][x]))
|
||||||
|
JS|=(1<<x)<<(wg<<3);
|
||||||
|
|
||||||
|
if(rapid)
|
||||||
|
for(x=0;x<2;x++)
|
||||||
|
if(DTestButton(&GamePadConfig[wg][8+x]))
|
||||||
|
JS|=(1<<x)<<(wg<<3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for(x=0;x<32;x+=8) /* Now, test to see if anything weird(up+down at same time)
|
||||||
|
// is happening, and correct */
|
||||||
|
// {
|
||||||
|
// if((JS & (0xC0<<x) ) == (0xC0<<x) ) JS&=~(0xC0<<x);
|
||||||
|
// if((JS & (0x30<<x) ) == (0x30<<x) ) JS&=~(0x30<<x);
|
||||||
|
// }
|
||||||
|
|
||||||
|
JSreturn=JS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtConfig powerpadsc[2][12]={
|
||||||
|
{
|
||||||
|
MK(O),MK(P),MK(BRACKET_LEFT),
|
||||||
|
MK(BRACKET_RIGHT),MK(K),MK(L),MK(SEMICOLON),
|
||||||
|
MK(APOSTROPHE),
|
||||||
|
MK(M),MK(COMMA),MK(PERIOD),MK(SLASH)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MK(O),MK(P),MK(BRACKET_LEFT),
|
||||||
|
MK(BRACKET_RIGHT),MK(K),MK(L),MK(SEMICOLON),
|
||||||
|
MK(APOSTROPHE),
|
||||||
|
MK(M),MK(COMMA),MK(PERIOD),MK(SLASH)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32 powerpadbuf[2]={0,0};
|
||||||
|
|
||||||
|
static uint32 UpdatePPadData(int w)
|
||||||
|
{
|
||||||
|
if(FCEUI_IsMovieActive()<0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32 r=0;
|
||||||
|
ButtConfig *ppadtsc=powerpadsc[w];
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<12;x++)
|
||||||
|
if(DTestButton(&ppadtsc[x])) r|=1<<x;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 MouseData[3]={0,0,0};
|
||||||
|
static uint8 fkbkeys[0x48];
|
||||||
|
|
||||||
|
void FCEUD_UpdateInput(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int t=0;
|
||||||
|
|
||||||
|
UpdatePhysicalInput();
|
||||||
|
KeyboardCommands();
|
||||||
|
|
||||||
|
for(x=0;x<2;x++)
|
||||||
|
switch(InputType[x])
|
||||||
|
{
|
||||||
|
case SI_GAMEPAD:t|=1;break;
|
||||||
|
case SI_ARKANOID:t|=2;break;
|
||||||
|
case SI_ZAPPER:t|=2;break;
|
||||||
|
case SI_POWERPADA:
|
||||||
|
case SI_POWERPADB:powerpadbuf[x]=UpdatePPadData(x);break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(InputType[2])
|
||||||
|
{
|
||||||
|
case SIFC_ARKANOID:t|=2;break;
|
||||||
|
case SIFC_SHADOW:t|=2;break;
|
||||||
|
case SIFC_FKB:if(cidisabled) UpdateFKB();break;
|
||||||
|
case SIFC_HYPERSHOT: UpdateHyperShot();break;
|
||||||
|
case SIFC_MAHJONG: UpdateMahjong();break;
|
||||||
|
case SIFC_QUIZKING: UpdateQuizKing();break;
|
||||||
|
case SIFC_FTRAINERB:
|
||||||
|
case SIFC_FTRAINERA: UpdateFTrainer();break;
|
||||||
|
case SIFC_TOPRIDER: UpdateTopRider();break;
|
||||||
|
case SIFC_OEKAKIDS:t|=2;break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(t&1)
|
||||||
|
UpdateGamepad();
|
||||||
|
|
||||||
|
if(t&2)
|
||||||
|
GetMouseData(MouseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitOtherInput(void)
|
||||||
|
{
|
||||||
|
void *InputDPtr;
|
||||||
|
|
||||||
|
int t;
|
||||||
|
int x;
|
||||||
|
int attrib;
|
||||||
|
|
||||||
|
for(t=0,x=0;x<2;x++)
|
||||||
|
{
|
||||||
|
attrib=0;
|
||||||
|
InputDPtr=0;
|
||||||
|
switch(InputType[x])
|
||||||
|
{
|
||||||
|
case SI_POWERPADA:
|
||||||
|
case SI_POWERPADB:InputDPtr=&powerpadbuf[x];break;
|
||||||
|
case SI_GAMEPAD:InputDPtr=&JSreturn;break;
|
||||||
|
case SI_ARKANOID:InputDPtr=MouseData;t|=1;break;
|
||||||
|
case SI_ZAPPER:InputDPtr=MouseData;
|
||||||
|
t|=1;
|
||||||
|
attrib=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
|
||||||
|
}
|
||||||
|
|
||||||
|
attrib=0;
|
||||||
|
InputDPtr=0;
|
||||||
|
switch(InputType[2])
|
||||||
|
{
|
||||||
|
case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
|
||||||
|
case SIFC_OEKAKIDS:InputDPtr=MouseData;t|=1;attrib=1;break;
|
||||||
|
case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
|
||||||
|
case SIFC_FKB:InputDPtr=fkbkeys;break;
|
||||||
|
case SIFC_HYPERSHOT:InputDPtr=&HyperShotData;break;
|
||||||
|
case SIFC_MAHJONG:InputDPtr=&MahjongData;break;
|
||||||
|
case SIFC_QUIZKING:InputDPtr=&QuizKingData;break;
|
||||||
|
case SIFC_TOPRIDER:InputDPtr=&TopRiderData;break;
|
||||||
|
case SIFC_BWORLD:InputDPtr=BWorldData;break;
|
||||||
|
case SIFC_FTRAINERA:
|
||||||
|
case SIFC_FTRAINERB:InputDPtr=&FTrainerData;break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FCEUI_SetInputFC(InputType[2],InputDPtr,attrib);
|
||||||
|
FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
|
||||||
|
|
||||||
|
if(t)
|
||||||
|
InitMouse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ButtConfig fkbmap[0x48]=
|
||||||
|
{
|
||||||
|
MK(F1),MK(F2),MK(F3),MK(F4),MK(F5),MK(F6),MK(F7),MK(F8),
|
||||||
|
MK(1),MK(2),MK(3),MK(4),MK(5),MK(6),MK(7),MK(8),MK(9),MK(0),
|
||||||
|
MK(MINUS),MK(EQUAL),MK(BACKSLASH),MK(BACKSPACE),
|
||||||
|
MK(ESCAPE),MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y),MK(U),MK(I),MK(O),
|
||||||
|
MK(P),MK(GRAVE),MK(BRACKET_LEFT),MK(ENTER),
|
||||||
|
MK(LEFTCONTROL),MK(A),MK(S),MK(D),MK(F),MK(G),MK(H),MK(J),MK(K),
|
||||||
|
MK(L),MK(SEMICOLON),MK(APOSTROPHE),MK(BRACKET_RIGHT),MK(INSERT),
|
||||||
|
MK(LEFTSHIFT),MK(Z),MK(X),MK(C),MK(V),MK(B),MK(N),MK(M),MK(COMMA),
|
||||||
|
MK(PERIOD),MK(SLASH),MK(RIGHTALT),MK(RIGHTSHIFT),MK(LEFTALT),MK(SPACE),
|
||||||
|
MK(DELETE),MK(END),MK(PAGEDOWN),
|
||||||
|
MK(CURSORUP),MK(CURSORLEFT),MK(CURSORRIGHT),MK(CURSORDOWN)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateFKB(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<0x48;x++)
|
||||||
|
{
|
||||||
|
fkbkeys[x]=0;
|
||||||
|
|
||||||
|
if(DTestButton(&fkbmap[x]))
|
||||||
|
fkbkeys[x]=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ButtConfig HyperShotButtons[4]=
|
||||||
|
{
|
||||||
|
MK(Q),MK(W),MK(E),MK(R)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateHyperShot(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
HyperShotData=0;
|
||||||
|
for(x=0;x<0x4;x++)
|
||||||
|
{
|
||||||
|
if(DTestButton(&HyperShotButtons[x]))
|
||||||
|
HyperShotData|=1<<x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ButtConfig MahjongButtons[21]=
|
||||||
|
{
|
||||||
|
MK(Q),MK(W),MK(E),MK(R),MK(T),
|
||||||
|
MK(A),MK(S),MK(D),MK(F),MK(G),MK(H),MK(J),MK(K),MK(L),
|
||||||
|
MK(Z),MK(X),MK(C),MK(V),MK(B),MK(N),MK(M)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateMahjong(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
MahjongData=0;
|
||||||
|
for(x=0;x<21;x++)
|
||||||
|
{
|
||||||
|
if(DTestButton(&MahjongButtons[x]))
|
||||||
|
MahjongData|=1<<x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtConfig QuizKingButtons[6]=
|
||||||
|
{
|
||||||
|
MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateQuizKing(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
QuizKingData=0;
|
||||||
|
|
||||||
|
for(x=0;x<6;x++)
|
||||||
|
{
|
||||||
|
if(DTestButton(&QuizKingButtons[x]))
|
||||||
|
QuizKingData|=1<<x;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtConfig TopRiderButtons[8]=
|
||||||
|
{
|
||||||
|
MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y),MK(U),MK(I)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateTopRider(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
TopRiderData=0;
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
if(DTestButton(&TopRiderButtons[x]))
|
||||||
|
TopRiderData|=1<<x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtConfig FTrainerButtons[12]=
|
||||||
|
{
|
||||||
|
MK(O),MK(P),MK(BRACKET_LEFT),
|
||||||
|
MK(BRACKET_RIGHT),MK(K),MK(L),MK(SEMICOLON),
|
||||||
|
MK(APOSTROPHE),
|
||||||
|
MK(M),MK(COMMA),MK(PERIOD),MK(SLASH)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateFTrainer(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
FTrainerData=0;
|
||||||
|
|
||||||
|
for(x=0;x<12;x++)
|
||||||
|
{
|
||||||
|
if(DTestButton(&FTrainerButtons[x]))
|
||||||
|
FTrainerData|=1<<x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subcon(char *text, ButtConfig *bc)
|
||||||
|
{
|
||||||
|
uint8 buf[256];
|
||||||
|
int wc;
|
||||||
|
|
||||||
|
for(wc=0;wc<MAXBUTTCONFIG;wc++)
|
||||||
|
{
|
||||||
|
sprintf(buf,"%s (%d)",text,wc+1);
|
||||||
|
DWaitButton(buf,bc,wc);
|
||||||
|
|
||||||
|
if(wc && bc->ButtType[wc]==bc->ButtType[wc-1] && bc->DeviceNum[wc]==bc->DeviceNum[wc-1] &&
|
||||||
|
bc->ButtonNum[wc]==bc->ButtonNum[wc-1])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bc->NumC=wc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigDevice(int which, int arg)
|
||||||
|
{
|
||||||
|
uint8 buf[256];
|
||||||
|
int x;
|
||||||
|
|
||||||
|
ButtonConfigBegin();
|
||||||
|
switch(which)
|
||||||
|
{
|
||||||
|
case FCFGD_QUIZKING:
|
||||||
|
for(x=0;x<6;x++)
|
||||||
|
{
|
||||||
|
sprintf(buf,"Quiz King Buzzer #%d", x+1);
|
||||||
|
subcon(buf,&QuizKingButtons[x]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FCFGD_HYPERSHOT:
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
{
|
||||||
|
sprintf(buf,"Hyper Shot %d: %s",((x&2)>>1)+1,(x&1)?"JUMP":"RUN");
|
||||||
|
subcon(buf,&HyperShotButtons[x]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FCFGD_POWERPAD:
|
||||||
|
for(x=0;x<12;x++)
|
||||||
|
{
|
||||||
|
sprintf(buf,"PowerPad %d: %d", (arg&1)+1,x+11);
|
||||||
|
subcon(buf,&powerpadsc[arg&1][x]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FCFGD_GAMEPAD:
|
||||||
|
{
|
||||||
|
char *str[10]={"A","B","SELECT","START","UP","DOWN","LEFT","RIGHT","Rapid A","Rapid B"};
|
||||||
|
for(x=0;x<10;x++)
|
||||||
|
{
|
||||||
|
sprintf(buf,"GamePad #%d: %s",arg+1,str[x]);
|
||||||
|
subcon(buf,&GamePadConfig[arg][x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonConfigEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CFGSTRUCT InputConfig[]={
|
||||||
|
ACA(UsrInputType),
|
||||||
|
AC(powerpadsc),
|
||||||
|
AC(QuizKingButtons),
|
||||||
|
AC(FTrainerButtons),
|
||||||
|
AC(HyperShotButtons),
|
||||||
|
AC(MahjongButtons),
|
||||||
|
AC(GamePadConfig),
|
||||||
|
AC(fkbmap),
|
||||||
|
ENDCFGSTRUCT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void InputCfg(char *text)
|
||||||
|
{
|
||||||
|
if(!strncasecmp(text,"gamepad",strlen("gamepad")))
|
||||||
|
{
|
||||||
|
ConfigDevice(FCFGD_GAMEPAD,(text[strlen("gamepad")]-'1')&3);
|
||||||
|
}
|
||||||
|
else if(!strncasecmp(text,"powerpad",strlen("powerpad")))
|
||||||
|
{
|
||||||
|
ConfigDevice(FCFGD_POWERPAD,(text[strlen("powerpad")]-'1')&1);
|
||||||
|
}
|
||||||
|
else if(!strcasecmp(text,"hypershot"))
|
||||||
|
ConfigDevice(FCFGD_HYPERSHOT,0);
|
||||||
|
else if(!strcasecmp(text,"quizking"))
|
||||||
|
ConfigDevice(FCFGD_QUIZKING,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FCExp(char *text)
|
||||||
|
{
|
||||||
|
static char *fccortab[11]={"none","arkanoid","shadow","4player","fkb","hypershot",
|
||||||
|
"mahjong","quizking","ftrainera","ftrainerb","oekakids"};
|
||||||
|
|
||||||
|
static int fccortabi[11]={SIFC_NONE,SIFC_ARKANOID,SIFC_SHADOW,
|
||||||
|
SIFC_4PLAYER,SIFC_FKB,SIFC_HYPERSHOT,SIFC_MAHJONG,SIFC_QUIZKING,
|
||||||
|
SIFC_FTRAINERA,SIFC_FTRAINERB,SIFC_OEKAKIDS};
|
||||||
|
int y;
|
||||||
|
for(y=0;y<11;y++)
|
||||||
|
if(!strcmp(fccortab[y],text))
|
||||||
|
UsrInputType[2]=fccortabi[y];
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *cortab[6]={"none","gamepad","zapper","powerpada","powerpadb","arkanoid"};
|
||||||
|
static int cortabi[6]={SI_NONE,SI_GAMEPAD,
|
||||||
|
SI_ZAPPER,SI_POWERPADA,SI_POWERPADB,SI_ARKANOID};
|
||||||
|
|
||||||
|
static void Input1(char *text)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
|
||||||
|
for(y=0;y<6;y++)
|
||||||
|
if(!strcmp(cortab[y],text))
|
||||||
|
UsrInputType[0]=cortabi[y];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Input2(char *text)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
|
||||||
|
for(y=0;y<6;y++)
|
||||||
|
if(!strcmp(cortab[y],text))
|
||||||
|
UsrInputType[1]=cortabi[y];
|
||||||
|
}
|
||||||
|
|
||||||
|
ARGPSTRUCT InputArgs[]={
|
||||||
|
{"-inputcfg",0,(void *)InputCfg,0x2000},
|
||||||
|
{"-fcexp",0,(void *)FCExp,0x2000},
|
||||||
|
{"-input1",0,(void *)Input1,0x2000},
|
||||||
|
{"-input2",0,(void *)Input2,0x2000},
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef _aosdfjk02fmasf
|
||||||
|
#define _aosdfjk02fmasf
|
||||||
|
#define MAXBUTTCONFIG 4
|
||||||
|
typedef struct {
|
||||||
|
uint8 ButtType[MAXBUTTCONFIG];
|
||||||
|
uint8 DeviceNum[MAXBUTTCONFIG];
|
||||||
|
uint16 ButtonNum[MAXBUTTCONFIG];
|
||||||
|
uint32 NumC;
|
||||||
|
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
|
||||||
|
} ButtConfig;
|
||||||
|
|
||||||
|
extern CFGSTRUCT InputConfig[];
|
||||||
|
extern ARGPSTRUCT InputArgs[];
|
||||||
|
void ParseGIInput(FCEUGI *GI);
|
||||||
|
|
||||||
|
#define BUTTC_KEYBOARD 0x00
|
||||||
|
#define BUTTC_JOYSTICK 0x01
|
||||||
|
#define BUTTC_MOUSE 0x02
|
||||||
|
|
||||||
|
#define FCFGD_GAMEPAD 1
|
||||||
|
#define FCFGD_POWERPAD 2
|
||||||
|
#define FCFGD_HYPERSHOT 3
|
||||||
|
#define FCFGD_QUIZKING 4
|
||||||
|
|
||||||
|
void InitOtherInput(void);
|
||||||
|
void InputUserActiveFix(void);
|
||||||
|
#ifdef EXTGUI
|
||||||
|
extern ButtConfig GamePadConfig[4][10];
|
||||||
|
extern ButtConfig powerpadsc[2][12];
|
||||||
|
extern ButtConfig QuizKingButtons[6];
|
||||||
|
extern ButtConfig FTrainerButtons[12];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void IncreaseEmulationSpeed(void);
|
||||||
|
void DecreaseEmulationSpeed(void);
|
||||||
|
|
||||||
|
void FCEUD_UpdateInput(void);
|
||||||
|
#endif
|
|
@ -0,0 +1,161 @@
|
||||||
|
#ifdef SDL
|
||||||
|
#include <SDL.h>
|
||||||
|
#define SDLK_A SDLK_a
|
||||||
|
#define SDLK_B SDLK_b
|
||||||
|
#define SDLK_C SDLK_c
|
||||||
|
#define SDLK_D SDLK_d
|
||||||
|
#define SDLK_E SDLK_e
|
||||||
|
#define SDLK_F SDLK_f
|
||||||
|
#define SDLK_G SDLK_g
|
||||||
|
#define SDLK_H SDLK_h
|
||||||
|
#define SDLK_I SDLK_i
|
||||||
|
#define SDLK_J SDLK_j
|
||||||
|
#define SDLK_K SDLK_k
|
||||||
|
#define SDLK_L SDLK_l
|
||||||
|
#define SDLK_M SDLK_m
|
||||||
|
#define SDLK_N SDLK_n
|
||||||
|
#define SDLK_O SDLK_o
|
||||||
|
#define SDLK_P SDLK_p
|
||||||
|
#define SDLK_Q SDLK_q
|
||||||
|
#define SDLK_R SDLK_r
|
||||||
|
#define SDLK_S SDLK_s
|
||||||
|
#define SDLK_T SDLK_t
|
||||||
|
#define SDLK_U SDLK_u
|
||||||
|
#define SDLK_V SDLK_v
|
||||||
|
#define SDLK_W SDLK_w
|
||||||
|
#define SDLK_X SDLK_x
|
||||||
|
#define SDLK_Y SDLK_y
|
||||||
|
#define SDLK_Z SDLK_z
|
||||||
|
#define SDLK_LEFTCONTROL SDLK_LCTRL
|
||||||
|
#define SDLK_RIGHTCONTROL SDLK_RCTRL
|
||||||
|
#define SDLK_LEFTALT SDLK_LALT
|
||||||
|
#define SDLK_RIGHTALT SDLK_RALT
|
||||||
|
#define SDLK_LEFTSHIFT SDLK_LSHIFT
|
||||||
|
#define SDLK_RIGHTSHIFT SDLK_RSHIFT
|
||||||
|
#define SDLK_CURSORDOWN SDLK_DOWN
|
||||||
|
#define SDLK_CURSORUP SDLK_UP
|
||||||
|
#define SDLK_CURSORLEFT SDLK_LEFT
|
||||||
|
#define SDLK_CURSORRIGHT SDLK_RIGHT
|
||||||
|
#define SDLK_ENTER SDLK_RETURN
|
||||||
|
#define SDLK_EQUAL SDLK_EQUALS
|
||||||
|
#define SDLK_APOSTROPHE SDLK_QUOTE
|
||||||
|
#define SDLK_BRACKET_LEFT SDLK_LEFTBRACKET
|
||||||
|
#define SDLK_BRACKET_RIGHT SDLK_RIGHTBRACKET
|
||||||
|
#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */
|
||||||
|
#define SDLK_GRAVE SDLK_BACKQUOTE
|
||||||
|
#define MKK(k) SDLK_##k
|
||||||
|
#define MKK_COUNT (SDLK_LAST+1)
|
||||||
|
|
||||||
|
#elif DOS
|
||||||
|
|
||||||
|
#define SCAN_GRAVE 0x29
|
||||||
|
#define SCAN_1 0x02
|
||||||
|
#define SCAN_2 0x03
|
||||||
|
#define SCAN_3 0x04
|
||||||
|
#define SCAN_4 0x05
|
||||||
|
#define SCAN_5 0x06
|
||||||
|
#define SCAN_6 0x07
|
||||||
|
#define SCAN_7 0x08
|
||||||
|
#define SCAN_8 0x09
|
||||||
|
#define SCAN_9 0x0A
|
||||||
|
#define SCAN_0 0x0B
|
||||||
|
#define SCAN_MINUS 0x0C
|
||||||
|
#define SCAN_EQUAL 0x0D
|
||||||
|
#define SCAN_BACKSLASH 0x2B
|
||||||
|
#define SCAN_BACKSPACE 0x0E
|
||||||
|
#define SCAN_TAB 0x0F
|
||||||
|
#define SCAN_Q 0x10
|
||||||
|
#define SCAN_W 0x11
|
||||||
|
#define SCAN_E 0x12
|
||||||
|
#define SCAN_R 0x13
|
||||||
|
#define SCAN_T 0x14
|
||||||
|
#define SCAN_Y 0x15
|
||||||
|
#define SCAN_U 0x16
|
||||||
|
#define SCAN_I 0x17
|
||||||
|
#define SCAN_O 0x18
|
||||||
|
#define SCAN_P 0x19
|
||||||
|
#define SCAN_BRACKET_LEFT 0x1A
|
||||||
|
#define SCAN_BRACKET_RIGHT 0x1B
|
||||||
|
#define SCAN_LOWBACKSLASH 0x2B
|
||||||
|
#define SCAN_CAPSLOCK 0x3A
|
||||||
|
#define SCAN_A 0x1E
|
||||||
|
#define SCAN_S 0x1F
|
||||||
|
#define SCAN_D 0x20
|
||||||
|
#define SCAN_F 0x21
|
||||||
|
#define SCAN_G 0x22
|
||||||
|
#define SCAN_H 0x23
|
||||||
|
#define SCAN_J 0x24
|
||||||
|
#define SCAN_K 0x25
|
||||||
|
#define SCAN_L 0x26
|
||||||
|
#define SCAN_SEMICOLON 0x27
|
||||||
|
#define SCAN_APOSTROPHE 0x28
|
||||||
|
#define SCAN_ENTER 0x1C
|
||||||
|
#define SCAN_LEFTSHIFT 0x2A
|
||||||
|
#define SCAN_Z 0x2C
|
||||||
|
#define SCAN_X 0x2D
|
||||||
|
#define SCAN_C 0x2E
|
||||||
|
#define SCAN_V 0x2F
|
||||||
|
#define SCAN_B 0x30
|
||||||
|
#define SCAN_N 0x31
|
||||||
|
#define SCAN_M 0x32
|
||||||
|
#define SCAN_COMMA 0x33
|
||||||
|
#define SCAN_PERIOD 0x34
|
||||||
|
#define SCAN_SLASH 0x35
|
||||||
|
#define SCAN_RIGHTSHIFT 0x36
|
||||||
|
#define SCAN_LEFTCONTROL 0x1D
|
||||||
|
#define SCAN_LEFTALT 0x38
|
||||||
|
#define SCAN_SPACE 0x39
|
||||||
|
|
||||||
|
/* Extended keys. */
|
||||||
|
#define SCAN_RIGHTALT (0x38|0x80)
|
||||||
|
#define SCAN_RIGHTCONTROL (0x1D|0x80)
|
||||||
|
#define SCAN_BL_INSERT (0x52|0x80)
|
||||||
|
#define SCAN_BL_DELETE (0x53|0x80)
|
||||||
|
#define SCAN_BL_CURSORLEFT (0x4B|0x80)
|
||||||
|
#define SCAN_BL_HOME (0x47|0x80)
|
||||||
|
#define SCAN_BL_END (0x4F|0x80)
|
||||||
|
#define SCAN_BL_CURSORUP (0x48|0x80)
|
||||||
|
#define SCAN_BL_CURSORDOWN (0x50|0x80)
|
||||||
|
#define SCAN_BL_PAGEUP (0x49|0x80)
|
||||||
|
#define SCAN_BL_PAGEDOWN (0x51|0x80)
|
||||||
|
#define SCAN_BL_CURSORRIGHT (0x4D|0x80)
|
||||||
|
|
||||||
|
#define SCAN_SCROLLLOCK 0x46
|
||||||
|
/* Keys often found in the key pad area. */
|
||||||
|
#define SCAN_NUMLOCK 0x45
|
||||||
|
#define SCAN_HOME 0x47
|
||||||
|
#define SCAN_CURSORLEFT 0x4B
|
||||||
|
#define SCAN_END 0x4F
|
||||||
|
#define SCAN_SLASH 0x35
|
||||||
|
#define SCAN_CURSORUP 0x48
|
||||||
|
#define SCAN_CENTER 0x4C
|
||||||
|
#define SCAN_CURSORDOWN 0x50
|
||||||
|
#define SCAN_INSERT 0x52
|
||||||
|
#define SCAN_PAUSE 0xC5
|
||||||
|
#define SCAN_ASTERISK 0x37
|
||||||
|
#define SCAN_PAGEUP 0x49
|
||||||
|
#define SCAN_CURSORRIGHT 0x4D
|
||||||
|
#define SCAN_PAGEDOWN 0x51
|
||||||
|
#define SCAN_DELETE 0x53
|
||||||
|
#define SCAN_KP_MINUS 0x4A
|
||||||
|
#define SCAN_KP_PLUS 0x4E
|
||||||
|
#define SCAN_KP_ENTER 0x1C
|
||||||
|
|
||||||
|
#define SCAN_ESCAPE 0x01
|
||||||
|
#define SCAN_F1 0x3B
|
||||||
|
#define SCAN_F2 0x3C
|
||||||
|
#define SCAN_F3 0x3D
|
||||||
|
#define SCAN_F4 0x3E
|
||||||
|
#define SCAN_F5 0x3F
|
||||||
|
#define SCAN_F6 0x40
|
||||||
|
#define SCAN_F7 0x41
|
||||||
|
#define SCAN_F8 0x42
|
||||||
|
#define SCAN_F9 0x43
|
||||||
|
#define SCAN_F10 0x44
|
||||||
|
#define SCAN_F11 0x57
|
||||||
|
#define SCAN_F12 0x58
|
||||||
|
|
||||||
|
#define MK_COUNT 256
|
||||||
|
#define MK(k) SCAN_##k
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,553 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "throttle.h"
|
||||||
|
|
||||||
|
#include "../common/cheat.h"
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
#include "dface.h"
|
||||||
|
|
||||||
|
extern int32 fps_scale;
|
||||||
|
|
||||||
|
int CloseGame(void);
|
||||||
|
|
||||||
|
static char *soundrecfn=0; /* File name of sound recording. */
|
||||||
|
|
||||||
|
static int ntsccol=0,ntschue=0,ntsctint=0;
|
||||||
|
int soundvol=100;
|
||||||
|
long soundq=0;
|
||||||
|
int _sound=1;
|
||||||
|
long soundrate=48000;
|
||||||
|
#ifdef WIN32
|
||||||
|
long soundbufsize=52;
|
||||||
|
#else
|
||||||
|
long soundbufsize=24;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FRAMESKIP
|
||||||
|
static int frameskip=0;
|
||||||
|
#endif
|
||||||
|
static int inited=0;
|
||||||
|
static int isloaded=0; // Is game loaded?
|
||||||
|
|
||||||
|
int srendlinev[2]={8,0};
|
||||||
|
int erendlinev[2]={231,239};
|
||||||
|
|
||||||
|
|
||||||
|
static uint8 *DrBaseDirectory;
|
||||||
|
|
||||||
|
int eoptions=0;
|
||||||
|
|
||||||
|
static void DriverKill(void);
|
||||||
|
static int DriverInitialize(FCEUGI *gi);
|
||||||
|
int gametype;
|
||||||
|
|
||||||
|
FCEUGI *CurGame=NULL;
|
||||||
|
|
||||||
|
static void ParseGI(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
ParseGIInput(gi);
|
||||||
|
gametype=gi->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef EXTGUI
|
||||||
|
void FCEUD_PrintError(char *s)
|
||||||
|
{
|
||||||
|
puts(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_Message(char *s)
|
||||||
|
{
|
||||||
|
fputs(s,stdout);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *cpalette=0;
|
||||||
|
static void LoadCPalette(void)
|
||||||
|
{
|
||||||
|
uint8 tmpp[192];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if(!(fp=FCEUD_UTF8fopen(cpalette,"rb")))
|
||||||
|
{
|
||||||
|
printf(" Error loading custom palette from file: %s\n",cpalette);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fread(tmpp,1,192,fp);
|
||||||
|
FCEUI_SetPaletteArray(tmpp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
#ifdef EXTGUI
|
||||||
|
extern CFGSTRUCT GUIConfig;
|
||||||
|
#endif
|
||||||
|
static CFGSTRUCT fceuconfig[]={
|
||||||
|
AC(soundrate),
|
||||||
|
AC(soundq),
|
||||||
|
AC(_sound),
|
||||||
|
AC(soundvol),
|
||||||
|
AC(soundbufsize),
|
||||||
|
ACS(cpalette),
|
||||||
|
AC(ntsctint),
|
||||||
|
AC(ntschue),
|
||||||
|
AC(ntsccol),
|
||||||
|
AC(eoptions),
|
||||||
|
ACA(srendlinev),
|
||||||
|
ACA(erendlinev),
|
||||||
|
ADDCFGSTRUCT(InputConfig),
|
||||||
|
ADDCFGSTRUCT(DriverConfig),
|
||||||
|
#ifdef EXTGUI
|
||||||
|
ADDCFGSTRUCT(GUIConfig),
|
||||||
|
#endif
|
||||||
|
ENDCFGSTRUCT
|
||||||
|
};
|
||||||
|
|
||||||
|
static void SaveConfig(void)
|
||||||
|
{
|
||||||
|
char tdir[2048];
|
||||||
|
sprintf(tdir,"%s"PSS"fceu98.cfg",DrBaseDirectory);
|
||||||
|
FCEUI_GetNTSCTH(&ntsctint, &ntschue);
|
||||||
|
SaveFCEUConfig(tdir,fceuconfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LoadConfig(void)
|
||||||
|
{
|
||||||
|
char tdir[2048];
|
||||||
|
sprintf(tdir,"%s"PSS"fceu98.cfg",DrBaseDirectory);
|
||||||
|
FCEUI_GetNTSCTH(&ntsctint, &ntschue); /* Get default settings for if
|
||||||
|
no config file exists. */
|
||||||
|
LoadFCEUConfig(tdir,fceuconfig);
|
||||||
|
InputUserActiveFix();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateDirs(void)
|
||||||
|
{
|
||||||
|
char *subs[7]={"fcs","fcm","snaps","gameinfo","sav","cheats","movie"};
|
||||||
|
char tdir[2048];
|
||||||
|
int x;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
mkdir(DrBaseDirectory);
|
||||||
|
for(x=0;x<6;x++)
|
||||||
|
{
|
||||||
|
sprintf(tdir,"%s"PSS"%s",DrBaseDirectory,subs[x]);
|
||||||
|
mkdir(tdir);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
mkdir(DrBaseDirectory,S_IRWXU);
|
||||||
|
for(x=0;x<6;x++)
|
||||||
|
{
|
||||||
|
sprintf(tdir,"%s"PSS"%s",DrBaseDirectory,subs[x]);
|
||||||
|
mkdir(tdir,S_IRWXU);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
static void SetSignals(void (*t)(int))
|
||||||
|
{
|
||||||
|
int sigs[11]={SIGINT,SIGTERM,SIGHUP,SIGPIPE,SIGSEGV,SIGFPE,SIGKILL,SIGALRM,SIGABRT,SIGUSR1,SIGUSR2};
|
||||||
|
int x;
|
||||||
|
for(x=0;x<11;x++)
|
||||||
|
signal(sigs[x],t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CloseStuff(int signum)
|
||||||
|
{
|
||||||
|
DriverKill();
|
||||||
|
printf("\nSignal %d has been caught and dealt with...\n",signum);
|
||||||
|
switch(signum)
|
||||||
|
{
|
||||||
|
case SIGINT:printf("How DARE you interrupt me!\n");break;
|
||||||
|
case SIGTERM:printf("MUST TERMINATE ALL HUMANS\n");break;
|
||||||
|
case SIGHUP:printf("Reach out and hang-up on someone.\n");break;
|
||||||
|
case SIGPIPE:printf("The pipe has broken! Better watch out for floods...\n");break;
|
||||||
|
case SIGSEGV:printf("Iyeeeeeeeee!!! A segmentation fault has occurred. Have a fluffy day.\n");break;
|
||||||
|
/* So much SIGBUS evil. */
|
||||||
|
#ifdef SIGBUS
|
||||||
|
#if(SIGBUS!=SIGSEGV)
|
||||||
|
case SIGBUS:printf("I told you to be nice to the driver.\n");break;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
case SIGFPE:printf("Those darn floating points. Ne'er know when they'll bite!\n");break;
|
||||||
|
case SIGALRM:printf("Don't throw your clock at the meowing cats!\n");break;
|
||||||
|
case SIGABRT:printf("Abort, Retry, Ignore, Fail?\n");break;
|
||||||
|
case SIGUSR1:
|
||||||
|
case SIGUSR2:printf("Killing your processes is not nice.\n");break;
|
||||||
|
}
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void DoArgs(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
static ARGPSTRUCT FCEUArgs[]={
|
||||||
|
{"-soundbufsize",0,&soundbufsize,0},
|
||||||
|
{"-soundrate",0,&soundrate,0},
|
||||||
|
{"-soundq",0,&soundq,0},
|
||||||
|
#ifdef FRAMESKIP
|
||||||
|
{"-frameskip",0,&frameskip,0},
|
||||||
|
#endif
|
||||||
|
{"-sound",0,&_sound,0},
|
||||||
|
{"-soundvol",0,&soundvol,0},
|
||||||
|
{"-cpalette",0,&cpalette,0x4001},
|
||||||
|
{"-soundrecord",0,&soundrecfn,0x4001},
|
||||||
|
|
||||||
|
{"-ntsccol",0,&ntsccol,0},
|
||||||
|
{"-pal",0,&eoptions,0x8000|EO_PAL},
|
||||||
|
|
||||||
|
{"-lowpass",0,&eoptions,0x8000|EO_LOWPASS},
|
||||||
|
{"-gg",0,&eoptions,0x8000|EO_GAMEGENIE},
|
||||||
|
{"-no8lim",0,&eoptions,0x8001},
|
||||||
|
{"-snapname",0,&eoptions,0x8000|EO_SNAPNAME},
|
||||||
|
{"-nofs",0,&eoptions,0x8000|EO_NOFOURSCORE},
|
||||||
|
{"-clipsides",0,&eoptions,0x8000|EO_CLIPSIDES},
|
||||||
|
{"-nothrottle",0,&eoptions,0x8000|EO_NOTHROTTLE},
|
||||||
|
{"-slstart",0,&srendlinev[0],0},{"-slend",0,&erendlinev[0],0},
|
||||||
|
{"-slstartp",0,&srendlinev[1],0},{"-slendp",0,&erendlinev[1],0},
|
||||||
|
{0,(int *)InputArgs,0,0},
|
||||||
|
{0,(int *)DriverArgs,0,0},
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseArguments(argc, argv, FCEUArgs);
|
||||||
|
if(cpalette)
|
||||||
|
{
|
||||||
|
if(cpalette[0]=='0')
|
||||||
|
if(cpalette[1]==0)
|
||||||
|
{
|
||||||
|
free(cpalette);
|
||||||
|
cpalette=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FCEUI_SetVidSystem((eoptions&EO_PAL)?1:0);
|
||||||
|
FCEUI_SetGameGenie((eoptions&EO_GAMEGENIE)?1:0);
|
||||||
|
FCEUI_SetLowPass((eoptions&EO_LOWPASS)?1:0);
|
||||||
|
|
||||||
|
FCEUI_DisableSpriteLimitation(eoptions&1);
|
||||||
|
FCEUI_SetSnapName(eoptions&EO_SNAPNAME);
|
||||||
|
|
||||||
|
for(x=0;x<2;x++)
|
||||||
|
{
|
||||||
|
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
|
||||||
|
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
|
||||||
|
}
|
||||||
|
|
||||||
|
FCEUI_SetRenderedLines(srendlinev[0],erendlinev[0],srendlinev[1],erendlinev[1]);
|
||||||
|
DoDriverArgs();
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "usage.h"
|
||||||
|
|
||||||
|
/* Loads a game, given a full path/filename. The driver code must be
|
||||||
|
initialized after the game is loaded, because the emulator code
|
||||||
|
provides data necessary for the driver code(number of scanlines to
|
||||||
|
render, what virtual input devices to use, etc.).
|
||||||
|
*/
|
||||||
|
int LoadGame(const char *path)
|
||||||
|
{
|
||||||
|
FCEUGI *tmp;
|
||||||
|
|
||||||
|
CloseGame();
|
||||||
|
if(!(tmp=FCEUI_LoadGame(path,1)))
|
||||||
|
return 0;
|
||||||
|
CurGame=tmp;
|
||||||
|
ParseGI(tmp);
|
||||||
|
RefreshThrottleFPS();
|
||||||
|
|
||||||
|
if(!DriverInitialize(tmp))
|
||||||
|
return(0);
|
||||||
|
if(soundrecfn)
|
||||||
|
{
|
||||||
|
if(!FCEUI_BeginWaveRecord(soundrecfn))
|
||||||
|
{
|
||||||
|
free(soundrecfn);
|
||||||
|
soundrecfn=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isloaded=1;
|
||||||
|
#ifdef EXTGUI
|
||||||
|
if(eoptions&EO_AUTOHIDE) GUI_Hide(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FCEUD_NetworkConnect();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Closes a game. Frees memory, and deinitializes the drivers. */
|
||||||
|
int CloseGame(void)
|
||||||
|
{
|
||||||
|
if(!isloaded) return(0);
|
||||||
|
FCEUI_CloseGame();
|
||||||
|
DriverKill();
|
||||||
|
isloaded=0;
|
||||||
|
CurGame=0;
|
||||||
|
|
||||||
|
if(soundrecfn)
|
||||||
|
FCEUI_EndWaveRecord();
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
GUI_Hide(0);
|
||||||
|
#endif
|
||||||
|
InputUserActiveFix();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count);
|
||||||
|
|
||||||
|
void DoFun(void)
|
||||||
|
{
|
||||||
|
uint8 *gfx;
|
||||||
|
int32 *sound;
|
||||||
|
int32 ssize;
|
||||||
|
static int fskipc=0;
|
||||||
|
static int opause=0;
|
||||||
|
|
||||||
|
#ifdef FRAMESKIP
|
||||||
|
fskipc=(fskipc+1)%(frameskip+1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(NoWaiting) {gfx=0;}
|
||||||
|
FCEUI_Emulate(&gfx, &sound, &ssize, fskipc);
|
||||||
|
FCEUD_Update(gfx, sound, ssize);
|
||||||
|
|
||||||
|
if(opause!=FCEUI_EmulationPaused())
|
||||||
|
{
|
||||||
|
opause=FCEUI_EmulationPaused();
|
||||||
|
SilenceSound(opause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int CLImain(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(!(ret=FCEUI_Initialize()))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
DrBaseDirectory=GetBaseDirectory();
|
||||||
|
FCEUI_SetBaseDirectory(DrBaseDirectory);
|
||||||
|
|
||||||
|
CreateDirs();
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
if(argc==2 && !strcmp(argv[1],"-help")) // I hope no one has a game named "-help" :b
|
||||||
|
#else
|
||||||
|
if(argc<=1)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ShowUsage(argv[0]);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadConfig();
|
||||||
|
DoArgs(argc-2,&argv[1]);
|
||||||
|
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
||||||
|
if(cpalette)
|
||||||
|
LoadCPalette();
|
||||||
|
|
||||||
|
/* All the config files and arguments are parsed now. */
|
||||||
|
#ifdef EXTGUI
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
#else
|
||||||
|
if(!LoadGame(argv[argc-1]))
|
||||||
|
{
|
||||||
|
DriverKill();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(CurGame)
|
||||||
|
DoFun();
|
||||||
|
|
||||||
|
#if(0)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=1;x<argc;x++)
|
||||||
|
{ LoadGame(argv[x]); while(CurGame) DoFun(); }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CloseGame();
|
||||||
|
|
||||||
|
SaveConfig();
|
||||||
|
|
||||||
|
FCEUI_Kill();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DriverInitialize(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
SetSignals(CloseStuff);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialize video before all else, due to some wacko dependencies
|
||||||
|
in the SexyAL code(DirectSound) that need to be fixed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(!InitVideo(gi)) return 0;
|
||||||
|
inited|=4;
|
||||||
|
|
||||||
|
if(InitSound(gi))
|
||||||
|
inited|=1;
|
||||||
|
|
||||||
|
if(InitJoysticks())
|
||||||
|
inited|=2;
|
||||||
|
|
||||||
|
if(!InitKeyboard()) return 0;
|
||||||
|
inited|=8;
|
||||||
|
|
||||||
|
InitOtherInput();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DriverKill(void)
|
||||||
|
{
|
||||||
|
SaveConfig();
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
SetSignals(SIG_IGN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(inited&2)
|
||||||
|
KillJoysticks();
|
||||||
|
if(inited&8)
|
||||||
|
KillKeyboard();
|
||||||
|
if(inited&4)
|
||||||
|
KillVideo();
|
||||||
|
if(inited&1)
|
||||||
|
KillSound();
|
||||||
|
if(inited&16)
|
||||||
|
KillMouse();
|
||||||
|
inited=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count)
|
||||||
|
{
|
||||||
|
#ifdef NETWORK
|
||||||
|
extern int FCEUDnetplay;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ocount = Count;
|
||||||
|
// apply frame scaling to Count
|
||||||
|
Count = (Count<<8)/fps_scale;
|
||||||
|
if(Count)
|
||||||
|
{
|
||||||
|
int32 can=GetWriteSound();
|
||||||
|
static int uflow=0;
|
||||||
|
int32 tmpcan;
|
||||||
|
|
||||||
|
// don't underflow when scaling fps
|
||||||
|
if(can >= GetMaxSound() && fps_scale<=256) uflow=1; /* Go into massive underflow mode. */
|
||||||
|
|
||||||
|
if(can > Count) can=Count;
|
||||||
|
else uflow=0;
|
||||||
|
|
||||||
|
WriteSound(Buffer,can);
|
||||||
|
|
||||||
|
//if(uflow) puts("Underflow");
|
||||||
|
tmpcan = GetWriteSound();
|
||||||
|
// don't underflow when scaling fps
|
||||||
|
if(fps_scale>256 || ((tmpcan < Count*0.90) && !uflow))
|
||||||
|
{
|
||||||
|
if(XBuf && (inited&4) && !(NoWaiting & 2))
|
||||||
|
BlitScreen(XBuf);
|
||||||
|
Buffer+=can;
|
||||||
|
Count-=can;
|
||||||
|
if(Count)
|
||||||
|
{
|
||||||
|
if(NoWaiting)
|
||||||
|
{
|
||||||
|
can=GetWriteSound();
|
||||||
|
if(Count>can) Count=can;
|
||||||
|
WriteSound(Buffer,Count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(Count>0)
|
||||||
|
{
|
||||||
|
WriteSound(Buffer,(Count<ocount) ? Count : ocount);
|
||||||
|
Count -= ocount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} //else puts("Skipped");
|
||||||
|
#ifdef NETWORK
|
||||||
|
else if(!NoWaiting && FCEUDnetplay && (uflow || tmpcan >= (Count * 1.8)))
|
||||||
|
{
|
||||||
|
if(Count > tmpcan) Count=tmpcan;
|
||||||
|
while(tmpcan > 0)
|
||||||
|
{
|
||||||
|
// printf("Overwrite: %d\n", (Count <= tmpcan)?Count : tmpcan);
|
||||||
|
WriteSound(Buffer, (Count <= tmpcan)?Count : tmpcan);
|
||||||
|
tmpcan -= Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused()))
|
||||||
|
SpeedThrottle();
|
||||||
|
if(XBuf && (inited&4))
|
||||||
|
{
|
||||||
|
BlitScreen(XBuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FCEUD_UpdateInput();
|
||||||
|
//if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
|
||||||
|
// SpeedThrottle();
|
||||||
|
//if(XBuf && (inited&4))
|
||||||
|
//{
|
||||||
|
// BlitScreen(XBuf);
|
||||||
|
//}
|
||||||
|
//if(Count)
|
||||||
|
// WriteSound(Buffer,Count,NoWaiting);
|
||||||
|
//FCEUD_UpdateInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Maybe ifndef WXWINDOWS would be better? ^_^ */
|
||||||
|
#ifndef EXTGUI
|
||||||
|
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode)
|
||||||
|
{
|
||||||
|
return(fopen(fn,mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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 __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../../driver.h"
|
||||||
|
#include "../common/config.h"
|
||||||
|
#include "../common/args.h"
|
||||||
|
|
||||||
|
extern int eoptions;
|
||||||
|
#define EO_NO8LIM 1
|
||||||
|
#define EO_SUBASE 2
|
||||||
|
#define EO_CLIPSIDES 8
|
||||||
|
#define EO_SNAPNAME 16
|
||||||
|
#define EO_NOFOURSCORE 32
|
||||||
|
#define EO_NOTHROTTLE 64
|
||||||
|
#define EO_GAMEGENIE 128
|
||||||
|
#define EO_PAL 256
|
||||||
|
#define EO_LOWPASS 512
|
||||||
|
#define EO_AUTOHIDE 1024
|
||||||
|
|
||||||
|
extern int srendlinev[2],erendlinev[2];
|
||||||
|
extern int NoWaiting;
|
||||||
|
|
||||||
|
extern int soundvol;
|
||||||
|
extern long soundq;
|
||||||
|
extern int _sound;
|
||||||
|
extern long soundrate;
|
||||||
|
extern long soundbufsize;
|
||||||
|
|
||||||
|
int CLImain(int argc, char *argv[]);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
static const struct {
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int height;
|
||||||
|
unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
|
||||||
|
uint8 pixel_data[32 * 32 * 3 + 1];
|
||||||
|
} fceu_playicon = {
|
||||||
|
32, 32, 3,
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\0\0\0\0\0\0\0\0\0\\\223\373\\\223\373\267\317\373"
|
||||||
|
"\246\304\373\260\312\373\222\267\373\246\304\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\267\317\373\246\304\373\260\312\373\210\261\373\246\304\373\\\223\373\\"
|
||||||
|
"\223\373\210\261\373\222\267\373\267\317\373\241\301\373\\\223\373\\\223"
|
||||||
|
"\373\0\0\0\0\0\0\\\223\373\\\223\373\227\272\373\227\272\373\227\272\373"
|
||||||
|
"\227\272\373\227\272\373\227\272\373\\\223\373\\\223\373z`sr\242\373\227"
|
||||||
|
"\272\373\227\272\373\\\223\373\\\223\373\\\223\373\\\223\373\213\261\373"
|
||||||
|
"z\247\373\213\261\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\313i=\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40"
|
||||||
|
"\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40"
|
||||||
|
"\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\257T*\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40"
|
||||||
|
"\355\235\203\355\235\203\341\232\205\341\232\205\365\255\233\355\235\203"
|
||||||
|
"\355\235\203\350\250\232\365\255\233\355\235\203\307L\14\307L\14\307L\14"
|
||||||
|
"\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256B\12\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\315Z\40\273zc\233l_\325\225\205\325\225\205\325\225\205\273\212"
|
||||||
|
"\201\325\225\205\237qd\325\225\205\317\231\216\307L\14\307L\14\307L\14\307"
|
||||||
|
"L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256B\12\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\315Z\40\344\232\203\301\215\201\344\232\203\273\212\201\325\225"
|
||||||
|
"\205\2114\10\344\232\203\350\250\232\325\225\205\333\230\205\307L\14\307"
|
||||||
|
"L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256"
|
||||||
|
"B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\315Z\40\2259\11}0\10\2259\11}0\10}0\10\307L\14\225"
|
||||||
|
"9\11d&\6}0\10}0\10\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14"
|
||||||
|
"\307L\14\307L\14\307L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40\355\235\203"
|
||||||
|
"\355\233\201\355\235\203\355\235\203\355\235\203\365\255\233\355\235\203"
|
||||||
|
"\341\232\205\355\235\203\355\235\203\307L\14\365\255\233\355\235\203\365"
|
||||||
|
"\255\233\355\235\203\355\235\203\355\235\203\355\235\203\355\235\203\307"
|
||||||
|
"L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\315Z\40\325\225\205\311\221\204\311\221\204"
|
||||||
|
"\325\225\205\311\221\204\325\225\205\311\221\204\325\225\205\325\225\205"
|
||||||
|
"\311\221\204\307L\14\325\225\205\311\221\204\325\225\205\311\221\204\325"
|
||||||
|
"\225\205\311\221\204\325\225\205\311\221\204\307L\14\256B\12\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\315Z\40\325\225\205\325\225\205\325\225\205\325\225\205\325\225"
|
||||||
|
"\205\325\225\205\317\231\216\325\225\205\325\225\205\325\225\205\307L\14"
|
||||||
|
"\325\225\205\317\231\216\325\225\205\317\231\216\325\225\205\325\225\205"
|
||||||
|
"\273zc\241n_\307L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0"
|
||||||
|
"\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40\325\225\205\325"
|
||||||
|
"\225\205\325\225\205\365\255\233\333\243\231\325\225\205\333\230\205\325"
|
||||||
|
"\225\205\325\225\205\325\225\205\307L\14\325\225\205\317\223\204\325\225"
|
||||||
|
"\205\333\230\205\325\225\205\325\225\205\333\230\205\317\223\204\307L\14"
|
||||||
|
"\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\315Z\40\325\225\205\325\225\205\325\225\205"
|
||||||
|
"\325\225\205\311\221\204\325\225\205\325\225\205\325\225\205\344\232\203"
|
||||||
|
"\273\212\201\307L\14\325\225\205\273\212\201\325\225\205\325\225\205\344"
|
||||||
|
"\232\203\273\212\201\344\232\203\273\212\201\341\232\205\256B\12\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\257T*d&\6d&\6d&\6d&\6d&\6d&\6d&\6d&\6}0\10d&\6\256B\12d&\6p+\7"
|
||||||
|
"d&\6d&\6}0\10d&\6}0\10d&\6d&\6\223@\26\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\234\243"
|
||||||
|
"\335\213\237\344\237\244\333\251\247\326\237\244\333\\\223\373\267\252\317"
|
||||||
|
"\222\241\341\267\252\317\210\237\346\241\245\332\267\252\317\246\246\327"
|
||||||
|
"\246\246\327\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0"
|
||||||
|
"\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\257hT\\\223\373\213\261\373\\\223"
|
||||||
|
"\373\241\301\373\210\261\373\246\304\373\222\267\373\241\301\373\260\312"
|
||||||
|
"\373\\\223\373\237\277\373\246\304\373\267\317\373\241\301\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\246\304\373\\\223\373\241"
|
||||||
|
"\301\373\210\261\373\246\304\373\222\267\373\241\301\373\260\312\373\\\223"
|
||||||
|
"\373\237\277\373\246\304\373\267\317\373\241\301\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373"
|
||||||
|
"\\\223\373\\\223\373D\203\270D\203\270\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0"
|
||||||
|
"\0\0\0\0\\\223\373\\\223\373(\211n\0\247\0\0n\0(\211n\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\0\0\0\0\0\0\\\223\373(\211n\0\247\0\0\247\0\0\247\0\0\247\0(\211n\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\210\261\373\246\304\373\241\301\373z\247"
|
||||||
|
"\373\\\223\373\227\272\373\227\272\373\227\272\373\227\272\373\227\272\373"
|
||||||
|
"\227\272\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\0\0\0\0\0\0(\211n\0\247\0\0n\0\0\247\0\\\215\12fs\16"
|
||||||
|
"\0\247\0(\211n\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373Z\231Z[\230SZ\231Z[\230SZ\231Z[\230S\\\223\373\0\0\0\0"
|
||||||
|
"\0\0\0\247\0\0\247\0\0\247\0\0\247\0vy\7p|\7\0\247\0\0\247\0(\211n\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373b\237L\200\317\20\200\317"
|
||||||
|
"\20\200\317\20\200\317\20\200\317\20\200\317\20[\223H\0\0\0\0\0\0\230P.\323"
|
||||||
|
"d0\230P.\323d0\221M&\313`%\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323"
|
||||||
|
"d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323"
|
||||||
|
"d0\230P.\323d0\230P.\323d0\0\0\0\0\0\0\0\0\0\237N(\225E\35\237N(\225E\35"
|
||||||
|
"\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237"
|
||||||
|
"N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N("
|
||||||
|
"\225E\35\237N(\225E\35\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
* Copyright (C) 2002 Paul Kuliniewicz
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* PK: SDL joystick input stuff */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "sdl.h"
|
||||||
|
|
||||||
|
#define MAX_JOYSTICKS 32
|
||||||
|
static SDL_Joystick *Joysticks[MAX_JOYSTICKS] = {NULL};
|
||||||
|
|
||||||
|
int DTestButtonJoy(ButtConfig *bc)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<bc->NumC;x++)
|
||||||
|
{
|
||||||
|
if(bc->ButtonNum[x]&0x8000) /* Axis "button" */
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
pos = SDL_JoystickGetAxis(Joysticks[bc->DeviceNum[x]], bc->ButtonNum[x]&16383);
|
||||||
|
if ((bc->ButtonNum[x]&0x4000) && pos <= -16383)
|
||||||
|
return(1);
|
||||||
|
else if (!(bc->ButtonNum[x]&0x4000) && pos >= 16363)
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
else if(bc->ButtonNum[x]&0x2000) /* Hat "button" */
|
||||||
|
{
|
||||||
|
if( SDL_JoystickGetHat(Joysticks[bc->DeviceNum[x]],(bc->ButtonNum[x]>>8)&0x1F) & (bc->ButtonNum[x]&0xFF))
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(SDL_JoystickGetButton(Joysticks[bc->DeviceNum[x]], bc->ButtonNum[x] ))
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jinited=0;
|
||||||
|
|
||||||
|
/* Cleanup opened joysticks. */
|
||||||
|
int KillJoysticks (void)
|
||||||
|
{
|
||||||
|
int n; /* joystick index */
|
||||||
|
|
||||||
|
if(!jinited) return(0);
|
||||||
|
for (n = 0; n < MAX_JOYSTICKS; n++)
|
||||||
|
{
|
||||||
|
if (Joysticks[n] != 0)
|
||||||
|
SDL_JoystickClose(Joysticks[n]);
|
||||||
|
Joysticks[n]=0;
|
||||||
|
}
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize joysticks. */
|
||||||
|
int InitJoysticks (void)
|
||||||
|
{
|
||||||
|
int n; /* joystick index */
|
||||||
|
int total;
|
||||||
|
|
||||||
|
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||||
|
total=SDL_NumJoysticks();
|
||||||
|
if(total>MAX_JOYSTICKS) total=MAX_JOYSTICKS;
|
||||||
|
|
||||||
|
for (n = 0; n < total; n++)
|
||||||
|
{
|
||||||
|
/* Open the joystick under SDL. */
|
||||||
|
Joysticks[n] = SDL_JoystickOpen(n);
|
||||||
|
//printf("Could not open joystick %d: %s.\n",
|
||||||
|
//joy[n] - 1, SDL_GetError());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
jinited=1;
|
||||||
|
return(1);
|
||||||
|
}
|
|
@ -0,0 +1,224 @@
|
||||||
|
#include "sdl.h"
|
||||||
|
#include <SDL/SDL_net.h>
|
||||||
|
#include "sdl-netplay.h"
|
||||||
|
|
||||||
|
char *ServerHost;
|
||||||
|
|
||||||
|
static int LocalPortTCP=0xFCE;
|
||||||
|
static int LocalPortUDP=0xFCE;
|
||||||
|
static int RemotePortTCP=0xFCE;
|
||||||
|
|
||||||
|
static int RemotePortUDP; /* Not configurable, figured out during handshake. */
|
||||||
|
|
||||||
|
static TCPsocket Socket;
|
||||||
|
static UDPsocket UDPSocket;
|
||||||
|
static SDLNet_SocketSet set;
|
||||||
|
|
||||||
|
|
||||||
|
static void en32(uint8 *buf, uint32 morp)
|
||||||
|
{
|
||||||
|
buf[0]=morp;
|
||||||
|
buf[1]=morp>>8;
|
||||||
|
buf[2]=morp>>16;
|
||||||
|
buf[3]=morp>>24;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 de32(uint8 *morp)
|
||||||
|
{
|
||||||
|
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int FCEUD_NetworkConnect(void)
|
||||||
|
{
|
||||||
|
IPaddress rip;
|
||||||
|
|
||||||
|
SDLNet_Init();
|
||||||
|
|
||||||
|
if(netplay==1) /* Be a server. */
|
||||||
|
{
|
||||||
|
TCPsocket tmp;
|
||||||
|
Uint16 p=LocalPortUDP;
|
||||||
|
|
||||||
|
SDLNet_ResolveHost(&rip,NULL,LocalPortTCP);
|
||||||
|
|
||||||
|
UDPSocket=SDLNet_UDP_Open(&p);
|
||||||
|
|
||||||
|
tmp=SDLNet_TCP_Open(&rip);
|
||||||
|
Socket=SDLNet_TCP_Accept(&tmp);
|
||||||
|
|
||||||
|
memcpy(&rip,SDLNet_TCP_GetPeerAddress(Socket),sizeof(IPaddress));
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8 buf[12];
|
||||||
|
uint32 player=1;
|
||||||
|
|
||||||
|
magic=SDL_GetTicks();
|
||||||
|
|
||||||
|
SDLNet_Write32(buf,uport);
|
||||||
|
SDLNet_Write32(buf+4,1);
|
||||||
|
SDLNet_Write32(buf+8,magic);
|
||||||
|
|
||||||
|
SDLNet_TCP_Send(Socket, buf, 12);
|
||||||
|
|
||||||
|
/* Get the UDP port the client is waiting for data on. */
|
||||||
|
SDLNet_TCP_Recv(Socket, buf, 2);
|
||||||
|
RemotePortUDP=de32(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* Be a client */
|
||||||
|
{
|
||||||
|
SDLNet_ResolveHost(&rip,ServerHost,RemotePortTCP);
|
||||||
|
Socket=SDLNet_TCP_Open(&rip);
|
||||||
|
|
||||||
|
{
|
||||||
|
Uint16 p=LocalPortUDP;
|
||||||
|
uint8 buf[12];
|
||||||
|
|
||||||
|
UDPSocket=SDLNet_UDP_Open(&p);
|
||||||
|
|
||||||
|
/* Now, tell the server what local UDP port it should send to. */
|
||||||
|
en32(buf,p);
|
||||||
|
SDLNet_TCP_Send(Socket, buf, 4);
|
||||||
|
|
||||||
|
/* Get the UDP port from the server we should send data to. */
|
||||||
|
SDLNet_TCP_Recv(Socket, buf, 12);
|
||||||
|
RemotePortUDP=de32(buf);
|
||||||
|
magic=de32(buf+8);
|
||||||
|
}
|
||||||
|
set=SDLNet_AllocSocketSet(1);
|
||||||
|
SDLNet_TCP_AddSocket(set,TCPSocket);
|
||||||
|
SDLNet_UDP_AddSocket(set,UDPSocket);
|
||||||
|
} // End client connect code.
|
||||||
|
|
||||||
|
rip.port=RemotePortUDP;
|
||||||
|
SDLNet_UDP_Bind(UDPSocket, 0, &rip);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int CheckUDP(uint8 *packet, int32 len, int32 alt)
|
||||||
|
{
|
||||||
|
uint32 crc;
|
||||||
|
uint32 repcrc;
|
||||||
|
|
||||||
|
crc=FCEUI_CRC32(0,packet+4,len+8);
|
||||||
|
repcrc=de32(packet);
|
||||||
|
|
||||||
|
if(crc!=repcrc) return(0); /* CRC32 mismatch, bad packet. */
|
||||||
|
packet+=4;
|
||||||
|
|
||||||
|
if(de32(packet)!=magic) /* Magic number mismatch, bad or spoofed packet. */
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
packet+=4;
|
||||||
|
if(alt)
|
||||||
|
{
|
||||||
|
if(de32(packet)<incounter) /* Time warped packet. */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(de32(packet)!=incounter) /* Time warped packet. */
|
||||||
|
return(0);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Be careful where these MakeXXX() functions are used. */
|
||||||
|
static uint8 *MakeUDP(uint8 *data, int32 len)
|
||||||
|
{
|
||||||
|
/* UDP packet data header is 12 bytes in length. */
|
||||||
|
static uint8 buf[12+32]; // arbitrary 32.
|
||||||
|
|
||||||
|
en32(buf+4,magic);
|
||||||
|
en32(buf+8,outcounter);
|
||||||
|
memcpy(buf+12,data,len);
|
||||||
|
en32(buf,FCEUI_CRC32(0,buf+4,8+len));
|
||||||
|
return(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 *MakeTCP(uint8 *data, int32 len)
|
||||||
|
{
|
||||||
|
/* TCP packet data header is 4 bytes in length. */
|
||||||
|
static uint8 buf[4+32]; // arbitrary 32.
|
||||||
|
|
||||||
|
en32(buf,outcounter);
|
||||||
|
memcpy(buf+4,data,len);
|
||||||
|
return(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UDPHEADSIZE 12
|
||||||
|
#define TCPHEADSIZE 4
|
||||||
|
|
||||||
|
void FCEUD_NetworkClose(void)
|
||||||
|
{
|
||||||
|
SDLNet_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1 byte to server */
|
||||||
|
int FCEUD_SendDataToServer(uint8 v,uint8 cmd)
|
||||||
|
{
|
||||||
|
UDPpacket upack;
|
||||||
|
|
||||||
|
upack.channel=0;
|
||||||
|
upack.data=MakeUDP(data,1);
|
||||||
|
upack.len=upack.maxlen=UDPHEADSIZE+1;
|
||||||
|
upack.status=0;
|
||||||
|
|
||||||
|
SDLNet_UDP_Send(UDPSocket,0,&upack);
|
||||||
|
|
||||||
|
outcounter++;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_SendDataToClients(uint8 *data)
|
||||||
|
{
|
||||||
|
UDPpacket upack;
|
||||||
|
|
||||||
|
SDLNet_TCP_Send(Socket,MakeTCP(data,5),TCPHEADSIZE+5);
|
||||||
|
|
||||||
|
upack.channel=0;
|
||||||
|
upack.data=MakeUDP(data,5);
|
||||||
|
upack.len=upack.maxlen=UDPHEADSIZE+5;
|
||||||
|
upack.status=0;
|
||||||
|
|
||||||
|
SDLNet_UDP_Send(UDPSocket,0,&upack);
|
||||||
|
|
||||||
|
outcounter++;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUD_GetDataFromServer(uint8 *data)
|
||||||
|
{
|
||||||
|
uint8 buf[128];
|
||||||
|
NoWaiting&=~2;
|
||||||
|
|
||||||
|
while(SDLNet_CheckSockets(set,1)==0)
|
||||||
|
{
|
||||||
|
// do something here.
|
||||||
|
}
|
||||||
|
if(SDLNet_SocketReady(Socket))
|
||||||
|
{
|
||||||
|
SDLNet_TCP_Recv
|
||||||
|
if(de32(buf)==incounter) /* New packet, keep. */
|
||||||
|
{
|
||||||
|
unsigned long beefie;
|
||||||
|
memcpy(data,buf+TCPHEADSIZE,5);
|
||||||
|
incounter++;
|
||||||
|
|
||||||
|
if(!ioctl(Socket,FIONREAD,&beefie))
|
||||||
|
if(beefie)
|
||||||
|
NoWaiting|=2;
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(SDLNet_SocketReady(UDPSocket)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue