// license:BSD-3-Clause // copyright-holders:Aaron Giles /*************************************************************************** ticket.c Generic ticket dispensing device. ***************************************************************************/ #include "emu.h" #include "machine/ticket.h" //************************************************************************** // DEBUGGING //************************************************************************** #define DEBUG_TICKET 0 #define LOG(x) do { if (DEBUG_TICKET) logerror x; } while (0) //************************************************************************** // GLOBAL VARIABLES //************************************************************************** // device type definition const device_type TICKET_DISPENSER = &device_creator; //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- // ticket_dispenser_device - constructor //------------------------------------------------- ticket_dispenser_device::ticket_dispenser_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, TICKET_DISPENSER, "Ticket Dispenser", tag, owner, clock, "ticket_dispenser", __FILE__), m_motor_sense(TICKET_MOTOR_ACTIVE_LOW), m_status_sense(TICKET_STATUS_ACTIVE_LOW), m_period(attotime::from_msec(100)), m_active_bit(0x80), m_motoron(0), m_ticketdispensed(0), m_ticketnotdispensed(0), m_status(0), m_power(0), m_timer(nullptr) { } //------------------------------------------------- // ~ticket_dispenser_device - destructor //------------------------------------------------- ticket_dispenser_device::~ticket_dispenser_device() { } //************************************************************************** // CONFIGURATION HELPERS //************************************************************************** //------------------------------------------------- // static_set_period - configure the clock period // for dispensing //------------------------------------------------- void ticket_dispenser_device::static_set_period(device_t &device, const attotime &period) { downcast(device).m_period = period; } //------------------------------------------------- // static_set_senses - configure the senses of // the motor and status bits //------------------------------------------------- void ticket_dispenser_device::static_set_senses(device_t &device, uint8_t motor_sense, uint8_t status_sense) { ticket_dispenser_device &ticket = downcast(device); ticket.m_motor_sense = motor_sense; ticket.m_status_sense = status_sense; } //************************************************************************** // READ/WRITE HANDLERS //************************************************************************** //------------------------------------------------- // read - read the status line via the active bit // (legacy method) //------------------------------------------------- READ8_MEMBER( ticket_dispenser_device::read ) { LOG(("%s: Ticket Status Read = %02X\n", machine().describe_context(), m_status)); return m_status; } //------------------------------------------------- // line_r - read the status line as a proper line //------------------------------------------------- READ_LINE_MEMBER( ticket_dispenser_device::line_r ) { return m_status ? 1 : 0; } //------------------------------------------------- // write - write the control line via the active // bit (legacy method) //------------------------------------------------- WRITE8_MEMBER( ticket_dispenser_device::write ) { // On an activate signal, start dispensing! if ((data & m_active_bit) == m_motoron) { if (!m_power) { LOG(("%s: Ticket Power On\n", machine().describe_context())); m_timer->adjust(m_period); m_power = 1; m_status = m_ticketnotdispensed; } } else { if (m_power) { LOG(("%s: Ticket Power Off\n", machine().describe_context())); m_timer->adjust(attotime::never); machine().output().set_led_value(2,0); m_power = 0; } } } //------------------------------------------------- // motor_w - write the control line as a proper // line //------------------------------------------------- WRITE_LINE_MEMBER( ticket_dispenser_device::motor_w ) { write(machine().driver_data()->generic_space(), 0, state ? m_active_bit : 0); } //************************************************************************** // DEVICE INTERFACE //************************************************************************** //------------------------------------------------- // device_start - handle device startup //------------------------------------------------- void ticket_dispenser_device::device_start() { m_active_bit = 0x80; m_motoron = (m_motor_sense == TICKET_MOTOR_ACTIVE_HIGH) ? m_active_bit : 0; m_ticketdispensed = (m_status_sense == TICKET_STATUS_ACTIVE_HIGH) ? m_active_bit : 0; m_ticketnotdispensed = m_ticketdispensed ^ m_active_bit; m_timer = timer_alloc(); save_item(NAME(m_status)); save_item(NAME(m_power)); } //------------------------------------------------- // device_reset - handle device startup //------------------------------------------------- void ticket_dispenser_device::device_reset() { m_status = m_ticketnotdispensed; m_power = 0x00; } //------------------------------------------------- // device_timer - handle timer callbacks //------------------------------------------------- void ticket_dispenser_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { // if we still have power, keep toggling ticket states if (m_power) { m_status ^= m_active_bit; LOG(("Ticket Status Changed to %02X\n", m_status)); m_timer->adjust(m_period); } // update LED status (fixme: should map to an output) machine().output().set_led_value(2, (m_status == m_ticketdispensed)); // if we just dispensed, increment global count if (m_status == m_ticketdispensed) { machine().bookkeeping().increment_dispensed_tickets(1); LOG(("Ticket Dispensed\n")); } }