map016.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  ** map16.c
 21  **
 22  ** mapper 16 interface
 23  ** $Id: map016.c,v 1.2 2001/04/27 14:37:11 neil Exp $
 24  */
 25  
 26  #include "noftypes.h"
 27  #include "nes_mmc.h"
 28  #include "nes_ppu.h"
 29  #include "nes.h"
 30  
 31  static struct
 32  {
 33     int counter;
 34     bool enabled;
 35  } irq;
 36  
 37  /* mapper 16: Bandai */
 38  
 39  static void map16_init(void)
 40  {
 41     mmc_bankrom(16, 0x8000, 0);
 42     mmc_bankrom(16, 0xC000, MMC_LASTBANK);
 43     irq.counter = 0;
 44     irq.enabled = false;
 45  }
 46  
 47  static void map16_write(uint32 address, uint8 value)
 48  {
 49     int reg = address & 0xF;
 50  
 51     if (reg < 8)
 52     {
 53        mmc_bankvrom(1, reg << 10, value);
 54     }
 55     else
 56     {
 57        switch (address & 0x000F)
 58        {
 59        case 0x8:
 60           mmc_bankrom(16, 0x8000, value);
 61           break;
 62  
 63        case 0x9:
 64           switch (value & 3)
 65           {
 66           case 0:
 67              ppu_mirror(0, 0, 1, 1); /* horizontal */
 68              break;
 69        
 70           case 1:
 71              ppu_mirror(0, 1, 0, 1); /* vertical */
 72              break;
 73        
 74           case 2:
 75              ppu_mirror(0, 0, 0, 0);
 76              break;
 77        
 78           case 3:
 79              ppu_mirror(1, 1, 1, 1);
 80              break;
 81           }
 82           break;
 83     
 84        case 0xA:
 85           irq.enabled = (value & 1) ? true : false;
 86           break;
 87   
 88        case 0xB:
 89           irq.counter = (irq.counter & 0xFF00) | value;
 90           break;
 91     
 92        case 0xC:
 93           irq.counter = (value << 8) | (irq.counter & 0xFF);
 94           break;
 95     
 96        case 0xD:
 97           /* eeprom I/O port? */
 98           break;
 99        }
100     }
101  }
102  
103  static void map16_hblank(int vblank)
104  {
105     UNUSED(vblank);
106  
107     if (irq.enabled)
108     {
109        if (irq.counter)
110        {
111           if (0 == --irq.counter)
112              nes_irq();
113        }
114     }
115  }
116  
117  static void map16_getstate(SnssMapperBlock *state)
118  {
119     state->extraData.mapper16.irqCounterLowByte = irq.counter & 0xFF;
120     state->extraData.mapper16.irqCounterHighByte = irq.counter >> 8;
121     state->extraData.mapper16.irqCounterEnabled = irq.enabled;
122  }
123  
124  static void map16_setstate(SnssMapperBlock *state)
125  {
126     irq.counter = (state->extraData.mapper16.irqCounterHighByte << 8)
127                         | state->extraData.mapper16.irqCounterLowByte;
128     irq.enabled = state->extraData.mapper16.irqCounterEnabled;
129  }
130  
131  static const map_memwrite map16_memwrite[] =
132  {
133     { 0x6000, 0x600D, map16_write },
134     { 0x7FF0, 0x7FFD, map16_write },
135     { 0x8000, 0x800D, map16_write },
136     {     -1,     -1, NULL }
137  };
138  
139  const mapintf_t map16_intf = 
140  {
141     16, /* mapper number */
142     "Bandai", /* mapper name */
143     map16_init, /* init routine */
144     NULL, /* vblank callback */
145     map16_hblank, /* hblank callback */
146     map16_getstate, /* get state (snss) */
147     map16_setstate, /* set state (snss) */
148     NULL, /* memory read structure */
149     map16_memwrite, /* memory write structure */
150     NULL /* external sound device */
151  };
152  
153  /*
154  ** $Log: map016.c,v $
155  ** Revision 1.2  2001/04/27 14:37:11  neil
156  ** wheeee
157  **
158  ** Revision 1.1  2001/04/27 12:54:40  neil
159  ** blah
160  **
161  ** Revision 1.1.1.1  2001/04/27 07:03:54  neil
162  ** initial
163  **
164  ** Revision 1.1  2000/10/24 12:19:33  matt
165  ** changed directory structure
166  **
167  ** Revision 1.8  2000/10/22 19:17:46  matt
168  ** mapper cleanups galore
169  **
170  ** Revision 1.7  2000/10/22 15:03:13  matt
171  ** simplified mirroring
172  **
173  ** Revision 1.6  2000/10/21 19:33:38  matt
174  ** many more cleanups
175  **
176  ** Revision 1.5  2000/10/10 13:58:16  matt
177  ** stroustrup squeezing his way in the door
178  **
179  ** Revision 1.4  2000/08/16 02:50:11  matt
180  ** random mapper cleanups
181  **
182  ** Revision 1.3  2000/07/15 23:52:20  matt
183  ** rounded out a bunch more mapper interfaces
184  **
185  ** Revision 1.2  2000/07/11 05:03:49  matt
186  ** value masking isn't necessary for the banking routines
187  **
188  ** Revision 1.1  2000/07/11 03:14:18  melanson
189  ** Initial commit for mappers 16, 34, and 231
190  **
191  **
192  */