summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/ticket.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/ticket.c')
-rw-r--r--src/mame/machine/ticket.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/mame/machine/ticket.c b/src/mame/machine/ticket.c
new file mode 100644
index 00000000000..caf30035fe2
--- /dev/null
+++ b/src/mame/machine/ticket.c
@@ -0,0 +1,190 @@
+/***************************************************************************
+
+ machine.c
+
+ Functions to emulate a prototypical ticket dispenser hardware.
+
+ Right now, this is an *extremely* basic ticket dispenser.
+ TODO: Active Bit may not be Bit 7 in all applications.
+ Add a ticket dispenser interface instead of passing a bunch
+ of arguments to ticket_dispenser_init.
+***************************************************************************/
+
+#include "driver.h"
+#include "machine/ticket.h"
+
+/*#define DEBUG_TICKET*/
+
+#define MAX_DISPENSERS 2
+
+struct ticket_state
+{
+ UINT8 status;
+ UINT8 power;
+ emu_timer *timer;
+};
+
+static int active_bit = 0x80;
+static int time_msec;
+static int motoron;
+static int ticketdispensed;
+static int ticketnotdispensed;
+
+static struct ticket_state dispenser[MAX_DISPENSERS];
+
+static TIMER_CALLBACK_PTR( ticket_dispenser_toggle );
+
+
+/***************************************************************************
+ ticket_dispenser_init
+
+***************************************************************************/
+void ticket_dispenser_init(int msec, int motoronhigh, int statusactivehigh)
+{
+ int i;
+
+ time_msec = msec;
+ motoron = motoronhigh ? active_bit : 0;
+ ticketdispensed = statusactivehigh ? active_bit : 0;
+ ticketnotdispensed = ticketdispensed ^ active_bit;
+ dispensed_tickets = 0;
+
+ for (i = 0; i < MAX_DISPENSERS; i++)
+ {
+ dispenser[i].status = ticketnotdispensed;
+ dispenser[i].power = 0x00;
+ dispenser[i].timer = timer_alloc_ptr(ticket_dispenser_toggle, &dispenser[i]);
+
+ state_save_register_item("ticket", i, dispenser[i].status);
+ state_save_register_item("ticket", i, dispenser[i].power);
+ }
+}
+
+/***************************************************************************
+ ticket_dispenser_r
+***************************************************************************/
+READ8_HANDLER( ticket_dispenser_r )
+{
+ return ticket_dispenser_0_r(offset);
+}
+
+READ8_HANDLER( ticket_dispenser_0_r )
+{
+#ifdef DEBUG_TICKET
+ logerror("PC: %04X Ticket Status Read = %02X\n", activecpu_get_pc(), status);
+#endif
+ return dispenser[0].status;
+}
+
+READ8_HANDLER( ticket_dispenser_1_r )
+{
+#ifdef DEBUG_TICKET
+ logerror("PC: %04X Ticket Status Read = %02X\n", activecpu_get_pc(), status);
+#endif
+ return dispenser[1].status;
+}
+
+/***************************************************************************
+ ticket_dispenser_w
+***************************************************************************/
+WRITE8_HANDLER( ticket_dispenser_w )
+{
+ ticket_dispenser_0_w(offset, data);
+}
+
+WRITE8_HANDLER( ticket_dispenser_0_w )
+{
+ /* On an activate signal, start dispensing! */
+ if ((data & active_bit) == motoron)
+ {
+ if (!dispenser[0].power)
+ {
+#ifdef DEBUG_TICKET
+ logerror("PC: %04X Ticket Power On\n", activecpu_get_pc());
+#endif
+ timer_adjust_ptr(dispenser[0].timer, ATTOTIME_IN_MSEC(time_msec), attotime_zero);
+ dispenser[0].power = 1;
+
+ dispenser[0].status = ticketnotdispensed;
+ }
+ }
+ else
+ {
+ if (dispenser[0].power)
+ {
+#ifdef DEBUG_TICKET
+ logerror("PC: %04X Ticket Power Off\n", activecpu_get_pc());
+#endif
+ timer_adjust_ptr(dispenser[0].timer, attotime_never, attotime_never);
+ set_led_status(2,0);
+ dispenser[0].power = 0;
+ }
+ }
+}
+
+WRITE8_HANDLER( ticket_dispenser_1_w )
+{
+ /* On an activate signal, start dispensing! */
+ if ((data & active_bit) == motoron)
+ {
+ if (!dispenser[1].power)
+ {
+#ifdef DEBUG_TICKET
+ logerror("PC: %04X Ticket Power On\n", activecpu_get_pc());
+#endif
+ timer_adjust_ptr(dispenser[1].timer, ATTOTIME_IN_MSEC(time_msec), attotime_zero);
+ dispenser[1].power = 1;
+
+ dispenser[1].status = ticketnotdispensed;
+ }
+ }
+ else
+ {
+ if (dispenser[1].power)
+ {
+#ifdef DEBUG_TICKET
+ logerror("PC: %04X Ticket Power Off\n", activecpu_get_pc());
+#endif
+ timer_adjust_ptr(dispenser[1].timer, attotime_never, attotime_never);
+ set_led_status(2,0);
+ dispenser[1].power = 0;
+ }
+ }
+}
+
+
+/***************************************************************************
+ ticket_dispenser_toggle
+
+ How I think this works:
+ When a ticket dispenses, there is N milliseconds of status = high,
+ and N milliseconds of status = low (a wait cycle?).
+***************************************************************************/
+static TIMER_CALLBACK_PTR( ticket_dispenser_toggle )
+{
+ struct ticket_state *dispenser = param;
+
+ /* If we still have power, keep toggling ticket states. */
+ if (dispenser->power)
+ {
+ dispenser->status ^= active_bit;
+#ifdef DEBUG_TICKET
+ logerror("Ticket Status Changed to %02X\n", status);
+#endif
+ timer_adjust_ptr(dispenser->timer, ATTOTIME_IN_MSEC(time_msec), attotime_zero);
+ }
+
+ if (dispenser->status == ticketdispensed)
+ {
+ set_led_status(2,1);
+ dispensed_tickets++;
+
+#ifdef DEBUG_TICKET
+ logerror("Ticket Dispensed\n");
+#endif
+ }
+ else
+ {
+ set_led_status(2,0);
+ }
+}