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