1 /*
2 * cbm5x0.c
3 *
4 * Written by
5 * Andre Fachat <fachat@physik.tu-chemnitz.de>
6 * Andreas Boose <viceteam@t-online.de>
7 * Marco van den Heuvel <blackystardust68@yahoo.com>
8 *
9 * This file is part of VICE, the Versatile Commodore Emulator.
10 * See README for copyright notice.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 * 02111-1307 USA.
26 *
27 */
28
29 #include "vice.h"
30
31 #include <math.h> /* modf */
32 #include <stdio.h>
33
34 #include "alarm.h"
35 #include "attach.h"
36 #include "autostart.h"
37 #include "bbrtc.h"
38 #include "cartio.h"
39 #include "cartridge.h"
40 #include "cbm2-cmdline-options.h"
41 #include "cbm2-resources.h"
42 #include "cbm2-snapshot.h"
43 #include "cbm2.h"
44 #include "cbm2acia.h"
45 #include "cbm2cia.h"
46 #include "cbm2iec.h"
47 #include "cbm2mem.h"
48 #include "cbm2tpi.h"
49 #include "cbm2ui.h"
50 #include "cia.h"
51 #include "clkguard.h"
52 #include "datasette.h"
53 #include "debug.h"
54 #include "debugcart.h"
55 #include "diskimage.h"
56 #include "drive-cmdline-options.h"
57 #include "drive-resources.h"
58 #include "drive-sound.h"
59 #include "drive.h"
60 #include "fliplist.h"
61 #include "fsdevice.h"
62 #include "gfxoutput.h"
63 #include "iecdrive.h"
64 #include "init.h"
65 #include "joyport.h"
66 #include "joystick.h"
67 #include "kbdbuf.h"
68 #include "keyboard.h"
69 #include "log.h"
70 #include "machine-drive.h"
71 #include "machine-printer.h"
72 #include "machine-video.h"
73 #include "machine.h"
74 #include "maincpu.h"
75 #include "mem.h"
76 #include "monitor.h"
77 #include "network.h"
78 #include "paperclip64.h"
79 #include "parallel.h"
80 #include "printer.h"
81 #include "resources.h"
82 #include "rs232drv.h"
83 #include "sampler.h"
84 #include "sampler2bit.h"
85 #include "sampler4bit.h"
86 #include "screenshot.h"
87 #include "serial.h"
88 #include "sid-cmdline-options.h"
89 #include "sid-resources.h"
90 #include "sid.h"
91 #include "snapshot.h"
92 #include "sound.h"
93 #include "tape.h"
94 #include "tapeport.h"
95 #include "tpi.h"
96 #include "traps.h"
97 #include "types.h"
98 #include "vice-event.h"
99 #include "vicii.h"
100 #include "vicii-resources.h"
101 #include "video.h"
102 #include "video-sound.h"
103 #include "vsync.h"
104
105 #ifdef HAVE_MOUSE
106 #include "mouse.h"
107 #endif
108
109
110 /** \brief Delay in seconds before pasting -keybuf argument into the buffer
111 */
112 #define KBDBUF_ALARM_DELAY 8
113
114
115 machine_context_t machine_context;
116
117 const char machine_name[] = "CBM-II";
118 int machine_class = VICE_MACHINE_CBM5x0;
119
120 static void machine_vsync_hook(void);
121
122 #define C500_POWERLINE_CYCLES_PER_IRQ (C500_PAL_CYCLES_PER_RFSH)
123
124 static log_t cbm2_log = LOG_ERR;
125 static machine_timing_t machine_timing;
126
127 /* FIXME: add different keyboard types */
machine_get_keyboard_type(void)128 int machine_get_keyboard_type(void)
129 {
130 #if 0
131 int type;
132 if (resources_get_int("KeyboardType", &type) < 0) {
133 return 0;
134 }
135 return type;
136 #endif
137 return 0;
138 }
139
machine_get_keyboard_type_name(int type)140 char *machine_get_keyboard_type_name(int type)
141 {
142 return NULL; /* return 0 if no different types exist */
143 }
144
145 /* return number of available keyboard types for this machine */
machine_get_num_keyboard_types(void)146 int machine_get_num_keyboard_types(void)
147 {
148 return 1;
149 }
150
machine_get_keyboard_info_list(void)151 kbdtype_info_t *machine_get_keyboard_info_list(void)
152 {
153 return NULL; /* return 0 if no different types exist */
154 }
155
156
157 /* ------------------------------------------------------------------------- */
158
159 static joyport_port_props_t control_port_1 =
160 {
161 "Control port 1",
162 1, /* has a potentiometer connected to this port */
163 0, /* officially has lightpen support on this port,
164 but no lightpen support is in the cbm5x0 code */
165 1 /* port is always active */
166 };
167
168 static joyport_port_props_t control_port_2 =
169 {
170 "Control port 2",
171 1, /* has a potentiometer connected to this port */
172 0, /* has NO lightpen support on this port */
173 1 /* port is always active */
174 };
175
init_joyport_ports(void)176 static int init_joyport_ports(void)
177 {
178 if (joyport_port_register(JOYPORT_1, &control_port_1) < 0) {
179 return -1;
180 }
181 return joyport_port_register(JOYPORT_2, &control_port_2);
182 }
183
184 /* CBM-II-specific resource initialization. This is called before initializing
185 the machine itself with `machine_init()'. */
machine_resources_init(void)186 int machine_resources_init(void)
187 {
188 if (traps_resources_init() < 0) {
189 init_resource_fail("traps");
190 return -1;
191 }
192 if (cbm2_resources_init() < 0) {
193 init_resource_fail("cbm2");
194 return -1;
195 }
196 if (cartio_resources_init() < 0) {
197 init_resource_fail("cartio");
198 return -1;
199 }
200 if (cartridge_resources_init() < 0) {
201 init_resource_fail("cartridge");
202 return -1;
203 }
204 if (vicii_resources_init() < 0) {
205 init_resource_fail("vicii");
206 return -1;
207 }
208 if (sid_resources_init() < 0) {
209 init_resource_fail("sid");
210 return -1;
211 }
212 if (drive_resources_init() < 0) {
213 init_resource_fail("drive");
214 return -1;
215 }
216 /*
217 * This needs to be called before tapeport_resources_init(), otherwise
218 * the tapecart will fail to initialize due to the Datasette resource
219 * appearing after the Tapecart resources
220 */
221 if (datasette_resources_init() < 0) {
222 init_resource_fail("datasette");
223 return -1;
224 }
225 if (tapeport_resources_init() < 0) {
226 init_resource_fail("tapeport");
227 return -1;
228 }
229 if (acia1_resources_init() < 0) {
230 init_resource_fail("acia1");
231 return -1;
232 }
233 if (rs232drv_resources_init() < 0) {
234 init_resource_fail("rs232drv");
235 return -1;
236 }
237 if (printer_resources_init() < 0) {
238 init_resource_fail("printer");
239 return -1;
240 }
241 if (printer_userport_resources_init() < 0) {
242 init_resource_fail("userport printer");
243 return -1;
244 }
245 if (init_joyport_ports() < 0) {
246 init_resource_fail("joyport ports");
247 return -1;
248 }
249 if (joyport_resources_init() < 0) {
250 init_resource_fail("joyport devices");
251 return -1;
252 }
253 if (joyport_sampler2bit_resources_init() < 0) {
254 init_resource_fail("joyport 2bit sampler");
255 return -1;
256 }
257 if (joyport_sampler4bit_resources_init() < 0) {
258 init_resource_fail("joyport 4bit sampler");
259 return -1;
260 }
261 if (joyport_bbrtc_resources_init() < 0) {
262 init_resource_fail("joyport bbrtc");
263 return -1;
264 }
265 if (joyport_paperclip64_resources_init() < 0) {
266 init_resource_fail("joyport paperclip64 dongle");
267 return -1;
268 }
269 if (joystick_resources_init() < 0) {
270 init_resource_fail("joystick");
271 return -1;
272 }
273 if (gfxoutput_resources_init() < 0) {
274 init_resource_fail("gfxoutput");
275 return -1;
276 }
277 if (sampler_resources_init() < 0) {
278 init_resource_fail("samplerdrv");
279 return -1;
280 }
281 if (fliplist_resources_init() < 0) {
282 init_resource_fail("flip list");
283 return -1;
284 }
285 if (file_system_resources_init() < 0) {
286 init_resource_fail("file system");
287 return -1;
288 }
289 /* Initialize file system device-specific resources. */
290 if (fsdevice_resources_init() < 0) {
291 init_resource_fail("file system device");
292 return -1;
293 }
294 if (disk_image_resources_init() < 0) {
295 init_resource_fail("disk image");
296 return -1;
297 }
298 if (event_resources_init() < 0) {
299 init_resource_fail("event");
300 return -1;
301 }
302 if (kbdbuf_resources_init() < 0) {
303 init_resource_fail("Keyboard");
304 return -1;
305 }
306 if (autostart_resources_init() < 0) {
307 init_resource_fail("autostart");
308 return -1;
309 }
310 #ifdef HAVE_NETWORK
311 if (network_resources_init() < 0) {
312 init_resource_fail("network");
313 return -1;
314 }
315 #endif
316 #ifdef DEBUG
317 if (debug_resources_init() < 0) {
318 init_resource_fail("debug");
319 return -1;
320 }
321 #endif
322 #ifdef HAVE_MOUSE
323 if (mouse_resources_init() < 0) {
324 init_resource_fail("mouse");
325 return -1;
326 }
327 /* FIXME: add lightpen support for xcbm5x0 */
328 #if 0
329 if (lightpen_resources_init() < 0) {
330 init_resource_fail("lightpen");
331 return -1;
332 }
333 #endif
334 #endif
335 if (debugcart_resources_init() < 0) {
336 init_resource_fail("debug cart");
337 return -1;
338 }
339 return 0;
340 }
341
machine_resources_shutdown(void)342 void machine_resources_shutdown(void)
343 {
344 cbm2_resources_shutdown();
345 rs232drv_resources_shutdown();
346 printer_resources_shutdown();
347 drive_resources_shutdown();
348 fsdevice_resources_shutdown();
349 disk_image_resources_shutdown();
350 sampler_resources_shutdown();
351 cartio_shutdown();
352 joyport_bbrtc_resources_shutdown();
353 tapeport_resources_shutdown();
354 debugcart_resources_shutdown();
355 cartridge_resources_shutdown();
356 }
357
358 /* CBM-II-specific command-line option initialization. */
machine_cmdline_options_init(void)359 int machine_cmdline_options_init(void)
360 {
361 if (traps_cmdline_options_init() < 0) {
362 init_cmdline_options_fail("traps");
363 return -1;
364 }
365 if (cbm2_cmdline_options_init() < 0) {
366 init_cmdline_options_fail("cbm2");
367 return -1;
368 }
369 if (cartio_cmdline_options_init() < 0) {
370 init_cmdline_options_fail("cartio");
371 return -1;
372 }
373 if (cartridge_cmdline_options_init() < 0) {
374 init_cmdline_options_fail("cartridge");
375 return -1;
376 }
377 if (vicii_cmdline_options_init() < 0) {
378 init_cmdline_options_fail("vicii");
379 return -1;
380 }
381 if (sid_cmdline_options_init(SIDTYPE_SID) < 0) {
382 init_cmdline_options_fail("sid");
383 return -1;
384 }
385 if (drive_cmdline_options_init() < 0) {
386 init_cmdline_options_fail("drive");
387 return -1;
388 }
389 if (tapeport_cmdline_options_init() < 0) {
390 init_cmdline_options_fail("tapeport");
391 return -1;
392 }
393 if (datasette_cmdline_options_init() < 0) {
394 init_cmdline_options_fail("datasette");
395 return -1;
396 }
397 if (acia1_cmdline_options_init() < 0) {
398 init_cmdline_options_fail("acia1");
399 return -1;
400 }
401 if (rs232drv_cmdline_options_init() < 0) {
402 init_cmdline_options_fail("rs232drv");
403 return -1;
404 }
405 if (printer_cmdline_options_init() < 0) {
406 init_cmdline_options_fail("printer");
407 return -1;
408 }
409 if (printer_userport_cmdline_options_init() < 0) {
410 init_cmdline_options_fail("userport printer");
411 return -1;
412 }
413 if (joyport_cmdline_options_init() < 0) {
414 init_cmdline_options_fail("joyport");
415 return -1;
416 }
417 if (joyport_bbrtc_cmdline_options_init() < 0) {
418 init_cmdline_options_fail("bbrtc");
419 return -1;
420 }
421 if (joystick_cmdline_options_init() < 0) {
422 init_cmdline_options_fail("joystick");
423 return -1;
424 }
425 if (gfxoutput_cmdline_options_init() < 0) {
426 init_cmdline_options_fail("gfxoutput");
427 return -1;
428 }
429 if (sampler_cmdline_options_init() < 0) {
430 init_cmdline_options_fail("samplerdrv");
431 return -1;
432 }
433 if (fliplist_cmdline_options_init() < 0) {
434 init_cmdline_options_fail("flip list");
435 return -1;
436 }
437 if (file_system_cmdline_options_init() < 0) {
438 init_cmdline_options_fail("attach");
439 return -1;
440 }
441 if (fsdevice_cmdline_options_init() < 0) {
442 init_cmdline_options_fail("file system");
443 return -1;
444 }
445 if (disk_image_cmdline_options_init() < 0) {
446 init_cmdline_options_fail("disk image");
447 return -1;
448 }
449 if (event_cmdline_options_init() < 0) {
450 init_cmdline_options_fail("event");
451 return -1;
452 }
453 if (kbdbuf_cmdline_options_init() < 0) {
454 init_cmdline_options_fail("keyboard");
455 return -1;
456 }
457 if (autostart_cmdline_options_init() < 0) {
458 init_resource_fail("autostart");
459 return -1;
460 }
461 #ifdef HAVE_NETWORK
462 if (network_cmdline_options_init() < 0) {
463 init_cmdline_options_fail("network");
464 return -1;
465 }
466 #endif
467 #ifdef DEBUG
468 if (debug_cmdline_options_init() < 0) {
469 init_cmdline_options_fail("debug");
470 return -1;
471 }
472 #endif
473 #ifdef HAVE_MOUSE
474 if (mouse_cmdline_options_init() < 0) {
475 init_cmdline_options_fail("mouse");
476 return -1;
477 }
478 #endif
479 if (debugcart_cmdline_options_init() < 0) {
480 init_cmdline_options_fail("debug cart");
481 return -1;
482 }
483 return 0;
484 }
485
486 /* ------------------------------------------------------------------------- */
487 /* provide the 50(?)Hz IRQ signal for the standard IRQ */
488
489 #define SIGNAL_VERT_BLANK_OFF tpicore_set_int(machine_context.tpi1, 0, 1);
490
491 #define SIGNAL_VERT_BLANK_ON tpicore_set_int(machine_context.tpi1, 0, 0);
492
493 /* ------------------------------------------------------------------------- */
494 /* for the C500 there is a powerline IRQ... */
495
496 static alarm_t *c500_powerline_clk_alarm = NULL;
497 static CLOCK c500_powerline_clk = 0;
498
c500_powerline_clk_alarm_handler(CLOCK offset,void * data)499 static void c500_powerline_clk_alarm_handler(CLOCK offset, void *data)
500 {
501 c500_powerline_clk += C500_POWERLINE_CYCLES_PER_IRQ;
502
503 SIGNAL_VERT_BLANK_OFF
504
505 alarm_set(c500_powerline_clk_alarm, c500_powerline_clk);
506
507 SIGNAL_VERT_BLANK_ON
508 }
509
c500_powerline_clk_overflow_callback(CLOCK sub,void * data)510 static void c500_powerline_clk_overflow_callback(CLOCK sub, void *data)
511 {
512 c500_powerline_clk -= sub;
513 }
514
515
516 /*
517 * C500 extra data (state of 50Hz clk)
518 */
519 #define C500DATA_DUMP_VER_MAJOR 0
520 #define C500DATA_DUMP_VER_MINOR 0
521
522 /*
523 * DWORD IRQCLK CPU clock ticks until next 50 Hz IRQ
524 *
525 */
526
527 static const char module_name[] = "C500DATA";
528
cbm2_c500_snapshot_write_module(snapshot_t * p)529 int cbm2_c500_snapshot_write_module(snapshot_t *p)
530 {
531 snapshot_module_t *m;
532
533 m = snapshot_module_create(p, module_name, C500DATA_DUMP_VER_MAJOR,
534 C500DATA_DUMP_VER_MINOR);
535 if (m == NULL) {
536 return -1;
537 }
538
539 SMW_DW(m, c500_powerline_clk - maincpu_clk);
540
541 snapshot_module_close(m);
542
543 return 0;
544 }
545
cbm2_c500_snapshot_read_module(snapshot_t * p)546 int cbm2_c500_snapshot_read_module(snapshot_t *p)
547 {
548 uint8_t vmajor, vminor;
549 snapshot_module_t *m;
550 uint32_t dword;
551
552 m = snapshot_module_open(p, module_name, &vmajor, &vminor);
553 if (m == NULL) {
554 return -1;
555 }
556
557 if (vmajor != C500DATA_DUMP_VER_MAJOR) {
558 snapshot_module_close(m);
559 return -1;
560 }
561
562 SMR_DW(m, &dword);
563 c500_powerline_clk = maincpu_clk + dword;
564 alarm_set(c500_powerline_clk_alarm, c500_powerline_clk);
565
566 snapshot_module_close(m);
567
568 return 0;
569 }
570
571 /* ------------------------------------------------------------------------- */
572
cbm2_monitor_init(void)573 static void cbm2_monitor_init(void)
574 {
575 unsigned int dnr;
576 monitor_cpu_type_t asm6502;
577 monitor_interface_t *drive_interface_init[NUM_DISK_UNITS];
578 monitor_cpu_type_t *asmarray[2];
579
580 asmarray[0] = &asm6502;
581 asmarray[1] = NULL;
582
583 asm6502_init(&asm6502);
584
585 for (dnr = 0; dnr < NUM_DISK_UNITS; dnr++) {
586 drive_interface_init[dnr] = drive_cpu_monitor_interface_get(dnr);
587 }
588
589 /* Initialize the monitor. */
590 monitor_init(maincpu_monitor_interface_get(), drive_interface_init,
591 asmarray);
592 }
593
machine_setup_context(void)594 void machine_setup_context(void)
595 {
596 cia1_setup_context(&machine_context);
597 tpi1_setup_context(&machine_context);
598 tpi2_setup_context(&machine_context);
599 machine_printer_setup_context(&machine_context);
600 }
601
602 /* CBM-II-specific initialization. */
machine_specific_init(void)603 int machine_specific_init(void)
604 {
605 cbm2_log = log_open("CBM2");
606
607 cbm2_init_ok = 1;
608
609 event_init();
610
611 /* Setup trap handling - must be before mem_load() */
612 traps_init();
613
614 if (mem_load() < 0) {
615 return -1;
616 }
617
618 gfxoutput_init();
619
620 #ifdef HAVE_MOUSE
621 /* Initialize mouse support (if present). */
622 mouse_init();
623
624 #if 0
625 /* Initialize lightpen support and register VICII callbacks */
626 lightpen_init();
627 lightpen_register_timing_callback(vicii_lightpen_timing, 0);
628 lightpen_register_trigger_callback(vicii_trigger_light_pen);
629 #endif
630 #endif
631
632 rs232drv_init();
633
634 /* initialize print devices */
635 printer_init();
636
637 /* Pre-init CBM-II-specific parts of the menus before vicii_init()
638 creates a canvas window with a menubar at the top. */
639 if (!console_mode) {
640 cbm5x0ui_init_early();
641 }
642
643 if (vicii_init(VICII_STANDARD) == NULL) {
644 return -1;
645 }
646 /*
647 c500_set_phi1_bank(15);
648 c500_set_phi2_bank(15);
649 */
650
651 c500_powerline_clk_alarm = alarm_new(maincpu_alarm_context,
652 "C500PowerlineClk",
653 c500_powerline_clk_alarm_handler,
654 NULL);
655 clk_guard_add_callback(maincpu_clk_guard,
656 c500_powerline_clk_overflow_callback, NULL);
657 machine_timing.cycles_per_sec = C500_PAL_CYCLES_PER_SEC;
658 machine_timing.rfsh_per_sec = C500_PAL_RFSH_PER_SEC;
659 machine_timing.cycles_per_rfsh = C500_PAL_CYCLES_PER_RFSH;
660
661 cia1_init(machine_context.cia1);
662 acia1_init();
663 tpi1_init(machine_context.tpi1);
664 tpi2_init(machine_context.tpi2);
665
666 /* Initialize the datasette emulation. */
667 datasette_init();
668
669 /* Fire up the hardware-level 1541 emulation. */
670 drive_init();
671
672 disk_image_init();
673
674 cbm2_monitor_init();
675
676 /* Initialize vsync and register our hook function. */
677 vsync_init(machine_vsync_hook);
678 vsync_set_machine_parameter(machine_timing.rfsh_per_sec,
679 machine_timing.cycles_per_sec);
680
681 /* Initialize native sound chip */
682 sid_sound_chip_init();
683
684 drive_sound_init();
685 video_sound_init();
686
687 /* Initialize sound. Notice that this does not really open the audio
688 device yet. */
689 sound_init((unsigned int)machine_timing.cycles_per_sec,
690 (unsigned int)machine_timing.cycles_per_rfsh);
691
692 /* Initialize the CBM-II-specific part of the UI. */
693 if (!console_mode) {
694 cbm5x0ui_init();
695 }
696
697 if (!video_disabled_mode) {
698 joystick_init();
699 }
700
701 cbm2iec_init();
702
703 machine_drive_stub();
704
705 /* Initialize the CBM5x0-specific I/O */
706 cbm5x0io_init();
707
708 return 0;
709 }
710
711 /* CBM-II-specific initialization. */
machine_specific_reset(void)712 void machine_specific_reset(void)
713 {
714 int delay; /* delay in seconds for the kbduf_init() call */
715
716 ciacore_reset(machine_context.cia1);
717 tpicore_reset(machine_context.tpi1);
718 tpicore_reset(machine_context.tpi2);
719 acia1_reset();
720
721 sid_reset();
722
723 c500_powerline_clk = maincpu_clk + C500_POWERLINE_CYCLES_PER_IRQ;
724 alarm_set(c500_powerline_clk_alarm, c500_powerline_clk);
725 vicii_reset();
726
727 printer_reset();
728
729 rs232drv_reset();
730
731 drive_reset();
732 datasette_reset();
733
734 mem_reset();
735
736 /* Initialize keyboard buffer.
737 This appears to work but doesn't account for banking
738 */
739 switch (ramsize) {
740 case 64:
741 delay = 8;
742 break;
743 case 128:
744 delay = 12;
745 break;
746 case 256:
747 delay = 20;
748 break;
749 case 512:
750 delay = 31;
751 break;
752 case 1024:
753 delay = 58;
754 break;
755 default:
756 /* invalid ramsize */
757 delay = 1;
758 break;
759 }
760 kbdbuf_init(0x03ab, 0x00d1, 10,
761 (CLOCK)(machine_timing.rfsh_per_sec *
762 machine_timing.cycles_per_rfsh * delay));
763
764
765 sampler_reset();
766 }
767
machine_specific_powerup(void)768 void machine_specific_powerup(void)
769 {
770 }
771
machine_specific_shutdown(void)772 void machine_specific_shutdown(void)
773 {
774 /* and the tape */
775 tape_image_detach_internal(1);
776
777 ciacore_shutdown(machine_context.cia1);
778 tpicore_shutdown(machine_context.tpi1);
779 tpicore_shutdown(machine_context.tpi2);
780
781 #ifdef HAVE_MOUSE
782 mouse_shutdown();
783 #endif
784
785 /* close the video chip(s) */
786 vicii_shutdown();
787
788 if (!console_mode) {
789 cbm5x0ui_shutdown();
790 }
791 }
792
machine_handle_pending_alarms(int num_write_cycles)793 void machine_handle_pending_alarms(int num_write_cycles)
794 {
795 }
796
797 /* ------------------------------------------------------------------------- */
798
799 /* This hook is called at the end of every frame. */
machine_vsync_hook(void)800 static void machine_vsync_hook(void)
801 {
802 CLOCK sub;
803
804 drive_vsync_hook();
805
806 autostart_advance();
807
808 screenshot_record();
809
810 sub = clk_guard_prevent_overflow(maincpu_clk_guard);
811
812 /* The drive has to deal both with our overflowing and its own one, so
813 it is called even when there is no overflowing in the main CPU. */
814 drive_cpu_prevent_clk_overflow_all(sub);
815 }
816
817 /* Dummy - no restore key. */
machine_set_restore_key(int v)818 void machine_set_restore_key(int v)
819 {
820 }
821
machine_has_restore_key(void)822 int machine_has_restore_key(void)
823 {
824 return 0;
825 }
826
827 /* ------------------------------------------------------------------------- */
828
machine_get_cycles_per_second(void)829 long machine_get_cycles_per_second(void)
830 {
831 return machine_timing.cycles_per_sec;
832 }
833
machine_get_cycles_per_frame(void)834 long machine_get_cycles_per_frame(void)
835 {
836 return machine_timing.cycles_per_rfsh;
837 }
838
machine_get_line_cycle(unsigned int * line,unsigned int * cycle,int * half_cycle)839 void machine_get_line_cycle(unsigned int *line, unsigned int *cycle, int *half_cycle)
840 {
841 *line = (unsigned int)((maincpu_clk) / machine_timing.cycles_per_line
842 % machine_timing.screen_lines);
843
844 *cycle = (unsigned int)((maincpu_clk) % machine_timing.cycles_per_line);
845
846 *half_cycle = (int)-1;
847 }
848
machine_change_timing(int timeval,int border_mode)849 void machine_change_timing(int timeval, int border_mode)
850 {
851 /* log_message(LOG_DEFAULT, "machine_change_timing_c500 %d", timeval); */
852
853 switch (timeval) {
854 case MACHINE_SYNC_PAL:
855 machine_timing.cycles_per_sec = C500_PAL_CYCLES_PER_SEC;
856 machine_timing.cycles_per_rfsh = C500_PAL_CYCLES_PER_RFSH;
857 machine_timing.rfsh_per_sec = C500_PAL_RFSH_PER_SEC;
858 machine_timing.cycles_per_line = C500_PAL_CYCLES_PER_LINE;
859 machine_timing.screen_lines = C500_PAL_SCREEN_LINES;
860 machine_timing.power_freq = 50;
861 break;
862 case MACHINE_SYNC_NTSC:
863 machine_timing.cycles_per_sec = C500_NTSC_CYCLES_PER_SEC;
864 machine_timing.cycles_per_rfsh = C500_NTSC_CYCLES_PER_RFSH;
865 machine_timing.rfsh_per_sec = C500_NTSC_RFSH_PER_SEC;
866 machine_timing.cycles_per_line = C500_NTSC_CYCLES_PER_LINE;
867 machine_timing.screen_lines = C500_NTSC_SCREEN_LINES;
868 machine_timing.power_freq = 60;
869 break;
870 default:
871 log_error(LOG_DEFAULT, "Unknown machine timing.");
872 }
873
874 debug_set_machine_parameter(machine_timing.cycles_per_line,
875 machine_timing.screen_lines);
876 drive_set_machine_parameter(machine_timing.cycles_per_sec);
877 #ifdef HAVE_MOUSE
878 neos_mouse_set_machine_parameter(machine_timing.cycles_per_sec);
879 #endif
880 clk_guard_set_clk_base(maincpu_clk_guard,
881 (CLOCK)machine_timing.cycles_per_rfsh);
882
883 vicii_change_timing(&machine_timing, border_mode);
884 cia1_set_timing(machine_context.cia1,
885 (int)machine_timing.cycles_per_sec,
886 machine_timing.power_freq);
887 }
888
889 /* Set the screen refresh rate, as this is variable in the CRTC */
machine_set_cycles_per_frame(long cpf)890 void machine_set_cycles_per_frame(long cpf)
891 {
892 double i, f;
893
894 machine_timing.cycles_per_rfsh = cpf;
895 machine_timing.rfsh_per_sec = ((double)machine_timing.cycles_per_sec)
896 / ((double)cpf);
897
898 f = modf(machine_timing.rfsh_per_sec, &i) * 1000;
899 log_message(cbm2_log, "cycles per frame set to %ld, refresh to %d.%03dHz",
900 cpf, (int)i, (int)f);
901
902 vsync_set_machine_parameter(machine_timing.rfsh_per_sec,
903 machine_timing.cycles_per_sec);
904 }
905
906 /* ------------------------------------------------------------------------- */
907
machine_write_snapshot(const char * name,int save_roms,int save_disks,int event_mode)908 int machine_write_snapshot(const char *name, int save_roms, int save_disks,
909 int event_mode)
910 {
911 int err = cbm2_snapshot_write(name, save_roms, save_disks, event_mode);
912 if ((err < 0) && (snapshot_get_error() == SNAPSHOT_NO_ERROR)) {
913 snapshot_set_error(SNAPSHOT_CANNOT_WRITE_SNAPSHOT);
914 }
915 return err;
916 }
917
machine_read_snapshot(const char * name,int event_mode)918 int machine_read_snapshot(const char *name, int event_mode)
919 {
920 int err = cbm2_snapshot_read(name, event_mode);
921 if ((err < 0) && (snapshot_get_error() == SNAPSHOT_NO_ERROR)) {
922 snapshot_set_error(SNAPSHOT_CANNOT_READ_SNAPSHOT);
923 }
924 return err;
925 }
926
927 /* ------------------------------------------------------------------------- */
928
machine_autodetect_psid(const char * name)929 int machine_autodetect_psid(const char *name)
930 {
931 return -1;
932 }
933
machine_screenshot(screenshot_t * screenshot,struct video_canvas_s * canvas)934 int machine_screenshot(screenshot_t *screenshot, struct video_canvas_s *canvas)
935 {
936 if (canvas == vicii_get_canvas()) {
937 vicii_screenshot(screenshot);
938 return 0;
939 }
940 return -1;
941 }
942
machine_canvas_async_refresh(struct canvas_refresh_s * refresh,struct video_canvas_s * canvas)943 int machine_canvas_async_refresh(struct canvas_refresh_s *refresh,
944 struct video_canvas_s *canvas)
945 {
946 if (canvas == vicii_get_canvas()) {
947 vicii_async_refresh(refresh);
948 return 0;
949 }
950 return -1;
951 }
952
953 /*-----------------------------------------------------------------------*/
954
machine_diskcontents_bus_read(unsigned int unit)955 struct image_contents_s *machine_diskcontents_bus_read(unsigned int unit)
956 {
957 return NULL;
958 }
959
machine_tape_type_default(void)960 uint8_t machine_tape_type_default(void)
961 {
962 return TAPE_CAS_TYPE_BAS;
963 }
964
machine_tape_behaviour(void)965 uint8_t machine_tape_behaviour(void)
966 {
967 return TAPE_BEHAVIOUR_NORMAL;
968 }
969
machine_addr_in_ram(unsigned int addr)970 int machine_addr_in_ram(unsigned int addr)
971 {
972 /* FIXME: handle the banking */
973 return (addr < 0xe000 && !(addr >= 0x8000 && addr < 0xc000)) ? 1 : 0;
974 }
975
machine_get_name(void)976 const char *machine_get_name(void)
977 {
978 return "CBM-II-5x0";
979 }
980