1 // FB Alpha Aztarac driver module
2 // Based on MAME driver by Mathis Rosenhauer
3 
4 #include "burnint.h"
5 #include "m68000_intf.h"
6 #include "z80_intf.h"
7 #include "vector.h"
8 #include "ay8910.h"
9 
10 static UINT8 *AllMem;
11 static UINT8 *MemEnd;
12 static UINT8 *AllRam;
13 static UINT8 *RamEnd;
14 static UINT8 *Drv68KROM;
15 static UINT8 *DrvZ80ROM;
16 static UINT8 *Drv68KRAM;
17 static UINT8 *DrvZ80RAM;
18 static UINT8 *DrvVecRAM;
19 static UINT8 *DrvNVRAM;
20 
21 static UINT32 *DrvPalette;
22 static UINT8 DrvRecalc;
23 
24 static UINT8 *soundlatch;
25 static INT32 sound_irq_timer;
26 static INT32 sound_status;
27 
28 static INT32 sound_initialized = 0;
29 
30 static INT32 xcenter;
31 static INT32 ycenter;
32 
33 static INT32 watchdog;
34 
35 static UINT8 DrvJoy1[8];
36 static UINT8 DrvDips[1];
37 static UINT8 DrvInputs[1];
38 static UINT8 DrvReset;
39 
40 static INT16 DrvAnalogPort0;
41 static INT16 DrvAnalogPort1;
42 
43 static UINT8 xAxis = 0;
44 static UINT8 yAxis = 0;
45 static UINT8 Dial = 0;
46 static UINT8 DialInputs[2];
47 
48 #define A(a, b, c, d) {a, b, (UINT8*)(c), d}
49 
50 static struct BurnInputInfo AztaracInputList[] = {
51 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 4,		"p1 coin"	},
52 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 2,		"p1 start"	},
53 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 1,		"p1 fire 1"	},
54 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy1 + 0,		"p1 fire 2"	},
55 
56 	A("Left/Right",		BIT_ANALOG_REL, &DrvAnalogPort0,	"p1 x-axis"),
57 	A("Up/Down",		BIT_ANALOG_REL, &DrvAnalogPort1,	"p1 y-axis"),
58 
59 	{"Aim Left",		BIT_DIGITAL,	DialInputs + 0,		"p1 fire 3"	},
60 	{"Aim Right",		BIT_DIGITAL,	DialInputs + 1,		"p1 fire 4"	},
61 
62 	{"Reset",			BIT_DIGITAL,	&DrvReset,			"reset"		},
63 	{"Service",			BIT_DIGITAL,	DrvJoy1 + 7,		"service"	},
64 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,		"dip"		},
65 };
66 
67 STDINPUTINFO(Aztarac)
68 
69 #undef A
70 
71 static struct BurnDIPInfo AztaracDIPList[] =
72 {
73 	{0x0a, 0xf0, 0xff, 0xff, NULL},
74 	{0x00, 0xff, 0xff, 0x00, NULL},
75 
76 	{0   , 0xfe, 0   ,    2, "Hires Mode"	},
77 	{0x00, 0x01, 0x01, 0x00, "No"			},
78 	{0x00, 0x01, 0x01, 0x01, "Yes"			},
79 };
80 
STDDIPINFO(Aztarac)81 STDDIPINFO(Aztarac)
82 
83 static inline void read_vectorram (INT32 addr, INT32 *x, INT32 *y, INT32 *c)
84 {
85 	*c = SekReadWord(0xff8000 + addr);
86 	*x = SekReadWord(0xff9000 + addr) & 0x03ff;
87 	*y = SekReadWord(0xffa000 + addr) & 0x03ff;
88 	if (*x & 0x200) *x |= 0xfffffc00; // signed
89 	if (*y & 0x200) *y |= 0xfffffc00; // signed
90 }
91 
aztarac_process_vector_list()92 static void aztarac_process_vector_list()
93 {
94 	INT32 x, y, c, intensity, xoffset, yoffset, color;
95 	INT32 defaddr, objaddr, ndefs;
96 
97 	vector_reset();
98 
99 	for (objaddr = 0; objaddr < 0x800; objaddr++)
100 	{
101 		read_vectorram (objaddr * 2, &xoffset, &yoffset, &c);
102 
103 		if (c & 0x4000)	break;
104 
105 		if ((c & 0x2000) == 0)
106 		{
107 			defaddr = (c >> 1) & 0x7ff;
108 
109 			vector_add_point((xcenter + (xoffset << 16)), (ycenter - (yoffset << 16)), 0, 0);
110 
111 			read_vectorram (defaddr * 2, &x, &ndefs, &c);
112 			ndefs++;
113 
114 			if (c & 0xff00)
115 			{
116 				intensity = (c >> 8);
117 				color = c & 0x3f;
118 
119 				while (ndefs--)
120 				{
121 					defaddr++;
122 					read_vectorram (defaddr * 2, &x, &y, &c);
123 
124 					if ((c & 0xff00) == 0)
125 						vector_add_point((xcenter + ((x + xoffset) << 16)), (ycenter - ((y + yoffset) << 16)), 0, 0);
126 					else
127 						vector_add_point((xcenter + ((x + xoffset) << 16)), (ycenter - ((y + yoffset) << 16)), color, intensity);
128 				}
129 			}
130 			else
131 			{
132 				while (ndefs--)
133 				{
134 					defaddr++;
135 					read_vectorram (defaddr * 2, &x, &y, &c);
136 
137 					color = c & 0x3f;
138 					vector_add_point((xcenter + ((x + xoffset) << 16)), (ycenter - ((y + yoffset) << 16)), color, c >> 8);
139 				}
140 			}
141 		}
142 	}
143 }
144 
sync_cpu()145 static inline void sync_cpu()
146 {
147 	INT32 cycles = (SekTotalCycles() / 4) - ZetTotalCycles();
148 
149 	if (cycles > 0)	ZetRun(cycles);
150 }
151 
aztarac_write_word(UINT32 address,UINT16 data)152 static void __fastcall aztarac_write_word(UINT32 address, UINT16 data)
153 {
154 	if ((address & 0xfffff00) == 0x022000) {
155 		*((UINT16*)(DrvNVRAM + (address & 0xfe))) = BURN_ENDIAN_SWAP_INT16(data | 0xfff0);
156 		return;
157 	}
158 
159 	if (address == 0xffb000) {
160 		if (data) aztarac_process_vector_list(); // used once?
161 		return;
162 	}
163 }
164 
aztarac_write_byte(UINT32 address,UINT8 data)165 static void __fastcall aztarac_write_byte(UINT32 address, UINT8 data)
166 {
167 	if (address == 0x027009) {
168 		sync_cpu();
169 		*soundlatch = data;
170 		sound_status ^= 0x21;
171 
172 		if (sound_status & 0x20) ZetSetIRQLine(0, CPU_IRQSTATUS_AUTO);
173 
174 		return;
175 	}
176 
177 	if (address == 0xffb001) {
178 		if (data) aztarac_process_vector_list();
179 		return;
180 	}
181 }
182 
aztarac_read_word(UINT32 address)183 static UINT16 __fastcall aztarac_read_word(UINT32 address)
184 {
185 	switch (address)
186 	{
187 		case 0x027004:
188 			return 0xff00 | DrvInputs[0];
189 
190 		case 0x02700e:
191 			watchdog = 0;
192 			return 0;
193 	}
194 
195 	return 0;
196 }
197 
aztarac_read_byte(UINT32 address)198 static UINT8 __fastcall aztarac_read_byte(UINT32 address)
199 {
200 	switch (address)
201 	{
202 		case 0x027000:
203 			return xAxis - 0x0f;
204 
205 		case 0x027001:
206 			return yAxis - 0x0f;
207 
208 		case 0x027005:
209 			return DrvInputs[0]; // inputs
210 
211 		case 0x027009:
212 			sync_cpu();
213 			return sound_status & 0x01;
214 
215 		case 0x02700d:
216 			return Dial;
217 	}
218 
219 	return 0;
220 }
221 
aztarac_sound_write(UINT16 address,UINT8 data)222 static void __fastcall aztarac_sound_write(UINT16 address, UINT8 data)
223 {
224 	switch (address)
225 	{
226 		case 0x8c00:
227 		case 0x8c01:
228 		case 0x8c02:
229 		case 0x8c03:
230 		case 0x8c04:
231 		case 0x8c05:
232 		case 0x8c06:
233 		case 0x8c07:
234 			AY8910Write((address & 6) / 2, ~address & 1, data);
235 		return;
236 
237 		case 0x9000:
238 			sound_status &= ~0x10;
239 		return;
240 	}
241 }
242 
aztarac_sound_read(UINT16 address)243 static UINT8 __fastcall aztarac_sound_read(UINT16 address)
244 {
245 	switch (address)
246 	{
247 		case 0x8800:
248 			sound_status = (sound_status | 0x01) & ~0x20;
249 			return *soundlatch;
250 
251 		case 0x8c00:
252 		case 0x8c01:
253 		case 0x8c02:
254 		case 0x8c03:
255 		case 0x8c04:
256 		case 0x8c05:
257 		case 0x8c06:
258 		case 0x8c07:
259 			return AY8910Read((address & 6) / 2);
260 
261 		case 0x9000:
262 			return sound_status & ~0x01;
263 	}
264 
265 	return 0;
266 }
267 
aztarac_irq_callback(INT32)268 static INT32 __fastcall aztarac_irq_callback(INT32)
269 {
270 	return 0x0c;
271 }
272 
res_check()273 static INT32 res_check()
274 {
275 	if (DrvDips[0] & 1) {
276 		INT32 Width, Height;
277 		BurnDrvGetVisibleSize(&Width, &Height);
278 
279 		if (Height != 1080) {
280 			vector_rescale((1080*1024/768), 1080);
281 			return 1;
282 		}
283 	} else {
284 		INT32 Width, Height;
285 		BurnDrvGetVisibleSize(&Width, &Height);
286 
287 		if (Height != 768) {
288 			vector_rescale(1024, 768);
289 			return 1;
290 		}
291 	}
292 	return 0;
293 }
294 
DrvDoReset(INT32 reset_ram)295 static INT32 DrvDoReset(INT32 reset_ram)
296 {
297 	if (reset_ram) {
298 		memset (AllRam, 0, RamEnd - AllRam);
299 	}
300 
301 	SekOpen(0);
302 	SekReset();
303 	SekClose();
304 
305 	ZetOpen(0);
306 	ZetReset();
307 	ZetClose();
308 
309 	AY8910Reset(0);
310 	AY8910Reset(1);
311 	AY8910Reset(2);
312 	AY8910Reset(3);
313 
314 	sound_status = 0;
315 	sound_irq_timer = 0;
316 
317 	watchdog = 0;
318 
319 	vector_reset();
320 
321 	res_check();
322 
323 	return 0;
324 }
325 
MemIndex()326 static INT32 MemIndex()
327 {
328 	UINT8 *Next; Next = AllMem;
329 
330 	Drv68KROM		= Next; Next += 0x010000;
331 	DrvZ80ROM		= Next; Next += 0x002000;
332 
333 	DrvNVRAM		= Next; Next += 0x000400;
334 
335 	AllRam			= Next;
336 
337 	Drv68KRAM		= Next; Next += 0x002000;
338 	DrvZ80RAM		= Next; Next += 0x000800;
339 	DrvVecRAM		= Next; Next += 0x003000;
340 
341 	soundlatch		= Next; Next += 0x000004; // 1
342 
343 	RamEnd			= Next;
344 
345 	DrvPalette		= (UINT32*)Next; Next += 0x0040 * 256 * sizeof(UINT32);
346 
347 	MemEnd			= Next;
348 
349 	return 0;
350 }
351 
DrvPaletteInit()352 static void DrvPaletteInit()
353 {
354 	for (INT32 i = 0; i < 0x40; i++) // color
355 	{
356 		for (INT32 j = 0; j < 256; j++) // intensity
357 		{
358 			INT32 r = (i >> 4) & 3;
359 			r = (r << 6) | (r << 4) | (r << 2) | (r << 0);
360 
361 			INT32 g = (i >> 2) & 3;
362 			g = (g << 6) | (g << 4) | (g << 2) | (g << 0);
363 
364 			INT32 b = (i >> 0) & 3;
365 			b = (b << 6) | (b << 4) | (b << 2) | (b << 0);
366 
367 			r = (r * j) / 255;
368 			g = (g * j) / 255;
369 			b = (b * j) / 255;
370 
371 			DrvPalette[i * 256 + j] = (r << 16) | (g << 8) | b;
372 		}
373 	}
374 }
375 
DrvInit()376 static INT32 DrvInit()
377 {
378 	BurnSetRefreshRate(40.0);
379 
380 	AllMem = NULL;
381 	MemIndex();
382 	INT32 nLen = MemEnd - (UINT8 *)0;
383 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
384 	memset(AllMem, 0, nLen);
385 	MemIndex();
386 
387 	{
388 		if (BurnLoadRom(Drv68KROM + 0x00001,  0, 2)) return 1;
389 		if (BurnLoadRom(Drv68KROM + 0x00000,  1, 2)) return 1;
390 		if (BurnLoadRom(Drv68KROM + 0x02001,  2, 2)) return 1;
391 		if (BurnLoadRom(Drv68KROM + 0x02000,  3, 2)) return 1;
392 		if (BurnLoadRom(Drv68KROM + 0x04001,  4, 2)) return 1;
393 		if (BurnLoadRom(Drv68KROM + 0x04000,  5, 2)) return 1;
394 		if (BurnLoadRom(Drv68KROM + 0x06001,  6, 2)) return 1;
395 		if (BurnLoadRom(Drv68KROM + 0x06000,  7, 2)) return 1;
396 		if (BurnLoadRom(Drv68KROM + 0x08001,  8, 2)) return 1;
397 		if (BurnLoadRom(Drv68KROM + 0x08000,  9, 2)) return 1;
398 		if (BurnLoadRom(Drv68KROM + 0x0a001, 10, 2)) return 1;
399 		if (BurnLoadRom(Drv68KROM + 0x0a000, 11, 2)) return 1;
400 
401 		if (BurnLoadRom(DrvZ80ROM + 0x00000, 12, 1)) return 1;
402 		if (BurnLoadRom(DrvZ80ROM + 0x01000, 13, 1)) return 1;
403 	}
404 
405 	SekInit(0, 0x68000);
406 	SekOpen(0);
407 	SekSetIrqCallback(aztarac_irq_callback);
408 	SekMapMemory(Drv68KROM,		0x000000, 0x00bfff, MAP_ROM);
409 	SekMapMemory(DrvNVRAM,		0x022000, 0x0223ff, MAP_ROM);
410 	SekMapMemory(DrvVecRAM,		0xff8000, 0xffafff, MAP_RAM);
411 	SekMapMemory(Drv68KRAM,		0xffe000, 0xffffff, MAP_RAM);
412 	SekSetWriteWordHandler(0,	aztarac_write_word);
413 	SekSetWriteByteHandler(0,	aztarac_write_byte);
414 	SekSetReadWordHandler(0,	aztarac_read_word);
415 	SekSetReadByteHandler(0,	aztarac_read_byte);
416 	SekClose();
417 
418 	ZetInit(0);
419 	ZetOpen(0);
420 	ZetMapMemory(DrvZ80ROM,		0x0000, 0x1fff, MAP_ROM);
421 	ZetMapMemory(DrvZ80RAM,		0x8000, 0x87ff, MAP_RAM);
422 	ZetSetWriteHandler(aztarac_sound_write);
423 	ZetSetReadHandler(aztarac_sound_read);
424 	ZetClose();
425 
426 	AY8910Init(0, 2000000, 0);
427 	AY8910Init(1, 2000000, 1);
428 	AY8910Init(2, 2000000, 1);
429 	AY8910Init(3, 2000000, 1);
430 	AY8910SetAllRoutes(0, 0.15, BURN_SND_ROUTE_BOTH);
431 	AY8910SetAllRoutes(1, 0.15, BURN_SND_ROUTE_BOTH);
432 	AY8910SetAllRoutes(2, 0.15, BURN_SND_ROUTE_BOTH);
433 	AY8910SetAllRoutes(3, 0.15, BURN_SND_ROUTE_BOTH);
434 
435 	DrvPaletteInit();
436 
437 	vector_init();
438 	vector_set_scale(1024, 768);
439 
440 	xcenter = (1024 / 2) << 16;
441 	ycenter = ( 768 / 2) << 16;
442 
443 	memset (DrvNVRAM, 0xff, 0x100);
444 
445 	DrvDoReset(1);
446 
447 	return 0;
448 }
449 
DrvExit()450 static INT32 DrvExit()
451 {
452 	vector_exit();
453 
454 	SekExit();
455 	ZetExit();
456 
457 	AY8910Exit(0);
458 	AY8910Exit(1);
459 	AY8910Exit(2);
460 	AY8910Exit(3);
461 
462 	BurnFree (AllMem);
463 
464 	sound_initialized = 0;
465 
466 	return 0;
467 }
468 
DrvDraw()469 static INT32 DrvDraw()
470 {
471 	if (DrvRecalc) {
472 		DrvPaletteInit();
473 		DrvRecalc = 0;
474 	}
475 
476 	if (res_check()) return 0; // resolution was changed
477 
478 	draw_vector(DrvPalette);
479 
480 	return 0;
481 }
482 
DrvFrame()483 static INT32 DrvFrame()
484 {
485 	if (DrvReset) {
486 		DrvDoReset(1);
487 	}
488 
489 	watchdog++;
490 	if (watchdog == 180) { // 3 seconds?
491 		DrvDoReset(0);
492 	}
493 
494 	SekNewFrame();
495 	ZetNewFrame();
496 
497 	{
498 		DrvInputs[0] = 0xff;
499 		for (INT32 i = 0; i < 8; i++) {
500 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
501 		}
502 
503 		xAxis = (DrvAnalogPort0 >> 7) + 0x0f;
504 		if (xAxis > 0x80) xAxis = 0;
505 
506 		yAxis = (~DrvAnalogPort1 >> 7) + 0x10;
507 		if (yAxis > 0x1d) yAxis = 0x1d;
508 
509 		if (DialInputs[0]) {
510 			Dial += 0x04;
511 		} else {
512 			if (DialInputs[1]) {
513 				Dial -= 0x04;
514 			}
515 		}
516 	}
517 
518 	INT32 nInterleave = 100;
519 	INT32 nCyclesTotal[2] = { 8000000 / 40, 2000000 / 40 };
520 	INT32 nCyclesDone[2]  = { 0, 0 };
521 
522 	SekOpen(0);
523 	ZetOpen(0);
524 
525 	for (INT32 i = 0; i < nInterleave; i++, sound_irq_timer++)
526 	{
527 		nCyclesDone[0] += SekRun(nCyclesTotal[0] / nInterleave);
528 		if (i == (nInterleave - 1)) SekSetIRQLine(4, CPU_IRQSTATUS_AUTO);
529 
530 		//nCyclesDone[1] += ZetRun((SekTotalCycles() / 4) - ZetTotalCycles());
531 		sync_cpu();
532 
533 		if ((sound_irq_timer % 40) == 39) {	// every 20000 cycles, 50000 / frame
534 			sound_status ^= 0x10;
535 			if (sound_status & 0x10) ZetSetIRQLine(0, CPU_IRQSTATUS_AUTO);
536 		}
537 	}
538 
539 	SekClose();
540 	ZetClose();
541 
542 	if (pBurnSoundOut) {
543 		AY8910Render(pBurnSoundOut, nBurnSoundLen);
544 	}
545 
546 	if (pBurnDraw) {
547 		DrvDraw();
548 	}
549 
550 	return 0;
551 }
552 
DrvScan(INT32 nAction,INT32 * pnMin)553 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
554 {
555 	struct BurnArea ba;
556 
557 	if (pnMin != NULL) {
558 		*pnMin = 0x029698;
559 	}
560 
561 	if (nAction & ACB_MEMORY_ROM) {
562 		ba.Data		= Drv68KROM;
563 		ba.nLen		= 0x000c000;
564 		ba.nAddress	= 0x0000000;
565 		ba.szName	= "68K ROM";
566 		BurnAcb(&ba);
567 
568 		ba.Data		= DrvZ80ROM;
569 		ba.nLen		= 0x0002000;
570 		ba.nAddress	= 0x0000000;
571 		ba.szName	= "Z80 ROM";
572 		BurnAcb(&ba);
573 	}
574 
575 	if (nAction & ACB_MEMORY_RAM) {
576 		ba.Data		= Drv68KRAM;
577 		ba.nLen		= 0x0002000;
578 		ba.nAddress	= 0x0ffe000;
579 		ba.szName	= "68K RAM";
580 		BurnAcb(&ba);
581 
582 		ba.Data		= DrvVecRAM;
583 		ba.nLen		= 0x0003000;
584 		ba.nAddress	= 0x0ff8000;
585 		ba.szName	= "Vector RAM";
586 		BurnAcb(&ba);
587 
588  		ba.Data		= DrvZ80RAM;
589 		ba.nLen		= 0x0000800;
590 		ba.nAddress	= 0x0000000;
591 		ba.szName	= "Z80 RAM";
592 		BurnAcb(&ba);
593 	}
594 
595 	if (nAction & ACB_NVRAM) {
596 		ba.Data		= DrvNVRAM;
597 		ba.nLen		= 0x000100;
598 		ba.nAddress	= 0x022000;
599 		ba.szName	= "NV RAM";
600 		BurnAcb(&ba);
601 	}
602 
603 	if (nAction & ACB_DRIVER_DATA) {
604 		SekScan(nAction);
605 		ZetScan(nAction);
606 
607 		AY8910Scan(nAction, pnMin);
608 
609 		SCAN_VAR(*soundlatch);
610 		SCAN_VAR(sound_irq_timer);
611 		SCAN_VAR(sound_status);
612 	}
613 
614 	vector_scan(nAction);
615 
616 	return 0;
617 }
618 
619 
620 // Aztarac
621 
622 static struct BurnRomInfo aztaracRomDesc[] = {
623 	{ "6.l8",	0x1000, 0x25f8da18, 1 | BRF_PRG | BRF_ESS }, //  0 68K Code
624 	{ "0.n8",	0x1000, 0x04e20626, 1 | BRF_PRG | BRF_ESS }, //  1
625 	{ "7.l7",	0x1000, 0x230e244c, 1 | BRF_PRG | BRF_ESS }, //  2
626 	{ "1.n7",	0x1000, 0x37b12697, 1 | BRF_PRG | BRF_ESS }, //  3
627 	{ "8.l6",	0x1000, 0x1293fb9d, 1 | BRF_PRG | BRF_ESS }, //  4
628 	{ "2.n6",	0x1000, 0x712c206a, 1 | BRF_PRG | BRF_ESS }, //  5
629 	{ "9.l5",	0x1000, 0x743a6501, 1 | BRF_PRG | BRF_ESS }, //  6
630 	{ "3.n5",	0x1000, 0xa65cbf99, 1 | BRF_PRG | BRF_ESS }, //  7
631 	{ "a.l4",	0x1000, 0x9cf1b0a1, 1 | BRF_PRG | BRF_ESS }, //  8
632 	{ "4.n4",	0x1000, 0x5f0080d5, 1 | BRF_PRG | BRF_ESS }, //  9
633 	{ "b.l3",	0x1000, 0x8cc7f7fa, 1 | BRF_PRG | BRF_ESS }, // 10
634 	{ "5.n3",	0x1000, 0x40452376, 1 | BRF_PRG | BRF_ESS }, // 11
635 
636 	{ "c.j4",	0x1000, 0xe897dfcd, 2 | BRF_PRG | BRF_ESS }, // 12 Z80 Code
637 	{ "d.j3",	0x1000, 0x4016de77, 2 | BRF_PRG | BRF_ESS }, // 13
638 
639 	/* not hooked up */
640 	{ "l5.l5",	0x00020, 0x317fb438, 0 | BRF_OPT },			 // 14 Proms
641 	{ "k8.k8",	0x01000, 0x596ad8d9, 0 | BRF_OPT },			 // 15
642 	{ "k9.k9",	0x01000, 0xb8544823, 0 | BRF_OPT },			 // 16
643 };
644 
645 STD_ROM_PICK(aztarac)
646 STD_ROM_FN(aztarac)
647 
648 struct BurnDriver BurnDrvAztarac = {
649 	"aztarac", NULL, NULL, NULL, "1983",
650 	"Aztarac\0", "Vector graphics", "Centuri", "Miscellaneous",
651 	NULL, NULL, NULL, NULL,
652 	BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_SHOOT, 0,
653 	NULL, aztaracRomInfo, aztaracRomName, NULL, NULL, NULL, NULL, AztaracInputInfo, AztaracDIPInfo,
654 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x40 * 256,
655 	1024, 768, 4, 3
656 };
657