1 /*
2 * vic20memsnapshot.c - VIC20 memory snapshot handling.
3 *
4 * Written by
5 * Ettore Perazzoli <ettore@comm2000.it>
6 * Andre Fachat <fachat@physik.tu-chemnitz.de>
7 * Andreas Boose <viceteam@t-online.de>
8 *
9 * Multiple memory configuration support originally by
10 * Alexander Lehmann <alex@mathematik.th-darmstadt.de>
11 *
12 * This file is part of VICE, the Versatile Commodore Emulator.
13 * See README for copyright notice.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 * 02111-1307 USA.
29 *
30 */
31
32 #include "vice.h"
33
34 #include <stdio.h>
35 #include <string.h>
36
37 #ifdef HAVE_MEMORY_H
38 #include <memory.h>
39 #endif
40
41 #include "cart/vic20cart.h"
42 #include "log.h"
43 #include "mem.h"
44 #include "resources.h"
45 #include "snapshot.h"
46 #include "types.h"
47 #include "vic20-resources.h"
48 #include "vic20mem.h"
49 #include "vic20memrom.h"
50 #include "vic20memsnapshot.h"
51 #include "vic20rom.h"
52
53
54 static log_t vic20_snapshot_log = LOG_ERR;
55
56 /************************************************************************/
57
58 /*
59 * VIC20 memory dump contains the available memory at the moment
60 */
61 #define VIC20MEM_DUMP_VER_MAJOR 1
62 #define VIC20MEM_DUMP_VER_MINOR 1
63 #define SNAP_MEM_MODULE_NAME "VIC20MEM"
64
65 /*
66 * UBYTE CONFIG Bit 0: 1 = expansion block 0 RAM enabled
67 * 1: 1 = expansion block 1 RAM enabled
68 * 2: 1 = expansion block 2 RAM enabled
69 * 3: 1 = expansion block 3 RAM enabled
70 * 5: 1 = expansion block 5 RAM enabled
71 *
72 * UBYTE cpu_last_data
73 * UBYTE v_bus_last_data
74 * UBYTE v_bus_last_high
75 * ARRAY RAM0 1k RAM $0000-$03ff
76 * ARRAY RAM1 4k RAM $1000-$1fff
77 * ARRAY BLK0 3k RAM $0400-$0fff (if blk 0 RAM enabled)
78 * ARRAY BLK1 8k RAM $2000-$3fff (if blk 1 RAM enabled)
79 * ARRAY BLK2 8k RAM $4000-$5fff (if blk 2 RAM enabled)
80 * ARRAY BLK3 8k RAM $6000-$7fff (if blk 3 RAM enabled)
81 * ARRAY BLK5 8k RAM $A000-$Bfff (if blk 5 RAM enabled)
82 *
83 */
84
85
mem_write_ram_snapshot_module(snapshot_t * p)86 static int mem_write_ram_snapshot_module(snapshot_t *p)
87 {
88 snapshot_module_t *m;
89 uint8_t config;
90
91 config = (ram_block_0_enabled ? 1 : 0)
92 | (ram_block_1_enabled ? 2 : 0)
93 | (ram_block_2_enabled ? 4 : 0)
94 | (ram_block_3_enabled ? 8 : 0)
95 | (ram_block_5_enabled ? 32 : 0);
96
97 m = snapshot_module_create(p, SNAP_MEM_MODULE_NAME,
98 VIC20MEM_DUMP_VER_MAJOR,
99 VIC20MEM_DUMP_VER_MINOR);
100 if (m == NULL) {
101 return -1;
102 }
103
104 SMW_B(m, config);
105
106 SMW_B(m, vic20_cpu_last_data);
107 SMW_B(m, vic20_v_bus_last_data);
108 SMW_B(m, vic20_v_bus_last_high);
109
110 SMW_BA(m, mem_ram, 0x0400);
111 SMW_BA(m, mem_ram + 0x1000, 0x1000);
112
113 if (config & 1) {
114 SMW_BA(m, mem_ram + 0x0400, 0x0c00);
115 }
116 if (config & 2) {
117 SMW_BA(m, mem_ram + 0x2000, 0x2000);
118 }
119 if (config & 4) {
120 SMW_BA(m, mem_ram + 0x4000, 0x2000);
121 }
122 if (config & 8) {
123 SMW_BA(m, mem_ram + 0x6000, 0x2000);
124 }
125 if (config & 32) {
126 SMW_BA(m, mem_ram + 0xA000, 0x2000);
127 }
128
129 snapshot_module_close(m);
130
131 return 0;
132 }
133
mem_read_ram_snapshot_module(snapshot_t * p)134 static int mem_read_ram_snapshot_module(snapshot_t *p)
135 {
136 uint8_t vmajor, vminor;
137 snapshot_module_t *m;
138 uint8_t config;
139
140 m = snapshot_module_open(p, SNAP_MEM_MODULE_NAME, &vmajor, &vminor);
141 if (m == NULL) {
142 return -1;
143 }
144
145 if (vmajor != VIC20MEM_DUMP_VER_MAJOR) {
146 snapshot_module_close(m);
147 return -1;
148 }
149
150 SMR_B(m, &config);
151
152 SMR_B(m, &vic20_cpu_last_data);
153 SMR_B(m, &vic20_v_bus_last_data);
154 SMR_B(m, &vic20_v_bus_last_high);
155
156 SMR_BA(m, mem_ram, 0x0400);
157 SMR_BA(m, mem_ram + 0x1000, 0x1000);
158
159 resources_set_int("RAMBlock0", (config & 1) ? 1 : 0 );
160 if (config & 1) {
161 SMR_BA(m, mem_ram + 0x0400, 0x0c00);
162 }
163 resources_set_int("RAMBlock1", (config & 2) ? 1 : 0 );
164 if (config & 2) {
165 SMR_BA(m, mem_ram + 0x2000, 0x2000);
166 }
167 resources_set_int("RAMBlock2", (config & 4) ? 1 : 0 );
168 if (config & 4) {
169 SMR_BA(m, mem_ram + 0x4000, 0x2000);
170 }
171 resources_set_int("RAMBlock3", (config & 8) ? 1 : 0 );
172 if (config & 8) {
173 SMR_BA(m, mem_ram + 0x6000, 0x2000);
174 }
175 resources_set_int("RAMBlock5", (config & 32) ? 1 : 0 );
176 if (config & 32) {
177 SMR_BA(m, mem_ram + 0xA000, 0x2000);
178 }
179
180 snapshot_module_close(m);
181
182 mem_initialize_memory();
183
184 return 0;
185 }
186
187 /*
188 * VIC20 ROM dump
189 */
190 #define VIC20ROM_DUMP_VER_MAJOR 1
191 #define VIC20ROM_DUMP_VER_MINOR 1
192 #define SNAP_ROM_MODULE_NAME "VIC20ROM"
193
194 /*
195 * UBYTE CONFIG Bit 0: 1 = ROM block $2*** enabled
196 * 1: 1 = ROM block $3*** enabled
197 * 2: 1 = ROM block $4*** enabled
198 * 3: 1 = ROM block $5*** enabled
199 * 4: 1 = ROM block $6*** enabled
200 * 5: 1 = ROM block $7*** enabled
201 * 6: 1 = ROM block $A*** enabled
202 * 7: 1 = ROM block $B*** enabled
203 *
204 * ARRAY KERNAL 8k KERNAL ROM $e000-$ffff
205 * ARRAY BASIC 8k BASIC ROM $c000-$dfff
206 * ARRAY CHARGEN 4k CHARGEN ROM
207 * ARRAY BLK1A 4k ROM $2*** (if CONFIG & 1)
208 * ARRAY BLK1B 4k ROM $3*** (if CONFIG & 2)
209 * ARRAY BLK3A 4k ROM $6*** (if CONFIG & 16)
210 * ARRAY BLK3B 4k ROM $7*** (if CONFIG & 32)
211 * ARRAY BLK5A 4k ROM $A*** (if CONFIG & 64)
212 * ARRAY BLK5B 4k ROM $B*** (if CONFIG & 128)
213 *
214 * ARRAY BLK2A 4k ROM $4*** (if CONFIG & 4)
215 * ARRAY BLK2B 4k ROM $5*** (if CONFIG & 8)
216 */
217
218
mem_write_rom_snapshot_module(snapshot_t * p,int save_roms)219 static int mem_write_rom_snapshot_module(snapshot_t *p, int save_roms)
220 {
221 snapshot_module_t *m;
222
223 if (!save_roms) {
224 return 0;
225 }
226
227 m = snapshot_module_create(p, SNAP_ROM_MODULE_NAME, VIC20MEM_DUMP_VER_MAJOR, VIC20MEM_DUMP_VER_MINOR);
228 if (m == NULL) {
229 return -1;
230 }
231
232 /* old cart system config bits. all zero = no roms */
233 SMW_B(m, 0x00);
234
235 /* save kernal */
236 SMW_BA(m, vic20memrom_kernal_rom, 0x2000);
237 /* save basic */
238 SMW_BA(m, vic20memrom_basic_rom, 0x2000);
239
240 SMW_BA(m, vic20memrom_chargen_rom, 0x1000);
241
242 snapshot_module_close(m);
243
244 return 0;
245 }
246
mem_read_rom_snapshot_module(snapshot_t * p)247 static int mem_read_rom_snapshot_module(snapshot_t *p)
248 {
249 uint8_t vmajor, vminor;
250 snapshot_module_t *m;
251 uint8_t config;
252 int trapfl;
253
254 m = snapshot_module_open(p, SNAP_ROM_MODULE_NAME, &vmajor, &vminor);
255 if (m == NULL) {
256 return 0; /* optional */
257 }
258
259 if (vmajor != VIC20ROM_DUMP_VER_MAJOR) {
260 snapshot_module_close(m);
261 return -1;
262 }
263
264 /* disable traps before loading the ROM */
265 resources_get_int("VirtualDevices", &trapfl);
266 resources_set_int("VirtualDevices", 0);
267
268 /* old cart system ROMs (ignored) */
269 SMR_B(m, &config);
270
271 /* read kernal */
272 SMR_BA(m, vic20memrom_kernal_rom, 0x2000);
273 /* read basic */
274 SMR_BA(m, vic20memrom_basic_rom, 0x2000);
275
276 SMR_BA(m, vic20memrom_chargen_rom, 0x1000);
277
278 vic20rom_kernal_checksum();
279 vic20rom_basic_checksum();
280
281 log_warning(vic20_snapshot_log,
282 "Dumped Romset files and saved settings will "
283 "represent\nthe state before loading the snapshot!");
284
285 /* enable traps again when necessary */
286 resources_set_int("VirtualDevices", trapfl);
287
288 snapshot_module_close(m);
289
290 mem_initialize_memory();
291
292 return 0;
293 }
294
vic20_snapshot_write_module(snapshot_t * m,int save_roms)295 int vic20_snapshot_write_module(snapshot_t *m, int save_roms)
296 {
297 if (mem_write_ram_snapshot_module(m) < 0
298 || mem_write_rom_snapshot_module(m, save_roms) < 0
299 || vic20cart_snapshot_write_module(m) < 0) {
300 return -1;
301 }
302 return 0;
303 }
304
vic20_snapshot_read_module(snapshot_t * m)305 int vic20_snapshot_read_module(snapshot_t *m)
306 {
307 if (mem_read_ram_snapshot_module(m) < 0
308 || mem_read_rom_snapshot_module(m) < 0
309 || vic20cart_snapshot_read_module(m) < 0) {
310 return -1;
311 }
312 return 0;
313 }
314