1 /***************************************************************************
2
3 machine.c
4
5 Functions to emulate a prototypical ticket dispenser hardware.
6
7 Right now, this is an *extremely* basic ticket dispenser.
8 TODO: Active Bit may not be Bit 7 in all applications.
9 Add a ticket dispenser interface instead of passing a bunch
10 of arguments to ticket_dispenser_init.
11 Add sound, graphical output?
12 ***************************************************************************/
13
14 #include "driver.h"
15 #include "machine/ticket.h"
16
17 /*#define DEBUG_TICKET*/
18
19 #define MAX_DISPENSERS 2
20
21 extern unsigned int dispensed_tickets;
22
23 struct ticket_state
24 {
25 int status;
26 int power;
27 void *timer;
28 };
29
30 static int active_bit = 0x80;
31 static int time_msec;
32 static int motoron;
33 static int ticketdispensed;
34 static int ticketnotdispensed;
35
36 static struct ticket_state dispenser[MAX_DISPENSERS];
37
38 /* Callback routine used during ticket dispensing */
39 static void ticket_dispenser_toggle(int parm);
40
41
42 /***************************************************************************
43 ticket_dispenser_init
44
45 ***************************************************************************/
ticket_dispenser_init(int msec,int motoronhigh,int statusactivehigh)46 void ticket_dispenser_init(int msec, int motoronhigh, int statusactivehigh)
47 {
48 int i;
49
50 time_msec = msec;
51 motoron = motoronhigh ? active_bit : 0;
52 ticketdispensed = statusactivehigh ? active_bit : 0;
53 ticketnotdispensed = ticketdispensed ^ active_bit;
54 dispensed_tickets = 0;
55
56 for (i = 0; i < MAX_DISPENSERS; i++)
57 {
58 dispenser[i].status = ticketnotdispensed;
59 dispenser[i].power = 0x00;
60 dispenser[i].timer = timer_alloc(ticket_dispenser_toggle);
61 }
62 }
63
64 /***************************************************************************
65 ticket_dispenser_r
66 ***************************************************************************/
READ_HANDLER(ticket_dispenser_r)67 READ_HANDLER( ticket_dispenser_r )
68 {
69 return ticket_dispenser_0_r(offset);
70 }
71
READ_HANDLER(ticket_dispenser_0_r)72 READ_HANDLER( ticket_dispenser_0_r )
73 {
74 #ifdef DEBUG_TICKET
75 logerror("PC: %04X Ticket Status Read = %02X\n", activecpu_get_pc(), status);
76 #endif
77 return dispenser[0].status;
78 }
79
READ_HANDLER(ticket_dispenser_1_r)80 READ_HANDLER( ticket_dispenser_1_r )
81 {
82 #ifdef DEBUG_TICKET
83 logerror("PC: %04X Ticket Status Read = %02X\n", activecpu_get_pc(), status);
84 #endif
85 return dispenser[1].status;
86 }
87
88 /***************************************************************************
89 ticket_dispenser_w
90 ***************************************************************************/
WRITE_HANDLER(ticket_dispenser_w)91 WRITE_HANDLER( ticket_dispenser_w )
92 {
93 ticket_dispenser_0_w(offset, data);
94 }
95
WRITE_HANDLER(ticket_dispenser_0_w)96 WRITE_HANDLER( ticket_dispenser_0_w )
97 {
98 /* On an activate signal, start dispensing! */
99 if ((data & active_bit) == motoron)
100 {
101 if (!dispenser[0].power)
102 {
103 #ifdef DEBUG_TICKET
104 logerror("PC: %04X Ticket Power On\n", activecpu_get_pc());
105 #endif
106 timer_adjust(dispenser[0].timer, TIME_IN_MSEC(time_msec), 0, 0);
107 dispenser[0].power = 1;
108
109 dispenser[0].status = ticketnotdispensed;
110 }
111 }
112 else
113 {
114 if (dispenser[0].power)
115 {
116 #ifdef DEBUG_TICKET
117 logerror("PC: %04X Ticket Power Off\n", activecpu_get_pc());
118 #endif
119 timer_adjust(dispenser[0].timer, TIME_NEVER, 0, 0);
120 set_led_status(2,0);
121 dispenser[0].power = 0;
122 }
123 }
124 }
125
WRITE_HANDLER(ticket_dispenser_1_w)126 WRITE_HANDLER( ticket_dispenser_1_w )
127 {
128 /* On an activate signal, start dispensing! */
129 if ((data & active_bit) == motoron)
130 {
131 if (!dispenser[1].power)
132 {
133 #ifdef DEBUG_TICKET
134 logerror("PC: %04X Ticket Power On\n", activecpu_get_pc());
135 #endif
136 timer_adjust(dispenser[1].timer, TIME_IN_MSEC(time_msec), 1, 0);
137 dispenser[1].power = 1;
138
139 dispenser[1].status = ticketnotdispensed;
140 }
141 }
142 else
143 {
144 if (dispenser[1].power)
145 {
146 #ifdef DEBUG_TICKET
147 logerror("PC: %04X Ticket Power Off\n", activecpu_get_pc());
148 #endif
149 timer_adjust(dispenser[1].timer, TIME_NEVER, 1, 0);
150 set_led_status(2,0);
151 dispenser[1].power = 0;
152 }
153 }
154 }
155
156
157 /***************************************************************************
158 ticket_dispenser_toggle
159
160 How I think this works:
161 When a ticket dispenses, there is N milliseconds of status = high,
162 and N milliseconds of status = low (a wait cycle?).
163 ***************************************************************************/
ticket_dispenser_toggle(int which)164 static void ticket_dispenser_toggle(int which)
165 {
166 /* If we still have power, keep toggling ticket states. */
167 if (dispenser[which].power)
168 {
169 dispenser[which].status ^= active_bit;
170 #ifdef DEBUG_TICKET
171 logerror("Ticket Status Changed to %02X\n", status);
172 #endif
173 timer_adjust(dispenser[which].timer, TIME_IN_MSEC(time_msec), which, 0);
174 }
175
176 if (dispenser[which].status == ticketdispensed)
177 {
178 set_led_status(2,1);
179 dispensed_tickets++;
180
181 #ifdef DEBUG_TICKET
182 logerror("Ticket Dispensed\n");
183 #endif
184 }
185 else
186 {
187 set_led_status(2,0);
188 }
189 }
190