1 // FB Alpha Quantum driver module
2 // Based on MAME driver by Hedley Rainnie, Aaron Giles, Couriersud, and Paul Forgey
3 
4 #include "tiles_generic.h"
5 #include "m68000_intf.h"
6 #include "watchdog.h"
7 #include "avgdvg.h"
8 #include "vector.h"
9 #include "pokey.h"
10 #include "burn_gun.h"
11 
12 static UINT8 *AllMem;
13 static UINT8 *AllRam;
14 static UINT8 *RamEnd;
15 static UINT8 *MemEnd;
16 static UINT8 *Drv68KROM;
17 static UINT8 *DrvNVRAM;
18 static UINT8 *Drv68KRAM;
19 static UINT8 *DrvVectorRAM;
20 static UINT8 *DrvColRAM;
21 
22 static UINT32 *DrvPalette;
23 static UINT8 DrvRecalc;
24 
25 static UINT8 DrvJoy1[8];
26 static UINT8 DrvJoy2[8];
27 static UINT8 DrvDips[3];
28 static UINT16 DrvInputs[2];
29 static UINT8 DrvReset;
30 
31 static INT16 DrvAnalogPort0 = 0;
32 static INT16 DrvAnalogPort1 = 0;
33 
34 static INT32 avgOK = 0;
35 
36 #define A(a, b, c, d) {a, b, (UINT8*)(c), d}
37 static struct BurnInputInfo QuantumInputList[] = {
38 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 5,	"p1 coin"	},
39 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 2,	"p1 start"	},
40 	{"P1 Up",		    BIT_DIGITAL,	DrvJoy2 + 0,	"p1 up"	    },
41 	{"P1 Down",		    BIT_DIGITAL,	DrvJoy2 + 1,	"p1 down"	},
42 	{"P1 Left",		    BIT_DIGITAL,	DrvJoy2 + 2,	"p1 left"	},
43 	{"P1 Right",		BIT_DIGITAL,	DrvJoy2 + 3,	"p1 right"	},
44 	A("P1 Trackball X", BIT_ANALOG_REL, &DrvAnalogPort0,"p1 x-axis"),
45 	A("P1 Trackball Y", BIT_ANALOG_REL, &DrvAnalogPort1,"p1 y-axis"),
46 
47 	{"P2 Start",		BIT_DIGITAL,	DrvJoy1 + 3,	"p2 start"	},
48 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy1 + 4,	"p2 coin"	},
49 	{"P3 Coin",			BIT_DIGITAL,	DrvJoy1 + 1,	"p3 coin"	},
50 
51 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
52 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
53 	{"Dip B",			BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
54 	{"Dip C",			BIT_DIPSWITCH,	DrvDips + 2,	"dip"		},
55 };
56 #undef A
57 
58 STDINPUTINFO(Quantum)
59 
60 #define DO 0xc
61 static struct BurnDIPInfo QuantumDIPList[]=
62 {
63 	{DO+0, 0xff, 0xff, 0x00, NULL				},
64 	{DO+1, 0xff, 0xff, 0x80, NULL				},
65 
66 	{0   , 0xfe, 0   ,    4, "Coinage"			},
67 	{DO+0, 0x01, 0xc0, 0x80, "2 Coins 1 Credits"},
68 	{DO+0, 0x01, 0xc0, 0x00, "1 Coin  1 Credits"},
69 	{DO+0, 0x01, 0xc0, 0xc0, "1 Coin  2 Credits"},
70 	{DO+0, 0x01, 0xc0, 0x40, "Free Play"		},
71 
72 	{0   , 0xfe, 0   ,    4, "Right Coin"		},
73 	{DO+0, 0x01, 0x30, 0x00, "*1"				},
74 	{DO+0, 0x01, 0x30, 0x20, "*4"				},
75 	{DO+0, 0x01, 0x30, 0x10, "*5"				},
76 	{DO+0, 0x01, 0x30, 0x30, "*6"				},
77 
78 	{0   , 0xfe, 0   ,    2, "Left Coin"		},
79 	{DO+0, 0x01, 0x08, 0x00, "*1"				},
80 	{DO+0, 0x01, 0x08, 0x08, "*2"				},
81 
82 	{0   , 0xfe, 0   ,    5, "Bonus Coins"		},
83 	{DO+0, 0x01, 0x07, 0x00, "None"				},
84 	{DO+0, 0x01, 0x07, 0x01, "1 each 5"			},
85 	{DO+0, 0x01, 0x07, 0x02, "1 each 4"			},
86 	{DO+0, 0x01, 0x07, 0x05, "1 each 3"			},
87 	{DO+0, 0x01, 0x07, 0x06, "2 each 4"			},
88 
89 	{0   , 0xfe, 0   ,    2, "Service Mode"			},
90 	{DO+1, 0x01, 0x80, 0x80, "Off"					},
91 	{DO+1, 0x01, 0x80, 0x00, "On"					},
92 
93 	{0   , 0xfe, 0   ,    2, "Hires Mode"			},
94 	{DO+2, 0x01, 0x01, 0x00, "No"					},
95 	{DO+2, 0x01, 0x01, 0x01, "Yes"					},
96 };
97 #undef DO
98 
STDDIPINFO(Quantum)99 STDDIPINFO(Quantum)
100 
101 static void DrvPaletteWrite(INT32 i, UINT8 data)
102 {
103 	DrvColRAM[i] = data;
104 	UINT32 *dst = DrvPalette + i * 256;
105 
106 	for (INT32 j = 0; j < 256; j++) // intensity
107 	{
108 		int bit3 = (~data >> 3) & 1;
109 		int bit2 = (~data >> 2) & 1;
110 		int bit1 = (~data >> 1) & 1;
111 		int bit0 = (~data >> 0) & 1;
112 		int r = bit3 * 0xee;
113 		int g = bit1 * 0xee + bit0 * 0x11;
114 		int b = bit2 * 0xee;
115 
116 		r = (r * j) / 255;
117 		g = (g * j) / 255;
118 		b = (b * j) / 255;
119 
120 		dst[j] = (r << 16) | (g << 8) | b; // must be 32bit palette! -dink (see vector.cpp)
121 	}
122 }
123 
quantum_write_word(UINT32 address,UINT16 data)124 static void __fastcall quantum_write_word(UINT32 address, UINT16 data)
125 {
126 	if ((address & 0xffffc0) == 0x840000) {
127 		pokey_write((address / 0x20) & 1, address / 2, data);
128 		return;
129 	}
130 
131 	if ((address & 0xffffe0) == 0x950000) {
132 		address = (address / 2) & 0xf;
133 		UINT8 p = DrvColRAM[address];
134 		if (p != (data & 0xff)) {
135 			DrvPaletteWrite(address,data);
136 		}
137 		return;
138 	}
139 
140 	switch (address)
141 	{
142 		case 0x958000:
143 		case 0x958001:
144 			// coin counter 0 = data & 2, 1 = data & 1
145 			// NVRAM Store = data & 0x04
146 			// led outputs = data & 0x30
147 			avg_set_flip_x(data & 0x40);
148 			avg_set_flip_y(data & 0x80);
149 		return;
150 
151 		case 0x960000:
152 		case 0x960001:
153 			// NVRAM Recall
154 		return;
155 
156 		case 0x968000:
157 		case 0x968001:
158 			avgdvg_reset();
159 		return;
160 
161 		case 0x970000:
162 		case 0x970001:
163 			avgdvg_go();
164 			avgOK = 1;
165 		return;
166 
167 		case 0x978000:
168 		case 0x978001:
169 			BurnWatchdogWrite();
170 		return;
171 	}
172 }
173 
quantum_write_byte(UINT32 address,UINT8 data)174 static void __fastcall quantum_write_byte(UINT32 address, UINT8 data)
175 {
176 	if ((address & 0xffffc0) == 0x840000) {
177 		pokey_write((address / 0x20) & 1, address / 2, data);
178 		return;
179 	}
180 
181 	if ((address & 0xffffe0) == 0x950000) {
182 		address = (address / 2) & 0xf;
183 		UINT8 p = DrvColRAM[address];
184 		if (p != data) {
185 			DrvPaletteWrite(address,data);
186 		}
187 		return;
188 	}
189 
190 	switch (address)
191 	{
192 		case 0x958000:
193 		case 0x958001:
194 			// coin counter 0 = data & 2, 1 = data & 1
195 			// NVRAM Store = data & 0x04
196 			// led outputs = data & 0x30
197 			avg_set_flip_x(data & 0x40);
198 			avg_set_flip_y(data & 0x80);
199 		return;
200 
201 		case 0x960000:
202 		case 0x960001:
203 			// NVRAM Recall
204 		return;
205 
206 		case 0x968000:
207 		case 0x968001:
208 			avgdvg_reset();
209 		return;
210 
211 		case 0x970000:
212 		case 0x970001:
213 			avgdvg_go();
214 			avgOK = 1;
215 		return;
216 
217 		case 0x978000:
218 		case 0x978001:
219 			BurnWatchdogWrite();
220 		return;
221 	}
222 }
223 
quantum_read_word(UINT32 address)224 static UINT16 __fastcall quantum_read_word(UINT32 address)
225 {
226 	if ((address & 0xffffc0) == 0x840000) {
227 		return pokey_read((address / 0x20) & 1, address / 2);
228 	}
229 
230 	switch (address)
231 	{
232 		case 0x940000:
233 		case 0x940001:
234 			return (BurnTrackballRead(0, 1)&0xf) | ((BurnTrackballRead(0, 0)&0xf) << 4);
235 
236 		case 0x948000:
237 		case 0x948001:
238 			return (DrvInputs[0] & ~0x81) | (DrvDips[1] & 0x80) | (avgdvg_done() ? 1 : 0);
239 
240 		case 0x978000:
241 		case 0x978001:
242 			return 0; // nop
243 	}
244 
245 	return 0;
246 }
247 
quantum_read_byte(UINT32 address)248 static UINT8 __fastcall quantum_read_byte(UINT32 address)
249 {
250 	if ((address & 0xffffc0) == 0x840000) {
251 		return pokey_read((address / 0x20) & 1, address / 2);
252 	}
253 
254 	switch (address)
255 	{
256 		case 0x940000:
257 		case 0x940001:
258 			return (BurnTrackballRead(0, 1)&0xf) | ((BurnTrackballRead(0, 0)&0xf) << 4);
259 
260 		case 0x948000:
261 			return 0xff;
262 
263 		case 0x948001:
264 			return (DrvInputs[0] & 0x7e) | (DrvDips[1] & 0x80) | (avgdvg_done() ? 1 : 0);
265 
266 		case 0x978000:
267 		case 0x978001:
268 			return 0; // nop
269 	}
270 
271 	return 0;
272 }
273 
dip0_read(INT32 offset)274 static INT32 dip0_read(INT32 offset)
275 {
276 	return (DrvDips[0] << (7 - (offset))) & 0x80;
277 }
278 
dip1_read(INT32 offset)279 static INT32 dip1_read(INT32 offset)
280 {
281 	return (0 << (7 - (offset))) & 0x80;
282 }
283 
res_check()284 static INT32 res_check()
285 {
286 	if (DrvDips[2] & 1) {
287 		INT32 Width, Height;
288 		BurnDrvGetVisibleSize(&Width, &Height);
289 
290 		if (Height != 1080) {
291 			vector_rescale((1080*480/640), 1080);
292 			return 1;
293 		}
294 	} else {
295 		INT32 Width, Height;
296 		BurnDrvGetVisibleSize(&Width, &Height);
297 
298 		if (Height != 640) {
299 			vector_rescale(480, 640);
300 			return 1;
301 		}
302 	}
303 	return 0;
304 }
305 
DrvDoReset(INT32 clear_mem)306 static INT32 DrvDoReset(INT32 clear_mem)
307 {
308 	if (clear_mem) {
309 		memset (AllRam, 0, RamEnd - AllRam);
310 	}
311 
312 	SekOpen(0);
313 	SekReset();
314 	SekClose();
315 
316 	BurnWatchdogReset();
317 	avgdvg_reset();
318 
319 	avgOK = 0;
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 += 0x014000;
331 
332 	DrvPalette		= (UINT32*)Next; Next += 0x1000 * sizeof(UINT32);
333 
334 	DrvNVRAM		= Next; Next += 0x000400; // really 200
335 
336 	AllRam			= Next;
337 
338 	DrvVectorRAM	= Next; Next += 0x004000; // 2x size
339 	Drv68KRAM		= Next; Next += 0x005000;
340 	DrvColRAM		= Next; Next += 0x000010;
341 
342 	RamEnd			= Next;
343 
344 	MemEnd			= Next;
345 
346 	return 0;
347 }
348 
DrvInit()349 static INT32 DrvInit()
350 {
351 	BurnAllocMemIndex();
352 
353 	memset (DrvNVRAM, 0xff, 0x200);
354 
355 	{
356 		if (BurnLoadRom(Drv68KROM + 0x000001,  0, 2)) return 1;
357 		if (BurnLoadRom(Drv68KROM + 0x000000,  1, 2)) return 1;
358 		if (BurnLoadRom(Drv68KROM + 0x004001,  2, 2)) return 1;
359 		if (BurnLoadRom(Drv68KROM + 0x004000,  3, 2)) return 1;
360 		if (BurnLoadRom(Drv68KROM + 0x008001,  4, 2)) return 1;
361 		if (BurnLoadRom(Drv68KROM + 0x008000,  5, 2)) return 1;
362 		if (BurnLoadRom(Drv68KROM + 0x00c001,  6, 2)) return 1;
363 		if (BurnLoadRom(Drv68KROM + 0x00c000,  7, 2)) return 1;
364 		if (BurnLoadRom(Drv68KROM + 0x010001,  8, 2)) return 1;
365 		if (BurnLoadRom(Drv68KROM + 0x010000,  9, 2)) return 1;
366 	}
367 
368 	SekInit(0, 0x68000);
369 	SekOpen(0);
370 	SekMapMemory(Drv68KROM,			0x000000, 0x013fff, MAP_ROM);
371 	SekMapMemory(Drv68KRAM,			0x018000, 0x01cfff, MAP_RAM);
372 	SekMapMemory(DrvVectorRAM,		0x800000, 0x801fff, MAP_RAM);
373 	SekMapMemory(DrvNVRAM,			0x900000, 0x9003ff, MAP_RAM); // 0-1ff
374 //	SekMapMemory(DrvColRAM,			0x950000, 0x95001f, MAP_WRITE);
375 	SekSetWriteWordHandler(0,		quantum_write_word);
376 	SekSetWriteByteHandler(0,		quantum_write_byte);
377 	SekSetReadWordHandler(0,		quantum_read_word);
378 	SekSetReadByteHandler(0,		quantum_read_byte);
379 	SekClose();
380 
381 	avgdvg_init(USE_AVG_QUANTUM, DrvVectorRAM, 0x2000, SekTotalCycles, 900, 600);
382 	avgdvg_set_cycles(6048000);
383 
384 	PokeyInit(600000, 2, 0.50, 0);
385 	PokeySetTotalCyclesCB(SekTotalCycles);
386 	PokeyPotCallback(0, 0, dip0_read);
387 	PokeyPotCallback(0, 1, dip0_read);
388 	PokeyPotCallback(0, 2, dip0_read);
389 	PokeyPotCallback(0, 3, dip0_read);
390 	PokeyPotCallback(0, 4, dip0_read);
391 	PokeyPotCallback(0, 5, dip0_read);
392 	PokeyPotCallback(0, 6, dip0_read);
393 	PokeyPotCallback(0, 7, dip0_read);
394 	PokeyPotCallback(1, 0, dip1_read);
395 	PokeyPotCallback(1, 1, dip1_read);
396 	PokeyPotCallback(1, 2, dip1_read);
397 	PokeyPotCallback(1, 3, dip1_read);
398 	PokeyPotCallback(1, 4, dip1_read);
399 	PokeyPotCallback(1, 5, dip1_read);
400 	PokeyPotCallback(1, 6, dip1_read);
401 	PokeyPotCallback(1, 7, dip1_read);
402 
403 	BurnTrackballInit(2);
404 
405 	DrvDoReset(1);
406 
407 	return 0;
408 }
409 
DrvExit()410 static INT32 DrvExit()
411 {
412 	SekExit();
413 	PokeyExit();
414 	avgdvg_exit();
415 
416 	BurnTrackballExit();
417 
418 	BurnFreeMemIndex();
419 
420 	return 0;
421 }
422 
DrvPaletteUpdate()423 static void DrvPaletteUpdate()
424 {
425     for (INT32 i = 0; i < 0x10; i++) // color
426 	{
427 		UINT8 data = DrvColRAM[i];
428 		for (INT32 j = 0; j < 256; j++) // intensity
429 		{
430 			int bit3 = (~data >> 3) & 1;
431 			int bit2 = (~data >> 2) & 1;
432 			int bit1 = (~data >> 1) & 1;
433 			int bit0 = (~data >> 0) & 1;
434 			int r = bit3 * 0xee;
435 			int g = bit1 * 0xee + bit0 * 0x11;
436 			int b = bit2 * 0xee;
437 
438 			r = (r * j) / 255;
439 			g = (g * j) / 255;
440 			b = (b * j) / 255;
441 
442 			DrvPalette[i * 256 + j] = (r << 16) | (g << 8) | b; // must be 32bit palette! -dink (see vector.cpp)
443 		}
444 	}
445 }
446 
DrvDraw()447 static INT32 DrvDraw()
448 {
449 	if (DrvRecalc) {
450 		DrvPaletteUpdate();
451 		DrvRecalc = 1;
452 	}
453 
454 	if ((~DrvDips[1] & 0x80) && avgOK) avgdvg_go(); // service mode doesn't run avgdvg_go(), so we do it manually.
455 
456 	if (res_check()) return 0; // resolution was changed
457 
458 	draw_vector(DrvPalette);
459 
460 	return 0;
461 }
462 
DrvFrame()463 static INT32 DrvFrame()
464 {
465 	BurnWatchdogUpdate();
466 
467 	if (DrvReset) {
468 		DrvDoReset(1);
469 	}
470 
471 	{
472 		DrvInputs[0] = 0xfffe;
473 		DrvInputs[1] = 0; // for quick udlr check.
474 
475 		for (INT32 i = 0; i < 8; i++) {
476 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
477 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i; // udlr (digital)
478 		}
479 
480 		BurnTrackballConfig(0, AXIS_NORMAL, AXIS_REVERSED);
481 		BurnTrackballFrame(0, DrvAnalogPort0, DrvAnalogPort1, (DrvInputs[1]) ? 4 : 1, 7); // Velocity: 4 digital, 1 analog
482 		BurnTrackballUDLR(0, DrvJoy2[0], DrvJoy2[1], DrvJoy2[2], DrvJoy2[3]);
483 		BurnTrackballUpdate(0);
484 	}
485 
486 	INT32 nInterleave = 20; // irq is 4.10 / frame
487 	INT32 nCyclesTotal[1] = { 6048000 / 60 };
488 	INT32 nCyclesDone[1] = { 0 };
489 	INT32 nSoundBufferPos = 0;
490 
491 	SekOpen(0);
492 
493 	for (INT32 i = 0; i < nInterleave; i++)
494 	{
495 		CPU_RUN(0, Sek);
496 		if ((i % 5) == 4) SekSetIRQLine(1, CPU_IRQSTATUS_AUTO);
497 
498 		// Render Sound Segment
499 		if (pBurnSoundOut) {
500 			INT32 nSegmentLength = nBurnSoundLen / nInterleave;
501 			INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
502 			pokey_update(pSoundBuf, nSegmentLength);
503 			nSoundBufferPos += nSegmentLength;
504 		}
505 	}
506 
507 	// Make sure the buffer is entirely filled.
508 	if (pBurnSoundOut) {
509 		INT32 nSegmentLength = nBurnSoundLen - nSoundBufferPos;
510 		INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
511 		if (nSegmentLength) {
512 			pokey_update(pSoundBuf, nSegmentLength);
513 		}
514 	}
515 
516 	if (pBurnDraw) {
517 		BurnDrvRedraw();
518 	}
519 
520 	SekClose();
521 
522 	return 0;
523 }
524 
DrvScan(INT32 nAction,INT32 * pnMin)525 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
526 {
527 	struct BurnArea ba;
528 
529 	if (pnMin) {
530 		*pnMin = 0x029722;
531 	}
532 
533 	if (nAction & ACB_NVRAM) {
534 		memset(&ba, 0, sizeof(ba));
535 		ba.Data	  = DrvNVRAM;
536 		ba.nLen	  = 0x200;
537 		ba.szName = "NV Ram";
538 		ba.nAddress	= 0x900000;
539 		BurnAcb(&ba);
540 	}
541 
542 	if (nAction & ACB_VOLATILE) {
543 		memset(&ba, 0, sizeof(ba));
544 		ba.Data	  = AllRam;
545 		ba.nLen	  = RamEnd - AllRam;
546 		ba.szName = "All Ram";
547 		BurnAcb(&ba);
548 
549 		SekScan(nAction);
550 
551 		avgdvg_scan(nAction, pnMin);
552 		BurnWatchdogScan(nAction);
553 
554 		BurnTrackballScan();
555 
556 		SCAN_VAR(avgOK);
557 
558 		pokey_scan(nAction, pnMin);
559 	}
560 
561 	return 0;
562 }
563 
564 
565 // Quantum (rev 2)
566 
567 static struct BurnRomInfo quantumRomDesc[] = {
568 	{ "136016.201",		0x2000, 0x7e7be63a, 1 | BRF_PRG | BRF_ESS }, //  0 68k Code
569 	{ "136016.206",		0x2000, 0x2d8f5759, 1 | BRF_PRG | BRF_ESS }, //  1
570 	{ "136016.102",		0x2000, 0x408d34f4, 1 | BRF_PRG | BRF_ESS }, //  2
571 	{ "136016.107",		0x2000, 0x63154484, 1 | BRF_PRG | BRF_ESS }, //  3
572 	{ "136016.203",		0x2000, 0xbdc52fad, 1 | BRF_PRG | BRF_ESS }, //  4
573 	{ "136016.208",		0x2000, 0xdab4066b, 1 | BRF_PRG | BRF_ESS }, //  5
574 	{ "136016.104",		0x2000, 0xbf271e5c, 1 | BRF_PRG | BRF_ESS }, //  6
575 	{ "136016.109",		0x2000, 0xd2894424, 1 | BRF_PRG | BRF_ESS }, //  7
576 	{ "136016.105",		0x2000, 0x13ec512c, 1 | BRF_PRG | BRF_ESS }, //  8
577 	{ "136016.110",		0x2000, 0xacb50363, 1 | BRF_PRG | BRF_ESS }, //  9
578 
579 	{ "136002-125.6h",	0x0100, 0x5903af03, 2 | BRF_GRA },           // 10 AVG PROM
580 
581 	{ "cf2038n.1b",		0x00eb, 0xb372fa4f, 3 | BRF_OPT },           // 11 PLDs
582 };
583 
584 STD_ROM_PICK(quantum)
585 STD_ROM_FN(quantum)
586 
587 struct BurnDriver BurnDrvQuantum = {
588 	"quantum", NULL, NULL, NULL, "1982",
589 	"Quantum (rev 2)\0", NULL, "General Computer Corporation (Atari license)", "Miscellaneous",
590 	NULL, NULL, NULL, NULL,
591 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, GBF_ACTION, 0,
592 	NULL, quantumRomInfo, quantumRomName, NULL, NULL, NULL, NULL, QuantumInputInfo, QuantumDIPInfo,
593 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
594 	480, 640, 3, 4
595 };
596 
597 
598 // Quantum (rev 1)
599 
600 static struct BurnRomInfo quantum1RomDesc[] = {
601 	{ "136016.101",		0x2000, 0x5af0bd5b, 1 | BRF_PRG | BRF_ESS }, //  0 68k Code
602 	{ "136016.106",		0x2000, 0xf9724666, 1 | BRF_PRG | BRF_ESS }, //  1
603 	{ "136016.102",		0x2000, 0x408d34f4, 1 | BRF_PRG | BRF_ESS }, //  2
604 	{ "136016.107",		0x2000, 0x63154484, 1 | BRF_PRG | BRF_ESS }, //  3
605 	{ "136016.103",		0x2000, 0x948f228b, 1 | BRF_PRG | BRF_ESS }, //  4
606 	{ "136016.108",		0x2000, 0xe4c48e4e, 1 | BRF_PRG | BRF_ESS }, //  5
607 	{ "136016.104",		0x2000, 0xbf271e5c, 1 | BRF_PRG | BRF_ESS }, //  6
608 	{ "136016.109",		0x2000, 0xd2894424, 1 | BRF_PRG | BRF_ESS }, //  7
609 	{ "136016.105",		0x2000, 0x13ec512c, 1 | BRF_PRG | BRF_ESS }, //  8
610 	{ "136016.110",		0x2000, 0xacb50363, 1 | BRF_PRG | BRF_ESS }, //  9
611 
612 	{ "136002-125.6h",	0x0100, 0x5903af03, 2 | BRF_GRA },           // 10 AVG PROM
613 
614 	{ "cf2038n.1b",		0x00eb, 0xb372fa4f, 3 | BRF_OPT },           // 11 PLDs
615 };
616 
617 STD_ROM_PICK(quantum1)
618 STD_ROM_FN(quantum1)
619 
620 struct BurnDriver BurnDrvQuantum1 = {
621 	"quantum1", "quantum", NULL, NULL, "1982",
622 	"Quantum (rev 1)\0", NULL, "General Computer Corporation (Atari license)", "Miscellaneous",
623 	NULL, NULL, NULL, NULL,
624 	BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, GBF_ACTION, 0,
625 	NULL, quantum1RomInfo, quantum1RomName, NULL, NULL, NULL, NULL, QuantumInputInfo, QuantumDIPInfo,
626 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
627 	480, 640, 3, 4
628 };
629 
630 
631 // Quantum (prototype)
632 
633 static struct BurnRomInfo quantumpRomDesc[] = {
634 	{ "quantump.2e",	0x2000, 0x176d73d3, 1 | BRF_PRG | BRF_ESS }, //  0 68k Code
635 	{ "quantump.3e",	0x2000, 0x12fc631f, 1 | BRF_PRG | BRF_ESS }, //  1
636 	{ "quantump.2f",	0x2000, 0xb64fab48, 1 | BRF_PRG | BRF_ESS }, //  2
637 	{ "quantump.3f",	0x2000, 0xa52a9433, 1 | BRF_PRG | BRF_ESS }, //  3
638 	{ "quantump.2h",	0x2000, 0x5b29cba3, 1 | BRF_PRG | BRF_ESS }, //  4
639 	{ "quantump.3h",	0x2000, 0xc64fc03a, 1 | BRF_PRG | BRF_ESS }, //  5
640 	{ "quantump.2k",	0x2000, 0x854f9c09, 1 | BRF_PRG | BRF_ESS }, //  6
641 	{ "quantump.3k",	0x2000, 0x1aac576c, 1 | BRF_PRG | BRF_ESS }, //  7
642 	{ "quantump.2l",	0x2000, 0x1285b5e7, 1 | BRF_PRG | BRF_ESS }, //  8
643 	{ "quantump.3l",	0x2000, 0xe19de844, 1 | BRF_PRG | BRF_ESS }, //  9
644 
645 	{ "136002-125.6h",	0x0100, 0x5903af03, 2 | BRF_GRA },           // 10 AVG PROM
646 
647 	{ "cf2038n.1b",		0x00eb, 0xb372fa4f, 3 | BRF_OPT },           // 11 PLDs
648 };
649 
650 STD_ROM_PICK(quantump)
651 STD_ROM_FN(quantump)
652 
653 struct BurnDriver BurnDrvQuantump = {
654 	"quantump", "quantum", NULL, NULL, "1982",
655 	"Quantum (prototype)\0", NULL, "General Computer Corporation (Atari license)", "Miscellaneous",
656 	NULL, NULL, NULL, NULL,
657 	BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, GBF_ACTION, 0,
658 	NULL, quantumpRomInfo, quantumpRomName, NULL, NULL, NULL, NULL, QuantumInputInfo, QuantumDIPInfo,
659 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x1000,
660 	480, 640, 3, 4
661 };
662