trunk/src/mame/drivers/peplus.c
r17536 | r17537 | |
219 | 219 | UINT8 m_bv_busy; |
220 | 220 | UINT8 m_bv_pulse; |
221 | 221 | UINT8 m_bv_denomination; |
| 222 | UINT8 m_bv_protocol; |
222 | 223 | UINT64 m_bv_cycles; |
223 | 224 | UINT8 m_bv_last_enable_state; |
224 | 225 | UINT8 m_bv_enable_state; |
225 | 226 | UINT8 m_bv_enable_count; |
| 227 | UINT8 m_bv_data_bit; |
| 228 | UINT8 m_bv_loop_count; |
| 229 | UINT16 id023_data; |
226 | 230 | DECLARE_WRITE8_MEMBER(peplus_bgcolor_w); |
227 | 231 | DECLARE_WRITE8_MEMBER(peplus_crtc_display_w); |
228 | 232 | DECLARE_WRITE8_MEMBER(peplus_io_w); |
r17536 | r17537 | |
260 | 264 | DECLARE_DRIVER_INIT(peplussbw); |
261 | 265 | }; |
262 | 266 | |
| 267 | static const UINT8 id_022[8] = { 0x00, 0x01, 0x04, 0x09, 0x13, 0x16, 0x18, 0x00 }; |
| 268 | static const UINT16 id_023[8] = { 0x4a6c, 0x4a7b, 0x4a4b, 0x4a5a, 0x4a2b, 0x4a0a, 0x4a19, 0x4a3a }; |
263 | 269 | |
264 | 270 | #define MASTER_CLOCK XTAL_20MHz |
265 | 271 | #define CPU_CLOCK ((MASTER_CLOCK)/2) /* divided by 2 - 7474 */ |
r17536 | r17537 | |
573 | 579 | READ8_MEMBER(peplus_state::peplus_input0_r) |
574 | 580 | { |
575 | 581 | /* |
| 582 | PE+ bill validators have a dip switch setting to switch between ID-022 and ID-023 protocols. |
| 583 | |
576 | 584 | Emulating IGT IDO22 Pulse Protocol (IGT Smoke 2.2) |
577 | | ID022 protocol requires a 20ms on/off pulse x times for denomination followed by a 50ms stop pulse. |
578 | | The DBV then waits for at least 3 toggling (ACK) pulses of alternating 20ms each from the game. |
579 | | If no toggling received within 200ms, the bill was rejected by the game (e.g. Max Credits reached). |
580 | | Once toggling received, the DBV stacks the bill and sends two 10ms stacked pulses separated by a 10ms pause. |
| 585 | ID022 protocol requires a 20ms on/off pulse x times for denomination followed by a 50ms stop pulse. |
| 586 | The DBV then waits for at least 3 toggling (ACK) pulses of alternating 20ms each from the game. |
| 587 | If no toggling received within 200ms, the bill was rejected by the game (e.g. Max Credits reached). |
| 588 | Once toggling received, the DBV stacks the bill and sends a 10ms stacked pulses. |
581 | 589 | |
582 | | TODO: Will need to include IGT IDO23 (IGT 2.5) for Superboard games. |
583 | | PE+ bill validators have a dip switch setting to switch between ID-022 and ID-023 protocols. |
| 590 | Emulating IGT IDO23 Pulse Protocol (IGT 2.5) |
| 591 | ID023 protocol requires a start pulse of 50ms ON followed by a 20ms pause. Next a 15-bit data stream |
| 592 | is sent based on the country code and denomination (see table below). And finally a 90ms stop pulse. |
| 593 | There is then a 200ms pause and the entire sequence is transmitted again two more times. |
| 594 | The DBV then waits for the toggling much like the ID-022 protocol above, however ends with two 10ms |
| 595 | stack pulses instead of one. |
584 | 596 | |
585 | | IDO23 Denomination Codes |
586 | | ------------------------ |
587 | | 0x00 = $1 |
588 | | 0x02 = $5 |
589 | | 0x03 = $10 |
590 | | 0x04 = $20 |
591 | | 0x06 = $50 |
592 | | 0x07 = $100 |
| 597 | Ticket handling has not been emulated. |
593 | 598 | |
594 | | IDO23 Country Codes |
595 | | ------------------------ |
596 | | 0x25(37) = USA |
| 599 | IDO23 Country Codes |
| 600 | ------------------- |
| 601 | 0x07 = Canada |
| 602 | 0x25 = USA |
597 | 603 | |
| 604 | IDO23 USA 15-bit Data Samples: |
| 605 | ---------+--------------+--------------+-----------+ |
| 606 | Bill Amt | Country Code | Denom Code | Checksum | |
| 607 | ---------+--------------+--------------+-----------+ |
| 608 | $1 | 1 0 0 1 0 1 | 0 0 1 1 0 | 1 1 0 0 | |
| 609 | $2 | 1 0 0 1 0 1 | 0 0 1 1 1 | 1 0 1 1 | |
| 610 | $5 | 1 0 0 1 0 1 | 0 0 1 0 0 | 1 0 1 1 | |
| 611 | $10 | 1 0 0 1 0 1 | 0 0 1 0 1 | 1 0 1 0 | |
| 612 | $20 | 1 0 0 1 0 1 | 0 0 0 1 0 | 1 0 1 1 | |
| 613 | $50 | 1 0 0 1 0 1 | 0 0 0 0 0 | 1 0 1 0 | |
| 614 | $100 | 1 0 0 1 0 1 | 0 0 0 0 1 | 1 0 0 1 | |
| 615 | Ticket | 1 0 0 1 0 1 | 0 0 0 1 1 | 1 0 1 0 | |
| 616 | ---------+--------------+--------------+-----------+ |
| 617 | |
598 | 618 | Direction Data |
599 | 619 | -------------- |
600 | 620 | A (FA) <-- [FRONT OF BILL] --> (FB) B |
r17536 | r17537 | |
606 | 626 | */ |
607 | 627 | UINT64 curr_cycles = machine().firstcpu->total_cycles(); |
608 | 628 | |
609 | | if ((ioport("DBV")->read_safe(0xff) & 0x01) == 0x00) { |
| 629 | // Allow Bill Insert if DBV Enabled |
| 630 | if (m_bv_enable_state == 0x01 && ((ioport("DBV")->read_safe(0xff) & 0x01) == 0x00)) { |
610 | 631 | // If not busy |
611 | 632 | if (m_bv_busy == 0) { |
612 | 633 | m_bv_busy = 1; |
613 | 634 | |
614 | | // Fetch Current Denomination |
| 635 | // Fetch Current Denomination and Protocol |
615 | 636 | m_bv_denomination = ioport("BC")->read(); |
| 637 | m_bv_protocol = ioport("BP")->read(); |
616 | 638 | |
617 | | m_bv_cycles = curr_cycles; |
| 639 | if (m_bv_protocol == 0) { |
| 640 | // ID-022 |
| 641 | m_bv_denomination = id_022[m_bv_denomination]; |
| 642 | |
| 643 | if (m_bv_denomination == 0) |
| 644 | m_bv_state = 0x03; // $1 So Skip Credit Pulse |
| 645 | else |
| 646 | m_bv_state = 0x01; // Greater than $1 Needs Credit Pulse |
| 647 | } else { |
| 648 | // ID-023 |
| 649 | id023_data = id_023[m_bv_denomination]; |
| 650 | |
| 651 | m_bv_data_bit = 14; |
| 652 | m_bv_loop_count = 0; |
| 653 | |
| 654 | m_bv_state = 0x11; |
| 655 | } |
| 656 | |
| 657 | m_bv_cycles = curr_cycles; |
618 | 658 | m_bv_pulse = 1; |
619 | | |
620 | | if (m_bv_denomination == 0) |
621 | | m_bv_state = 3; // $1 So Skip Credit Pulse |
622 | | else |
623 | | m_bv_state = 1; // Greater than $1 Needs Credit Pulse |
| 659 | m_bv_enable_count = 0; |
624 | 660 | } |
625 | 661 | } |
626 | 662 | |
r17536 | r17537 | |
642 | 678 | m_bv_pulse = 1; |
643 | 679 | |
644 | 680 | m_bv_denomination--; |
645 | | |
| 681 | |
646 | 682 | if (m_bv_denomination == 0) |
647 | 683 | m_bv_state++; // Done with Credit Pulse |
648 | 684 | else |
649 | | m_bv_state = 1; // Continue Pulsing Denomination |
| 685 | m_bv_state = 0x01; // Continue Pulsing Denomination |
650 | 686 | } |
651 | 687 | break; |
652 | 688 | case 0x03: // Stop Pulse 50ms ON |
r17536 | r17537 | |
676 | 712 | // No Toggling Found, Game Rejected Bill |
677 | 713 | if (curr_cycles - m_bv_cycles >= 833.3 * 200) { |
678 | 714 | m_bv_pulse = 0; |
679 | | m_bv_state = 0; |
| 715 | m_bv_state = 0x00; |
680 | 716 | } |
681 | 717 | } |
682 | 718 | break; |
r17536 | r17537 | |
684 | 720 | if (curr_cycles - m_bv_cycles >= 833.3 * 10) { |
685 | 721 | m_bv_cycles = curr_cycles; |
686 | 722 | m_bv_pulse = 0; |
| 723 | m_bv_state = 0x00; |
| 724 | } |
| 725 | break; |
| 726 | case 0x11: // Start Pulse 50ms ON |
| 727 | if (curr_cycles - m_bv_cycles >= 833.3 * 50) { |
| 728 | m_bv_cycles = curr_cycles; |
| 729 | m_bv_pulse = 0; |
687 | 730 | m_bv_state++; |
688 | 731 | } |
689 | 732 | break; |
690 | | case 0x06: // Stacked Pulse 10ms OFF |
| 733 | case 0x12: // Start Pulse 20ms OFF |
| 734 | if (curr_cycles - m_bv_cycles >= 833.3 * 20) { |
| 735 | m_bv_cycles = curr_cycles; |
| 736 | m_bv_pulse = 1; |
| 737 | m_bv_state++; |
| 738 | } |
| 739 | break; |
| 740 | case 0x13: // Data Sync Pulse 20ms ON |
| 741 | if (curr_cycles - m_bv_cycles >= 833.3 * 20) { |
| 742 | m_bv_cycles = curr_cycles; |
| 743 | m_bv_pulse = 1 - ((id023_data >> m_bv_data_bit) & 0x01); |
| 744 | m_bv_state++; |
| 745 | } |
| 746 | break; |
| 747 | case 0x14: // Data Value Pulse 20ms OFF |
| 748 | if (curr_cycles - m_bv_cycles >= 833.3 * 20) { |
| 749 | m_bv_cycles = curr_cycles; |
| 750 | m_bv_pulse = 1; |
| 751 | |
| 752 | if (m_bv_data_bit == 0) { |
| 753 | m_bv_data_bit = 14; // Done with Data Stream |
| 754 | m_bv_state++; |
| 755 | } else { |
| 756 | m_bv_data_bit--; |
| 757 | m_bv_state = 0x13; // More Data Yet |
| 758 | } |
| 759 | } |
| 760 | break; |
| 761 | case 0x15: // Stop Pulse 90ms ON |
| 762 | if (curr_cycles - m_bv_cycles >= 833.3 * 90) { |
| 763 | m_bv_cycles = curr_cycles; |
| 764 | m_bv_pulse = 0; |
| 765 | |
| 766 | if (m_bv_loop_count >= 2) { |
| 767 | m_bv_state = 0x17; // Done, Ready for Toggling |
| 768 | } else { |
| 769 | m_bv_loop_count++; |
| 770 | m_bv_state++; |
| 771 | } |
| 772 | } |
| 773 | break; |
| 774 | case 0x16: // Repeat Pulse 200ms OFF |
| 775 | if (curr_cycles - m_bv_cycles >= 833.3 * 200) { |
| 776 | m_bv_cycles = curr_cycles; |
| 777 | m_bv_pulse = 1; |
| 778 | m_bv_state = 0x11; // Repeat from Start |
| 779 | } |
| 780 | break; |
| 781 | case 0x17: // Begin Toggle Polling |
| 782 | if (m_bv_enable_state != m_bv_last_enable_state) { |
| 783 | m_bv_enable_count++; |
| 784 | m_bv_last_enable_state = m_bv_enable_state; |
| 785 | |
| 786 | // Got Enough Toggles, Advance to Stacking |
| 787 | if (m_bv_enable_count == 0x03) { |
| 788 | m_bv_cycles = curr_cycles; |
| 789 | m_bv_pulse = 1; |
| 790 | m_bv_state++; |
| 791 | } |
| 792 | } else { |
| 793 | // No Toggling Found, Game Rejected Bill |
| 794 | if (curr_cycles - m_bv_cycles >= 833.3 * 200) { |
| 795 | m_bv_pulse = 0; |
| 796 | m_bv_state = 0x00; |
| 797 | } |
| 798 | } |
| 799 | break; |
| 800 | case 0x18: // Stacked Pulse 10ms ON |
691 | 801 | if (curr_cycles - m_bv_cycles >= 833.3 * 10) { |
692 | 802 | m_bv_cycles = curr_cycles; |
| 803 | m_bv_pulse = 0; |
| 804 | m_bv_state++; |
| 805 | } |
| 806 | break; |
| 807 | case 0x19: // Stacked Pulse 10ms OFF |
| 808 | if (curr_cycles - m_bv_cycles >= 833.3 * 10) { |
| 809 | m_bv_cycles = curr_cycles; |
693 | 810 | m_bv_pulse = 1; |
694 | 811 | m_bv_state++; |
695 | 812 | } |
696 | 813 | break; |
697 | | case 0x07: // Stacked Pulse 10ms ON |
| 814 | case 0x1a: // Stacked Pulse 10ms ON |
698 | 815 | if (curr_cycles - m_bv_cycles >= 833.3 * 10) { |
699 | 816 | m_bv_cycles = curr_cycles; |
700 | 817 | m_bv_pulse = 0; |
701 | | m_bv_state = 0; |
| 818 | m_bv_state = 0x00; |
702 | 819 | } |
703 | 820 | break; |
704 | 821 | } |
r17536 | r17537 | |
1006 | 1123 | PORT_CONFNAME( 0x1f, 0x00, "Bill Choices" ) |
1007 | 1124 | PORT_CONFSETTING( 0x00, "$1" ) |
1008 | 1125 | PORT_CONFSETTING( 0x01, "$2" ) |
1009 | | PORT_CONFSETTING( 0x04, "$5" ) |
1010 | | PORT_CONFSETTING( 0x09, "$10" ) |
1011 | | PORT_CONFSETTING( 0x13, "$20" ) |
1012 | | PORT_CONFSETTING( 0x16, "$50" ) |
1013 | | PORT_CONFSETTING( 0x18, "$100" ) |
| 1126 | PORT_CONFSETTING( 0x02, "$5" ) |
| 1127 | PORT_CONFSETTING( 0x03, "$10" ) |
| 1128 | PORT_CONFSETTING( 0x04, "$20" ) |
| 1129 | PORT_CONFSETTING( 0x05, "$50" ) |
| 1130 | PORT_CONFSETTING( 0x06, "$100" ) |
| 1131 | |
| 1132 | PORT_START("BP") |
| 1133 | PORT_CONFNAME( 0x1f, 0x00, "Bill Protocol" ) |
| 1134 | PORT_CONFSETTING( 0x00, "ID-022" ) |
| 1135 | PORT_CONFSETTING( 0x01, "ID-023" ) |
1014 | 1136 | |
1015 | 1137 | PORT_START("SW1") |
1016 | 1138 | PORT_DIPNAME( 0x01, 0x01, "Line Frequency" ) |