fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 1766 lines 36 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/arch/macplus/macplus.c * 7 * Created: 2007-04-15 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2007-2024 Hampa Hug <hampa@hampa.ch> * 9 *****************************************************************************/ 10 11/***************************************************************************** 12 * This program is free software. You can redistribute it and / or modify it * 13 * under the terms of the GNU General Public License version 2 as published * 14 * by the Free Software Foundation. * 15 * * 16 * This program is distributed in the hope that it will be useful, but * 17 * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 * Public License for more details. * 20 *****************************************************************************/ 21 22 23#include "main.h" 24#include "hook.h" 25#include "hotkey.h" 26#include "iwm.h" 27#include "keyboard.h" 28#include "macplus.h" 29#include "mem.h" 30#include "msg.h" 31#include "rtc.h" 32#include "scsi.h" 33#include "serial.h" 34#include "sony.h" 35#include "sound.h" 36#include "video.h" 37 38#include <string.h> 39 40#include <chipset/e6522.h> 41#include <chipset/e8530.h> 42 43#include <cpu/e68000/e68000.h> 44 45#include <devices/memory.h> 46#include <devices/nvram.h> 47 48#include <drivers/block/block.h> 49 50#include <drivers/video/terminal.h> 51 52#include <lib/brkpt.h> 53#include <lib/inidsk.h> 54#include <lib/iniram.h> 55#include <lib/initerm.h> 56#include <lib/load.h> 57#include <lib/log.h> 58#include <lib/sysdep.h> 59 60#include <libini/libini.h> 61 62 63/* The CPU is synchronized with real time MAC_CPU_SYNC times per seconds */ 64#define MAC_CPU_SYNC 250 65 66#ifdef PCE_HOST_WINDOWS 67#define MAC_CPU_SLEEP 20000 68#else 69#define MAC_CPU_SLEEP 10000 70#endif 71 72 73static 74unsigned char par_classic_pwm[64] = { 75 0x00, 0x01, 0x3b, 0x02, 0x3c, 0x28, 0x36, 0x03, 76 0x3d, 0x20, 0x31, 0x29, 0x37, 0x13, 0x23, 0x04, 77 0x3e, 0x34, 0x1e, 0x21, 0x32, 0x0c, 0x0e, 0x2a, 78 0x38, 0x10, 0x1b, 0x14, 0x24, 0x17, 0x2c, 0x05, 79 0x3f, 0x3a, 0x27, 0x35, 0x1f, 0x30, 0x12, 0x22, 80 0x33, 0x1d, 0x0b, 0x0d, 0x0f, 0x1a, 0x16, 0x2b, 81 0x39, 0x26, 0x2f, 0x11, 0x1c, 0x0a, 0x19, 0x15, 82 0x25, 0x2e, 0x09, 0x18, 0x2d, 0x08, 0x07, 0x06 83}; 84 85static 86void mac_classic_set_pwm (macplus_t *sim, const unsigned char *buf, unsigned cnt) 87{ 88 unsigned i, v; 89 90 v = 0; 91 92 for (i = 0; i < cnt; i++) { 93 v += par_classic_pwm[buf[0] & 0x3f]; 94 } 95 96 v = v / cnt; 97 98 if (v < 1) { 99 v = 1; 100 } 101 else if (v > 31) { 102 v = 31; 103 } 104 105 v = 32 + (223 * (30 - (v - 1)) + 15) / 30; 106 107 if ((sim->video != NULL) && (sim->video->brightness != v)) { 108 mac_video_set_brightness (sim->video, v); 109 } 110} 111 112static 113void mac_interrupt_check (macplus_t *sim) 114{ 115 unsigned i; 116 unsigned val; 117 118 val = sim->intr >> 1; 119 120 i = 0; 121 while (val != 0) { 122 i += 1; 123 val = val >> 1; 124 } 125 126#ifdef DEBUG_INT 127 mac_log_deb ("interrupt level %u\n", i); 128#endif 129 130 e68_interrupt (sim->cpu, i); 131} 132 133void mac_interrupt (macplus_t *sim, unsigned level, int val) 134{ 135 if (val) { 136 sim->intr |= (1U << level); 137 } 138 else { 139 sim->intr &= ~(1U << level); 140 } 141 142 mac_interrupt_check (sim); 143} 144 145static 146void mac_interrupt_via (void *ext, unsigned char val) 147{ 148 macplus_t *sim = ext; 149 150 if (val) { 151 sim->intr_scsi_via |= 1; 152 } 153 else { 154 sim->intr_scsi_via &= ~1; 155 } 156 157 mac_interrupt (ext, 1, sim->intr_scsi_via); 158} 159 160static 161void mac_interrupt_scsi (void *ext, unsigned char val) 162{ 163 macplus_t *sim = ext; 164 165 if (sim->via_port_b & 0x40) { 166 val = 0; 167 } 168 else { 169 val = (val != 0); 170 } 171 172 if (val) { 173 sim->intr_scsi_via |= 2; 174 } 175 else { 176 sim->intr_scsi_via &= ~2; 177 } 178 179 mac_interrupt (sim, 1, sim->intr_scsi_via); 180} 181 182static 183void mac_interrupt_scc (void *ext, unsigned char val) 184{ 185 mac_interrupt (ext, 2, val); 186} 187 188static 189void mac_interrupt_vbi (void *ext, unsigned char val) 190{ 191 unsigned i; 192 unsigned char pbuf[370]; 193 macplus_t *sim = ext; 194 195 if (val) { 196 e6522_set_ca1_inp (&sim->via, 0); 197 e6522_set_ca1_inp (&sim->via, 1); 198 199 mac_sound_vbl (&sim->sound); 200 201 for (i = 0; i < 370; i++) { 202 pbuf[i] = mem_get_uint8 (sim->mem, sim->sbuf1 + i + 1); 203 } 204 205 if (sim->model & PCE_MAC_CLASSIC) { 206 mac_classic_set_pwm (sim, pbuf, 370); 207 } 208 else { 209 mac_iwm_set_pwm (&sim->iwm, pbuf, 370); 210 } 211 } 212} 213 214static 215void mac_interrupt_sony_check (macplus_t *sim) 216{ 217 unsigned long a7; 218 219#ifdef DEBUG_SONY 220 mac_log_deb ("sony: check\n"); 221#endif 222 if (e68_get_iml (sim->cpu) == 7) { 223#ifdef DEBUG_SONY 224 mac_log_deb ("sony: check aborted (iml=7)\n"); 225#endif 226 return; 227 } 228 229 a7 = e68_get_areg32 (sim->cpu, 7); 230 e68_set_mem32 (sim->cpu, a7 - 4, e68_get_pc (sim->cpu)); 231 e68_set_areg32 (sim->cpu, 7, a7 - 4); 232 233 e68_set_pc_prefetch (sim->cpu, sim->sony.check_addr); 234} 235 236void mac_interrupt_osi (void *ext, unsigned char val) 237{ 238 macplus_t *sim = ext; 239 240 if (val) { 241 if (mac_sony_check (&sim->sony)) { 242 mac_interrupt_sony_check (sim); 243 } 244 245 e6522_set_ca2_inp (&sim->via, 0); 246 e6522_set_ca2_inp (&sim->via, 1); 247 } 248} 249 250static 251void mac_set_reset (void *ext, unsigned char val) 252{ 253 if (val == 0) { 254 return; 255 } 256 257 mac_reset (ext); 258} 259 260static 261void mac_ram_write (void *ext, uint32_t addr, unsigned size) 262{ 263 macplus_t *sim = ext; 264 265 if (sim->video == NULL) { 266 return; 267 } 268 269 if ((addr + size) > sim->video->vbuf_addr && 270 addr < (sim->video->vbuf_addr + sim->video->vbuf_size)) { 271 mac_video_set_dirty (sim->video); 272 } 273} 274 275static 276void mac_set_vbuf (macplus_t *sim, unsigned long addr) 277{ 278 unsigned char *vbuf; 279 unsigned long vbuf_size; 280 mem_blk_t *blk; 281 282 vbuf_size = ((unsigned long)(sim->video->w + 7) / 8) * sim->video->h; 283 284 if (addr < mem_blk_get_size (sim->ram)) { 285 vbuf = mem_blk_get_data (sim->ram) + addr; 286 } 287 else { 288 blk = mem_get_blk (sim->mem, addr); 289 290 if (blk == NULL) { 291 mac_video_set_vbuf (sim->video, NULL); 292 mac_video_set_vbuf_addr (sim->video, 0, 0); 293 return; 294 } 295 296 vbuf = mem_blk_get_data (blk); 297 vbuf += mem_blk_get_addr (blk) - sim->vbuf1; 298 } 299 300 mac_video_set_vbuf (sim->video, vbuf); 301 mac_video_set_vbuf_addr (sim->video, addr, vbuf_size); 302} 303 304static 305void mac_check_mouse (macplus_t *sim) 306{ 307 if (sim->adb != NULL) { 308 return; 309 } 310 311 if ((sim->mouse_delta_x <= -2) || (sim->mouse_delta_x >= 2)) { 312 if (sim->dcd_a) { 313 sim->via_port_b &= ~0x10; 314 } 315 else { 316 sim->via_port_b |= 0x10; 317 } 318 319 if (sim->mouse_delta_x > 0) { 320 sim->via_port_b ^= 0x10; 321 sim->mouse_delta_x -= 2; 322 } 323 else { 324 sim->mouse_delta_x += 2; 325 } 326 327 e6522_set_irb_inp (&sim->via, sim->via_port_b); 328 e8530_set_dcd_a (&sim->scc, sim->dcd_a); 329 330 sim->dcd_a = !sim->dcd_a; 331 } 332 333 if ((sim->mouse_delta_y <= -2) || (sim->mouse_delta_y >= 2)) { 334 if (sim->dcd_b) { 335 sim->via_port_b &= ~0x20; 336 } 337 else { 338 sim->via_port_b |= 0x20; 339 } 340 341 if (sim->mouse_delta_y > 0) { 342 sim->mouse_delta_y -= 2; 343 } 344 else { 345 sim->via_port_b ^= 0x20; 346 sim->mouse_delta_y += 2; 347 } 348 349 e6522_set_irb_inp (&sim->via, sim->via_port_b); 350 e8530_set_dcd_b (&sim->scc, sim->dcd_b); 351 352 sim->dcd_b = !sim->dcd_b; 353 } 354} 355 356static 357void mac_set_mouse (void *ext, int dx, int dy, unsigned but) 358{ 359 macplus_t *sim = ext; 360 unsigned char old; 361 362 if (sim->pause) { 363 if (but) { 364 mac_set_pause (sim, 0); 365 } 366 367 return; 368 } 369 370 if ((sim->mouse_button ^ but) & ~but & 4) { 371 mac_set_msg (sim, "term.release", "1"); 372 } 373 374 sim->mouse_button = but; 375 376 if (sim->adb_mouse != NULL) { 377 adb_mouse_move (sim->adb_mouse, but, dx, dy); 378 return; 379 } 380 381 old = sim->via_port_b; 382 383 if (but & 1) { 384 sim->via_port_b &= 0xf7; 385 } 386 else { 387 sim->via_port_b |= 0x08; 388 } 389 390 if (sim->via_port_b != old) { 391 e6522_set_irb_inp (&sim->via, sim->via_port_b); 392 } 393 394 sim->mouse_delta_x += dx; 395 sim->mouse_delta_y += dy; 396} 397 398static 399void mac_get_mouse (void *ext, int *x, int *y) 400{ 401 macplus_t *sim = ext; 402 403 /* RawMouse low-memory global at 0x82c */ 404 *y = (int) mem_get_uint16_be (sim->mem, 0x82c); 405 *x = (int) mem_get_uint16_be (sim->mem, 0x82e); 406} 407 408static 409void mac_set_key (void *ext, unsigned event, pce_key_t key) 410{ 411 macplus_t *sim = ext; 412 413 if (event == PCE_KEY_EVENT_MAGIC) { 414 mac_set_hotkey (sim, key); 415 return; 416 } 417 418 if (sim->kbd != NULL) { 419 mac_kbd_set_key (sim->kbd, event, key); 420 } 421 422 if (sim->adb_kbd != NULL) { 423 adb_kbd_set_key (sim->adb_kbd, event, key); 424 } 425} 426 427static 428void mac_set_adb_int (void *ext, unsigned char val) 429{ 430 macplus_t *sim = ext; 431 432 if (val) { 433 sim->via_port_b &= ~0x08; 434 } 435 else { 436 sim->via_port_b |= 0x08; 437 } 438 439 e6522_set_irb_inp (&sim->via, sim->via_port_b); 440} 441 442static 443void mac_set_iwm_motor (void *ext, unsigned char val) 444{ 445 macplus_t *sim = ext; 446 447 mac_set_speed (sim, PCE_MAC_SPEED_IWM, val ? 4 : 0); 448} 449 450static 451void mac_set_rtc_data (void *ext, unsigned char val) 452{ 453 macplus_t *sim = ext; 454 455 if (val) { 456 sim->via_port_b |= 0x01; 457 } 458 else { 459 sim->via_port_b &= ~0x01; 460 } 461 462 e6522_set_irb_inp (&sim->via, sim->via_port_b); 463} 464 465static 466void mac_set_via_port_a (void *ext, unsigned char val) 467{ 468 macplus_t *sim = ext; 469 unsigned char old; 470 471 if (sim->via_port_a == val) { 472 return; 473 } 474 475#ifdef DEBUG_VIA 476 mac_log_deb ("via: set port a: %02X\n", val); 477#endif 478 479 old = sim->via_port_a; 480 sim->via_port_a = val; 481 482 if ((old ^ val) & 0x10) { 483 if (sim->model & PCE_MAC_PLUS) { 484 mac_set_overlay (sim, (val & 0x10) != 0); 485 } 486 else if (sim->model & (PCE_MAC_SE | PCE_MAC_CLASSIC)) { 487 mac_iwm_set_drive_sel (&sim->iwm, (val & 0x10) != 0); 488 } 489 } 490 491 if ((old ^ val) & 0x20) { 492 mac_iwm_set_head_sel (&sim->iwm, (val & 0x20) != 0); 493 } 494 495 if ((old ^ val) & 0x40) { 496 unsigned long addr; 497 498 if (val & 0x40) { 499 mac_log_deb ("main video buffer\n"); 500 addr = sim->vbuf1; 501 } 502 else { 503 mac_log_deb ("alternate video buffer\n"); 504 addr = sim->vbuf2; 505 } 506 507 mac_set_vbuf (sim, addr); 508 } 509 510 if ((old ^ val) & 0x08) { 511 if (sim->model & PCE_MAC_PLUS) { 512 unsigned char *sbuf; 513 514 sbuf = mem_blk_get_data (sim->ram); 515 516 if (val & 0x08) { 517 mac_log_deb ("main sound buffer\n"); 518 sbuf += sim->sbuf1; 519 } 520 else { 521 mac_log_deb ("alternate sound buffer\n"); 522 sbuf += sim->sbuf2; 523 } 524 525 mac_sound_set_sbuf (&sim->sound, sbuf); 526 } 527 } 528 529 if ((old ^ val) & 0x07) { 530 mac_sound_set_volume (&sim->sound, val & 7); 531 } 532} 533 534static 535void mac_set_via_port_b (void *ext, unsigned char val) 536{ 537 macplus_t *sim = ext; 538 unsigned char old; 539 540 if (sim->via_port_b == val) { 541 return; 542 } 543 544#ifdef DEBUG_VIA 545 mac_log_deb ("via: set port b: %02X\n", val); 546#endif 547 548 old = sim->via_port_b; 549 sim->via_port_b = val; 550 551 mac_rtc_set_uint8 (&sim->rtc, val); 552 553 if ((old ^ val) & 0x80) { 554 mac_sound_set_enable (&sim->sound, (val & 0x80) == 0); 555 } 556 557 if (sim->adb != NULL) { 558 mac_adb_set_state (sim->adb, (val >> 4) & 3); 559 } 560} 561 562static 563unsigned char mac_scc_get_uint8 (void *ext, unsigned long addr) 564{ 565 unsigned char val; 566 macplus_t *sim = ext; 567 568 val = 0xff; 569 570 switch (addr) { 571 case 0x1ffff8: 572 val = e8530_get_ctl_b (&sim->scc); 573 break; 574 575 case 0x1ffffa: 576 val = e8530_get_ctl_a (&sim->scc); 577 break; 578 579 case 0x1ffffc: 580 val = e8530_get_data_b (&sim->scc); 581 break; 582 583 case 0x1ffffe: 584 val = e8530_get_data_a (&sim->scc); 585 break; 586 } 587 588#ifdef DEBUG_SCC 589 mac_log_deb ("scc: get 8: %06lX -> %02X\n", addr, val); 590#endif 591 592 return (val); 593} 594 595static 596void mac_scc_set_uint8 (void *ext, unsigned long addr, unsigned char val) 597{ 598 macplus_t *sim = ext; 599 600#ifdef DEBUG_SCC 601 mac_log_deb ("scc: set 8: %06lX <- %02X\n", addr, val); 602#endif 603 604 switch (addr) { 605 case 0x3ffff9: 606 e8530_set_ctl_b (&sim->scc, val); 607 break; 608 609 case 0x3ffffb: 610 e8530_set_ctl_a (&sim->scc, val); 611 break; 612 613 case 0x3ffffd: 614 e8530_set_data_b (&sim->scc, val); 615 break; 616 617 case 0x3fffff: 618 e8530_set_data_a (&sim->scc, val); 619 break; 620 } 621} 622 623 624static 625void mac_setup_system (macplus_t *sim, ini_sct_t *ini) 626{ 627 int memtest; 628 const char *model; 629 ini_sct_t *sct; 630 631 if ((sct = ini_next_sct (ini, NULL, "system")) == NULL) { 632 sct = ini; 633 } 634 635 ini_get_string (sct, "model", &model, "mac-plus"); 636 637 if (ini_get_bool (sct, "memtest", &memtest, 1)) { 638 ini_get_bool (ini, "memtest", &memtest, 1); 639 } 640 641 pce_log_tag (MSG_INF, "SYSTEM:", "model=%s memtest=%d\n", 642 model, memtest 643 ); 644 645 if (strcmp (model, "mac-128k") == 0) { 646 sim->model = PCE_MAC_PLUS; 647 } 648 else if (strcmp (model, "mac-512k") == 0) { 649 sim->model = PCE_MAC_PLUS; 650 } 651 else if (strcmp (model, "mac-plus") == 0) { 652 sim->model = PCE_MAC_PLUS; 653 } 654 else if (strcmp (model, "mac-se") == 0) { 655 sim->model = PCE_MAC_SE; 656 } 657 else if (strcmp (model, "mac-classic") == 0) { 658 sim->model = PCE_MAC_CLASSIC; 659 } 660 else { 661 pce_log (MSG_ERR, "*** unknown model (%s)\n", model); 662 sim->model = PCE_MAC_PLUS; 663 } 664 665 sim->memtest = (memtest != 0); 666} 667 668static 669void mac_setup_mem (macplus_t *sim, ini_sct_t *ini) 670{ 671 sim->mem = mem_new(); 672 673 mem_set_fct (sim->mem, sim, 674 mac_mem_get_uint8, mac_mem_get_uint16, mac_mem_get_uint32, 675 mac_mem_set_uint8, mac_mem_set_uint16, mac_mem_set_uint32 676 ); 677 678 ini_get_ram (sim->mem, ini, &sim->ram); 679 ini_get_rom (sim->mem, ini); 680 681 sim->ram = mem_get_blk (sim->mem, 0x00000000); 682 sim->rom = mem_get_blk (sim->mem, 0x00400000); 683 684 sim->ram_ovl = NULL; 685 sim->rom_ovl = NULL; 686 687 if (sim->ram == NULL) { 688 pce_log (MSG_ERR, "*** RAM not found at 000000\n"); 689 return; 690 } 691 692 if (sim->rom == NULL) { 693 pce_log (MSG_ERR, "*** ROM not found at 400000\n"); 694 return; 695 } 696 697 sim->ram_ovl = mem_blk_clone (sim->ram); 698 mem_blk_set_addr (sim->ram_ovl, 0x00600000); 699 700 if (mem_blk_get_size (sim->ram_ovl) > 0x00200000) { 701 mem_blk_set_size (sim->ram_ovl, 0x00200000); 702 } 703 704 sim->rom_ovl = mem_blk_clone (sim->rom); 705 mem_blk_set_addr (sim->rom_ovl, 0); 706 707 sim->overlay = 0; 708 709 if (sim->memtest == 0) { 710 pce_log_tag (MSG_INF, "RAM:", "disabling memory test\n"); 711 712 if (sim->model & PCE_MAC_PLUS) { 713 mem_set_uint32_be (sim->mem, 0x02ae, 0x00400000); 714 } 715 else if (sim->model & (PCE_MAC_SE | PCE_MAC_CLASSIC)) { 716 mem_set_uint32_be (sim->mem, 0x0cfc, 0x574c5343); 717 } 718 } 719} 720 721static 722void mac_setup_cpu (macplus_t *sim, ini_sct_t *ini) 723{ 724 ini_sct_t *sct; 725 const char *model; 726 unsigned speed; 727 728 sct = ini_next_sct (ini, NULL, "cpu"); 729 730 ini_get_string (sct, "model", &model, "68000"); 731 ini_get_uint16 (sct, "speed", &speed, 0); 732 733 pce_log_tag (MSG_INF, "CPU:", "model=%s speed=%d\n", model, speed); 734 735 sim->cpu = e68_new(); 736 if (sim->cpu == NULL) { 737 return; 738 } 739 740 if (mac_set_cpu_model (sim, model)) { 741 pce_log (MSG_ERR, "*** unknown cpu model (%s)\n", model); 742 } 743 744 e68_set_mem_fct (sim->cpu, sim->mem, 745 &mem_get_uint8, 746 &mem_get_uint16_be, 747 &mem_get_uint32_be, 748 &mem_set_uint8, 749 &mem_set_uint16_be, 750 &mem_set_uint32_be 751 ); 752 753 e68_set_reset_fct (sim->cpu, sim, mac_set_reset); 754 755 e68_set_hook_fct (sim->cpu, sim, mac_hook); 756 757 e68_set_address_check (sim->cpu, 0); 758 759 sim->speed_factor = speed; 760 sim->speed_limit[PCE_MAC_SPEED_USER] = speed; 761} 762 763static 764void mac_setup_via (macplus_t *sim, ini_sct_t *ini) 765{ 766 ini_sct_t *sct; 767 mem_blk_t *blk; 768 unsigned long addr, size; 769 770 sct = ini_next_sct (ini, NULL, "via"); 771 772 ini_get_uint32 (sct, "address", &addr, 0x00efe000); 773 ini_get_uint32 (sct, "size", &size, 16 * 512); 774 775 pce_log_tag (MSG_INF, "VIA:", "addr=0x%06lx size=0x%lx\n", addr, size); 776 777 e6522_init (&sim->via, 9); 778 779 e6522_set_irq_fct (&sim->via, sim, mac_interrupt_via); 780 781 e6522_set_ora_fct (&sim->via, sim, mac_set_via_port_a); 782 e6522_set_orb_fct (&sim->via, sim, mac_set_via_port_b); 783 784 blk = mem_blk_new (addr, size, 0); 785 786 if (blk == NULL) { 787 return; 788 } 789 790 mem_blk_set_fct (blk, &sim->via, 791 e6522_get_uint8, e6522_get_uint16, e6522_get_uint32, 792 e6522_set_uint8, e6522_set_uint16, e6522_set_uint32 793 ); 794 795 mem_add_blk (sim->mem, blk, 1); 796} 797 798static 799void mac_setup_scc (macplus_t *sim, ini_sct_t *ini) 800{ 801 ini_sct_t *sct; 802 mem_blk_t *blk; 803 unsigned long addr, size; 804 805 sct = ini_next_sct (ini, NULL, "scc"); 806 807 ini_get_uint32 (sct, "address", &addr, 0x800000); 808 ini_get_uint32 (sct, "size", &size, 0x400000); 809 810 pce_log_tag (MSG_INF, "SCC:", "addr=0x%06lx size=0x%lx\n", addr, size); 811 812 e8530_init (&sim->scc); 813 e8530_set_irq_fct (&sim->scc, sim, mac_interrupt_scc); 814 e8530_set_clock (&sim->scc, 3672000, 3672000, 3672000); 815 816 blk = mem_blk_new (addr, size, 0); 817 if (blk == NULL) { 818 return; 819 } 820 821 mem_blk_set_fct (blk, sim, 822 mac_scc_get_uint8, NULL, NULL, 823 mac_scc_set_uint8, NULL, NULL 824 ); 825 826 mem_add_blk (sim->mem, blk, 1); 827} 828 829static 830void mac_setup_serial (macplus_t *sim, ini_sct_t *ini) 831{ 832 ini_sct_t *sct; 833 unsigned port; 834 unsigned multichar; 835 const char *driver; 836 837 mac_ser_init (&sim->ser[0]); 838 mac_ser_set_scc (&sim->ser[0], &sim->scc, 0); 839 840 mac_ser_init (&sim->ser[1]); 841 mac_ser_set_scc (&sim->ser[1], &sim->scc, 1); 842 843 sct = ini_next_sct (ini, NULL, "serial"); 844 845 while (sct != NULL) { 846 ini_get_uint16 (sct, "port", &port, 0); 847 ini_get_uint16 (sct, "multichar", &multichar, 1); 848 ini_get_string (sct, "driver", &driver, NULL); 849 850 pce_log_tag (MSG_INF, "SERIAL:", "port=%u multichar=%u driver=%s\n", 851 port, multichar, 852 (driver != NULL) ? driver : "<none>" 853 ); 854 855 sct = ini_next_sct (ini, sct, "serial"); 856 857 if (port > 1) { 858 pce_log (MSG_ERR, "*** bad port number (%u)\n", port); 859 continue; 860 } 861 862 e8530_set_multichar (&sim->scc, port, multichar, multichar); 863 864 if (driver != NULL) { 865 if (mac_ser_set_driver (&sim->ser[port], driver)) { 866 pce_log (MSG_ERR, "*** can't open driver (%s)\n", driver); 867 } 868 } 869 } 870} 871 872static 873void mac_setup_rtc (macplus_t *sim, ini_sct_t *ini) 874{ 875 ini_sct_t *sct; 876 const char *fname; 877 const char *start; 878 int localtime, realtime, romdisk, atalk; 879 unsigned volume; 880 881 sct = ini_next_sct (ini, NULL, "rtc"); 882 883 ini_get_string (sct, "file", &fname, "pram.dat"); 884 ini_get_bool (sct, "localtime", &localtime, 0); 885 ini_get_bool (sct, "realtime", &realtime, 1); 886 ini_get_bool (sct, "romdisk", &romdisk, 0); 887 ini_get_uint16 (sct, "volume", &volume, 0xff); 888 ini_get_string (sct, "start", &start, NULL); 889 890 if (ini_get_bool (sct, "appletalk", &atalk, 0)) { 891 atalk = -1; 892 } 893 894 pce_log_tag (MSG_INF, "RTC:", 895 "file=%s localtime=%d realtime=%d start=%s romdisk=%d " 896 "atalk=%d volume=%u\n", 897 fname, localtime, realtime, (start != NULL) ? start : "<now>", 898 romdisk, atalk, volume 899 ); 900 901 sim->rtc_fname = strdup (fname); 902 903 mac_rtc_init (&sim->rtc); 904 905 mac_rtc_set_data_fct (&sim->rtc, sim, mac_set_rtc_data); 906 mac_rtc_set_osi_fct (&sim->rtc, sim, mac_interrupt_osi); 907 908 if (localtime) { 909 mac_rtc_set_time_gmtoff (&sim->rtc); 910 } 911 912 mac_rtc_set_realtime (&sim->rtc, realtime); 913 914 if (mac_rtc_load_file (&sim->rtc, fname)) { 915 pce_log (MSG_ERR, "*** reading rtc file failed\n"); 916 } 917 918 if (romdisk) { 919 sim->rtc.data[0x78] = 0x00; 920 sim->rtc.data[0x79] = 0x06; 921 sim->rtc.data[0x7a] = 0xff; 922 sim->rtc.data[0x7b] = 0xcb; 923 } 924 925 if (atalk == 0) { 926 sim->rtc.data[0x13] = 0x22; 927 } 928 else if (atalk == 1) { 929 sim->rtc.data[0x13] = 0x21; 930 } 931 932 if (volume < 8) { 933 sim->rtc.data[0x08] &= 0xf8; 934 sim->rtc.data[0x08] |= (volume & 7); 935 } 936 937 if (start != NULL) { 938 mac_rtc_set_time_str (&sim->rtc, start); 939 } 940 else { 941 mac_rtc_set_time_now (&sim->rtc); 942 } 943} 944 945static 946void mac_setup_kbd (macplus_t *sim, ini_sct_t *ini) 947{ 948 ini_sct_t *sct; 949 unsigned model; 950 int intl, motion; 951 952 sim->kbd = NULL; 953 954 if ((sim->model & PCE_MAC_PLUS) == 0) { 955 return; 956 } 957 958 sct = ini_next_sct (ini, NULL, "keyboard"); 959 960 ini_get_uint16 (sct, "model", &model, 1); 961 ini_get_bool (sct, "intl", &intl, 0); 962 ini_get_bool (sct, "keypad_motion", &motion, 0); 963 964 pce_log_tag (MSG_INF, 965 "KEYBOARD:", "model=%u international=%d keypad=%s\n", 966 model, 967 intl, 968 motion ? "motion" : "keypad" 969 ); 970 971 sim->kbd = mac_kbd_new(); 972 973 if (sim->kbd == NULL) { 974 return; 975 } 976 977 mac_kbd_set_model (sim->kbd, model, intl); 978 mac_kbd_set_keypad_mode (sim->kbd, motion); 979 mac_kbd_set_data_fct (sim->kbd, &sim->via, e6522_set_shift_inp); 980 mac_kbd_set_intr_fct (sim->kbd, sim, mac_interrupt); 981 982 e6522_set_shift_out_fct (&sim->via, sim->kbd, mac_kbd_set_uint8); 983 e6522_set_cb2_fct (&sim->via, sim->kbd, mac_kbd_set_data); 984} 985 986static 987void mac_setup_adb (macplus_t *sim, ini_sct_t *ini) 988{ 989 ini_sct_t *sct; 990 int mouse, keyboard, motion; 991 992 sim->adb = NULL; 993 sim->adb_mouse = NULL; 994 sim->adb_kbd = NULL; 995 996 if ((sim->model & (PCE_MAC_SE | PCE_MAC_CLASSIC)) == 0) { 997 return; 998 } 999 1000 sct = ini_next_sct (ini, NULL, "adb"); 1001 1002 ini_get_bool (sct, "mouse", &mouse, 1); 1003 ini_get_bool (sct, "keyboard", &keyboard, 1); 1004 ini_get_bool (sct, "keypad_motion", &motion, 0); 1005 1006 pce_log_tag (MSG_INF, "ADB:", "enabled\n"); 1007 1008 sim->adb = mac_adb_new(); 1009 1010 if (sim->adb == NULL) { 1011 pce_log (MSG_ERR, "*** can't create adb\n"); 1012 return; 1013 } 1014 1015 adb_set_shift_in_fct (sim->adb, &sim->via, e6522_shift_in); 1016 adb_set_shift_out_fct (sim->adb, &sim->via, e6522_shift_out); 1017 1018 adb_set_int_fct (sim->adb, sim, mac_set_adb_int); 1019 1020 if (mouse) { 1021 pce_log_tag (MSG_INF, "ADB:", "mouse\n"); 1022 1023 sim->adb_mouse = adb_mouse_new(); 1024 1025 if (sim->adb_mouse != NULL) { 1026 adb_add_device (sim->adb, &sim->adb_mouse->dev); 1027 } 1028 } 1029 1030 if (keyboard) { 1031 pce_log_tag (MSG_INF, "ADB:", 1032 "keyboard keypad_mode=%s\n", 1033 motion ? "motion" : "keypad" 1034 ); 1035 1036 sim->adb_kbd = adb_kbd_new(); 1037 1038 if (sim->adb_kbd != NULL) { 1039 adb_kbd_set_keypad_mode (sim->adb_kbd, motion); 1040 adb_add_device (sim->adb, &sim->adb_kbd->dev); 1041 } 1042 } 1043} 1044 1045static 1046void mac_setup_disks (macplus_t *sim, ini_sct_t *ini) 1047{ 1048 sim->dsks = ini_get_disks (ini); 1049} 1050 1051static 1052void mac_setup_iwm (macplus_t *sim, ini_sct_t *ini) 1053{ 1054 unsigned n; 1055 int single, rotate, inserted, pwm; 1056 unsigned drive, disk; 1057 ini_sct_t *sct, *sctdev; 1058 1059 sct = ini_next_sct (ini, NULL, "iwm"); 1060 1061 mac_iwm_init (&sim->iwm); 1062 mac_iwm_set_motor_fct (&sim->iwm, sim, mac_set_iwm_motor); 1063 mac_iwm_set_disks (&sim->iwm, sim->dsks); 1064 1065 pce_log_tag (MSG_INF, "IWM:", "addr=0x%06lx\n", 0xd00000UL); 1066 1067 sctdev = ini_next_sct (sct, NULL, "drive"); 1068 1069 n = 0; 1070 1071 while (sctdev != NULL) { 1072 ini_get_uint16 (sctdev, "drive", &drive, n); 1073 ini_get_uint16 (sctdev, "disk", &disk, drive); 1074 1075 ini_get_bool (sct, "single_sided", &single, 0); 1076 ini_get_bool (sctdev, "single_sided", &single, single); 1077 1078 ini_get_bool (sct, "pwm", &pwm, 1); 1079 ini_get_bool (sctdev, "pwm", &pwm, pwm); 1080 1081 ini_get_bool (sct, "inserted", &inserted, 0); 1082 ini_get_bool (sctdev, "inserted", &inserted, inserted); 1083 1084 if ((drive >= 1) && (drive <= 8)) { 1085 if (par_disk_boot & (1U << (drive - 1))) { 1086 inserted = 1; 1087 } 1088 } 1089 1090 ini_get_bool (sct, "auto_rotate", &rotate, 0); 1091 ini_get_bool (sctdev, "auto_rotate", &rotate, rotate); 1092 1093 pce_log_tag (MSG_INF, 1094 "IWM:", "drive=%u size=%uK pwm=%d ins=%d rotate=%d disk=%u\n", 1095 drive, single ? 400 : 800, pwm, inserted, rotate, disk 1096 ); 1097 1098 mac_iwm_enable_pwm (&sim->iwm, drive - 1, pwm); 1099 mac_iwm_set_heads (&sim->iwm, drive - 1, single ? 1 : 2); 1100 mac_iwm_set_disk_id (&sim->iwm, drive - 1, disk); 1101 mac_iwm_set_auto_rotate (&sim->iwm, drive - 1, rotate); 1102 1103 if (inserted) { 1104 mac_iwm_insert (&sim->iwm, drive - 1); 1105 } 1106 1107 n = drive + 1; 1108 1109 sctdev = ini_next_sct (sct, sctdev, "drive"); 1110 } 1111} 1112 1113static 1114void mac_setup_scsi (macplus_t *sim, ini_sct_t *ini) 1115{ 1116 ini_sct_t *sct, *sctdev; 1117 mem_blk_t *blk; 1118 unsigned long addr, size; 1119 unsigned id, drive, daynaport; 1120 const char *vendor, *product, *mac_addr, *tap_dev, *tap_cmd, *bridged_if; 1121 1122 sct = ini_next_sct (ini, NULL, "scsi"); 1123 1124 if (sct == NULL) { 1125 return; 1126 } 1127 1128 ini_get_uint32 (sct, "address", &addr, 0x580000); 1129 ini_get_uint32 (sct, "size", &size, 0x80000); 1130 1131 pce_log_tag (MSG_INF, "SCSI:", "addr=0x%06lx size=0x%lx\n", addr, size); 1132 1133 mac_scsi_init (&sim->scsi); 1134 1135 if (sim->model & PCE_MAC_SE) { 1136 mac_scsi_set_int_fct (&sim->scsi, sim, mac_interrupt_scsi); 1137 } 1138 1139 mac_scsi_set_disks (&sim->scsi, sim->dsks); 1140 1141 blk = mem_blk_new (addr, size, 0); 1142 if (blk == NULL) { 1143 return; 1144 } 1145 1146 mem_blk_set_fct (blk, &sim->scsi, 1147 mac_scsi_get_uint8, mac_scsi_get_uint16, NULL, 1148 mac_scsi_set_uint8, mac_scsi_set_uint16, NULL 1149 ); 1150 1151 mem_add_blk (sim->mem, blk, 1); 1152 1153 sctdev = ini_next_sct (sct, NULL, "device"); 1154 while (sctdev != NULL) { 1155 ini_get_uint16 (sctdev, "id", &id, 0); 1156 ini_get_uint16 (sctdev, "drive", &drive, 0); 1157 ini_get_uint16 (sctdev, "daynaport", &daynaport, 0); 1158 1159 if (drive) { 1160 ini_get_string (sctdev, "vendor", &vendor, "PCE"); 1161 ini_get_string (sctdev, "product", &product, "PCEDISK"); 1162 1163 pce_log_tag (MSG_INF, 1164 "SCSI:", 1165 "id=%u drive=%u vendor=\"%s\" product=\"%s\"\n", 1166 id, drive, vendor, product 1167 ); 1168 1169 mac_scsi_set_drive (&sim->scsi, id, drive); 1170 mac_scsi_set_drive_vendor (&sim->scsi, id, vendor); 1171 mac_scsi_set_drive_product (&sim->scsi, id, product); 1172 } 1173 else if (daynaport) { 1174 ini_get_string (sctdev, "tap", &tap_dev, "/dev/tap0"); 1175 ini_get_string (sctdev, "tap_cmd", &tap_cmd, ""); 1176 ini_get_string (sctdev, "mac_addr", &mac_addr, "00:80:19:c0:ff:ee"); 1177 ini_get_string (sctdev, "bridged_if", &bridged_if, ""); 1178 1179 pce_log_tag (MSG_INF, 1180 "SCSI:", 1181#if PCE_ENABLE_VMNET 1182 "id=%u daynaport=%u bridged=%s mac_addr=%s\n", 1183 id, daynaport, bridged_if, mac_addr 1184#else 1185 "id=%u daynaport=%u tap=%s cmd=%s mac_addr=%s\n", 1186 id, daynaport, tap_dev, tap_cmd, mac_addr 1187#endif 1188 ); 1189 1190 mac_scsi_set_daynaport (&sim->scsi, id, tap_dev, tap_cmd, mac_addr, bridged_if); 1191 } 1192 1193 sctdev = ini_next_sct (sct, sctdev, "device"); 1194 } 1195} 1196 1197static 1198void mac_setup_sony (macplus_t *sim, ini_sct_t *ini) 1199{ 1200 unsigned i; 1201 int format_hd_as_dd; 1202 char var[32]; 1203 unsigned def, val; 1204 ini_sct_t *sct; 1205 1206 sct = ini_next_sct (ini, NULL, "sony"); 1207 1208 ini_get_uint16 (sct, "insert_delay", &def, 0); 1209 ini_get_bool (sct, "format_hd_as_dd", &format_hd_as_dd, 0); 1210 1211 mac_sony_init (&sim->sony, sct != NULL); 1212 mac_sony_set_mem (&sim->sony, sim->mem); 1213 mac_sony_set_disks (&sim->sony, sim->dsks); 1214 1215 sim->sony.format_hd_as_dd = format_hd_as_dd; 1216 1217 if (sct == NULL) { 1218 return; 1219 } 1220 1221 for (i = 0; i < SONY_DRIVES; i++) { 1222 if (par_disk_boot & (1U << i)) { 1223 val = 1; 1224 } 1225 else { 1226 sprintf (var, "insert_delay_%u", i + 1); 1227 ini_get_uint16 (sct, var, &val, def); 1228 } 1229 1230 mac_sony_set_delay (&sim->sony, i, val); 1231 1232 pce_log_tag (MSG_INF, "SONY:", "drive=%u delay=%lu\n", 1233 i + 1, val 1234 ); 1235 } 1236} 1237 1238static 1239void mac_setup_sound (macplus_t *sim, ini_sct_t *ini) 1240{ 1241 unsigned long addr; 1242 unsigned long freq; 1243 const char *driver; 1244 ini_sct_t *sct; 1245 1246 mac_sound_init (&sim->sound); 1247 1248 if (sim->ram == NULL) { 1249 return; 1250 } 1251 1252 sct = ini_next_sct (ini, NULL, "sound"); 1253 1254 addr = mem_blk_get_size (sim->ram); 1255 addr = (addr < 0x300) ? 0 : (addr - 0x300); 1256 1257 ini_get_uint32 (sct, "address", &addr, addr); 1258 ini_get_uint32 (sct, "lowpass", &freq, 6000); 1259 ini_get_string (sct, "driver", &driver, NULL); 1260 1261 pce_log_tag (MSG_INF, "SOUND:", "addr=0x%06lX lowpass=%lu driver=%s\n", 1262 addr, freq, 1263 (driver != NULL) ? driver : "<none>" 1264 ); 1265 1266 sim->sbuf1 = addr; 1267 sim->sbuf2 = addr - 0x5c00; 1268 1269 mac_sound_set_sbuf (&sim->sound, mem_blk_get_data (sim->ram) + sim->sbuf1); 1270 1271 mac_sound_set_lowpass (&sim->sound, freq); 1272 1273 if (driver != NULL) { 1274 if (mac_sound_set_driver (&sim->sound, driver)) { 1275 pce_log (MSG_ERR, 1276 "*** setting sound driver failed (%s)\n", 1277 driver 1278 ); 1279 } 1280 } 1281} 1282 1283static 1284void mac_setup_terminal (macplus_t *sim, ini_sct_t *ini) 1285{ 1286 sim->trm = ini_get_terminal (ini, par_terminal); 1287 1288 if (sim->trm == NULL) { 1289 return; 1290 } 1291 1292 trm_set_msg_fct (sim->trm, sim, mac_set_msg); 1293 trm_set_key_fct (sim->trm, sim, mac_set_key); 1294 trm_set_mouse_fct (sim->trm, sim, mac_set_mouse); 1295 trm_set_get_mouse_fct (sim->trm, sim, mac_get_mouse); 1296} 1297 1298static 1299void mac_setup_video (macplus_t *sim, ini_sct_t *ini) 1300{ 1301 unsigned long addr1, addr2; 1302 unsigned w, h, i; 1303 unsigned bright; 1304 unsigned long col0, col1; 1305 ini_sct_t *sct; 1306 1307 if (sim->ram == NULL) { 1308 return; 1309 } 1310 1311 sct = ini_next_sct (ini, NULL, "video"); 1312 1313 ini_get_uint16 (sct, "width", &w, 512); 1314 ini_get_uint16 (sct, "height", &h, 342); 1315 1316 addr1 = mem_blk_get_size (sim->ram); 1317 addr1 = (addr1 < 0x5900) ? 0 : (addr1 - ((w * h / 8) + 0x380)); 1318 1319 ini_get_uint32 (sct, "address", &addr2, addr1); 1320 ini_get_uint32 (sct, "color0", &col0, 0); 1321 ini_get_uint32 (sct, "color1", &col1, 0xffffff); 1322 ini_get_uint16 (sct, "brightness", &bright, 1000); 1323 1324 pce_log_tag (MSG_INF, "VIDEO:", "addr=0x%06lX w=%u h=%u bright=%u%%\n", 1325 addr2, w, h, bright / 10 1326 ); 1327 1328 sim->vbuf1 = addr2; 1329 1330 if ((addr1 == addr2) && (addr2 >= 0x8000)) { 1331 sim->vbuf2 = addr2 - 0x8000; 1332 } 1333 else { 1334 sim->vbuf2 = addr2; 1335 } 1336 1337 sim->video = mac_video_new (w, h); 1338 1339 if (sim->video == NULL) { 1340 return; 1341 } 1342 1343 mac_video_set_vbi_fct (sim->video, sim, mac_interrupt_vbi); 1344 1345 mac_set_vbuf (sim, sim->vbuf1); 1346 1347 if (sim->trm != NULL) { 1348 mac_video_set_terminal (sim->video, sim->trm); 1349 1350 trm_open (sim->trm, w, h); 1351 } 1352 1353 mac_video_set_color (sim->video, col0, col1); 1354 mac_video_set_brightness (sim->video, (255UL * bright + 500) / 1000); 1355 1356 for (i = 0; i < (w / 8) * h; i++) { 1357 mem_set_uint8 (sim->mem, sim->vbuf1 + i, 0xff); 1358 } 1359} 1360 1361void mac_init (macplus_t *sim, ini_sct_t *ini) 1362{ 1363 unsigned i; 1364 1365 sim->trm = NULL; 1366 sim->video = NULL; 1367 1368 sim->reset = 0; 1369 1370 sim->disk_id = 1; 1371 1372 sim->dcd_a = 0; 1373 sim->dcd_b = 0; 1374 1375 sim->mouse_delta_x = 0; 1376 sim->mouse_delta_y = 0; 1377 sim->mouse_button = 0; 1378 1379 sim->intr = 0; 1380 1381 sim->pause = 0; 1382 sim->brk = 0; 1383 1384 sim->speed_factor = 1; 1385 sim->speed_limit[0] = 1; 1386 sim->speed_clock_extra = 0; 1387 1388 for (i = 1; i < PCE_MAC_SPEED_CNT; i++) { 1389 sim->speed_limit[i] = 0; 1390 } 1391 1392 sim->ser_clk = 0; 1393 sim->clk_cnt = 0; 1394 1395 for (i = 0; i < 4; i++) { 1396 sim->clk_div[i] = 0; 1397 } 1398 1399 bps_init (&sim->bps); 1400 1401 mac_setup_system (sim, ini); 1402 mac_setup_mem (sim, ini); 1403 mac_setup_cpu (sim, ini); 1404 mac_setup_via (sim, ini); 1405 mac_setup_scc (sim, ini); 1406 mac_setup_serial (sim, ini); 1407 mac_setup_rtc (sim, ini); 1408 mac_setup_kbd (sim, ini); 1409 mac_setup_adb (sim, ini); 1410 mac_setup_disks (sim, ini); 1411 mac_setup_iwm (sim, ini); 1412 mac_setup_scsi (sim, ini); 1413 mac_setup_sony (sim, ini); 1414 mac_setup_sound (sim, ini); 1415 mac_setup_terminal (sim, ini); 1416 mac_setup_video (sim, ini); 1417 1418 e68_set_ram_write_fct (sim->cpu, sim, mac_ram_write); 1419 1420 pce_load_mem_ini (sim->mem, ini); 1421 1422 trm_set_msg_trm (sim->trm, "term.title", "pce-macplus"); 1423 1424 mac_clock_discontinuity (sim); 1425} 1426 1427macplus_t *mac_new (ini_sct_t *ini) 1428{ 1429 macplus_t *sim; 1430 1431 sim = malloc (sizeof (macplus_t)); 1432 if (sim == NULL) { 1433 return (NULL); 1434 } 1435 1436 mac_init (sim, ini); 1437 1438 return (sim); 1439} 1440 1441void mac_free (macplus_t *sim) 1442{ 1443 if (sim == NULL) { 1444 return; 1445 } 1446 1447 if (mac_rtc_save_file (&sim->rtc, sim->rtc_fname)) { 1448 pce_log (MSG_ERR, "*** writing rtc file failed (%s)\n", 1449 sim->rtc_fname 1450 ); 1451 } 1452 1453 free (sim->rtc_fname); 1454 1455 mac_video_del (sim->video); 1456 trm_del (sim->trm); 1457 mac_sound_free (&sim->sound); 1458 mac_sony_free (&sim->sony); 1459 mac_scsi_free (&sim->scsi); 1460 mac_iwm_free (&sim->iwm); 1461 dsks_del (sim->dsks); 1462 mac_adb_del (sim->adb); 1463 mac_kbd_del (sim->kbd); 1464 mac_rtc_free (&sim->rtc); 1465 mac_ser_free (&sim->ser[1]); 1466 mac_ser_free (&sim->ser[0]); 1467 e8530_free (&sim->scc); 1468 e6522_free (&sim->via); 1469 e68_del (sim->cpu); 1470 mem_del (sim->mem); 1471 1472 mem_blk_del (sim->ram_ovl); 1473 mem_blk_del (sim->rom_ovl); 1474 1475 bps_free (&sim->bps); 1476} 1477 1478void mac_del (macplus_t *sim) 1479{ 1480 if (sim != NULL) { 1481 mac_free (sim); 1482 free (sim); 1483 } 1484} 1485 1486 1487unsigned long long mac_get_clkcnt (macplus_t *sim) 1488{ 1489 return (sim->clk_cnt); 1490} 1491 1492void mac_clock_discontinuity (macplus_t *sim) 1493{ 1494 sim->sync_clk = 0; 1495 sim->sync_us = 0; 1496 pce_get_interval_us (&sim->sync_us); 1497 1498 sim->speed_clock_extra = 0; 1499} 1500 1501void mac_set_pause (macplus_t *sim, int pause) 1502{ 1503 sim->pause = (pause != 0); 1504 1505 if (sim->pause == 0) { 1506 mac_clock_discontinuity (sim); 1507 } 1508} 1509 1510static 1511void mac_adjust_speed (macplus_t *sim) 1512{ 1513 unsigned i, v; 1514 1515 v = 0; 1516 1517 for (i = 0; i < PCE_MAC_SPEED_CNT; i++) { 1518 if (sim->speed_limit[i] > 0) { 1519 if ((v == 0) || (sim->speed_limit[i] < v)) { 1520 v = sim->speed_limit[i]; 1521 } 1522 } 1523 } 1524 1525 if (v == sim->speed_factor) { 1526 return; 1527 } 1528 1529 mac_log_deb ("speed: %u\n", v); 1530 1531 mac_rtc_set_realtime (&sim->rtc, (v != 1)); 1532 1533 sim->speed_factor = v; 1534 sim->speed_clock_extra = 0; 1535 1536 mac_clock_discontinuity (sim); 1537} 1538 1539void mac_set_speed (macplus_t *sim, unsigned idx, unsigned factor) 1540{ 1541 if (idx >= PCE_MAC_SPEED_CNT) { 1542 return; 1543 } 1544 1545 sim->speed_limit[idx] = factor; 1546 1547 mac_adjust_speed (sim); 1548} 1549 1550int mac_set_msg_trm (macplus_t *sim, const char *msg, const char *val) 1551{ 1552 if (sim->trm == NULL) { 1553 return (1); 1554 } 1555 1556 return (trm_set_msg_trm (sim->trm, msg, val)); 1557} 1558 1559int mac_set_cpu_model (macplus_t *sim, const char *model) 1560{ 1561 if (strcmp (model, "68000") == 0) { 1562 e68_set_68000 (sim->cpu); 1563 } 1564 else if (strcmp (model, "68010") == 0) { 1565 e68_set_68010 (sim->cpu); 1566 } 1567 else if (strcmp (model, "68020") == 0) { 1568 e68_set_68020 (sim->cpu); 1569 } 1570 else { 1571 return (1); 1572 } 1573 1574 return (0); 1575} 1576 1577void mac_reset (macplus_t *sim) 1578{ 1579 if (sim->reset) { 1580 return; 1581 } 1582 1583 sim->reset = 1; 1584 1585 mac_log_deb ("mac: reset\n"); 1586 1587 sim->dcd_a = 0; 1588 sim->dcd_b = 0; 1589 1590 sim->mouse_delta_x = 0; 1591 sim->mouse_delta_y = 0; 1592 sim->mouse_button = 0; 1593 1594 sim->intr = 0; 1595 sim->intr_scsi_via = 0; 1596 1597 if (sim->model & PCE_MAC_PLUS) { 1598 mac_set_overlay (sim, 1); 1599 } 1600 else { 1601 mac_set_overlay (sim, 0); 1602 if ((sim->rom != NULL) && (sim->rom->size >= 8)) { 1603 e68_set_mem32 (sim->cpu, 0, mem_blk_get_uint32_be (sim->rom, 0)); 1604 e68_set_mem32 (sim->cpu, 4, mem_blk_get_uint32_be (sim->rom, 4)); 1605 } 1606 } 1607 1608 e6522_reset (&sim->via); 1609 1610 sim->via_port_a = 0xf7; 1611 sim->via_port_b = 0xff; 1612 1613 e6522_set_ira_inp (&sim->via, sim->via_port_a); 1614 e6522_set_irb_inp (&sim->via, sim->via_port_b); 1615 1616 mac_sony_reset (&sim->sony); 1617 mac_scsi_reset (&sim->scsi); 1618 e8530_reset (&sim->scc); 1619 1620 if (sim->adb != NULL) { 1621 adb_reset (sim->adb); 1622 } 1623 1624 e68_reset (sim->cpu); 1625 1626 mac_clock_discontinuity (sim); 1627 1628 sim->reset = 0; 1629} 1630 1631static 1632void mac_realtime_sync (macplus_t *sim, unsigned long n) 1633{ 1634 unsigned long us1, us2; 1635 1636 sim->sync_clk += n; 1637 1638 if (sim->sync_clk >= (MAC_CPU_CLOCK / MAC_CPU_SYNC)) { 1639 sim->sync_clk -= (MAC_CPU_CLOCK / MAC_CPU_SYNC); 1640 1641 us1 = pce_get_interval_us (&sim->sync_us); 1642 us2 = (1000000 / MAC_CPU_SYNC); 1643 1644 if (us1 < us2) { 1645 sim->sync_sleep += us2 - us1; 1646 1647 if (sim->sync_sleep > 0) { 1648 sim->speed_clock_extra += 1; 1649 } 1650 } 1651 else { 1652 sim->sync_sleep -= us1 - us2; 1653 1654 if (sim->sync_sleep < 0) { 1655 if (sim->speed_clock_extra > 0) { 1656 sim->speed_clock_extra -= 1; 1657 } 1658 } 1659 } 1660 1661 if (sim->sync_sleep >= MAC_CPU_SLEEP) { 1662 pce_usleep (sim->sync_sleep); 1663 } 1664 1665 if (sim->sync_sleep < -1000000) { 1666 mac_log_deb ("system too slow, skipping 1 second\n"); 1667 sim->sync_sleep += 1000000; 1668 } 1669 } 1670} 1671 1672void mac_clock_scc (macplus_t *sim, unsigned n) 1673{ 1674 /* 3.672 MHz = (15/32 * 7.8336 MHz) */ 1675 sim->ser_clk += 15 * n; 1676 1677 if (sim->ser_clk >= 32) { 1678 e8530_clock (&sim->scc, sim->ser_clk / 32); 1679 sim->ser_clk &= 31; 1680 } 1681} 1682 1683void mac_clock (macplus_t *sim, unsigned n) 1684{ 1685 unsigned long viaclk, clkdiv, cpuclk; 1686 1687 if (n == 0) { 1688 n = sim->cpu->delay; 1689 if (n == 0) { 1690 n = 1; 1691 } 1692 } 1693 1694 if (sim->speed_factor == 0) { 1695 cpuclk = n + sim->speed_clock_extra; 1696 clkdiv = 1; 1697 } 1698 else { 1699 cpuclk = n; 1700 clkdiv = sim->speed_factor; 1701 } 1702 1703 e68_clock (sim->cpu, cpuclk); 1704 1705 mac_sound_clock (&sim->sound, cpuclk); 1706 1707 sim->clk_cnt += n; 1708 1709 sim->clk_div[0] += n; 1710 1711 while (sim->clk_div[0] >= clkdiv) { 1712 sim->clk_div[1] += 1; 1713 sim->clk_div[0] -= clkdiv; 1714 } 1715 1716 if (sim->clk_div[1] < 10) { 1717 return; 1718 } 1719 1720 viaclk = sim->clk_div[1] / 10; 1721 1722 e6522_clock (&sim->via, viaclk); 1723 1724 if (sim->adb != NULL) { 1725 mac_adb_clock (sim->adb, 10 * viaclk); 1726 } 1727 1728 mac_iwm_clock (&sim->iwm, viaclk); 1729 1730 mac_clock_scc (sim, 10 * viaclk); 1731 1732 sim->clk_div[1] -= 10 * viaclk; 1733 sim->clk_div[2] += 10 * viaclk; 1734 1735 if (sim->clk_div[2] < 256) { 1736 return; 1737 } 1738 1739 mac_video_clock (sim->video, sim->clk_div[2]); 1740 1741 mac_ser_process (&sim->ser[0]); 1742 mac_ser_process (&sim->ser[1]); 1743 1744 if (sim->kbd != NULL) { 1745 mac_kbd_clock (sim->kbd, sim->clk_div[2]); 1746 } 1747 1748 sim->clk_div[3] += sim->clk_div[2]; 1749 sim->clk_div[2] = 0; 1750 1751 if (sim->clk_div[3] < 8192) { 1752 return; 1753 } 1754 1755 if (sim->trm != NULL) { 1756 trm_check (sim->trm); 1757 } 1758 1759 mac_check_mouse (sim); 1760 1761 mac_rtc_clock (&sim->rtc, sim->clk_div[3]); 1762 1763 mac_realtime_sync (sim, sim->clk_div[3]); 1764 1765 sim->clk_div[3] = 0; 1766}