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