~ubuntu-branches/ubuntu/trusty/vice/trusty

« back to all changes in this revision

Viewing changes to src/c64/cart/ds12c887rtc.c

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2013-07-28 20:38:23 UTC
  • mfrom: (1.1.10) (9.2.7 sid)
  • Revision ID: package-import@ubuntu.com-20130728203823-1h8s6bcv22oundul
Tags: 2.4.dfsg-1
* New upstream release (closes: #693065, #693641).
* Drop vice-ffmpeg.patch , applied upstream.
* Disable architecture specific compilation (closes: #686400, #714136).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ds12c887rtc.c - DS12C887 RTC based cartridge 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 "c64export.h"
 
34
#include "cartio.h"
 
35
#include "cartridge.h"
 
36
#include "cmdline.h"
 
37
#include "ds12c887.h"
 
38
#include "ds12c887rtc.h"
 
39
#include "lib.h"
 
40
#include "machine.h"
 
41
#include "maincpu.h"
 
42
#include "resources.h"
 
43
#include "sid.h"
 
44
#include "snapshot.h"
 
45
#include "uiapi.h"
 
46
#include "translate.h"
 
47
 
 
48
/*
 
49
    DS12C887 RTC Cartridge
 
50
 
 
51
    This cartridge is an RTC interface.
 
52
 
 
53
    When inserted into the cart port the cart uses 2 registers,
 
54
    one for setting the register being addressed and 1 for
 
55
    reading/writing the RTC register. The base address can be
 
56
    relocated to the following : $D500, $D600, $D700, $DE00, $DF00.
 
57
*/
 
58
 
 
59
/* RTC enabled ?? */
 
60
static int ds12c887rtc_enabled = 0;
 
61
 
 
62
/* RTC base address */
 
63
static int ds12c887rtc_base_address;
 
64
 
 
65
/* ---------------------------------------------------------------------*/
 
66
 
 
67
/* Some prototypes are needed */
 
68
static BYTE ds12c887rtc_read(WORD addr);
 
69
static void ds12c887rtc_store(WORD addr, BYTE byte);
 
70
 
 
71
static io_source_t ds12c887rtc_device = {
 
72
    CARTRIDGE_NAME_DS12C887RTC,
 
73
    IO_DETACH_RESOURCE,
 
74
    "DS12C887RTC",
 
75
    0xde00, 0xde01, 0xff,
 
76
    0,
 
77
    ds12c887rtc_store,
 
78
    ds12c887rtc_read,
 
79
    ds12c887rtc_read,
 
80
    NULL,
 
81
    CARTRIDGE_DS12C887RTC,
 
82
    0,
 
83
    0
 
84
};
 
85
 
 
86
static io_source_list_t *ds12c887rtc_list_item = NULL;
 
87
 
 
88
static c64export_resource_t export_res = {
 
89
    CARTRIDGE_NAME_DS12C887RTC, 0, 0, &ds12c887rtc_device, NULL, CARTRIDGE_DS12C887RTC
 
90
};
 
91
 
 
92
/* ds12c887 context */
 
93
static rtc_ds12c887_t *ds12c887rtc_context = NULL;
 
94
 
 
95
/* ds12c887 offset */
 
96
/* FIXME: Implement saving/setting/loading of the offset */
 
97
static time_t ds12c887rtc_offset = 0;
 
98
 
 
99
/* rtc ram */
 
100
/* FIXME: Implement saving/loading of the ram */
 
101
static char ds12c887rtc_ram[128];
 
102
 
 
103
/* ---------------------------------------------------------------------*/
 
104
 
 
105
int ds12c887rtc_cart_enabled(void)
 
106
{
 
107
    return ds12c887rtc_enabled;
 
108
}
 
109
 
 
110
static int set_ds12c887rtc_enabled(int val, void *param)
 
111
{
 
112
    if (!ds12c887rtc_enabled && val) {
 
113
        if (c64export_add(&export_res) < 0) {
 
114
            return -1;
 
115
        }
 
116
        ds12c887rtc_list_item = io_source_register(&ds12c887rtc_device);
 
117
        ds12c887rtc_context = ds12c887_init((BYTE *)ds12c887rtc_ram, &ds12c887rtc_offset);
 
118
        ds12c887rtc_enabled = 1;
 
119
    } else if (ds12c887rtc_enabled && !val) {
 
120
        if (ds12c887rtc_list_item != NULL) {
 
121
            c64export_remove(&export_res);
 
122
            io_source_unregister(ds12c887rtc_list_item);
 
123
            ds12c887rtc_list_item = NULL;
 
124
            ds12c887_destroy(ds12c887rtc_context);
 
125
        }
 
126
        ds12c887rtc_enabled = 0;
 
127
    }
 
128
    return 0;
 
129
}
 
130
 
 
131
static int set_ds12c887rtc_base(int val, void *param)
 
132
{
 
133
    int addr = val;
 
134
    int old = ds12c887rtc_enabled;
 
135
 
 
136
    if (val == ds12c887rtc_base_address) {
 
137
        return 0;
 
138
    }
 
139
 
 
140
    if (addr == 0xffff) {
 
141
        if (machine_class == VICE_MACHINE_VIC20) {
 
142
            addr = 0x9800;
 
143
        } else {
 
144
            addr = 0xde00;
 
145
        }
 
146
    }
 
147
 
 
148
    if (old) {
 
149
        set_ds12c887rtc_enabled(0, NULL);
 
150
    }
 
151
 
 
152
    switch (addr) {
 
153
        case 0xde00:
 
154
            if (machine_class != VICE_MACHINE_VIC20) {
 
155
                ds12c887rtc_device.start_address = (WORD)addr;
 
156
                ds12c887rtc_device.end_address = (WORD)(addr + 1);
 
157
                export_res.io1 = &ds12c887rtc_device;
 
158
                export_res.io2 = NULL;
 
159
            } else {
 
160
                return -1;
 
161
            }
 
162
            break;
 
163
        case 0xdf00:
 
164
            if (machine_class != VICE_MACHINE_VIC20) {
 
165
                ds12c887rtc_device.start_address = (WORD)addr;
 
166
                ds12c887rtc_device.end_address = (WORD)(addr + 1);
 
167
                export_res.io1 = NULL;
 
168
                export_res.io2 = &ds12c887rtc_device;
 
169
            } else {
 
170
                return -1;
 
171
            }
 
172
            break;
 
173
/* FIXME: $d100/$d200/$d300 base address handling still needs to be implemented */
 
174
#if 0
 
175
        case 0xd100:
 
176
        case 0xd200:
 
177
        case 0xd300:
 
178
#endif
 
179
        case 0xd700:
 
180
            if (machine_class != VICE_MACHINE_VIC20) {
 
181
                ds12c887rtc_device.start_address = (WORD)addr;
 
182
                ds12c887rtc_device.end_address = (WORD)(addr + 1);
 
183
                export_res.io1 = NULL;
 
184
                export_res.io2 = NULL;
 
185
            } else {
 
186
                return -1;
 
187
            }
 
188
            break;
 
189
        case 0xd500:
 
190
        case 0xd600:
 
191
            if (machine_class != VICE_MACHINE_VIC20 && machine_class != VICE_MACHINE_C128) {
 
192
                ds12c887rtc_device.start_address = (WORD)addr;
 
193
                ds12c887rtc_device.end_address = (WORD)(addr + 1);
 
194
                export_res.io1 = NULL;
 
195
                export_res.io2 = NULL;
 
196
            } else {
 
197
                return -1;
 
198
            }
 
199
            break;
 
200
        case 0x9800:
 
201
        case 0x9c00:
 
202
            if (machine_class == VICE_MACHINE_VIC20) {
 
203
                ds12c887rtc_device.start_address = (WORD)addr;
 
204
                ds12c887rtc_device.end_address = (WORD)(addr + 1);
 
205
             } else {
 
206
                return -1;
 
207
            }
 
208
            break;
 
209
        default:
 
210
            return -1;
 
211
    }
 
212
 
 
213
    ds12c887rtc_base_address = val;
 
214
 
 
215
    if (old) {
 
216
        set_ds12c887rtc_enabled(1, NULL);
 
217
    }
 
218
    return 0;
 
219
}
 
220
 
 
221
void ds12c887rtc_reset(void)
 
222
{
 
223
    if (ds12c887rtc_context) {
 
224
        ds12c887_reset(ds12c887rtc_context);
 
225
    }
 
226
}
 
227
 
 
228
int ds12c887rtc_enable(void)
 
229
{
 
230
    return resources_set_int("DS12C887RTC", 1);
 
231
}
 
232
 
 
233
void ds12c887rtc_detach(void)
 
234
{
 
235
    resources_set_int("DS12C887RTC", 0);
 
236
}
 
237
 
 
238
/* ---------------------------------------------------------------------*/
 
239
 
 
240
static BYTE ds12c887rtc_read(WORD addr)
 
241
{
 
242
    if (addr & 1) {
 
243
        ds12c887rtc_device.io_source_valid = 1;
 
244
        return ds12c887_read(ds12c887rtc_context);
 
245
    }
 
246
 
 
247
    ds12c887rtc_device.io_source_valid = 0;
 
248
 
 
249
    return 0;
 
250
}
 
251
 
 
252
static void ds12c887rtc_store(WORD addr, BYTE byte)
 
253
{
 
254
    if (addr & 1) {
 
255
        ds12c887_store_data(ds12c887rtc_context, byte);
 
256
    } else {
 
257
        ds12c887_store_address(ds12c887rtc_context, byte);
 
258
    }
 
259
}
 
260
 
 
261
/* ---------------------------------------------------------------------*/
 
262
 
 
263
static const resource_int_t resources_int[] = {
 
264
  { "DS12C887RTC", 0, RES_EVENT_STRICT, (resource_value_t)0,
 
265
    &ds12c887rtc_enabled, set_ds12c887rtc_enabled, NULL },
 
266
  { "DS12C887RTCbase", 0xffff, RES_EVENT_NO, NULL,
 
267
    &ds12c887rtc_base_address, set_ds12c887rtc_base, NULL },
 
268
  { NULL }
 
269
};
 
270
 
 
271
int ds12c887rtc_resources_init(void)
 
272
{
 
273
    return resources_register_int(resources_int);
 
274
}
 
275
 
 
276
void ds12c887rtc_resources_shutdown(void)
 
277
{
 
278
    if (ds12c887rtc_context) {
 
279
        ds12c887_destroy(ds12c887rtc_context);
 
280
    }
 
281
}
 
282
 
 
283
/* ---------------------------------------------------------------------*/
 
284
 
 
285
static const cmdline_option_t cmdline_options[] =
 
286
{
 
287
    { "-ds12c887rtc", SET_RESOURCE, 0,
 
288
      NULL, NULL, "DS12C887RTC", (resource_value_t)1,
 
289
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
290
      IDCLS_UNUSED, IDCLS_ENABLE_DS12C887RTC,
 
291
      NULL, NULL },
 
292
    { "+ds12c887rtc", SET_RESOURCE, 0,
 
293
      NULL, NULL, "DS12C887RTC", (resource_value_t)0,
 
294
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
295
      IDCLS_UNUSED, IDCLS_DISABLE_DS12C887RTC,
 
296
      NULL, NULL },
 
297
    { "-ds12c887rtcbase", SET_RESOURCE, 1,
 
298
      NULL, NULL, "DS12C887RTCbase", NULL,
 
299
      USE_PARAM_ID, USE_DESCRIPTION_ID,
 
300
      IDCLS_P_BASE_ADDRESS, IDCLS_DS12C887RTC_BASE,
 
301
      NULL, NULL },
 
302
    { NULL }
 
303
};
 
304
 
 
305
int ds12c887rtc_cmdline_options_init(void)
 
306
{
 
307
    return cmdline_register_options(cmdline_options);
 
308
}
 
309
 
 
310
/* ---------------------------------------------------------------------*/
 
311
 
 
312
#define CART_DUMP_VER_MAJOR   0
 
313
#define CART_DUMP_VER_MINOR   0
 
314
#define SNAP_MODULE_NAME  "CARTDS12C887RTC"
 
315
 
 
316
int ds12c887rtc_snapshot_write_module(snapshot_t *s)
 
317
{
 
318
    snapshot_module_t *m;
 
319
 
 
320
    m = snapshot_module_create(s, SNAP_MODULE_NAME,
 
321
                          CART_DUMP_VER_MAJOR, CART_DUMP_VER_MINOR);
 
322
    if (m == NULL) {
 
323
        return -1;
 
324
    }
 
325
 
 
326
    /* FIXME: Implement the RTC snapshot part */
 
327
    if (0
 
328
        || (SMW_DW(m, (DWORD)ds12c887rtc_base_address) < 0)) {
 
329
        snapshot_module_close(m);
 
330
        return -1;
 
331
    }
 
332
 
 
333
    snapshot_module_close(m);
 
334
    return 0;
 
335
}
 
336
 
 
337
int ds12c887rtc_snapshot_read_module(snapshot_t *s)
 
338
{
 
339
    BYTE vmajor, vminor;
 
340
    snapshot_module_t *m;
 
341
    int temp_ds12c887rtc_address;
 
342
 
 
343
    m = snapshot_module_open(s, SNAP_MODULE_NAME, &vmajor, &vminor);
 
344
    if (m == NULL) {
 
345
        return -1;
 
346
    }
 
347
 
 
348
    if ((vmajor != CART_DUMP_VER_MAJOR) || (vminor != CART_DUMP_VER_MINOR)) {
 
349
        snapshot_module_close(m);
 
350
        return -1;
 
351
    }
 
352
 
 
353
    /* FIXME: Implement the RTC snapshot part */
 
354
    if (0
 
355
        || (SMR_DW_INT(m, &temp_ds12c887rtc_address) < 0)) {
 
356
        snapshot_module_close(m);
 
357
        return -1;
 
358
    }
 
359
 
 
360
    snapshot_module_close(m);
 
361
 
 
362
    /* HACK set address to an invalid value, then use the function */
 
363
    ds12c887rtc_base_address = -1;
 
364
    set_ds12c887rtc_base(temp_ds12c887rtc_address, NULL);
 
365
 
 
366
    return ds12c887rtc_enable();
 
367
}