1 /***************************************************************************
2
3 machine.c
4
5 Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
6 I/O ports)
7
8 ***************************************************************************/
9
10 #include "driver.h"
11 #include "vidhrdw/generic.h"
12 #include "cpu/z80/z80.h"
13
14
15 unsigned char *digdug_sharedram;
16 static unsigned char interrupt_enable_1,interrupt_enable_2,interrupt_enable_3;
17
18 static int credits;
19
20 static void *nmi_timer;
21
22 WRITE_HANDLER( digdug_halt_w );
23
24
digdig_init_machine(void)25 void digdig_init_machine(void)
26 {
27 credits = 0;
28 nmi_timer = 0;
29 interrupt_enable_1 = interrupt_enable_2 = interrupt_enable_3 = 0;
30 digdug_halt_w (0, 0);
31 }
32
33
READ_HANDLER(digdug_sharedram_r)34 READ_HANDLER( digdug_sharedram_r )
35 {
36 return digdug_sharedram[offset];
37 }
38
39
WRITE_HANDLER(digdug_sharedram_w)40 WRITE_HANDLER( digdug_sharedram_w )
41 {
42 /* a video ram write */
43 if (offset < 0x400)
44 dirtybuffer[offset] = 1;
45
46 /* location 9b3d is set to zero just before CPU 2 spins */
47 if (offset == 0x1b3d && data == 0 && cpu_get_pc () == 0x1df1 && cpu_getactivecpu () == 1)
48 cpu_spinuntil_int ();
49
50 digdug_sharedram[offset] = data;
51 }
52
53
54 /***************************************************************************
55
56 Emulate the custom IO chip.
57
58 ***************************************************************************/
59 static int customio_command;
60 static int leftcoinpercred,leftcredpercoin;
61 static int rightcoinpercred,rightcredpercoin;
62 static unsigned char customio[16];
63 static int mode;
64
WRITE_HANDLER(digdug_customio_data_w)65 WRITE_HANDLER( digdug_customio_data_w )
66 {
67 customio[offset] = data;
68
69 //logerror("%04x: custom IO offset %02x data %02x\n",cpu_get_pc(),offset,data);
70
71 switch (customio_command)
72 {
73 case 0xc1:
74 if (offset == 8)
75 {
76 leftcoinpercred = customio[2] & 0x0f;
77 leftcredpercoin = customio[3] & 0x0f;
78 rightcoinpercred = customio[4] & 0x0f;
79 rightcredpercoin = customio[5] & 0x0f;
80 }
81 break;
82 }
83 }
84
85
READ_HANDLER(digdug_customio_data_r)86 READ_HANDLER( digdug_customio_data_r )
87 {
88 switch (customio_command)
89 {
90 case 0x71:
91 if (offset == 0)
92 {
93 if (mode) /* switch mode */
94 {
95 /* bit 7 is the service switch */
96 return readinputport(4);
97 }
98 else /* credits mode: return number of credits in BCD format */
99 {
100 int in;
101 static int leftcoininserted;
102 static int rightcoininserted;
103
104
105 in = readinputport(4);
106
107 /* check if the user inserted a coin */
108 if (leftcoinpercred > 0)
109 {
110 if ((in & 0x01) == 0 && credits < 99)
111 {
112 leftcoininserted++;
113 if (leftcoininserted >= leftcoinpercred)
114 {
115 credits += leftcredpercoin;
116 leftcoininserted = 0;
117 }
118 }
119 if ((in & 0x02) == 0 && credits < 99)
120 {
121 rightcoininserted++;
122 if (rightcoininserted >= rightcoinpercred)
123 {
124 credits += rightcredpercoin;
125 rightcoininserted = 0;
126 }
127 }
128 }
129 else credits = 2;
130
131
132 /* check for 1 player start button */
133 if ((in & 0x10) == 0)
134 if (credits >= 1) credits--;
135
136 /* check for 2 players start button */
137 if ((in & 0x20) == 0)
138 if (credits >= 2) credits -= 2;
139
140 return (credits / 10) * 16 + credits % 10;
141 }
142 }
143 else if (offset == 1)
144 {
145 int p2 = readinputport (2);
146
147 if (mode == 0)
148 {
149 /* check directions, according to the following 8-position rule */
150 /* 0 */
151 /* 7 1 */
152 /* 6 8 2 */
153 /* 5 3 */
154 /* 4 */
155 if ((p2 & 0x01) == 0) /* up */
156 p2 = (p2 & ~0x0f) | 0x00;
157 else if ((p2 & 0x02) == 0) /* right */
158 p2 = (p2 & ~0x0f) | 0x02;
159 else if ((p2 & 0x04) == 0) /* down */
160 p2 = (p2 & ~0x0f) | 0x04;
161 else if ((p2 & 0x08) == 0) /* left */
162 p2 = (p2 & ~0x0f) | 0x06;
163 else
164 p2 = (p2 & ~0x0f) | 0x08;
165 }
166
167 return p2;
168 }
169 else if (offset == 2)
170 {
171 int p2 = readinputport (3);
172
173 if (mode == 0)
174 {
175 /* check directions, according to the following 8-position rule */
176 /* 0 */
177 /* 7 1 */
178 /* 6 8 2 */
179 /* 5 3 */
180 /* 4 */
181 if ((p2 & 0x01) == 0) /* up */
182 p2 = (p2 & ~0x0f) | 0x00;
183 else if ((p2 & 0x02) == 0) /* right */
184 p2 = (p2 & ~0x0f) | 0x02;
185 else if ((p2 & 0x04) == 0) /* down */
186 p2 = (p2 & ~0x0f) | 0x04;
187 else if ((p2 & 0x08) == 0) /* left */
188 p2 = (p2 & ~0x0f) | 0x06;
189 else
190 p2 = (p2 & ~0x0f) | 0x08;
191 }
192
193 return p2; /*p2 jochen*/
194 }
195 break;
196
197 case 0xb1: /* status? */
198 if (offset <= 2)
199 return 0;
200 break;
201
202 case 0xd2: /* checking the dipswitches */
203 if (offset == 0)
204 return readinputport (0);
205 else if (offset == 1)
206 return readinputport (1);
207 break;
208 }
209
210 return -1;
211 }
212
213
READ_HANDLER(digdug_customio_r)214 READ_HANDLER( digdug_customio_r )
215 {
216 return customio_command;
217 }
218
digdug_nmi_generate(int param)219 void digdug_nmi_generate (int param)
220 {
221 cpu_cause_interrupt (0, Z80_NMI_INT);
222 }
223
224
WRITE_HANDLER(digdug_customio_w)225 WRITE_HANDLER( digdug_customio_w )
226 {
227 /*if (data != 0x10 && data != 0x71)
228 logerror("%04x: custom IO command %02x\n",cpu_get_pc(),data);*/
229
230 customio_command = data;
231
232 switch (data)
233 {
234 case 0x10:
235 if (nmi_timer) timer_remove (nmi_timer);
236 nmi_timer = 0;
237 return;
238
239 case 0xa1: /* go into switch mode */
240 mode = 1;
241 break;
242
243 case 0xc1:
244 case 0xe1: /* go into credit mode */
245 mode = 0;
246 break;
247
248 case 0xb1: /* status? */
249 credits = 0; /* this is a good time to reset the credits counter */
250 break;
251 }
252
253 nmi_timer = timer_pulse (TIME_IN_USEC (50), 0, digdug_nmi_generate);
254 }
255
256
257
WRITE_HANDLER(digdug_halt_w)258 WRITE_HANDLER( digdug_halt_w )
259 {
260 if (data & 1)
261 {
262 cpu_set_reset_line(1,CLEAR_LINE);
263 cpu_set_reset_line(2,CLEAR_LINE);
264 }
265 else
266 {
267 cpu_set_reset_line(1,ASSERT_LINE);
268 cpu_set_reset_line(2,ASSERT_LINE);
269 }
270 }
271
272
273
WRITE_HANDLER(digdug_interrupt_enable_1_w)274 WRITE_HANDLER( digdug_interrupt_enable_1_w )
275 {
276 interrupt_enable_1 = (data&1);
277 }
278
279
280
digdug_interrupt_1(void)281 int digdug_interrupt_1(void)
282 {
283 if (interrupt_enable_1) return interrupt();
284 else return ignore_interrupt();
285 }
286
287
288
WRITE_HANDLER(digdug_interrupt_enable_2_w)289 WRITE_HANDLER( digdug_interrupt_enable_2_w )
290 {
291 interrupt_enable_2 = data & 1;
292 }
293
294
295
digdug_interrupt_2(void)296 int digdug_interrupt_2(void)
297 {
298 if (interrupt_enable_2) return interrupt();
299 else return ignore_interrupt();
300 }
301
302
303
WRITE_HANDLER(digdug_interrupt_enable_3_w)304 WRITE_HANDLER( digdug_interrupt_enable_3_w )
305 {
306 interrupt_enable_3 = !(data & 1);
307 }
308
309
310
digdug_interrupt_3(void)311 int digdug_interrupt_3(void)
312 {
313 if (interrupt_enable_3) return nmi_interrupt();
314 else return ignore_interrupt();
315 }
316