From e6ed765304c33449adfd0e334e0d62f161c82e92 Mon Sep 17 00:00:00 2001 From: Jim Stolis Date: Tue, 28 Aug 2012 16:00:57 +0000 Subject: [PATCH] Added IGT ID-023 Protocol to driver. This additional DBV protocol allows all remaining unsupported sets to accept dollar bills in-game. The protocol is switchable via driver configuration (along with denomination). [Jim Stolis] --- src/mame/drivers/peplus.c | 194 +++++++++++++++++++++++++++++++------- 1 file changed, 158 insertions(+), 36 deletions(-) diff --git a/src/mame/drivers/peplus.c b/src/mame/drivers/peplus.c index 7406c105f41..f3507e676e9 100644 --- a/src/mame/drivers/peplus.c +++ b/src/mame/drivers/peplus.c @@ -219,10 +219,14 @@ public: UINT8 m_bv_busy; UINT8 m_bv_pulse; UINT8 m_bv_denomination; + UINT8 m_bv_protocol; UINT64 m_bv_cycles; UINT8 m_bv_last_enable_state; UINT8 m_bv_enable_state; UINT8 m_bv_enable_count; + UINT8 m_bv_data_bit; + UINT8 m_bv_loop_count; + UINT16 id023_data; DECLARE_WRITE8_MEMBER(peplus_bgcolor_w); DECLARE_WRITE8_MEMBER(peplus_crtc_display_w); DECLARE_WRITE8_MEMBER(peplus_io_w); @@ -260,6 +264,8 @@ public: DECLARE_DRIVER_INIT(peplussbw); }; +static const UINT8 id_022[8] = { 0x00, 0x01, 0x04, 0x09, 0x13, 0x16, 0x18, 0x00 }; +static const UINT16 id_023[8] = { 0x4a6c, 0x4a7b, 0x4a4b, 0x4a5a, 0x4a2b, 0x4a0a, 0x4a19, 0x4a3a }; #define MASTER_CLOCK XTAL_20MHz #define CPU_CLOCK ((MASTER_CLOCK)/2) /* divided by 2 - 7474 */ @@ -573,27 +579,41 @@ READ8_MEMBER(peplus_state::peplus_watchdog_r) READ8_MEMBER(peplus_state::peplus_input0_r) { /* + PE+ bill validators have a dip switch setting to switch between ID-022 and ID-023 protocols. + Emulating IGT IDO22 Pulse Protocol (IGT Smoke 2.2) - ID022 protocol requires a 20ms on/off pulse x times for denomination followed by a 50ms stop pulse. - The DBV then waits for at least 3 toggling (ACK) pulses of alternating 20ms each from the game. - If no toggling received within 200ms, the bill was rejected by the game (e.g. Max Credits reached). - Once toggling received, the DBV stacks the bill and sends two 10ms stacked pulses separated by a 10ms pause. + ID022 protocol requires a 20ms on/off pulse x times for denomination followed by a 50ms stop pulse. + The DBV then waits for at least 3 toggling (ACK) pulses of alternating 20ms each from the game. + If no toggling received within 200ms, the bill was rejected by the game (e.g. Max Credits reached). + Once toggling received, the DBV stacks the bill and sends a 10ms stacked pulses. - TODO: Will need to include IGT IDO23 (IGT 2.5) for Superboard games. - PE+ bill validators have a dip switch setting to switch between ID-022 and ID-023 protocols. + Emulating IGT IDO23 Pulse Protocol (IGT 2.5) + ID023 protocol requires a start pulse of 50ms ON followed by a 20ms pause. Next a 15-bit data stream + is sent based on the country code and denomination (see table below). And finally a 90ms stop pulse. + There is then a 200ms pause and the entire sequence is transmitted again two more times. + The DBV then waits for the toggling much like the ID-022 protocol above, however ends with two 10ms + stack pulses instead of one. - IDO23 Denomination Codes - ------------------------ - 0x00 = $1 - 0x02 = $5 - 0x03 = $10 - 0x04 = $20 - 0x06 = $50 - 0x07 = $100 + Ticket handling has not been emulated. - IDO23 Country Codes - ------------------------ - 0x25(37) = USA + IDO23 Country Codes + ------------------- + 0x07 = Canada + 0x25 = USA + + IDO23 USA 15-bit Data Samples: + ---------+--------------+--------------+-----------+ + Bill Amt | Country Code | Denom Code | Checksum | + ---------+--------------+--------------+-----------+ + $1 | 1 0 0 1 0 1 | 0 0 1 1 0 | 1 1 0 0 | + $2 | 1 0 0 1 0 1 | 0 0 1 1 1 | 1 0 1 1 | + $5 | 1 0 0 1 0 1 | 0 0 1 0 0 | 1 0 1 1 | + $10 | 1 0 0 1 0 1 | 0 0 1 0 1 | 1 0 1 0 | + $20 | 1 0 0 1 0 1 | 0 0 0 1 0 | 1 0 1 1 | + $50 | 1 0 0 1 0 1 | 0 0 0 0 0 | 1 0 1 0 | + $100 | 1 0 0 1 0 1 | 0 0 0 0 1 | 1 0 0 1 | + Ticket | 1 0 0 1 0 1 | 0 0 0 1 1 | 1 0 1 0 | + ---------+--------------+--------------+-----------+ Direction Data -------------- @@ -606,21 +626,37 @@ READ8_MEMBER(peplus_state::peplus_input0_r) */ UINT64 curr_cycles = machine().firstcpu->total_cycles(); - if ((ioport("DBV")->read_safe(0xff) & 0x01) == 0x00) { + // Allow Bill Insert if DBV Enabled + if (m_bv_enable_state == 0x01 && ((ioport("DBV")->read_safe(0xff) & 0x01) == 0x00)) { // If not busy if (m_bv_busy == 0) { m_bv_busy = 1; - // Fetch Current Denomination + // Fetch Current Denomination and Protocol m_bv_denomination = ioport("BC")->read(); + m_bv_protocol = ioport("BP")->read(); - m_bv_cycles = curr_cycles; + if (m_bv_protocol == 0) { + // ID-022 + m_bv_denomination = id_022[m_bv_denomination]; + + if (m_bv_denomination == 0) + m_bv_state = 0x03; // $1 So Skip Credit Pulse + else + m_bv_state = 0x01; // Greater than $1 Needs Credit Pulse + } else { + // ID-023 + id023_data = id_023[m_bv_denomination]; + + m_bv_data_bit = 14; + m_bv_loop_count = 0; + + m_bv_state = 0x11; + } + + m_bv_cycles = curr_cycles; m_bv_pulse = 1; - - if (m_bv_denomination == 0) - m_bv_state = 3; // $1 So Skip Credit Pulse - else - m_bv_state = 1; // Greater than $1 Needs Credit Pulse + m_bv_enable_count = 0; } } @@ -642,11 +678,11 @@ READ8_MEMBER(peplus_state::peplus_input0_r) m_bv_pulse = 1; m_bv_denomination--; - + if (m_bv_denomination == 0) m_bv_state++; // Done with Credit Pulse else - m_bv_state = 1; // Continue Pulsing Denomination + m_bv_state = 0x01; // Continue Pulsing Denomination } break; case 0x03: // Stop Pulse 50ms ON @@ -676,29 +712,110 @@ READ8_MEMBER(peplus_state::peplus_input0_r) // No Toggling Found, Game Rejected Bill if (curr_cycles - m_bv_cycles >= 833.3 * 200) { m_bv_pulse = 0; - m_bv_state = 0; + m_bv_state = 0x00; } } break; case 0x05: // Stacked Pulse 10ms ON if (curr_cycles - m_bv_cycles >= 833.3 * 10) { + m_bv_cycles = curr_cycles; + m_bv_pulse = 0; + m_bv_state = 0x00; + } + break; + case 0x11: // Start Pulse 50ms ON + if (curr_cycles - m_bv_cycles >= 833.3 * 50) { m_bv_cycles = curr_cycles; m_bv_pulse = 0; m_bv_state++; } break; - case 0x06: // Stacked Pulse 10ms OFF + case 0x12: // Start Pulse 20ms OFF + if (curr_cycles - m_bv_cycles >= 833.3 * 20) { + m_bv_cycles = curr_cycles; + m_bv_pulse = 1; + m_bv_state++; + } + break; + case 0x13: // Data Sync Pulse 20ms ON + if (curr_cycles - m_bv_cycles >= 833.3 * 20) { + m_bv_cycles = curr_cycles; + m_bv_pulse = 1 - ((id023_data >> m_bv_data_bit) & 0x01); + m_bv_state++; + } + break; + case 0x14: // Data Value Pulse 20ms OFF + if (curr_cycles - m_bv_cycles >= 833.3 * 20) { + m_bv_cycles = curr_cycles; + m_bv_pulse = 1; + + if (m_bv_data_bit == 0) { + m_bv_data_bit = 14; // Done with Data Stream + m_bv_state++; + } else { + m_bv_data_bit--; + m_bv_state = 0x13; // More Data Yet + } + } + break; + case 0x15: // Stop Pulse 90ms ON + if (curr_cycles - m_bv_cycles >= 833.3 * 90) { + m_bv_cycles = curr_cycles; + m_bv_pulse = 0; + + if (m_bv_loop_count >= 2) { + m_bv_state = 0x17; // Done, Ready for Toggling + } else { + m_bv_loop_count++; + m_bv_state++; + } + } + break; + case 0x16: // Repeat Pulse 200ms OFF + if (curr_cycles - m_bv_cycles >= 833.3 * 200) { + m_bv_cycles = curr_cycles; + m_bv_pulse = 1; + m_bv_state = 0x11; // Repeat from Start + } + break; + case 0x17: // Begin Toggle Polling + if (m_bv_enable_state != m_bv_last_enable_state) { + m_bv_enable_count++; + m_bv_last_enable_state = m_bv_enable_state; + + // Got Enough Toggles, Advance to Stacking + if (m_bv_enable_count == 0x03) { + m_bv_cycles = curr_cycles; + m_bv_pulse = 1; + m_bv_state++; + } + } else { + // No Toggling Found, Game Rejected Bill + if (curr_cycles - m_bv_cycles >= 833.3 * 200) { + m_bv_pulse = 0; + m_bv_state = 0x00; + } + } + break; + case 0x18: // Stacked Pulse 10ms ON + if (curr_cycles - m_bv_cycles >= 833.3 * 10) { + m_bv_cycles = curr_cycles; + m_bv_pulse = 0; + m_bv_state++; + } + break; + case 0x19: // Stacked Pulse 10ms OFF if (curr_cycles - m_bv_cycles >= 833.3 * 10) { m_bv_cycles = curr_cycles; m_bv_pulse = 1; m_bv_state++; } break; - case 0x07: // Stacked Pulse 10ms ON + case 0x1a: // Stacked Pulse 10ms ON if (curr_cycles - m_bv_cycles >= 833.3 * 10) { m_bv_cycles = curr_cycles; m_bv_pulse = 0; - m_bv_state = 0; + m_bv_state = 0x00; } break; } @@ -1006,11 +1123,16 @@ static INPUT_PORTS_START( peplus ) PORT_CONFNAME( 0x1f, 0x00, "Bill Choices" ) PORT_CONFSETTING( 0x00, "$1" ) PORT_CONFSETTING( 0x01, "$2" ) - PORT_CONFSETTING( 0x04, "$5" ) - PORT_CONFSETTING( 0x09, "$10" ) - PORT_CONFSETTING( 0x13, "$20" ) - PORT_CONFSETTING( 0x16, "$50" ) - PORT_CONFSETTING( 0x18, "$100" ) + PORT_CONFSETTING( 0x02, "$5" ) + PORT_CONFSETTING( 0x03, "$10" ) + PORT_CONFSETTING( 0x04, "$20" ) + PORT_CONFSETTING( 0x05, "$50" ) + PORT_CONFSETTING( 0x06, "$100" ) + + PORT_START("BP") + PORT_CONFNAME( 0x1f, 0x00, "Bill Protocol" ) + PORT_CONFSETTING( 0x00, "ID-022" ) + PORT_CONFSETTING( 0x01, "ID-023" ) PORT_START("SW1") PORT_DIPNAME( 0x01, 0x01, "Line Frequency" )