map042.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  ** map042.c
 21  **
 22  ** Mapper #42 (Baby Mario bootleg)
 23  ** Implementation by Firebug
 24  ** Mapper information courtesy of Kevin Horton
 25  ** $Id: map042.c,v 1.2 2001/04/27 14:37:11 neil Exp $
 26  **
 27  */
 28  
 29  #include "noftypes.h"
 30  #include "nes_mmc.h"
 31  #include "nes.h"
 32  #include "libsnss.h"
 33  #include "log.h"
 34  
 35  static struct
 36  {
 37    bool enabled;
 38    uint32 counter;
 39  } irq;
 40  
 41  /********************************/
 42  /* Mapper #42 IRQ reset routine */
 43  /********************************/
 44  static void map42_irq_reset (void)
 45  {
 46    /* Turn off IRQs */
 47    irq.enabled = false;
 48    irq.counter = 0x0000;
 49  
 50    /* Done */
 51    return;
 52  }
 53  
 54  /********************************************/
 55  /* Mapper #42: Baby Mario bootleg cartridge */
 56  /********************************************/
 57  static void map42_init (void)
 58  {
 59    /* Set the hardwired pages */
 60    mmc_bankrom (8, 0x8000, 0x0C);
 61    mmc_bankrom (8, 0xA000, 0x0D);
 62    mmc_bankrom (8, 0xC000, 0x0E);
 63    mmc_bankrom (8, 0xE000, 0x0F);
 64  
 65    /* Reset the IRQ counter */
 66    map42_irq_reset ();
 67  
 68    /* Done */
 69    return;
 70  }
 71  
 72  /****************************************/
 73  /* Mapper #42 callback for IRQ handling */
 74  /****************************************/
 75  static void map42_hblank (int vblank)
 76  {
 77     /* Counter is M2 based so it doesn't matter whether */
 78     /* the PPU is in its VBlank period or not           */
 79     UNUSED(vblank);
 80  
 81     /* Increment the counter if it is enabled and check for strike */
 82     if (irq.enabled)
 83     {
 84       /* Is there a constant for cycles per scanline? */
 85       /* If so, someone ought to substitute it here   */
 86       irq.counter = irq.counter + 114;
 87  
 88       /* IRQ is triggered after 24576 M2 cycles */
 89       if (irq.counter >= 0x6000)
 90       {
 91         /* Trigger the IRQ */
 92         nes_irq ();
 93  
 94         /* Reset the counter */
 95         map42_irq_reset ();
 96       }
 97     }
 98  }
 99  
100  /******************************************/
101  /* Mapper #42 write handler ($E000-$FFFF) */
102  /******************************************/
103  static void map42_write (uint32 address, uint8 value)
104  {
105    switch (address & 0x03)
106    {
107      /* Register 0: Select ROM page at $6000-$7FFF */
108      case 0x00: mmc_bankrom (8, 0x6000, value & 0x0F);
109                 break;
110  
111      /* Register 1: mirroring */
112      case 0x01: if (value & 0x08) ppu_mirror(0, 0, 1, 1); /* horizontal */
113                 else              ppu_mirror(0, 1, 0, 1); /* vertical   */
114                 break;
115  
116      /* Register 2: IRQ */
117      case 0x02: if (value & 0x02) irq.enabled = true;
118                 else              map42_irq_reset ();
119                 break;
120  
121      /* Register 3: unused */
122      default:   break;
123    }
124  
125    /* Done */
126    return;
127  }
128  
129  /****************************************************/
130  /* Shove extra mapper information into a SNSS block */
131  /****************************************************/
132  static void map42_setstate (SnssMapperBlock *state)
133  {
134    /* TODO: Store SNSS information */
135    UNUSED (state);
136  
137    /* Done */
138    return;
139  }
140  
141  /*****************************************************/
142  /* Pull extra mapper information out of a SNSS block */
143  /*****************************************************/
144  static void map42_getstate (SnssMapperBlock *state)
145  {
146    /* TODO: Retrieve SNSS information */
147    UNUSED (state);
148  
149    /* Done */
150    return;
151  }
152  
153  static const map_memwrite map42_memwrite [] =
154  {
155     { 0xE000, 0xFFFF, map42_write },
156     {     -1,     -1, NULL }
157  };
158  
159  const mapintf_t map42_intf =
160  {
161     42,                               /* Mapper number */
162     "Baby Mario (bootleg)",           /* Mapper name */
163     map42_init,                       /* Initialization routine */
164     NULL,                             /* VBlank callback */
165     map42_hblank,                     /* HBlank callback */
166     map42_getstate,                   /* Get state (SNSS) */
167     map42_setstate,                   /* Set state (SNSS) */
168     NULL,                             /* Memory read structure */
169     map42_memwrite,                   /* Memory write structure */
170     NULL                              /* External sound device */
171  };
172  
173  /*
174  ** $Log: map042.c,v $
175  ** Revision 1.2  2001/04/27 14:37:11  neil
176  ** wheeee
177  **
178  ** Revision 1.1  2001/04/27 12:54:40  neil
179  ** blah
180  **
181  ** Revision 1.1  2001/04/27 10:57:41  neil
182  ** wheee
183  **
184  ** Revision 1.1  2000/12/27 19:23:30  firebug
185  ** initial revision
186  **
187  **
188  */