1 // FB Alpha Omega Race driver moulde
2 // Based on MAME driver by Bernd Wiebelt
3 
4 #include "tiles_generic.h"
5 #include "z80_intf.h"
6 #include "ay8910.h"
7 #include "watchdog.h"
8 #include "burn_gun.h"
9 #include "avgdvg.h"
10 #include "vector.h"
11 #include "bitswap.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 *DrvVidPROM;
20 static UINT8 *DrvNVRAM;
21 static UINT8 *DrvZ80RAM0;
22 static UINT8 *DrvZ80RAM1;
23 static UINT8 *DrvVectorRAM;
24 static UINT8 *DrvVectorROM;
25 
26 static UINT32 *DrvPalette;
27 static UINT8 DrvRecalc;
28 
29 static UINT8 avgletsgo;
30 static UINT8 soundlatch;
31 
32 static UINT8 DrvJoy1[8];
33 static UINT8 DrvJoy2[8];
34 static UINT8 DrvJoy3[8];
35 static UINT8 DrvDips[4];
36 static UINT8 DrvInputs[2];
37 static UINT8 DrvReset;
38 
39 static INT16 DrvAnalogPort0 = 0;
40 static INT16 DrvAnalogPort1 = 0;
41 
42 #define A(a, b, c, d) {a, b, (UINT8*)(c), d}
43 static struct BurnInputInfo OmegraceInputList[] = {
44 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 0,	"p1 coin"	},
45 	{"P1 Start",		BIT_DIGITAL,	DrvJoy2 + 6,	"p1 start"	},
46 	{"P1 Left",		    BIT_DIGITAL,	DrvJoy3 + 0,	"p1 left"	},
47 	{"P1 Right",		BIT_DIGITAL,	DrvJoy3 + 1,	"p1 right"	},
48 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 6,	"p1 fire 1"	},
49 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 fire 2"	},
50 	A("P1 Spinner",     BIT_ANALOG_REL, &DrvAnalogPort0,"p1 x-axis"),
51 
52 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy1 + 1,	"p2 coin"	},
53 	{"P2 Start",		BIT_DIGITAL,	DrvJoy2 + 2,	"p2 start"	},
54 	{"P2 Left",		    BIT_DIGITAL,	DrvJoy3 + 2,	"p2 left"	},
55 	{"P2 Right",		BIT_DIGITAL,	DrvJoy3 + 3,	"p2 right"	},
56 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy2 + 1,	"p2 fire 1"	},
57 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy2 + 0,	"p2 fire 2"	},
58 	A("P2 Spinner",     BIT_ANALOG_REL, &DrvAnalogPort1,"p2 x-axis"),
59 
60 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
61 	{"Service",			BIT_DIGITAL,	DrvJoy1 + 7,	"service"	},
62 	{"Tilt",			BIT_DIGITAL,	DrvJoy1 + 4,	"tilt"		},
63 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
64 	{"Dip B",			BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
65 	{"Dip C",			BIT_DIPSWITCH,	DrvDips + 2,	"dip"		},
66 	{"Dip D",			BIT_DIPSWITCH,	DrvDips + 3,	"dip"		},
67 };
68 #undef A
69 STDINPUTINFO(Omegrace)
70 
71 static struct BurnDIPInfo OmegraceDIPList[]=
72 {
73 	DIP_OFFSET(0x11)
74 	{0x00, 0xff, 0xff, 0xff, NULL						},
75 	{0x01, 0xff, 0xff, 0xbf, NULL						},
76 	{0x02, 0xff, 0xff, 0x80, NULL						},
77 	{0x03, 0xff, 0xff, 0x00, NULL						},
78 
79 	{0   , 0xfe, 0   ,    4, "1st Bonus Life"			},
80 	{0x00, 0x01, 0x03, 0x00, "40k"						},
81 	{0x00, 0x01, 0x03, 0x01, "50k"						},
82 	{0x00, 0x01, 0x03, 0x02, "70k"						},
83 	{0x00, 0x01, 0x03, 0x03, "100k"						},
84 
85 	{0   , 0xfe, 0   ,    4, "2nd & 3rd Bonus Life"		},
86 	{0x00, 0x01, 0x0c, 0x00, "150k 250k"				},
87 	{0x00, 0x01, 0x0c, 0x04, "250k 500k"				},
88 	{0x00, 0x01, 0x0c, 0x08, "500k 750k"				},
89 	{0x00, 0x01, 0x0c, 0x0c, "750k 1500k"				},
90 
91 	{0   , 0xfe, 0   ,    4, "Credit(s)/Ships"			},
92 	{0x00, 0x01, 0x30, 0x00, "1C/2S 2C/4S"				},
93 	{0x00, 0x01, 0x30, 0x10, "1C/2S 2C/5S"				},
94 	{0x00, 0x01, 0x30, 0x20, "1C/3S 2C/6S"				},
95 	{0x00, 0x01, 0x30, 0x30, "1C/3S 2C/7S"				},
96 
97 	{0   , 0xfe, 0   ,    8, "Coin A"					},
98 	{0x01, 0x01, 0x07, 0x06, "2 Coins 1 Credits"		},
99 	{0x01, 0x01, 0x07, 0x07, "1 Coin  1 Credits"		},
100 	{0x01, 0x01, 0x07, 0x03, "4 Coins 5 Credits"		},
101 	{0x01, 0x01, 0x07, 0x04, "3 Coins 4 Credits"		},
102 	{0x01, 0x01, 0x07, 0x05, "2 Coins 3 Credits"		},
103 	{0x01, 0x01, 0x07, 0x00, "1 Coin  2 Credits"		},
104 	{0x01, 0x01, 0x07, 0x01, "1 Coin  3 Credits"		},
105 	{0x01, 0x01, 0x07, 0x02, "1 Coin  5 Credits"		},
106 
107 	{0   , 0xfe, 0   ,    8, "Coin B"					},
108 	{0x01, 0x01, 0x38, 0x30, "2 Coins 1 Credits"		},
109 	{0x01, 0x01, 0x38, 0x38, "1 Coin  1 Credits"		},
110 	{0x01, 0x01, 0x38, 0x18, "4 Coins 5 Credits"		},
111 	{0x01, 0x01, 0x38, 0x20, "3 Coins 4 Credits"		},
112 	{0x01, 0x01, 0x38, 0x28, "2 Coins 3 Credits"		},
113 	{0x01, 0x01, 0x38, 0x00, "1 Coin  2 Credits"		},
114 	{0x01, 0x01, 0x38, 0x08, "1 Coin  3 Credits"		},
115 	{0x01, 0x01, 0x38, 0x10, "1 Coin  5 Credits"		},
116 
117 	{0   , 0xfe, 0   ,    2, "Free Play"				},
118 	{0x01, 0x01, 0x40, 0x00, "Off"						},
119 	{0x01, 0x01, 0x40, 0x40, "On"						},
120 
121 	{0   , 0xfe, 0   ,    2, "Cabinet"					},
122 	{0x01, 0x01, 0x80, 0x00, "Upright"					},
123 	{0x01, 0x01, 0x80, 0x80, "Cocktail"					},
124 
125 	{0   , 0xfe, 0   ,    2, "Service Mode"				},
126 	{0x02, 0x01, 0x80, 0x80, "Off"						},
127 	{0x02, 0x01, 0x80, 0x00, "On"						},
128 
129 	{0   , 0xfe, 0   ,    2, "Hires Mode"				},
130 	{0x03, 0x01, 0x01, 0x00, "No"						},
131 	{0x03, 0x01, 0x01, 0x01, "Yes"						},
132 };
133 
STDDIPINFO(Omegrace)134 STDDIPINFO(Omegrace)
135 
136 static void __fastcall omegrace_main_write_port(UINT16 port, UINT8 data)
137 {
138 	switch (port & 0xff)
139 	{
140 		case 0x0a:
141 			avgdvg_reset();
142 		return;
143 
144 		case 0x13:
145 			// omegrace_leds_w (don't bother)
146 		return;
147 
148 		case 0x14:
149 			soundlatch = data;
150 			ZetSetIRQLine(1, 0, CPU_IRQSTATUS_HOLD);
151 		return;
152 	}
153 }
154 
spinner_read(INT32 player)155 static inline UINT8 spinner_read(INT32 player)
156 {
157 	const UINT8 spinnerTable[2][0x40] = { {
158 		0x00, 0x04, 0x14, 0x10, 0x18, 0x1c, 0x5c, 0x58,
159 		0x50, 0x54, 0x44, 0x40, 0x48, 0x4c, 0x6c, 0x68,
160 		0x60, 0x64, 0x74, 0x70, 0x78, 0x7c, 0xfc, 0xf8,
161 		0xf0, 0xf4, 0xe4, 0xe0, 0xe8, 0xec, 0xcc, 0xc8,
162 		0xc0, 0xc4, 0xd4, 0xd0, 0xd8, 0xdc, 0x9c, 0x98,
163 		0x90, 0x94, 0x84, 0x80, 0x88, 0x8c, 0xac, 0xa8,
164 		0xa0, 0xa4, 0xb4, 0xb0, 0xb8, 0xbc, 0x3c, 0x38,
165 		0x30, 0x34, 0x24, 0x20, 0x28, 0x2c, 0x0c, 0x08
166 	}, {
167 		0x00, 0x01, 0x05, 0x04, 0x06, 0x07, 0x17, 0x16,
168 		0x14, 0x15, 0x11, 0x10, 0x12, 0x13, 0x1b, 0x1a,
169 		0x18, 0x19, 0x1d, 0x1c, 0x1e, 0x1f, 0x3f, 0x3e,
170 		0x3c, 0x3d, 0x39, 0x38, 0x3a, 0x3b, 0x33, 0x32,
171 		0x30, 0x31, 0x35, 0x34, 0x36, 0x37, 0x27, 0x26,
172 		0x24, 0x25, 0x21, 0x20, 0x22, 0x23, 0x2b, 0x2a,
173 		0x28, 0x29, 0x2d, 0x2c, 0x2e, 0x2f, 0x0f, 0x0e,
174 		0x0c, 0x0d, 0x09, 0x08, 0x0a, 0x0b, 0x03, 0x02   // p2 table decoded by dink aug.2020
175 	} };
176 
177 	return spinnerTable[player][BurnTrackballRead(0, player) & 0x3f];
178 }
179 
omegrace_main_read_port(UINT16 port)180 static UINT8 __fastcall omegrace_main_read_port(UINT16 port)
181 {
182 	switch (port & 0xff)
183 	{
184 		case 0x08:
185 			avgdvg_go();
186 			avgletsgo = 1;
187 			return 0;
188 
189 		case 0x09:
190 			return BurnWatchdogRead();
191 
192 		case 0x0b:
193 			return (avgdvg_done() ? 0 : 0x80);
194 
195 		case 0x10:
196 			return DrvDips[0];
197 
198 		case 0x17:
199 			return DrvDips[1];
200 
201 		case 0x11:
202 			return (DrvInputs[0] & ~0x80) | (DrvDips[2] & 0x80);
203 
204 		case 0x12:
205 			return DrvInputs[1] ^ 0xcc;
206 
207 		case 0x15:
208 			return spinner_read(0);
209 
210 		case 0x16:
211 			return spinner_read(1);
212 	}
213 
214 	return 0;
215 }
216 
omegrace_sound_write_port(UINT16 port,UINT8 data)217 static void __fastcall omegrace_sound_write_port(UINT16 port, UINT8 data)
218 {
219 	switch (port & 0xff)
220 	{
221 		case 0x00:
222 		case 0x01:
223 		case 0x02:
224 		case 0x03:
225 			AY8910Write((port/2)&1, port & 1, data);
226 		return;
227 	}
228 }
229 
omegrace_sound_read_port(UINT16 port)230 static UINT8 __fastcall omegrace_sound_read_port(UINT16 port)
231 {
232 	switch (port & 0xff)
233 	{
234 		case 0x00:
235 			return soundlatch;
236 	}
237 
238 	return 0;
239 }
240 
res_check()241 static INT32 res_check()
242 {
243 	if (DrvDips[3] & 1) {
244 		INT32 Width, Height;
245 		BurnDrvGetVisibleSize(&Width, &Height);
246 
247 		if (Height != 1080) {
248 			vector_rescale((1080*800/600), 1080);
249 			return 1;
250 		}
251 	} else {
252 		INT32 Width, Height;
253 		BurnDrvGetVisibleSize(&Width, &Height);
254 
255 		if (Height != 600) {
256 			vector_rescale(800, 600);
257 			return 1;
258 		}
259 	}
260 	return 0;
261 }
262 
DrvDoReset(INT32 clear_mem)263 static INT32 DrvDoReset(INT32 clear_mem)
264 {
265 	if (clear_mem) {
266 		memset (AllRam, 0, RamEnd - AllRam);
267 	}
268 
269 	ZetOpen(0);
270 	ZetReset();
271 	ZetClose();
272 
273 	ZetOpen(1);
274 	ZetReset();
275 	ZetClose();
276 
277 	avgdvg_reset();
278 
279 	BurnWatchdogReset();
280 
281 	AY8910Reset(0);
282 	AY8910Reset(1);
283 
284 	soundlatch = 0;
285 	avgletsgo = 0;
286 
287 	res_check();
288 
289 	return 0;
290 }
291 
MemIndex()292 static INT32 MemIndex()
293 {
294 	UINT8 *Next; Next = AllMem;
295 
296 	DrvZ80ROM0		= Next; Next += 0x004000;
297 	DrvZ80ROM1		= Next; Next += 0x000800;
298 
299 	DrvVidPROM		= Next; Next += 0x000100;
300 
301 	DrvPalette		= (UINT32*)Next; Next += 0x8000 * sizeof(UINT32);
302 
303 	DrvNVRAM		= Next; Next += 0x000100;
304 
305 	AllRam			= Next;
306 
307 	DrvZ80RAM0		= Next; Next += 0x000c00;
308 	DrvZ80RAM1		= Next; Next += 0x000400;
309 
310 	// these need to overlap for the avgdvg device! leave them alone!
311 	DrvVectorRAM	= Next; Next += 0x001000;
312 	RamEnd			= Next;
313 	DrvVectorROM	= Next; Next += 0x001000;
314 
315 	MemEnd			= Next;
316 
317 	return 0;
318 }
319 
DrvPROMDescramble()320 static void DrvPROMDescramble()
321 {
322 	for (INT32 i = 0; i < 0x100; i++)
323 	{
324 		DrvVidPROM[i] = (DrvVidPROM[i] & 0xf0) | ((DrvVidPROM[i] & 3) << 2) | ((DrvVidPROM[i] >> 2) & 3);
325 	}
326 }
327 
DrvInit()328 static INT32 DrvInit()
329 {
330 	BurnSetRefreshRate(42.00);
331 
332 	AllMem = NULL;
333 	MemIndex();
334 	INT32 nLen = MemEnd - (UINT8 *)0;
335 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
336 	memset(AllMem, 0, nLen);
337 	MemIndex();
338 
339 	{
340 		if (BurnLoadRom(DrvZ80ROM0   + 0x0000,  0, 1)) return 1;
341 		if (BurnLoadRom(DrvZ80ROM0   + 0x1000,  1, 1)) return 1;
342 		if (BurnLoadRom(DrvZ80ROM0   + 0x2000,  2, 1)) return 1;
343 		if (BurnLoadRom(DrvZ80ROM0   + 0x3000,  3, 1)) return 1;
344 
345 		if (BurnLoadRom(DrvVectorROM + 0x0000,  4, 1)) return 1;
346 		if (BurnLoadRom(DrvVectorROM + 0x0800,  5, 1)) return 1;
347 
348 		if (BurnLoadRom(DrvZ80ROM1   + 0x0000,  6, 1)) return 1;
349 
350 		if (BurnLoadRom(DrvVidPROM   + 0x0000,  7, 1)) return 1;
351 
352 		DrvPROMDescramble();
353 	}
354 
355 	ZetInit(0);
356 	ZetOpen(0);
357 	ZetMapMemory(DrvZ80ROM0,		0x0000, 0x3fff, MAP_ROM);
358 	ZetMapMemory(DrvZ80RAM0,		0x4000, 0x4bff, MAP_RAM);
359 	ZetMapMemory(DrvNVRAM,			0x5c00, 0x5cff, MAP_RAM);
360 	ZetMapMemory(DrvVectorRAM,		0x8000, 0x8fff, MAP_RAM);
361 	ZetMapMemory(DrvVectorROM,		0x9000, 0x9fff, MAP_ROM);
362 	ZetSetOutHandler(omegrace_main_write_port);
363 	ZetSetInHandler(omegrace_main_read_port);
364 	ZetClose();
365 
366 	ZetInit(1);
367 	ZetOpen(1);
368 	ZetMapMemory(DrvZ80ROM1,		0x0000, 0x07ff, MAP_ROM);
369 	ZetMapMemory(DrvZ80ROM1,		0x0800, 0x0fff, MAP_ROM);
370 	ZetMapMemory(DrvZ80RAM1,		0x1000, 0x13ff, MAP_RAM);
371 	ZetSetOutHandler(omegrace_sound_write_port);
372 	ZetSetInHandler(omegrace_sound_read_port);
373 	ZetClose();
374 
375 	BurnWatchdogInit(DrvDoReset, 120);
376 
377 	AY8910Init(0, 1000000, 0);
378 	AY8910Init(1, 1000000, 1);
379 	AY8910SetAllRoutes(0, 0.25, BURN_SND_ROUTE_BOTH);
380 	AY8910SetAllRoutes(1, 0.25, BURN_SND_ROUTE_BOTH);
381 
382 	avgdvg_init(USE_DVG, DrvVectorRAM, 0x2000, ZetTotalCycles, 1044, 1044);
383 	vector_set_offsets(11, 0);
384 
385 	BurnTrackballInit(2);
386 
387 	DrvDoReset(1);
388 
389 	return 0;
390 }
391 
DrvExit()392 static INT32 DrvExit()
393 {
394 	ZetExit();
395 	AY8910Exit(0);
396 	AY8910Exit(1);
397 	avgdvg_exit();
398 
399 	BurnTrackballExit();
400 
401 	BurnFree(AllMem);
402 
403 	return 0;
404 }
405 
DrvPaletteInit()406 static void DrvPaletteInit()
407 {
408 	UINT32 colors[2] = { 0x000000, 0xffffff };
409 
410     for (INT32 i = 0; i < 0x2; i++) // color
411 	{
412 		for (INT32 j = 0; j < 256; j++) // intensity
413 		{
414 			int r = (colors[i] >> 16) & 0xff;
415 			int g = (colors[i] >> 8) & 0xff;
416 			int b = (colors[i] >> 0) & 0xff;
417 
418 			r = (r * j) / 255;
419 			g = (g * j) / 255;
420 			b = (b * j) / 255;
421 
422 			DrvPalette[i * 256 + j] = (r << 16) | (g << 8) | b; // must be 32bit palette! -dink (see vector.cpp)
423 		}
424 	}
425 }
426 
DrvDraw()427 static INT32 DrvDraw()
428 {
429 	if (DrvRecalc) {
430 		DrvPaletteInit();
431 		DrvRecalc = 0;
432 	}
433 
434 	if (res_check()) return 0; // resolution was changed
435 
436 	draw_vector(DrvPalette);
437 
438 	return 0;
439 }
440 
DrvFrame()441 static INT32 DrvFrame()
442 {
443 	BurnWatchdogUpdate();
444 
445 	if (DrvReset) {
446 		DrvDoReset(1);
447 	}
448 
449 	{
450 		DrvInputs[0] = 0xff;
451 		DrvInputs[1] = 0xff;
452 		for (INT32 i = 0; i < 8; i++) {
453 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
454 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
455 		}
456 
457 		BurnTrackballConfig(0, AXIS_NORMAL, AXIS_NORMAL);
458 		BurnTrackballFrame(0, DrvAnalogPort0, DrvAnalogPort1, 0x01, 0x07);
459 		BurnTrackballUDLR(0, DrvJoy3[2], DrvJoy3[3], DrvJoy3[0], DrvJoy3[1]);
460 		BurnTrackballUpdate(0);
461 	}
462 
463 	INT32 nInterleave = 60;
464 	INT32 nCyclesTotal[2] = { 3000000 / 40, 1500000 / 40 };
465 	INT32 nCyclesDone[2] = { 0, 0 };
466 
467 	for (INT32 i = 0; i < nInterleave; i++)
468 	{
469 		ZetOpen(0);
470 		CPU_RUN(0, Zet);
471 		if ((i % 10) == 9) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD); // 6x (really 6.25 per frame
472 		ZetClose();
473 
474 		ZetOpen(1);
475 		CPU_RUN(1, Zet);
476 		if ((i % 10) == 9) ZetNmi(); // 6x (really 6.25 per frame
477 		ZetClose();
478 	}
479 
480 	if (pBurnSoundOut) {
481 		AY8910Render(pBurnSoundOut, nBurnSoundLen);
482 	}
483 
484 	if (pBurnDraw) {
485 		DrvDraw();
486 	}
487 
488 	return 0;
489 }
490 
DrvScan(INT32 nAction,INT32 * pnMin)491 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
492 {
493 	struct BurnArea ba;
494 
495 	if (pnMin) {
496 		*pnMin = 0x029702;
497 	}
498 
499 	if (nAction & ACB_VOLATILE) {
500 		memset(&ba, 0, sizeof(ba));
501 
502 		ba.Data	  = AllRam;
503 		ba.nLen	  = RamEnd - AllRam;
504 		ba.szName = "All Ram";
505 		BurnAcb(&ba);
506 
507 		ZetScan(nAction);
508 
509 		avgdvg_scan(nAction, pnMin);
510 		AY8910Scan(nAction, pnMin);
511 		BurnWatchdogScan(nAction);
512 		BurnTrackballScan();
513 
514 		SCAN_VAR(soundlatch);
515 		SCAN_VAR(avgletsgo);
516 	}
517 
518 	if (nAction & ACB_NVRAM) {
519 		ba.Data		= DrvNVRAM;
520 		ba.nLen		= 0x00100;
521 		ba.nAddress	= 0;
522 		ba.szName	= "NV RAM";
523 		BurnAcb(&ba);
524 	}
525 
526 	return 0;
527 }
528 
529 
530 // Omega Race (set 1)
531 
532 static struct BurnRomInfo omegraceRomDesc[] = {
533 	{ "omega.m7",					0x1000, 0x0424d46e, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
534 	{ "omega.l7",					0x1000, 0xedcd7a7d, 1 | BRF_PRG | BRF_ESS }, //  1
535 	{ "omega.k7",					0x1000, 0x6d10f197, 1 | BRF_PRG | BRF_ESS }, //  2
536 	{ "omega.j7",					0x1000, 0x8e8d4b54, 1 | BRF_PRG | BRF_ESS }, //  3
537 	{ "omega.e1",					0x0800, 0x1d0fdf3a, 1 | BRF_PRG | BRF_ESS }, //  4
538 	{ "omega.f1",					0x0800, 0xd44c0814, 1 | BRF_PRG | BRF_ESS }, //  5
539 
540 	{ "sound.k5",					0x0800, 0x7d426017, 2 | BRF_PRG | BRF_ESS }, //  6 Z80 #1 Code
541 
542 	{ "dvgprom.bin",				0x0100, 0xd481e958, 3 | BRF_GRA },           //  7 Video PROM
543 };
544 
545 STD_ROM_PICK(omegrace)
546 STD_ROM_FN(omegrace)
547 
548 struct BurnDriver BurnDrvOmegrace = {
549 	"omegrace", NULL, NULL, NULL, "1981",
550 	"Omega Race (set 1)\0", NULL, "Midway", "Miscellaneous",
551 	NULL, NULL, NULL, NULL,
552 	BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_SHOOT, 0,
553 	NULL, omegraceRomInfo, omegraceRomName, NULL, NULL, NULL, NULL, OmegraceInputInfo, OmegraceDIPInfo,
554 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x8000,
555 	800, 600, 4, 3
556 };
557 
558 
559 // Omega Race (set 2)
560 
561 static struct BurnRomInfo omegrace2RomDesc[] = {
562 	{ "o.r._1a.m7",					0x1000, 0xf8539d46, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
563 	{ "o.r._2a.l7",					0x1000, 0x0ff70783, 1 | BRF_PRG | BRF_ESS }, //  1
564 	{ "o.r._3a.k7",					0x1000, 0x6349130d, 1 | BRF_PRG | BRF_ESS }, //  2
565 	{ "o.r._4a.j7",					0x1000, 0x0a5ef64a, 1 | BRF_PRG | BRF_ESS }, //  3
566 	{ "o.r._vector_i_6-1-81.e1",	0x0800, 0x1d0fdf3a, 1 | BRF_PRG | BRF_ESS }, //  4
567 	{ "o.r._vector_ii_6-1-81.f1",	0x0800, 0xd44c0814, 1 | BRF_PRG | BRF_ESS }, //  5
568 
569 	{ "o.r.r._audio_6-1-81.k5",		0x0800, 0x7d426017, 2 | BRF_PRG | BRF_ESS }, //  6 Z80 #1 Code
570 
571 	{ "dvgprom.bin",				0x0100, 0xd481e958, 3 | BRF_GRA },           //  7 Video PROM
572 };
573 
574 STD_ROM_PICK(omegrace2)
575 STD_ROM_FN(omegrace2)
576 
577 struct BurnDriver BurnDrvOmegrace2 = {
578 	"omegrace2", "omegrace", NULL, NULL, "1981",
579 	"Omega Race (set 2)\0", NULL, "Midway", "Miscellaneous",
580 	NULL, NULL, NULL, NULL,
581 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, GBF_SHOOT, 0,
582 	NULL, omegrace2RomInfo, omegrace2RomName, NULL, NULL, NULL, NULL, OmegraceInputInfo, OmegraceDIPInfo,
583 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x8000,
584 	800, 600, 4, 3
585 };
586 
587 
588 // Delta Race
589 
590 static struct BurnRomInfo deltraceRomDesc[] = {
591 	{ "omega.m7",					0x1000, 0x0424d46e, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
592 	{ "omega.l7",					0x1000, 0xedcd7a7d, 1 | BRF_PRG | BRF_ESS }, //  1
593 	{ "omega.k7",					0x1000, 0x6d10f197, 1 | BRF_PRG | BRF_ESS }, //  2
594 	{ "delta.j7",					0x1000, 0x8ef9541e, 1 | BRF_PRG | BRF_ESS }, //  3
595 	{ "omega.e1",					0x0800, 0x1d0fdf3a, 1 | BRF_PRG | BRF_ESS }, //  4
596 	{ "omega.f1",					0x0800, 0xd44c0814, 1 | BRF_PRG | BRF_ESS }, //  5
597 
598 	{ "sound.k5",					0x0800, 0x7d426017, 2 | BRF_PRG | BRF_ESS }, //  6 Z80 #1 Code
599 
600 	{ "dvgprom.bin",				0x0100, 0xd481e958, 3 | BRF_GRA },           //  7 Video PROM
601 };
602 
603 STD_ROM_PICK(deltrace)
604 STD_ROM_FN(deltrace)
605 
606 struct BurnDriver BurnDrvDeltrace = {
607 	"deltrace", "omegrace", NULL, NULL, "1981",
608 	"Delta Race\0", NULL, "bootleg (Allied Leisure)", "Miscellaneous",
609 	NULL, NULL, NULL, NULL,
610 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, GBF_SHOOT, 0,
611 	NULL, deltraceRomInfo, deltraceRomName, NULL, NULL, NULL, NULL, OmegraceInputInfo, OmegraceDIPInfo,
612 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x8000,
613 	800, 600, 4, 3
614 };
615