trunk/src/mess/drivers/px4.c
r241689 | r241690 | |
21 | 21 | #include "sound/speaker.h" |
22 | 22 | #include "bus/generic/slot.h" |
23 | 23 | #include "bus/generic/carts.h" |
| 24 | #include "coreutil.h" |
24 | 25 | #include "px4.lh" |
25 | 26 | |
26 | 27 | |
r241689 | r241690 | |
70 | 71 | m_swr(0), |
71 | 72 | m_one_sec_int_enabled(true), m_alarm_int_enabled(true), m_key_int_enabled(true), |
72 | 73 | m_key_status(0), m_interrupt_status(0), |
| 74 | m_time(), m_clock_state(0), |
73 | 75 | m_ear_last_state(0), |
74 | 76 | m_sio_pin(0), m_serial_rx(0), m_rs232_dcd(0), m_rs232_cts(0), |
75 | 77 | m_centronics_busy(0), m_centronics_perror(0) |
r241689 | r241690 | |
230 | 232 | UINT8 m_key_status; |
231 | 233 | UINT8 m_interrupt_status; |
232 | 234 | |
| 235 | system_time m_time; |
| 236 | int m_clock_state; |
| 237 | |
233 | 238 | // external cassette/barcode reader |
234 | 239 | int m_ear_last_state; |
235 | 240 | |
r241689 | r241690 | |
553 | 558 | if (0) |
554 | 559 | logerror("%s: sior_r 0x%02x\n", machine().describe_context(), m_sior); |
555 | 560 | |
| 561 | // reading clock? |
| 562 | if (m_clock_state > 0) |
| 563 | { |
| 564 | switch (m_clock_state++) |
| 565 | { |
| 566 | case 1: m_sior = (dec_2_bcd(m_time.local_time.year) >> 4) & 0xf; break; |
| 567 | case 2: m_sior = dec_2_bcd(m_time.local_time.year) & 0xf; break; |
| 568 | case 3: m_sior = dec_2_bcd(m_time.local_time.month + 1); break; |
| 569 | case 4: m_sior = dec_2_bcd(m_time.local_time.mday); break; |
| 570 | case 5: m_sior = dec_2_bcd(m_time.local_time.hour); break; |
| 571 | case 6: m_sior = dec_2_bcd(m_time.local_time.minute); break; |
| 572 | case 7: m_sior = dec_2_bcd(m_time.local_time.second); break; |
| 573 | case 8: m_sior = dec_2_bcd(m_time.local_time.weekday); break; |
| 574 | } |
| 575 | |
| 576 | // done? |
| 577 | if (m_clock_state == 9) |
| 578 | m_clock_state = 0; |
| 579 | } |
| 580 | |
556 | 581 | return m_sior; |
557 | 582 | } |
558 | 583 | |
r241689 | r241690 | |
562 | 587 | if (0) |
563 | 588 | logerror("%s: sior_w (0x%02x)\n", machine().describe_context(), data); |
564 | 589 | |
565 | | m_sior = data; |
566 | | |
567 | | switch (data) |
| 590 | // writing clock? |
| 591 | if (m_clock_state > 0) |
568 | 592 | { |
569 | | case 0x01: |
| 593 | struct tm *t = localtime(&m_time.time); |
570 | 594 | |
571 | | if (VERBOSE) |
572 | | logerror("7508 cmd: Power OFF\n"); |
| 595 | switch (m_clock_state++) |
| 596 | { |
| 597 | case 1: |
| 598 | { |
| 599 | int year = dec_2_bcd(m_time.local_time.year); |
| 600 | year = (year & 0xff0f) | ((data & 0xf) << 4); |
| 601 | t->tm_year = bcd_2_dec(year) - 1900; |
| 602 | } |
| 603 | break; |
| 604 | case 2: |
| 605 | { |
| 606 | int year = dec_2_bcd(m_time.local_time.year); |
| 607 | year = (year & 0xfff0) | (data & 0xf); |
| 608 | t->tm_year = bcd_2_dec(year) - 1900; |
| 609 | } |
| 610 | break; |
| 611 | case 3: t->tm_mon = bcd_2_dec(data & 0x7f) - 1; break; |
| 612 | case 4: t->tm_mday = bcd_2_dec(data & 0x7f); break; |
| 613 | case 5: t->tm_hour = bcd_2_dec(data & 0x7f); break; |
| 614 | case 6: t->tm_min = bcd_2_dec(data & 0x7f); break; |
| 615 | case 7: t->tm_sec = bcd_2_dec(data & 0x7f); break; |
| 616 | case 8: t->tm_wday = bcd_2_dec(data & 0x7f); break; |
| 617 | } |
573 | 618 | |
574 | | break; |
| 619 | // update |
| 620 | m_time.set(mktime(t)); |
575 | 621 | |
576 | | case 0x02: |
| 622 | // done? |
| 623 | if (m_clock_state == 9) |
| 624 | m_clock_state = 0; |
| 625 | } |
| 626 | else |
| 627 | { |
| 628 | m_sior = data; |
577 | 629 | |
578 | | if (VERBOSE) |
579 | | logerror("7508 cmd: Read Status\n"); |
580 | | |
581 | | if (m_interrupt_status != 0) |
| 630 | switch (data) |
582 | 631 | { |
| 632 | case 0x01: |
583 | 633 | if (VERBOSE) |
584 | | logerror("> 7508 has interrupts pending: 0x%02x\n", m_interrupt_status); |
| 634 | logerror("7508 cmd: Power OFF\n"); |
585 | 635 | |
586 | | // signal the interrupt(s) |
587 | | m_sior = 0xc1 | m_interrupt_status; |
588 | | m_interrupt_status = 0x00; |
589 | | } |
590 | | else if (m_key_status != 0xff) |
591 | | { |
592 | | m_sior = m_key_status; |
593 | | m_key_status = 0xff; |
594 | | } |
595 | | else |
596 | | { |
597 | | // nothing happened |
598 | | m_sior = 0xbf; |
599 | | } |
| 636 | break; |
600 | 637 | |
601 | | break; |
| 638 | case 0x02: |
| 639 | if (VERBOSE) |
| 640 | logerror("7508 cmd: Read Status\n"); |
602 | 641 | |
603 | | case 0x03: if (VERBOSE) logerror("7508 cmd: KB Reset\n"); break; |
604 | | case 0x04: if (VERBOSE) logerror("7508 cmd: KB Repeat Timer 1 Set\n"); break; |
605 | | case 0x14: if (VERBOSE) logerror("7508 cmd: KB Repeat Timer 2 Set\n"); break; |
606 | | case 0x24: if (VERBOSE) logerror("7508 cmd: KB Repeat Timer 1 Read\n"); break; |
607 | | case 0x34: if (VERBOSE) logerror("7508 cmd: KB Repeat Timer 2 Read\n"); break; |
608 | | case 0x05: if (VERBOSE) logerror("7508 cmd: KB Repeat OFF\n"); break; |
609 | | case 0x15: if (VERBOSE) logerror("7508 cmd: KB Repeat ON\n"); break; |
| 642 | if (m_interrupt_status != 0) |
| 643 | { |
| 644 | if (VERBOSE) |
| 645 | logerror("> 7508 has interrupts pending: 0x%02x\n", m_interrupt_status); |
610 | 646 | |
611 | | case 0x06: |
| 647 | // signal the interrupt(s) |
| 648 | m_sior = 0xc1 | m_interrupt_status; |
| 649 | m_interrupt_status = 0x00; |
| 650 | } |
| 651 | else if (m_key_status != 0xff) |
| 652 | { |
| 653 | m_sior = m_key_status; |
| 654 | m_key_status = 0xff; |
| 655 | } |
| 656 | else |
| 657 | { |
| 658 | // nothing happened |
| 659 | m_sior = 0xbf; |
| 660 | } |
612 | 661 | |
613 | | if (VERBOSE) |
614 | | logerror("7508 cmd: KB Interrupt OFF\n"); |
| 662 | break; |
615 | 663 | |
616 | | m_key_int_enabled = false; |
617 | | break; |
| 664 | case 0x03: if (VERBOSE) logerror("7508 cmd: KB Reset\n"); break; |
| 665 | case 0x04: if (VERBOSE) logerror("7508 cmd: KB Repeat Timer 1 Set\n"); break; |
| 666 | case 0x14: if (VERBOSE) logerror("7508 cmd: KB Repeat Timer 2 Set\n"); break; |
| 667 | case 0x24: if (VERBOSE) logerror("7508 cmd: KB Repeat Timer 1 Read\n"); break; |
| 668 | case 0x34: if (VERBOSE) logerror("7508 cmd: KB Repeat Timer 2 Read\n"); break; |
| 669 | case 0x05: if (VERBOSE) logerror("7508 cmd: KB Repeat OFF\n"); break; |
| 670 | case 0x15: if (VERBOSE) logerror("7508 cmd: KB Repeat ON\n"); break; |
618 | 671 | |
619 | | case 0x16: |
| 672 | case 0x06: |
| 673 | if (VERBOSE) |
| 674 | logerror("7508 cmd: KB Interrupt OFF\n"); |
620 | 675 | |
621 | | if (VERBOSE) |
622 | | logerror("7508 cmd: KB Interrupt ON\n"); |
| 676 | m_key_int_enabled = false; |
| 677 | break; |
623 | 678 | |
624 | | m_key_int_enabled = true; |
625 | | break; |
| 679 | case 0x16: |
| 680 | if (VERBOSE) |
| 681 | logerror("7508 cmd: KB Interrupt ON\n"); |
626 | 682 | |
627 | | case 0x07: if (VERBOSE) logerror("7508 cmd: Clock Read\n"); break; |
628 | | case 0x17: if (VERBOSE) logerror("7508 cmd: Clock Write\n"); break; |
| 683 | m_key_int_enabled = true; |
| 684 | break; |
629 | 685 | |
630 | | case 0x08: |
| 686 | case 0x07: |
| 687 | if (VERBOSE) |
| 688 | logerror("7508 cmd: Clock Read\n"); |
631 | 689 | |
632 | | if (VERBOSE) |
633 | | logerror("7508 cmd: Power Switch Read\n"); |
| 690 | m_clock_state = 1; |
| 691 | break; |
634 | 692 | |
635 | | // indicate that the power switch is in the "ON" position |
636 | | m_sior = 0x01; |
637 | | break; |
| 693 | case 0x17: |
| 694 | if (VERBOSE) |
| 695 | logerror("7508 cmd: Clock Write\n"); |
638 | 696 | |
639 | | case 0x09: if (VERBOSE) logerror("7508 cmd: Alarm Read\n"); break; |
640 | | case 0x19: if (VERBOSE) logerror("7508 cmd: Alarm Set\n"); break; |
641 | | case 0x29: if (VERBOSE) logerror("7508 cmd: Alarm OFF\n"); break; |
642 | | case 0x39: if (VERBOSE) logerror("7508 cmd: Alarm ON\n"); break; |
| 697 | m_clock_state = 1; |
| 698 | break; |
643 | 699 | |
644 | | case 0x0a: |
| 700 | case 0x08: |
| 701 | if (VERBOSE) |
| 702 | logerror("7508 cmd: Power Switch Read\n"); |
645 | 703 | |
646 | | if (VERBOSE) |
647 | | logerror("7508 cmd: DIP Switch Read\n"); |
648 | | m_sior = ioport("dips")->read(); |
649 | | break; |
| 704 | // indicate that the power switch is in the "ON" position |
| 705 | m_sior = 0x01; |
| 706 | break; |
650 | 707 | |
651 | | case 0x0b: if (VERBOSE) logerror("7508 cmd: Stop Key Interrupt disable\n"); break; |
652 | | case 0x1b: if (VERBOSE) logerror("7508 cmd: Stop Key Interrupt enable\n"); break; |
653 | | case 0x0c: if (VERBOSE) logerror("7508 cmd: 7 chr. Buffer\n"); break; |
654 | | case 0x1c: if (VERBOSE) logerror("7508 cmd: 1 chr. Buffer\n"); break; |
| 708 | case 0x09: if (VERBOSE) logerror("7508 cmd: Alarm Read\n"); break; |
| 709 | case 0x19: if (VERBOSE) logerror("7508 cmd: Alarm Set\n"); break; |
| 710 | case 0x29: if (VERBOSE) logerror("7508 cmd: Alarm OFF\n"); break; |
| 711 | case 0x39: if (VERBOSE) logerror("7508 cmd: Alarm ON\n"); break; |
655 | 712 | |
656 | | case 0x0d: |
| 713 | case 0x0a: |
| 714 | if (VERBOSE) |
| 715 | logerror("7508 cmd: DIP Switch Read\n"); |
| 716 | m_sior = ioport("dips")->read(); |
| 717 | break; |
657 | 718 | |
658 | | if (VERBOSE) |
659 | | logerror("7508 cmd: 1 sec. Interrupt OFF\n"); |
| 719 | case 0x0b: if (VERBOSE) logerror("7508 cmd: Stop Key Interrupt disable\n"); break; |
| 720 | case 0x1b: if (VERBOSE) logerror("7508 cmd: Stop Key Interrupt enable\n"); break; |
| 721 | case 0x0c: if (VERBOSE) logerror("7508 cmd: 7 chr. Buffer\n"); break; |
| 722 | case 0x1c: if (VERBOSE) logerror("7508 cmd: 1 chr. Buffer\n"); break; |
660 | 723 | |
661 | | m_one_sec_int_enabled = false; |
662 | | break; |
| 724 | case 0x0d: |
| 725 | if (VERBOSE) |
| 726 | logerror("7508 cmd: 1 sec. Interrupt OFF\n"); |
663 | 727 | |
664 | | case 0x1d: |
| 728 | m_one_sec_int_enabled = false; |
| 729 | break; |
665 | 730 | |
666 | | if (VERBOSE) |
667 | | logerror("7508 cmd: 1 sec. Interrupt ON\n"); |
| 731 | case 0x1d: |
| 732 | if (VERBOSE) |
| 733 | logerror("7508 cmd: 1 sec. Interrupt ON\n"); |
668 | 734 | |
669 | | m_one_sec_int_enabled = true; |
670 | | break; |
| 735 | m_one_sec_int_enabled = true; |
| 736 | break; |
671 | 737 | |
672 | | case 0x0e: |
| 738 | case 0x0e: |
| 739 | if (VERBOSE) |
| 740 | logerror("7508 cmd: KB Clear\n"); |
673 | 741 | |
674 | | if (VERBOSE) |
675 | | logerror("7508 cmd: KB Clear\n"); |
| 742 | m_sior = 0xbf; |
| 743 | break; |
676 | 744 | |
677 | | m_sior = 0xbf; |
678 | | break; |
679 | | |
680 | | case 0x0f: if (VERBOSE) logerror("7508 cmd: System Reset\n"); break; |
| 745 | case 0x0f: if (VERBOSE) logerror("7508 cmd: System Reset\n"); break; |
| 746 | } |
681 | 747 | } |
682 | 748 | } |
683 | 749 | |
r241689 | r241690 | |
1000 | 1066 | m_isr |= INT0_7508; |
1001 | 1067 | gapnit_interrupt(); |
1002 | 1068 | } |
| 1069 | |
| 1070 | // update clock |
| 1071 | m_time.set(m_time.time + 1); |
1003 | 1072 | } |
1004 | 1073 | |
1005 | 1074 | INPUT_CHANGED_MEMBER( px4_state::key_callback ) |
r241689 | r241690 | |
1163 | 1232 | m_caps2_rom = memregion(region_tag.cpy(m_caps2->tag()).cat(GENERIC_ROM_REGION_TAG)); |
1164 | 1233 | |
1165 | 1234 | m_nvram->set_base(m_ram->pointer(), 0x10000); |
| 1235 | |
| 1236 | // initialize clock |
| 1237 | machine().base_datetime(m_time); |
1166 | 1238 | } |
1167 | 1239 | |
1168 | 1240 | void px4_state::machine_reset() |