more 0.98.15-like timing, but sound glitches
[fceu.git] / mappers / 90.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Ben Parnell
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "mapinc.h"
22
23 #define tkcom1 mapbyte1[1]
24 #define tkcom2 mapbyte1[2]
25
26 #define prgb    mapbyte2
27 #define unkl    (mapbyte2+4)
28 #define chrlow  mapbyte3
29 #define chrhigh mapbyte4
30
31 static uint8 tekker=0x80;
32
33 static DECLFR(tekread)
34 {
35  return tekker;
36 }
37
38 static void tekprom(void)
39 {
40  switch(tkcom1&3)
41   {
42    case 1:              // 16 KB
43           ROM_BANK16(0x8000,prgb[0]);
44           ROM_BANK16(0xC000,prgb[2]);
45           break;
46
47    case 2:              //2 = 8 KB ??
48    case 3:
49           ROM_BANK8(0x8000,prgb[0]);
50           ROM_BANK8(0xa000,prgb[1]);
51           ROM_BANK8(0xc000,prgb[2]);
52           ROM_BANK8(0xe000,prgb[3]);
53           break;
54   }
55   X6502_Rebase();
56 }
57
58 static void tekvrom(void)
59 {
60  int x;
61  switch(tkcom1&0x18)
62   {
63    case 0x00:      // 8KB
64            VROM_BANK8(chrlow[0]|(chrhigh[0]<<8));
65            break;
66    case 0x08:      // 4KB
67           for(x=0;x<8;x+=4)
68            VROM_BANK4(x<<10,chrlow[x]|(chrhigh[x]<<8));
69           break;
70    case 0x10:      // 2KB
71           for(x=0;x<8;x+=2)
72            VROM_BANK2(x<<10,chrlow[x]|(chrhigh[x]<<8));
73           break;
74    case 0x18:      // 1KB
75            for(x=0;x<8;x++)
76             VROM_BANK1(x<<10,chrlow[x]|(chrhigh[x]<<8));
77            break;
78  }
79 }
80
81 static DECLFW(Mapper90_write)
82 {
83  A&=0xF007;
84
85  if(A>=0x8000 && A<=0x8003)
86  {
87   prgb[A&3]=V;
88   tekprom();
89  }
90  else if(A>=0x9000 && A<=0x9007)
91  {
92   chrlow[A&7]=V;
93   tekvrom();
94  }
95  else if(A>=0xa000 && A<=0xa007)
96  {
97   chrhigh[A&7]=V;
98   tekvrom();
99  }
100  else if(A>=0xb000 && A<=0xb003)
101  {
102   unkl[A&3]=V;
103  }
104  else switch(A)
105  {
106    case 0xc004:
107    case 0xc000:IRQLatch=V;break;
108
109    case 0xc005:
110    case 0xc001:X6502_IRQEnd(FCEU_IQEXT);
111                IRQCount=V;break;
112    case 0xc006:
113    case 0xc002:X6502_IRQEnd(FCEU_IQEXT);
114                IRQa=0;
115                IRQCount=IRQLatch;
116                break;
117    case 0xc007:
118    case 0xc003:IRQa=1;break;
119
120    case 0xd000:tkcom1=V;break;
121    case 0xd001:switch(V&3){
122                   case 0x00:MIRROR_SET(0);break;
123                   case 0x01:MIRROR_SET(1);break;
124                   case 0x02:onemir(0);break;
125                   case 0x03:onemir(1);break;
126                }
127                break;
128    break;
129  }
130 }
131
132 static void Mapper90_hb(void)
133 {
134  if(IRQa)
135  {
136   if(IRQCount)
137   {
138    IRQCount--;
139    if(!IRQCount)
140    {
141     X6502_IRQBegin(FCEU_IQEXT);
142     IRQCount=IRQLatch;
143    }
144   }
145  }
146 }
147
148 void Mapper90_init(void)
149 {
150   tekker^=0x80;
151   SetWriteHandler(0x8000,0xffff,Mapper90_write);
152   SetReadHandler(0x5000,0x5000,tekread);
153   GameHBIRQHook=Mapper90_hb;
154 }
155