1 // FB Neo Tecmo System driver module
2 // Based on MAME driver by Farfetch, David Haywood, Tomasz Slanina, and nuapete
3 
4 #include "tiles_generic.h"
5 #include "m68000_intf.h"
6 #include "msm6295.h"
7 #include "eeprom.h"
8 #include "ymz280b.h"
9 #include "burn_ymf262.h"
10 #include "z80_intf.h"
11 #include "watchdog.h"
12 
13 static UINT8 *AllMem;
14 static UINT8 *MemEnd;
15 static UINT8 *AllRam;
16 static UINT8 *RamEnd;
17 static UINT8 *Drv68KROM;
18 static UINT8 *DrvSprROM;
19 static UINT8 *DrvGfxROM0;
20 static UINT8 *DrvGfxROM1;
21 static UINT8 *DrvGfxROM2;
22 static UINT8 *DrvGfxROM3;
23 
24 static UINT8 *Drv68KRAM;
25 static UINT8 *DrvSprRAM;
26 static UINT8 *DrvPalRAM;
27 static UINT8 *DrvTxtRAM;
28 static UINT8 *DrvBgRAM0;
29 static UINT8 *DrvBgRAM1;
30 static UINT8 *DrvBgRAM2;
31 static UINT8 *DrvBgScrRAM0;
32 static UINT8 *DrvBgScrRAM1;
33 static UINT8 *DrvBgScrRAM2;
34 static UINT8 *spritelist_select;
35 static UINT8 *Drv88Regs;
36 static UINT8 *DrvA8Regs;
37 static UINT8 *DrvB0Regs;
38 static UINT8 *DrvC0Regs;
39 static UINT8 *DrvC8Regs;
40 
41 static UINT8 *DrvZ80ROM;
42 static UINT8 *DrvZ80RAM;
43 static UINT8 *DrvSndROM0;
44 static UINT8 *DrvSndROM1;
45 static UINT8 *DrvOkiBank;
46 static UINT8 *DrvZ80Bank;
47 static UINT8 *soundlatch;
48 static UINT8 *soundlatch2;
49 
50 static UINT8 protection_read_pointer;
51 static UINT8 protection_status;
52 static UINT8 protection_value;
53 
54 static UINT16 *DrvTmpSprites;
55 
56 static UINT32 *DrvPalette;
57 static UINT32 *DrvPalette24;
58 static UINT8 DrvRecalc;
59 
60 static UINT8 DrvJoy1[16];
61 static UINT8 DrvJoy2[16];
62 static UINT8 DrvReset;
63 static UINT16 DrvInputs[2];
64 
65 static INT32 vblank;
66 static INT32 deroon;
67 
68 static struct BurnInputInfo DrvInputList[] = {
69 	{"P1 Coin",		    BIT_DIGITAL,	DrvJoy1 + 8,	"p1 coin"	},
70 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 7,	"p1 start"	},
71 	{"P1 Up",		    BIT_DIGITAL,	DrvJoy1 + 0,	"p1 up"		},
72 	{"P1 Down",		    BIT_DIGITAL,	DrvJoy1 + 1,	"p1 down"	},
73 	{"P1 Left",		    BIT_DIGITAL,	DrvJoy1 + 2,	"p1 left"	},
74 	{"P1 Right",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 right"	},
75 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 4,	"p1 fire 1"	},
76 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 fire 2"	},
77 	{"P1 Button 3",		BIT_DIGITAL,	DrvJoy1 + 6,	"p1 fire 3"	},
78 	{"P1 Button 4",		BIT_DIGITAL,	DrvJoy1 + 10,	"p1 fire 4"	},
79 
80 	{"P2 Start",		BIT_DIGITAL,	DrvJoy2 + 7,	"p2 start"	},
81 	{"P2 Up",		    BIT_DIGITAL,	DrvJoy2 + 0,	"p2 up"		},
82 	{"P2 Down",		    BIT_DIGITAL,	DrvJoy2 + 1,	"p2 down"	},
83 	{"P2 Left",		    BIT_DIGITAL,	DrvJoy2 + 2,	"p2 left"	},
84 	{"P2 Right",		BIT_DIGITAL,	DrvJoy2 + 3,	"p2 right"	},
85 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy2 + 4,	"p2 fire 1"	},
86 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy2 + 5,	"p2 fire 2"	},
87 	{"P2 Button 3",		BIT_DIGITAL,	DrvJoy2 + 6,	"p2 fire 3"	},
88 	{"P2 Button 4",		BIT_DIGITAL,	DrvJoy2 + 10,	"p2 fire 4"	},
89 
90 	{"Reset",		    BIT_DIGITAL,	&DrvReset,	    "reset"		},
91 	{"Service Mode",	BIT_DIGITAL,	DrvJoy1 + 9,	"diag"	    },
92 	{"Service",		    BIT_DIGITAL,	DrvJoy2 + 9,	"service"	},
93 };
94 
95 STDINPUTINFO(Drv)
96 
97 struct prot_data
98 {
99 	UINT8 passwd_len;
100 	const UINT8* passwd;
101 	const UINT8* code;
102 	UINT8 checksums[4];
103 };
104 
105 static const struct prot_data *protection_data;
106 
107 static const UINT8 deroon_passwd[] = { 'L', 'U', 'N', 'A', 0 };
108 static const UINT8 deroon_upload[] = { 0x02, 0x4e, 0x75, 0x00 };
109 static const struct prot_data deroon_data  = { 0x05, deroon_passwd, deroon_upload, { 0xa6, 0x29, 0x4b, 0x3f } };
110 
111 static const UINT8 tkdensho_passwd[] = { 'A','G','E','P','R','O','T','E','C','T',' ','S','T','A','R','T', 0 };
112 static const UINT8 tkdensho_upload[] = { 0x06, 0x4e, 0xf9, 0x00, 0x00, 0x22, 0xc4, 0x00 };
113 static const struct prot_data tkdensho_data  = { 0x11, tkdensho_passwd, tkdensho_upload, { 0xbf, 0xfa, 0xda, 0xda } };
114 static const struct prot_data tkdenshoa_data = { 0x11, tkdensho_passwd, tkdensho_upload, { 0xbf, 0xfa, 0x21, 0x5d } };
115 
protection_reset()116 static void protection_reset()
117 {
118 	protection_read_pointer = 0;
119 	protection_status = 0; // idle
120 	protection_value = 0xff;
121 }
122 
tecmosys_prot_data_write(INT32 data)123 static void tecmosys_prot_data_write(INT32 data)
124 {
125 	static const UINT8 ranges[] = {
126 		0x10,0x11,0x12,0x13,
127 		0x24,0x25,0x26,0x27,
128 		0x38,0x39,0x3a,0x3b,
129 		0x4c,0x4d,0x4e,0x4f,
130 		0x00
131 	};
132 
133 	switch (protection_status)
134 	{
135 		case 0: // idle
136 			if (data == 0x13)
137 			{
138 				protection_status = 1; // login
139 				protection_value = protection_data->passwd_len;
140 				protection_read_pointer = 0;
141 				break;
142 			}
143 			break;
144 
145 		case 1: // login
146 			if (protection_read_pointer >= protection_data->passwd_len)
147 			{
148 				protection_status = 2; // send code
149 				protection_value = protection_data->code[0];
150 				protection_read_pointer = 1;
151 			}
152 			else
153 				protection_value = protection_data->passwd[protection_read_pointer++] == data ? 0 : 0xff;
154 			break;
155 
156 		case 2: // send code
157 			if (protection_read_pointer >= protection_data->code[0]+2)
158 			{
159 				protection_status = 3; // send address
160 				protection_value = ranges[0];
161 				protection_read_pointer = 1;
162 			}
163 			else
164 				protection_value = data == protection_data->code[protection_read_pointer-1] ? protection_data->code[protection_read_pointer++] : 0xff;
165 			break;
166 
167 		case 3: // send address
168 			if (protection_read_pointer >= 17)
169 			{
170 				protection_status = 4; // send checksum
171 				protection_value = 0;
172 				protection_read_pointer = 0;
173 			}
174 			else
175 			{
176 				protection_value = data == ranges[protection_read_pointer-1] ? ranges[protection_read_pointer++] : 0xff;
177 			}
178 			break;
179 
180 		case 4: // send checksum
181 			if (protection_read_pointer >= 5)
182 			{
183 				protection_status = 5; // done
184 				protection_value = 0;
185 			}
186 			else
187 				protection_value = data == protection_data->checksums[protection_read_pointer] ? protection_data->checksums[protection_read_pointer++] : 0xff;
188 			break;
189 
190 		case 5: // done
191 			break;
192 	}
193 }
194 
cpu_sync()195 static inline void cpu_sync() // sync z80 & 68k
196 {
197 	INT32 t = (SekTotalCycles() / 2) - ZetTotalCycles();
198 
199 	if (t > 0) {
200 		BurnTimerUpdate(t);
201 	}
202 }
203 
tecmosys_main_write_word(UINT32 address,UINT16 data)204 static void __fastcall tecmosys_main_write_word(UINT32 address, UINT16 data)
205 {
206 	switch (address)
207 	{
208 		case 0x880000:
209 		case 0x880002:
210 			*((UINT16*)(Drv88Regs + (address & 0x02))) = data;
211 		return;
212 
213 		case 0x880008:
214 			*spritelist_select = data & 0x03;
215 		return;
216 
217 		case 0x880022:
218 			BurnWatchdogWrite();
219 		return;
220 
221 		case 0xa00000:
222 			EEPROMWrite((data & 0x0400), (data & 0x0200), (data & 0x0800));
223 		return;
224 
225 		case 0xa80000:
226 		case 0xa80002:
227 		case 0xa80004:
228 			*((UINT16*)(DrvA8Regs + (address & 0x06))) = data;
229 		return;
230 
231 		case 0xb00000:
232 		case 0xb00002:
233 		case 0xb00004:
234 			*((UINT16*)(DrvB0Regs + (address & 0x06))) = data;
235 		return;
236 
237 		case 0xb80000: // protection status - does nothing
238 		return;
239 
240 		case 0xc00000:
241 		case 0xc00002:
242 		case 0xc00004:
243 			*((UINT16*)(DrvC0Regs + (address & 0x06))) = data;
244 		return;
245 
246 		case 0xc80000:
247 		case 0xc80002:
248 		case 0xc80004:
249 			*((UINT16*)(DrvC8Regs + (address & 0x06))) = data;
250 		return;
251 
252 		case 0xe00000:
253 			cpu_sync();
254 			*soundlatch = data & 0xff;
255 			ZetNmi();
256 		return;
257 
258 		case 0xe80000:
259 			tecmosys_prot_data_write(data >> 8);
260 		return;
261 	}
262 
263 	//bprintf(0, _T("ww: %X  %x\n"), address, data);
264 }
265 
tecmosys_main_write_byte(UINT32 address,UINT8 data)266 static void __fastcall tecmosys_main_write_byte(UINT32 address, UINT8 data)
267 {
268 	//bprintf(0, _T("wb: %X  %x\n"), address, data);
269 }
270 
tecmosys_main_read_word(UINT32 address)271 static UINT16 __fastcall tecmosys_main_read_word(UINT32 address)
272 {
273 	switch (address)
274 	{
275 		case 0x880000:
276 			return vblank ^ 1;
277 
278 		case 0xd00000:
279 			return DrvInputs[0];
280 
281 		case 0xd00002:
282 			return DrvInputs[1];
283 
284 		case 0xd80000:
285 			return (EEPROMRead() & 1) << 11;
286 
287 		case 0xf00000:
288 			cpu_sync();
289 			return *soundlatch2;
290 
291 		case 0xf80000:
292 			INT32 ret = protection_value;
293 			protection_value = 0xff;
294 			return ret << 8;
295 	}
296 
297 	return 0;
298 }
299 
tecmosys_main_read_byte(UINT32 address)300 static UINT8 __fastcall tecmosys_main_read_byte(UINT32 address)
301 {
302 	switch (address)
303 	{
304 		case 0xb80000:
305 			return 0x00; // protection status
306 	}
307 
308 	//bprintf(0, _T("rb: %X  %x\n"), address);
309 
310 	return 0;
311 }
312 
palette_update(INT32 pal)313 static inline void palette_update(INT32 pal)
314 {
315 	UINT16 p = BURN_ENDIAN_SWAP_INT16(*((UINT16*)(DrvPalRAM + pal * 2)));
316 
317 	INT32 r = (p >>  5) & 0x1f;
318 	INT32 g = (p >> 10) & 0x1f;
319 	INT32 b = (p >>  0) & 0x1f;
320 
321 	r = (r << 3) | (r >> 2);
322 	g = (g << 3) | (g >> 2);
323 	b = (b << 3) | (b >> 2);
324 
325 	DrvPalette[pal] = BurnHighCol(r, g, b, 0);
326 	DrvPalette24[pal] = (r << 16) + (g << 8) + b;
327 }
328 
tecmosys_palette_write_word(UINT32 address,UINT16 data)329 static void __fastcall tecmosys_palette_write_word(UINT32 address, UINT16 data)
330 {
331 	if ((address & 0xff8000) == 0x900000) {
332 		*((UINT16 *)(DrvPalRAM + 0x0000 + (address & 0x7ffe))) = BURN_ENDIAN_SWAP_INT16(data);
333 		palette_update((0x0000 + (address & 0x7ffe)) / 2);
334 		return;
335 	}
336 
337 	if ((address & 0xfff000) == 0x980000) {
338 		*((UINT16 *)(DrvPalRAM + 0x8000 + (address & 0x0ffe))) = BURN_ENDIAN_SWAP_INT16(data);
339 		palette_update((0x8000 + (address & 0x0ffe)) / 2);
340 		return;
341 	}
342 }
343 
tecmosys_palette_write_byte(UINT32 address,UINT8 data)344 static void __fastcall tecmosys_palette_write_byte(UINT32 address, UINT8 data)
345 {
346 	if ((address & 0xff8000) == 0x900000) {
347 		DrvPalRAM[(0x0000 + (address & 0x7fff)) ^ 1] = data;
348 		palette_update((0x0000 + (address & 0x7ffe)) / 2);
349 		return;
350 	}
351 
352 	if ((address & 0xfff000) == 0x980000) {
353 		DrvPalRAM[(0x8000 + (address & 0x0fff)) ^ 1] = data;
354 		palette_update((0x8000 + (address & 0x0ffe)) / 2);
355 		return;
356 	}
357 }
358 
bankswitch(INT32 data)359 static void bankswitch(INT32 data)
360 {
361 	ZetMapMemory(DrvZ80ROM + (data & 0x0f) * 0x4000, 0x8000, 0xbfff, MAP_ROM);
362 
363 	*DrvZ80Bank = data & 0x0f;
364 }
365 
oki_bankswitch(INT32 data)366 static void oki_bankswitch(INT32 data)
367 {
368 	INT32 upperbank = (data & 0x30) >> 4;
369 	INT32 lowerbank = (data & 0x03) >> 0;
370 
371 	MSM6295SetBank(0, DrvSndROM0 + lowerbank * 0x20000, 0x00000, 0x1ffff);
372 	MSM6295SetBank(0, DrvSndROM0 + upperbank * 0x20000, 0x20000, 0x3ffff);
373 
374 	*DrvOkiBank = data & 0x33;
375 }
376 
tecmosys_sound_out(UINT16 port,UINT8 data)377 static void __fastcall tecmosys_sound_out(UINT16 port, UINT8 data)
378 {
379 	switch (port & 0xff)
380 	{
381 		case 0x00:
382 		case 0x01:
383 		case 0x02:
384 		case 0x03:
385 			BurnYMF262Write(port & 3, data);
386 		return;
387 
388 		case 0x10:
389 			MSM6295Write(0, data);
390 		return;
391 
392 		case 0x20:
393 			oki_bankswitch(data);
394 		return;
395 
396 		case 0x30:
397 			bankswitch(data);
398 		return;
399 
400 		case 0x50:
401 			*soundlatch2 = data;
402 		return;
403 
404 		case 0x60:
405 		case 0x61:
406 			YMZ280BWrite(port & 1, data);
407 		return;
408 	}
409 }
410 
tecmosys_sound_in(UINT16 port)411 static UINT8 __fastcall tecmosys_sound_in(UINT16 port)
412 {
413 	switch (port & 0xff)
414 	{
415 		case 0x00:
416 		case 0x01:
417 		case 0x02:
418 		case 0x03:
419 			return BurnYMF262Read(port & 3);
420 
421 		case 0x10:
422 			return MSM6295Read(0);
423 
424 		case 0x40:
425 			return *soundlatch;
426 
427 		case 0x60:
428 		case 0x61:
429 			return YMZ280BRead(port & 1);
430 	}
431 
432 	return 0;
433 }
434 
tilemap_callback(txt)435 static tilemap_callback( txt )
436 {
437 	UINT16 *vram = (UINT16*)DrvTxtRAM;
438 
439 	INT32 attr  = BURN_ENDIAN_SWAP_INT16(vram[offs * 2 + 0]);
440 	INT32 code  = BURN_ENDIAN_SWAP_INT16(vram[offs * 2 + 1]);
441 
442 	TILE_SET_INFO(0, code, attr, TILE_FLIPYX(attr >> 6));
443 }
444 
tilemap_callback(bg0)445 static tilemap_callback( bg0 )
446 {
447 	UINT16 *vram = (UINT16*)DrvBgRAM0;
448 
449 	INT32 attr  = BURN_ENDIAN_SWAP_INT16(vram[offs * 2 + 0]);
450 	INT32 code  = BURN_ENDIAN_SWAP_INT16(vram[offs * 2 + 1]);
451 
452 	TILE_SET_INFO(1, code, attr, TILE_FLIPYX(attr >> 6));
453 }
454 
tilemap_callback(bg1)455 static tilemap_callback( bg1 )
456 {
457 	UINT16 *vram = (UINT16*)DrvBgRAM1;
458 
459 	INT32 attr  = BURN_ENDIAN_SWAP_INT16(vram[offs * 2 + 0]);
460 	INT32 code  = BURN_ENDIAN_SWAP_INT16(vram[offs * 2 + 1]);
461 
462 	TILE_SET_INFO(2, code, attr, TILE_FLIPYX(attr >> 6));
463 }
464 
tilemap_callback(bg2)465 static tilemap_callback( bg2 )
466 {
467 	UINT16 *vram = (UINT16*)DrvBgRAM2;
468 
469 	INT32 attr  = BURN_ENDIAN_SWAP_INT16(vram[offs * 2 + 0]);
470 	INT32 code  = BURN_ENDIAN_SWAP_INT16(vram[offs * 2 + 1]);
471 
472 	TILE_SET_INFO(3, code, attr, TILE_FLIPYX(attr >> 6));
473 }
474 
DrvFMIRQHandler(INT32,INT32 nStatus)475 static void DrvFMIRQHandler(INT32, INT32 nStatus)
476 {
477 	ZetSetIRQLine(0, (nStatus) ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE);
478 }
479 
DrvSynchroniseStream(INT32 nSoundRate)480 static INT32 DrvSynchroniseStream(INT32 nSoundRate)
481 {
482 	return (INT64)ZetTotalCycles() * nSoundRate / 8000000;
483 }
484 
DrvDoReset(INT32 clear_mem)485 static INT32 DrvDoReset(INT32 clear_mem)
486 {
487 	if (clear_mem) {
488 		memset(AllRam, 0, RamEnd - AllRam);
489 	}
490 
491 	SekOpen(0);
492 	SekReset();
493 	SekClose();
494 
495 	EEPROMReset();
496 
497 	protection_reset();
498 
499 	BurnWatchdogResetEnable();
500 
501 	ZetOpen(0);
502 	bankswitch(0);
503 	ZetReset();
504 	BurnYMF262Reset();
505 	ZetClose();
506 
507 	YMZ280BReset();
508 	MSM6295Reset();
509 	oki_bankswitch(0);
510 
511 	return 0;
512 }
513 
MemIndex(INT32 sndlen)514 static INT32 MemIndex(INT32 sndlen)
515 {
516 	UINT8 *Next; Next = AllMem;
517 
518 	Drv68KROM			= Next; Next += 0x100000;
519 
520 	DrvGfxROM0			= Next; Next += 0x200000;
521 	DrvGfxROM1			= Next; Next += 0x200000;
522 	DrvGfxROM2			= Next; Next += 0x200000;
523 	DrvGfxROM3			= Next; Next += 0x200000;
524 
525 	DrvZ80ROM			= Next; Next += 0x040000;
526 
527 	MSM6295ROM			= Next;
528 	DrvSndROM0			= Next; Next += 0x100000;
529 
530 	YMZ280BROM			= Next;
531 	DrvSndROM1			= Next; Next += sndlen;
532 
533 	DrvPalette			= (UINT32*)Next; Next += 0x4800 * sizeof(UINT32);
534 	DrvPalette24		= (UINT32*)Next; Next += 0x4800 * sizeof(UINT32);
535 
536 	DrvTmpSprites		= (UINT16*)Next; Next += 320 * 256 * sizeof(UINT16);
537 
538 	AllRam				= Next;
539 
540 	Drv68KRAM			= Next; Next += 0x010000;
541 	DrvSprRAM			= Next; Next += 0x010000;
542 	DrvPalRAM			= Next; Next += 0x009000;
543 
544 	DrvTxtRAM			= Next; Next += 0x004000;
545 
546 	DrvBgRAM0			= Next; Next += 0x001000;
547 	DrvBgScrRAM0		= Next; Next += 0x000400;
548 	DrvBgRAM1			= Next; Next += 0x001000;
549 	DrvBgScrRAM1		= Next; Next += 0x000400;
550 	DrvBgRAM2			= Next; Next += 0x001000;
551 	DrvBgScrRAM2		= Next; Next += 0x000400;
552 
553 	DrvOkiBank 			= Next; Next += 0x000001 * sizeof(UINT32);
554 	DrvZ80Bank 			= Next; Next += 0x000001 * sizeof(UINT32);
555 
556 	DrvZ80RAM			= Next; Next += 0x001800;
557 
558 	soundlatch 			= Next; Next += 0x000001 * sizeof(UINT32);
559 	soundlatch2 		= Next; Next += 0x000001 * sizeof(UINT32);
560 
561 	spritelist_select	= Next; Next += 0x000001 * sizeof(UINT32);
562 
563 	Drv88Regs			= Next; Next += 0x000004;
564 	DrvA8Regs			= Next; Next += 0x000006;
565 	DrvB0Regs			= Next; Next += 0x000006;
566 	DrvC0Regs			= Next; Next += 0x000006;
567 	DrvC8Regs			= Next; Next += 0x000006;
568 
569 	RamEnd				= Next;
570 
571 	MemEnd				= Next;
572 
573 	return 0;
574 }
575 
descramble_sprites(INT32 len)576 static void descramble_sprites(INT32 len)
577 {
578 	UINT8 *src = DrvSprROM;
579 	UINT8 tmp[4];
580 
581 	for (INT32 i=0; i < len; i+=4)
582 	{
583 		tmp[0] = ((src[i+2]&0xf0)>>0) | ((src[i+3]&0xf0)>>4);
584 		tmp[1] = ((src[i+2]&0x0f)<<4) | ((src[i+3]&0x0f)>>0);
585 		tmp[2] = ((src[i+0]&0xf0)>>0) | ((src[i+1]&0xf0)>>4);
586 		tmp[3] = ((src[i+0]&0x0f)<<4) | ((src[i+1]&0x0f)<<0);
587 
588 		memcpy (src + i, tmp, 4);
589 	}
590 }
591 
expand_tiles(UINT8 * rom,INT32 len)592 static void expand_tiles(UINT8 *rom, INT32 len)
593 {
594 	INT32 Planes[4] = { STEP4(0,1) };
595 	INT32 XOffs[16] = { STEP8(0,4), STEP8(256,4) };
596 	INT32 YOffs[16] = { STEP8(0,32), STEP8(512,32) };
597 
598 	UINT8 *tmp = (UINT8*)BurnMalloc(len);
599 
600 	memcpy (tmp, rom, len);
601 
602 	GfxDecode((len * 2) / (16 * 16), 4, 16, 16, Planes, XOffs, YOffs, 128*8, tmp, rom);
603 
604 	BurnFree (tmp);
605 }
606 
CommonInit(INT32 (* pRomLoadCallback)(),INT32 spritelen,INT32 sndlen,const struct prot_data * dev_data_pointer,INT32 game)607 static INT32 CommonInit(INT32 (*pRomLoadCallback)(), INT32 spritelen, INT32 sndlen, const struct prot_data *dev_data_pointer, INT32 game)
608 {
609 	AllMem = NULL;
610 	MemIndex(sndlen);
611 	INT32 nLen = MemEnd - (UINT8 *)0;
612 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
613 	memset(AllMem, 0, nLen);
614 	MemIndex(sndlen);
615 
616 	DrvSprROM = (UINT8*)BurnMalloc(spritelen);
617 	if (DrvSprROM == NULL) return 1;
618 
619 	if (pRomLoadCallback) {
620 		if (pRomLoadCallback()) return 1;
621 	}
622 
623 	descramble_sprites(spritelen);
624 	BurnNibbleExpand(DrvGfxROM0, NULL, 0x100000, 0, 0);
625 	expand_tiles(DrvGfxROM1, 0x100000);
626 	expand_tiles(DrvGfxROM2, 0x100000);
627 	expand_tiles(DrvGfxROM3, 0x100000);
628 
629 	SekInit(0, 0x68000);
630 	SekOpen(0);
631 	SekMapMemory(Drv68KROM,				0x000000, 0x0fffff, MAP_ROM);
632 	SekMapMemory(Drv68KRAM,				0x200000, 0x20ffff, MAP_RAM);
633 	SekMapMemory(DrvBgRAM0,				0x300000, 0x300fff, MAP_RAM);
634 	SekMapMemory(DrvBgScrRAM0,			0x301000, 0x3013ff, MAP_RAM);
635 	SekMapMemory(DrvBgRAM1,				0x400000, 0x400fff, MAP_RAM);
636 	SekMapMemory(DrvBgScrRAM1,			0x401000, 0x4013ff, MAP_RAM);
637 	SekMapMemory(DrvBgRAM2,				0x500000, 0x500fff, MAP_RAM);
638 	SekMapMemory(DrvBgScrRAM2,			0x501000, 0x5013ff, MAP_RAM);
639 	SekMapMemory(DrvTxtRAM,				0x700000, 0x703fff, MAP_RAM);
640 	SekMapMemory(DrvSprRAM,				0x800000, 0x80ffff, MAP_RAM);
641 	SekMapMemory(DrvPalRAM,				0x900000, 0x907fff, MAP_ROM);
642 	SekMapMemory(DrvPalRAM + 0x8000,	0x980000, 0x980fff, MAP_ROM);
643 	SekSetWriteWordHandler(0,			tecmosys_main_write_word);
644 	SekSetWriteByteHandler(0,			tecmosys_main_write_byte);
645 	SekSetReadWordHandler(0,			tecmosys_main_read_word);
646 	SekSetReadByteHandler(0,			tecmosys_main_read_byte);
647 
648 	SekMapHandler(1,					0x900000, 0x980fff, MAP_WRITE);
649 	SekSetWriteWordHandler(1,			tecmosys_palette_write_word);
650 	SekSetWriteByteHandler(1,			tecmosys_palette_write_byte);
651 	SekClose();
652 
653 	deroon = game;
654 	protection_data = dev_data_pointer;
655 
656 	EEPROMInit(&eeprom_interface_93C46);
657 
658 	BurnWatchdogInit(DrvDoReset, 400);
659 
660 	BurnSetRefreshRate(57.4458);
661 
662 	ZetInit(0);
663 	ZetOpen(0);
664 	ZetMapMemory(DrvZ80ROM, 0x0000, 0x7fff, MAP_ROM);
665 	ZetMapMemory(DrvZ80RAM, 0xe000, 0xf7ff, MAP_RAM);
666 	ZetSetOutHandler(tecmosys_sound_out);
667 	ZetSetInHandler(tecmosys_sound_in);
668 	ZetClose();
669 
670 	BurnYMF262Init(14318180, &DrvFMIRQHandler, DrvSynchroniseStream, 1);
671 	BurnYMF262SetRoute(BURN_SND_YMF262_YMF262_ROUTE_1, 1.00, BURN_SND_ROUTE_LEFT);
672 	BurnYMF262SetRoute(BURN_SND_YMF262_YMF262_ROUTE_2, 1.00, BURN_SND_ROUTE_RIGHT);
673 	BurnTimerAttachZet(8000000);
674 
675 	YMZ280BInit(16934400, NULL, sndlen);
676 	YMZ280BSetRoute(BURN_SND_YMZ280B_YMZ280B_ROUTE_1, 0.30, BURN_SND_ROUTE_LEFT);
677 	YMZ280BSetRoute(BURN_SND_YMZ280B_YMZ280B_ROUTE_2, 0.30, BURN_SND_ROUTE_RIGHT);
678 
679 	MSM6295Init(0, 2000000 / 132, 1);
680 	MSM6295SetRoute(0, 0.50, BURN_SND_ROUTE_BOTH);
681 
682 	GenericTilesInit();
683 	GenericTilemapInit(0, TILEMAP_SCAN_ROWS, txt_map_callback,  8,  8, 64, 64);
684 	GenericTilemapInit(1, TILEMAP_SCAN_ROWS, bg0_map_callback, 16, 16, 32, 32);
685 	GenericTilemapInit(2, TILEMAP_SCAN_ROWS, bg1_map_callback, 16, 16, 32, 32);
686 	GenericTilemapInit(3, TILEMAP_SCAN_ROWS, bg2_map_callback, 16, 16, 32, 32);
687 	GenericTilemapSetGfx(0, DrvGfxROM0, 4,  8,  8, 0x200000, 0xc400, 0x3f);
688 	GenericTilemapSetGfx(1, DrvGfxROM1, 4, 16, 16, 0x200000, 0x0000, 0x3f);
689 	GenericTilemapSetGfx(2, DrvGfxROM2, 4, 16, 16, 0x200000, 0x4000, 0x3f);
690 	GenericTilemapSetGfx(3, DrvGfxROM3, 4, 16, 16, 0x200000, 0x8000, 0x3f);
691 	GenericTilemapSetTransparent(0, 0);
692 	GenericTilemapSetTransparent(1, 0);
693 	if (deroon != 1) // deroon doesn't have background layer
694 		GenericTilemapSetTransparent(2, 0);
695 	else
696 		GenericTilemapSetEnable(1, 0);
697 	GenericTilemapSetTransparent(3, 0);
698 
699 	DrvDoReset(1);
700 
701 	return 0;
702 }
703 
DrvExit()704 static INT32 DrvExit()
705 {
706 	GenericTilesExit();
707 
708 	EEPROMExit();
709 
710 	SekExit();
711 
712 	ZetExit();
713 
714 	BurnYMF262Exit();
715 
716 	MSM6295Exit();
717 	MSM6295ROM = NULL;
718 
719 	YMZ280BExit();
720 	YMZ280BROM = NULL;
721 
722 	BurnFree (DrvSprROM);
723 	BurnFree (AllMem);
724 
725 	return 0;
726 }
727 
draw_sprites()728 static void draw_sprites()
729 {
730 	INT32 extrax =  (*((UINT16*)(Drv88Regs + 0)));
731 	INT32 extray =  (*((UINT16*)(Drv88Regs + 2)));
732 
733 	memset (DrvTmpSprites, 0, 320 * 240 * sizeof(INT16));
734 
735 	UINT16 *spriteram = (UINT16*)(DrvSprRAM + (*spritelist_select * 0x4000));
736 
737 	for (INT32 i = 0; i < 0x4000/2; i+=8)
738 	{
739 		INT32 x   = ((BURN_ENDIAN_SWAP_INT16(spriteram[i+0]) + 386) - extrax) & 0x3ff;
740 		INT32 y   = ((BURN_ENDIAN_SWAP_INT16(spriteram[i+1]) +   1) - extray) & 0x1ff;
741 		INT32 zoomx = BURN_ENDIAN_SWAP_INT16(spriteram[i+2]) & 0x0fff;
742 		INT32 zoomy = BURN_ENDIAN_SWAP_INT16(spriteram[i+3]) & 0x0fff;
743 		INT32 prio  =(BURN_ENDIAN_SWAP_INT16(spriteram[i+4]) & 0x0030) << 10;
744 		INT32 flipx = BURN_ENDIAN_SWAP_INT16(spriteram[i+4]) & 0x0040;
745 		INT32 flipy = BURN_ENDIAN_SWAP_INT16(spriteram[i+4]) & 0x0080;
746 		INT32 color = BURN_ENDIAN_SWAP_INT16(spriteram[i+4]) & 0x3f00;
747 		INT32 addr  =(BURN_ENDIAN_SWAP_INT16(spriteram[i+5]) | ((BURN_ENDIAN_SWAP_INT16(spriteram[i+4]) & 0x000f) << 16)) << 8;
748 		INT32 ysize =(BURN_ENDIAN_SWAP_INT16(spriteram[i+6]) & 0x00ff) << 4;
749 		INT32 xsize =(BURN_ENDIAN_SWAP_INT16(spriteram[i+6]) & 0xff00) >> 4;
750 
751 		if ((BURN_ENDIAN_SWAP_INT16(spriteram[i+4]) & 0x8000) || !zoomx || !zoomy) continue;
752 
753 		if (x & 0x200) x -= 0x400; // positions are signed
754 		if (y & 0x100) y -= 0x200;
755 
756 		if (zoomx == 0x100 && zoomy == 0x100) {
757 			DrawCustomMaskTile(DrvTmpSprites, xsize, ysize, 0/*addr*/, x, y, flipx, flipy, color + prio, 0/*8*/, 0, 0, DrvSprROM + addr);
758 		} else {
759 			RenderZoomedTile(DrvTmpSprites, DrvSprROM + addr, 0/*addr*/, color + prio, 0, x, y, flipx, flipy, xsize, ysize, zoomx << 8, zoomy << 8);
760 		}
761 	}
762 }
763 
blend_sprites_and_transfer()764 static void blend_sprites_and_transfer()
765 {
766 	UINT16 *srcptr  = pTransDraw;
767 	UINT16 *srcptr2 = DrvTmpSprites;
768 	UINT8  *dstptr  = pBurnDraw;
769 	UINT16 *palram  = (UINT16*)DrvPalRAM;
770 
771 	for (INT32 z = 0; z < 320 * 240; z++)
772 	{
773 		if (!(srcptr2[z] & 0x3fff))	// tiles only, copy
774 		{
775 			PutPix(dstptr + z * nBurnBpp, DrvPalette[(srcptr[z] & 0x7ff) + 0x4000]);
776 			continue;
777 		}
778 
779 		// check for blend/priority
780 
781 		INT32 pxl  = (srcptr [z] & 0x07ff) + 0x4000;
782 		INT32 pxl2 = (srcptr2[z] & 0x3fff);
783 
784 		if ((BURN_ENDIAN_SWAP_INT16(palram[pxl]) & 0x8000) && (BURN_ENDIAN_SWAP_INT16(palram[pxl2]) & 0x8000)) // blend
785 		{
786 			INT32 colour  = DrvPalette24[pxl];
787 			INT32 colour2 = DrvPalette24[pxl2];
788 
789 			INT32 b = ((colour & 0x000000ff) + (colour2 & 0x000000ff)) >>  1;
790 			INT32 g = ((colour & 0x0000ff00) + (colour2 & 0x0000ff00)) >>  9;
791 			INT32 r = ((colour & 0x00ff0000) + (colour2 & 0x00ff0000)) >> 17;
792 
793 			PutPix(dstptr + z * nBurnBpp, BurnHighCol(r, g, b, 0));
794 		}
795 		else if ((srcptr2[z] & 0xc000) >= (srcptr[z] & 0xc000))
796 		{
797 			PutPix(dstptr + z * nBurnBpp, DrvPalette[pxl2]);
798 		}
799 		else
800 		{
801 			PutPix(dstptr + z * nBurnBpp, DrvPalette[pxl]);
802 		}
803 	}
804 }
805 
DrvDraw()806 static INT32 DrvDraw()
807 {
808 	if (DrvRecalc) {
809 		for (INT32 i = 0; i < 0x9000/2; i++) {
810 			palette_update(i);
811 		}
812 		DrvRecalc = 0;
813 	}
814 
815 	BurnTransferClear();
816 
817 	GenericTilemapSetScrollX(1, *((UINT16*)(DrvC8Regs + 0)) + 104);
818 	GenericTilemapSetScrollY(1, *((UINT16*)(DrvC8Regs + 2)) + 16);
819 	GenericTilemapSetScrollX(2, *((UINT16*)(DrvA8Regs + 0)) + 106);
820 	GenericTilemapSetScrollY(2, *((UINT16*)(DrvA8Regs + 2)) + 17);
821 	GenericTilemapSetScrollX(3, *((UINT16*)(DrvB0Regs + 0)) + 106);
822 	GenericTilemapSetScrollY(3, *((UINT16*)(DrvB0Regs + 2)) + 17);
823 
824 	GenericTilemapDraw(1, pTransDraw, 0);
825 	GenericTilemapDraw(2, pTransDraw, 0);
826 	GenericTilemapDraw(3, pTransDraw, 0);
827 	GenericTilemapDraw(0, pTransDraw, 0);
828 
829 	blend_sprites_and_transfer();
830 
831 	draw_sprites(); // draw next frame's sprites
832 
833 	return 0;
834 }
835 
DrvFrame()836 static INT32 DrvFrame()
837 {
838 	SekNewFrame();
839 	ZetNewFrame();
840 
841 	BurnWatchdogUpdate();
842 
843 	if (DrvReset) {
844 		DrvDoReset(1);
845 	}
846 
847 	{
848 		memset (DrvInputs, 0xff, 2 * sizeof(UINT16));
849 
850 		for (INT32 i = 0; i < 16; i++) {
851 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
852 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
853 		}
854 
855 		// clear opposites
856 		if ((DrvInputs[0] & 0x03) == 0x00) DrvInputs[0] |= 0x03;
857 		if ((DrvInputs[0] & 0x0c) == 0x00) DrvInputs[0] |= 0x0c;
858 		if ((DrvInputs[1] & 0x03) == 0x00) DrvInputs[1] |= 0x03;
859 		if ((DrvInputs[1] & 0x0c) == 0x00) DrvInputs[1] |= 0x0c;
860 	}
861 
862 	INT32 nInterleave = 256;
863 	INT32 nCyclesTotal[2] = { (INT32)(16000000 / 57.4458), (INT32)(8000000 / 57.4458) };
864 	INT32 nCyclesDone[2] = { 0, 0 };
865 
866 	nCyclesTotal[0] = (INT32)((INT64)nCyclesTotal[0] * nBurnCPUSpeedAdjust / 0x0100);
867 
868 	SekOpen(0);
869 	ZetOpen(0);
870 
871 	vblank = 0;
872 
873 	for (INT32 i = 0; i < nInterleave; i++)
874 	{
875 		if (i == 240) {
876 			vblank = 1;
877 			SekSetIRQLine(1, CPU_IRQSTATUS_AUTO);
878 
879 			if (pBurnDraw) {
880 				DrvDraw();
881 			}
882 		}
883 
884 		nCyclesDone[0] += SekRun(((i + 1) * nCyclesTotal[0] / nInterleave) - nCyclesDone[0]);
885 
886 		BurnTimerUpdate((i + 1) * nCyclesTotal[1] / nInterleave);
887 	}
888 
889 	BurnTimerEndFrame(nCyclesTotal[1]);
890 
891 	if (pBurnSoundOut) {
892 		YMZ280BRender(pBurnSoundOut, nBurnSoundLen);
893 		BurnYMF262Update(nBurnSoundLen);
894 		MSM6295Render(pBurnSoundOut, nBurnSoundLen);
895 	}
896 
897 	ZetClose();
898 	SekClose();
899 
900 	return 0;
901 }
902 
DrvScan(INT32 nAction,INT32 * pnMin)903 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
904 {
905 	struct BurnArea ba;
906 
907 	if (pnMin) {
908 		*pnMin =  0x029702;
909 	}
910 
911 	if (nAction & ACB_MEMORY_RAM) {
912 		memset(&ba, 0, sizeof(ba));
913 		ba.Data	  = AllRam;
914 		ba.nLen	  = RamEnd-AllRam;
915 		ba.szName = "All Ram";
916 		BurnAcb(&ba);
917 	}
918 
919 	if (nAction & ACB_DRIVER_DATA) {
920 
921 		SekScan(nAction);
922 		ZetScan(nAction);
923 
924 		BurnYMF262Scan(nAction, pnMin);
925 		YMZ280BScan(nAction, pnMin);
926 		MSM6295Scan(nAction, pnMin);
927 
928 		EEPROMScan(nAction, pnMin);
929 		BurnWatchdogScan(nAction);
930 
931 		SCAN_VAR(protection_read_pointer);
932 		SCAN_VAR(protection_status);
933 		SCAN_VAR(protection_value);
934 	}
935 
936 	if (nAction & ACB_WRITE) {
937 		ZetOpen(0);
938 		bankswitch(*DrvZ80Bank);
939 		ZetClose();
940 
941 		oki_bankswitch(*DrvOkiBank);
942 	}
943 
944  	return 0;
945 }
946 
947 
948 // Deroon DeroDero
949 
950 static struct BurnRomInfo deroonRomDesc[] = {
951 	{ "t001.upau1",				0x080000, 0x14b92c18, 1 | BRF_PRG | BRF_ESS }, //  0 68K Code
952 	{ "t002.upal1",				0x080000, 0x0fb05c68, 1 | BRF_PRG | BRF_ESS }, //  1
953 
954 	{ "t003.uz1",				0x040000, 0x8bdfafa0, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 Code
955 
956 	{ "t101.uah1",				0x200000, 0x74baf845, 3 | BRF_GRA },           //  3 Sprites
957 	{ "t102.ual1",				0x200000, 0x1a02c4a3, 3 | BRF_GRA },           //  4
958 	{ "t103.ubl1",				0x400000, 0x84e7da88, 3 | BRF_GRA },           //  5
959 	{ "t104.ucl1",				0x200000, 0x66eb611a, 3 | BRF_GRA },           //  6
960 
961 	{ "t301.ubd1",				0x100000, 0x8b026177, 4 | BRF_GRA },           //  7 Character Tiles
962 
963 	{ "t201.ubb1",				0x100000, 0xd5a087ac, 6 | BRF_GRA },           //  8 Midground Layer
964 
965 	{ "t202.ubc1",				0x100000, 0xf051dae1, 7 | BRF_GRA },           //  9 Foreground Layer
966 
967 	{ "t401.uya1",				0x200000, 0x92111992, 8 | BRF_SND },           // 10 YMZ280B Samples
968 
969 	{ "t501.uad1",				0x080000, 0x2fbcfe27, 9 | BRF_SND },           // 11 OKI6295 Samples
970 
971 	{ "deroon_68hc11a8.rom",	0x002000, 0x00000000, 0 | BRF_NODUMP },        // 12 68HC11A8 Code
972 	{ "deroon_68hc11a8.eeprom",	0x000200, 0x00000000, 0 | BRF_NODUMP },        // 13 68HC11A8 EEPROM
973 };
974 
975 STD_ROM_PICK(deroon)
STD_ROM_FN(deroon)976 STD_ROM_FN(deroon)
977 
978 static INT32 DeroonRomCallback()
979 {
980 	if (BurnLoadRom(Drv68KROM  + 0x0000001,  0, 2)) return 1;
981 	if (BurnLoadRom(Drv68KROM  + 0x0000000,  1, 2)) return 1;
982 
983 	if (BurnLoadRom(DrvZ80ROM  + 0x0000000,  2, 1)) return 1;
984 
985 	if (BurnLoadRom(DrvSprROM + 0x0000000,   3, 2)) return 1;
986 	if (BurnLoadRom(DrvSprROM + 0x0000001,   4, 2)) return 1;
987 	if (BurnLoadRom(DrvSprROM + 0x0800001,   5, 2)) return 1;
988 	if (BurnLoadRom(DrvSprROM + 0x1000001,   6, 2)) return 1;
989 
990 	if (BurnLoadRom(DrvGfxROM0 + 0x0000000,  7, 1)) return 1;
991 
992 	if (BurnLoadRom(DrvGfxROM2 + 0x0000000,  8, 1)) return 1;
993 
994 	if (BurnLoadRom(DrvGfxROM3 + 0x0000000,  9, 1)) return 1;
995 
996 	if (BurnLoadRom(DrvSndROM1 + 0x0000000, 10, 1)) return 1;
997 
998 	if (BurnLoadRom(DrvSndROM0 + 0x0000000, 11, 1)) return 1;
999 
1000 	return 0;
1001 }
1002 
DeroonInit()1003 static INT32 DeroonInit()
1004 {
1005 	return CommonInit(DeroonRomCallback, 0x2000000, 0x200000, &deroon_data, 1);
1006 }
1007 
1008 struct BurnDriver BurnDrvDeroon = {
1009 	"deroon", NULL, NULL, NULL, "1995",
1010 	"Deroon DeroDero\0", NULL, "Tecmo", "Miscellaneous",
1011 	NULL, NULL, NULL, NULL,
1012 	BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_PUZZLE, 0,
1013 	NULL, deroonRomInfo, deroonRomName, NULL, NULL, NULL, NULL, DrvInputInfo, NULL,
1014 	DeroonInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x4800,
1015 	320, 240, 4, 3
1016 };
1017 
1018 
1019 // Deroon DeroDero (alt set)
1020 // maybe a bad dump - this set needs to be confirmed
1021 
1022 static struct BurnRomInfo deroonaRomDesc[] = {
1023 	{ "t.01",					0x080000, 0x7ad6c740, 1 | BRF_PRG | BRF_ESS }, //  0 68K Code
1024 	{ "t.02",					0x080000, 0xe44f4430, 1 | BRF_PRG | BRF_ESS }, //  1
1025 
1026 	{ "t003.bin",				0x040000, 0x8bdfafa0, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 Code
1027 
1028 	{ "t101.uah1",				0x200000, 0x74baf845, 3 | BRF_GRA },           //  3 Sprites
1029 	{ "t102.ual1",				0x200000, 0x1a02c4a3, 3 | BRF_GRA },           //  4
1030 	{ "t103.ubl1",				0x400000, 0x84e7da88, 3 | BRF_GRA },           //  5
1031 	{ "t104.ucl1",				0x200000, 0x66eb611a, 3 | BRF_GRA },           //  6
1032 
1033 	{ "t301.ubd1",				0x100000, 0x8b026177, 4 | BRF_GRA },           //  7 Character Tiles
1034 
1035 	{ "t201.ubb1",				0x100000, 0xd5a087ac, 6 | BRF_GRA },           //  8 Midground Layer
1036 
1037 	{ "t202.ubc1",				0x100000, 0xf051dae1, 7 | BRF_GRA },           //  9 Foreground Layer
1038 
1039 	{ "t401.uya1",				0x200000, 0x92111992, 8 | BRF_SND },           // 10 YMZ280B Samples
1040 
1041 	{ "t501.uad1",				0x080000, 0x2fbcfe27, 9 | BRF_SND },           // 11 OKI6295 Samples
1042 
1043 	{ "deroon_68hc11a8.rom",	0x002000, 0x00000000, 0 | BRF_NODUMP },        // 12 68HC11A8 Code
1044 	{ "deroon_68hc11a8.eeprom",	0x000200, 0x00000000, 0 | BRF_NODUMP },        // 13 68HC11A8 EEPROM
1045 };
1046 
1047 STD_ROM_PICK(deroona)
1048 STD_ROM_FN(deroona)
1049 
1050 struct BurnDriver BurnDrvDeroona = {
1051 	"deroona", "deroon", NULL, NULL, "1995",
1052 	"Deroon DeroDero (alt set)\0", NULL, "Tecmo", "Miscellaneous",
1053 	NULL, NULL, NULL, NULL,
1054 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_POST90S, GBF_PUZZLE, 0,
1055 	NULL, deroonaRomInfo, deroonaRomName, NULL, NULL, NULL, NULL, DrvInputInfo, NULL,
1056 	DeroonInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x4800,
1057 	320, 240, 4, 3
1058 };
1059 
1060 // Deroon DeroDero (newer)
1061 
1062 static struct BurnRomInfo deroon2RomDesc[] = {
1063 	{ "stk_t01.upau1",			0x080000, 0x90c794df, 1 | BRF_PRG | BRF_ESS }, //  0 68K Code
1064 	{ "stk_t02.upal1",			0x080000, 0xcca9f87c, 1 | BRF_PRG | BRF_ESS }, //  1
1065 
1066 	{ "t003.uz1",				0x040000, 0x8bdfafa0, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 Code
1067 
1068 	{ "t101.uah1",				0x200000, 0x74baf845, 3 | BRF_GRA },           //  3 Sprites
1069 	{ "t102.ual1",				0x200000, 0x1a02c4a3, 3 | BRF_GRA },           //  4
1070 	{ "t103.ubl1",				0x400000, 0x84e7da88, 3 | BRF_GRA },           //  5
1071 	{ "t104.ucl1",				0x200000, 0x66eb611a, 3 | BRF_GRA },           //  6
1072 
1073 	{ "t301.ubd1",				0x100000, 0x8b026177, 4 | BRF_GRA },           //  7 Character Tiles
1074 
1075 	{ "t201.ubb1",				0x100000, 0xd5a087ac, 6 | BRF_GRA },           //  8 Midground Layer
1076 
1077 	{ "t202.ubc1",				0x100000, 0xf051dae1, 7 | BRF_GRA },           //  9 Foreground Layer
1078 
1079 	{ "t401.uya1",				0x200000, 0x92111992, 8 | BRF_SND },           // 10 YMZ280B Samples
1080 
1081 	{ "t501.uad1",				0x080000, 0x2fbcfe27, 9 | BRF_SND },           // 11 OKI6295 Samples
1082 
1083 	{ "deroon_68hc11a8.rom",	0x002000, 0x00000000, 0 | BRF_NODUMP },        // 12 68HC11A8 Code
1084 	{ "deroon_68hc11a8.eeprom",	0x000200, 0x00000000, 0 | BRF_NODUMP },        // 13 68HC11A8 EEPROM
1085 };
1086 
1087 STD_ROM_PICK(deroon2)
1088 STD_ROM_FN(deroon2)
1089 
1090 struct BurnDriver BurnDrvDeroon2 = {
1091 	"deroon2", "deroon", NULL, NULL, "1995",
1092 	"Deroon DeroDero (newer)\0", NULL, "Tecmo", "Miscellaneous",
1093 	NULL, NULL, NULL, NULL,
1094 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_POST90S, GBF_PUZZLE, 0,
1095 	NULL, deroon2RomInfo, deroon2RomName, NULL, NULL, NULL, NULL, DrvInputInfo, NULL,
1096 	DeroonInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x4800,
1097 	320, 240, 4, 3
1098 };
1099 
1100 // Toukidenshou - Angel Eyes (VER. 960614)
1101 
1102 static struct BurnRomInfo tkdenshoRomDesc[] = {
1103 	{ "aeprge-2.pal",		0x080000, 0x25e453d6, 1 | BRF_PRG | BRF_ESS }, //  0 68K Code
1104 	{ "aeprgo-2.pau",		0x080000, 0x22d59510, 1 | BRF_PRG | BRF_ESS }, //  1
1105 
1106 	{ "aesprg-2.z1",		0x020000, 0x43550ab6, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 Code
1107 
1108 	{ "ae100h.ah1",			0x400000, 0x06be252b, 3 | BRF_GRA },           //  3 Sprites
1109 	{ "ae100.al1",			0x400000, 0x009cdff4, 3 | BRF_GRA },           //  4
1110 	{ "ae101h.bh1",			0x400000, 0xf2469eff, 3 | BRF_GRA },           //  5
1111 	{ "ae101.bl1",			0x400000, 0xdb7791bb, 3 | BRF_GRA },           //  6
1112 	{ "ae102h.ch1",			0x200000, 0xf9d2a343, 3 | BRF_GRA },           //  7
1113 	{ "ae102.cl1",			0x200000, 0x681be889, 3 | BRF_GRA },           //  8
1114 	{ "ae104.el1",			0x400000, 0xe431b798, 3 | BRF_GRA },           //  9
1115 	{ "ae105.fl1",			0x400000, 0xb7f9ebc1, 3 | BRF_GRA },           // 10
1116 	{ "ae106.gl1",			0x200000, 0x7c50374b, 3 | BRF_GRA },           // 11
1117 
1118 	{ "ae300w36.bd1",		0x080000, 0xe829f29e, 4 | BRF_GRA },           // 12 Character Tiles
1119 
1120 	{ "ae200w74.ba1",		0x100000, 0xc1645041, 5 | BRF_GRA },           // 13 Background Tiles
1121 
1122 	{ "ae201w75.bb1",		0x100000, 0x3f63bdff, 6 | BRF_GRA },           // 14 Midground Tiles
1123 
1124 	{ "ae202w76.bc1",		0x100000, 0x5cc857ca, 7 | BRF_GRA },           // 15 Foreground Tiles
1125 
1126 	{ "ae400t23.ya1",		0x200000, 0xc6ffb043, 8 | BRF_SND },           // 16 YMZ280B Samples
1127 	{ "ae401t24.yb1",		0x200000, 0xd83f1a73, 8 | BRF_SND },           // 17
1128 
1129 	{ "ae500w07.ad1",		0x080000, 0x3734f92c, 9 | BRF_SND },           // 18 OKI6295 Samples
1130 
1131 	{ "tkdensho_68hc11a8.rom",	0x002000, 0x00000000, 0 | BRF_NODUMP },        // 19 68HC11A8 Code
1132 	{ "tkdensho_68hc11a8.eeprom",	0x000200, 0x00000000, 0 | BRF_NODUMP },        // 20 68HC11A8 EEPROM
1133 };
1134 
1135 STD_ROM_PICK(tkdensho)
STD_ROM_FN(tkdensho)1136 STD_ROM_FN(tkdensho)
1137 
1138 static INT32 TkdenshoRomCallback()
1139 {
1140 	if (BurnLoadRom(Drv68KROM  + 0x0000001,  0, 2)) return 1;
1141 	if (BurnLoadRom(Drv68KROM  + 0x0000000,  1, 2)) return 1;
1142 
1143 	if (BurnLoadRom(DrvZ80ROM  + 0x0000000,  2, 1)) return 1;
1144 	memcpy (DrvZ80ROM + 0x20000, DrvZ80ROM, 0x20000);
1145 
1146 	if (BurnLoadRom(DrvSprROM + 0x0000000,   3, 2)) return 1;
1147 	if (BurnLoadRom(DrvSprROM + 0x0000001,   4, 2)) return 1;
1148 	if (BurnLoadRom(DrvSprROM + 0x0800000,   5, 2)) return 1;
1149 	if (BurnLoadRom(DrvSprROM + 0x0800001,   6, 2)) return 1;
1150 	if (BurnLoadRom(DrvSprROM + 0x1000000,   7, 2)) return 1;
1151 	if (BurnLoadRom(DrvSprROM + 0x1000001,   8, 2)) return 1;
1152 	if (BurnLoadRom(DrvSprROM + 0x2000001,   9, 2)) return 1;
1153 	if (BurnLoadRom(DrvSprROM + 0x2800001,  10, 2)) return 1;
1154 	if (BurnLoadRom(DrvSprROM + 0x3000001,  11, 2)) return 1;
1155 
1156 	if (BurnLoadRom(DrvGfxROM0 + 0x0000000, 12, 1)) return 1;
1157 	memcpy (DrvGfxROM0 + 0x80000, DrvGfxROM0, 0x80000); // double here rather than mask later
1158 
1159 	if (BurnLoadRom(DrvGfxROM1 + 0x0000000, 13, 1)) return 1;
1160 
1161 	if (BurnLoadRom(DrvGfxROM2 + 0x0000000, 14, 1)) return 1;
1162 
1163 	if (BurnLoadRom(DrvGfxROM3 + 0x0000000, 15, 1)) return 1;
1164 
1165 	if (BurnLoadRom(DrvSndROM1 + 0x0000000, 16, 1)) return 1;
1166 	if (BurnLoadRom(DrvSndROM1 + 0x0200000, 17, 1)) return 1;
1167 
1168 	if (BurnLoadRom(DrvSndROM0 + 0x0000000, 18, 1)) return 1;
1169 
1170 	return 0;
1171 }
1172 
TkdenshoInit()1173 static INT32 TkdenshoInit()
1174 {
1175 	return CommonInit(TkdenshoRomCallback, 0x4000000, 0x400000, &tkdensho_data, 0);
1176 }
1177 
1178 struct BurnDriver BurnDrvTkdensho = {
1179 	"tkdensho", NULL, NULL, NULL, "1996",
1180 	"Toukidenshou - Angel Eyes (VER. 960614)\0", NULL, "Tecmo", "Miscellaneous",
1181 	NULL, NULL, NULL, NULL,
1182 	BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_VSFIGHT, 0,
1183 	NULL, tkdenshoRomInfo, tkdenshoRomName, NULL, NULL, NULL, NULL, DrvInputInfo, NULL,
1184 	TkdenshoInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x4800,
1185 	320, 240, 4, 3
1186 };
1187 
1188 
1189 // Toukidenshou - Angel Eyes (VER. 960427)
1190 
1191 static struct BurnRomInfo tkdenshoaRomDesc[] = {
1192 	{ "aeprge.pal",			0x080000, 0x17a209ff, 1 | BRF_PRG | BRF_ESS }, //  0 68K Code
1193 	{ "aeprgo.pau",			0x080000, 0xd265e6a1, 1 | BRF_PRG | BRF_ESS }, //  1
1194 
1195 	{ "aesprg-2.z1",		0x020000, 0x43550ab6, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 Code
1196 
1197 	{ "ae100h.ah1",			0x400000, 0x06be252b, 3 | BRF_GRA },           //  3 Sprites
1198 	{ "ae100.al1",			0x400000, 0x009cdff4, 3 | BRF_GRA },           //  4
1199 	{ "ae101h.bh1",			0x400000, 0xf2469eff, 3 | BRF_GRA },           //  5
1200 	{ "ae101.bl1",			0x400000, 0xdb7791bb, 3 | BRF_GRA },           //  6
1201 	{ "ae102h.ch1",			0x200000, 0xf9d2a343, 3 | BRF_GRA },           //  7
1202 	{ "ae102.cl1",			0x200000, 0x681be889, 3 | BRF_GRA },           //  8
1203 	{ "ae104.el1",			0x400000, 0xe431b798, 3 | BRF_GRA },           //  9
1204 	{ "ae105.fl1",			0x400000, 0xb7f9ebc1, 3 | BRF_GRA },           // 10
1205 	{ "ae106.gl1",			0x200000, 0x7c50374b, 3 | BRF_GRA },           // 11
1206 
1207 	{ "ae300w36.bd1",		0x080000, 0xe829f29e, 4 | BRF_GRA },           // 12 Character Tiles
1208 
1209 	{ "ae200w74.ba1",		0x100000, 0xc1645041, 5 | BRF_GRA },           // 13 Background Tiles
1210 
1211 	{ "ae201w75.bb1",		0x100000, 0x3f63bdff, 6 | BRF_GRA },           // 14 Midground Tiles
1212 
1213 	{ "ae202w76.bc1",		0x100000, 0x5cc857ca, 7 | BRF_GRA },           // 15 Foreground Tiles
1214 
1215 	{ "ae400t23.ya1",		0x200000, 0xc6ffb043, 8 | BRF_SND },           // 16 YMZ280B Samples
1216 	{ "ae401t24.yb1",		0x200000, 0xd83f1a73, 8 | BRF_SND },           // 17
1217 
1218 	{ "ae500w07.ad1",		0x080000, 0x3734f92c, 9 | BRF_SND },           // 18 OKI6295 Samples
1219 
1220 	{ "tkdensho_68hc11a8.rom",	0x002000, 0x00000000, 0 | BRF_NODUMP },        // 19 68HC11A8 Code
1221 	{ "tkdensho_68hc11a8.eeprom",	0x000200, 0x00000000, 0 | BRF_NODUMP },        // 20 68HC11A8 EEPROM
1222 };
1223 
1224 STD_ROM_PICK(tkdenshoa)
STD_ROM_FN(tkdenshoa)1225 STD_ROM_FN(tkdenshoa)
1226 
1227 static INT32 TkdenshoaInit()
1228 {
1229 	return CommonInit(TkdenshoRomCallback, 0x4000000, 0x400000, &tkdenshoa_data, 0);
1230 }
1231 
1232 struct BurnDriver BurnDrvTkdenshoa = {
1233 	"tkdenshoa", "tkdensho", NULL, NULL, "1996",
1234 	"Toukidenshou - Angel Eyes (VER. 960427)\0", NULL, "Tecmo", "Miscellaneous",
1235 	NULL, NULL, NULL, NULL,
1236 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_POST90S, GBF_VSFIGHT, 0,
1237 	NULL, tkdenshoaRomInfo, tkdenshoaRomName, NULL, NULL, NULL, NULL, DrvInputInfo, NULL,
1238 	TkdenshoaInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x4800,
1239 	320, 240, 4, 3
1240 };
1241