1 /*****************************************************************************
2 ** $Source: /cygdrive/d/Private/_SVNROOT/bluemsx/blueMSX/Src/Memory/romMapperKonami4.c,v $
3 **
4 ** $Revision: 1.8 $
5 **
6 ** $Date: 2008-03-30 18:38:44 $
7 **
8 ** More info: http://www.bluemsx.com
9 **
10 ** Copyright (C) 2003-2006 Daniel Vik
11 **
12 ** This program is free software; you can redistribute it and/or modify
13 ** it under the terms of the GNU General Public License as published by
14 ** the Free Software Foundation; either version 2 of the License, or
15 ** (at your option) any later version.
16 **
17 ** This program is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ** GNU General Public License for more details.
21 **
22 ** You should have received a copy of the GNU General Public License
23 ** along with this program; if not, write to the Free Software
24 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 **
26 ******************************************************************************
27 */
28 #include "romMapperKonami4.h"
29 #include "MediaDb.h"
30 #include "SlotManager.h"
31 #include "DeviceManager.h"
32 #include "SaveState.h"
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdio.h>
36 
37 
38 typedef struct {
39     int deviceHandle;
40     UInt8* romData;
41     int slot;
42     int sslot;
43     int startPage;
44     int size;
45     int romMapper[4];
46 } RomMapperKonami4;
47 
saveState(RomMapperKonami4 * rm)48 static void saveState(RomMapperKonami4* rm)
49 {
50     SaveState* state = saveStateOpenForWrite("mapperKonami4");
51     char tag[16];
52     int i;
53 
54     for (i = 0; i < 4; i++) {
55         sprintf(tag, "romMapper%d", i);
56         saveStateSet(state, tag, rm->romMapper[i]);
57     }
58 
59     saveStateClose(state);
60 }
61 
loadState(RomMapperKonami4 * rm)62 static void loadState(RomMapperKonami4* rm)
63 {
64     SaveState* state = saveStateOpenForRead("mapperKonami4");
65     char tag[16];
66     int i;
67 
68     for (i = 0; i < 4; i++) {
69         sprintf(tag, "romMapper%d", i);
70         rm->romMapper[i] = saveStateGet(state, tag, 0);
71     }
72 
73     saveStateClose(state);
74 
75     for (i = 0; i < 4; i++) {
76         slotMapPage(rm->slot, rm->sslot, rm->startPage + i, rm->romData + rm->romMapper[i] * 0x2000, 1, 0);
77     }
78 }
79 
destroy(RomMapperKonami4 * rm)80 static void destroy(RomMapperKonami4* rm)
81 {
82     slotUnregister(rm->slot, rm->sslot, rm->startPage);
83     deviceManagerUnregister(rm->deviceHandle);
84 
85     free(rm->romData);
86     free(rm);
87 }
88 
write(RomMapperKonami4 * rm,UInt16 address,UInt8 value)89 static void write(RomMapperKonami4* rm, UInt16 address, UInt8 value)
90 {
91     int bank;
92 
93     address += 0x4000;
94 
95     /* Page at 4000h is fixed */
96     if (address < 0x6000 || address >= 0xc000) {
97         return;
98     }
99 
100     bank = (address - 0x4000) >> 13;
101 
102     value %= rm->size / 0x2000;
103     if (rm->romMapper[bank] != value) {
104         UInt8* bankData = rm->romData + ((int)value << 13);
105 
106         rm->romMapper[bank] = value;
107 
108         slotMapPage(rm->slot, rm->sslot, rm->startPage + bank, bankData, 1, 0);
109     }
110 }
111 
romMapperKonami4Create(const char * filename,UInt8 * romData,int size,int slot,int sslot,int startPage)112 int romMapperKonami4Create(const char* filename, UInt8* romData,
113                            int size, int slot, int sslot, int startPage)
114 {
115     DeviceCallbacks callbacks = { destroy, NULL, saveState, loadState };
116     RomMapperKonami4* rm;
117     int romSize;
118     int i;
119 
120     if (size < 0x8000) {
121         return 0;
122     }
123 
124     rm = malloc(sizeof(RomMapperKonami4));
125 
126     rm->deviceHandle = deviceManagerRegister(ROM_KONAMI4, &callbacks, rm);
127     slotRegister(slot, sslot, startPage, 4, NULL, NULL, write, destroy, rm);
128 
129     romSize = size > 0x40000 ? size : 0x40000;
130     rm->romData = malloc(romSize);
131     memcpy(rm->romData, romData, size);
132 
133     if (size < 0x40000) {
134         memset(rm->romData + size, 0xff, 0x40000 - size);
135     }
136 
137     rm->size = romSize;
138     rm->slot  = slot;
139     rm->sslot = sslot;
140     rm->startPage  = startPage;
141 
142     rm->romMapper[0] = 0;
143     rm->romMapper[1] = 1;
144     rm->romMapper[2] = 2;
145     rm->romMapper[3] = 3;
146 
147     for (i = 0; i < 4; i++) {
148         slotMapPage(rm->slot, rm->sslot, rm->startPage + i, rm->romData + rm->romMapper[i] * 0x2000, 1, 0);
149     }
150 
151     return 1;
152 }
153 
154