2
* ramcart.c - RAMCART emulation.
5
* Marco van den Heuvel <blackystardust68@yahoo.com>
7
* This file is part of VICE, the Versatile Commodore Emulator.
8
* See README for copyright notice.
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
34
#include "c64export.h"
36
#include "cartridge.h"
38
#include "interrupt.h"
45
#include "resources.h"
48
#ifdef HAS_TRANSLATION
49
#include "translate.h"
55
static const c64export_resource_t export_res = {
59
/* RAMCART registers */
60
static BYTE ramcart[2];
63
static BYTE *ramcart_ram = NULL;
64
static unsigned int old_ramcart_ram_size = 0;
66
static log_t ramcart_log = LOG_ERR;
68
static int ramcart_activate(void);
69
static int ramcart_deactivate(void);
71
/* ------------------------------------------------------------------------- */
73
/* Flag: Do we enable the external RAMCART? */
76
/* Flag: Is the RAMCART readonly ? */
77
int ramcart_readonly=0;
79
/* Size of the RAMCART. */
80
static DWORD ramcart_size = 0;
82
/* Size of the RAMCART in KB. */
83
static DWORD ramcart_size_kb = 0;
85
/* Filename of the RAMCART image. */
86
static char *ramcart_filename = NULL;
88
void ramcart_init_config(void)
93
mem_pla_config_changed();
97
static int set_ramcart_enabled(resource_value_t v, void *param)
100
if (ramcart_enabled) {
101
if (ramcart_deactivate() < 0) {
105
c64export_remove(&export_res);
108
mem_pla_config_changed();
111
if (c64export_query(&export_res) >= 0) {
112
if (!ramcart_enabled) {
113
if (ramcart_activate() < 0) {
118
if (c64export_add(&export_res) < 0)
123
mem_pla_config_changed();
131
static int set_ramcart_readonly(resource_value_t v, void *param)
133
ramcart_readonly=(int)v;
137
static int set_ramcart_size(resource_value_t v, void *param)
139
if ((DWORD)v == ramcart_size_kb)
147
log_message(ramcart_log, "Unknown RAMCART size %ld.", (long)v);
151
if (ramcart_enabled) {
152
ramcart_deactivate();
153
ramcart_size_kb = (DWORD)v;
154
ramcart_size = ramcart_size_kb << 10;
157
ramcart_size_kb = (DWORD)v;
158
ramcart_size = ramcart_size_kb << 10;
164
static int set_ramcart_filename(resource_value_t v, void *param)
166
const char *name = (const char *)v;
168
if (ramcart_filename != NULL && name != NULL
169
&& strcmp(name, ramcart_filename) == 0)
172
if (ramcart_enabled) {
173
ramcart_deactivate();
174
util_string_set(&ramcart_filename, name);
177
util_string_set(&ramcart_filename, name);
183
static const resource_t resources[] = {
184
{ "RAMCART", RES_INTEGER, (resource_value_t)0,
185
(void *)&ramcart_enabled, set_ramcart_enabled, NULL },
186
{ "RAMCART_RO", RES_INTEGER, (resource_value_t)0,
187
(void *)&ramcart_readonly, set_ramcart_readonly, NULL },
188
{ "RAMCARTsize", RES_INTEGER, (resource_value_t)128,
189
(void *)&ramcart_size_kb, set_ramcart_size, NULL },
190
{ "RAMCARTfilename", RES_STRING, (resource_value_t)"",
191
(void *)&ramcart_filename, set_ramcart_filename, NULL },
195
int ramcart_resources_init(void)
197
return resources_register(resources);
200
void ramcart_resources_shutdown(void)
202
lib_free(ramcart_filename);
205
/* ------------------------------------------------------------------------- */
207
#ifdef HAS_TRANSLATION
208
static const cmdline_option_t cmdline_options[] =
210
{ "-ramcart", SET_RESOURCE, 0, NULL, NULL, "RAMCART", (resource_value_t)1,
211
0, IDCLS_ENABLE_RAMCART },
212
{ "+ramcart", SET_RESOURCE, 0, NULL, NULL, "RAMCART", (resource_value_t)0,
213
0, IDCLS_DISABLE_RAMCART },
214
{ "-ramcartimage", SET_RESOURCE, 1, NULL, NULL, "RAMCARTfilename", NULL,
215
IDCLS_P_NAME, IDCLS_SPECIFY_RAMCART_NAME },
216
{ "-ramcartsize", SET_RESOURCE, 1, NULL, NULL, "RAMCARTsize", NULL,
217
IDCLS_P_SIZE_IN_KB, IDCLS_RAMCART_SIZE },
221
static const cmdline_option_t cmdline_options[] =
223
{ "-ramcart", SET_RESOURCE, 0, NULL, NULL, "RAMCART", (resource_value_t)1,
224
NULL, N_("Enable the RAMCART expansion") },
225
{ "+ramcart", SET_RESOURCE, 0, NULL, NULL, "RAMCART", (resource_value_t)0,
226
NULL, N_("Disable the RAMCART expansion") },
227
{ "-ramcartimage", SET_RESOURCE, 1, NULL, NULL, "RAMCARTfilename", NULL,
228
N_("<name>"), N_("Specify name of RAMCART image") },
229
{ "-ramcartsize", SET_RESOURCE, 1, NULL, NULL, "RAMCARTsize", NULL,
230
N_("<size in KB>"), N_("Size of the RAMCART expansion") },
235
int ramcart_cmdline_options_init(void)
237
return cmdline_register_options(cmdline_options);
240
/* ------------------------------------------------------------------------- */
242
void ramcart_init(void)
244
ramcart_log = log_open("RAMCART");
247
void ramcart_reset(void)
253
static int ramcart_activate(void)
258
ramcart_ram = (BYTE *)lib_realloc((void *)ramcart_ram, (size_t)ramcart_size);
260
/* Clear newly allocated RAM. */
261
if (ramcart_size > old_ramcart_ram_size)
262
memset(ramcart_ram, 0, (size_t)(ramcart_size - old_ramcart_ram_size));
264
old_ramcart_ram_size = ramcart_size;
266
log_message(ramcart_log, "%dKB unit installed.", (int)(ramcart_size >> 10));
268
if (!util_check_null_string(ramcart_filename)) {
269
if (util_file_load(ramcart_filename, ramcart_ram, (size_t)ramcart_size,
270
UTIL_FILE_LOAD_RAW) < 0) {
271
log_message(ramcart_log,
272
"Reading RAMCART image %s failed.", ramcart_filename);
273
if (util_file_save(ramcart_filename, ramcart_ram, ramcart_size) < 0) {
274
log_message(ramcart_log,
275
"Creating RAMCART image %s failed.", ramcart_filename);
278
log_message(ramcart_log, "Creating RAMCART image %s.", ramcart_filename);
281
log_message(ramcart_log, "Reading RAMCART image %s.", ramcart_filename);
288
static int ramcart_deactivate(void)
290
if (ramcart_ram == NULL)
293
if (!util_check_null_string(ramcart_filename)) {
294
if (util_file_save(ramcart_filename, ramcart_ram, ramcart_size) < 0) {
295
log_message(ramcart_log,
296
"Writing RAMCART image %s failed.", ramcart_filename);
299
log_message(ramcart_log, "Writing RAMCART image %s.", ramcart_filename);
302
lib_free(ramcart_ram);
304
old_ramcart_ram_size = 0;
309
void ramcart_shutdown(void)
311
ramcart_deactivate();
314
/* ------------------------------------------------------------------------- */
316
BYTE REGPARM1 ramcart_reg_read(WORD addr)
320
retval=ramcart[addr];
325
void REGPARM2 ramcart_reg_store(WORD addr, BYTE byte)
327
if (addr==1 && ramcart_size_kb==128)
333
BYTE REGPARM1 ramcart_roml_read(WORD addr)
337
if (ramcart_readonly==1 && ramcart_size_kb==128 && addr>=0x8000 && addr<=0x80ff)
338
retval=ramcart_ram[((ramcart[1]&1)*65536)+(ramcart[0]*256)+(addr&0xff)];
340
retval=plus60k_ram_read(addr);
344
void REGPARM2 ramcart_roml_store(WORD addr, BYTE byte)
346
plus60k_ram_store(addr, byte);
349
BYTE REGPARM1 ramcart_window_read(WORD addr)
353
retval=ramcart_ram[((ramcart[1]&1)*65536)+(ramcart[0]*256)+(addr&0xff)];
358
void REGPARM2 ramcart_window_store(WORD addr, BYTE byte)
360
ramcart_ram[((ramcart[1]&1)*65536)+(ramcart[0]*256)+(addr&0xff)]=byte;