1 // FB Alpha Tutankham driver module
2 // Based on MAME driver by Mirko Buffoni & Rob Jarrett
3 
4 #include "tiles_generic.h"
5 #include "m6809_intf.h"
6 #include "z80_intf.h"
7 #include "timeplt_snd.h"
8 
9 static UINT8 *AllMem;
10 static UINT8 *MemEnd;
11 static UINT8 *AllRam;
12 static UINT8 *RamEnd;
13 static UINT8 *DrvM6809ROM;
14 static UINT8 *DrvZ80ROM;
15 static UINT8 *DrvVidRAM;
16 static UINT8 *DrvM6809RAM;
17 static UINT8 *DrvZ80RAM;
18 static UINT8 *DrvPalRAM;
19 
20 static UINT32 *DrvPalette;
21 static UINT8  DrvRecalc;
22 
23 static UINT8 scrolldata;
24 static UINT8 sound_mute;
25 static UINT8 irq_enable;
26 static UINT8 flipscreenx;
27 static UINT8 flipscreeny;
28 static UINT8 nRomBank;
29 
30 static UINT8 DrvJoy1[8];
31 static UINT8 DrvJoy2[8];
32 static UINT8 DrvJoy3[8];
33 static UINT8 DrvDips[2];
34 static UINT8 DrvInputs[3];
35 static UINT8 DrvReset;
36 
37 static INT32 watchdog;
38 
39 static INT32 StarsEnabled;
40 static INT32 StarScrollX, StarScrollY;
41 
42 static struct BurnInputInfo TutankhmInputList[] = {
43 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 0,	"p1 coin"	},
44 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 start"	},
45 	{"P1 Left Stick Up",	BIT_DIGITAL,	DrvJoy2 + 2,	"p1 up"		},
46 	{"P1 Left Stick Down",	BIT_DIGITAL,	DrvJoy2 + 3,	"p1 down"	},
47 	{"P1 Left Stick Left",	BIT_DIGITAL,	DrvJoy2 + 0,	"p1 left"	},
48 	{"P1 Left Stick Right",	BIT_DIGITAL,	DrvJoy2 + 1,	"p1 right"	},
49 	{"P1 Right Stick Left",	BIT_DIGITAL,	DrvJoy2 + 4,	"p3 left"	},
50 	{"P1 Right Stick Right",BIT_DIGITAL,	DrvJoy2 + 5,	"p3 right"	},
51 	{"P1 Flash Bomb",	BIT_DIGITAL,	DrvJoy2 + 6,	"p1 fire 1"	},
52 
53 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy1 + 1,	"p2 coin"	},
54 	{"P2 Start",		BIT_DIGITAL,	DrvJoy1 + 4,	"p2 start"	},
55 	{"P2 Left Stick Up",	BIT_DIGITAL,	DrvJoy3 + 2,	"p2 up"		},
56 	{"P2 Left Stick Down",	BIT_DIGITAL,	DrvJoy3 + 3,	"p2 down"	},
57 	{"P2 Left Stick Left",	BIT_DIGITAL,	DrvJoy3 + 0,	"p2 left"	},
58 	{"P2 Left Stick Right",	BIT_DIGITAL,	DrvJoy3 + 1,	"p2 right"	},
59 	{"P2 Right Stick Left",	BIT_DIGITAL,	DrvJoy3 + 4,	"p4 left"	},
60 	{"P2 Right Stick Right",BIT_DIGITAL,	DrvJoy3 + 5,	"p4 right"	},
61 	{"P2 Flash Bomb",	BIT_DIGITAL,	DrvJoy3 + 6,	"p2 fire 1"	},
62 
63 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
64 	{"Service",			BIT_DIGITAL,	DrvJoy1 + 2,	"service"	},
65 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
66 	{"Dip B",			BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
67 };
68 
69 STDINPUTINFO(Tutankhm)
70 
71 static struct BurnDIPInfo TutankhmDIPList[]=
72 {
73 	{0x14, 0xff, 0xff, 0x6b, NULL			},
74 	{0x15, 0xff, 0xff, 0xff, NULL			},
75 
76 	{0   , 0xfe, 0   ,    4, "Lives"		},
77 	{0x14, 0x01, 0x03, 0x03, "3"			},
78 	{0x14, 0x01, 0x03, 0x01, "4"			},
79 	{0x14, 0x01, 0x03, 0x02, "5"			},
80 	{0x14, 0x01, 0x03, 0x00, "255 (Cheat)"		},
81 
82 	{0   , 0xfe, 0   ,    2, "Cabinet"		},
83 	{0x14, 0x01, 0x04, 0x00, "Upright"		},
84 	{0x14, 0x01, 0x04, 0x04, "Cocktail"		},
85 
86 	{0   , 0xfe, 0   ,    2, "Bonus Life"		},
87 	{0x14, 0x01, 0x08, 0x08, "30000"		},
88 	{0x14, 0x01, 0x08, 0x00, "40000"		},
89 
90 	{0   , 0xfe, 0   ,    4, "Difficulty"		},
91 	{0x14, 0x01, 0x30, 0x30, "Easy"			},
92 	{0x14, 0x01, 0x30, 0x20, "Normal"		},
93 	{0x14, 0x01, 0x30, 0x10, "Hard"			},
94 	{0x14, 0x01, 0x30, 0x00, "Hardest"		},
95 
96 	{0   , 0xfe, 0   ,    2, "Flash Bomb"		},
97 	{0x14, 0x01, 0x40, 0x40, "1 per Life"		},
98 	{0x14, 0x01, 0x40, 0x00, "1 per Game"		},
99 
100 	{0   , 0xfe, 0   ,    2, "Demo Sounds"		},
101 	{0x14, 0x01, 0x80, 0x80, "Off"			},
102 	{0x14, 0x01, 0x80, 0x00, "On"			},
103 
104 	{0   , 0xfe, 0   ,   16, "Coin A"		},
105 	{0x15, 0x01, 0x0f, 0x02, "4 Coins 1 Credits"	},
106 	{0x15, 0x01, 0x0f, 0x05, "3 Coins 1 Credits"	},
107 	{0x15, 0x01, 0x0f, 0x08, "2 Coins 1 Credits"	},
108 	{0x15, 0x01, 0x0f, 0x04, "3 Coins 2 Credits"	},
109 	{0x15, 0x01, 0x0f, 0x01, "4 Coins 3 Credits"	},
110 	{0x15, 0x01, 0x0f, 0x0f, "1 Coin  1 Credits"	},
111 	{0x15, 0x01, 0x0f, 0x03, "3 Coins 4 Credits"	},
112 	{0x15, 0x01, 0x0f, 0x07, "2 Coins 3 Credits"	},
113 	{0x15, 0x01, 0x0f, 0x0e, "1 Coin  2 Credits"	},
114 	{0x15, 0x01, 0x0f, 0x06, "2 Coins 5 Credits"	},
115 	{0x15, 0x01, 0x0f, 0x0d, "1 Coin  3 Credits"	},
116 	{0x15, 0x01, 0x0f, 0x0c, "1 Coin  4 Credits"	},
117 	{0x15, 0x01, 0x0f, 0x0b, "1 Coin  5 Credits"	},
118 	{0x15, 0x01, 0x0f, 0x0a, "1 Coin  6 Credits"	},
119 	{0x15, 0x01, 0x0f, 0x09, "1 Coin  7 Credits"	},
120 	{0x15, 0x01, 0x0f, 0x00, "Free Play"		},
121 
122 	{0   , 0xfe, 0   ,   16, "Coin B"		},
123 	{0x15, 0x01, 0xf0, 0x20, "4 Coins 1 Credits"	},
124 	{0x15, 0x01, 0xf0, 0x50, "3 Coins 1 Credits"	},
125 	{0x15, 0x01, 0xf0, 0x80, "2 Coins 1 Credits"	},
126 	{0x15, 0x01, 0xf0, 0x40, "3 Coins 2 Credits"	},
127 	{0x15, 0x01, 0xf0, 0x10, "4 Coins 3 Credits"	},
128 	{0x15, 0x01, 0xf0, 0xf0, "1 Coin  1 Credits"	},
129 	{0x15, 0x01, 0xf0, 0x30, "3 Coins 4 Credits"	},
130 	{0x15, 0x01, 0xf0, 0x70, "2 Coins 3 Credits"	},
131 	{0x15, 0x01, 0xf0, 0xe0, "1 Coin  2 Credits"	},
132 	{0x15, 0x01, 0xf0, 0x60, "2 Coins 5 Credits"	},
133 	{0x15, 0x01, 0xf0, 0xd0, "1 Coin  3 Credits"	},
134 	{0x15, 0x01, 0xf0, 0xc0, "1 Coin  4 Credits"	},
135 	{0x15, 0x01, 0xf0, 0xb0, "1 Coin  5 Credits"	},
136 	{0x15, 0x01, 0xf0, 0xa0, "1 Coin  6 Credits"	},
137 	{0x15, 0x01, 0xf0, 0x90, "1 Coin  7 Credits"	},
138 	{0x15, 0x01, 0xf0, 0x00, "No Coin B"		},
139 };
140 
STDDIPINFO(Tutankhm)141 STDDIPINFO(Tutankhm)
142 
143 static void bankswitch(INT32 data)
144 {
145 	nRomBank = data;
146 
147 	INT32 bank = 0x10000 + (data & 0x0f) * 0x1000;
148 
149 	M6809MapMemory(DrvM6809ROM + bank, 0x9000, 0x9fff, MAP_ROM);
150 }
151 
tutankhm_write(UINT16 address,UINT8 data)152 static void tutankhm_write(UINT16 address, UINT8 data)
153 {
154 	if ((address & 0xfff0) == 0x8000) {
155 		DrvPalRAM[address & 0x0f] = data;
156 		return;
157 	}
158 
159 	switch (address)
160 	{
161 		case 0x8100:
162 			scrolldata = data;
163 		return;
164 
165 		case 0x8200:
166 			irq_enable = data & 1;
167 			if (!irq_enable) {
168 				M6809SetIRQLine(0, CPU_IRQSTATUS_NONE);
169 			}
170 		return;
171 
172 		case 0x8202:
173 			// coin counter
174 		return;
175 
176 		case 0x8204:
177 			StarsEnabled = data & 1;
178 		return;
179 
180 		case 0x8205:
181 			sound_mute = data & 1;
182 		return;
183 
184 		case 0x8206:
185 			flipscreenx = data & 1;
186 		return;
187 
188 		case 0x8207:
189 			flipscreeny = data & 1;
190 		return;
191 
192 		case 0x8300:
193 			bankswitch(data);
194 		return;
195 
196 		case 0x8600:
197 			ZetSetIRQLine(0, CPU_IRQSTATUS_ACK);
198 		return;
199 
200 		case 0x8700:
201 			TimepltSndSoundlatch(data);
202 		return;
203 	}
204 }
205 
tutankhm_read(UINT16 address)206 static UINT8 tutankhm_read(UINT16 address)
207 {
208 	switch (address)
209 	{
210 		case 0x8120:
211 			watchdog = 0;
212 			return 0;
213 
214 		case 0x8160:
215 			return DrvDips[0];
216 
217 		case 0x8180:
218 			return DrvInputs[0];
219 
220 		case 0x81a0:
221 			return DrvInputs[1];
222 
223 		case 0x81c0:
224 			return DrvInputs[2];
225 
226 		case 0x81e0:
227 			return DrvDips[1];
228 
229 		case 0x8200:
230 			return 0;
231 	}
232 
233 	return 0;
234 }
235 
DrvDoReset(INT32 clear_ram)236 static INT32 DrvDoReset(INT32 clear_ram)
237 {
238 	if (clear_ram) {
239 		memset(AllRam, 0, RamEnd - AllRam);
240 	}
241 
242 	M6809Open(0);
243 	M6809Reset();
244 	bankswitch(0);
245 	M6809Close();
246 
247 	TimepltSndReset();
248 
249 	irq_enable = 0;
250 	sound_mute = 0;
251 	watchdog = 0;
252 	scrolldata = 0;
253 	flipscreenx = 0;
254 	flipscreeny = 0;
255 
256 	StarsEnabled = 0;
257 	StarScrollX = StarScrollY = 0;
258 
259 	HiscoreReset();
260 
261 	return 0;
262 }
263 
264 struct Star {
265 	UINT16 x, y;
266 	UINT8 Colour, Set;
267 };
268 
269 #define MAX_STARS 252
270 static struct Star StarSeedTab[MAX_STARS];
271 
DrvInitStars()272 static void DrvInitStars()
273 {
274 	/*
275 	  Galaga star line and pixel locations pulled directly from
276 	  a clocked stepping of the 05 starfield. The chip was clocked
277 	  on a test rig with hblank and vblank simulated, each X & Y
278 	  location of a star being recorded along with it's color value.
279 
280 	  The lookup table is generated using a reverse engineered
281 	  linear feedback shift register + XOR boolean expression.
282 
283 	  Because the starfield begins generating stars at the point
284 	  in time it's enabled the exact horiz location of the stars
285 	  on Galaga depends on the length of time of the POST for the
286 	  original board.
287 
288 	  Two control bits determine which of two sets are displayed
289 	  set 0 or 1 and simultaneously 2 or 3.
290 
291 	  There are 63 stars in each set, 126 displayed at any one time
292 	  Code: jmakovicka, based on info from http://www.pin4.at/pro_custom_05xx.php
293 	*/
294 
295 	const UINT16 feed = 0x9420;
296 
297 	INT32 idx = 0;
298 	for (UINT16 sf = 0; sf < 4; ++sf)
299 	{
300 		// starfield select flags
301 		UINT16 sf1 = (sf >> 1) & 1;
302 		UINT16 sf2 = sf & 1;
303 
304 		UINT16 i = 0x70cc;
305 		for (INT32 cnt = 0; cnt < 65535; ++cnt)
306 		{
307 			// output enable lookup
308 			UINT16 xor1 = i ^ (i >> 3);
309 			UINT16 xor2 = xor1 ^ (i >> 2);
310 			UINT16 oe = (sf1 ? 0 : 0x4000) | ((sf1 ^ sf2) ? 0 : 0x1000);
311 			if ((i & 0x8007) == 0x8007
312 			    && (~i & 0x2008) == 0x2008
313 			    && (xor1 & 0x0100) == (sf1 ? 0 : 0x0100)
314 			    && (xor2 & 0x0040) == (sf2 ? 0 : 0x0040)
315 			    && (i & 0x5000) == oe
316 			    && cnt >= 256 * 4)
317 			{
318 				// color lookup
319 				UINT16 xor3 = (i >> 1) ^ (i >> 6);
320 				UINT16 clr =
321 					(((i >> 9) & 0x07)
322 					 | ((xor3 ^ (i >> 4) ^ (i >> 7)) & 0x08)
323 					 | (~xor3 & 0x10)
324 					 | (((i >> 2) ^ (i >> 5)) & 0x20))
325 					^ ((i & 0x4000) ? 0 : 0x24)
326 					^ ((((i >> 2) ^ i) & 0x1000) ? 0x21 : 0);
327 
328 				StarSeedTab[idx].x = cnt % 256;
329 				StarSeedTab[idx].y = cnt / 256;
330 				StarSeedTab[idx].Colour = clr;
331 				StarSeedTab[idx].Set = sf;
332 				++idx;
333 			}
334 
335 			// update the LFSR
336 			if (i & 1)
337 				i = (i >> 1) ^ feed;
338 			else
339 				i = (i >> 1);
340 		}
341 	}
342 }
343 
MemIndex()344 static INT32 MemIndex()
345 {
346 	UINT8 *Next; Next = AllMem;
347 
348 	DrvM6809ROM		= Next; Next += 0x020000;
349 	DrvZ80ROM		= Next; Next += 0x003000;
350 
351 	DrvPalette		= (UINT32*)Next; Next += (0x0010 + 0x0080) * sizeof(UINT32);
352 
353 	AllRam			= Next;
354 
355 	DrvVidRAM		= Next; Next += 0x008000;
356 	DrvM6809RAM		= Next; Next += 0x000800;
357 	DrvZ80RAM		= Next; Next += 0x000400;
358 	DrvPalRAM		= Next; Next += 0x000010;
359 
360 	RamEnd			= Next;
361 
362 	MemEnd			= Next;
363 
364 	return 0;
365 }
366 
DrvInit()367 static INT32 DrvInit()
368 {
369 	AllMem = NULL;
370 	MemIndex();
371 	INT32 nLen = MemEnd - (UINT8 *)0;
372 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
373 	memset(AllMem, 0, nLen);
374 	MemIndex();
375 
376 	{
377 		if (BurnLoadRom(DrvM6809ROM + 0x0a000,  0, 1)) return 1;
378 		if (BurnLoadRom(DrvM6809ROM + 0x0b000,  1, 1)) return 1;
379 		if (BurnLoadRom(DrvM6809ROM + 0x0c000,  2, 1)) return 1;
380 		if (BurnLoadRom(DrvM6809ROM + 0x0d000,  3, 1)) return 1;
381 		if (BurnLoadRom(DrvM6809ROM + 0x0e000,  4, 1)) return 1;
382 		if (BurnLoadRom(DrvM6809ROM + 0x0f000,  5, 1)) return 1;
383 		if (BurnLoadRom(DrvM6809ROM + 0x10000,  6, 1)) return 1;
384 		if (BurnLoadRom(DrvM6809ROM + 0x11000,  7, 1)) return 1;
385 		if (BurnLoadRom(DrvM6809ROM + 0x12000,  8, 1)) return 1;
386 		if (BurnLoadRom(DrvM6809ROM + 0x13000,  9, 1)) return 1;
387 		if (BurnLoadRom(DrvM6809ROM + 0x14000, 10, 1)) return 1;
388 		if (BurnLoadRom(DrvM6809ROM + 0x15000, 11, 1)) return 1;
389 		if (BurnLoadRom(DrvM6809ROM + 0x16000, 12, 1)) return 1;
390 		if (BurnLoadRom(DrvM6809ROM + 0x17000, 13, 1)) return 1;
391 		if (BurnLoadRom(DrvM6809ROM + 0x18000, 14, 1)) return 1;
392 
393 		if (BurnLoadRom(DrvZ80ROM   + 0x00000, 15, 1)) return 1;
394 		if (BurnLoadRom(DrvZ80ROM   + 0x01000, 16, 1)) return 1;
395 	}
396 
397 	M6809Init(0);
398 	M6809Open(0);
399 	M6809MapMemory(DrvVidRAM,		0x0000, 0x7fff, MAP_RAM);
400 	M6809MapMemory(DrvM6809RAM,		0x8800, 0x8fff, MAP_RAM);
401 	M6809MapMemory(DrvM6809ROM + 0xa000,	0xa000, 0xffff, MAP_ROM);
402 	M6809SetWriteHandler(tutankhm_write);
403 	M6809SetReadHandler(tutankhm_read);
404 	M6809Close();
405 
406 	TimepltSndInit(DrvZ80ROM, DrvZ80RAM, 0);
407 	TimepltSndSrcGain(0.55); // quench distortion when enemy spawns
408 
409 	GenericTilesInit();
410 
411 	DrvInitStars();
412 
413 	DrvDoReset(1);
414 
415 	return 0;
416 }
417 
DrvExit()418 static INT32 DrvExit()
419 {
420 	GenericTilesExit();
421 
422 	M6809Exit();
423 
424 	TimepltSndExit();
425 
426 	BurnFree (AllMem);
427 
428 	return 0;
429 }
430 
DrvPaletteUpdate()431 static void DrvPaletteUpdate()
432 {
433 	for (INT32 i = 0; i < 0x10; i++) {
434 		INT32 r = (DrvPalRAM[i] >> 0) & 7;
435 		INT32 g = (DrvPalRAM[i] >> 3) & 7;
436 		INT32 b = (DrvPalRAM[i] >> 6) & 3;
437 
438 		r  = (r << 5) | (r << 2) | (r >> 1);
439 		g  = (g << 5) | (g << 2) | (g >> 1);
440 		b |= (b << 6) | (b << 4) | (b << 2);
441 
442 		DrvPalette[i] = BurnHighCol(r,g,b,0);
443 	}
444 
445 	for (INT32 i = 0; i < 0x40; i++) { // starfield palette
446 		static const INT32 map[4] = { 0x00, 0x47, 0x97, 0xde };
447 
448 		INT32 bits = (i >> 0) & 0x03;
449 		INT32 r = map[bits];
450 		bits = (i >> 2) & 0x03;
451 		INT32 g = map[bits];
452 		bits = (i >> 4) & 0x03;
453 		INT32 b = map[bits];
454 
455 		DrvPalette[0x20 + i] = BurnHighCol(r, g, b, 0);
456 	}
457 }
458 
draw_layer()459 static void draw_layer()
460 {
461 	INT32 flipx = (flipscreenx) ? 255 : 0;
462 	INT32 flipy = (flipscreeny) ? 255 : 0;
463 
464 	for (INT32 y = 16; y < 256 - 16; y++)
465 	{
466 		UINT16 *dst = pTransDraw + (y - 16) * nScreenWidth;
467 
468 		for (INT32 x = 0; x < nScreenWidth; x++)
469 		{
470 			UINT8 effx = x ^ flipx;
471 			UINT8 yscroll = (effx < 192) ? scrolldata : 0;
472 			UINT8 effy = (y ^ flipy) + yscroll;
473 			dst[x] = (DrvVidRAM[effy * 128 + effx / 2] >> (4 * (effx & 1))) & 0xf;
474 		}
475 	}
476 }
477 
render_stars()478 static void render_stars()
479 {
480 	if (StarsEnabled) {
481 		INT32 StarCounter;
482 		INT32 SetA, SetB;
483 		INT32 transloc;
484 		SetA = ((nCurrentFrame+0x40) & 0x80) ? 1 : 0;
485 		SetB = (nCurrentFrame & 0x80) ? 2 : 3;
486 
487 		for (StarCounter = 0; StarCounter < 252; StarCounter++) {
488 			INT32 x, y;
489 
490 			if ((SetA == StarSeedTab[StarCounter].Set) || (SetB == StarSeedTab[StarCounter].Set)) {
491 				x = (StarSeedTab[StarCounter].x + StarScrollX) % 256 + 16;
492 				y = (112 + StarSeedTab[StarCounter].y + StarScrollY) % 256;
493 
494 				if (x >= 0 && x < nScreenWidth && y >= 0 && y < nScreenHeight) {
495 					transloc = (y * nScreenWidth) + x;
496 					if (!pTransDraw[transloc])
497 						pTransDraw[transloc] = StarSeedTab[StarCounter].Colour + 0x20;
498 				}
499 			}
500 
501 		}
502 	}
503 }
504 
DrvDraw()505 static INT32 DrvDraw()
506 {
507 //	if (DrvRecalc) {
508 		DrvPaletteUpdate();
509 		DrvRecalc = 0;
510 //	}
511 
512 	BurnTransferClear();
513 
514 	if (nBurnLayer & 1) draw_layer();
515 
516 	if (nBurnLayer & 2) render_stars();
517 
518 	BurnTransferCopy(DrvPalette);
519 
520 	return 0;
521 }
522 
DrvFrame()523 static INT32 DrvFrame()
524 {
525 	watchdog++;
526 	if (watchdog >= 180) {
527 		DrvDoReset(0);
528 	}
529 
530 	if (DrvReset) {
531 		DrvDoReset(1);
532 	}
533 
534 	ZetNewFrame();
535 
536 	{
537 		memset (DrvInputs, 0xff, 3);
538 		for (INT32 i = 0; i < 8; i++) {
539 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
540 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
541 			DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
542 		}
543 
544 		// Clear opposites
545 		if ((DrvInputs[1] & 0x0c) == 0) DrvInputs[1] |= 0x0c;
546 		if ((DrvInputs[1] & 0x03) == 0) DrvInputs[1] |= 0x03;
547 		if ((DrvInputs[1] & 0x30) == 0) DrvInputs[1] |= 0x30;
548 		if ((DrvInputs[2] & 0x0c) == 0) DrvInputs[2] |= 0x0c;
549 		if ((DrvInputs[2] & 0x03) == 0) DrvInputs[2] |= 0x03;
550 		if ((DrvInputs[2] & 0x30) == 0) DrvInputs[2] |= 0x30;
551 	}
552 
553 	INT32 nInterleave = 256;
554 	INT32 nCyclesTotal[2] = { 1536000 / 60, 1789772 / 60 };
555 	INT32 nCyclesDone[2] = { 0, 0 };
556 
557 	M6809Open(0);
558 	ZetOpen(0);
559 
560 	for (INT32 i = 0; i < nInterleave; i++)
561 	{
562 		CPU_RUN(0, M6809);
563 		if (i == (nInterleave - 1) && irq_enable && (nCurrentFrame & 1)) M6809SetIRQLine(0, CPU_IRQSTATUS_ACK);
564 
565 		CPU_RUN(1, Zet);
566 	}
567 
568 	ZetClose();
569 	M6809Close();
570 
571 	if (pBurnSoundOut) {
572 		if (sound_mute) {
573 			BurnSoundClear();
574 		} else {
575 			TimepltSndUpdate(pBurnSoundOut, nBurnSoundLen);
576 		}
577 	}
578 
579 	if (pBurnDraw) {
580 		DrvDraw();
581 	}
582 
583 	return 0;
584 }
585 
DrvScan(INT32 nAction,INT32 * pnMin)586 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
587 {
588 	struct BurnArea ba;
589 
590 	if (pnMin) {
591 		*pnMin = 0x029521;
592 	}
593 
594 	if (nAction & ACB_VOLATILE) {
595 		memset(&ba, 0, sizeof(ba));
596 
597 		ba.Data	  = AllRam;
598 		ba.nLen	  = RamEnd - AllRam;
599 		ba.szName = "All Ram";
600 		BurnAcb(&ba);
601 
602 		M6809Scan(nAction);
603 		TimepltSndScan(nAction, pnMin);
604 
605 		SCAN_VAR(scrolldata);
606 		SCAN_VAR(sound_mute);
607 		SCAN_VAR(irq_enable);
608 		SCAN_VAR(flipscreenx);
609 		SCAN_VAR(flipscreeny);
610 		SCAN_VAR(nRomBank);
611 		SCAN_VAR(StarsEnabled);
612 	}
613 
614 	if (nAction & ACB_WRITE) {
615 		M6809Open(0);
616 		bankswitch(nRomBank);
617 		M6809Close();
618 	}
619 
620 	return 0;
621 }
622 
623 
624 // Tutankham
625 
626 static struct BurnRomInfo tutankhmRomDesc[] = {
627 	{ "m1.1h",	0x1000, 0xda18679f, 1 | BRF_PRG | BRF_ESS }, //  0 M6809 Code
628 	{ "m2.2h",	0x1000, 0xa0f02c85, 1 | BRF_PRG | BRF_ESS }, //  1
629 	{ "3j.3h",	0x1000, 0xea03a1ab, 1 | BRF_PRG | BRF_ESS }, //  2
630 	{ "m4.4h",	0x1000, 0xbd06fad0, 1 | BRF_PRG | BRF_ESS }, //  3
631 	{ "m5.5h",	0x1000, 0xbf9fd9b0, 1 | BRF_PRG | BRF_ESS }, //  4
632 	{ "j6.6h",	0x1000, 0xfe079c5b, 1 | BRF_PRG | BRF_ESS }, //  5
633 	{ "c1.1i",	0x1000, 0x7eb59b21, 1 | BRF_PRG | BRF_ESS }, //  6
634 	{ "c2.2i",	0x1000, 0x6615eff3, 1 | BRF_PRG | BRF_ESS }, //  7
635 	{ "c3.3i",	0x1000, 0xa10d4444, 1 | BRF_PRG | BRF_ESS }, //  8
636 	{ "c4.4i",	0x1000, 0x58cd143c, 1 | BRF_PRG | BRF_ESS }, //  9
637 	{ "c5.5i",	0x1000, 0xd7e7ae95, 1 | BRF_PRG | BRF_ESS }, // 10
638 	{ "c6.6i",	0x1000, 0x91f62b82, 1 | BRF_PRG | BRF_ESS }, // 11
639 	{ "c7.7i",	0x1000, 0xafd0a81f, 1 | BRF_PRG | BRF_ESS }, // 12
640 	{ "c8.8i",	0x1000, 0xdabb609b, 1 | BRF_PRG | BRF_ESS }, // 13
641 	{ "c9.9i",	0x1000, 0x8ea9c6a6, 1 | BRF_PRG | BRF_ESS }, // 14
642 
643 	{ "s1.7a",	0x1000, 0xb52d01fa, 2 | BRF_PRG | BRF_ESS }, // 15 Z80 Code
644 	{ "s2.8a",	0x1000, 0x9db5c0ce, 2 | BRF_PRG | BRF_ESS }, // 16
645 };
646 
647 STD_ROM_PICK(tutankhm)
648 STD_ROM_FN(tutankhm)
649 
650 struct BurnDriver BurnDrvTutankhm = {
651 	"tutankhm", NULL, NULL, NULL, "1982",
652 	"Tutankham\0", NULL, "Konami", "GX350",
653 	NULL, NULL, NULL, NULL,
654 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED | BDF_HISCORE_SUPPORTED, 4, HARDWARE_PREFIX_KONAMI, GBF_MAZE, 0,
655 	NULL, tutankhmRomInfo, tutankhmRomName, NULL, NULL, NULL, NULL, TutankhmInputInfo, TutankhmDIPInfo,
656 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x10,
657 	224, 256, 3, 4
658 };
659 
660 
661 // Tutankham (Stern Electronics)
662 
663 static struct BurnRomInfo tutankhmsRomDesc[] = {
664 	{ "m1.1h",	0x1000, 0xda18679f, 1 | BRF_PRG | BRF_ESS }, //  0 M6809 Code
665 	{ "m2.2h",	0x1000, 0xa0f02c85, 1 | BRF_PRG | BRF_ESS }, //  1
666 	{ "3a.3h",	0x1000, 0x2d62d7b1, 1 | BRF_PRG | BRF_ESS }, //  2
667 	{ "m4.4h",	0x1000, 0xbd06fad0, 1 | BRF_PRG | BRF_ESS }, //  3
668 	{ "m5.5h",	0x1000, 0xbf9fd9b0, 1 | BRF_PRG | BRF_ESS }, //  4
669 	{ "a6.6h",	0x1000, 0xc43b3865, 1 | BRF_PRG | BRF_ESS }, //  5
670 	{ "c1.1i",	0x1000, 0x7eb59b21, 1 | BRF_PRG | BRF_ESS }, //  6
671 	{ "c2.2i",	0x1000, 0x6615eff3, 1 | BRF_PRG | BRF_ESS }, //  7
672 	{ "c3.3i",	0x1000, 0xa10d4444, 1 | BRF_PRG | BRF_ESS }, //  8
673 	{ "c4.4i",	0x1000, 0x58cd143c, 1 | BRF_PRG | BRF_ESS }, //  9
674 	{ "c5.5i",	0x1000, 0xd7e7ae95, 1 | BRF_PRG | BRF_ESS }, // 10
675 	{ "c6.6i",	0x1000, 0x91f62b82, 1 | BRF_PRG | BRF_ESS }, // 11
676 	{ "c7.7i",	0x1000, 0xafd0a81f, 1 | BRF_PRG | BRF_ESS }, // 12
677 	{ "c8.8i",	0x1000, 0xdabb609b, 1 | BRF_PRG | BRF_ESS }, // 13
678 	{ "c9.9i",	0x1000, 0x8ea9c6a6, 1 | BRF_PRG | BRF_ESS }, // 14
679 
680 	{ "s1.7a",	0x1000, 0xb52d01fa, 2 | BRF_PRG | BRF_ESS }, // 15 Z80 Code
681 	{ "s2.8a",	0x1000, 0x9db5c0ce, 2 | BRF_PRG | BRF_ESS }, // 16
682 };
683 
684 STD_ROM_PICK(tutankhms)
685 STD_ROM_FN(tutankhms)
686 
687 struct BurnDriver BurnDrvTutankhms = {
688 	"tutankhms", "tutankhm", NULL, NULL, "1982",
689 	"Tutankham (Stern Electronics)\0", NULL, "Konami (Stern Electronics license)", "GX350",
690 	NULL, NULL, NULL, NULL,
691 	BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED | BDF_HISCORE_SUPPORTED, 4, HARDWARE_PREFIX_KONAMI, GBF_MAZE, 0,
692 	NULL, tutankhmsRomInfo, tutankhmsRomName, NULL, NULL, NULL, NULL, TutankhmInputInfo, TutankhmDIPInfo,
693 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x10,
694 	224, 256, 3, 4
695 };
696