1 // FB Alpha Double Wings driver module
2 // Based on MAME driver by David Haywood
3 
4 #include "tiles_generic.h"
5 #include "m68000_intf.h"
6 #include "z80_intf.h"
7 #include "deco16ic.h"
8 #include "burn_ym2151.h"
9 #include "msm6295.h"
10 #include "deco146.h"
11 
12 static UINT8 *AllMem;
13 static UINT8 *MemEnd;
14 static UINT8 *AllRam;
15 static UINT8 *RamEnd;
16 static UINT8 *Drv68KROM;
17 static UINT8 *Drv68KCode;
18 static UINT8 *DrvZ80ROM;
19 static UINT8 *DrvGfxROM0;
20 static UINT8 *DrvGfxROM1;
21 static UINT8 *DrvGfxROM2;
22 static UINT8 *DrvSndROM0;
23 static UINT8 *Drv68KRAM;
24 static UINT8 *DrvUnkRAM0;
25 static UINT8 *DrvUnkRAM1;
26 static UINT8 *DrvSprRAM;
27 static UINT8 *DrvZ80RAM;
28 static UINT8 *DrvPalRAM;
29 
30 static UINT32 *DrvPalette;
31 static UINT8 DrvRecalc;
32 
33 static UINT8 flipscreen;
34 static UINT8 soundlatch;
35 static UINT8 sound_irq;
36 
37 static UINT8 DrvJoy1[16];
38 static UINT8 DrvJoy2[16];
39 static UINT8 DrvDips[2];
40 static UINT8 DrvReset;
41 static UINT16 DrvInputs[2];
42 
43 static struct BurnInputInfo DblewingInputList[] = {
44 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy2 + 0,	"p1 coin"	},
45 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 7,	"p1 start"	},
46 	{"P1 Up",			BIT_DIGITAL,	DrvJoy1 + 0,	"p1 up"		},
47 	{"P1 Down",			BIT_DIGITAL,	DrvJoy1 + 1,	"p1 down"	},
48 	{"P1 Left",			BIT_DIGITAL,	DrvJoy1 + 2,	"p1 left"	},
49 	{"P1 Right",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 right"	},
50 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 4,	"p1 fire 1"	},
51 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 fire 2"	},
52 	{"P1 Button 3",		BIT_DIGITAL,	DrvJoy1 + 6,	"p1 fire 3"	},
53 
54 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy2 + 1,	"p2 coin"	},
55 	{"P2 Start",		BIT_DIGITAL,	DrvJoy1 + 15,	"p2 start"	},
56 	{"P2 Up",			BIT_DIGITAL,	DrvJoy1 + 8,	"p2 up"		},
57 	{"P2 Down",			BIT_DIGITAL,	DrvJoy1 + 9,	"p2 down"	},
58 	{"P2 Left",			BIT_DIGITAL,	DrvJoy1 + 10,	"p2 left"	},
59 	{"P2 Right",		BIT_DIGITAL,	DrvJoy1 + 11,	"p2 right"	},
60 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy1 + 12,	"p2 fire 1"	},
61 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy1 + 13,	"p2 fire 2"	},
62 	{"P2 Button 3",		BIT_DIGITAL,	DrvJoy1 + 14,	"p2 fire 3"	},
63 
64 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
65 	{"Service",			BIT_DIGITAL,	DrvJoy2 + 2,	"service"	},
66 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
67 	{"Dip B",			BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
68 };
69 
70 STDINPUTINFO(Dblewing)
71 
72 static struct BurnDIPInfo DblewingDIPList[]=
73 {
74 	{0x14, 0xff, 0xff, 0xff, NULL			},
75 	{0x15, 0xff, 0xff, 0x7f, NULL			},
76 
77 	{0   , 0xfe, 0   ,    8, "Coin A"		},
78 	{0x14, 0x01, 0x07, 0x00, "3 Coins 1 Credits"	},
79 	{0x14, 0x01, 0x07, 0x01, "2 Coins 1 Credits"	},
80 	{0x14, 0x01, 0x07, 0x07, "1 Coin  1 Credits"	},
81 	{0x14, 0x01, 0x07, 0x06, "1 Coin  2 Credits"	},
82 	{0x14, 0x01, 0x07, 0x05, "1 Coin  3 Credits"	},
83 	{0x14, 0x01, 0x07, 0x04, "1 Coin  4 Credits"	},
84 	{0x14, 0x01, 0x07, 0x03, "1 Coin  5 Credits"	},
85 	{0x14, 0x01, 0x07, 0x02, "1 Coin  6 Credits"	},
86 
87 	{0   , 0xfe, 0   ,    8, "Coin B"		},
88 	{0x14, 0x01, 0x38, 0x00, "3 Coins 1 Credits"	},
89 	{0x14, 0x01, 0x38, 0x08, "2 Coins 1 Credits"	},
90 	{0x14, 0x01, 0x38, 0x38, "1 Coin  1 Credits"	},
91 	{0x14, 0x01, 0x38, 0x30, "1 Coin  2 Credits"	},
92 	{0x14, 0x01, 0x38, 0x28, "1 Coin  3 Credits"	},
93 	{0x14, 0x01, 0x38, 0x20, "1 Coin  4 Credits"	},
94 	{0x14, 0x01, 0x38, 0x18, "1 Coin  5 Credits"	},
95 	{0x14, 0x01, 0x38, 0x10, "1 Coin  6 Credits"	},
96 
97 //	not supported
98 //	{0   , 0xfe, 0   ,    2, "Flip Screen"		},
99 //	{0x14, 0x01, 0x40, 0x40, "Off"			},
100 //	{0x14, 0x01, 0x40, 0x00, "On"			},
101 
102 	{0   , 0xfe, 0   ,    2, "Region"		},
103 	{0x14, 0x01, 0x80, 0x80, "Japan"		},
104 	{0x14, 0x01, 0x80, 0x00, "Korea"		},
105 
106 	{0   , 0xfe, 0   ,    4, "Lives"		},
107 	{0x15, 0x01, 0x03, 0x02, "1"			},
108 	{0x15, 0x01, 0x03, 0x01, "2"			},
109 	{0x15, 0x01, 0x03, 0x03, "3"			},
110 	{0x15, 0x01, 0x03, 0x00, "5"			},
111 
112 	{0   , 0xfe, 0   ,    4, "Difficulty"		},
113 	{0x15, 0x01, 0x0c, 0x08, "Easy"			},
114 	{0x15, 0x01, 0x0c, 0x0c, "Normal"		},
115 	{0x15, 0x01, 0x0c, 0x04, "Hard"			},
116 	{0x15, 0x01, 0x0c, 0x00, "Hardest"		},
117 
118 	{0   , 0xfe, 0   ,    4, "Bonus Life"		},
119 	{0x15, 0x01, 0x30, 0x20, "Every 100,000"	},
120 	{0x15, 0x01, 0x30, 0x30, "Every 150,000"	},
121 	{0x15, 0x01, 0x30, 0x10, "Every 300,000"	},
122 	{0x15, 0x01, 0x30, 0x00, "250,000 Only"		},
123 
124 	{0   , 0xfe, 0   ,    2, "Allow Continue"	},
125 	{0x15, 0x01, 0x40, 0x00, "Off"			},
126 	{0x15, 0x01, 0x40, 0x40, "On"			},
127 
128 	{0   , 0xfe, 0   ,    2, "Demo Sounds"		},
129 	{0x15, 0x01, 0x80, 0x80, "Off"			},
130 	{0x15, 0x01, 0x80, 0x00, "On"			},
131 };
132 
STDDIPINFO(Dblewing)133 STDDIPINFO(Dblewing)
134 
135 static void __fastcall dblewing_write_word(UINT32 address, UINT16 data)
136 {
137 	if ((address & 0xffc000) == 0x280000) {
138 		deco146_104_prot_ww(0, address, data);
139 		return;
140 	}
141 
142 	deco16_write_control_word(0, address, 0x28c000, data);
143 }
144 
dblewing_write_byte(UINT32 address,UINT8 data)145 static void __fastcall dblewing_write_byte(UINT32 address, UINT8 data)
146 {
147 	if ((address & 0xffc000) == 0x280000) {
148 		deco146_104_prot_wb(0, address, data);
149 		return;
150 	}
151 }
152 
dblewing_read_word(UINT32 address)153 static UINT16 __fastcall dblewing_read_word(UINT32 address)
154 {
155 	if ((address & 0xffc000) == 0x280000) {
156 		return deco146_104_prot_rw(0, address);
157 	}
158 
159 	return 0;
160 }
161 
dblewing_read_byte(UINT32 address)162 static UINT8 __fastcall dblewing_read_byte(UINT32 address)
163 {
164 	if ((address & 0xffc000) == 0x280000) {
165 		return deco146_104_prot_rb(0, address);
166 	}
167 
168 	return 0;
169 }
170 
dblewing_sound_write(UINT16 address,UINT8 data)171 static void __fastcall dblewing_sound_write(UINT16 address, UINT8 data)
172 {
173 	switch (address)
174 	{
175 		case 0xa000:
176 			BurnYM2151SelectRegister(data);
177 		return;
178 
179 		case 0xa001:
180 			BurnYM2151WriteRegister(data);
181 		return;
182 
183 		case 0xb000:
184 		case 0xf000:
185 			MSM6295Write(0, data);
186 		return;
187 	}
188 }
189 
dblewing_sound_read(UINT16 address)190 static UINT8 __fastcall dblewing_sound_read(UINT16 address)
191 {
192 	switch (address)
193 	{
194 		case 0xa000:
195 		case 0xa001:
196 			return BurnYM2151Read();
197 
198 		case 0xb000:
199 		case 0xf000:
200 			return MSM6295Read(0);
201 
202 		case 0xc000:
203 			sound_irq = 0;
204 			return soundlatch;
205 
206 		case 0xd000:
207 			return sound_irq ^ 1;
208 	}
209 
210 	return 0;
211 }
212 
sound_callback(UINT16 data)213 static void sound_callback(UINT16 data)
214 {
215 	soundlatch = data & 0xff;
216 	sound_irq = 1;
217 }
218 
input_read()219 static UINT16 input_read()
220 {
221 	return DrvInputs[0];
222 }
223 
system_read()224 static UINT16 system_read()
225 {
226 	return (DrvInputs[1] & 0x7) | deco16_vblank;
227 }
228 
dips_read()229 static UINT16 dips_read()
230 {
231 	return (DrvDips[1] * 256) + DrvDips[0];
232 }
233 
dblewing_sound_read_port(UINT16 port)234 static UINT8 __fastcall dblewing_sound_read_port(UINT16 port)
235 {
236 	return DrvZ80ROM[port];
237 }
238 
DrvYM2151IrqHandler(INT32 state)239 static void DrvYM2151IrqHandler(INT32 state)
240 {
241 	ZetSetIRQLine(0, (state) ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE);
242 }
243 
dblewing_bank_callback(const INT32 bank)244 static INT32 dblewing_bank_callback( const INT32 bank )
245 {
246 	return ((bank >> 4) & 0x7) * 0x1000;
247 }
248 
DrvDoReset()249 static INT32 DrvDoReset()
250 {
251 	memset (AllRam, 0, RamEnd - AllRam);
252 
253 	SekOpen(0);
254 	SekReset();
255 	SekClose();
256 
257 	ZetOpen(0);
258 	ZetReset();
259 	BurnYM2151Reset();
260 	ZetClose();
261 
262 	MSM6295Reset(0);
263 
264 	deco16Reset();
265 
266 	flipscreen = 0;
267 	soundlatch = 0;
268 	sound_irq = 0;
269 
270 	return 0;
271 }
272 
MemIndex()273 static INT32 MemIndex()
274 {
275 	UINT8 *Next; Next = AllMem;
276 
277 	Drv68KROM	= Next; Next += 0x080000;
278 	Drv68KCode	= Next; Next += 0x080000;
279 
280 	DrvZ80ROM	= Next; Next += 0x010000;
281 
282 	DrvGfxROM0	= Next; Next += 0x200000;
283 	DrvGfxROM1	= Next; Next += 0x200000;
284 	DrvGfxROM2	= Next; Next += 0x400000;
285 
286 	MSM6295ROM	= Next;
287 	DrvSndROM0	= Next; Next += 0x080000;
288 
289 	DrvPalette	= (UINT32*)Next; Next += 0x0400 * sizeof(UINT32);
290 
291 	AllRam		= Next;
292 
293 	Drv68KRAM	= Next; Next += 0x004000;
294 	DrvUnkRAM0	= Next; Next += 0x000400;
295 	DrvUnkRAM1	= Next; Next += 0x000400;
296 	DrvSprRAM	= Next; Next += 0x000800;
297 	DrvPalRAM	= Next; Next += 0x000800;
298 	DrvZ80RAM	= Next; Next += 0x000800;
299 
300 	RamEnd		= Next;
301 
302 	MemEnd		= Next;
303 
304 	return 0;
305 }
306 
DrvInit()307 static INT32 DrvInit()
308 {
309 	BurnSetRefreshRate(58.00);
310 
311 	AllMem = NULL;
312 	MemIndex();
313 	INT32 nLen = MemEnd - (UINT8 *)0;
314 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
315 	memset(AllMem, 0, nLen);
316 	MemIndex();
317 
318 	{
319 		if (BurnLoadRom(Drv68KROM  + 0x000000,  0, 2)) return 1;
320 		if (BurnLoadRom(Drv68KROM  + 0x000001,  1, 2)) return 1;
321 
322 		if (BurnLoadRom(DrvZ80ROM  + 0x000000,  2, 1)) return 1;
323 
324 		if (BurnLoadRom(DrvGfxROM1 + 0x000000,  3, 1)) return 1;
325 
326 		if (BurnLoadRom(DrvGfxROM2 + 0x000000,  4, 2)) return 1;
327 		if (BurnLoadRom(DrvGfxROM2 + 0x000001,  5, 2)) return 1;
328 
329 		if (BurnLoadRom(DrvSndROM0 + 0x000000,  6, 1)) return 1;
330 		memcpy (DrvSndROM0 + 0x20000, DrvSndROM0, 0x20000);
331 
332 		deco102_decrypt_cpu(Drv68KROM, Drv68KCode, 0x80000, 0x399d, 0x25, 0x3d);
333 		deco56_decrypt_gfx(DrvGfxROM1, 0x100000);
334 		deco16_tile_decode(DrvGfxROM1, DrvGfxROM0, 0x100000, 1);
335 		deco16_tile_decode(DrvGfxROM1, DrvGfxROM1, 0x100000, 0);
336 		deco16_sprite_decode(DrvGfxROM2, 0x200000);
337 	}
338 
339 	deco16Init(1, 0, 1);
340 	deco16_set_graphics(DrvGfxROM0, 0x100000 * 2, DrvGfxROM1, 0x100000 * 2, NULL, 0);
341 	deco16_set_global_offsets(0, 8);
342 	deco16_set_color_base(0, 0);
343 	deco16_set_color_base(1, 0x100);
344 	deco16_set_color_mask(0, 0xf);
345 	deco16_set_color_mask(1, 0xf);
346 	deco16_set_transparency_mask(0, 0xf);
347 	deco16_set_transparency_mask(1, 0xf);
348 	deco16_set_bank_callback(0, dblewing_bank_callback);
349 	deco16_set_bank_callback(1, dblewing_bank_callback);
350 
351 	SekInit(0, 0x68000);
352 	SekOpen(0);
353 	SekMapMemory(Drv68KROM,			0x000000, 0x07ffff, MAP_READ);
354 	SekMapMemory(Drv68KCode,		0x000000, 0x07ffff, MAP_FETCH);
355 	SekMapMemory(deco16_pf_ram[0],		0x100000, 0x100fff, MAP_RAM);
356 	SekMapMemory(deco16_pf_ram[1],		0x102000, 0x102fff, MAP_RAM);
357 	SekMapMemory(deco16_pf_rowscroll[0],	0x104000, 0x104fff, MAP_RAM);
358 	SekMapMemory(deco16_pf_rowscroll[1],	0x106000, 0x106fff, MAP_RAM);
359 	SekMapMemory(DrvUnkRAM0,		0x284000, 0x284400, MAP_RAM);
360 	SekMapMemory(DrvUnkRAM1,		0x288000, 0x288400, MAP_RAM);
361 	SekMapMemory(DrvSprRAM,			0x300000, 0x3007ff, MAP_RAM);
362 	SekMapMemory(DrvPalRAM,			0x320000, 0x3207ff, MAP_RAM);
363 	SekMapMemory(Drv68KRAM,			0xff0000, 0xff3fff, MAP_RAM);
364 	SekMapMemory(Drv68KRAM,			0xff4000, 0xff7fff, MAP_RAM);
365 	SekMapMemory(Drv68KRAM,			0xff8000, 0xffbfff, MAP_RAM);
366 	SekMapMemory(Drv68KRAM,			0xffc000, 0xffffff, MAP_RAM);
367 	SekSetWriteWordHandler(0,		dblewing_write_word);
368 	SekSetWriteByteHandler(0,		dblewing_write_byte);
369 	SekSetReadWordHandler(0,		dblewing_read_word);
370 	SekSetReadByteHandler(0,		dblewing_read_byte);
371 	SekClose();
372 
373 	ZetInit(0);
374 	ZetOpen(0);
375 	ZetMapMemory(DrvZ80ROM,			0x0000, 0x7fff, MAP_ROM);
376 	ZetMapMemory(DrvZ80RAM,			0x8000, 0x87ff, MAP_RAM);
377 	ZetSetWriteHandler(dblewing_sound_write);
378 	ZetSetReadHandler(dblewing_sound_read);
379 	ZetSetInHandler(dblewing_sound_read_port);
380 	ZetClose();
381 
382 	deco_104_init();
383 	deco_146_104_set_interface_scramble_interleave();
384 	deco_146_104_set_use_magic_read_address_xor(1);
385 	deco_146_104_set_port_a_cb(input_read); // inputs
386 	deco_146_104_set_port_b_cb(system_read); // system
387 	deco_146_104_set_port_c_cb(dips_read); // dips
388 	deco_146_104_set_soundlatch_cb(sound_callback);
389 
390 	BurnYM2151Init(3580000, 1);
391 	BurnYM2151SetIrqHandler(&DrvYM2151IrqHandler);
392 	BurnYM2151SetAllRoutes(0.75, BURN_SND_ROUTE_BOTH);
393 	BurnTimerAttachZet(3580000);
394 
395 	MSM6295Init(0, 1000000 / 132, 1);
396 	MSM6295SetRoute(0, 0.50, BURN_SND_ROUTE_BOTH);
397 
398 	GenericTilesInit();
399 
400 	DrvDoReset();
401 
402 	return 0;
403 }
404 
DrvExit()405 static INT32 DrvExit()
406 {
407 	GenericTilesExit();
408 	deco16Exit();
409 
410 	MSM6295Exit(0);
411 	BurnYM2151Exit();
412 
413 	SekExit();
414 	ZetExit();
415 
416 	BurnFree (AllMem);
417 
418 	MSM6295ROM = NULL;
419 
420 	return 0;
421 }
422 
draw_sprites()423 static void draw_sprites()
424 {
425 	UINT16 *spriteram = (UINT16 *)DrvSprRAM;
426 
427 	for (INT32 offs = 0; offs < 0x400; offs += 4)
428 	{
429 		INT32 inc, mult;
430 
431 		INT32 sprite = BURN_ENDIAN_SWAP_INT16(spriteram[offs+1]);
432 
433 		INT32 y = BURN_ENDIAN_SWAP_INT16(spriteram[offs]);
434 
435 		if ((y & 0x1000) && (nCurrentFrame & 1)) continue;
436 
437 		INT32 w = y & 0x0800;
438 		INT32 x = BURN_ENDIAN_SWAP_INT16(spriteram[offs + 2]);
439 		INT32 colour = (x >> 9) & 0x1f;
440 
441 		INT32 fx = y & 0x2000;
442 		INT32 fy = y & 0x4000;
443 		INT32 multi = (1 << ((y & 0x0600) >> 9)) - 1;
444 
445 		x = x & 0x01ff;
446 		y = y & 0x01ff;
447 		if (x >= 320) x -= 512;
448 		if (y >= 256) y -= 512;
449 		y = 240 - y;
450 		x = 304 - x;
451 
452 		sprite &= ~multi;
453 
454 		if (fy)
455 			inc = -1;
456 		else
457 		{
458 			sprite += multi;
459 			inc = 1;
460 		}
461 
462 		if (!flipscreen)
463 		{
464 			y = 240 - y;
465 			x = 304 - x;
466 			if (fy) fy = 0; else fy = 1;
467 			if (fx) fx = 0; else fx = 1;
468 			mult = 16;
469 
470 		}
471 		else mult = -16;
472 
473 		INT32 mult2 = multi + 1;
474 
475 		while (multi >= 0)
476 		{
477 			INT32 code = (sprite - multi * inc) & 0x3fff;
478 
479 			Draw16x16MaskTile(pTransDraw, code, x, (y + mult * multi) - 8, fx, fy, colour, 4, 0, 0x200, DrvGfxROM2);
480 
481 			if (w)
482 			{
483 				code = ((sprite - multi * inc)-mult2) & 0x3fff;
484 
485 				Draw16x16MaskTile(pTransDraw, code, x-16, (y + mult * multi) - 8, fx, fy, colour, 4, 0, 0x200, DrvGfxROM2);
486 			}
487 
488 			multi--;
489 		}
490 	}
491 }
492 
DrvPaletteUpdate()493 static void DrvPaletteUpdate()
494 {
495 	UINT16 *p = (UINT16*)DrvPalRAM;
496 
497 	for (INT32 i = 0; i < 0x800 / 2; i++)
498 	{
499 		UINT8 b = (BURN_ENDIAN_SWAP_INT16(p[i]) >> 8) & 0xf;
500 		UINT8 g = (BURN_ENDIAN_SWAP_INT16(p[i]) >> 4) & 0xf;
501 		UINT8 r = (BURN_ENDIAN_SWAP_INT16(p[i]) >> 0) & 0xf;
502 
503 		DrvPalette[i] = BurnHighCol(r+r*16, g+g*16, b+b*16, 0);
504 	}
505 }
506 
DrvDraw()507 static INT32 DrvDraw()
508 {
509 //	if (DrvRecalc) {
510 		DrvPaletteUpdate();
511 		DrvRecalc = 0;
512 //	}
513 
514 	deco16_pf12_update();
515 
516 	flipscreen = 1; //~deco16_pf_control[0][0] & 0x80;
517 
518 	//bprintf (0, _T("%4.4x\n"), deco16_pf_control[0][0]);
519 
520 	BurnTransferClear();
521 
522 	if (nBurnLayer & 1) deco16_draw_layer(1, pTransDraw, 0);
523 
524 	if (nBurnLayer & 2) deco16_draw_layer(0, pTransDraw, 0);
525 
526 	if (nBurnLayer & 4) draw_sprites();
527 
528 	BurnTransferCopy(DrvPalette);
529 
530 	return 0;
531 }
532 
DrvFrame()533 static INT32 DrvFrame()
534 {
535 	if (DrvReset) {
536 		DrvDoReset();
537 	}
538 
539 	ZetNewFrame();
540 
541 	{
542 		memset (DrvInputs, 0xff, 2 * sizeof(UINT16));
543 
544 		for (INT32 i = 0; i < 16; i++) {
545 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
546 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
547 		}
548 	}
549 
550 	INT32 nInterleave = 256;
551 	INT32 nCyclesTotal[2] = { 14000000 / 58, 3580000 / 58 };
552 	INT32 nCyclesDone[2] = { 0, 0 };
553 	INT32 nSoundBufferPos = 0;
554 
555 	SekOpen(0);
556 	ZetOpen(0);
557 
558 	deco16_vblank = 8;
559 
560 	for (INT32 i = 0; i < nInterleave; i++)
561 	{
562 		if (i == 16) deco16_vblank = 0;
563 		if (i == 248) {
564 			deco16_vblank = 0x08;
565 			SekSetIRQLine(6, CPU_IRQSTATUS_AUTO);
566 
567 			if (pBurnDraw) {
568 				DrvDraw();
569 			}
570 		}
571 
572 		CPU_RUN(0, Sek);
573 		CPU_RUN_TIMER(1);
574 
575 		if (pBurnSoundOut && i%4==3) {
576 			INT32 nSegmentLength = nBurnSoundLen / (nInterleave/4);
577 			INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
578 			BurnYM2151Render(pSoundBuf, nSegmentLength);
579 			MSM6295Render(0, pSoundBuf, nSegmentLength);
580 			nSoundBufferPos += nSegmentLength;
581 		}
582 	}
583 
584 	if (pBurnSoundOut) {
585 		INT32 nSegmentLength = nBurnSoundLen - nSoundBufferPos;
586 		INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
587 
588 		if (nSegmentLength) {
589 			BurnYM2151Render(pSoundBuf, nSegmentLength);
590 			MSM6295Render(0, pSoundBuf, nSegmentLength);
591 		}
592 	}
593 
594 	ZetClose();
595 	SekClose();
596 
597 	return 0;
598 }
599 
DrvScan(INT32 nAction,INT32 * pnMin)600 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
601 {
602 	struct BurnArea ba;
603 
604 	if (pnMin != NULL) {
605 		*pnMin = 0x029682;
606 	}
607 
608 	if (nAction & ACB_MEMORY_RAM) {
609 		memset(&ba, 0, sizeof(ba));
610 		ba.Data	  = AllRam;
611 		ba.nLen	  = RamEnd-AllRam;
612 		ba.szName = "All Ram";
613 		BurnAcb(&ba);
614 	}
615 
616 	if (nAction & ACB_DRIVER_DATA) {
617 		SekScan(nAction);
618 		ZetScan(nAction);
619 
620 		deco16Scan();
621 
622 		BurnYM2151Scan(nAction, pnMin);
623 		MSM6295Scan(nAction, pnMin);
624 
625 		SCAN_VAR(flipscreen);
626 		SCAN_VAR(soundlatch);
627 		SCAN_VAR(sound_irq);
628 	}
629 
630 	return 0;
631 }
632 
633 
634 // Double Wings (set 1)
635 
636 static struct BurnRomInfo dblewingRomDesc[] = {
637 	{ "kp_00-.3d",			0x040000, 0x547dc83e, 1 | BRF_PRG | BRF_ESS },   //  0 68k Code
638 	{ "kp_01-.5d",			0x040000, 0x7a210c33, 1 | BRF_PRG | BRF_ESS },   //  1
639 
640 	{ "kp_02-.10h",			0x010000, 0xdef035fa, 2 | BRF_PRG | BRF_ESS },   //  2 Z80 Code
641 
642 	{ "mbe-02.8h",			0x100000, 0x5a6d3ac5, 3 | BRF_GRA },             //  3 Character and Background Tiles
643 
644 	{ "mbe-00.14a",			0x100000, 0xe33f5c93, 4 | BRF_GRA },             //  4 Sprites
645 	{ "mbe-01.16a",			0x100000, 0xef452ad7, 4 | BRF_GRA },             //  5
646 
647 	{ "kp_03-.16h",			0x020000, 0x5d7f930d, 5 | BRF_SND },             //  6 OKI M6295 Samples
648 
649 	{ "pal1618-vg-00.1f",  	0x00117, 0x8c2849e5, 0 | BRF_OPT }, 			 //  7 Plds
650 	{ "pal1618-vg-01.1h",  	0x00117, 0x04b0bab6, 0 | BRF_OPT }, 			 //  8
651 	{ "pal16r8-vg-02.11b", 	0x00117, 0x00000000, 0 | BRF_OPT | BRF_NODUMP }, //  9
652 };
653 
654 STD_ROM_PICK(dblewing)
655 STD_ROM_FN(dblewing)
656 
657 // Double Wings (set 2)
658 
659 static struct BurnRomInfo dblewingaRomDesc[] = {
660 	{ "2.3d",				0x040000, 0x1e6b0653, 1 | BRF_PRG | BRF_ESS },   //  0 68k Code
661 	{ "1.5d",				0x040000, 0x4d537dc9, 1 | BRF_PRG | BRF_ESS },   //  1
662 
663 	{ "kp_02-.10h",			0x010000, 0xdef035fa, 2 | BRF_PRG | BRF_ESS },   //  2 Z80 Code
664 
665 	{ "mbe-02.8h",			0x100000, 0x5a6d3ac5, 3 | BRF_GRA },             //  3 Character and Background Tiles
666 
667 	{ "mbe-00.14a",			0x100000, 0xe33f5c93, 4 | BRF_GRA },             //  4 Sprites
668 	{ "mbe-01.16a",			0x100000, 0xef452ad7, 4 | BRF_GRA },             //  5
669 
670 	{ "kp_03-.16h",			0x020000, 0x5d7f930d, 5 | BRF_SND },           	 //  6 OKI M6295 Samples
671 
672 	{ "pal16l8-vg-00.1f",  	0x00117, 0x8c2849e5, 0 | BRF_OPT }, 			 //  7 Plds
673 	{ "pal16l8-vg-01.1h",  	0x00117, 0x04b0bab6, 0 | BRF_OPT }, 			 //  8
674 	{ "pal16r8-vg-02.11b", 	0x00117, 0x00000000, 0 | BRF_OPT | BRF_NODUMP }, //  9
675 };
676 
677 STD_ROM_PICK(dblewinga)
678 STD_ROM_FN(dblewinga)
679 
680 // Double Wings (Asia)
681 
682 /*
683 The most noticeable difference with the set below is that it doesn't use checkpoints, but respawns you when you die.
684 Checkpoints were more common in Japan, so this is likely to be an export version.
685 */
686 static struct BurnRomInfo dblewingbRomDesc[] = {
687 	{ "17.3d",	    		0x040000, 0x3a7ba822, 1 | BRF_PRG | BRF_ESS },   //  0 68k Code
688 	{ "18.5d",	    		0x040000, 0xe5f5f004, 1 | BRF_PRG | BRF_ESS },   //  1
689 
690 	{ "kp_02-.10h",			0x010000, 0xdef035fa, 2 | BRF_PRG | BRF_ESS },   //  2 Z80 Code
691 
692 	{ "mbe-02.8h",			0x100000, 0x5a6d3ac5, 3 | BRF_GRA },             //  3 Character and Background Tiles
693 
694 	{ "mbe-00.14a",			0x100000, 0xe33f5c93, 4 | BRF_GRA },             //  4 Sprites
695 	{ "mbe-01.16a",			0x100000, 0xef452ad7, 4 | BRF_GRA },             //  5
696 
697 	{ "kp_03-.16h",			0x020000, 0x5d7f930d, 5 | BRF_SND },             //  6 OKI M6295 Samples
698 
699 	{ "pal16l8-vg-00.1f",  	0x00117, 0x8c2849e5, 0 | BRF_OPT }, 			 //  7 Plds
700 	{ "pal16l8-vg-01.1h",  	0x00117, 0x04b0bab6, 0 | BRF_OPT }, 			 //  8
701 	{ "pal16r8-vg-02.11b", 	0x00117, 0x00000000, 0 | BRF_OPT | BRF_NODUMP }, //  9
702 };
703 
704 STD_ROM_PICK(dblewingb)
705 STD_ROM_FN(dblewingb)
706 
707 struct BurnDriver BurnDrvDblewing = {
708 	"dblewing", NULL, NULL, NULL, "1993",
709 	"Double Wings (set 1)\0", NULL, "Mitchell", "DECO IC16",
710 	NULL, NULL, NULL, NULL,
711 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_PREFIX_DATAEAST, GBF_VERSHOOT, 0,
712 	NULL, dblewingRomInfo, dblewingRomName, NULL, NULL, NULL, NULL, DblewingInputInfo, DblewingDIPInfo,
713 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x400,
714 	240, 320, 3, 4
715 };
716 
717 struct BurnDriver BurnDrvDblewinga = {
718 	"dblewinga", "dblewing", NULL, NULL, "1993",
719 	"Double Wings (set 2)\0", NULL, "Mitchell", "DECO IC16",
720 	NULL, NULL, NULL, NULL,
721 	BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_PREFIX_DATAEAST, GBF_VERSHOOT, 0,
722 	NULL, dblewingaRomInfo, dblewingaRomName, NULL, NULL, NULL, NULL, DblewingInputInfo, DblewingDIPInfo,
723 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x400,
724 	240, 320, 3, 4
725 };
726 
727 struct BurnDriver BurnDrvDblewingb = {
728 	"dblewingb", "dblewing", NULL, NULL, "1994",
729 	"Double Wings (Asia)\0", NULL, "Mitchell", "DECO IC16",
730 	NULL, NULL, NULL, NULL,
731 	BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_PREFIX_DATAEAST, GBF_VERSHOOT, 0,
732 	NULL, dblewingbRomInfo, dblewingbRomName, NULL, NULL, NULL, NULL, DblewingInputInfo, DblewingDIPInfo,
733 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x400,
734 	240, 320, 3, 4
735 };