1 /*****************************************************************************
2 ** $Source: /cygdrive/d/Private/_SVNROOT/bluemsx/blueMSX/Src/Memory/ram1kBMirrored.c,v $
3 **
4 ** $Revision: 1.12 $
5 **
6 ** $Date: 2008-05-19 19:25:59 $
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 "ram1kBMirrored.h"
29 #include "MediaDb.h"
30 #include "SlotManager.h"
31 #include "DeviceManager.h"
32 #include "DebugDeviceManager.h"
33 #include "SaveState.h"
34 #include "Language.h"
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
38
39
40 typedef struct {
41 int deviceHandle;
42 int debugHandle;
43 int slot;
44 int sslot;
45 int startPage;
46 int pages;
47 UInt32 mask;
48 UInt8 ramData[0x2000];
49 } Ram1kBMirrored;
50
saveState(Ram1kBMirrored * rm)51 static void saveState(Ram1kBMirrored* rm)
52 {
53 SaveState* state = saveStateOpenForWrite("mapperMirroredRam");
54
55 saveStateSet(state, "mask", rm->mask);
56 saveStateSetBuffer(state, "ramData", rm->ramData, rm->mask + 1);
57
58 saveStateClose(state);
59 }
60
loadState(Ram1kBMirrored * rm)61 static void loadState(Ram1kBMirrored* rm)
62 {
63 SaveState* state = saveStateOpenForRead("mapperMirroredRam");
64
65 rm->mask = saveStateGet(state, "mask", 0x400);
66 saveStateGetBuffer(state, "ramData", rm->ramData, rm->mask + 1);
67
68 saveStateClose(state);
69 }
70
destroy(Ram1kBMirrored * rm)71 static void destroy(Ram1kBMirrored* rm)
72 {
73 debugDeviceUnregister(rm->debugHandle);
74
75 slotUnregister(rm->slot, rm->sslot, 0);
76 deviceManagerUnregister(rm->deviceHandle);
77
78 free(rm);
79 }
80
getDebugInfo(Ram1kBMirrored * rm,DbgDevice * dbgDevice)81 static void getDebugInfo(Ram1kBMirrored* rm, DbgDevice* dbgDevice)
82 {
83 dbgDeviceAddMemoryBlock(dbgDevice, langDbgMemRamNormal(), 0, 0, rm->mask + 1, rm->ramData);
84 }
85
dbgWriteMemory(Ram1kBMirrored * rm,char * name,void * data,int start,int size)86 static int dbgWriteMemory(Ram1kBMirrored* rm, char* name, void* data, int start, int size)
87 {
88 if (strcmp(name, "Normal") || start + size >= (int)rm->mask) {
89 return 0;
90 }
91
92 memcpy(rm->ramData + start, data, size);
93
94 return 1;
95 }
96
read(Ram1kBMirrored * rm,UInt16 address)97 static UInt8 read(Ram1kBMirrored* rm, UInt16 address)
98 {
99 return rm->ramData[address & rm->mask];
100 }
101
write(Ram1kBMirrored * rm,UInt16 address,UInt8 value)102 static void write(Ram1kBMirrored* rm, UInt16 address, UInt8 value)
103 {
104 rm->ramData[address & rm->mask] = value;
105 }
106
ramMirroredCreate(int size,int slot,int sslot,int startPage,UInt32 ramBlockSize,UInt8 ** ramPtr,UInt32 * ramSize)107 int ramMirroredCreate(int size, int slot, int sslot, int startPage,
108 UInt32 ramBlockSize, UInt8** ramPtr, UInt32* ramSize)
109 {
110 DeviceCallbacks callbacks = { destroy, NULL, saveState, loadState };
111 DebugCallbacks dbgCallbacks = { getDebugInfo, dbgWriteMemory, NULL, NULL };
112 Ram1kBMirrored* rm;
113 int pages = size / 0x2000;
114 int i;
115
116 if (size > 0x10000 || (size & 0x1fff)) {
117 return 0;
118 }
119
120 // Start page must be zero (only full slot allowed)
121 if (startPage + pages > 8) {
122 return 0;
123 }
124
125 rm = malloc(sizeof(Ram1kBMirrored));
126
127 rm->mask = ramBlockSize - 1;
128 rm->slot = slot;
129 rm->sslot = sslot;
130 rm->startPage = startPage;
131 rm->pages = pages;
132
133 memset(rm->ramData, 0, sizeof(rm->ramData));
134
135 rm->debugHandle = debugDeviceRegister(DBGTYPE_RAM, langDbgDevRam(), &dbgCallbacks, rm);
136
137 for (i = 0; i < pages; i++) {
138 slotMapPage(slot, sslot, i + startPage, NULL, 0, 0);
139 }
140
141 rm->deviceHandle = deviceManagerRegister(ramBlockSize == 0x400 ? RAM_1KB_MIRRORED : RAM_2KB_MIRRORED,
142 &callbacks, rm);
143 slotRegister(slot, sslot, startPage, pages, read, read, write, destroy, rm);
144
145 if (ramPtr != NULL) {
146 *ramPtr = rm->ramData;
147 }
148
149 if (ramSize != NULL) {
150 *ramSize = rm->pages * 0x2000;
151 }
152
153 return 1;
154 }
155
156