1 /***************************************************************************
2 
3 Namco System II
4 
5   machine.c
6 
7   Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
8   I/O ports)
9 
10 ***************************************************************************/
11 
12 #include "driver.h"
13 #include "cpu/m6809/m6809.h"
14 #include "cpu/m6805/m6805.h"
15 #include "namcos2.h"
16 #include "vidhrdw/generic.h"
17 #include "machine/random.h"
18 
19 data16_t *namcos2_68k_master_ram;
20 data16_t *namcos2_68k_slave_ram;
21 
22 int namcos2_gametype;
23 
24 static unsigned mFinalLapProtCount;
25 
READ16_HANDLER(namcos2_flap_prot_r)26 READ16_HANDLER( namcos2_flap_prot_r )
27 {
28 	const data16_t table0[8] = { 0x0000,0x0040,0x0440,0x2440,0x2480,0xa080,0x8081,0x8041 };
29 	const data16_t table1[8] = { 0x0040,0x0060,0x0060,0x0860,0x0864,0x08e4,0x08e5,0x08a5 };
30 	data16_t data;
31 
32 	switch( offset )
33 	{
34 	case 0:
35 		data = 0x0101;
36 		break;
37 
38 	case 1:
39 		data = 0x3e55;
40 		break;
41 
42 	case 2:
43 		data = table1[mFinalLapProtCount&7];
44 		data = (data&0xff00)>>8;
45 		break;
46 
47 	case 3:
48 		data = table1[mFinalLapProtCount&7];
49 		mFinalLapProtCount++;
50 		data = data&0x00ff;
51 		break;
52 
53 	case 0x3fffc/2:
54 		data = table0[mFinalLapProtCount&7];
55 		data = data&0xff00;
56 		break;
57 
58 	case 0x3fffe/2:
59 		data = table0[mFinalLapProtCount&7];
60 		mFinalLapProtCount++;
61 		data = (data&0x00ff)<<8;
62 		break;
63 
64 	default:
65 		data = 0;
66 	}
67 	return data;
68 }
69 
70 /*************************************************************/
71 /* Perform basic machine initialisation 					 */
72 /*************************************************************/
73 
MACHINE_INIT(namcos2)74 MACHINE_INIT( namcos2 ){
75 	int loop;
76 
77 	mFinalLapProtCount = 0;
78 
79 	/* Initialise the bank select in the sound CPU */
80 	namcos2_sound_bankselect_w(0,0); /* Page in bank 0 */
81 
82 	/* Place CPU2 & CPU3 into the reset condition */
83 	cpu_set_reset_line(NAMCOS2_CPU3, ASSERT_LINE);
84 	cpu_set_reset_line(NAMCOS2_CPU2, ASSERT_LINE);
85 	cpu_set_reset_line(NAMCOS2_CPU4, ASSERT_LINE);
86 
87 	/* Initialise interrupt handlers */
88 	for(loop=0;loop<20;loop++)
89 	{
90 		namcos2_68k_master_C148[loop]=0;
91 		namcos2_68k_slave_C148[loop]=0;
92 	}
93 }
94 
95 /*************************************************************/
96 /* EEPROM Load/Save and read/write handling 				 */
97 /*************************************************************/
98 
99 data16_t *namcos2_eeprom;
100 size_t namcos2_eeprom_size;
101 
NVRAM_HANDLER(namcos2)102 NVRAM_HANDLER( namcos2 ){
103 	if( read_or_write ){
104 		mame_fwrite (file, namcos2_eeprom, namcos2_eeprom_size);
105 	}
106 	else {
107 		if (file)
108 		{
109 			mame_fread (file, namcos2_eeprom, namcos2_eeprom_size);
110 		}
111 		else
112 		{
113 			memset (namcos2_eeprom, 0xff, namcos2_eeprom_size);
114 		}
115 	}
116 }
117 
WRITE16_HANDLER(namcos2_68k_eeprom_w)118 WRITE16_HANDLER( namcos2_68k_eeprom_w ){
119 	COMBINE_DATA( &namcos2_eeprom[offset] );
120 }
121 
READ16_HANDLER(namcos2_68k_eeprom_r)122 READ16_HANDLER( namcos2_68k_eeprom_r ){
123 	return namcos2_eeprom[offset];
124 }
125 
126 /*************************************************************/
127 /* 68000 Shared memory area - Data ROM area 				 */
128 /*************************************************************/
READ16_HANDLER(namcos2_68k_data_rom_r)129 READ16_HANDLER( namcos2_68k_data_rom_r ){
130 	data16_t *ROM = (data16_t *)memory_region(REGION_USER1);
131 	return ROM[offset];
132 }
133 
134 
135 
136 /**************************************************************/
137 /* 68000 Shared serial communications processor (CPU5?) 	  */
138 /**************************************************************/
139 
140 data16_t  namcos2_68k_serial_comms_ctrl[0x8];
141 data16_t *namcos2_68k_serial_comms_ram;
142 
READ16_HANDLER(namcos2_68k_serial_comms_ram_r)143 READ16_HANDLER( namcos2_68k_serial_comms_ram_r ){
144 	return namcos2_68k_serial_comms_ram[offset];
145 }
146 
WRITE16_HANDLER(namcos2_68k_serial_comms_ram_w)147 WRITE16_HANDLER( namcos2_68k_serial_comms_ram_w ){
148 	COMBINE_DATA( &namcos2_68k_serial_comms_ram[offset] );
149 }
150 
READ16_HANDLER(namcos2_68k_serial_comms_ctrl_r)151 READ16_HANDLER( namcos2_68k_serial_comms_ctrl_r )
152 {
153 	data16_t retval = namcos2_68k_serial_comms_ctrl[offset];
154 
155 	switch(offset){
156 	case 0x00:
157 		retval |= 0x0004; 	/* Set READY? status bit */
158 		break;
159 
160 	default:
161 		break;
162 	}
163 	return retval;
164 }
165 
WRITE16_HANDLER(namcos2_68k_serial_comms_ctrl_w)166 WRITE16_HANDLER( namcos2_68k_serial_comms_ctrl_w )
167 {
168 	COMBINE_DATA( &namcos2_68k_serial_comms_ctrl[offset] );
169 }
170 
171 /*************************************************************/
172 /* 68000 Shared protection/random key generator 			 */
173 /*************************************************************
174 
175 Custom chip ID numbers:
176 
177 Game		Year	ID (dec)	ID (hex)
178 --------	----	---			-----
179 finallap	1987
180 assault		1988	unused
181 metlhawk	1988
182 ordyne		1988	176			$00b0
183 mirninja	1988	177			$00b1
184 phelios		1988	178			$00b2	readme says 179
185 dirtfoxj	1989	180			$00b4
186 fourtrax	1989
187 valkyrie	1989
188 finehour	1989	188			$00bc
189 burnforc	1989	189			$00bd
190 marvland	1989	190			$00be
191 kyukaidk	1990	191			$00bf
192 dsaber		1990	192			$00c0
193 finalap2	1990	318			$013e
194 rthun2		1990	319			$013f
195 gollygho	1990				$0143
196 cosmogng	1991	330			$014a
197 sgunner2	1991	346			$015a	ID out of order; gfx board is not standard
198 finalap3	1992	318			$013e	same as finalap2
199 suzuka8h	1992
200 sws92		1992	331			$014b
201 sws92g		1992	332			$014c
202 suzuk8h2	1993
203 sws93		1993	334			$014e
204  *************************************************************/
205 static int sendval = 0;
READ16_HANDLER(namcos2_68k_key_r)206 READ16_HANDLER( namcos2_68k_key_r )
207 {
208 	switch (namcos2_gametype)
209 	{
210 	case NAMCOS2_ORDYNE:
211 		switch(offset)
212 		{
213 		case 2: return 0x1001;
214 		case 3: return 0x1;
215 		case 4: return 0x110;
216 		case 5: return 0x10;
217 		case 6: return 0xB0;
218 		case 7: return 0xB0;
219 		}
220 		break;
221 
222 	case NAMCOS2_STEEL_GUNNER_2:
223 		switch( offset )
224 		{
225 			case 4: return 0x15a;
226 		}
227 	    break;
228 
229 	case NAMCOS2_MIRAI_NINJA:
230 		switch(offset)
231 		{
232 		case 7: return 0xB1;
233 		}
234 	    break;
235 
236 	case NAMCOS2_PHELIOS:
237 		switch(offset)
238 		{
239 		case 0: return 0xF0;
240 		case 1: return 0xFF0;
241 		case 2: return 0xB2;
242 		case 3: return 0xB2;
243 		case 4: return 0xF;
244 		case 5: return 0xF00F;
245 		case 7: return 0xB2;
246 		}
247 	    break;
248 
249 	case NAMCOS2_DIRT_FOX_JP:
250 		switch(offset)
251 		{
252 		case 1: return 0xB4;
253 		}
254 		break;
255 
256 	case NAMCOS2_FINEST_HOUR:
257 		switch(offset)
258 		{
259 		case 7: return 0xBC;
260 		}
261 	    break;
262 
263 	case NAMCOS2_BURNING_FORCE:
264 		switch(offset)
265 		{
266 		case 1: return 0xBD;
267 		case 7: return 0xBD;
268 		}
269 		break;
270 
271 	case NAMCOS2_MARVEL_LAND:
272 		switch(offset)
273 		{
274 		case 0: return 0x10;
275 		case 1: return 0x110;
276 		case 4: return 0xBE;
277 		case 6: return 0x1001;
278 		case 7: return (sendval==1)?0xBE:1;
279 		}
280 	    break;
281 
282 	case NAMCOS2_DRAGON_SABER:
283 		switch(offset)
284 		{
285 		case 2: return 0xC0;
286 		}
287 		break;
288 
289 	case NAMCOS2_ROLLING_THUNDER_2:
290 		switch(offset)
291 		{
292 		case 4:
293 			if( sendval == 1 ){
294 		        sendval = 0;
295 		        return 0x13F;
296 			}
297 			break;
298 		case 7:
299 			if( sendval == 1 ){
300 			    sendval = 0;
301 			    return 0x13F;
302 			}
303 			break;
304 		case 2: return 0;
305 		}
306 		break;
307 
308 	case NAMCOS2_COSMO_GANG:
309 		switch(offset)
310 		{
311 		case 3: return 0x14A;
312 		}
313 		break;
314 
315 	case NAMCOS2_SUPER_WSTADIUM_92:
316 		switch(offset)
317 		{
318 		case 3: return 0x14B;
319 		}
320 		break;
321 
322 	case NAMCOS2_SUPER_WSTADIUM_92T:
323 		switch(offset)
324 		{
325 		case 3: return 0x14C;
326 		}
327 		break;
328 
329 	case NAMCOS2_SUPER_WSTADIUM_93:
330 		switch(offset)
331 		{
332 		case 3: return 0x14E;
333 		}
334 		break;
335 
336 	case NAMCOS2_SUZUKA_8_HOURS_2:
337 		switch(offset)
338 		{
339 		case 3: return 0x14D;
340 		case 2: return 0;
341 		}
342 		break;
343 
344 	case NAMCOS2_GOLLY_GHOST:
345 		switch(offset)
346 		{
347 		case 0: return 2;
348 		case 1: return 2;
349 		case 2: return 0;
350 		case 4: return 0x143;
351 		}
352 		break;
353 	}
354 	return mame_rand()&0xffff;
355 }
356 
WRITE16_HANDLER(namcos2_68k_key_w)357 WRITE16_HANDLER( namcos2_68k_key_w )
358 {
359 	if ((namcos2_gametype == NAMCOS2_MARVEL_LAND) && (offset == 5))
360 	{
361 		if (data == 0x615E) sendval = 1;
362 	}
363 	if ((namcos2_gametype == NAMCOS2_ROLLING_THUNDER_2) && (offset == 4)) {
364 		if (data == 0x13EC) sendval = 1;
365 	}
366 	if ((namcos2_gametype == NAMCOS2_ROLLING_THUNDER_2) && (offset == 7)) {
367 		if (data == 0x13EC) sendval = 1;
368 	}
369 	if ((namcos2_gametype == NAMCOS2_MARVEL_LAND) && (offset == 6)) {
370 		if (data == 0x1001) sendval = 0;
371 	}
372 }
373 
374 /*************************************************************/
375 /* 68000 Interrupt/IO Handlers - CUSTOM 148 - NOT SHARED	 */
376 /*************************************************************/
377 
378 #define NO_OF_LINES 	256
379 #define FRAME_TIME		(1.0/60.0)
380 #define LINE_LENGTH 	(FRAME_TIME/NO_OF_LINES)
381 
382 data16_t  namcos2_68k_master_C148[0x20];
383 data16_t  namcos2_68k_slave_C148[0x20];
384 
385 static data16_t
ReadC148(int cpu,offs_t offset)386 ReadC148( int cpu, offs_t offset )
387 {
388 	offs_t addr = ((offset*2)+0x1c0000)&0x1fe000;
389 	data16_t *pC148Reg;
390 	if( cpu == CPU_SLAVE )
391 	{
392 		pC148Reg = namcos2_68k_slave_C148;
393 	}
394 	else /* cpu == CPU_MASTER */
395 	{
396 		pC148Reg = namcos2_68k_master_C148;
397 	}
398 
399 	switch( addr )
400 	{
401 	case 0x1d8000: /* ack EXIRQ */
402 		cpu_set_irq_line(cpu, pC148Reg[NAMCOS2_C148_EXIRQ], CLEAR_LINE);
403 		break;
404 
405 	case 0x1da000: /* ack POSIRQ */
406 		cpu_set_irq_line(cpu, pC148Reg[NAMCOS2_C148_POSIRQ], CLEAR_LINE);
407 		break;
408 
409 	case 0x1dc000: /* ack NAMCOS2_C148_SERIRQ */
410 		cpu_set_irq_line(cpu, pC148Reg[NAMCOS2_C148_SERIRQ], CLEAR_LINE);
411 		break;
412 
413 	case 0x1de000: /* ack VBLANK */
414 		cpu_set_irq_line(cpu, pC148Reg[NAMCOS2_C148_VBLANKIRQ], CLEAR_LINE);
415 		break;
416 
417 	case 0x1e0000: /* EEPROM Status Register */
418 		return ~0; /* Only BIT0 used: 1=EEPROM READY 0=EEPROM BUSY */
419 
420 	default:
421 		break;
422 	}
423 	return pC148Reg[(addr>>13)&0x1f];
424 }
425 
426 static void
WriteC148(int cpu,offs_t offset,data16_t data)427 WriteC148( int cpu, offs_t offset, data16_t data )
428 {
429 	offs_t addr = ((offset*2)+0x1c0000)&0x1fe000;
430 	int altCPU;
431 	data16_t *pC148Reg;
432 	if( cpu == CPU_SLAVE )
433 	{
434 		altCPU = CPU_MASTER;
435 		pC148Reg = namcos2_68k_slave_C148;
436 	}
437 	else /* cpu == CPU_MASTER */
438 	{
439 		altCPU = CPU_SLAVE;
440 		pC148Reg = namcos2_68k_master_C148;
441 	}
442 
443 	pC148Reg[(addr>>13)&0x1f] = data&0x0007;
444 
445 	switch(addr){
446 	case 0x1c6000: /* Master/Slave IRQ level */
447 	case 0x1c8000: /* EXIRQ level */
448 	case 0x1ca000: /* POSIRQ level */
449 	case 0x1cc000: /* SCIRQ level */
450 	case 0x1ce000: /* VBLANK level */
451 		break;
452 
453 	case 0x1d4000: /* trigger master/slave interrupt */
454 		if( cpu == CPU_MASTER )
455 		{
456 			cpu_set_irq_line(altCPU, namcos2_68k_slave_C148[NAMCOS2_C148_CPUIRQ], ASSERT_LINE);
457 		}
458 		else /* cpu == CPU_SLAVE */
459 		{
460 			cpu_set_irq_line(altCPU, namcos2_68k_master_C148[NAMCOS2_C148_CPUIRQ], ASSERT_LINE);
461 		}
462 		break;
463 
464 	case 0x1d6000: /* ack master/slave interrupt */
465 	case 0x1d8000: /* ack EXIRQ */
466 	case 0x1da000: /* ack POSIRQ */
467 	case 0x1dc000: /* ack SCIRQ */
468 	case 0x1de000: /* ack VBLANK */
469 		(void)ReadC148( cpu, offset );
470 		break;
471 
472 	case 0x1e2000: /* Sound CPU Reset control */
473 		if( cpu == CPU_MASTER )
474 		{
475 			if(data&0x01)
476 			{
477 				/* Resume execution */
478 				cpu_set_reset_line (NAMCOS2_CPU3, CLEAR_LINE);
479 				cpu_yield();
480 			}
481 			else
482 			{
483 				/* Suspend execution */
484 				cpu_set_reset_line(NAMCOS2_CPU3, ASSERT_LINE);
485 			}
486 		}
487 		else
488 		{ /* HACK! */
489 			cpu_set_irq_line(
490 				CPU_SLAVE,
491 				namcos2_68k_master_C148[NAMCOS2_C148_POSIRQ],
492 				HOLD_LINE);
493 		}
494 		break;
495 
496 	case 0x1e4000: /* Alt 68000 & IO CPU Reset */
497 		if( cpu == CPU_MASTER )
498 		{
499 			if(data&0x01)
500 			{
501 				/* Resume execution */
502 				cpu_set_reset_line(altCPU, CLEAR_LINE);
503 				cpu_set_reset_line(NAMCOS2_CPU4, CLEAR_LINE);
504 				/* Give the new CPU an immediate slice of the action */
505 				cpu_yield();
506 			}
507 			else
508 			{
509 				/* Suspend execution */
510 				cpu_set_reset_line(altCPU, ASSERT_LINE);
511 				cpu_set_reset_line(NAMCOS2_CPU4, ASSERT_LINE);
512 			}
513 		}
514 		break;
515 
516 	case 0x1e6000: /* Watchdog reset kicker */
517 		/* watchdog_reset_w(0,0); */
518 		break;
519 
520 	default:
521 		break;
522 	}
523 }
524 
525 
WRITE16_HANDLER(namcos2_68k_master_C148_w)526 WRITE16_HANDLER( namcos2_68k_master_C148_w ){
527 	WriteC148( CPU_MASTER, offset, data );
528 }
529 
READ16_HANDLER(namcos2_68k_master_C148_r)530 READ16_HANDLER( namcos2_68k_master_C148_r ){
531 	return ReadC148( CPU_MASTER, offset );
532 }
533 
namcos2_68k_master_posirq(int scanline)534 void namcos2_68k_master_posirq( int scanline ){
535 	force_partial_update(scanline);
536 	cpu_set_irq_line(CPU_MASTER , namcos2_68k_master_C148[NAMCOS2_C148_POSIRQ] , ASSERT_LINE);
537 }
538 
539 static int
GetPosIRQScanline(void)540 GetPosIRQScanline( void )
541 {
542 	int scanline;
543 	switch( namcos2_gametype )
544 	{
545 		case NAMCOS2_FOUR_TRAX:
546 		scanline = 160;
547 		break;
548 
549 		case NAMCOS2_SUZUKA_8_HOURS_2:
550 		case NAMCOS2_SUZUKA_8_HOURS:
551 		scanline = 56;
552 		break;
553 
554 		case NAMCOS2_LUCKY_AND_WILD:
555 		scanline = 40;
556 		break;
557 
558 		case NAMCOS2_FINEST_HOUR:
559 		scanline = 192;
560 		break;
561 
562 		case NAMCOS2_BURNING_FORCE:
563 		scanline = 24; /* ? */
564 		break;
565 
566 		default: /* Final Lap */
567 		scanline = 64;
568 		break;
569 	}
570 	return scanline;
571 }
572 
INTERRUPT_GEN(namcos2_68k_master_vblank)573 INTERRUPT_GEN( namcos2_68k_master_vblank )
574 {
575 	if(namcos2_68k_master_C148[NAMCOS2_C148_POSIRQ])
576 	{
577 		int scanline = GetPosIRQScanline();
578 		timer_set( cpu_getscanlinetime(scanline), scanline, namcos2_68k_master_posirq );
579 	}
580 	cpu_set_irq_line( CPU_MASTER, namcos2_68k_master_C148[NAMCOS2_C148_VBLANKIRQ], HOLD_LINE);
581 }
582 
WRITE16_HANDLER(namcos2_68k_slave_C148_w)583 WRITE16_HANDLER( namcos2_68k_slave_C148_w ){
584 	WriteC148( CPU_SLAVE, offset, data );
585 }
586 
READ16_HANDLER(namcos2_68k_slave_C148_r)587 READ16_HANDLER( namcos2_68k_slave_C148_r )
588 {
589 	return ReadC148( CPU_SLAVE, offset );
590 }
591 
namcos2_68k_slave_posirq(int scanline)592 void namcos2_68k_slave_posirq( int scanline )
593 {
594 	force_partial_update(scanline);
595 	cpu_set_irq_line(CPU_SLAVE , namcos2_68k_slave_C148[NAMCOS2_C148_POSIRQ] , ASSERT_LINE);
596 }
597 
INTERRUPT_GEN(namcos2_68k_slave_vblank)598 INTERRUPT_GEN( namcos2_68k_slave_vblank ){
599 	if(namcos2_68k_slave_C148[NAMCOS2_C148_POSIRQ])
600 	{
601 		int scanline = GetPosIRQScanline();
602 		timer_set( cpu_getscanlinetime(scanline), scanline, namcos2_68k_slave_posirq );
603 	}
604 	cpu_set_irq_line( CPU_SLAVE, namcos2_68k_slave_C148[NAMCOS2_C148_VBLANKIRQ], HOLD_LINE);
605 }
606 
607 /**************************************************************/
608 /*	Sound sub-system										  */
609 /**************************************************************/
610 
WRITE_HANDLER(namcos2_sound_bankselect_w)611 WRITE_HANDLER( namcos2_sound_bankselect_w )
612 {
613 	unsigned char *RAM=memory_region(REGION_CPU3);
614 	unsigned long max = (memory_region_length(REGION_CPU3) - 0x10000) / 0x4000;
615 	int bank = ( data >> 4 ) % max;	/* 991104.CAB */
616 	cpu_setbank( CPU3_ROM1, &RAM[ 0x10000 + ( 0x4000 * bank ) ] );
617 }
618 
619 
620 
621 /**************************************************************/
622 /*															  */
623 /*	68705 IO CPU Support functions							  */
624 /*															  */
625 /**************************************************************/
626 
627 static int namcos2_mcu_analog_ctrl=0;
628 static int namcos2_mcu_analog_data=0xaa;
629 static int namcos2_mcu_analog_complete=0;
630 
WRITE_HANDLER(namcos2_mcu_analog_ctrl_w)631 WRITE_HANDLER( namcos2_mcu_analog_ctrl_w )
632 {
633 	namcos2_mcu_analog_ctrl=data&0xff;
634 
635 	/* Check if this is a start of conversion */
636 	/* Input ports 2 thru 9 are the analog channels */
637 	if(data&0x40)
638 	{
639 		/* Set the conversion complete flag */
640 		namcos2_mcu_analog_complete=2;
641 		/* We convert instantly, good eh! */
642 		switch((data>>2)&0x07)
643 		{
644 			case 0:
645 				namcos2_mcu_analog_data=input_port_2_r(0);
646 				break;
647 			case 1:
648 				namcos2_mcu_analog_data=input_port_3_r(0);
649 				break;
650 			case 2:
651 				namcos2_mcu_analog_data=input_port_4_r(0);
652 				break;
653 			case 3:
654 				namcos2_mcu_analog_data=input_port_5_r(0);
655 				break;
656 			case 4:
657 				namcos2_mcu_analog_data=input_port_6_r(0);
658 				break;
659 			case 5:
660 				namcos2_mcu_analog_data=input_port_7_r(0);
661 				break;
662 			case 6:
663 				namcos2_mcu_analog_data=input_port_8_r(0);
664 				break;
665 			case 7:
666 				namcos2_mcu_analog_data=input_port_9_r(0);
667 				break;
668 		}
669 #if 0
670 		/* Perform the offset handling on the input port */
671 		/* this converts it to a twos complement number */
672 		if( namcos2_gametype==NAMCOS2_DIRT_FOX ||
673 			namcos2_gametype==NAMCOS2_DIRT_FOX_JP )
674 		{
675 			namcos2_mcu_analog_data^=0x80;
676 		}
677 #endif
678 		/* If the interrupt enable bit is set trigger an A/D IRQ */
679 		if(data&0x20)
680 		{
681 			cpu_set_irq_line( CPU_MCU, HD63705_INT_ADCONV , PULSE_LINE);
682 		}
683 	}
684 }
685 
READ_HANDLER(namcos2_mcu_analog_ctrl_r)686 READ_HANDLER( namcos2_mcu_analog_ctrl_r )
687 {
688 	int data=0;
689 
690 	/* ADEF flag is only cleared AFTER a read from control THEN a read from DATA */
691 	if(namcos2_mcu_analog_complete==2) namcos2_mcu_analog_complete=1;
692 	if(namcos2_mcu_analog_complete) data|=0x80;
693 
694 	/* Mask on the lower 6 register bits, Irq EN/Channel/Clock */
695 	data|=namcos2_mcu_analog_ctrl&0x3f;
696 	/* Return the value */
697 	return data;
698 }
699 
WRITE_HANDLER(namcos2_mcu_analog_port_w)700 WRITE_HANDLER( namcos2_mcu_analog_port_w )
701 {
702 }
703 
READ_HANDLER(namcos2_mcu_analog_port_r)704 READ_HANDLER( namcos2_mcu_analog_port_r )
705 {
706 	if(namcos2_mcu_analog_complete==1) namcos2_mcu_analog_complete=0;
707 	return namcos2_mcu_analog_data;
708 }
709 
WRITE_HANDLER(namcos2_mcu_port_d_w)710 WRITE_HANDLER( namcos2_mcu_port_d_w )
711 {
712 	/* Undefined operation on write */
713 }
714 
READ_HANDLER(namcos2_mcu_port_d_r)715 READ_HANDLER( namcos2_mcu_port_d_r )
716 {
717 	/* Provides a digital version of the analog ports */
718 	int threshold=0x7f;
719 	int data=0;
720 
721 	/* Read/convert the bits one at a time */
722 	if(input_port_2_r(0)>threshold) data|=0x01;
723 	if(input_port_3_r(0)>threshold) data|=0x02;
724 	if(input_port_4_r(0)>threshold) data|=0x04;
725 	if(input_port_5_r(0)>threshold) data|=0x08;
726 	if(input_port_6_r(0)>threshold) data|=0x10;
727 	if(input_port_7_r(0)>threshold) data|=0x20;
728 	if(input_port_8_r(0)>threshold) data|=0x40;
729 	if(input_port_9_r(0)>threshold) data|=0x80;
730 
731 	/* Return the result */
732 	return data;
733 }
734 
READ_HANDLER(namcos2_input_port_0_r)735 READ_HANDLER( namcos2_input_port_0_r )
736 {
737 	int data=readinputport(0);
738 
739 	int one_joy_trans0[2][10]={
740         {0x05,0x01,0x09,0x08,0x0a,0x02,0x06,0x04,0x12,0x14},
741         {0x00,0x20,0x20,0x20,0x08,0x08,0x00,0x08,0x02,0x02}};
742 
743 	int datafake, i;
744 
745 	switch(namcos2_gametype)
746 	{
747 		case NAMCOS2_ASSAULT:
748 		case NAMCOS2_ASSAULT_JP:
749 		case NAMCOS2_ASSAULT_PLUS:
750 			datafake=~readinputport(15) & 0xff;
751 			log_cb(RETRO_LOG_DEBUG, LOGPRE "xxx=%08x\n",datafake);
752 			for (i=0;i<10;i++)
753 				if (datafake==one_joy_trans0[0][i])
754 				{
755 					data&=~one_joy_trans0[1][i];
756 					break;
757 				}
758 	}
759 	return data;
760 }
761 
READ_HANDLER(namcos2_input_port_10_r)762 READ_HANDLER( namcos2_input_port_10_r )
763 {
764 	int data=readinputport(10);
765 
766 	int one_joy_trans10[2][10]={
767         {0x05,0x01,0x09,0x08,0x0a,0x02,0x06,0x04,0x1a,0x18},
768         {0x08,0x08,0x00,0x02,0x00,0x02,0x02,0x08,0x80,0x80}};
769 
770 	int datafake, i;
771 
772 	switch(namcos2_gametype)
773 	{
774 		case NAMCOS2_ASSAULT:
775 		case NAMCOS2_ASSAULT_JP:
776 		case NAMCOS2_ASSAULT_PLUS:
777 			datafake=~readinputport(15) & 0xff;
778 			for (i=0;i<10;i++)
779 				if (datafake==one_joy_trans10[0][i])
780 				{
781 					data&=~one_joy_trans10[1][i];
782 					break;
783 				}
784 	}
785 	return data;
786 }
787 
READ_HANDLER(namcos2_input_port_12_r)788 READ_HANDLER( namcos2_input_port_12_r )
789 {
790 	int data=readinputport(12);
791 
792 	int one_joy_trans12[2][4]={
793         {0x12,0x14,0x11,0x18},
794         {0x02,0x08,0x08,0x02}};
795 
796 	int datafake, i;
797 
798 	switch(namcos2_gametype)
799 	{
800 		case NAMCOS2_ASSAULT:
801 		case NAMCOS2_ASSAULT_JP:
802 		case NAMCOS2_ASSAULT_PLUS:
803 			datafake=~readinputport(15) & 0xff;
804 			for (i=0;i<4;i++)
805 				if (datafake==one_joy_trans12[0][i])
806 				{
807 					data&=~one_joy_trans12[1][i];
808 					break;
809 				}
810 	}
811 	return data;
812 }
813