#include "mapinc.h"
//#define DEBUG90
-static int is209;
+// Mapper 090 is simpliest mapper hardware and have not extended nametable control and latched chr banks in 4k mode
+// Mapper 209 much compicated hardware with decribed above features disabled by default and switchable by command
+// Mapper 211 the same mapper 209 but with forced nametable control
+
+static int is209;
static int is211;
static uint8 IRQMode; // from $c001
static uint8 chrlow[8];
static uint8 chrhigh[8];
+static uint8 chr[2];
+
static uint16 names[4];
static uint8 tekker;
static SFORMAT Tek_StateRegs[]={
- {&IRQMode, 1, "IRQMODE"},
- {&IRQPre, 1, "IRQPRE"},
- {&IRQPreSize, 1, "IRQPRESIZE"},
+ {&IRQMode, 1, "IRQM"},
+ {&IRQPre, 1, "IRQP"},
+ {&IRQPreSize, 1, "IRQR"},
{&IRQCount, 1, "IRQC"},
- {&IRQXOR, 1, "IRQXOR"},
- {&IRQa, 1, "IRQa"},
+ {&IRQXOR, 1, "IRQX"},
+ {&IRQa, 1, "IRQA"},
{mul, 2, "MUL"},
{®ie, 1, "REGI"},
{tkcom, 4, "TKCO"},
{prgb, 4, "PRGB"},
+ {chr, 2, "CLTC"},
{chrlow, 4, "CHRL"},
{chrhigh, 8, "CHRH"},
{&names[0], 2|FCEUSTATE_RLSB, "NMS0"},
}
}
-static void tekprom(void)
+static void tekprom(void) // TODO: verify for single, small multi and large multi
{
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));
+ setprg32(0x8000,(prgb[3]&7)|((tkcom[3]&7)<<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));
+ setprg16(0x8000,(prgb[1]&0x0F)|((tkcom[3]&7)<<4));
+ setprg16(0xC000,0x0F|((tkcom[3]&7)<<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);
+ case 02:
+ if(tkcom[0]&0x80)
+ setprg8(0x6000,(prgb[3]&0x1F)|((tkcom[3]&7)<<5)); // 45in1 multy has different bits, seems board was hacked to support big data banks
+ setprg8(0x8000,(prgb[0]&0x1F)|((tkcom[3]&7)<<5));
+ setprg8(0xa000,(prgb[1]&0x1F)|((tkcom[3]&7)<<5));
+ setprg8(0xc000,(prgb[2]&0x1F)|((tkcom[3]&7)<<5));
+ setprg8(0xe000,0x1F|((tkcom[3]&7)<<5));
+// setprg8(0xe000,(prgb[3]&0x0F)|((tkcom[3]&6)<<3));
+// setprg32(0x8000,((prgb[0]&0x0F)>>2)|((tkcom[3]&6)<<3));
break;
case 04: if(tkcom[0]&0x80)
setprg8(0x6000,(((prgb[3]<<2)+3)&0x3F)|bankmode);
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);
+// for(x=0;x<8;x+=4)
+// setchr4(x<<10,((chrlow[x]|(chrhigh[x]<<8))&mask)|bank);
+ setchr4(0x0000,((chrlow[chr[0]]|(chrhigh[chr[0]]<<8))&mask)|bank);
+ setchr4(0x1000,((chrlow[chr[1]]|(chrhigh[chr[1]]<<8))&mask)|bank);
break;
case 0x10: // 2KB
for(x=0;x<8;x+=2)
static DECLFW(M90TekWrite)
{
- switch(A)
+ switch(A&0x5C03)
{
case 0x5800: mul[0]=V; break;
case 0x5801: mul[1]=V; break;
static DECLFR(M90TekRead)
{
- switch(A)
+ switch(A&0x5C03)
{
case 0x5800: return (mul[0]*mul[1]);
case 0x5801: return((mul[0]*mul[1])>>8);
case 0x5803: return (regie);
+ default: return tekker;
}
- return(tekker);
+ return(0xff);
}
static DECLFW(M90PRGWrite)
{
+// FCEU_printf("bs %04x %02x\n",A,V);
prgb[A&3]=V;
tekprom();
}
static DECLFW(M90CHRlowWrite)
{
+// FCEU_printf("bs %04x %02x\n",A,V);
chrlow[A&7]=V;
tekvrom();
}
static DECLFW(M90CHRhiWrite)
{
+// FCEU_printf("bs %04x %02x\n",A,V);
chrhigh[A&7]=V;
tekvrom();
}
static DECLFW(M90NTWrite)
{
+// FCEU_printf("bs %04x %02x\n",A,V);
if(A&4)
{
names[A&3]&=0x00FF;
static DECLFW(M90IRQWrite)
{
+// FCEU_printf("bs %04x %02x\n",A,V);
switch(A&7)
{
case 00: //FCEU_printf("%s IRQ (C000)\n",V&1?"Enable":"Disable");
case 03: //FCEU_printf("Enable IRQ (C003) scanline=%d\n", scanline);
IRQa=1;break;
case 01: IRQMode=V;
-/* FCEU_printf("IRQ Count method: ");
+ /*FCEU_printf("IRQ Count method: ");
switch (IRQMode&3)
{
case 00: FCEU_printf("M2 cycles\n");break;
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;
+ 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);
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");
+ // else if(V==0xFF) FCEU_printf("Prescaler is changed for 12bits\n");
+ // else FCEU_printf("Counter Stopped\n");
IRQPreSize=V;break;
}
}
static DECLFW(M90ModeWrite)
{
+// FCEU_printf("bs %04x %02x\n",A,V);
tkcom[A&3]=V;
tekprom();
tekvrom();
#endif
}
+static DECLFW(M90DummyWrite)
+{
+// FCEU_printf("bs %04x %02x\n",A,V);
+}
+
static void CCL(void)
{
if((IRQMode>>6) == 1) // Count Up
}
lastread=A;
}
-// else
-// {
-// if((!lastread)&&(A&0x1000))
-// ClockCounter();
-// lastread=A&0x1000;
-// }
-
+
+ if(is209)
+ {
+ uint8 l,h;
+ h=A>>8;
+ if(h<0x20&&((h&0x0F)==0xF))
+ {
+ l=A&0xF0;
+ if(l==0xD0)
+ {
+ chr[(h&0x10)>>4]=((h&0x10)>>2);
+ tekvrom();
+ }
+ else if(l==0xE0)
+ {
+ chr[(h&0x10)>>4]=((h&0x10)>>2)|2;
+ tekvrom();
+ }
+ }
+ }
+ else
+ {
+ chr[0]=0;
+ chr[1]=4;
+ }
}
static void togglie()
{
- tekker>>=6;
- if(tekker>3)
- tekker=0;
- else
- tekker++;
- tekker<<=6;
- FCEU_printf("tekker=%04x\n",tekker);
+ tekker+=0x40;
+ tekker&=0xC0;
+ FCEU_printf("tekker=%02x\n",tekker);
memset(tkcom,0x00,sizeof(tkcom));
memset(prgb,0xff,sizeof(prgb));
tekprom();
static void M90Power(void)
{
SetWriteHandler(0x5000,0x5fff,M90TekWrite);
- SetWriteHandler(0x8000,0x8fff,M90PRGWrite);
+ SetWriteHandler(0x8000,0x8ff0,M90PRGWrite);
SetWriteHandler(0x9000,0x9fff,M90CHRlowWrite);
SetWriteHandler(0xA000,0xAfff,M90CHRhiWrite);
SetWriteHandler(0xB000,0xBfff,M90NTWrite);
SetWriteHandler(0xC000,0xCfff,M90IRQWrite);
- SetWriteHandler(0xD000,0xDfff,M90ModeWrite);
+ SetWriteHandler(0xD000,0xD5ff,M90ModeWrite);
+ SetWriteHandler(0xE000,0xFfff,M90DummyWrite);
SetReadHandler(0x5000,0x5fff,M90TekRead);
SetReadHandler(0x6000,0xffff,CartBR);
info->Reset=togglie;
info->Power=M90Power;
PPU_hook=M90PPU;
- GameHBIRQHook2=SLWrap;
MapIRQHook=CPUWrap;
+ GameHBIRQHook2=SLWrap;
GameStateRestore=M90Restore;
AddExState(Tek_StateRegs, ~0, 0, 0);
}
is209=1;
info->Reset=togglie;
info->Power=M90Power;
+ PPU_hook=M90PPU;
+ MapIRQHook=CPUWrap;
GameHBIRQHook2=SLWrap;
GameStateRestore=M90Restore;
AddExState(Tek_StateRegs, ~0, 0, 0);
is211=1;
info->Reset=togglie;
info->Power=M90Power;
+ PPU_hook=M90PPU;
+ MapIRQHook=CPUWrap;
GameHBIRQHook2=SLWrap;
GameStateRestore=M90Restore;
AddExState(Tek_StateRegs, ~0, 0, 0);