fceux/boards/tengen.cpp

199 lines
4.2 KiB
C++

/* 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();
}
*/