~ubuntu-branches/ubuntu/quantal/vice/quantal

« back to all changes in this revision

Viewing changes to src/c64/ramcart.c

  • Committer: Bazaar Package Importer
  • Author(s): Zed Pobre
  • Date: 2006-07-30 19:15:59 UTC
  • mto: (9.1.1 lenny) (1.1.6 upstream)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20060730191559-g31ymd2mk102kzff
Tags: upstream-1.19
ImportĀ upstreamĀ versionĀ 1.19

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ramcart.c - RAMCART emulation.
 
3
 *
 
4
 * Written by
 
5
 *  Marco van den Heuvel <blackystardust68@yahoo.com>
 
6
 * 
 
7
 * This file is part of VICE, the Versatile Commodore Emulator.
 
8
 * See README for copyright notice.
 
9
 *
 
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.
 
14
 *
 
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.
 
19
 *
 
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
 
23
 *  02111-1307  USA.
 
24
 *
 
25
 */
 
26
 
 
27
#include "vice.h"
 
28
 
 
29
#include <stdio.h>
 
30
#include <stdlib.h>
 
31
#include <string.h>
 
32
 
 
33
#include "c64cart.h"
 
34
#include "c64export.h"
 
35
#include "c64mem.h"
 
36
#include "cartridge.h"
 
37
#include "cmdline.h"
 
38
#include "interrupt.h"
 
39
#include "lib.h"
 
40
#include "log.h"
 
41
#include "machine.h"
 
42
#include "maincpu.h"
 
43
#include "mem.h"
 
44
#include "plus60k.h"
 
45
#include "resources.h"
 
46
#include "ramcart.h"
 
47
#include "snapshot.h"
 
48
#ifdef HAS_TRANSLATION
 
49
#include "translate.h"
 
50
#endif
 
51
#include "types.h"
 
52
#include "util.h"
 
53
 
 
54
 
 
55
static const c64export_resource_t export_res = {
 
56
    "RAMCART", 1, 1, 1, 0
 
57
};
 
58
 
 
59
/* RAMCART registers */
 
60
static BYTE ramcart[2];
 
61
 
 
62
/* RAMCART image.  */
 
63
static BYTE *ramcart_ram = NULL;
 
64
static unsigned int old_ramcart_ram_size = 0;
 
65
 
 
66
static log_t ramcart_log = LOG_ERR;
 
67
 
 
68
static int ramcart_activate(void);
 
69
static int ramcart_deactivate(void);
 
70
 
 
71
/* ------------------------------------------------------------------------- */
 
72
 
 
73
/* Flag: Do we enable the external RAMCART?  */
 
74
int ramcart_enabled;
 
75
 
 
76
/* Flag: Is the RAMCART readonly ?  */
 
77
int ramcart_readonly=0;
 
78
 
 
79
/* Size of the RAMCART.  */
 
80
static DWORD ramcart_size = 0;
 
81
 
 
82
/* Size of the RAMCART in KB.  */
 
83
static DWORD ramcart_size_kb = 0;
 
84
 
 
85
/* Filename of the RAMCART image.  */
 
86
static char *ramcart_filename = NULL;
 
87
 
 
88
void ramcart_init_config(void)
 
89
{
 
90
  if (ramcart_enabled)
 
91
  {
 
92
    export.exrom=1;
 
93
    mem_pla_config_changed();
 
94
  }
 
95
}
 
96
 
 
97
static int set_ramcart_enabled(resource_value_t v, void *param)
 
98
{
 
99
    if (!(int)v) {
 
100
        if (ramcart_enabled) {
 
101
            if (ramcart_deactivate() < 0) {
 
102
                return -1;
 
103
            }
 
104
        }
 
105
        c64export_remove(&export_res);
 
106
        ramcart_enabled = 0;
 
107
        export.exrom=0;
 
108
        mem_pla_config_changed();
 
109
        return 0;
 
110
    } else { 
 
111
        if (c64export_query(&export_res) >= 0) {
 
112
            if (!ramcart_enabled) {
 
113
                if (ramcart_activate() < 0) {
 
114
                    return -1;
 
115
                }
 
116
            }
 
117
 
 
118
            if (c64export_add(&export_res) < 0)
 
119
                return -1;
 
120
 
 
121
            ramcart_enabled = 1;
 
122
            export.exrom=1;
 
123
            mem_pla_config_changed();
 
124
            return 0;
 
125
        } else {
 
126
            return -1;
 
127
        }
 
128
    }
 
129
}
 
130
 
 
131
static int set_ramcart_readonly(resource_value_t v, void *param)
 
132
{
 
133
  ramcart_readonly=(int)v;
 
134
  return 0;
 
135
}
 
136
 
 
137
static int set_ramcart_size(resource_value_t v, void *param)
 
138
{
 
139
    if ((DWORD)v == ramcart_size_kb)
 
140
        return 0;
 
141
 
 
142
    switch ((DWORD)v) {
 
143
      case 64:
 
144
      case 128:
 
145
        break;
 
146
      default:
 
147
        log_message(ramcart_log, "Unknown RAMCART size %ld.", (long)v);
 
148
        return -1;
 
149
    }
 
150
 
 
151
    if (ramcart_enabled) {
 
152
        ramcart_deactivate();
 
153
        ramcart_size_kb = (DWORD)v;
 
154
        ramcart_size = ramcart_size_kb << 10;
 
155
        ramcart_activate();
 
156
    } else {
 
157
        ramcart_size_kb = (DWORD)v;
 
158
        ramcart_size = ramcart_size_kb << 10;
 
159
    }
 
160
 
 
161
    return 0;
 
162
}
 
