map073.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  ** map073.c
 21  **
 22  ** Mapper #73 (Konami VRC3)
 23  ** Implementation by Firebug
 24  ** $Id: map073.c,v 1.2 2001/04/27 14:37:11 neil Exp $
 25  **
 26  */
 27  
 28  #include "noftypes.h"
 29  #include "nes_mmc.h"
 30  #include "nes.h"
 31  #include "libsnss.h"
 32  #include "log.h"
 33  
 34  static struct
 35  {
 36    bool enabled;
 37    uint32 counter;
 38  } irq;
 39  
 40  /**************************/
 41  /* Mapper #73: Salamander */
 42  /**************************/
 43  static void map73_init (void)
 44  {
 45    /* Turn off IRQs */
 46    irq.enabled = false;
 47    irq.counter = 0x0000;
 48  
 49    /* Done */
 50    return;
 51  }
 52  
 53  /****************************************/
 54  /* Mapper #73 callback for IRQ handling */
 55  /****************************************/
 56  static void map73_hblank (int vblank)
 57  {
 58     /* Counter is M2 based so it doesn't matter whether */
 59     /* the PPU is in its VBlank period or not           */
 60     UNUSED (vblank);
 61  
 62     /* Increment the counter if it is enabled and check for strike */
 63     if (irq.enabled)
 64     {
 65       /* Is there a constant for cycles per scanline? */
 66       /* If so, someone ought to substitute it here   */
 67       irq.counter = irq.counter + 114;
 68  
 69       /* Counter triggered on overflow into Q16 */
 70       if (irq.counter & 0x10000)
 71       {
 72         /* Clip to sixteen-bit word */
 73         irq.counter &= 0xFFFF;
 74  
 75         /* Trigger the IRQ */
 76         nes_irq ();
 77  
 78         /* Shut off IRQ counter */
 79         irq.enabled = false;
 80       }
 81     }
 82  }
 83  
 84  /******************************************/
 85  /* Mapper #73 write handler ($8000-$FFFF) */
 86  /******************************************/
 87  static void map73_write (uint32 address, uint8 value)
 88  {
 89    switch (address & 0xF000)
 90    {
 91      case 0x8000: irq.counter &= 0xFFF0;
 92                   irq.counter |= (uint32) (value);
 93                   break;
 94      case 0x9000: irq.counter &= 0xFF0F;
 95                   irq.counter |= (uint32) (value << 4);
 96                   break;
 97      case 0xA000: irq.counter &= 0xF0FF;
 98                   irq.counter |= (uint32) (value << 8);
 99                   break;
100      case 0xB000: irq.counter &= 0x0FFF;
101                   irq.counter |= (uint32) (value << 12);
102                   break;
103      case 0xC000: if (value & 0x02) irq.enabled = true;
104                   else              irq.enabled = false;
105                   break;
106      case 0xF000: mmc_bankrom (16, 0x8000, value);
107      default:     break;
108    }
109  
110    /* Done */
111    return;
112  }
113  
114  /****************************************************/
115  /* Shove extra mapper information into a SNSS block */
116  /****************************************************/
117  static void map73_setstate (SnssMapperBlock *state)
118  {
119    /* TODO: Store SNSS information */
120    UNUSED (state);
121  
122    /* Done */
123    return;
124  }
125  
126  /*****************************************************/
127  /* Pull extra mapper information out of a SNSS block */
128  /*****************************************************/
129  static void map73_getstate (SnssMapperBlock *state)
130  {
131    /* TODO: Retrieve SNSS information */
132    UNUSED (state);
133  
134    /* Done */
135    return;
136  }
137  
138  static const map_memwrite map73_memwrite [] =
139  {
140     { 0x8000, 0xFFFF, map73_write },
141     {     -1,     -1, NULL }
142  };
143  
144  const mapintf_t map73_intf =
145  {
146     73,                               /* Mapper number */
147     "Konami VRC3",                    /* Mapper name */
148     map73_init,                       /* Initialization routine */
149     NULL,                             /* VBlank callback */
150     map73_hblank,                     /* HBlank callback */
151     map73_getstate,                   /* Get state (SNSS) */
152     map73_setstate,                   /* Set state (SNSS) */
153     NULL,                             /* Memory read structure */
154     map73_memwrite,                   /* Memory write structure */
155     NULL                              /* External sound device */
156  };
157  
158  /*
159  ** $Log: map073.c,v $
160  ** Revision 1.2  2001/04/27 14:37:11  neil
161  ** wheeee
162  **
163  ** Revision 1.1  2001/04/27 12:54:40  neil
164  ** blah
165  **
166  ** Revision 1.1  2001/04/27 10:57:41  neil
167  ** wheee
168  **
169  ** Revision 1.1  2000/12/30 06:35:05  firebug
170  ** Initial revision
171  **
172  **
173  */