32
32
#include <stdlib.h>
35
34
#include "attach.h"
36
35
#include "autostart.h"
37
36
#include "c64-cmdline-options.h"
38
37
#include "c64-resources.h"
39
38
#include "c64-snapshot.h"
41
41
#include "c64cart.h"
42
42
#include "c64cia.h"
43
#include "c64export.h"
44
#include "c64fastiec.h"
46
#include "c64keyboard.h"
47
#include "c64memrom.h"
48
#include "c64rsuser.h"
44
49
#include "c64tpi.h"
46
51
#include "cartridge.h"
48
53
#include "clkguard.h"
50
54
#include "datasette.h"
51
56
#include "drive-cmdline-options.h"
52
57
#include "drive-resources.h"
53
#include "drive-snapshot.h"
55
59
#include "drivecpu.h"
57
#include "interrupt.h"
60
#include "imagecontents.h"
58
61
#include "kbdbuf.h"
59
62
#include "keyboard.h"
64
#include "machine-drive.h"
65
#include "machine-printer.h"
66
#include "machine-video.h"
61
67
#include "machine.h"
62
68
#include "maincpu.h"
65
72
#include "patchrom.h"
66
73
#include "printer.h"
68
75
#include "resources.h"
70
79
#include "screenshot.h"
71
80
#include "serial.h"
72
81
#include "sid-cmdline-options.h"
73
82
#include "sid-resources.h"
74
#include "sid-snapshot.h"
84
91
#include "vsidui.h"
89
#include "c64rsuser.h"
103
machine_context_t machine_context;
105
#define NUM_KEYBOARD_MAPPINGS 3
107
const char *machine_keymap_res_name_list[NUM_KEYBOARD_MAPPINGS] = {
108
"KeymapSymFile", "KeymapSymDeFile", "KeymapPosFile"
111
char *machine_keymap_file_list[NUM_KEYBOARD_MAPPINGS] = {
99
115
const char machine_name[] = "C64";
116
int machine_class = VICE_MACHINE_C64;
101
118
static void machine_vsync_hook(void);
103
120
/* ------------------------------------------------------------------------- */
106
static trap_t c64_serial_traps[] = {
122
static const trap_t c64_serial_traps[] = {
111
127
{ 0x20, 0x97, 0xEE },
128
serial_trap_attention,
117
133
"SerialSaListen",
120
136
{ 0x78, 0x20, 0x8E },
137
serial_trap_attention,
126
142
"SerialSendByte",
129
145
{ 0x78, 0x20, 0x97 },
135
151
"SerialReceiveByte",
138
154
{ 0x78, 0xA9, 0x00 },
147
163
{ 0xAD, 0x00, 0xDD },
163
179
/* Tape traps. */
164
static trap_t c64_tape_traps[] = {
180
static const trap_t c64_tape_traps[] = {
166
182
"TapeFindHeader",
185
{ 0x20, 0x41, 0xF8 },
170
186
tape_find_header_trap,
194
{ 0x20, 0xBD, 0xFC },
179
195
tape_receive_trap,
210
static const tape_init_t tapeinit = {
194
229
static log_t c64_log = LOG_ERR;
196
static long cycles_per_sec = C64_PAL_CYCLES_PER_SEC;
197
static long cycles_per_rfsh = C64_PAL_CYCLES_PER_RFSH;
198
static double rfsh_per_sec = C64_PAL_RFSH_PER_SEC;
230
static machine_timing_t machine_timing;
200
232
/* ------------------------------------------------------------------------ */
202
234
/* C64-specific resource initialization. This is called before initializing
203
235
the machine itself with `machine_init()'. */
204
int machine_init_resources(void)
236
int machine_resources_init(void)
206
238
if (traps_resources_init() < 0
207
239
|| vsync_resources_init() < 0
208
|| video_resources_init(VIDEO_RESOURCES_PAL) < 0
240
|| machine_video_resources_init() < 0
209
241
|| c64_resources_init() < 0
242
|| c64export_resources_init() < 0
210
243
|| reu_resources_init() < 0
211
|| vic_ii_resources_init() < 0
245
|| tfe_resources_init() < 0
247
|| vicii_resources_init() < 0
212
248
|| sound_resources_init() < 0
213
249
|| sid_resources_init() < 0
215
250
|| acia1_resources_init() < 0
216
|| rs232_resources_init() < 0
251
|| rs232drv_resources_init() < 0
217
252
|| rsuser_resources_init() < 0
253
|| serial_resources_init() < 0
219
254
|| printer_resources_init() < 0
220
255
#ifdef HAVE_MOUSE
221
256
|| mouse_resources_init() < 0
223
259
|| kbd_resources_init() < 0
224
261
|| drive_resources_init() < 0
225
262
|| datasette_resources_init() < 0
226
263
|| cartridge_resources_init() < 0
251
301
|| video_init_cmdline_options() < 0
252
302
|| c64_cmdline_options_init() < 0
253
303
|| reu_cmdline_options_init() < 0
254
|| vic_ii_cmdline_options_init() < 0
305
|| tfe_cmdline_options_init() < 0
307
|| vicii_cmdline_options_init() < 0
255
308
|| sound_cmdline_options_init() < 0
256
309
|| sid_cmdline_options_init() < 0
258
310
|| acia1_cmdline_options_init() < 0
259
|| rs232_cmdline_options_init() < 0
311
|| rs232drv_cmdline_options_init() < 0
260
312
|| rsuser_cmdline_options_init() < 0
313
|| serial_cmdline_options_init() < 0
262
314
|| printer_cmdline_options_init() < 0
263
315
#ifdef HAVE_MOUSE
264
316
|| mouse_cmdline_options_init() < 0
266
319
|| kbd_cmdline_options_init() < 0
267
321
|| drive_cmdline_options_init() < 0
268
322
|| datasette_cmdline_options_init() < 0
269
323
|| cartridge_cmdline_options_init() < 0
276
330
static void c64_monitor_init(void)
278
333
monitor_cpu_type_t asm6502;
279
monitor_cpu_type_t *asmarray[2];
334
monitor_cpu_type_t *asmarray[2] = { &asm6502, NULL };
335
monitor_interface_t *drive_interface_init[DRIVE_NUM];
281
337
asm6502_init(&asm6502);
283
asmarray[0] = &asm6502;
339
for (dnr = 0; dnr < DRIVE_NUM; dnr++)
340
drive_interface_init[dnr] = drivecpu_monitor_interface_get(dnr);
286
342
/* Initialize the monitor. */
287
monitor_init(&maincpu_monitor_interface, drive0_get_monitor_interface_ptr(),
288
drive1_get_monitor_interface_ptr(), asmarray);
343
monitor_init(maincpu_monitor_interface_get(), drive_interface_init,
347
void machine_setup_context(void)
349
cia1_setup_context(&machine_context);
350
cia2_setup_context(&machine_context);
351
tpi_setup_context(&machine_context);
352
machine_printer_setup_context(&machine_context);
291
355
/* C64-specific initialization. */
292
int machine_init(void)
356
int machine_specific_init(void)
294
358
c64_log = log_open("C64");
298
360
if (mem_load() < 0)
303
364
psid_init_driver();
308
368
/* Setup trap handling. */
311
371
/* Initialize serial traps. */
312
if (serial_init(c64_serial_traps, 0xa4) < 0)
372
if (serial_init(c64_serial_traps) < 0)
375
serial_trap_init(0xa4);
376
serial_iec_bus_init();
315
378
/* Initialize drives. */
316
379
file_system_init();
319
381
/* Initialize RS232 handler. */
321
383
c64_rsuser_init();
324
385
/* Initialize print devices. */
327
388
/* Initialize the tape emulation. */
328
tape_init(0xb2, 0x90, 0x93, 0x29f, 0, 0xc1, 0xae, 0x277, 0xc6,
389
tape_init(&tapeinit);
331
391
/* Initialize the datasette emulation. */
332
392
datasette_init();
334
394
/* Fire up the hardware-level drive emulation. */
335
drive_init(C64_PAL_CYCLES_PER_SEC, C64_NTSC_CYCLES_PER_SEC);
337
397
/* Initialize autostart. */
338
autostart_init((CLOCK)(3 * rfsh_per_sec * cycles_per_rfsh),
398
autostart_init((CLOCK)(3 * C64_PAL_RFSH_PER_SEC
399
* C64_PAL_CYCLES_PER_RFSH),
339
400
1, 0xcc, 0xd1, 0xd3, 0xd5);
342
/* Initialize the VIC-II emulation. */
343
if (!vic_ii_init() && !console_mode && !vsid_mode)
403
if (vicii_init(VICII_STANDARD) == NULL && !console_mode && !vsid_mode)
346
vic_ii_enable_extended_keyboard_rows(0);
348
cia1_enable_extended_keyboard_rows(0);
406
cia1_init(machine_context.cia1);
407
cia2_init(machine_context.cia2);
410
tpi_init(machine_context.tpi1);
362
415
/* Initialize the keyboard. */
363
416
if (c64_kbd_init() < 0)
367
423
c64_monitor_init();
369
425
/* Initialize vsync and register our hook function. */
370
426
vsync_init(machine_vsync_hook);
371
vsync_set_machine_parameter(rfsh_per_sec, cycles_per_sec);
427
vsync_set_machine_parameter(machine_timing.rfsh_per_sec,
428
machine_timing.cycles_per_sec);
373
430
/* Initialize sound. Notice that this does not really open the audio
375
sound_init(cycles_per_sec, cycles_per_rfsh);
432
sound_init(machine_timing.cycles_per_sec, machine_timing.cycles_per_rfsh);
377
434
/* Initialize keyboard buffer. */
378
kbd_buf_init(631, 198, 10,
379
(CLOCK)(rfsh_per_sec * cycles_per_rfsh));
435
kbdbuf_init(631, 198, 10, (CLOCK)(machine_timing.rfsh_per_sec
436
* machine_timing.cycles_per_rfsh));
381
438
/* Initialize the C64-specific part of the UI. */
382
439
if (!console_mode) {
528
595
long machine_get_cycles_per_second(void)
530
return cycles_per_sec;
597
return machine_timing.cycles_per_sec;
600
void machine_get_line_cycle(unsigned int *line, unsigned int *cycle)
602
*line = (unsigned int)((maincpu_clk) / machine_timing.cycles_per_line
603
% machine_timing.screen_lines);
605
*cycle = (unsigned int)((maincpu_clk) % machine_timing.cycles_per_line);
533
608
void machine_change_timing(int timeval)
535
maincpu_trigger_reset();
537
610
switch (timeval) {
539
cycles_per_sec = C64_PAL_CYCLES_PER_SEC;
540
cycles_per_rfsh = C64_PAL_CYCLES_PER_RFSH;
541
rfsh_per_sec = C64_PAL_RFSH_PER_SEC;
543
case DRIVE_SYNC_NTSC:
544
cycles_per_sec = C64_NTSC_CYCLES_PER_SEC;
545
cycles_per_rfsh = C64_NTSC_CYCLES_PER_RFSH;
546
rfsh_per_sec = C64_NTSC_RFSH_PER_SEC;
548
case DRIVE_SYNC_NTSCOLD:
549
cycles_per_sec = C64_NTSCOLD_CYCLES_PER_SEC;
550
cycles_per_rfsh = C64_NTSCOLD_CYCLES_PER_RFSH;
551
rfsh_per_sec = C64_NTSCOLD_RFSH_PER_SEC;
611
case MACHINE_SYNC_PAL:
612
machine_timing.cycles_per_sec = C64_PAL_CYCLES_PER_SEC;
613
machine_timing.cycles_per_rfsh = C64_PAL_CYCLES_PER_RFSH;
614
machine_timing.rfsh_per_sec = C64_PAL_RFSH_PER_SEC;
615
machine_timing.cycles_per_line = C64_PAL_CYCLES_PER_LINE;
616
machine_timing.screen_lines = C64_PAL_SCREEN_LINES;
618
case MACHINE_SYNC_NTSC:
619
machine_timing.cycles_per_sec = C64_NTSC_CYCLES_PER_SEC;
620
machine_timing.cycles_per_rfsh = C64_NTSC_CYCLES_PER_RFSH;
621
machine_timing.rfsh_per_sec = C64_NTSC_RFSH_PER_SEC;
622
machine_timing.cycles_per_line = C64_NTSC_CYCLES_PER_LINE;
623
machine_timing.screen_lines = C64_NTSC_SCREEN_LINES;
625
case MACHINE_SYNC_NTSCOLD:
626
machine_timing.cycles_per_sec = C64_NTSCOLD_CYCLES_PER_SEC;
627
machine_timing.cycles_per_rfsh = C64_NTSCOLD_CYCLES_PER_RFSH;
628
machine_timing.rfsh_per_sec = C64_NTSCOLD_RFSH_PER_SEC;
629
machine_timing.cycles_per_line = C64_NTSCOLD_CYCLES_PER_LINE;
630
machine_timing.screen_lines = C64_NTSCOLD_SCREEN_LINES;
554
633
log_error(c64_log, "Unknown machine timing.");
557
vsync_set_machine_parameter(rfsh_per_sec, cycles_per_sec);
558
sound_set_machine_parameter(cycles_per_sec, cycles_per_rfsh);
636
vsync_set_machine_parameter(machine_timing.rfsh_per_sec,
637
machine_timing.cycles_per_sec);
638
sound_set_machine_parameter(machine_timing.cycles_per_sec,
639
machine_timing.cycles_per_rfsh);
640
debug_set_machine_parameter(machine_timing.cycles_per_line,
641
machine_timing.screen_lines);
642
drive_set_machine_parameter(machine_timing.cycles_per_sec);
643
serial_iec_device_set_machine_parameter(machine_timing.cycles_per_sec);
644
sid_set_machine_parameter(machine_timing.cycles_per_sec);
645
clk_guard_set_clk_base(maincpu_clk_guard, machine_timing.cycles_per_rfsh);
647
vicii_change_timing(&machine_timing);
649
machine_trigger_reset(MACHINE_RESET_MODE_HARD);
561
652
/* ------------------------------------------------------------------------- */
566
int machine_class = VICE_MACHINE_C64;
568
int machine_write_snapshot(const char *name, int save_roms, int save_disks)
654
int machine_write_snapshot(const char *name, int save_roms, int save_disks,
572
s = snapshot_create(name, ((BYTE)(SNAP_MAJOR)), ((BYTE)(SNAP_MINOR)),
577
/* Execute drive CPUs to get in sync with the main CPU. */
579
drive0_cpu_execute(clk);
581
drive1_cpu_execute(clk);
583
if (maincpu_snapshot_write_module(s) < 0
584
|| c64_snapshot_write_module(s, save_roms) < 0
585
|| cia1_snapshot_write_module(s) < 0
586
|| cia2_snapshot_write_module(s) < 0
587
|| sid_snapshot_write_module(s) < 0
588
|| drive_snapshot_write_module(s, save_disks, save_roms) < 0
589
|| vic_ii_snapshot_write_module(s) < 0) {
591
util_file_remove(name);
657
return c64_snapshot_write(name, save_roms, save_disks, event_mode);
599
int machine_read_snapshot(const char *name)
660
int machine_read_snapshot(const char *name, int event_mode)
604
s = snapshot_open(name, &major, &minor, machine_name);
608
if (major != SNAP_MAJOR || minor != SNAP_MINOR) {
610
"Snapshot version (%d.%d) not valid: expecting %d.%d.",
611
major, minor, SNAP_MAJOR, SNAP_MINOR);
615
vic_ii_prepare_for_snapshot();
617
if (maincpu_snapshot_read_module(s) < 0
618
|| c64_snapshot_read_module(s) < 0
619
|| cia1_snapshot_read_module(s) < 0
620
|| cia2_snapshot_read_module(s) < 0
621
|| sid_snapshot_read_module(s) < 0
622
|| drive_snapshot_read_module(s) < 0
623
|| vic_ii_snapshot_read_module(s) < 0)
633
maincpu_trigger_reset();
662
return c64_snapshot_read(name, event_mode);
637
665
/* ------------------------------------------------------------------------- */
650
678
psid_set_tune(tune);
653
int machine_screenshot(screenshot_t *screenshot, unsigned int wn)
656
return vic_ii_screenshot(screenshot);
660
int machine_canvas_screenshot(screenshot_t *screenshot,
661
struct video_canvas_s *canvas)
663
if (canvas == vic_ii_get_canvas())
664
return vic_ii_screenshot(screenshot);
668
void machine_video_refresh(void)
670
vic_ii_video_refresh();
681
int machine_screenshot(screenshot_t *screenshot, struct video_canvas_s *canvas)
683
if (canvas != vicii_get_canvas())
686
vicii_screenshot(screenshot);
690
int machine_canvas_async_refresh(struct canvas_refresh_s *refresh,
691
struct video_canvas_s *canvas)
693
if (canvas != vicii_get_canvas())
696
vicii_async_refresh(refresh);
673
700
void machine_update_memory_ptrs(void)
675
vic_ii_update_memory_ptrs_external();
702
vicii_update_memory_ptrs_external();
678
705
int machine_sid2_check_range(unsigned int sid2_adr)