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() |