map050.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 ** map050.c 21 ** 22 ** Mapper #50 (SMB2j - 3rd discovered variation) 23 ** Implementation by Firebug 24 ** Mapper information courtesy of Kevin Horton 25 ** $Id: map050.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 #50 IRQ reset routine */ 43 /********************************/ 44 static void map50_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 #50: 3rd discovered variation of SMB2j cart bootleg */ 56 /**************************************************************/ 57 static void map50_init (void) 58 { 59 /* Set the hardwired pages */ 60 mmc_bankrom (8, 0x6000, 0x0F); 61 mmc_bankrom (8, 0x8000, 0x08); 62 mmc_bankrom (8, 0xA000, 0x09); 63 mmc_bankrom (8, 0xE000, 0x0B); 64 65 /* Reset the IRQ counter */ 66 map50_irq_reset (); 67 68 /* Done */ 69 return; 70 } 71 72 /****************************************/ 73 /* Mapper #50 callback for IRQ handling */ 74 /****************************************/ 75 static void map50_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 line is hooked to Q12 of the counter */ 89 if (irq.counter & 0x1000) 90 { 91 /* Trigger the IRQ */ 92 nes_irq (); 93 94 /* Reset the counter */ 95 map50_irq_reset (); 96 } 97 } 98 } 99 100 /******************************************/ 101 /* Mapper #50 write handler ($4000-$5FFF) */ 102 /******************************************/ 103 static void map50_write (uint32 address, uint8 value) 104 { 105 uint8 selectable_bank; 106 107 /* For address to be decoded, A5 must be high and A6 low */ 108 if ((address & 0x60) != 0x20) return; 109 110 /* A8 low = $C000-$DFFF page selection */ 111 /* A8 high = IRQ timer toggle */ 112 if (address & 0x100) 113 { 114 /* IRQ settings */ 115 if (value & 0x01) irq.enabled = true; 116 else map50_irq_reset (); 117 } 118 else 119 { 120 /* Stupid data line swapping */ 121 selectable_bank = 0x00; 122 if (value & 0x08) selectable_bank |= 0x08; 123 if (value & 0x04) selectable_bank |= 0x02; 124 if (value & 0x02) selectable_bank |= 0x01; 125 if (value & 0x01) selectable_bank |= 0x04; 126 mmc_bankrom (8, 0xC000, selectable_bank); 127 } 128 129 /* Done */ 130 return; 131 } 132 133 /****************************************************/ 134 /* Shove extra mapper information into a SNSS block */ 135 /****************************************************/ 136 static void map50_setstate (SnssMapperBlock *state) 137 { 138 /* TODO: Store SNSS information */ 139 UNUSED (state); 140 141 /* Done */ 142 return; 143 } 144 145 /*****************************************************/ 146 /* Pull extra mapper information out of a SNSS block */ 147 /*****************************************************/ 148 static void map50_getstate (SnssMapperBlock *state) 149 { 150 /* TODO: Retrieve SNSS information */ 151 UNUSED (state); 152 153 /* Done */ 154 return; 155 } 156 157 static const map_memwrite map50_memwrite [] = 158 { 159 { 0x4000, 0x5FFF, map50_write }, 160 { -1, -1, NULL } 161 }; 162 163 const mapintf_t map50_intf = 164 { 165 50, /* Mapper number */ 166 "SMB2j (3rd discovered variant)", /* Mapper name */ 167 map50_init, /* Initialization routine */ 168 NULL, /* VBlank callback */ 169 map50_hblank, /* HBlank callback */ 170 map50_getstate, /* Get state (SNSS) */ 171 map50_setstate, /* Set state (SNSS) */ 172 NULL, /* Memory read structure */ 173 map50_memwrite, /* Memory write structure */ 174 NULL /* External sound device */ 175 }; 176 177 /* 178 ** $Log: map050.c,v $ 179 ** Revision 1.2 2001/04/27 14:37:11 neil 180 ** wheeee 181 ** 182 ** Revision 1.1 2001/04/27 12:54:40 neil 183 ** blah 184 ** 185 ** Revision 1.1 2001/04/27 10:57:41 neil 186 ** wheee 187 ** 188 ** Revision 1.1 2000/12/27 19:22:13 firebug 189 ** initial revision 190 ** 191 ** 192 */