map064.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 ** map64.c 21 ** 22 ** mapper 64 interface 23 ** $Id: map064.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.h" 29 #include "log.h" 30 31 static struct 32 { 33 int counter, latch; 34 bool enabled, reset; 35 } irq; 36 37 static uint8 command = 0; 38 static uint16 vrombase = 0x0000; 39 40 static void map64_hblank(int vblank) 41 { 42 if (vblank) 43 return; 44 45 irq.reset = false; 46 47 if (ppu_enabled()) 48 { 49 if (0 == irq.counter--) 50 { 51 irq.counter = irq.latch; 52 53 if (true == irq.enabled) 54 nes_irq(); 55 56 irq.reset = true; 57 } 58 } 59 } 60 61 /* mapper 64: Tengen RAMBO-1 */ 62 static void map64_write(uint32 address, uint8 value) 63 { 64 switch (address & 0xE001) 65 { 66 case 0x8000: 67 command = value; 68 vrombase = (value & 0x80) ? 0x1000 : 0x0000; 69 break; 70 71 case 0x8001: 72 switch (command & 0xF) 73 { 74 case 0: 75 mmc_bankvrom(1, 0x0000 ^ vrombase, value); 76 mmc_bankvrom(1, 0x0400 ^ vrombase, value); 77 break; 78 79 case 1: 80 mmc_bankvrom(1, 0x0800 ^ vrombase, value); 81 mmc_bankvrom(1, 0x0C00 ^ vrombase, value); 82 break; 83 84 case 2: 85 mmc_bankvrom(1, 0x1000 ^ vrombase, value); 86 break; 87 88 case 3: 89 mmc_bankvrom(1, 0x1400 ^ vrombase, value); 90 break; 91 92 case 4: 93 mmc_bankvrom(1, 0x1800 ^ vrombase, value); 94 break; 95 96 case 5: 97 mmc_bankvrom(1, 0x1C00 ^ vrombase, value); 98 break; 99 100 case 6: 101 mmc_bankrom(8, (command & 0x40) ? 0xA000 : 0x8000, value); 102 break; 103 104 case 7: 105 mmc_bankrom(8, (command & 0x40) ? 0xC000 : 0xA000, value); 106 break; 107 108 case 8: 109 mmc_bankvrom(1, 0x0400, value); 110 break; 111 112 case 9: 113 mmc_bankvrom(1, 0x0C00, value); 114 break; 115 116 case 15: 117 mmc_bankrom(8, (command & 0x40) ? 0x8000 : 0xC000, value); 118 break; 119 120 default: 121 #ifdef NOFRENDO_DEBUG 122 log_printf("mapper 64: unknown command #%d", command & 0xF); 123 #endif 124 break; 125 } 126 break; 127 128 case 0xA000: 129 if (value & 1) 130 ppu_mirror(0, 0, 1, 1); 131 else 132 ppu_mirror(0, 1, 0, 1); 133 break; 134 135 case 0xC000: 136 //irq.counter = value; 137 irq.latch = value; 138 break; 139 140 case 0xC001: 141 //irq.latch = value; 142 irq.reset = true; 143 break; 144 145 case 0xE000: 146 //irq.counter = irq.latch; 147 irq.enabled = false; 148 break; 149 150 case 0xE001: 151 irq.enabled = true; 152 break; 153 154 default: 155 #ifdef NOFRENDO_DEBUG 156 log_printf("mapper 64: Wrote $%02X to $%04X", value, address); 157 #endif 158 break; 159 } 160 161 if (true == irq.reset) 162 irq.counter = irq.latch; 163 } 164 165 static void map64_init(void) 166 { 167 mmc_bankrom(8, 0x8000, MMC_LASTBANK); 168 mmc_bankrom(8, 0xA000, MMC_LASTBANK); 169 mmc_bankrom(8, 0xC000, MMC_LASTBANK); 170 mmc_bankrom(8, 0xE000, MMC_LASTBANK); 171 172 irq.counter = irq.latch = 0; 173 irq.reset = irq.enabled = false; 174 } 175 176 static const map_memwrite map64_memwrite[] = 177 { 178 { 0x8000, 0xFFFF, map64_write }, 179 { -1, -1, NULL } 180 }; 181 182 const mapintf_t map64_intf = 183 { 184 64, /* mapper number */ 185 "Tengen RAMBO-1", /* mapper name */ 186 map64_init, /* init routine */ 187 NULL, /* vblank callback */ 188 map64_hblank, /* hblank callback */ 189 NULL, /* get state (snss) */ 190 NULL, /* set state (snss) */ 191 NULL, /* memory read structure */ 192 map64_memwrite, /* memory write structure */ 193 NULL /* external sound device */ 194 }; 195 196 /* 197 ** $Log: map064.c,v $ 198 ** Revision 1.2 2001/04/27 14:37:11 neil 199 ** wheeee 200 ** 201 ** Revision 1.1 2001/04/27 12:54:40 neil 202 ** blah 203 ** 204 ** Revision 1.1.1.1 2001/04/27 07:03:54 neil 205 ** initial 206 ** 207 ** Revision 1.1 2000/10/24 12:19:33 matt 208 ** changed directory structure 209 ** 210 ** Revision 1.8 2000/10/22 19:17:46 matt 211 ** mapper cleanups galore 212 ** 213 ** Revision 1.7 2000/10/22 15:03:13 matt 214 ** simplified mirroring 215 ** 216 ** Revision 1.6 2000/10/21 19:33:38 matt 217 ** many more cleanups 218 ** 219 ** Revision 1.5 2000/10/10 13:58:17 matt 220 ** stroustrup squeezing his way in the door 221 ** 222 ** Revision 1.4 2000/07/10 13:51:25 matt 223 ** using generic nes_irq() routine now 224 ** 225 ** Revision 1.3 2000/07/10 05:29:03 matt 226 ** cleaned up some mirroring issues 227 ** 228 ** Revision 1.2 2000/07/06 02:48:43 matt 229 ** clearly labelled structure members 230 ** 231 ** Revision 1.1 2000/07/05 05:05:18 matt 232 ** initial revision 233 ** 234 */