1 /*
2 * cbm2.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 "cbm2model.h"
48 #include "cbm2mem.h"
49 #include "cbm2tpi.h"
50 #include "cbm2ui.h"
51 #include "cia.h"
52 #include "clkguard.h"
53 #include "crtc.h"
54 #include "datasette.h"
55 #include "datasette-sound.h"
56 #include "debug.h"
57 #include "debugcart.h"
58 #include "diskimage.h"
59 #include "drive-cmdline-options.h"
60 #include "drive-resources.h"
61 #include "drive-sound.h"
62 #include "drive.h"
63 #include "fliplist.h"
64 #include "fsdevice.h"
65 #include "gfxoutput.h"
66 #include "iecdrive.h"
67 #include "init.h"
68 #include "joyport.h"
69 #include "joystick.h"
70 #include "kbdbuf.h"
71 #include "keyboard.h"
72 #include "log.h"
73 #include "machine-drive.h"
74 #include "machine-printer.h"
75 #include "machine-video.h"
76 #include "machine.h"
77 #include "maincpu.h"
78 #include "mem.h"
79 #include "monitor.h"
80 #include "network.h"
81 #include "paperclip64.h"
82 #include "parallel.h"
83 #include "printer.h"
84 #include "resources.h"
85 #include "rs232drv.h"
86 #include "sampler.h"
87 #include "sampler2bit.h"
88 #include "sampler4bit.h"
89 #include "screenshot.h"
90 #include "serial.h"
91 #include "sid-cmdline-options.h"
92 #include "sid-resources.h"
93 #include "sid.h"
94 #include "snapshot.h"
95 #include "sound.h"
96 #include "tape.h"
97 #include "tapeport.h"
98 #include "tpi.h"
99 #include "traps.h"
100 #include "types.h"
101 #include "userport.h"
102 #include "userport_4bit_sampler.h"
103 #include "userport_8bss.h"
104 #include "userport_dac.h"
105 #include "userport_digimax.h"
106 #include "userport_joystick.h"
107 #include "userport_rtc_58321a.h"
108 #include "userport_rtc_ds1307.h"
109 #include "vice-event.h"
110 #include "video.h"
111 #include "video-sound.h"
112 #include "vsync.h"
113
114 #ifdef HAVE_MOUSE
115 #include "mouse.h"
116 #endif
117
118 /** \brief Delay in seconds before pasting -keybuf argument into the buffer
119 */
120 #define KBDBUF_ALARM_DELAY 5
121
122
123 machine_context_t machine_context;
124
125 const char machine_name[] = "CBM-II";
126 int machine_class = VICE_MACHINE_CBM6x0;
127
128 static void machine_vsync_hook(void);
129
130 /*
131 static long cbm2_cycles_per_sec = C610_PAL_CYCLES_PER_SEC;
132 static double cbm2_rfsh_per_sec = C610_PAL_RFSH_PER_SEC;
133 static long cbm2_cycles_per_rfsh = C610_PAL_CYCLES_PER_RFSH;
134 */
135
136 static log_t cbm2_log = LOG_ERR;
137 static machine_timing_t machine_timing;
138
139 /* FIXME: add different keyboard types */
machine_get_keyboard_type(void)140 int machine_get_keyboard_type(void)
141 {
142 #if 0
143 int type;
144 if (resources_get_int("KeyboardType", &type) < 0) {
145 return 0;
146 }
147 return type;
148 #endif
149 return 0;
150 }
151
machine_get_keyboard_type_name(int type)152 char *machine_get_keyboard_type_name(int type)
153 {
154 return NULL; /* return 0 if no different types exist */
155 }
156
157 /* return number of available keyboard types for this machine */
machine_get_num_keyboard_types(void)158 int machine_get_num_keyboard_types(void)
159 {
160 return 1;
161 }
162
machine_get_keyboard_info_list(void)163 kbdtype_info_t *machine_get_keyboard_info_list(void)
164 {
165 return NULL; /* return 0 if no different types exist */
166 }
167
168
169 /* ------------------------------------------------------------------------- */
170
171 static joyport_port_props_t userport_joy_control_port_1 =
172 {
173 "Userport joystick adapter port 1",
174 0, /* has NO potentiometer connected to this port */
175 0, /* has NO lightpen support on this port */
176 0 /* port can be switched on/off */
177 };
178
179 static joyport_port_props_t userport_joy_control_port_2 =
180 {
181 "Userport joystick adapter port 2",
182 0, /* has NO potentiometer connected to this port */
183 0, /* has NO lightpen support on this port */
184 0 /* port can be switched on/off */
185 };
186
init_joyport_ports(void)187 static int init_joyport_ports(void)
188 {
189 if (joyport_port_register(JOYPORT_3, &userport_joy_control_port_1) < 0) {
190 return -1;
191 }
192 return joyport_port_register(JOYPORT_4, &userport_joy_control_port_2);
193 }
194
195 /* CBM-II-specific resource initialization. This is called before initializing
196 the machine itself with `machine_init()'. */
machine_resources_init(void)197 int machine_resources_init(void)
198 {
199 if (traps_resources_init() < 0) {
200 init_resource_fail("traps");
201 return -1;
202 }
203 if (cbm2_resources_init() < 0) {
204 init_resource_fail("cbm2");
205 return -1;
206 }
207 if (cartio_resources_init() < 0) {
208 init_resource_fail("cartio");
209 return -1;
210 }
211 if (cartridge_resources_init() < 0) {
212 init_resource_fail("cartridge");
213 return -1;
214 }
215 if (crtc_resources_init() < 0) {
216 init_resource_fail("crtc");
217 return -1;
218 }
219 if (sid_resources_init() < 0) {
220 init_resource_fail("sid");
221 return -1;
222 }
223 if (drive_resources_init() < 0) {
224 init_resource_fail("drive");
225 return -1;
226 }
227 /*
228 * This needs to be called before tapeport_resources_init(), otherwise
229 * the tapecart will fail to initialize due to the Datasette resource
230 * appearing after the Tapecart resources
231 */
232 if (datasette_resources_init() < 0) {
233 init_resource_fail("datasette");
234 return -1;
235 }
236 if (tapeport_resources_init() < 0) {
237 init_resource_fail("tapeport");
238 return -1;
239 }
240 if (acia1_resources_init() < 0) {
241 init_resource_fail("acia1");
242 return -1;
243 }
244 if (rs232drv_resources_init() < 0) {
245 init_resource_fail("rs232drv");
246 return -1;
247 }
248 if (printer_resources_init() < 0) {
249 init_resource_fail("printer");
250 return -1;
251 }
252 if (printer_userport_resources_init() < 0) {
253 init_resource_fail("userport printer");
254 return -1;
255 }
256 if (init_joyport_ports() < 0) {
257 init_resource_fail("joyport ports");
258 return -1;
259 }
260 if (joyport_resources_init() < 0) {
261 init_resource_fail("joyport devices");
262 return -1;
263 }
264 if (joyport_sampler2bit_resources_init() < 0) {
265 init_resource_fail("joyport 2bit sampler");
266 return -1;
267 }
268 if (joyport_sampler4bit_resources_init() < 0) {
269 init_resource_fail("joyport 4bit sampler");
270 return -1;
271 }
272 if (joyport_bbrtc_resources_init() < 0) {
273 init_resource_fail("joyport bbrtc");
274 return -1;
275 }
276 if (joyport_paperclip64_resources_init() < 0) {
277 init_resource_fail("joyport paperclip64 dongle");
278 return -1;
279 }
280 if (joystick_resources_init() < 0) {
281 init_resource_fail("joystick");
282 return -1;
283 }
284 if (sampler_resources_init() < 0) {
285 init_resource_fail("samplerdrv");
286 return -1;
287 }
288 if (userport_resources_init() < 0) {
289 init_resource_fail("userport devices");
290 return -1;
291 }
292 if (gfxoutput_resources_init() < 0) {
293 init_resource_fail("gfxoutput");
294 return -1;
295 }
296 if (fliplist_resources_init() < 0) {
297 init_resource_fail("flip list");
298 return -1;
299 }
300 if (file_system_resources_init() < 0) {
301 init_resource_fail("file system");
302 return -1;
303 }
304 /* Initialize file system device-specific resources. */
305 if (fsdevice_resources_init() < 0) {
306 init_resource_fail("file system device");
307 return -1;
308 }
309 if (disk_image_resources_init() < 0) {
310 init_resource_fail("disk image");
311 return -1;
312 }
313 if (event_resources_init() < 0) {
314 init_resource_fail("event");
315 return -1;
316 }
317 if (kbdbuf_resources_init() < 0) {
318 init_resource_fail("Keyboard");
319 return -1;
320 }
321 if (autostart_resources_init() < 0) {
322 init_resource_fail("autostart");
323 return -1;
324 }
325 #ifdef HAVE_NETWORK
326 if (network_resources_init() < 0) {
327 init_resource_fail("network");
328 return -1;
329 }
330 #endif
331 #ifdef DEBUG
332 if (debug_resources_init() < 0) {
333 init_resource_fail("debug");
334 return -1;
335 }
336 #endif
337 #ifdef HAVE_MOUSE
338 if (mouse_resources_init() < 0) {
339 init_resource_fail("mouse");
340 return -1;
341 }
342 #endif
343 if (userport_joystick_resources_init() < 0) {
344 init_resource_fail("userport joystick");
345 return -1;
346 }
347 if (userport_dac_resources_init() < 0) {
348 init_resource_fail("userport dac");
349 return -1;
350 }
351 if (userport_digimax_resources_init() < 0) {
352 init_resource_fail("userport digimax");
353 return -1;
354 }
355 if (userport_rtc_58321a_resources_init() < 0) {
356 init_resource_fail("userport rtc (58321a)");
357 return -1;
358 }
359 if (userport_rtc_ds1307_resources_init() < 0) {
360 init_resource_fail("userport rtc (ds1307)");
361 return -1;
362 }
363 if (userport_4bit_sampler_resources_init() < 0) {
364 init_resource_fail("userport 4bit sampler");
365 return -1;
366 }
367 if (userport_8bss_resources_init() < 0) {
368 init_resource_fail("userport 8bit stereo sampler");
369 return -1;
370 }
371 if (debugcart_resources_init() < 0) {
372 init_resource_fail("debug cart");
373 return -1;
374 }
375 return 0;
376 }
377
machine_resources_shutdown(void)378 void machine_resources_shutdown(void)
379 {
380 serial_shutdown();
381 cbm2_resources_shutdown();
382 rs232drv_resources_shutdown();
383 printer_resources_shutdown();
384 drive_resources_shutdown();
385 fsdevice_resources_shutdown();
386 disk_image_resources_shutdown();
387 sampler_resources_shutdown();
388 cartio_shutdown();
389 userport_rtc_58321a_resources_shutdown();
390 userport_rtc_ds1307_resources_shutdown();
391 userport_resources_shutdown();
392 joyport_bbrtc_resources_shutdown();
393 tapeport_resources_shutdown();
394 debugcart_resources_shutdown();
395 cartridge_resources_shutdown();
396 }
397
398 /* CBM-II-specific command-line option initialization. */
machine_cmdline_options_init(void)399 int machine_cmdline_options_init(void)
400 {
401 if (traps_cmdline_options_init() < 0) {
402 init_cmdline_options_fail("traps");
403 return -1;
404 }
405 if (cbm2_cmdline_options_init() < 0) {
406 init_cmdline_options_fail("cbm2");
407 return -1;
408 }
409 if (cartio_cmdline_options_init() < 0) {
410 init_cmdline_options_fail("cartio");
411 return -1;
412 }
413 if (cartridge_cmdline_options_init() < 0) {
414 init_cmdline_options_fail("cartridge");
415 return -1;
416 }
417 if (crtc_cmdline_options_init() < 0) {
418 init_cmdline_options_fail("crtc");
419 return -1;
420 }
421 if (sid_cmdline_options_init(SIDTYPE_SID) < 0) {
422 init_cmdline_options_fail("sid");
423 return -1;
424 }
425 if (drive_cmdline_options_init() < 0) {
426 init_cmdline_options_fail("drive");
427 return -1;
428 }
429 if (tapeport_cmdline_options_init() < 0) {
430 init_cmdline_options_fail("tapeport");
431 return -1;
432 }
433 if (datasette_cmdline_options_init() < 0) {
434 init_cmdline_options_fail("datasette");
435 return -1;
436 }
437 if (acia1_cmdline_options_init() < 0) {
438 init_cmdline_options_fail("acia1");
439 return -1;
440 }
441 if (rs232drv_cmdline_options_init() < 0) {
442 init_cmdline_options_fail("rs232drv");
443 return -1;
444 }
445 if (printer_cmdline_options_init() < 0) {
446 init_cmdline_options_fail("printer");
447 return -1;
448 }
449 if (printer_userport_cmdline_options_init() < 0) {
450 init_cmdline_options_fail("userport printer");
451 return -1;
452 }
453 if (joyport_cmdline_options_init() < 0) {
454 init_cmdline_options_fail("joyport");
455 return -1;
456 }
457 if (joyport_bbrtc_cmdline_options_init() < 0) {
458 init_cmdline_options_fail("bbrtc");
459 return -1;
460 }
461 if (joystick_cmdline_options_init() < 0) {
462 init_cmdline_options_fail("joystick");
463 return -1;
464 }
465 if (userport_cmdline_options_init() < 0) {
466 init_cmdline_options_fail("userport");
467 return -1;
468 }
469 if (gfxoutput_cmdline_options_init() < 0) {
470 init_cmdline_options_fail("gfxoutput");
471 return -1;
472 }
473 if (sampler_cmdline_options_init() < 0) {
474 init_cmdline_options_fail("samplerdrv");
475 return -1;
476 }
477 if (fliplist_cmdline_options_init() < 0) {
478 init_cmdline_options_fail("flip list");
479 return -1;
480 }
481 if (file_system_cmdline_options_init() < 0) {
482 init_cmdline_options_fail("attach");
483 return -1;
484 }
485 if (fsdevice_cmdline_options_init() < 0) {
486 init_cmdline_options_fail("file system");
487 return -1;
488 }
489 if (disk_image_cmdline_options_init() < 0) {
490 init_cmdline_options_fail("disk image");
491 return -1;
492 }
493 if (event_cmdline_options_init() < 0) {
494 init_cmdline_options_fail("event");
495 return -1;
496 }
497 if (kbdbuf_cmdline_options_init() < 0) {
498 init_cmdline_options_fail("keyboard");
499 return -1;
500 }
501 if (autostart_cmdline_options_init() < 0) {
502 init_cmdline_options_fail("autostart");
503 return -1;
504 }
505 #ifdef HAVE_NETWORK
506 if (network_cmdline_options_init() < 0) {
507 init_cmdline_options_fail("network");
508 return -1;
509 }
510 #endif
511 #ifdef DEBUG
512 if (debug_cmdline_options_init() < 0) {
513 init_cmdline_options_fail("debug");
514 return -1;
515 }
516 #endif
517 #ifdef HAVE_MOUSE
518 if (mouse_cmdline_options_init() < 0) {
519 init_cmdline_options_fail("mouse");
520 return -1;
521 }
522 #endif
523 if (userport_joystick_cmdline_options_init() < 0) {
524 init_cmdline_options_fail("userport joystick");
525 return -1;
526 }
527 if (userport_dac_cmdline_options_init() < 0) {
528 init_cmdline_options_fail("userport dac");
529 return -1;
530 }
531 if (userport_digimax_cmdline_options_init() < 0) {
532 init_cmdline_options_fail("userport digimax");
533 return -1;
534 }
535 if (userport_rtc_58321a_cmdline_options_init() < 0) {
536 init_cmdline_options_fail("userport rtc (58321a)");
537 return -1;
538 }
539 if (userport_rtc_ds1307_cmdline_options_init() < 0) {
540 init_cmdline_options_fail("userport rtc (ds1307)");
541 return -1;
542 }
543 if (userport_4bit_sampler_cmdline_options_init() < 0) {
544 init_cmdline_options_fail("userport 4bit sampler");
545 return -1;
546 }
547 if (userport_8bss_cmdline_options_init() < 0) {
548 init_cmdline_options_fail("userport 8bit stereo sampler");
549 return -1;
550 }
551 if (debugcart_cmdline_options_init() < 0) {
552 init_cmdline_options_fail("debug cart");
553 return -1;
554 }
555 return 0;
556 }
557
558 /* ------------------------------------------------------------------------- */
559 /* provide the 50(?)Hz IRQ signal for the standard IRQ */
560
561 #define SIGNAL_VERT_BLANK_OFF tpicore_set_int(machine_context.tpi1, 0, 1);
562
563 #define SIGNAL_VERT_BLANK_ON tpicore_set_int(machine_context.tpi1, 0, 0);
564
565 /* ------------------------------------------------------------------------- */
566 /* ... while the other CBM-II use the CRTC retrace signal. */
567
cbm2_crtc_signal(unsigned int signal)568 static void cbm2_crtc_signal(unsigned int signal)
569 {
570 if (signal) {
571 SIGNAL_VERT_BLANK_ON
572 } else {
573 SIGNAL_VERT_BLANK_OFF
574 }
575 }
576
577 /* ------------------------------------------------------------------------- */
578
cbm2_monitor_init(void)579 static void cbm2_monitor_init(void)
580 {
581 unsigned int dnr;
582 monitor_cpu_type_t asm6502;
583 monitor_interface_t *drive_interface_init[NUM_DISK_UNITS];
584 monitor_cpu_type_t *asmarray[2];
585
586 asmarray[0] = &asm6502;
587 asmarray[1] = NULL;
588
589 asm6502_init(&asm6502);
590
591 for (dnr = 0; dnr < NUM_DISK_UNITS; dnr++) {
592 drive_interface_init[dnr] = drive_cpu_monitor_interface_get(dnr);
593 }
594
595 /* Initialize the monitor. */
596 monitor_init(maincpu_monitor_interface_get(), drive_interface_init,
597 asmarray);
598 }
599
machine_setup_context(void)600 void machine_setup_context(void)
601 {
602 cia1_setup_context(&machine_context);
603 tpi1_setup_context(&machine_context);
604 tpi2_setup_context(&machine_context);
605 machine_printer_setup_context(&machine_context);
606 }
607
608 /* CBM-II-specific initialization. */
machine_specific_init(void)609 int machine_specific_init(void)
610 {
611 cbm2_log = log_open("CBM2");
612
613 cbm2_init_ok = 1;
614
615 event_init();
616
617 /* Setup trap handling - must be before mem_load() */
618 traps_init();
619
620 if (mem_load() < 0) {
621 return -1;
622 }
623
624 gfxoutput_init();
625
626 rs232drv_init();
627
628 /* initialize print devices */
629 printer_init();
630
631 /* Pre-init CBM-II-specific parts of the menus before crtc_init()
632 creates a canvas window with a menubar at the top. */
633 if (!console_mode) {
634 cbm2ui_init_early();
635 }
636
637 if (crtc_init() == NULL) {
638 return -1;
639 }
640 crtc_set_retrace_callback(cbm2_crtc_signal);
641 crtc_set_retrace_type(0);
642 crtc_set_hw_options(1, 0x7ff, 0x1000, 512, -0x2000);
643
644 cia1_init(machine_context.cia1);
645 acia1_init();
646 tpi1_init(machine_context.tpi1);
647 tpi2_init(machine_context.tpi2);
648
649 /* Initialize the datasette emulation. */
650 datasette_init();
651
652 /* Fire up the hardware-level 1541 emulation. */
653 drive_init();
654
655 disk_image_init();
656
657 cbm2_monitor_init();
658
659 /* Initialize vsync and register our hook function. */
660 vsync_init(machine_vsync_hook);
661 vsync_set_machine_parameter(machine_timing.rfsh_per_sec,
662 machine_timing.cycles_per_sec);
663
664 /* Initialize native sound chip */
665 sid_sound_chip_init();
666
667 /* Initialize userport based sound chips */
668 userport_dac_sound_chip_init();
669 userport_digimax_sound_chip_init();
670
671 drive_sound_init();
672 datasette_sound_init();
673 video_sound_init();
674
675 /* Initialize sound. Notice that this does not really open the audio
676 device yet. */
677 sound_init((unsigned int)machine_timing.cycles_per_sec,
678 (unsigned int)machine_timing.cycles_per_rfsh);
679
680 /* Initialize the CBM-II-specific part of the UI. */
681 if (!console_mode) {
682 cbm2ui_init();
683 }
684
685 if (!video_disabled_mode) {
686 joystick_init();
687 }
688
689 cbm2iec_init();
690
691 #ifdef HAVE_MOUSE
692 /* Initialize mouse support (if present). */
693 mouse_init();
694 #endif
695
696 machine_drive_stub();
697
698 /* Initialize the CBM2-specific I/O */
699 cbm2io_init();
700
701 return 0;
702 }
703
704 /* CBM-II-specific initialization. */
machine_specific_reset(void)705 void machine_specific_reset(void)
706 {
707 int delay = KBDBUF_ALARM_DELAY;
708 int model = cbm2model_get();
709
710 ciacore_reset(machine_context.cia1);
711 tpicore_reset(machine_context.tpi1);
712 tpicore_reset(machine_context.tpi2);
713 acia1_reset();
714
715 sid_reset();
716
717 crtc_reset();
718
719 printer_reset();
720
721 rs232drv_reset();
722
723 drive_reset();
724 datasette_reset();
725
726 mem_reset();
727
728 /* delays figured out by running each model */
729 /* printf("cbm2model: %d\n", model); */
730 switch (model) {
731 /* Most likely unneeded, since cbm5x0 should handle these. But should
732 * someone be clever enough to turn the #define's in cmb2model.h into
733 * an enum, a compiler could catch missing cases.
734 */
735 case CBM2MODEL_510_PAL: /* fallthrough */
736 case CBM2MODEL_510_NTSC:
737 delay = 7; /* only valid for the default 64KB RAM */
738 break;
739
740 /* 610: default RAM: 128KB */
741 case CBM2MODEL_610_PAL: /* fallthrough */
742 case CBM2MODEL_610_NTSC:
743 delay = 4;
744 break;
745
746 /* 620: default RAM: 256KB */
747 case CBM2MODEL_620_PAL: /* fallthrough */
748 case CBM2MODEL_620_NTSC:
749 delay = 8;
750 break;
751
752 case CBM2MODEL_620PLUS_PAL: /* fallthrough */
753 case CBM2MODEL_620PLUS_NTSC:
754 delay = 25;
755 break;
756 case CBM2MODEL_710_NTSC:
757 delay = 4;
758 break;
759 case CBM2MODEL_720_NTSC:
760 delay = 25;
761 break;
762 case CBM2MODEL_720PLUS_NTSC:
763 delay = 25;
764 break;
765
766 /* When the RAM set via -ramsize doesn't match the RAM size for the
767 * selected model in the table in cbm2model.h, the model is set
768 * to CBM2MODEL_UNKNOWN (99) */
769 default:
770 switch (ramsize) {
771 case 128:
772 delay = 4;
773 break;
774 case 256:
775 delay = 8;
776 break;
777 case 512:
778 delay = 13;
779 break;
780 case 1024:
781 delay = 30;
782 break;
783 default:
784 delay = 30; /* shouldn't get here */
785 }
786 break;
787 }
788
789 /* Initialize keyboard buffer.
790 This appears to work but doesn't account for banking. */
791 /* printf("init kbdbuf with %d seconds delay\n", delay); */
792 kbdbuf_init(0x03ab, 0x00d1, 10,
793 (CLOCK)(machine_timing.rfsh_per_sec *
794 machine_timing.cycles_per_rfsh * delay));
795
796 sampler_reset();
797 }
798
machine_specific_powerup(void)799 void machine_specific_powerup(void)
800 {
801 }
802
machine_specific_shutdown(void)803 void machine_specific_shutdown(void)
804 {
805 /* and the tape */
806 tape_image_detach_internal(1);
807
808 ciacore_shutdown(machine_context.cia1);
809 tpicore_shutdown(machine_context.tpi1);
810 tpicore_shutdown(machine_context.tpi2);
811
812 /* close the video chip(s) */
813 crtc_shutdown();
814
815 #ifdef HAVE_MOUSE
816 mouse_shutdown();
817 #endif
818
819 if (!console_mode) {
820 cbm2ui_shutdown();
821 }
822 }
823
machine_handle_pending_alarms(int num_write_cycles)824 void machine_handle_pending_alarms(int num_write_cycles)
825 {
826 }
827
828 /* ------------------------------------------------------------------------- */
829
830 /* This hook is called at the end of every frame. */
machine_vsync_hook(void)831 static void machine_vsync_hook(void)
832 {
833 CLOCK sub;
834
835 drive_vsync_hook();
836
837 autostart_advance();
838
839 screenshot_record();
840
841 sub = clk_guard_prevent_overflow(maincpu_clk_guard);
842
843 /* The drive has to deal both with our overflowing and its own one, so
844 it is called even when there is no overflowing in the main CPU. */
845 drive_cpu_prevent_clk_overflow_all(sub);
846 }
847
848 /* Dummy - no restore key. */
machine_set_restore_key(int v)849 void machine_set_restore_key(int v)
850 {
851 }
852
machine_has_restore_key(void)853 int machine_has_restore_key(void)
854 {
855 return 0;
856 }
857
858 /* ------------------------------------------------------------------------- */
859
machine_get_cycles_per_second(void)860 long machine_get_cycles_per_second(void)
861 {
862 return machine_timing.cycles_per_sec;
863 }
864
machine_get_cycles_per_frame(void)865 long machine_get_cycles_per_frame(void)
866 {
867 return machine_timing.cycles_per_rfsh;
868 }
869
machine_get_line_cycle(unsigned int * line,unsigned int * cycle,int * half_cycle)870 void machine_get_line_cycle(unsigned int *line, unsigned int *cycle, int *half_cycle)
871 {
872 *line = (unsigned int)((maincpu_clk) / machine_timing.cycles_per_line % machine_timing.screen_lines);
873
874 *cycle = (unsigned int)((maincpu_clk) % machine_timing.cycles_per_line);
875
876 *half_cycle = (int)-1;
877 }
878
machine_change_timing(int timeval,int border_mode)879 void machine_change_timing(int timeval, int border_mode)
880 {
881 /* log_message(LOG_DEFAULT, "machine_change_timing_c610 %d", timeval); */
882
883 switch (timeval) {
884 case MACHINE_SYNC_PAL:
885 machine_timing.cycles_per_sec = C610_PAL_CYCLES_PER_SEC;
886 machine_timing.cycles_per_rfsh = C610_PAL_CYCLES_PER_RFSH;
887 machine_timing.rfsh_per_sec = C610_PAL_RFSH_PER_SEC;
888 machine_timing.cycles_per_line = C610_PAL_CYCLES_PER_LINE;
889 machine_timing.screen_lines = C610_PAL_SCREEN_LINES;
890 machine_timing.power_freq = 50;
891 break;
892 case MACHINE_SYNC_NTSC:
893 machine_timing.cycles_per_sec = C610_NTSC_CYCLES_PER_SEC;
894 machine_timing.cycles_per_rfsh = C610_NTSC_CYCLES_PER_RFSH;
895 machine_timing.rfsh_per_sec = C610_NTSC_RFSH_PER_SEC;
896 machine_timing.cycles_per_line = C610_NTSC_CYCLES_PER_LINE;
897 machine_timing.screen_lines = C610_NTSC_SCREEN_LINES;
898 machine_timing.power_freq = 60;
899 break;
900 default:
901 log_error(LOG_DEFAULT, "Unknown machine timing.");
902 }
903
904 debug_set_machine_parameter(machine_timing.cycles_per_line,
905 machine_timing.screen_lines);
906 drive_set_machine_parameter(machine_timing.cycles_per_sec);
907 clk_guard_set_clk_base(maincpu_clk_guard, (CLOCK)machine_timing.cycles_per_rfsh);
908
909 cia1_set_timing(machine_context.cia1,
910 (int)machine_timing.cycles_per_sec,
911 machine_timing.power_freq);
912 }
913
914 /* Set the screen refresh rate, as this is variable in the CRTC */
machine_set_cycles_per_frame(long cpf)915 void machine_set_cycles_per_frame(long cpf)
916 {
917 double i, f;
918
919 machine_timing.cycles_per_rfsh = cpf;
920 machine_timing.rfsh_per_sec = ((double)machine_timing.cycles_per_sec)
921 / ((double)cpf);
922
923 f = modf(machine_timing.rfsh_per_sec, &i) * 1000;
924 log_message(cbm2_log, "cycles per frame set to %ld, refresh to %d.%03dHz",
925 cpf, (int)i, (int)f);
926
927 vsync_set_machine_parameter(machine_timing.rfsh_per_sec,
928 machine_timing.cycles_per_sec);
929 }
930
931 /* ------------------------------------------------------------------------- */
932
machine_write_snapshot(const char * name,int save_roms,int save_disks,int event_mode)933 int machine_write_snapshot(const char *name, int save_roms, int save_disks,
934 int event_mode)
935 {
936 int err = cbm2_snapshot_write(name, save_roms, save_disks, event_mode);
937 if ((err < 0) && (snapshot_get_error() == SNAPSHOT_NO_ERROR)) {
938 snapshot_set_error(SNAPSHOT_CANNOT_WRITE_SNAPSHOT);
939 }
940 return err;
941 }
942
machine_read_snapshot(const char * name,int event_mode)943 int machine_read_snapshot(const char *name, int event_mode)
944 {
945 int err = cbm2_snapshot_read(name, event_mode);
946 if ((err < 0) && (snapshot_get_error() == SNAPSHOT_NO_ERROR)) {
947 snapshot_set_error(SNAPSHOT_CANNOT_READ_SNAPSHOT);
948 }
949 return err;
950 }
951
952 /* ------------------------------------------------------------------------- */
953
machine_autodetect_psid(const char * name)954 int machine_autodetect_psid(const char *name)
955 {
956 return -1;
957 }
958
machine_screenshot(screenshot_t * screenshot,struct video_canvas_s * canvas)959 int machine_screenshot(screenshot_t *screenshot, struct video_canvas_s *canvas)
960 {
961 if (canvas == crtc_get_canvas()) {
962 crtc_screenshot(screenshot);
963 return 0;
964 }
965
966 return -1;
967 }
968
machine_canvas_async_refresh(struct canvas_refresh_s * refresh,struct video_canvas_s * canvas)969 int machine_canvas_async_refresh(struct canvas_refresh_s *refresh,
970 struct video_canvas_s *canvas)
971 {
972 if (canvas == crtc_get_canvas()) {
973 crtc_async_refresh(refresh);
974 return 0;
975 }
976 return -1;
977 }
978
979 /*-----------------------------------------------------------------------*/
980
machine_diskcontents_bus_read(unsigned int unit)981 struct image_contents_s *machine_diskcontents_bus_read(unsigned int unit)
982 {
983 return NULL;
984 }
985
machine_tape_type_default(void)986 uint8_t machine_tape_type_default(void)
987 {
988 return TAPE_CAS_TYPE_BAS;
989 }
990
machine_tape_behaviour(void)991 uint8_t machine_tape_behaviour(void)
992 {
993 return TAPE_BEHAVIOUR_NORMAL;
994 }
995
machine_addr_in_ram(unsigned int addr)996 int machine_addr_in_ram(unsigned int addr)
997 {
998 /* FIXME: handle the banking */
999 return (addr < 0xe000 && !(addr >= 0x8000 && addr < 0xc000)) ? 1 : 0;
1000 }
1001
machine_get_name(void)1002 const char *machine_get_name(void)
1003 {
1004 return machine_name;
1005 }
1006
1007 /* ------------------------------------------------------------------------- */
1008
1009 /* native screenshot support */
1010
crtc_get_active_bitmap(void)1011 uint8_t *crtc_get_active_bitmap(void)
1012 {
1013 return NULL;
1014 }
1015
1016 /* ------------------------------------------------------------------------- */
1017
cbm2_userport_set_flag(uint8_t b)1018 static void cbm2_userport_set_flag(uint8_t b)
1019 {
1020 if (b != 0) {
1021 ciacore_set_flag(machine_context.cia1);
1022 }
1023 }
1024
1025 static userport_port_props_t userport_props = {
1026 1, /* port has the pa2 pin */
1027 1, /* port has the pa3 pin */
1028 cbm2_userport_set_flag, /* port has the flag pin, set flag function */
1029 1, /* port has the pc pin */
1030 0 /* port does NOT have the cnt1, cnt2 or sp pins */
1031 };
1032
machine_register_userport(void)1033 int machine_register_userport(void)
1034 {
1035 userport_port_register(&userport_props);
1036
1037 return 0;
1038 }
1039