map085.c
  1  /*
  2  ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com)
  3  **
  4  **
  5  ** This program is free software; you can redistribute it and/or
  6  ** modify it under the terms of version 2 of the GNU Library General 
  7  ** Public License as published by the Free Software Foundation.
  8  **
  9  ** This program is distributed in the hope that it will be useful, 
 10  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 12  ** Library General Public License for more details.  To obtain a 
 13  ** copy of the GNU Library General Public License, write to the Free 
 14  ** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 15  **
 16  ** Any permitted reproduction of these routines, in whole or in part,
 17  ** must bear this legend.
 18  **
 19  **
 20  ** map85.c
 21  **
 22  ** mapper 85 interface
 23  ** $Id: map085.c,v 1.3 2001/05/06 01:42:03 neil Exp $
 24  */
 25  
 26  #include "noftypes.h"
 27  #include "nes_mmc.h"
 28  #include "nes.h"
 29  #include "log.h"
 30  
 31  static struct
 32  {
 33     int counter, latch;
 34     int wait_state;
 35     bool enabled;
 36  } irq;
 37  
 38  /* mapper 85: Konami VRC7 */
 39  static void map85_write(uint32 address, uint8 value)
 40  {
 41     uint8 bank = address >> 12;
 42     uint8 reg = (address & 0x10) | ((address & 0x08) << 1);
 43  
 44     switch (bank)
 45     {
 46     case 0x08:
 47        if (0x10 == reg)
 48           mmc_bankrom(8, 0xA000, value);
 49        else
 50           mmc_bankrom(8, 0x8000, value);
 51        break;
 52  
 53     case 0x09:
 54        /* 0x10 & 0x30 should be trapped by sound emulation */
 55        mmc_bankrom(8, 0xC000, value);
 56        break;
 57  
 58     case 0x0A:
 59        if (0x10 == reg)
 60           mmc_bankvrom(1, 0x0400, value);
 61        else
 62           mmc_bankvrom(1, 0x0000, value);
 63        break;
 64  
 65     case 0x0B:
 66        if (0x10 == reg)
 67           mmc_bankvrom(1, 0x0C00, value);
 68        else
 69           mmc_bankvrom(1, 0x0800, value);
 70        break;
 71  
 72     case 0x0C:
 73        if (0x10 == reg)
 74           mmc_bankvrom(1, 0x1400, value);
 75        else
 76           mmc_bankvrom(1, 0x1000, value);
 77        break;
 78  
 79     case 0x0D:
 80        if (0x10 == reg)
 81           mmc_bankvrom(1, 0x1C00, value);
 82        else
 83           mmc_bankvrom(1, 0x1800, value);
 84        break;
 85  
 86     case 0x0E:
 87        if (0x10 == reg)
 88        {
 89           irq.latch = value;
 90        }
 91        else
 92        {
 93           switch (value & 3)
 94           {
 95           case 0:
 96              ppu_mirror(0, 1, 0, 1); /* vertical */
 97              break;
 98  
 99           case 1:
100              ppu_mirror(0, 0, 1, 1); /* horizontal */
101              break;
102  
103           case 2:
104              ppu_mirror(0, 0, 0, 0);
105              break;
106  
107           case 3:
108              ppu_mirror(1, 1, 1, 1);
109              break;
110           }
111        }
112        break;
113  
114     case 0x0F:
115        if (0x10 == reg)
116        {
117           irq.enabled = irq.wait_state;
118        }
119        else
120        {
121           irq.wait_state = value & 0x01;
122           irq.enabled = (value & 0x02) ? true : false;
123           if (true == irq.enabled)
124              irq.counter = irq.latch;
125        }
126        break;
127  
128     default:
129  #ifdef NOFRENDO_DEBUG
130        log_printf("unhandled vrc7 write: $%02X to $%04X\n", value, address);
131  #endif /* NOFRENDO_DEBUG */
132        break;
133     }
134  }
135  
136  static void map85_hblank(int vblank)
137  {
138     UNUSED(vblank);
139  
140     if (irq.enabled)
141     {
142        if (++irq.counter > 0xFF)
143        {
144           irq.counter = irq.latch;
145           nes_irq();
146  
147           //return;
148        }
149        //irq.counter++;
150     }
151  }
152  
153  static const map_memwrite map85_memwrite[] =
154  {
155     { 0x8000, 0xFFFF, map85_write },
156     {     -1,     -1, NULL }
157  };
158  
159  static void map85_init(void)
160  {
161     mmc_bankrom(16, 0x8000, 0);
162     mmc_bankrom(16, 0xC000, MMC_LASTBANK);
163     
164     mmc_bankvrom(8, 0x0000, 0);
165  
166     irq.counter = irq.latch = 0;
167     irq.wait_state = 0;
168     irq.enabled = false;
169  }
170  
171  const mapintf_t map85_intf = 
172  {
173     85, /* mapper number */
174     "Konami VRC7", /* mapper name */
175     map85_init, /* init routine */
176     NULL, /* vblank callback */
177     map85_hblank, /* hblank callback */
178     NULL, /* get state (snss) */
179     NULL, /* set state (snss) */
180     NULL, /* memory read structure */
181     map85_memwrite, /* memory write structure */
182     NULL
183  };
184  
185  /*
186  ** $Log: map085.c,v $
187  ** Revision 1.3  2001/05/06 01:42:03  neil
188  ** boooo
189  **
190  ** Revision 1.2  2001/04/27 14:37:11  neil
191  ** wheeee
192  **
193  ** Revision 1.1  2001/04/27 12:54:40  neil
194  ** blah
195  **
196  ** Revision 1.1.1.1  2001/04/27 07:03:54  neil
197  ** initial
198  **
199  ** Revision 1.1  2000/10/24 12:19:33  matt
200  ** changed directory structure
201  **
202  ** Revision 1.10  2000/10/22 19:17:46  matt
203  ** mapper cleanups galore
204  **
205  ** Revision 1.9  2000/10/22 15:03:14  matt
206  ** simplified mirroring
207  **
208  ** Revision 1.8  2000/10/21 19:33:38  matt
209  ** many more cleanups
210  **
211  ** Revision 1.7  2000/10/10 13:58:17  matt
212  ** stroustrup squeezing his way in the door
213  **
214  ** Revision 1.6  2000/08/16 02:50:11  matt
215  ** random mapper cleanups
216  **
217  ** Revision 1.5  2000/07/23 14:37:21  matt
218  ** added a break statement
219  **
220  ** Revision 1.4  2000/07/15 23:52:19  matt
221  ** rounded out a bunch more mapper interfaces
222  **
223  ** Revision 1.3  2000/07/10 13:51:25  matt
224  ** using generic nes_irq() routine now
225  **
226  ** Revision 1.2  2000/07/10 05:29:03  matt
227  ** cleaned up some mirroring issues
228  **
229  ** Revision 1.1  2000/07/06 02:47:47  matt
230  ** initial revision
231  **
232  */