1 /***************************************************************************
2 
3   machine.c
4 
5   Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
6   I/O ports)
7 
8   The I8742 MCU takes care of handling the coin inputs and the tilt switch.
9   To simulate this, we read the status in the interrupt handler for the main
10   CPU and update the counters appropriately. We also must take care of
11   handling the coin/credit settings ourselves.
12 
13 ***************************************************************************/
14 
15 #include "driver.h"
16 
17 extern unsigned char *tnzs_workram;
18 
19 static int mcu_type;
20 
21 enum
22 {
23 	MCU_NONE,
24 	MCU_EXTRMATN,
25 	MCU_ARKANOID,
26 	MCU_DRTOPPEL,
27 	MCU_CHUKATAI,
28 	MCU_TNZS
29 };
30 
31 static int mcu_initializing,mcu_coinage_init,mcu_command,mcu_readcredits;
32 static int mcu_reportcoin;
33 static int tnzs_workram_backup;
34 static unsigned char mcu_coinage[4];
35 static unsigned char mcu_coinsA,mcu_coinsB,mcu_credits;
36 
37 
38 
READ_HANDLER(arkanoi2_sh_f000_r)39 READ_HANDLER( arkanoi2_sh_f000_r )
40 {
41 	int val;
42 
43 	//logerror("PC %04x: read input %04x\n", cpu_get_pc(), 0xf000 + offset);
44 
45 	val = readinputport(5 + offset/2);
46 	if (offset & 1)
47 	{
48 		return ((val >> 8) & 0xff);
49 	}
50 	else
51 	{
52 		return val & 0xff;
53 	}
54 }
55 
56 
mcu_reset(void)57 static void mcu_reset(void)
58 {
59 	mcu_initializing = 3;
60 	mcu_coinage_init = 0;
61 	mcu_coinage[0] = 1;
62 	mcu_coinage[1] = 1;
63 	mcu_coinage[2] = 1;
64 	mcu_coinage[3] = 1;
65 	mcu_coinsA = 0;
66 	mcu_coinsB = 0;
67 	mcu_credits = 0;
68 	mcu_reportcoin = 0;
69 	mcu_command = 0;
70 	tnzs_workram_backup = -1;
71 }
72 
mcu_handle_coins(int coin)73 static void mcu_handle_coins(int coin)
74 {
75 	static int insertcoin;
76 
77 	/* The coin inputs and coin counter is managed by the i8742 mcu. */
78 	/* Here we simulate it. */
79 	/* Chuka Taisen has a limit of 9 credits, so any */
80 	/* coins that could push it over 9 should be rejected */
81 	/* Coin/Play settings must also be taken into consideration */
82 
83 	if (coin & 0x08)	/* tilt */
84 		mcu_reportcoin = coin;
85 	else if (coin && coin != insertcoin)
86 	{
87 		if (coin & 0x01)	/* coin A */
88 		{
89 			if ((mcu_type == MCU_CHUKATAI) && ((mcu_credits+mcu_coinage[1]) > 9))
90 			{
91 				coin_lockout_global_w(0,1); /* Lock all coin slots */
92 			}
93 			else
94 			{
95 				//logerror("Coin dropped into slot A\n");
96 				coin_lockout_global_w(0,0); /* Unlock all coin slots */
97 				coin_counter_w(0,1); coin_counter_w(0,0); /* Count slot A */
98 				mcu_coinsA++;
99 				if (mcu_coinsA >= mcu_coinage[0])
100 				{
101 					mcu_coinsA -= mcu_coinage[0];
102 					mcu_credits += mcu_coinage[1];
103 				}
104 			}
105 		}
106 		if (coin & 0x02)	/* coin B */
107 		{
108 			if ((mcu_type == MCU_CHUKATAI) && ((mcu_credits+mcu_coinage[3]) > 9))
109 			{
110 				coin_lockout_global_w(0,1); /* Lock all coin slots */
111 			}
112 			else
113 			{
114 				//logerror("Coin dropped into slot B\n");
115 				coin_lockout_global_w(0,0); /* Unlock all coin slots */
116 				coin_counter_w(1,1); coin_counter_w(1,0); /* Count slot B */
117 				mcu_coinsB++;
118 				if (mcu_coinsB >= mcu_coinage[2])
119 				{
120 					mcu_coinsB -= mcu_coinage[2];
121 					mcu_credits += mcu_coinage[3];
122 				}
123 			}
124 		}
125 		if (coin & 0x04)	/* service */
126 		{
127 			//logerror("Coin dropped into service slot C\n");
128 			mcu_credits++;
129 		}
130 		mcu_reportcoin = coin;
131 	}
132 	else
133 	{
134 		coin_lockout_global_w(0,0); /* Unlock all coin slots */
135 		mcu_reportcoin = 0;
136 	}
137 	insertcoin = coin;
138 }
139 
140 
141 
READ_HANDLER(mcu_arkanoi2_r)142 static READ_HANDLER( mcu_arkanoi2_r )
143 {
144 	char *mcu_startup = "\x55\xaa\x5a";
145 
146 //	logerror("PC %04x: read mcu %04x\n", cpu_get_pc(), 0xc000 + offset);
147 
148 	if (offset == 0)
149 	{
150 		/* if the mcu has just been reset, return startup code */
151 		if (mcu_initializing)
152 		{
153 			mcu_initializing--;
154 			return mcu_startup[2 - mcu_initializing];
155 		}
156 
157 		switch (mcu_command)
158 		{
159 			case 0x41:
160 				return mcu_credits;
161 
162 			case 0xc1:
163 				/* Read the credit counter or the inputs */
164 				if (mcu_readcredits == 0)
165 				{
166 					mcu_readcredits = 1;
167 					if (mcu_reportcoin & 0x08)
168 					{
169 						mcu_initializing = 3;
170 						return 0xee;	/* tilt */
171 					}
172 					else return mcu_credits;
173 				}
174 				else return readinputport(2);	/* buttons */
175 
176 			default:
177 //logerror("error, unknown mcu command\n");
178 				/* should not happen */
179 				return 0xff;
180 				break;
181 		}
182 	}
183 	else
184 	{
185 		/*
186 		status bits:
187 		0 = mcu is ready to send data (read from c000)
188 		1 = mcu has read data (from c000)
189 		2 = unused
190 		3 = unused
191 		4-7 = coin code
192 		      0 = nothing
193 		      1,2,3 = coin switch pressed
194 		      e = tilt
195 		*/
196 		if (mcu_reportcoin & 0x08) return 0xe1;	/* tilt */
197 		if (mcu_reportcoin & 0x01) return 0x11;	/* coin 1 (will trigger "coin inserted" sound) */
198 		if (mcu_reportcoin & 0x02) return 0x21;	/* coin 2 (will trigger "coin inserted" sound) */
199 		if (mcu_reportcoin & 0x04) return 0x31;	/* coin 3 (will trigger "coin inserted" sound) */
200 		return 0x01;
201 	}
202 }
203 
WRITE_HANDLER(mcu_arkanoi2_w)204 static WRITE_HANDLER( mcu_arkanoi2_w )
205 {
206 	if (offset == 0)
207 	{
208 //	logerror("PC %04x (re %04x): write %02x to mcu %04x\n", cpu_get_pc(), cpu_geturnpc(), data, 0xc000 + offset);
209 		if (mcu_command == 0x41)
210 		{
211 			mcu_credits = (mcu_credits + data) & 0xff;
212 		}
213 	}
214 	else
215 	{
216 		/*
217 		0xc1: read number of credits, then buttons
218 		0x54+0x41: add value to number of credits
219 		0x84: coin 1 lockout (issued only in test mode)
220 		0x88: coin 2 lockout (issued only in test mode)
221 		0x80: release coin lockout (issued only in test mode)
222 		during initialization, a sequence of 4 bytes sets coin/credit settings
223 		*/
224 //	logerror("PC %04x (re %04x): write %02x to mcu %04x\n", cpu_get_pc(), cpu_geturnpc(), data, 0xc000 + offset);
225 
226 		if (mcu_initializing)
227 		{
228 			/* set up coin/credit settings */
229 			mcu_coinage[mcu_coinage_init++] = data;
230 			if (mcu_coinage_init == 4) mcu_coinage_init = 0;	/* must not happen */
231 		}
232 
233 		if (data == 0xc1)
234 			mcu_readcredits = 0;	/* reset input port number */
235 
236 		mcu_command = data;
237 	}
238 }
239 
240 
READ_HANDLER(mcu_chukatai_r)241 static READ_HANDLER( mcu_chukatai_r )
242 {
243 	char *mcu_startup = "\xa5\x5a\xaa";
244 
245 	//logerror("PC %04x (re %04x): read mcu %04x\n", cpu_get_pc(), cpu_geturnpc(), 0xc000 + offset);
246 
247 	if (offset == 0)
248 	{
249 		/* if the mcu has just been reset, return startup code */
250 		if (mcu_initializing)
251 		{
252 			mcu_initializing--;
253 			return mcu_startup[2 - mcu_initializing];
254 		}
255 
256 		switch (mcu_command)
257 		{
258 			case 0x1f:
259 				return (readinputport(4) >> 4) ^ 0x0f;
260 
261 			case 0x03:
262 				return readinputport(4) & 0x0f;
263 
264 			case 0x41:
265 				return mcu_credits;
266 
267 			case 0x93:
268 				/* Read the credit counter or the inputs */
269 				if (mcu_readcredits == 0)
270 				{
271 					mcu_readcredits += 1;
272 					if (mcu_reportcoin & 0x08)
273 					{
274 						mcu_initializing = 3;
275 						return 0xee;	/* tilt */
276 					}
277 					else return mcu_credits;
278 				}
279 				/* player 1 joystick and buttons */
280 				if (mcu_readcredits == 1)
281 				{
282 					mcu_readcredits += 1;
283 					return readinputport(2);
284 				}
285 				/* player 2 joystick and buttons */
286 				if (mcu_readcredits == 2)
287 				{
288 					return readinputport(3);
289 				}
290 
291 			default:
292 //logerror("error, unknown mcu command (%02x)\n",mcu_command);
293 				/* should not happen */
294 				return 0xff;
295 				break;
296 		}
297 	}
298 	else
299 	{
300 		/*
301 		status bits:
302 		0 = mcu is ready to send data (read from c000)
303 		1 = mcu has read data (from c000)
304 		2 = mcu is busy
305 		3 = unused
306 		4-7 = coin code
307 		      0 = nothing
308 		      1,2,3 = coin switch pressed
309 		      e = tilt
310 		*/
311 		if (mcu_reportcoin & 0x08) return 0xe1;	/* tilt */
312 		if (mcu_reportcoin & 0x01) return 0x11;	/* coin A */
313 		if (mcu_reportcoin & 0x02) return 0x21;	/* coin B */
314 		if (mcu_reportcoin & 0x04) return 0x31;	/* coin C */
315 		return 0x01;
316 	}
317 }
318 
WRITE_HANDLER(mcu_chukatai_w)319 static WRITE_HANDLER( mcu_chukatai_w )
320 {
321 	//logerror("PC %04x (re %04x): write %02x to mcu %04x\n", cpu_get_pc(), cpu_geturnpc(), data, 0xc000 + offset);
322 
323 	if (offset == 0)
324 	{
325 		if (mcu_command == 0x41)
326 		{
327 			mcu_credits = (mcu_credits + data) & 0xff;
328 		}
329 	}
330 	else
331 	{
332 		/*
333 		0x93: read number of credits, then joysticks/buttons
334 		0x03: read service & tilt switches
335 		0x1f: read coin switches
336 		0x4f+0x41: add value to number of credits
337 
338 		during initialization, a sequence of 4 bytes sets coin/credit settings
339 		*/
340 
341 		if (mcu_initializing)
342 		{
343 			/* set up coin/credit settings */
344 			mcu_coinage[mcu_coinage_init++] = data;
345 			if (mcu_coinage_init == 4) mcu_coinage_init = 0;	/* must not happen */
346 		}
347 
348 		if (data == 0x93)
349 			mcu_readcredits = 0;	/* reset input port number */
350 
351 		mcu_command = data;
352 	}
353 }
354 
355 
356 
READ_HANDLER(mcu_tnzs_r)357 static READ_HANDLER( mcu_tnzs_r )
358 {
359 	char *mcu_startup = "\x5a\xa5\x55";
360 
361 	//logerror("PC %04x (re %04x): read mcu %04x\n", cpu_get_pc(), cpu_geturnpc(), 0xc000 + offset);
362 
363 	if (offset == 0)
364 	{
365 		/* if the mcu has just been reset, return startup code */
366 		if (mcu_initializing)
367 		{
368 			mcu_initializing--;
369 			return mcu_startup[2 - mcu_initializing];
370 		}
371 
372 		switch (mcu_command)
373 		{
374 			case 0x01:
375 				return readinputport(2) ^ 0xff;	/* player 1 joystick + buttons */
376 
377 			case 0x02:
378 				return readinputport(3) ^ 0xff;	/* player 2 joystick + buttons */
379 
380 			case 0x1a:
381 				return readinputport(4) >> 4;
382 
383 			case 0x21:
384 				return readinputport(4) & 0x0f;
385 
386 			case 0x41:
387 				return mcu_credits;
388 
389 			case 0xa0:
390 				/* Read the credit counter */
391 				if (mcu_reportcoin & 0x08)
392 				{
393 					mcu_initializing = 3;
394 					return 0xee;	/* tilt */
395 				}
396 				else return mcu_credits;
397 
398 			case 0xa1:
399 				/* Read the credit counter or the inputs */
400 				if (mcu_readcredits == 0)
401 				{
402 					mcu_readcredits = 1;
403 					if (mcu_reportcoin & 0x08)
404 					{
405 						mcu_initializing = 3;
406 						return 0xee;	/* tilt */
407 //						return 0x64;	/* theres a reset input somewhere */
408 					}
409 					else return mcu_credits;
410 				}
411 				/* buttons */
412 				else return ((readinputport(2) & 0xf0) | (readinputport(3) >> 4)) ^ 0xff;
413 
414 			default:
415 //logerror("error, unknown mcu command\n");
416 				/* should not happen */
417 				return 0xff;
418 				break;
419 		}
420 	}
421 	else
422 	{
423 		/*
424 		status bits:
425 		0 = mcu is ready to send data (read from c000)
426 		1 = mcu has read data (from c000)
427 		2 = unused
428 		3 = unused
429 		4-7 = coin code
430 		      0 = nothing
431 		      1,2,3 = coin switch pressed
432 		      e = tilt
433 		*/
434 		if (mcu_reportcoin & 0x08) return 0xe1;	/* tilt */
435 		if (mcu_type == MCU_TNZS)
436 		{
437 			if (mcu_reportcoin & 0x01) return 0x31;	/* coin 1 (will trigger "coin inserted" sound) */
438 			if (mcu_reportcoin & 0x02) return 0x21;	/* coin 2 (will trigger "coin inserted" sound) */
439 			if (mcu_reportcoin & 0x04) return 0x11;	/* coin 3 (will NOT trigger "coin inserted" sound) */
440 		}
441 		else
442 		{
443 			if (mcu_reportcoin & 0x01) return 0x11;	/* coin 1 (will trigger "coin inserted" sound) */
444 			if (mcu_reportcoin & 0x02) return 0x21;	/* coin 2 (will trigger "coin inserted" sound) */
445 			if (mcu_reportcoin & 0x04) return 0x31;	/* coin 3 (will trigger "coin inserted" sound) */
446 		}
447 		return 0x01;
448 	}
449 }
450 
WRITE_HANDLER(mcu_tnzs_w)451 static WRITE_HANDLER( mcu_tnzs_w )
452 {
453 	if (offset == 0)
454 	{
455 		//logerror("PC %04x (re %04x): write %02x to mcu %04x\n", cpu_get_pc(), cpu_geturnpc(), data, 0xc000 + offset);
456 		if (mcu_command == 0x41)
457 		{
458 			mcu_credits = (mcu_credits + data) & 0xff;
459 		}
460 	}
461 	else
462 	{
463 		/*
464 		0xa0: read number of credits
465 		0xa1: read number of credits, then buttons
466 		0x01: read player 1 joystick + buttons
467 		0x02: read player 2 joystick + buttons
468 		0x1a: read coin switches
469 		0x21: read service & tilt switches
470 		0x4a+0x41: add value to number of credits
471 		0x84: coin 1 lockout (issued only in test mode)
472 		0x88: coin 2 lockout (issued only in test mode)
473 		0x80: release coin lockout (issued only in test mode)
474 		during initialization, a sequence of 4 bytes sets coin/credit settings
475 		*/
476 
477 		//logerror("PC %04x (re %04x): write %02x to mcu %04x\n", cpu_get_pc(), cpu_geturnpc(), data, 0xc000 + offset);
478 
479 		if (mcu_initializing)
480 		{
481 			/* set up coin/credit settings */
482 			mcu_coinage[mcu_coinage_init++] = data;
483 			if (mcu_coinage_init == 4) mcu_coinage_init = 0;	/* must not happen */
484 		}
485 
486 		if (data == 0xa1)
487 			mcu_readcredits = 0;	/* reset input port number */
488 
489 		/* Dr Toppel decrements credits differently. So handle it */
490 		if ((data == 0x09) && (mcu_type == MCU_DRTOPPEL))
491 			mcu_credits = (mcu_credits - 1) & 0xff;		/* Player 1 start */
492 		if ((data == 0x18) && (mcu_type == MCU_DRTOPPEL))
493 			mcu_credits = (mcu_credits - 2) & 0xff;		/* Player 2 start */
494 
495 		mcu_command = data;
496 	}
497 }
498 
499 
500 
init_extrmatn(void)501 void init_extrmatn(void)
502 {
503 	unsigned char *RAM = memory_region(REGION_CPU1);
504 
505 	mcu_type = MCU_EXTRMATN;
506 
507 	/* there's code which falls through from the fixed ROM to bank #7, I have to */
508 	/* copy it there otherwise the CPU bank switching support will not catch it. */
509 	memcpy(&RAM[0x08000],&RAM[0x2c000],0x4000);
510 }
511 
init_arkanoi2(void)512 void init_arkanoi2(void)
513 {
514 	unsigned char *RAM = memory_region(REGION_CPU1);
515 
516 	mcu_type = MCU_ARKANOID;
517 
518 	/* there's code which falls through from the fixed ROM to bank #2, I have to */
519 	/* copy it there otherwise the CPU bank switching support will not catch it. */
520 	memcpy(&RAM[0x08000],&RAM[0x18000],0x4000);
521 }
522 
init_drtoppel(void)523 void init_drtoppel(void)
524 {
525 	unsigned char *RAM = memory_region(REGION_CPU1);
526 
527 	mcu_type = MCU_DRTOPPEL;
528 
529 	/* there's code which falls through from the fixed ROM to bank #0, I have to */
530 	/* copy it there otherwise the CPU bank switching support will not catch it. */
531 	memcpy(&RAM[0x08000],&RAM[0x18000],0x4000);
532 }
533 
init_chukatai(void)534 void init_chukatai(void)
535 {
536 	unsigned char *RAM = memory_region(REGION_CPU1);
537 
538 	mcu_type = MCU_CHUKATAI;
539 
540 	/* there's code which falls through from the fixed ROM to bank #0, I have to */
541 	/* copy it there otherwise the CPU bank switching support will not catch it. */
542 	memcpy(&RAM[0x08000],&RAM[0x18000],0x4000);
543 }
544 
init_tnzs(void)545 void init_tnzs(void)
546 {
547 	unsigned char *RAM = memory_region(REGION_CPU1);
548 	mcu_type = MCU_TNZS;
549 
550 	/* there's code which falls through from the fixed ROM to bank #0, I have to */
551 	/* copy it there otherwise the CPU bank switching support will not catch it. */
552 	memcpy(&RAM[0x08000],&RAM[0x18000],0x4000);
553 }
554 
init_insectx(void)555 void init_insectx(void)
556 {
557 	mcu_type = MCU_NONE;
558 
559 	/* this game has no mcu, replace the handler with plain input port handlers */
560 	install_mem_read_handler(1, 0xc000, 0xc000, input_port_2_r );
561 	install_mem_read_handler(1, 0xc001, 0xc001, input_port_3_r );
562 	install_mem_read_handler(1, 0xc002, 0xc002, input_port_4_r );
563 }
564 
init_kageki(void)565 void init_kageki(void)
566 {
567 	/* this game has no mcu */
568 	mcu_type = MCU_NONE;
569 }
570 
571 
READ_HANDLER(tnzs_mcu_r)572 READ_HANDLER( tnzs_mcu_r )
573 {
574 	switch (mcu_type)
575 	{
576 		case MCU_ARKANOID:
577 			return mcu_arkanoi2_r(offset);
578 			break;
579 		case MCU_CHUKATAI:
580 			return mcu_chukatai_r(offset);
581 			break;
582 		case MCU_EXTRMATN:
583 		case MCU_DRTOPPEL:
584 		case MCU_TNZS:
585 		default:
586 			return mcu_tnzs_r(offset);
587 			break;
588 	}
589 }
590 
WRITE_HANDLER(tnzs_mcu_w)591 WRITE_HANDLER( tnzs_mcu_w )
592 {
593 	switch (mcu_type)
594 	{
595 		case MCU_ARKANOID:
596 			mcu_arkanoi2_w(offset,data);
597 			break;
598 		case MCU_CHUKATAI:
599 			mcu_chukatai_w(offset,data);
600 			break;
601 		case MCU_EXTRMATN:
602 		case MCU_DRTOPPEL:
603 		case MCU_TNZS:
604 		default:
605 			mcu_tnzs_w(offset,data);
606 			break;
607 	}
608 }
609 
tnzs_interrupt(void)610 int tnzs_interrupt(void)
611 {
612 	int coin;
613 
614 	switch (mcu_type)
615 	{
616 		case MCU_ARKANOID:
617 			coin = ((readinputport(5) & 0xf000) ^ 0xd000) >> 12;
618 			coin = (coin & 0x08) | ((coin & 0x03) << 1) | ((coin & 0x04) >> 2);
619 			mcu_handle_coins(coin);
620 			break;
621 
622 		case MCU_EXTRMATN:
623 		case MCU_DRTOPPEL:
624 			coin = (((readinputport(4) & 0x30) >> 4) | ((readinputport(4) & 0x03) << 2)) ^ 0x0c;
625 			mcu_handle_coins(coin);
626 			break;
627 
628 		case MCU_CHUKATAI:
629 		case MCU_TNZS:
630 			coin = (((readinputport(4) & 0x30) >> 4) | ((readinputport(4) & 0x03) << 2)) ^ 0x0f;
631 			mcu_handle_coins(coin);
632 			break;
633 
634 		case MCU_NONE:
635 		default:
636 			break;
637 	}
638 
639 	return 0;
640 }
641 
tnzs_init_machine(void)642 void tnzs_init_machine (void)
643 {
644 	/* initialize the mcu simulation */
645 	mcu_reset();
646 
647 	/* preset the banks */
648 	{
649 		unsigned char *RAM;
650 
651 		RAM = memory_region(REGION_CPU1);
652 		cpu_setbank(1,&RAM[0x18000]);
653 
654 		RAM = memory_region(REGION_CPU2);
655 		cpu_setbank(2,&RAM[0x10000]);
656 	}
657 }
658 
659 
READ_HANDLER(tnzs_workram_r)660 READ_HANDLER( tnzs_workram_r )
661 {
662 	/* Location $EF10 workaround required to stop TNZS getting */
663 	/* caught in and endless loop due to shared ram sync probs */
664 
665 	if ((offset == 0xf10) && (mcu_type == MCU_TNZS))
666 	{
667 		int tnzs_cpu0_pc;
668 
669 		tnzs_cpu0_pc = cpu_get_pc();
670 		switch (tnzs_cpu0_pc)
671 		{
672 			case 0xc66:		/* tnzs */
673 			case 0xc64:		/* tnzsb */
674 			case 0xab8:		/* tnzs2 */
675 				tnzs_workram[offset] = (tnzs_workram_backup & 0xff);
676 				return tnzs_workram_backup;
677 				break;
678 			default:
679 				break;
680 		}
681 	}
682 	return tnzs_workram[offset];
683 }
684 
READ_HANDLER(tnzs_workram_sub_r)685 READ_HANDLER( tnzs_workram_sub_r )
686 {
687 	return tnzs_workram[offset];
688 }
689 
WRITE_HANDLER(tnzs_workram_w)690 WRITE_HANDLER( tnzs_workram_w )
691 {
692 	/* Location $EF10 workaround required to stop TNZS getting */
693 	/* caught in and endless loop due to shared ram sync probs */
694 
695 	tnzs_workram_backup = -1;
696 
697 	if ((offset == 0xf10) && (mcu_type == MCU_TNZS))
698 	{
699 		int tnzs_cpu0_pc;
700 
701 		tnzs_cpu0_pc = cpu_get_pc();
702 		switch (tnzs_cpu0_pc)
703 		{
704 			case 0xab5:		/* tnzs2 */
705 				if (cpu_getpreviouspc() == 0xab4)
706 					break;  /* unfortunantly tnzsb is true here too, so stop it */
707 			case 0xc63:		/* tnzs */
708 			case 0xc61:		/* tnzsb */
709 				tnzs_workram_backup = data;
710 				break;
711 			default:
712 				break;
713 		}
714 	}
715 	if (tnzs_workram_backup == -1)
716 		tnzs_workram[offset] = data;
717 }
718 
WRITE_HANDLER(tnzs_workram_sub_w)719 WRITE_HANDLER( tnzs_workram_sub_w )
720 {
721 	tnzs_workram[offset] = data;
722 }
723 
WRITE_HANDLER(tnzs_bankswitch_w)724 WRITE_HANDLER( tnzs_bankswitch_w )
725 {
726 	unsigned char *RAM = memory_region(REGION_CPU1);
727 
728 	/* bit 4 resets the second CPU */
729 	if (data & 0x10)
730 		cpu_set_reset_line(1,CLEAR_LINE);
731 	else
732 		cpu_set_reset_line(1,ASSERT_LINE);
733 
734 	/* bits 0-2 select RAM/ROM bank */
735 //	logerror("PC %04x: writing %02x to bankswitch\n", cpu_get_pc(),data);
736 	cpu_setbank (1, &RAM[0x10000 + 0x4000 * (data & 0x07)]);
737 }
738 
WRITE_HANDLER(tnzs_bankswitch1_w)739 WRITE_HANDLER( tnzs_bankswitch1_w )
740 {
741 	unsigned char *RAM = memory_region(REGION_CPU2);
742 
743 //	logerror("PC %04x: writing %02x to bankswitch 1\n", cpu_get_pc(),data);
744 
745 	/* bit 2 resets the mcu */
746 	if (data & 0x04) mcu_reset();
747 
748 	/* bits 0-1 select ROM bank */
749 	cpu_setbank (2, &RAM[0x10000 + 0x2000 * (data & 3)]);
750 }
751