163
 
 
164
static int set_ramcart_filename(resource_value_t v, void *param)
 
165
{
 
166
    const char *name = (const char *)v;
 
167
 
 
168
    if (ramcart_filename != NULL && name != NULL
 
169
        && strcmp(name, ramcart_filename) == 0)
 
170
        return 0;
 
171
 
 
172
    if (ramcart_enabled) {
 
173
        ramcart_deactivate();
 
174
        util_string_set(&ramcart_filename, name);
 
175
        ramcart_activate();
 
176
    } else {
 
177
        util_string_set(&ramcart_filename, name);
 
178
    }
 
179
 
 
180
    return 0;
 
181
}
 
182
 
 
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 },
 
192
    { NULL }
 
193
};
 
194
 
 
195
int ramcart_resources_init(void)
 
196
{
 
197
    return resources_register(resources);
 
198
}
 
199
 
 
200
void ramcart_resources_shutdown(void)
 
201
{
 
202
    lib_free(ramcart_filename);
 
203
}
 
204
 
 
205
/* ------------------------------------------------------------------------- */
 
206
 
 
207
#ifdef HAS_TRANSLATION
 
208
static const cmdline_option_t cmdline_options[] =
 
209
{
 
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 },
 
218
    { NULL }
 
219
};
 
220
#else
 
221
static const cmdline_option_t cmdline_options[] =
 
222
{
 
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") },
 
231
    { NULL }
 
232
};
 
233
#endif
 
234
 
 
235
int ramcart_cmdline_options_init(void)
 
236
{
 
237
    return cmdline_register_options(cmdline_options);
 
238
}
 
239
 
 
240
/* ------------------------------------------------------------------------- */
 
241
 
 
242
void ramcart_init(void)
 
243
{
 
244
    ramcart_log = log_open("RAMCART");
 
245
}
 
246
 
 
247
void ramcart_reset(void)
 
248
{
 
249
  ramcart[0]=0;
 
250
  ramcart[1]=0;
 
251
}
 
252
 
 
253
static int ramcart_activate(void)
 
254
{
 
255
    if (!ramcart_size)
 
256
        return 0;
 
257
 
 
258
    ramcart_ram = (BYTE *)lib_realloc((void *)ramcart_ram, (size_t)ramcart_size);
 
259
 
 
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));
 
263
 
 
264
    old_ramcart_ram_size = ramcart_size;
 
265
 
 
266
    log_message(ramcart_log, "%dKB unit installed.", (int)(ramcart_size >> 10));
 
267
 
 
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);
 
276
                return -1;
 
277
            }
 
278
            log_message(ramcart_log, "Creating RAMCART image %s.", ramcart_filename);
 
279
            return 0;
 
280
        }
 
281
        log_message(ramcart_log, "Reading RAMCART image %s.", ramcart_filename);
 
282
    }
 
283
 
 
284
    ramcart_reset();
 
285
    return 0;
 
286
}
 
287
 
 
288
static int ramcart_deactivate(void)
 
289
{
 
290
    if (ramcart_ram == NULL)
 
291
        return 0;
 
292
 
 
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);
 
297
            return -1;
 
298
        }
 
299
        log_message(ramcart_log, "Writing RAMCART image %s.", ramcart_filename);
 
300
    }
 
301
 
 
302
    lib_free(ramcart_ram);
 
303
    ramcart_ram = NULL;
 
304
    old_ramcart_ram_size = 0;
 
305
 
 
306
    return 0;
 
307
}
 
308
 
 
309
void ramcart_shutdown(void)
 
310
{
 
311
    ramcart_deactivate();
 
312
}
 
313
 
 
314
/* ------------------------------------------------------------------------- */
 
315
 
 
316
BYTE REGPARM1 ramcart_reg_read(WORD addr)
 
317
{
 
318
    BYTE retval;
 
319
 
 
320
    retval=ramcart[addr];
 
321
 
 
322
    return retval;
 
323
}
 
324
 
 
325
void REGPARM2 ramcart_reg_store(WORD addr, BYTE byte)
 
326
{
 
327
  if (addr==1 && ramcart_size_kb==128)
 
328
    ramcart[1]=byte;
 
329
   if (addr==0)
 
330
     ramcart[0]=byte;
 
331
}
 
332
 
 
333
BYTE REGPARM1 ramcart_roml_read(WORD addr)
 
334
{
 
335
    BYTE retval;
 
336
 
 
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)];
 
339
    else
 
340
      retval=plus60k_ram_read(addr);
 
341
    return retval;
 
342
}
 
343
 
 
344
void REGPARM2 ramcart_roml_store(WORD addr, BYTE byte)
 
345
{
 
346
    plus60k_ram_store(addr, byte);
 
347
}
 
348
 
 
349
BYTE REGPARM1 ramcart_window_read(WORD addr)
 
350
{
 
351
    BYTE retval;
 
352
 
 
353
    retval=ramcart_ram[((ramcart[1]&1)*65536)+(ramcart[0]*256)+(addr&0xff)];
 
354
 
 
355
    return retval;
 
356
}
 
357
 
 
358
void REGPARM2 ramcart_window_store(WORD addr, BYTE byte)
 
359
{
 
360
  ramcart_ram[((ramcart[1]&1)*65536)+(ramcart[0]*256)+(addr&0xff)]=byte;
 
361
}