1 /*****************************************************************************
2 ** $Source: /cygdrive/d/Private/_SVNROOT/bluemsx/blueMSX/Src/Memory/romMapperASCII16nf.c,v $
3 **
4 ** $Revision: 1.6 $
5 **
6 ** $Date: 2008-03-30 18:38:42 $
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 "romMapperASCII16nf.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 //  Uses ASCII16 but in different adresses :
38 //  Know Game : Super Pierrot
39 
40 
41 typedef struct {
42     int deviceHandle;
43     UInt8* romData;
44     int slot;
45     int sslot;
46     int startPage;
47     UInt32 romMask;
48     int romMapper[4];
49 } RomMapperASCII16nf;
50 
saveState(RomMapperASCII16nf * rm)51 static void saveState(RomMapperASCII16nf* rm)
52 {
53     SaveState* state = saveStateOpenForWrite("mapperASCII16nf");
54     char tag[16];
55     int i;
56 
57     for (i = 0; i < 4; i++) {
58         sprintf(tag, "romMapper%d", i);
59         saveStateSet(state, tag, rm->romMapper[i]);
60     }
61 
62     saveStateClose(state);
63 }
64 
loadState(RomMapperASCII16nf * rm)65 static void loadState(RomMapperASCII16nf* rm)
66 {
67     SaveState* state = saveStateOpenForRead("mapperASCII16nf");
68     char tag[16];
69     int i;
70 
71     for (i = 0; i < 4; i++) {
72         sprintf(tag, "romMapper%d", i);
73         rm->romMapper[i] = saveStateGet(state, tag, 0);
74     }
75 
76     saveStateClose(state);
77 
78     for (i = 0; i < 4; i += 2) {
79         UInt8* bankData = rm->romData + (rm->romMapper[i] << 14);
80         slotMapPage(rm->slot, rm->sslot, rm->startPage + i,     bankData, 1, 0);
81         slotMapPage(rm->slot, rm->sslot, rm->startPage + i + 1, bankData + 0x2000, 1, 0);
82     }
83 }
84 
destroy(RomMapperASCII16nf * rm)85 static void destroy(RomMapperASCII16nf* rm)
86 {
87     slotUnregister(rm->slot, rm->sslot, rm->startPage);
88     deviceManagerUnregister(rm->deviceHandle);
89 
90     free(rm->romData);
91     free(rm);
92 }
93 
write(RomMapperASCII16nf * rm,UInt16 address,UInt8 value)94 static void write(RomMapperASCII16nf* rm, UInt16 address, UInt8 value)
95 {
96     int bank;
97 
98     address += 0x4000;
99 
100     if (address & 0x0800) {
101         return;
102     }
103 
104     bank = (address & 0x1000) >> 11;
105 
106     value &= rm->romMask;
107 
108     if (rm->romMapper[bank] != value) {
109         UInt8* bankData = rm->romData + ((int)value << 14);
110 
111         rm->romMapper[bank] = value;
112 
113         slotMapPage(rm->slot, rm->sslot, rm->startPage + bank,     bankData, 1, 0);
114         slotMapPage(rm->slot, rm->sslot, rm->startPage + bank + 1, bankData + 0x2000, 1, 0);
115     }
116 }
117 
romMapperASCII16nfCreate(const char * filename,UInt8 * romData,int size,int slot,int sslot,int startPage)118 int romMapperASCII16nfCreate(const char* filename, UInt8* romData,
119                              int size, int slot, int sslot, int startPage)
120 {
121     DeviceCallbacks callbacks = { destroy, NULL, saveState, loadState };
122     RomMapperASCII16nf* rm;
123     int i;
124 
125     rm = malloc(sizeof(RomMapperASCII16nf));
126 
127     rm->deviceHandle = deviceManagerRegister(ROM_ASCII16NF, &callbacks, rm);
128     slotRegister(slot, sslot, startPage, 4, NULL, NULL, write, destroy, rm);
129 
130     size = (size + 0x3fff) & ~0x3fff;
131 
132     rm->romData = malloc(size);
133     memcpy(rm->romData, romData, size);
134     rm->romMask = size / 0x4000 - 1;
135     rm->slot  = slot;
136     rm->sslot = sslot;
137     rm->startPage  = startPage;
138 
139     rm->romMapper[0] = 0;
140     rm->romMapper[2] = 0;
141 
142     for (i = 0; i < 4; i += 2) {
143         slotMapPage(rm->slot, rm->sslot, rm->startPage + i,     rm->romData + rm->romMapper[i] * 0x2000, 1, 0);
144         slotMapPage(rm->slot, rm->sslot, rm->startPage + i + 1, rm->romData + rm->romMapper[i] * 0x2000 + 0x2000, 1, 0);
145     }
146 
147     return 1;
148 }
149 
150