1 // FB Alpha Wyvern F-0 driver module
2 // Based on MAME driver by Luca Elia
3 
4 // Note: wyvernf0 sound hw has a dac @ 0xd600, but it is not used in the
5 // game at all except for initialization @ boot (0x80)
6 
7 #include "tiles_generic.h"
8 #include "z80_intf.h"
9 #include "taito_m68705.h"
10 #include "ay8910.h"
11 #include "msm5232.h"
12 
13 static UINT8 *AllMem;
14 static UINT8 *MemEnd;
15 static UINT8 *AllRam;
16 static UINT8 *RamEnd;
17 static UINT8 *DrvZ80ROM0;
18 static UINT8 *DrvZ80ROM1;
19 static UINT8 *DrvGfxROM0;
20 static UINT8 *DrvGfxROM1;
21 static UINT8 *DrvZ80RAM0;
22 static UINT8 *DrvMcuROM;
23 static UINT8 *DrvMcuRAM;
24 static UINT8 *DrvFgRAM;
25 static UINT8 *DrvBgRAM;
26 static UINT8 *DrvSprRAM;
27 static UINT8 *DrvPalRAM;
28 static UINT8 *DrvObjRAM;
29 static UINT8 *DrvZ80RAM1;
30 
31 static UINT8 *soundlatch;
32 static UINT8 *flipscreen;
33 static UINT8 *coin_lockout;
34 static UINT8 *scroll;
35 static UINT8 *pending_nmi;
36 static UINT8 *nmi_enable;
37 static UINT8 *DrvZ80ROMBank;
38 static UINT8 *DrvZ80RAMBank;
39 
40 static UINT32 *DrvPalette;
41 static UINT8 DrvRecalc;
42 
43 static UINT8 DrvJoy1[8];
44 static UINT8 DrvJoy2[8];
45 static UINT8 DrvJoy3[8];
46 static UINT8 DrvJoy4[8];
47 static UINT8 DrvJoy5[8];
48 static UINT8 DrvDips[3];
49 static UINT8 DrvInputs[5];
50 static UINT8 DrvReset;
51 
52 static struct BurnInputInfo Wyvernf0InputList[] = {
53 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 4,	"p1 coin"	},
54 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 0,	"p1 start"	},
55 	{"P1 Up",			BIT_DIGITAL,	DrvJoy2 + 5,	"p1 up"		},
56 	{"P1 Down",			BIT_DIGITAL,	DrvJoy2 + 4,	"p1 down"	},
57 	{"P1 Left",			BIT_DIGITAL,	DrvJoy2 + 2,	"p1 left"	},
58 	{"P1 Right",		BIT_DIGITAL,	DrvJoy2 + 3,	"p1 right"	},
59 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy3 + 5,	"p1 fire 1"	},
60 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy3 + 4,	"p1 fire 2"	},
61 	{"P1 Button 3",		BIT_DIGITAL,	DrvJoy3 + 3,	"p1 fire 3"	},
62 
63 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy1 + 5,	"p2 coin"	},
64 	{"P2 Start",		BIT_DIGITAL,	DrvJoy1 + 1,	"p2 start"	},
65 	{"P2 Up",			BIT_DIGITAL,	DrvJoy4 + 5,	"p2 up"		},
66 	{"P2 Down",			BIT_DIGITAL,	DrvJoy4 + 4,	"p2 down"	},
67 	{"P2 Left",			BIT_DIGITAL,	DrvJoy4 + 2,	"p2 left"	},
68 	{"P2 Right",		BIT_DIGITAL,	DrvJoy4 + 3,	"p2 right"	},
69 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy5 + 5,	"p2 fire 1"	},
70 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy5 + 4,	"p2 fire 2"	},
71 	{"P2 Button 3",		BIT_DIGITAL,	DrvJoy5 + 3,	"p2 fire 3"	},
72 
73 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
74 	{"Service",			BIT_DIGITAL,	DrvJoy1 + 2,	"service"	},
75 	{"Tilt",			BIT_DIGITAL,	DrvJoy1 + 3,	"tilt"		},
76 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
77 	{"Dip B",			BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
78 	{"Dip C",			BIT_DIPSWITCH,	DrvDips + 2,	"dip"		},
79 };
80 
81 STDINPUTINFO(Wyvernf0)
82 
83 static struct BurnDIPInfo Wyvernf0DIPList[]=
84 {
85 	{0x15, 0xff, 0xff, 0x6f, NULL					},
86 	{0x16, 0xff, 0xff, 0x00, NULL					},
87 	{0x17, 0xff, 0xff, 0xdc, NULL					},
88 
89 	{0   , 0xfe, 0   ,    4, "Bonus Life"			},
90 	{0x15, 0x01, 0x03, 0x00, "?? 0"					},
91 	{0x15, 0x01, 0x03, 0x01, "?? 1"					},
92 	{0x15, 0x01, 0x03, 0x02, "?? 2"					},
93 	{0x15, 0x01, 0x03, 0x03, "?? 3"					},
94 
95 	{0   , 0xfe, 0   ,    2, "Free Play"			},
96 	{0x15, 0x01, 0x04, 0x04, "Off"					},
97 	{0x15, 0x01, 0x04, 0x00, "On"					},
98 
99 	{0   , 0xfe, 0   ,    4, "Lives"				},
100 	{0x15, 0x01, 0x18, 0x00, "2"					},
101 	{0x15, 0x01, 0x18, 0x08, "3"					},
102 	{0x15, 0x01, 0x18, 0x10, "4"					},
103 	{0x15, 0x01, 0x18, 0x18, "5"					},
104 
105 	{0   , 0xfe, 0   ,    2, "Flip Screen"			},
106 	{0x15, 0x01, 0x40, 0x40, "Off"					},
107 	{0x15, 0x01, 0x40, 0x00, "On"					},
108 
109 	{0   , 0xfe, 0   ,    2, "Cabinet"				},
110 	{0x15, 0x01, 0x80, 0x00, "Upright"				},
111 	{0x15, 0x01, 0x80, 0x80, "Cocktail"				},
112 
113 	{0   , 0xfe, 0   ,    16, "Coin A"				},
114 	{0x16, 0x01, 0x0f, 0x0f, "9 Coins 1 Credits"	},
115 	{0x16, 0x01, 0x0f, 0x0e, "8 Coins 1 Credits"	},
116 	{0x16, 0x01, 0x0f, 0x0d, "7 Coins 1 Credits"	},
117 	{0x16, 0x01, 0x0f, 0x0c, "6 Coins 1 Credits"	},
118 	{0x16, 0x01, 0x0f, 0x0b, "5 Coins 1 Credits"	},
119 	{0x16, 0x01, 0x0f, 0x0a, "4 Coins 1 Credits"	},
120 	{0x16, 0x01, 0x0f, 0x09, "3 Coins 1 Credits"	},
121 	{0x16, 0x01, 0x0f, 0x08, "2 Coins 1 Credits"	},
122 	{0x16, 0x01, 0x0f, 0x00, "1 Coin  1 Credits"	},
123 	{0x16, 0x01, 0x0f, 0x01, "1 Coin  2 Credits"	},
124 	{0x16, 0x01, 0x0f, 0x02, "1 Coin  3 Credits"	},
125 	{0x16, 0x01, 0x0f, 0x03, "1 Coin  4 Credits"	},
126 	{0x16, 0x01, 0x0f, 0x04, "1 Coin  5 Credits"	},
127 	{0x16, 0x01, 0x0f, 0x05, "1 Coin  6 Credits"	},
128 	{0x16, 0x01, 0x0f, 0x06, "1 Coin  7 Credits"	},
129 	{0x16, 0x01, 0x0f, 0x07, "1 Coin  8 Credits"	},
130 
131 	{0   , 0xfe, 0   ,    16, "Coin B"				},
132 	{0x16, 0x01, 0xf0, 0xf0, "9 Coins 1 Credits"	},
133 	{0x16, 0x01, 0xf0, 0xe0, "8 Coins 1 Credits"	},
134 	{0x16, 0x01, 0xf0, 0xd0, "7 Coins 1 Credits"	},
135 	{0x16, 0x01, 0xf0, 0xc0, "6 Coins 1 Credits"	},
136 	{0x16, 0x01, 0xf0, 0xb0, "5 Coins 1 Credits"	},
137 	{0x16, 0x01, 0xf0, 0xa0, "4 Coins 1 Credits"	},
138 	{0x16, 0x01, 0xf0, 0x90, "3 Coins 1 Credits"	},
139 	{0x16, 0x01, 0xf0, 0x80, "2 Coins 1 Credits"	},
140 	{0x16, 0x01, 0xf0, 0x00, "1 Coin  1 Credits"	},
141 	{0x16, 0x01, 0xf0, 0x10, "1 Coin  2 Credits"	},
142 	{0x16, 0x01, 0xf0, 0x20, "1 Coin  3 Credits"	},
143 	{0x16, 0x01, 0xf0, 0x30, "1 Coin  4 Credits"	},
144 	{0x16, 0x01, 0xf0, 0x40, "1 Coin  5 Credits"	},
145 	{0x16, 0x01, 0xf0, 0x50, "1 Coin  6 Credits"	},
146 	{0x16, 0x01, 0xf0, 0x60, "1 Coin  7 Credits"	},
147 	{0x16, 0x01, 0xf0, 0x70, "1 Coin  8 Credits"	},
148 
149 	{0   , 0xfe, 0   ,    2, "Coinage Display"		},
150 	{0x17, 0x01, 0x10, 0x00, "No"					},
151 	{0x17, 0x01, 0x10, 0x10, "Yes"					},
152 
153 	{0   , 0xfe, 0   ,    2, "Copyright"			},
154 	{0x17, 0x01, 0x20, 0x00, "Taito Corporation"	},
155 	{0x17, 0x01, 0x20, 0x20, "Taito Corp. 1985"		},
156 
157 	{0   , 0xfe, 0   ,    2, "Invulnerability"		},
158 	{0x17, 0x01, 0x40, 0x40, "Off"					},
159 	{0x17, 0x01, 0x40, 0x00, "On"					},
160 
161 	{0   , 0xfe, 0   ,    2, "Coin Slots"			},
162 	{0x17, 0x01, 0x80, 0x00, "1"					},
163 	{0x17, 0x01, 0x80, 0x80, "2"					},
164 };
165 
STDDIPINFO(Wyvernf0)166 STDDIPINFO(Wyvernf0)
167 
168 static inline void palette_update(INT32 i)
169 {
170 	INT32 r = DrvPalRAM[i+0] & 0x0f;
171 	INT32 g = DrvPalRAM[i+1] >> 4;
172 	INT32 b = DrvPalRAM[i+1] & 0x0f;
173 
174 	DrvPalette[i/2] = BurnHighCol(r | (r << 4), g | (g << 4), b | (b << 4), 0);
175 }
176 
rambankswitch(INT32 data)177 static void rambankswitch(INT32 data)
178 {
179 	INT32 bank = (data & 0x80) ? 0x1000 : 0;
180 
181 	*DrvZ80RAMBank = data;
182 
183 	*coin_lockout = (~data & 0x40) ? 0xcf : 0xff;
184 
185 	*flipscreen = data & 0x03;
186 
187 	ZetMapMemory(DrvObjRAM + bank, 0x9000, 0x9fff, MAP_RAM);
188 }
189 
rombankswitch(INT32 data)190 static void rombankswitch(INT32 data)
191 {
192 	INT32 bank = 0x10000 + (data & 0x07) * 0x2000;
193 
194 	*DrvZ80ROMBank = data;
195 
196 	ZetMapMemory(DrvZ80ROM0 + bank,	0xa000, 0xbfff, MAP_ROM);
197 }
198 
wyvernf0_main_write(UINT16 address,UINT8 data)199 static void __fastcall wyvernf0_main_write(UINT16 address, UINT8 data)
200 {
201 	if ((address & 0xfc00) == 0xd800) {
202 		DrvPalRAM[address & 0x3ff] = data;
203 		palette_update(address & 0x3fe);
204 		return;
205 	}
206 
207 	switch (address)
208 	{
209 		case 0xd000:
210 		return;		// nop
211 
212 		case 0xd100:
213 			rambankswitch(data);
214 		return;
215 
216 		case 0xd200:
217 			rombankswitch(data);
218 		return;
219 
220 		case 0xd300:
221 		case 0xd301:
222 		case 0xd302:
223 		case 0xd303:
224 			scroll[address & 0x03] = data;
225 		return;
226 
227 		case 0xd400:
228 			standard_taito_mcu_write(data);
229 		return;
230 
231 		case 0xd610:
232 		{
233 			*soundlatch = data;
234 			if (*nmi_enable) {
235 				ZetNmi(1);
236 			} else {
237 				*pending_nmi = 1;
238 			}
239 		}
240 		return;
241 
242 		case 0xdc00:
243 		return; // nop
244 	}
245 }
246 
wyvernf0_main_read(UINT16 address)247 static UINT8 __fastcall wyvernf0_main_read(UINT16 address)
248 {
249 	switch (address)
250 	{
251 		case 0xd400:
252 			return standard_taito_mcu_read();
253 
254 		case 0xd401:
255 			return ( (!main_sent ? 1 : 0) | (mcu_sent ? 2 : 0) );
256 
257 		case 0xd600:
258 		case 0xd601:
259 		case 0xd602:
260 			return DrvDips[address - 0xd600];
261 
262 		case 0xd603:
263 		case 0xd604:
264 		case 0xd605:
265 		case 0xd606:
266 		case 0xd607:
267 			return DrvInputs[address - 0xd603];
268 
269 		case 0xd610:
270 			return *soundlatch;
271 	}
272 
273 	return 0;
274 }
275 
wyvernf0_sound_write(UINT16 address,UINT8 data)276 static void __fastcall wyvernf0_sound_write(UINT16 address, UINT8 data)
277 {
278 	if ((address & 0xfff0) == 0xc900) {
279 		MSM5232Write(address & 0x0f, data);
280 		return;
281 	}
282 
283 	switch (address)
284 	{
285 		case 0xc800:
286 		case 0xc801:
287 		case 0xc802:
288 		case 0xc803:
289 			AY8910Write((address/2) & 1, address & 1, data);
290 			if (data==0x88) { // end of sound command, turn off all channels to get rid of unwanted high pitched noises
291 				AY8910Write((address/2) & 1, 0, 0x08);
292 				AY8910Write((address/2) & 1, 1, 0x00);
293 				AY8910Write((address/2) & 1, 0, 0x09);
294 				AY8910Write((address/2) & 1, 1, 0x00);
295 				AY8910Write((address/2) & 1, 0, 0x0A);
296 				AY8910Write((address/2) & 1, 1, 0x00);
297 			}
298 		return;
299 
300 		case 0xd000:
301 			*soundlatch = data;
302 		return;
303 
304 		case 0xd200:
305 		{
306 			*nmi_enable = 1;
307 
308 			if (*pending_nmi)
309 			{
310 				ZetNmi();
311 				*pending_nmi = 0;
312 			}
313 		}
314 		return;
315 
316 		case 0xd400:
317 			*nmi_enable = 0;
318 		return;
319 
320 		case 0xd600:
321 		return; // ??
322 	}
323 }
324 
wyvernf0_sound_read(UINT16 address)325 static UINT8 __fastcall wyvernf0_sound_read(UINT16 address)
326 {
327 	switch (address)
328 	{
329 		case 0xd000:
330 			return *soundlatch;
331 	}
332 
333 	return 0;
334 }
335 
DrvDoReset()336 static INT32 DrvDoReset()
337 {
338 	memset (AllRam, 0, RamEnd - AllRam);
339 
340 	ZetOpen(0);
341 	ZetReset();
342 	rombankswitch(0);
343 	rambankswitch(0);
344 	ZetClose();
345 
346 	ZetOpen(1);
347 	ZetReset();
348 	ZetClose();
349 
350 	m67805_taito_reset();
351 
352 	AY8910Reset(0);
353 	AY8910Reset(1);
354 
355 	MSM5232Reset();
356 
357 	return 0;
358 }
359 
MemIndex()360 static INT32 MemIndex()
361 {
362 	UINT8 *Next; Next = AllMem;
363 
364 	DrvZ80ROM0		= Next; Next += 0x020000;
365 	DrvZ80ROM1		= Next; Next += 0x010000;
366 	DrvMcuROM       = Next; Next += 0x000800;
367 
368 	DrvGfxROM0		= Next; Next += 0x020000;
369 	DrvGfxROM1		= Next; Next += 0x010000;
370 
371 	DrvPalette		= (UINT32*)Next; Next += 0x0200 * sizeof(UINT32);
372 
373 	AllRam			= Next;
374 
375 	DrvZ80RAM0		= Next; Next += 0x001000;
376 	DrvFgRAM		= Next; Next += 0x000800;
377 	DrvBgRAM		= Next; Next += 0x000800;
378 	DrvSprRAM		= Next; Next += 0x000100;
379 	DrvPalRAM		= Next; Next += 0x000400;
380 	DrvObjRAM		= Next; Next += 0x002000;
381 
382 	DrvZ80RAM1		= Next; Next += 0x000800;
383 
384 	DrvMcuRAM       = Next; Next += 0x000800;
385 
386 	soundlatch		= Next; Next += 0x000001;
387 	flipscreen		= Next; Next += 0x000001;
388 	coin_lockout	= Next; Next += 0x000001;
389 	pending_nmi		= Next; Next += 0x000001;
390 	nmi_enable		= Next; Next += 0x000001;
391 	scroll			= Next; Next += 0x000004;
392 	DrvZ80ROMBank	= Next; Next += 0x000001;
393 	DrvZ80RAMBank	= Next; Next += 0x000001;
394 
395 	RamEnd			= Next;
396 
397 	MemEnd			= Next;
398 
399 	return 0;
400 }
401 
DrvGfxDecode(UINT8 * rom,INT32 len)402 static void DrvGfxDecode(UINT8 *rom, INT32 len)
403 {
404 	INT32 Planes[4] = { RGN_FRAC(len,0,4), RGN_FRAC(len,1,4), RGN_FRAC(len,2,4), RGN_FRAC(len,3,4) };
405 	INT32 XOffs[8] = { STEP8(7,-1) };
406 	INT32 YOffs[8] = { STEP8(0,8) };
407 
408 	UINT8 *tmp = (UINT8*)BurnMalloc(len);
409 	if (tmp == NULL) {
410 		return;
411 	}
412 
413 	memcpy (tmp, rom, len);
414 
415 	GfxDecode(((len/4)*8)/(8*8), 4, 8, 8, Planes, XOffs, YOffs, 0x040, tmp, rom);
416 
417 	BurnFree(tmp);
418 }
419 
DrvInit()420 static INT32 DrvInit()
421 {
422 	AllMem = NULL;
423 	MemIndex();
424 	INT32 nLen = MemEnd - (UINT8 *)0;
425 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
426 	memset(AllMem, 0, nLen);
427 	MemIndex();
428 
429 	{
430 		if (BurnLoadRom(DrvZ80ROM0 + 0x00000,  0, 1)) return 1;
431 		if (BurnLoadRom(DrvZ80ROM0 + 0x04000,  1, 1)) return 1;
432 		if (BurnLoadRom(DrvZ80ROM0 + 0x10000,  2, 1)) return 1;
433 		if (BurnLoadRom(DrvZ80ROM0 + 0x14000,  3, 1)) return 1;
434 		if (BurnLoadRom(DrvZ80ROM0 + 0x18000,  4, 1)) return 1;
435 		if (BurnLoadRom(DrvZ80ROM0 + 0x1c000,  5, 1)) return 1;
436 
437 		if (BurnLoadRom(DrvZ80ROM1 + 0x00000,  6, 1)) return 1;
438 		memset (DrvZ80ROM1 + 0xe000, 0xff, 0x2000);
439 
440 		if (BurnLoadRom(DrvGfxROM0 + 0x00000,  7, 1)) return 1;
441 		if (BurnLoadRom(DrvGfxROM0 + 0x04000,  8, 1)) return 1;
442 		if (BurnLoadRom(DrvGfxROM0 + 0x08000,  9, 1)) return 1;
443 		if (BurnLoadRom(DrvGfxROM0 + 0x0c000, 10, 1)) return 1;
444 
445 		if (BurnLoadRom(DrvGfxROM1 + 0x00000, 11, 1)) return 1;
446 		if (BurnLoadRom(DrvGfxROM1 + 0x02000, 12, 1)) return 1;
447 		if (BurnLoadRom(DrvGfxROM1 + 0x04000, 13, 1)) return 1;
448 		if (BurnLoadRom(DrvGfxROM1 + 0x06000, 14, 1)) return 1;
449 
450 		if (BurnLoadRom(DrvMcuROM  + 0x00000, 15, 1)) return 1;
451 
452 		DrvGfxDecode(DrvGfxROM0, 0x10000);
453 		DrvGfxDecode(DrvGfxROM1, 0x08000);
454 	}
455 
456 	ZetInit(0);
457 	ZetOpen(0);
458 	ZetMapMemory(DrvZ80ROM0,		0x0000, 0x7fff, MAP_ROM);
459 	ZetMapMemory(DrvZ80RAM0,		0x8000, 0x8fff, MAP_RAM);
460 	ZetMapMemory(DrvFgRAM,			0xc000, 0xc7ff, MAP_RAM);
461 	ZetMapMemory(DrvBgRAM,			0xc800, 0xcfff, MAP_RAM);
462 	ZetMapMemory(DrvSprRAM,			0xd500, 0xd5ff, MAP_RAM);
463 	ZetMapMemory(DrvPalRAM,			0xd800, 0xdbff, MAP_ROM);
464 	ZetSetWriteHandler(wyvernf0_main_write);
465 	ZetSetReadHandler(wyvernf0_main_read);
466 	ZetClose();
467 
468 	ZetInit(1);
469 	ZetOpen(1);
470 	ZetMapMemory(DrvZ80ROM1,		0x0000, 0x3fff, MAP_ROM);
471 	ZetMapMemory(DrvZ80RAM1,		0xc000, 0xc7ff, MAP_RAM);
472 	ZetMapMemory(DrvZ80ROM1 + 0xe000,	0xe000, 0xefff, MAP_ROM);
473 	ZetSetWriteHandler(wyvernf0_sound_write);
474 	ZetSetReadHandler(wyvernf0_sound_read);
475 	ZetClose();
476 
477 	m67805_taito_init(DrvMcuROM, DrvMcuRAM, &standard_m68705_interface);
478 
479 	AY8910Init(0, 3000000, 0);
480 	AY8910Init(1, 3000000, 1);
481 	AY8910SetAllRoutes(0, 0.14, BURN_SND_ROUTE_BOTH);
482 	AY8910SetAllRoutes(1, 0.14, BURN_SND_ROUTE_BOTH);
483 
484 	MSM5232Init(2000000, 1);
485 	MSM5232SetCapacitors(0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6);
486 	MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_0);
487 	MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_1);
488 	MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_2);
489 	MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_3);
490 	MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_4);
491 	MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_5);
492 	MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_6);
493 	MSM5232SetRoute(0.50, BURN_SND_MSM5232_ROUTE_7);
494 
495 	GenericTilesInit();
496 
497 	DrvDoReset();
498 
499 	return 0;
500 }
501 
DrvExit()502 static INT32 DrvExit()
503 {
504 	GenericTilesExit();
505 
506 	ZetExit();
507 
508 	m67805_taito_exit();
509 
510 	AY8910Exit(0);
511 	AY8910Exit(1);
512 
513 	MSM5232Exit();
514 
515 	BurnFree(AllMem);
516 
517 	return 0;
518 }
519 
draw_layer(UINT8 * ram,INT32 color_offset,UINT8 scrollx,UINT8 scrolly)520 static void draw_layer(UINT8 *ram, INT32 color_offset, UINT8 scrollx, UINT8 scrolly)
521 {
522 	for (INT32 offs = 0; offs < 32 * 32; offs++)
523 	{
524 		INT32 sx = (offs & 0x1f) * 8;
525 		INT32 sy = (offs / 0x20) * 8;
526 
527 		sx -= scrollx;
528 		if (sx < -7) sx += 256;
529 		sy -= scrolly;
530 		if (sy < -7) sy += 256;
531 
532 		if (sy >= 224) continue;
533 
534 		INT32 code = ((ram[offs * 2 + 1] & 0x03) << 8) + ram[offs * 2];
535 
536 		INT32 color = (code >> 12) & 0x07;
537 		INT32 flipx = (code >> 15) & 0x01;
538 		INT32 flipy = (code >> 14) & 0x01;
539 
540 		if (flipy) {
541 			if (flipx) {
542 				Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code & 0x3ff, sx, sy, color, 4, 0, color_offset, DrvGfxROM1);
543 			} else {
544 				Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code & 0x3ff, sx, sy, color, 4, 0, color_offset, DrvGfxROM1);
545 			}
546 		} else {
547 			if (flipx) {
548 				Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code & 0x3ff, sx, sy, color, 4, 0, color_offset, DrvGfxROM1);
549 			} else {
550 				Render8x8Tile_Mask_Clip(pTransDraw, code & 0x3ff, sx, sy, color, 4, 0, color_offset, DrvGfxROM1);
551 			}
552 		}
553 	}
554 }
555 
draw_sprites(INT32 is_foreground)556 static void draw_sprites(INT32 is_foreground)
557 {
558 	UINT8 *RAM = DrvSprRAM + (is_foreground ? 0x80 : 0);
559 
560 	for (INT32 offs = 0; offs < 0x100 / 2; offs += 4)
561 	{
562 		INT32 sx = RAM[offs + 3] - ((RAM[offs + 2] & 0x80) << 1);
563 		INT32 sy = 256 - 8 - RAM[offs + 0] - 23;
564 
565 		INT32 flipx = RAM[offs + 2] & 0x40;
566 		INT32 flipy = RAM[offs + 1] & 0x80;
567 
568 		if (*flipscreen & 0x01)
569 		{
570 			flipx = !flipx;
571 			sx = 256 - 8 - sx - 3 * 8;
572 		}
573 		if (*flipscreen & 0x02)
574 		{
575 			flipy = !flipy;
576 			sy = 256 - 8 - sy - 3 * 8;
577 		}
578 
579 		INT32 code  = (RAM[offs + 1] & 0x7f) + (is_foreground ? 0x80 : 0);
580 		INT32 color = (RAM[offs + 2] & 0x0f) + (is_foreground ? 0x10 : 0);
581 
582 		for (INT32 y = 0; y < 4; y++)
583 		{
584 			for (INT32 x = 0; x < 4; x++)
585 			{
586 				INT32 objoffs = code * 0x20 + (x + y * 4) * 2;
587 
588 				INT32 sxx = sx + (flipx ? 3-x : x) * 8;
589 				INT32 syy = sy + (flipy ? 3-y : y) * 8;
590 
591 				INT32 code1 = ((DrvObjRAM[objoffs + 1] & 0x07) << 8) + DrvObjRAM[objoffs];
592 
593 				if (flipy) {
594 					if (flipx) {
595 						Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code1, sxx, syy - 16, color, 4, 0, 0, DrvGfxROM0);
596 					} else {
597 						Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code1, sxx, syy - 16, color, 4, 0, 0, DrvGfxROM0);
598 					}
599 				} else {
600 					if (flipx) {
601 						Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code1, sxx, syy - 16, color, 4, 0, 0, DrvGfxROM0);
602 					} else {
603 						Render8x8Tile_Mask_Clip(pTransDraw, code1, sxx, syy - 16, color, 4, 0, 0, DrvGfxROM0);
604 					}
605 				}
606 			}
607 		}
608 	}
609 }
610 
DrvDraw()611 static INT32 DrvDraw()
612 {
613 	if (DrvRecalc) {
614 		for (INT32 i = 0; i < 0x400; i+=2) {
615 			palette_update(i);
616 		}
617 		DrvRecalc = 0;
618 	}
619 
620 	BurnTransferClear();
621 
622 	draw_layer(DrvBgRAM, 0x00, scroll[2] - 0x12, scroll[3] + 0x10);
623 	draw_sprites(0);
624 	draw_sprites(1);
625 	draw_layer(DrvFgRAM, 0x80, scroll[0] - 0x10, scroll[1] + 0x10);
626 
627 	BurnTransferCopy(DrvPalette);
628 
629 	return 0;
630 }
631 
DrvFrame()632 static INT32 DrvFrame()
633 {
634 	if (DrvReset) {
635 		DrvDoReset();
636 	}
637 
638 	{
639 		memset (DrvInputs, 0, 5);
640 
641 		for (INT32 i = 0; i < 8; i++) {
642 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
643 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
644 			DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
645 			DrvInputs[3] ^= (DrvJoy4[i] & 1) << i;
646 			DrvInputs[4] ^= (DrvJoy5[i] & 1) << i;
647 		}
648 
649 		DrvInputs[0] = (DrvInputs[0] & *coin_lockout);// | 0xc0;
650 	}
651 
652 	INT32 nInterleave = 100;
653 	INT32 nCyclesTotal[3] = { 6000000 / 60, 4000000 / 60, 4000000 / 60 };
654 	INT32 nCyclesDone[3]  = { 0, 0, 0 };
655 
656 	for (INT32 i = 0; i < nInterleave; i++)
657 	{
658 		ZetOpen(0);
659 		CPU_RUN(0, Zet);
660 		if (i == (nInterleave - 1)) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
661 		ZetClose();
662 
663 		ZetOpen(1);
664 		CPU_RUN(1, Zet);
665 		if (i == (nInterleave - 1) || i == (nInterleave / 2) - 1) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
666 		ZetClose();
667 
668 		m6805Open(0);
669 		CPU_RUN(2, m6805);
670 		m6805Close();
671 	}
672 
673 	if (pBurnSoundOut) {
674 		AY8910Render(pBurnSoundOut, nBurnSoundLen);
675 		MSM5232Update(pBurnSoundOut, nBurnSoundLen);
676 	}
677 
678 	if (pBurnDraw) {
679 		DrvDraw();
680 	}
681 
682 	return 0;
683 }
684 
DrvScan(INT32 nAction,INT32 * pnMin)685 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
686 {
687 	struct BurnArea ba;
688 
689 	if (pnMin) {
690 		*pnMin = 0x029702;
691 	}
692 
693 	if (nAction & ACB_VOLATILE) {
694 		memset(&ba, 0, sizeof(ba));
695 
696 		ba.Data	  = AllRam;
697 		ba.nLen	  = RamEnd - AllRam;
698 		ba.szName = "All Ram";
699 		BurnAcb(&ba);
700 
701 		ZetScan(nAction);
702 		m68705_taito_scan(nAction);
703 
704 		AY8910Scan(nAction, pnMin);
705 		MSM5232Scan(nAction, pnMin);
706 	}
707 
708 	if (nAction & ACB_WRITE) {
709 		ZetOpen(0);
710 		rambankswitch(*DrvZ80RAMBank);
711 		rombankswitch(*DrvZ80ROMBank);
712 		ZetClose();
713 	}
714 
715 	return 0;
716 }
717 
718 
719 // Wyvern F-0 (Rev 1)
720 
721 static struct BurnRomInfo wyvernf0RomDesc[] = {
722 	{ "a39_01-1.ic37",	0x4000, 0xa94887ec, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
723 	{ "a39_02-1.ic36",	0x4000, 0x171cfdbe, 1 | BRF_PRG | BRF_ESS }, //  1
724 	{ "a39_03.ic35",	0x4000, 0x50314281, 1 | BRF_PRG | BRF_ESS }, //  2
725 	{ "a39_04.ic34",	0x4000, 0x7a225bf9, 1 | BRF_PRG | BRF_ESS }, //  3
726 	{ "a39_05.ic33",	0x4000, 0x41f21a67, 1 | BRF_PRG | BRF_ESS }, //  4
727 	{ "a39_06.ic32",	0x4000, 0xdeb2d850, 1 | BRF_PRG | BRF_ESS }, //  5
728 
729 	{ "a39_16.ic26",	0x4000, 0x5a681fb4, 2 | BRF_PRG | BRF_ESS }, //  6 Z80 #0 Code
730 
731 	{ "a39_11.ic99",	0x4000, 0xaf70e1dc, 3 | BRF_GRA },           //  7 Sprites
732 	{ "a39_10.ic78",	0x4000, 0xa84380fb, 3 | BRF_GRA },           //  8
733 	{ "a39_09.ic96",	0x4000, 0xc0cee243, 3 | BRF_GRA },           //  9
734 	{ "a39_08.ic75",	0x4000, 0x0ad69501, 3 | BRF_GRA },           // 10
735 
736 	{ "a39_15.ic99",	0x2000, 0x90a66147, 4 | BRF_GRA },           // 11 Tiles
737 	{ "a39_14.ic73",	0x2000, 0xa31f3507, 4 | BRF_GRA },           // 12
738 	{ "a39_13.ic100",	0x2000, 0xbe708238, 4 | BRF_GRA },           // 13
739 	{ "a39_12.ic74",	0x2000, 0x1cc389de, 4 | BRF_GRA },           // 14
740 
741 	{ "a39_mc68705p5s.ic23",	0x0800, 0x14bff574, 4 | BRF_ESS | BRF_PRG }, //  15 MCU Code
742 };
743 
744 STD_ROM_PICK(wyvernf0)
745 STD_ROM_FN(wyvernf0)
746 
747 struct BurnDriver BurnDrvWyvernf0 = {
748 	"wyvernf0", NULL, NULL, NULL, "1985",
749 	"Wyvern F-0 (Rev 1)\0", NULL, "Taito Corporation", "Miscellaneous",
750 	NULL, NULL, NULL, NULL,
751 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2,  HARDWARE_TAITO_MISC, GBF_VERSHOOT, 0,
752 	NULL, wyvernf0RomInfo, wyvernf0RomName, NULL, NULL, NULL, NULL, Wyvernf0InputInfo, Wyvernf0DIPInfo,
753 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
754 	224, 256, 3, 4
755 };
756 
757 
758 // Wyvern F-0
759 /* Possibly the first version or even an earlier development version as A39 06 above isn't labeled as A39 06-1 */
760 
761 static struct BurnRomInfo wyvernf0aRomDesc[] = {
762 	{ "soft1_c2a0.ic37",	0x4000, 0x15f0beb8, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
763 	{ "soft2_7b60.ic36",	0x4000, 0x569a40c4, 1 | BRF_PRG | BRF_ESS }, //  1
764 	{ "ext1.ic35",			0x4000, 0x50314281, 1 | BRF_PRG | BRF_ESS }, //  2
765 	{ "ext2.ic34",			0x4000, 0x7a225bf9, 1 | BRF_PRG | BRF_ESS }, //  3
766 	{ "ext3.ic33",			0x4000, 0x41f21a67, 1 | BRF_PRG | BRF_ESS }, //  4
767 	{ "ext4_8ca8.ic32",		0x4000, 0x793e36de, 1 | BRF_PRG | BRF_ESS }, //  5
768 
769 	{ "sound_4182.ic26",	0x4000, 0x5a681fb4, 2 | BRF_PRG | BRF_ESS }, //  6 Z80 #0 Code
770 
771 	{ "obj4_d779.ic99",		0x4000, 0xaf70e1dc, 3 | BRF_GRA },           //  7 Sprites
772 	{ "obj3_5852.ic78",		0x4000, 0xa84380fb, 3 | BRF_GRA },           //  8
773 	{ "obj2_50fd.ic96",		0x4000, 0xc0cee243, 3 | BRF_GRA },           //  9
774 	{ "obj1_bd50.ic75",		0x4000, 0x0ad69501, 3 | BRF_GRA },           // 10
775 
776 	{ "sch_4.ic99",			0x2000, 0x90a66147, 4 | BRF_GRA },           // 11 Tiles
777 	{ "sch_3.ic73",			0x2000, 0xa31f3507, 4 | BRF_GRA },           // 12
778 	{ "sch_2.ic100",		0x2000, 0xbe708238, 4 | BRF_GRA },           // 13
779 	{ "sch_1.ic74",			0x2000, 0x1cc389de, 4 | BRF_GRA },           // 14
780 
781 	{ "a39_mc68705p5s.ic23",	0x0800, 0x14bff574, 4 | BRF_ESS | BRF_PRG }, //  15 MCU Code
782 };
783 
784 STD_ROM_PICK(wyvernf0a)
785 STD_ROM_FN(wyvernf0a)
786 
787 struct BurnDriver BurnDrvWyvernf0a = {
788 	"wyvernf0a", "wyvernf0", NULL, NULL, "1985",
789 	"Wyvern F-0\0", NULL, "Taito Corporation", "Miscellaneous",
790 	NULL, NULL, NULL, NULL,
791 	BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2,  HARDWARE_TAITO_MISC, GBF_VERSHOOT, 0,
792 	NULL, wyvernf0aRomInfo, wyvernf0aRomName, NULL, NULL, NULL, NULL, Wyvernf0InputInfo, Wyvernf0DIPInfo,
793 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
794 	224, 256, 3, 4
795 };
796