1 // FB Alpha Time Limit driver module
2 // Based on MAME driver by Ernesto Corvi
3 
4 #include "tiles_generic.h"
5 #include "z80_intf.h"
6 #include "ay8910.h"
7 
8 static UINT8 *AllMem;
9 static UINT8 *MemEnd;
10 static UINT8 *AllRam;
11 static UINT8 *RamEnd;
12 static UINT8 *DrvZ80ROM0;
13 static UINT8 *DrvZ80ROM1;
14 static UINT8 *DrvGfxROM0;
15 static UINT8 *DrvGfxROM1;
16 static UINT8 *DrvGfxROM2;
17 static UINT8 *DrvZ80RAM0;
18 static UINT8 *DrvZ80RAM1;
19 static UINT8 *DrvSprRAM;
20 static UINT8 *DrvVidRAM0;
21 static UINT8 *DrvVidRAM1;
22 static UINT8 *DrvColPROM;
23 
24 static UINT32 *DrvPalette;
25 static UINT8 DrvRecalc;
26 
27 static UINT8 DrvJoy1[8];
28 static UINT8 DrvJoy2[8];
29 static UINT8 DrvDips[1];
30 static UINT8 DrvInputs[2];
31 static UINT8 DrvReset;
32 
33 static UINT8 soundlatch;
34 static UINT8 nmi_enable;
35 static UINT8 scrolly;
36 static UINT16 scrollx;
37 static INT32 watchdog;
38 
39 static INT32 TimelimtMode = 0;
40 
41 static struct BurnInputInfo TimelimtInputList[] = {
42 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy2 + 0,	"p1 coin"	},
43 	{"P1 Start",		BIT_DIGITAL,	DrvJoy2 + 2,	"p1 start"	},
44 	{"P1 Up",			BIT_DIGITAL,	DrvJoy1 + 3,	"p1 up"		},
45 	{"P1 Down",			BIT_DIGITAL,	DrvJoy1 + 2,	"p1 down"	},
46 	{"P1 Left",			BIT_DIGITAL,	DrvJoy1 + 0,	"p1 left"	},
47 	{"P1 Right",		BIT_DIGITAL,	DrvJoy1 + 1,	"p1 right"	},
48 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 4,	"p1 fire 1"	},
49 
50 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
51 	{"Dips",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
52 };
53 
54 STDINPUTINFO(Timelimt)
55 
56 static struct BurnInputInfo ProgressInputList[] = {
57 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy2 + 0,	"p1 coin"	},
58 	{"P1 Start",		BIT_DIGITAL,	DrvJoy2 + 2,	"p1 start"	},
59 	{"P1 Up",			BIT_DIGITAL,	DrvJoy1 + 3,	"p1 up"		},
60 	{"P1 Down",			BIT_DIGITAL,	DrvJoy1 + 2,	"p1 down"	},
61 	{"P1 Left",			BIT_DIGITAL,	DrvJoy1 + 0,	"p1 left"	},
62 	{"P1 Right",		BIT_DIGITAL,	DrvJoy1 + 1,	"p1 right"	},
63 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 4,	"p1 fire 1"	},
64 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 fire 2"	},
65 	{"P1 Button 3",		BIT_DIGITAL,	DrvJoy1 + 7,	"p1 fire 3"	},
66 
67 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
68 	{"Dips",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
69 };
70 
71 STDINPUTINFO(Progress)
72 
73 static struct BurnDIPInfo TimelimtDIPList[]=
74 {
75 	DIP_OFFSET(0x08)
76 	{0x00, 0xff, 0xff, 0x01, NULL						},
77 
78 	{0   , 0xfe, 0   ,    8, "Coinage"					},
79 	{0x00, 0x01, 0x07, 0x00, "2 Coins 1 Credits"		},
80 	{0x00, 0x01, 0x07, 0x01, "1 Coin  1 Credits"		},
81 	{0x00, 0x01, 0x07, 0x02, "1 Coin  2 Credits"		},
82 	{0x00, 0x01, 0x07, 0x03, "1 Coin  3 Credits"		},
83 	{0x00, 0x01, 0x07, 0x04, "1 Coin  4 Credits"		},
84 	{0x00, 0x01, 0x07, 0x05, "1 Coin  5 Credits"		},
85 	{0x00, 0x01, 0x07, 0x06, "1 Coin  6 Credits"		},
86 	{0x00, 0x01, 0x07, 0x07, "1 Coin  7 Credits"		},
87 
88 	{0   , 0xfe, 0   ,    2, "Lives"					},
89 	{0x00, 0x01, 0x10, 0x00, "3"						},
90 	{0x00, 0x01, 0x10, 0x10, "5"						},
91 
92 	{0   , 0xfe, 0   ,    2, "Invincibility (Cheat)"	},
93 	{0x00, 0x01, 0x80, 0x00, "Off"						},
94 	{0x00, 0x01, 0x80, 0x80, "On"						},
95 };
96 
97 STDDIPINFO(Timelimt)
98 
99 static struct BurnDIPInfo ProgressDIPList[]=
100 {
101 	DIP_OFFSET(0x0a)
102 	{0x00, 0xff, 0xff, 0x01, NULL						},
103 
104 	{0   , 0xfe, 0   ,    8, "Coinage"					},
105 	{0x00, 0x01, 0x07, 0x00, "2 Coins 1 Credits"		},
106 	{0x00, 0x01, 0x07, 0x01, "1 Coin  1 Credits"		},
107 	{0x00, 0x01, 0x07, 0x02, "1 Coin  2 Credits"		},
108 	{0x00, 0x01, 0x07, 0x03, "1 Coin  3 Credits"		},
109 	{0x00, 0x01, 0x07, 0x04, "1 Coin  4 Credits"		},
110 	{0x00, 0x01, 0x07, 0x05, "1 Coin  5 Credits"		},
111 	{0x00, 0x01, 0x07, 0x06, "1 Coin  6 Credits"		},
112 	{0x00, 0x01, 0x07, 0x07, "1 Coin  7 Credits"		},
113 
114 	{0   , 0xfe, 0   ,    2, "Lives"					},
115 	{0x00, 0x01, 0x10, 0x00, "3"						},
116 	{0x00, 0x01, 0x10, 0x10, "5"						},
117 
118 	{0   , 0xfe, 0   ,    2, "Bonus Life"				},
119 	{0x00, 0x01, 0x20, 0x00, "20,000 & 100,000"			},
120 	{0x00, 0x01, 0x20, 0x20, "50,000 & 200,000"			},
121 
122 	{0   , 0xfe, 0   ,    2, "Invincibility (Cheat)"	},
123 	{0x00, 0x01, 0x80, 0x00, "Off"						},
124 	{0x00, 0x01, 0x80, 0x80, "On"						},
125 };
126 
STDDIPINFO(Progress)127 STDDIPINFO(Progress)
128 
129 static void __fastcall timelimt_main_write(UINT16 address, UINT8 data)
130 {
131 	switch (address)
132 	{
133 		case 0xb000:
134 			nmi_enable = data & 1;
135 		return;
136 
137 		case 0xb003:
138 			if (data & 1) {
139 				ZetReset(1);
140 			}
141 		return;
142 
143 		case 0xb800:
144 			soundlatch = data;
145 		return;
146 
147 		case 0xc800:
148 			scrollx = (scrollx & 0xff00) + data;
149 		return;
150 
151 		case 0xc801:
152 			scrollx = (scrollx & 0x00ff) + ((data & 1) << 8);
153 		return;
154 
155 		case 0xc802:
156 			scrolly = data;
157 		return;
158 
159 		case 0xc803: // nop
160 		case 0xc804:
161 		return;
162 	}
163 }
164 
timelimt_main_read(UINT16 address)165 static UINT8 __fastcall timelimt_main_read(UINT16 address)
166 {
167 	switch (address)
168 	{
169 		case 0xa000:
170 			return DrvInputs[0];
171 
172 		case 0xa800:
173 			return DrvInputs[1];
174 
175 		case 0xb000:
176 			return DrvDips[0];
177 	}
178 
179 	return 0;
180 }
181 
timelimt_main_read_port(UINT16 port)182 static UINT8 __fastcall timelimt_main_read_port(UINT16 port)
183 {
184 	if ((port & 0xff) == 0) {
185 		watchdog = 0;
186 		return 0;
187 	}
188 
189 	return 0;
190 }
191 
timelimt_sound_write_port(UINT16 port,UINT8 data)192 static void __fastcall timelimt_sound_write_port(UINT16 port, UINT8 data)
193 {
194 	switch (port & 0xff)
195 	{
196 		case 0x00:
197 			soundlatch = 0;
198 		return;
199 
200 		case 0x8c:
201 		case 0x8d:
202 		case 0x8e:
203 		case 0x8f:
204 			AY8910Write((port & 2) >> 1, port & 1, data);
205 		return;
206 	}
207 }
208 
timelimt_sound_read_port(UINT16 port)209 static UINT8 __fastcall timelimt_sound_read_port(UINT16 port)
210 {
211 	switch (port & 0xff)
212 	{
213 		case 0x8c:
214 		case 0x8d:
215 		case 0x8e:
216 		case 0x8f:
217 			return AY8910Read((port & 2) >> 1);
218 	}
219 
220 	return 0;
221 }
222 
timelimt_ay8910_1_portA_read(UINT32)223 static UINT8 timelimt_ay8910_1_portA_read(UINT32)
224 {
225 	return soundlatch;
226 }
227 
DrvDoReset(INT32 clear_ram)228 static INT32 DrvDoReset(INT32 clear_ram)
229 {
230 	if (clear_ram) {
231 		memset (AllRam, 0, RamEnd - AllRam);
232 	}
233 
234 	ZetReset(0);
235 
236 	ZetReset(1);
237 
238 	AY8910Reset(0);
239 	AY8910Reset(1);
240 
241 	soundlatch = 0;
242 	nmi_enable = 0;
243 	scrollx = 0;
244 	scrolly = 0;
245 	watchdog = 0;
246 
247 	return 0;
248 }
249 
MemIndex()250 static INT32 MemIndex()
251 {
252 	UINT8 *Next; Next = AllMem;
253 
254 	DrvZ80ROM0		= Next; Next += 0x008000;
255 	DrvZ80ROM1		= Next; Next += 0x002000;
256 
257 	DrvGfxROM0		= Next; Next += 0x004000;
258 	DrvGfxROM1		= Next; Next += 0x004000;
259 	DrvGfxROM2		= Next; Next += 0x010000;
260 
261 	DrvColPROM		= Next; Next += 0x000060;
262 
263 	DrvPalette		= (UINT32*)Next; Next += 0x0060 * sizeof(UINT32);
264 
265 	AllRam			= Next;
266 
267 	DrvZ80RAM0		= Next; Next += 0x000800;
268 	DrvZ80RAM1		= Next; Next += 0x000c00;
269 
270 	DrvVidRAM0		= Next; Next += 0x000400;
271 	DrvVidRAM1		= Next; Next += 0x000800;
272 
273 	DrvSprRAM		= Next; Next += 0x000100;
274 
275 	RamEnd			= Next;
276 
277 	MemEnd			= Next;
278 
279 	return 0;
280 }
281 
DrvPaletteInit()282 static void DrvPaletteInit()
283 {
284 	for (INT32 i = 0; i < 0x60; i++)
285 	{
286 		INT32 bit0 = (DrvColPROM[i] >> 0) & 0x01;
287 		INT32 bit1 = (DrvColPROM[i] >> 1) & 0x01;
288 		INT32 bit2 = (DrvColPROM[i] >> 2) & 0x01;
289 		INT32 r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
290 
291 		bit0 = (DrvColPROM[i] >> 3) & 0x01;
292 		bit1 = (DrvColPROM[i] >> 4) & 0x01;
293 		bit2 = (DrvColPROM[i] >> 5) & 0x01;
294 		INT32 g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
295 
296 		bit0 = (DrvColPROM[i] >> 6) & 0x01;
297 		bit1 = (DrvColPROM[i] >> 7) & 0x01;
298 		INT32 b = 0x4f * bit0 + 0xa8 * bit1;
299 
300 		DrvPalette[i] = BurnHighCol(r,g,b,0);
301 	}
302 }
303 
DrvGfxDecode()304 static void DrvGfxDecode()
305 {
306 	static INT32 Planes0[4] = { 0, 4, (0x1000*8)+0, (0x1000*8)+4 };
307 	static INT32 Planes1[3] = { 0, (0x2000*8), (0x4000*8) };
308 	static INT32 XOffs0[8]  = { STEP4(0,1), STEP4(8,1) };
309 	static INT32 YOffs0[8]  = { STEP8(0,16) };
310 	static INT32 XOffs1[16] = { STEP8(0,1), STEP8(64,1) };
311 	static INT32 YOffs1[16] = { STEP8(0,8), STEP8(128,8) };
312 
313 	UINT8 *tmp = (UINT8 *)BurnMalloc(0x6000);
314 	if (tmp == NULL) {
315 		return;
316 	}
317 
318 	memcpy (tmp, DrvGfxROM0, 0x4000);
319 
320 	GfxDecode(0x0100, 4,  8,  8, Planes0, XOffs0, YOffs0, 0x080, tmp, DrvGfxROM0);
321 
322 	memcpy (tmp, DrvGfxROM1, 0x4000);
323 
324 	GfxDecode(0x0100, 4,  8,  8, Planes0, XOffs0, YOffs0, 0x080, tmp, DrvGfxROM1);
325 
326 	memcpy (tmp, DrvGfxROM2, 0x6000);
327 
328 	GfxDecode(0x0100, 3, 16, 16, Planes1, XOffs1, YOffs1, 0x100, tmp, DrvGfxROM2);
329 
330 	BurnFree (tmp);
331 }
332 
DrvInit()333 static INT32 DrvInit()
334 {
335 	AllMem = NULL;
336 	MemIndex();
337 	INT32 nLen = MemEnd - (UINT8 *)0;
338 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
339 	memset(AllMem, 0, nLen);
340 	MemIndex();
341 
342 	{
343 		if (BurnLoadRom(DrvZ80ROM0 + 0x0000,  0, 1)) return 1;
344 		if (BurnLoadRom(DrvZ80ROM0 + 0x2000,  1, 1)) return 1;
345 		if (BurnLoadRom(DrvZ80ROM0 + 0x4000,  2, 1)) return 1;
346 		if (BurnLoadRom(DrvZ80ROM0 + 0x6000,  3, 1)) return 1;
347 
348 		if (BurnLoadRom(DrvGfxROM0 + 0x0000,  4, 1)) return 1;
349 		if (BurnLoadRom(DrvGfxROM0 + 0x1000,  5, 1)) return 1;
350 
351 		if (BurnLoadRom(DrvGfxROM1 + 0x0000,  6, 1)) return 1;
352 		if (BurnLoadRom(DrvGfxROM1 + 0x1000,  7, 1)) return 1;
353 
354 		if (BurnLoadRom(DrvGfxROM2 + 0x0000,  8, 1)) return 1;
355 		if (BurnLoadRom(DrvGfxROM2 + 0x2000,  9, 1)) return 1;
356 		if (BurnLoadRom(DrvGfxROM2 + 0x4000, 10, 1)) return 1;
357 
358 		if (BurnLoadRom(DrvColPROM + 0x0000, 11, 1)) return 1;
359 		if (BurnLoadRom(DrvColPROM + 0x0020, 12, 1)) return 1;
360 
361 		if (!TimelimtMode)
362 			if (BurnLoadRom(DrvColPROM + 0x0040, 13, 1)) return 1;
363 
364 		if (TimelimtMode)
365 		{ // fill in missing timelimt prom with color values, values (c) 2017 -dink
366 	            const UINT8 color_data[32] = {
367 		        //0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f
368 				0x00, 0x00, 0xA4, 0xF6, 0xC0, 0x2F, 0x07, 0xFF, 0x00, 0x99, 0x99, 0xF6, 0x0A, 0x1F, 0x58, 0xFF,
369 				0x00, 0x0F, 0xB5, 0x54, 0xE1, 0x50, 0x5F, 0x64, 0x00, 0x0B, 0x53, 0x0F, 0x80, 0x08, 0x0D, 0xAE
370 			};
371 
372 			memcpy (DrvColPROM + 0x40, color_data, 0x20);
373 		}
374 
375 		if (BurnLoadRom(DrvZ80ROM1 + 0x0000, 14, 1)) return 1;
376 
377 		if (TimelimtMode)
378 			if (BurnLoadRom(DrvZ80ROM1 + 0x1000, 15, 1)) return 1;
379 
380 		DrvGfxDecode();
381 		DrvPaletteInit();
382 	}
383 
384 	ZetInit(0);
385 	ZetOpen(0);
386 	ZetMapMemory(DrvZ80ROM0,	0x0000, 0x7fff, MAP_ROM);
387 	ZetMapMemory(DrvZ80RAM0,	0x8000, 0x87ff, MAP_RAM);
388 	ZetMapMemory(DrvVidRAM0,	0x8800, 0x8bff, MAP_RAM);
389 	ZetMapMemory(DrvVidRAM1,	0x9000, 0x97ff, MAP_RAM);
390 	ZetMapMemory(DrvSprRAM,		0x9800, 0x98ff, MAP_RAM);
391 	ZetSetWriteHandler(timelimt_main_write);
392 	ZetSetReadHandler(timelimt_main_read);
393 	ZetSetInHandler(timelimt_main_read_port);
394 	ZetClose();
395 
396 	ZetInit(1);
397 	ZetOpen(1);
398 	ZetMapMemory(DrvZ80ROM1,	0x0000, 0x1fff, MAP_ROM);
399 	ZetMapMemory(DrvZ80RAM1,	0x3000, 0x3bff, MAP_RAM);
400 	ZetSetOutHandler(timelimt_sound_write_port);
401 	ZetSetInHandler(timelimt_sound_read_port);
402 	ZetClose();
403 
404 	AY8910Init(0, 1536000, 0);
405 	AY8910SetAllRoutes(0, 0.15, BURN_SND_ROUTE_BOTH);
406 
407 	AY8910Init(1, 1536000, 1);
408 	AY8910SetPorts(1, &timelimt_ay8910_1_portA_read, NULL, NULL, NULL);
409 	AY8910SetAllRoutes(1, 0.15, BURN_SND_ROUTE_BOTH);
410 	AY8910SetBuffered(ZetTotalCycles, 3072000);
411 
412 	GenericTilesInit();
413 
414 	DrvDoReset(1);
415 
416 	return 0;
417 }
418 
DrvExit()419 static INT32 DrvExit()
420 {
421 	GenericTilesExit();
422 
423 	ZetExit();
424 
425 	AY8910Exit(0);
426 	AY8910Exit(1);
427 
428 	BurnFree(AllMem);
429 
430 	TimelimtMode = 0;
431 
432 	return 0;
433 }
434 
draw_bg_layer()435 static void draw_bg_layer()
436 {
437 	for (INT32 offs = 0; offs < 64 * 32; offs++)
438 	{
439 		INT32 sx = (offs & 0x3f) * 8;
440 		INT32 sy = (offs / 0x40) * 8;
441 
442 		sx -= scrollx;
443 		if (sx < -7) sx += 512;
444 		if (sx >= nScreenWidth) continue;
445 
446 		sy -= (scrolly + 16) & 0xff;
447 		if (sy < -7) sy += 256;
448 		if (sy >= nScreenHeight) continue;
449 
450 		INT32 code = DrvVidRAM1[offs];
451 
452 		Render8x8Tile_Clip(pTransDraw, code, sx, sy, 0, 4, 0, DrvGfxROM1);
453 	}
454 }
455 
draw_fg_layer()456 static void draw_fg_layer()
457 {
458 	for (INT32 offs = 0; offs < 32 * 32; offs++)
459 	{
460 		INT32 sx = ((offs & 0x1f) * 8);
461 		INT32 sy = ((offs / 0x20) * 8) - 16;
462 
463 		if (sx >= nScreenWidth || sy >= nScreenHeight) continue;
464 
465 		INT32 code = DrvVidRAM0[offs];
466 
467 		Render8x8Tile_Mask_Clip(pTransDraw, code, sx, sy, 0, 4, 0, 0x20, DrvGfxROM0);
468 	}
469 }
470 
draw_sprites()471 static void draw_sprites()
472 {
473 	for (INT32 offs = 0x100-4; offs >= 0; offs -= 4 )
474 	{
475 		INT32 sy    = (240 - DrvSprRAM[offs]) - 16;
476 		INT32 sx    = DrvSprRAM[offs+3];
477 		INT32 attr  = DrvSprRAM[offs+2];
478 		INT32 code  =(DrvSprRAM[offs+1] & 0x3f) | ((attr & 0x40) << 1) | ((attr & 0x80) >> 1);
479 		INT32 flipy = DrvSprRAM[offs+1] & 0x80;
480 		INT32 flipx = DrvSprRAM[offs+1] & 0x40;
481 		INT32 color = attr & 0x07;
482 
483 		Draw16x16MaskTile(pTransDraw, code, sx, sy, flipx, flipy, color, 3, 0, 0x40, DrvGfxROM2);
484 	}
485 }
486 
DrvDraw()487 static INT32 DrvDraw()
488 {
489 	if (DrvRecalc) {
490 		DrvPaletteInit();
491 		DrvRecalc = 0;
492 	}
493 
494 	BurnTransferClear();
495 
496 	if (nBurnLayer & 1) draw_bg_layer();
497 	if (nBurnLayer & 2) draw_sprites();
498 	if (nBurnLayer & 4) draw_fg_layer();
499 
500 	BurnTransferCopy(DrvPalette);
501 
502 	return 0;
503 }
504 
DrvFrame()505 static INT32 DrvFrame()
506 {
507 	watchdog++;
508 	if (watchdog >= 180) {
509 		DrvDoReset(0);
510 	}
511 
512 	if (DrvReset) {
513 		DrvDoReset(1);
514 	}
515 
516 	/*  -- save until 100% sure colors jive well. --
517 	static UINT8 oldj = 0;
518 	static INT32 selektor = 0;
519 
520 	if (DrvJoy1[4] && oldj == 0) {
521 		selektor++;
522 	}
523 	if (counter!=0) DrvColPROM[0x40 + selektor] = counter;
524 	bprintf(0, _T("DrvColPROM[0x40 + %X] = %X.\n"), selektor, counter);
525 	oldj = DrvJoy1[4];
526 
527 	//    0x40 + 2 = windows in police car
528 	//         + 3 = tires
529 	//           5 = hubcaps
530 	//           6 = headlights
531 	//           7 = body
532 	//           8
533 	//           9 = police pants 0x99
534 	//           A = police coat    ""
535 	//           B = shoes/hair
536 	//           C = Holster/belt 0xa ?
537 	//           D = Face       0x1f
538 	//			 E = gun        0x58
539 	//           F = cuff       0x65
540 	//           10 = nothing
541 	//           11 = gang suit 0xf
542 	//           12 = gang face 0xb5
543 	//           13 = gang shoes 0x54
544 	//           14 = gang tie/knife 0xe1
545 	//           15 = killr shirt 0x50
546 	//           16 = gang shirt 0x5f
547 	//           17 = "" pants 0x64
548 	//           18 = ?
549 	//           19 = bomb clock 0xb
550 	//           1a = skull border 0x53
551 	//           1b = bomb wrapper 0xf
552 	//           1c = bomb border/wire, 0x80
553 	//           1d = clock hands 0x8
554 	//           1e = bomb wrapper 2 0xd
555 	//           1f = skull 0xae
556 	*/
557 
558 	ZetNewFrame();
559 
560 	{
561 		DrvInputs[0] = 0;
562 		DrvInputs[1] = 0x03;
563 		for (INT32 i = 0; i < 8; i++) {
564 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
565 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
566 		}
567 	}
568 
569 
570 
571 	INT32 nInterleave = 50; // 3000 hz
572 	INT32 nCyclesTotal[2] = { 5000000 / 60, 3072000 / 60 };
573 	INT32 nCyclesDone[2] = { 0, 0 };
574 
575 	for (INT32 i = 0; i < nInterleave; i++)
576 	{
577 		ZetOpen(0);
578 		CPU_RUN(0, Zet);
579 		if (i == (nInterleave - 1) && nmi_enable && nCurrentFrame & 1) ZetNmi();
580 		ZetClose();
581 
582 		ZetOpen(1);
583 		CPU_RUN(1, Zet);
584 		if (i == (nInterleave - 1)) ZetSetIRQLine(0, CPU_IRQSTATUS_AUTO);
585 		ZetClose();
586 	}
587 
588 	if (pBurnSoundOut) {
589 		AY8910Render(pBurnSoundOut, nBurnSoundLen);
590 	}
591 
592 	if (pBurnDraw) {
593 		DrvDraw();
594 	}
595 
596 	return 0;
597 }
598 
DrvScan(INT32 nAction,INT32 * pnMin)599 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
600 {
601 	struct BurnArea ba;
602 
603 	if (pnMin) {
604 		*pnMin = 0x029702;
605 	}
606 
607 	if (nAction & ACB_VOLATILE) {
608 		memset(&ba, 0, sizeof(ba));
609 		ba.Data	  = AllRam;
610 		ba.nLen	  = RamEnd - AllRam;
611 		ba.szName = "All Ram";
612 		BurnAcb(&ba);
613 
614 		ZetScan(nAction);
615 
616 		AY8910Scan(nAction, pnMin);
617 
618 		SCAN_VAR(soundlatch);
619 		SCAN_VAR(nmi_enable);
620 		SCAN_VAR(scrollx);
621 		SCAN_VAR(scrolly);
622 		SCAN_VAR(watchdog);
623 	}
624 
625 	return 0;
626 }
627 
628 
629 // Time Limit
630 
631 static struct BurnRomInfo timelimtRomDesc[] = {
632 	{ "t8",		0x2000, 0x006767ca, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 code
633 	{ "t7",		0x2000, 0xcbe7cd86, 1 | BRF_PRG | BRF_ESS }, //  1
634 	{ "t6",		0x2000, 0xf5f17e39, 1 | BRF_PRG | BRF_ESS }, //  2
635 	{ "t9",		0x2000, 0x2d72ab45, 1 | BRF_PRG | BRF_ESS }, //  3
636 
637 	{ "tl11",	0x1000, 0x46676307, 2 | BRF_GRA },           //  4 Foreground Tiles
638 	{ "tl10",	0x1000, 0x2336908a, 2 | BRF_GRA },           //  5
639 
640 	{ "tl13",	0x1000, 0x072e4053, 3 | BRF_GRA },           //  6 Background Tiles
641 	{ "tl12",	0x1000, 0xce960389, 3 | BRF_GRA },           //  7
642 
643 	{ "tl3",	0x2000, 0x01a9fd95, 4 | BRF_GRA },           //  8 Sprites
644 	{ "tl2",	0x2000, 0x4693b849, 4 | BRF_GRA },           //  9
645 	{ "tl1",	0x2000, 0xc4007caf, 4 | BRF_GRA },           // 10
646 
647 	{ "clr.35",	0x0020, 0x9c9e6073, 5 | BRF_GRA },           // 11 Color proms
648 	{ "clr.48",	0x0020, 0xa0bcac59, 5 | BRF_GRA },           // 12
649 	{ "clr.57",	0x0020, 0x3a9f5394, 5 | BRF_GRA },           // 13
650 
651 	{ "tl5",	0x1000, 0x5b782e4a, 6 | BRF_PRG | BRF_ESS }, // 14 Z80 #1 code
652 	{ "tl4",	0x1000, 0xa32883a9, 6 | BRF_PRG | BRF_ESS }, // 15
653 };
654 
655 STD_ROM_PICK(timelimt)
STD_ROM_FN(timelimt)656 STD_ROM_FN(timelimt)
657 
658 static INT32 TimelimtInit()
659 {
660 	TimelimtMode = 1;
661 
662 	return DrvInit();
663 }
664 
665 struct BurnDriver BurnDrvTimelimt = {
666 	"timelimt", NULL, NULL, NULL, "1983",
667 	"Time Limit\0", NULL, "Chuo Co. Ltd", "Miscellaneous",
668 	NULL, NULL, NULL, NULL,
669 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 1, HARDWARE_MISC_PRE90S, GBF_PLATFORM, 0,
670 	NULL, timelimtRomInfo, timelimtRomName, NULL, NULL, NULL, NULL, TimelimtInputInfo, TimelimtDIPInfo,
671 	TimelimtInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x60,
672 	224, 256, 3, 4
673 };
674 
675 
676 // Progress
677 
678 static struct BurnRomInfo progressRomDesc[] = {
679 	{ "pg8.bin",	0x2000, 0xe8779658, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 code
680 	{ "pg7.bin",	0x2000, 0x5dcf6b6f, 1 | BRF_PRG | BRF_ESS }, //  1
681 	{ "pg6.bin",	0x2000, 0xf21d2a08, 1 | BRF_PRG | BRF_ESS }, //  2
682 	{ "pg9.bin",	0x2000, 0x052ab4ac, 1 | BRF_PRG | BRF_ESS }, //  3
683 
684 	{ "pg11.bin",	0x1000, 0xbd8462e4, 2 | BRF_GRA },           //  4 Foreground Tiles
685 	{ "pg10.bin",	0x1000, 0xc4bbf0b8, 2 | BRF_GRA },           //  5
686 
687 	{ "pg13.bin",	0x1000, 0x25ec45be, 3 | BRF_GRA },           //  6 Background Tiles
688 	{ "pg12.bin",	0x1000, 0xc837c5f5, 3 | BRF_GRA },           //  7
689 
690 	{ "pg1.bin",	0x2000, 0x155c8f7f, 4 | BRF_GRA },           //  8 Sprites
691 	{ "pg2.bin",	0x2000, 0xa6ca4dfc, 4 | BRF_GRA },           //  9
692 	{ "pg3.bin",	0x2000, 0x2b21c2fb, 4 | BRF_GRA },           // 10
693 
694 	{ "35.bin",	0x0020, 0x8c5ca730, 5 | BRF_GRA },           // 11 Color proms
695 	{ "48.bin",	0x0020, 0x12dd62cd, 5 | BRF_GRA },           // 12
696 	{ "57.bin",	0x0020, 0x18455a79, 5 | BRF_GRA },           // 13
697 
698 	{ "pg4.bin",	0x1000, 0xb1cc2fe8, 6 | BRF_PRG | BRF_ESS }, // 14 Z80 #1 code
699 };
700 
701 STD_ROM_PICK(progress)
702 STD_ROM_FN(progress)
703 
704 struct BurnDriver BurnDrvProgress = {
705 	"progress", NULL, NULL, NULL, "1984",
706 	"Progress\0", NULL, "Chuo Co. Ltd", "Miscellaneous",
707 	NULL, NULL, NULL, NULL,
708 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 1, HARDWARE_MISC_PRE90S, GBF_VERSHOOT, 0,
709 	NULL, progressRomInfo, progressRomName, NULL, NULL, NULL, NULL, ProgressInputInfo, ProgressDIPInfo,
710 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x60,
711 	224, 256, 3, 4
712 };
713