1 // FB Alpha Clash Road / Fire Battle driver module
2 // Based on MAME driver by Luca Elia
3 
4 #include "tiles_generic.h"
5 #include "z80_intf.h"
6 #include "wiping.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 *DrvColPROM;
18 static UINT8 *DrvSndROM;
19 static UINT8 *DrvSndPROM;
20 static UINT8 *DrvZ80RAM0;
21 static UINT8 *DrvVidRAM0;
22 static UINT8 *DrvVidRAM1;
23 static UINT8 *DrvShareRAM;
24 static UINT8 *DrvSprRAM;
25 
26 static UINT32 *DrvPalette;
27 static UINT8 DrvRecalc;
28 
29 static UINT8 *irq_mask;
30 static UINT8 *video_regs;
31 static UINT8 flipscreen;
32 static UINT8 sound_reset;
33 
34 static INT32 nExtraCycles;
35 
36 static UINT8 DrvJoy1[8];
37 static UINT8 DrvJoy2[8];
38 static UINT8 DrvDips[2];
39 static UINT8 DrvInputs[8];
40 static UINT8 DrvReset;
41 
42 static struct BurnInputInfo ClshroadInputList[] = {
43 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 6,	"p1 coin"	},
44 	{"P1 Start",		BIT_DIGITAL,	DrvJoy2 + 6,	"p1 start"	},
45 	{"P1 Up",			BIT_DIGITAL,	DrvJoy1 + 0,	"p1 up"		},
46 	{"P1 Down",			BIT_DIGITAL,	DrvJoy1 + 1,	"p1 down"	},
47 	{"P1 Left",			BIT_DIGITAL,	DrvJoy1 + 2,	"p1 left"	},
48 	{"P1 Right",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 right"	},
49 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 fire 1"	},
50 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy1 + 4,	"p1 fire 2"	},
51 
52 	{"P2 Start",		BIT_DIGITAL,	DrvJoy2 + 7,	"p2 start"	},
53 	{"P2 Up",			BIT_DIGITAL,	DrvJoy2 + 0,	"p2 up"		},
54 	{"P2 Down",			BIT_DIGITAL,	DrvJoy2 + 1,	"p2 down"	},
55 	{"P2 Left",			BIT_DIGITAL,	DrvJoy2 + 2,	"p2 left"	},
56 	{"P2 Right",		BIT_DIGITAL,	DrvJoy2 + 3,	"p2 right"	},
57 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy2 + 5,	"p2 fire 1"	},
58 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy2 + 4,	"p2 fire 2"	},
59 
60 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
61 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
62 	{"Dip B",			BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
63 };
64 
65 STDINPUTINFO(Clshroad)
66 
67 static struct BurnInputInfo FirebatlInputList[] = {
68 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 6,	"p1 coin"	},
69 	{"P1 Start",		BIT_DIGITAL,	DrvJoy2 + 6,	"p1 start"	},
70 	{"P1 Up",			BIT_DIGITAL,	DrvJoy1 + 0,	"p1 up"		},
71 	{"P1 Down",			BIT_DIGITAL,	DrvJoy1 + 1,	"p1 down"	},
72 	{"P1 Left",			BIT_DIGITAL,	DrvJoy1 + 2,	"p1 left"	},
73 	{"P1 Right",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 right"	},
74 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy1 + 4,	"p1 fire 1"	},
75 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 fire 2"	},
76 
77 	{"P2 Start",		BIT_DIGITAL,	DrvJoy2 + 7,	"p2 start"	},
78 	{"P2 Up",			BIT_DIGITAL,	DrvJoy2 + 0,	"p2 up"		},
79 	{"P2 Down",			BIT_DIGITAL,	DrvJoy2 + 1,	"p2 down"	},
80 	{"P2 Left",			BIT_DIGITAL,	DrvJoy2 + 2,	"p2 left"	},
81 	{"P2 Right",		BIT_DIGITAL,	DrvJoy2 + 3,	"p2 right"	},
82 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy2 + 4,	"p2 fire 1"	},
83 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy2 + 5,	"p2 fire 2"	},
84 
85 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
86 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
87 	{"Dip B",			BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
88 };
89 
90 STDINPUTINFO(Firebatl)
91 
92 static struct BurnDIPInfo ClshroadDIPList[]=
93 {
94 	{0x10, 0xff, 0xff, 0xfb, NULL					},
95 	{0x11, 0xff, 0xff, 0xff, NULL					},
96 
97 	{0   , 0xfe, 0   ,    4, "Coinage"				},
98 	{0x10, 0x01, 0x03, 0x00, "3 Coins 1 Credits"	},
99 	{0x10, 0x01, 0x03, 0x01, "2 Coins 1 Credits"	},
100 	{0x10, 0x01, 0x03, 0x03, "1 Coin  1 Credits"	},
101 	{0x10, 0x01, 0x03, 0x02, "1 Coin  2 Credits"	},
102 
103 	{0   , 0xfe, 0   ,    2, "Cabinet"				},
104 	{0x10, 0x01, 0x04, 0x00, "Upright"				},
105 	{0x10, 0x01, 0x04, 0x04, "Cocktail"				},
106 
107 	{0   , 0xfe, 0   ,    4, "Difficulty"			},
108 	{0x10, 0x01, 0x18, 0x18, "Normal"				},
109 	{0x10, 0x01, 0x18, 0x10, "Hard"					},
110 	{0x10, 0x01, 0x18, 0x08, "Harder"				},
111 	{0x10, 0x01, 0x18, 0x00, "Hardest"				},
112 
113 	{0   , 0xfe, 0   ,    2, "Invulnerability"		},
114 	{0x10, 0x01, 0x20, 0x20, "Off"					},
115 	{0x10, 0x01, 0x20, 0x00, "On"					},
116 };
117 
118 STDDIPINFO(Clshroad)
119 
120 static struct BurnDIPInfo FirebatlDIPList[]=
121 {
122 	{0x10, 0xff, 0xff, 0x03, NULL					},
123 	{0x11, 0xff, 0xff, 0x13, NULL					},
124 
125 	{0   , 0xfe, 0   ,    8, "Lives"				},
126 	{0x10, 0x01, 0x7f, 0x00, "1"					},
127 	{0x10, 0x01, 0x7f, 0x01, "2"					},
128 	{0x10, 0x01, 0x7f, 0x03, "3"					},
129 	{0x10, 0x01, 0x7f, 0x07, "4"					},
130 	{0x10, 0x01, 0x7f, 0x0f, "5"					},
131 	{0x10, 0x01, 0x7f, 0x1f, "6"					},
132 	{0x10, 0x01, 0x7f, 0x3f, "7"					},
133 	{0x10, 0x01, 0x7f, 0x7f, "Infinite Lives"		},
134 
135 	{0   , 0xfe, 0   ,    4, "Coinage"				},
136 	{0x11, 0x01, 0x03, 0x00, "3 Coins 1 Credits"	},
137 	{0x11, 0x01, 0x03, 0x01, "2 Coins 1 Credits"	},
138 	{0x11, 0x01, 0x03, 0x03, "1 Coin  1 Credits"	},
139 	{0x11, 0x01, 0x03, 0x02, "1 Coin  2 Credits"	},
140 
141 	{0   , 0xfe, 0   ,    2, "Cabinet"				},
142 	{0x11, 0x01, 0x04, 0x00, "Upright"				},
143 	{0x11, 0x01, 0x04, 0x04, "Cocktail"				},
144 
145 	{0   , 0xfe, 0   ,    2, "Demo Sounds"			},
146 	{0x11, 0x01, 0x08, 0x08, "Off"					},
147 	{0x11, 0x01, 0x08, 0x00, "On"					},
148 
149 	{0   , 0xfe, 0   ,    2, "Bonus Life"			},
150 	{0x11, 0x01, 0x10, 0x10, "10K 30K+"				},
151 	{0x11, 0x01, 0x10, 0x00, "20K 30K+"				},
152 };
153 
STDDIPINFO(Firebatl)154 STDDIPINFO(Firebatl)
155 
156 static void __fastcall clshroad_main_write(UINT16 address, UINT8 data)
157 {
158 	switch (address)
159 	{
160 		case 0xa000:
161 			sound_reset = ~data & 1;
162 			if (sound_reset ) {
163 				INT32 active = ZetGetActive();
164 				ZetClose();
165 				ZetOpen(1);
166 				ZetReset();
167 				ZetClose();
168 				ZetOpen(active);
169 			}
170 		return;
171 
172 		case 0xa001:
173 			irq_mask[0] = data & 1;
174 		return;
175 
176 		case 0xa003:
177 			irq_mask[1] = data & 1;
178 		return;
179 
180 		case 0xa004:
181 			flipscreen = data & 1;
182 		return;
183 
184 		case 0xb000:
185 		case 0xb001:
186 		case 0xb002:
187 		case 0xb003:
188 			video_regs[address & 3] = data;
189 		return;
190 	}
191 }
192 
clshroad_main_read(UINT16 address)193 static UINT8 __fastcall clshroad_main_read(UINT16 address)
194 {
195 	if ((address & 0xfff8) == 0xa100) {
196 		return DrvInputs[address & 7];
197 	}
198 
199 	return 0;
200 }
201 
clshroad_sound_write(UINT16 address,UINT8 data)202 static void __fastcall clshroad_sound_write(UINT16 address, UINT8 data)
203 {
204 	if ((address & 0xc000) == 0x4000) {
205 		wipingsnd_write(address, data);
206 		return;
207 	}
208 
209 	if ((address & 0xfff8) == 0xa000) {
210 		clshroad_main_write(address, data);
211 		return;
212 	}
213 }
214 
tilemap_scan(bg)215 static tilemap_scan( bg )
216 {
217 	return (col + (row * 64)) * 2;
218 }
219 
tilemap_callback(bg)220 static tilemap_callback( bg )
221 {
222 	TILE_SET_INFO(0, DrvVidRAM0[offs + 0x40], 0, 0);
223 }
224 
tilemap_callback(mg)225 static tilemap_callback( mg )
226 {
227 	TILE_SET_INFO(0, DrvVidRAM0[offs + 0x00], 0, 0);
228 }
229 
tilemap_scan(fg)230 static tilemap_scan( fg )
231 {
232 	if (col <=  1) return row + (col + 30) * 0x20;
233 	if (col >= 34) return row + (col - 34) * 0x20;
234 	if (row <=  1 || row >= 30) return 0;
235 
236 	return (col - 2) + row * 32;
237 }
238 
tilemap_callback(fg)239 static tilemap_callback( fg )
240 {
241 	UINT8 attr = DrvVidRAM1[offs + 0x400];
242 
243 	TILE_SET_INFO(1, DrvVidRAM1[offs] + ((attr & 0x10) << 4), attr, 0);
244 	*category = attr & 0x3f;
245 }
246 
DrvDoReset()247 static INT32 DrvDoReset()
248 {
249 	memset (AllRam, 0, RamEnd - AllRam);
250 
251 	memset (DrvVidRAM0, 0xf0, 0x800); // firebatl does not clear this on init
252 
253 	ZetOpen(0);
254 	ZetReset();
255 	ZetClose();
256 
257 	ZetOpen(1);
258 	ZetReset();
259 	ZetClose();
260 
261 	wipingsnd_reset();
262 
263 	flipscreen = 0;
264 	sound_reset = 0;
265 
266 	nExtraCycles = 0;
267 
268 	return 0;
269 }
270 
MemIndex()271 static INT32 MemIndex()
272 {
273 	UINT8 *Next; Next = AllMem;
274 
275 	DrvZ80ROM0		= Next; Next += 0x008000;
276 	DrvZ80ROM1		= Next; Next += 0x002000;
277 
278 	DrvGfxROM0		= Next; Next += 0x010000;
279 	DrvGfxROM1		= Next; Next += 0x010000;
280 	DrvGfxROM2		= Next; Next += 0x008000;
281 
282 	DrvColPROM		= Next; Next += 0x000500;
283 
284 	DrvSndROM		= Next; Next += 0x002000;
285 	DrvSndPROM		= Next; Next += 0x000200;
286 
287 	DrvPalette		= (UINT32*)Next; Next += 0x0200 * sizeof(UINT32);
288 
289 	AllRam			= Next;
290 
291 	DrvZ80RAM0		= Next; Next += 0x002000;
292 	DrvVidRAM0		= Next; Next += 0x000800;
293 	DrvVidRAM1		= Next; Next += 0x000800;
294 	DrvShareRAM		= Next; Next += 0x000200;
295 	DrvSprRAM		= Next; Next += 0x000200;
296 
297 	irq_mask		= Next; Next += 0x000002;
298 	video_regs		= Next; Next += 0x000004;
299 
300 	RamEnd			= Next;
301 
302 	MemEnd			= Next;
303 
304 	return 0;
305 }
306 
DrvGfxDecode()307 static INT32 DrvGfxDecode()
308 {
309 	INT32 Plane[4]  = { 0x4000 * 8 + 0, 0x4000 * 8 + 4, 0, 4 };
310 	INT32 XOffs[16] = { STEP4(0,1), STEP4(8,1), STEP4(128,1), STEP4(128+8,1) };
311 	INT32 YOffs[16] = { STEP8(0,16), STEP8(256,16) };
312 
313 	UINT8 *tmp = (UINT8*)BurnMalloc(0x8000);
314 	if (tmp == NULL) {
315 		return 1;
316 	}
317 
318 	memcpy (tmp, DrvGfxROM0, 0x8000);
319 
320 	GfxDecode(0x0100, 4, 16, 16, Plane, XOffs, YOffs, 0x200, tmp, DrvGfxROM0);
321 
322 	memcpy (tmp, DrvGfxROM1, 0x8000);
323 
324 	GfxDecode(0x0100, 4, 16, 16, Plane, XOffs, YOffs, 0x200, tmp, DrvGfxROM1);
325 
326 	memcpy (tmp, DrvGfxROM2, 0x8000);
327 
328 	GfxDecode(0x0200, 4,  8,  8, Plane, XOffs, YOffs, 0x080, tmp, DrvGfxROM2);
329 
330 	BurnFree(tmp);
331 
332 	return 0;
333 }
334 
DrvInit(INT32 game_select)335 static INT32 DrvInit(INT32 game_select)
336 {
337 	AllMem = NULL;
338 	MemIndex();
339 	INT32 nLen = MemEnd - (UINT8 *)0;
340 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
341 	memset(AllMem, 0, nLen);
342 	MemIndex();
343 
344 	{
345 		if (game_select == 0) // firebatl
346 		{
347 			if (BurnLoadRom(DrvZ80ROM0		+ 0x0000,  0, 1)) return 1;
348 			if (BurnLoadRom(DrvZ80ROM0		+ 0x2000,  1, 1)) return 1;
349 			if (BurnLoadRom(DrvZ80ROM0		+ 0x4000,  2, 1)) return 1;
350 
351 			if (BurnLoadRom(DrvZ80ROM1		+ 0x0000,  3, 1)) return 1;
352 
353 			if (BurnLoadRomExt(DrvGfxROM0	+ 0x0000,  4, 1, LD_INVERT)) return 1;
354 			if (BurnLoadRomExt(DrvGfxROM0	+ 0x2000,  5, 1, LD_INVERT)) return 1;
355 			if (BurnLoadRomExt(DrvGfxROM0	+ 0x4000,  6, 1, LD_INVERT)) return 1;
356 			if (BurnLoadRomExt(DrvGfxROM0	+ 0x6000,  7, 1, LD_INVERT)) return 1;
357 
358 			if (BurnLoadRomExt(DrvGfxROM1	+ 0x0000,  8, 1, LD_INVERT)) return 1;
359 			if (BurnLoadRomExt(DrvGfxROM1	+ 0x2000,  9, 1, LD_INVERT)) return 1;
360 			if (BurnLoadRomExt(DrvGfxROM1	+ 0x4000, 10, 1, LD_INVERT)) return 1;
361 			if (BurnLoadRomExt(DrvGfxROM1	+ 0x6000, 11, 1, LD_INVERT)) return 1;
362 
363 			if (BurnLoadRom(DrvGfxROM2	    + 0x0000, 12, 1)) return 1;
364 
365 			if (BurnLoadRom(DrvColPROM		+ 0x0000, 13, 1)) return 1;
366 			if (BurnLoadRom(DrvColPROM		+ 0x0100, 14, 1)) return 1;
367 			if (BurnLoadRom(DrvColPROM		+ 0x0200, 15, 1)) return 1;
368 			if (BurnLoadRom(DrvColPROM		+ 0x0300, 16, 1)) return 1;
369 			if (BurnLoadRom(DrvColPROM		+ 0x0400, 17, 1)) return 1;
370 
371 			if (BurnLoadRom(DrvSndROM		+ 0x0000, 18, 1)) return 1;
372 
373 			if (BurnLoadRom(DrvSndPROM		+ 0x0000, 19, 1)) return 1;
374 			if (BurnLoadRom(DrvSndPROM		+ 0x0100, 20, 1)) return 1;
375 		}
376 		else if (game_select == 1) // clshroad
377 		{
378 			if (BurnLoadRom(DrvZ80ROM0		+ 0x0000,  0, 1)) return 1;
379 
380 			if (BurnLoadRom(DrvZ80ROM1		+ 0x0000,  1, 1)) return 1;
381 
382 			if (BurnLoadRomExt(DrvGfxROM0	+ 0x0000,  2, 1, LD_INVERT)) return 1;
383 			if (BurnLoadRomExt(DrvGfxROM0	+ 0x4000,  3, 1, LD_INVERT)) return 1;
384 
385 			if (BurnLoadRomExt(DrvGfxROM1	+ 0x0000,  4, 1, LD_INVERT)) return 1;
386 			if (BurnLoadRomExt(DrvGfxROM1	+ 0x4000,  5, 1, LD_INVERT)) return 1;
387 
388 			if (BurnLoadRomExt(DrvGfxROM2	+ 0x0000,  6, 1, LD_INVERT)) return 1;
389 			if (BurnLoadRomExt(DrvGfxROM2	+ 0x4000,  7, 1, LD_INVERT)) return 1;
390 
391 			if (BurnLoadRom(DrvColPROM		+ 0x0000,  8, 1)) return 1;
392 			if (BurnLoadRom(DrvColPROM		+ 0x0100,  9, 1)) return 1;
393 			if (BurnLoadRom(DrvColPROM		+ 0x0200, 10, 1)) return 1;
394 
395 			if (BurnLoadRom(DrvSndROM		+ 0x0000, 11, 1)) return 1;
396 
397 			if (BurnLoadRom(DrvSndPROM		+ 0x0000, 12, 1)) return 1;
398 			if (BurnLoadRom(DrvSndPROM		+ 0x0100, 13, 1)) return 1;
399 		}
400 		else if (game_select == 2) // clshroads
401 		{
402 			if (BurnLoadRom(DrvZ80ROM0		+ 0x0000,  0, 1)) return 1;
403 
404 			if (BurnLoadRom(DrvZ80ROM1		+ 0x0000,  1, 1)) return 1;
405 
406 			if (BurnLoadRomExt(DrvGfxROM0	+ 0x0000,  2, 1, LD_INVERT)) return 1;
407 			if (BurnLoadRomExt(DrvGfxROM0	+ 0x2000,  3, 1, LD_INVERT)) return 1;
408 			if (BurnLoadRomExt(DrvGfxROM0	+ 0x4000,  4, 1, LD_INVERT)) return 1;
409 			if (BurnLoadRomExt(DrvGfxROM0	+ 0x6000,  5, 1, LD_INVERT)) return 1;
410 
411 			if (BurnLoadRomExt(DrvGfxROM1	+ 0x0000,  6, 1, LD_INVERT)) return 1;
412 			if (BurnLoadRomExt(DrvGfxROM1	+ 0x2000,  7, 1, LD_INVERT)) return 1;
413 			if (BurnLoadRomExt(DrvGfxROM1	+ 0x4000,  8, 1, LD_INVERT)) return 1;
414 			if (BurnLoadRomExt(DrvGfxROM1	+ 0x6000,  9, 1, LD_INVERT)) return 1;
415 
416 			if (BurnLoadRomExt(DrvGfxROM2	+ 0x0000, 10, 1, LD_INVERT)) return 1;
417 			if (BurnLoadRomExt(DrvGfxROM2	+ 0x4000, 11, 1, LD_INVERT)) return 1;
418 
419 			if (BurnLoadRom(DrvColPROM		+ 0x0000, 12, 1)) return 1;
420 			if (BurnLoadRom(DrvColPROM		+ 0x0100, 13, 1)) return 1;
421 			if (BurnLoadRom(DrvColPROM		+ 0x0200, 14, 1)) return 1;
422 
423 			if (BurnLoadRom(DrvSndROM		+ 0x0000, 15, 1)) return 1;
424 
425 			if (BurnLoadRom(DrvSndPROM		+ 0x0000, 16, 1)) return 1;
426 			if (BurnLoadRom(DrvSndPROM		+ 0x0100, 17, 1)) return 1;
427 		}
428 
429 		for (INT32 i = 0; i < 0x300; i++) { // colors 4bit->8bit
430 			DrvColPROM[i] = (DrvColPROM[i] & 0xf) | (DrvColPROM[i] << 4);
431 		}
432 
433 		for (INT32 i = 0x300; i < 0x400; i++) { // lut merge nibbles
434 			DrvColPROM[i] = (DrvColPROM[i] << 4) | (DrvColPROM[i + 0x100] & 0xf);
435 		}
436 
437 		DrvGfxDecode();
438 	}
439 
440 	ZetInit(0);
441 	ZetOpen(0);
442 	ZetMapMemory(DrvZ80ROM0,		0x0000, 0x7fff, MAP_ROM);
443 	ZetMapMemory(DrvZ80RAM0,		0x8000, 0x9fff, MAP_RAM);
444 	ZetMapMemory(DrvShareRAM,		0x9600, 0x97ff, MAP_RAM);
445 	ZetMapMemory(DrvSprRAM,			0x9e00, 0x9fff, MAP_RAM);
446 	ZetMapMemory(DrvVidRAM1,		0xa800, 0xafff, MAP_RAM);
447 	ZetMapMemory(DrvVidRAM0,		0xc000, 0xc7ff, MAP_RAM);
448 	ZetSetWriteHandler(clshroad_main_write);
449 	ZetSetReadHandler(clshroad_main_read);
450 	ZetClose();
451 
452 	ZetInit(1);
453 	ZetOpen(1);
454 	ZetMapMemory(DrvZ80ROM1,		0x0000, 0x1fff, MAP_ROM);
455 	ZetMapMemory(DrvShareRAM,		0x9600, 0x97ff, MAP_RAM);
456 	ZetSetWriteHandler(clshroad_sound_write);
457 	ZetClose();
458 
459 	wipingsnd_init(DrvSndROM, DrvSndPROM);
460 
461 	GenericTilesInit();
462 	GenericTilemapInit(0, bg_map_scan, bg_map_callback, 16, 16, 32, 16);
463 	GenericTilemapInit(1, bg_map_scan, mg_map_callback, 16, 16, 32, 16);
464 	GenericTilemapInit(2, fg_map_scan, fg_map_callback,  8,  8, 36, 32);
465 	GenericTilemapSetOffsets(2,   0, -16);
466 
467 	if (game_select == 0) // firebatl
468 	{
469 		GenericTilemapSetGfx(0, DrvGfxROM1, 4, 16, 16, 0x10000, 0x010, 0x00);
470 		GenericTilemapSetGfx(1, DrvGfxROM2, 2,  8,  8, 0x04000, 0x100, 0x3f);
471 		GenericTilemapSetOffsets(0, -42, -16);
472 		GenericTilemapSetOffsets(1, -42, -16);
473 		GenericTilemapSetTransparent(1, 0);
474 
475 		GenericTilemapCategoryConfig(2, 0x40);
476 		for (INT32 i = 0; i < 0x40; i++)
477 		{
478 			for (INT32 j = 0; j < 4; j++)
479 			{
480 				GenericTilemapSetCategoryEntry(2, i, j, DrvColPROM[0x300 + (i * 4) + j] == 0xf);
481 			}
482 		}
483 	}
484 	else // clash
485 	{
486 		GenericTilemapSetGfx(0, DrvGfxROM1, 4, 16, 16, 0x10000, 0x090, 0x00);
487 		GenericTilemapSetGfx(1, DrvGfxROM2, 4,  8,  8, 0x08000, 0x000, 0x0f);
488 		GenericTilemapSetTransparent(1, 0xf);
489 		GenericTilemapSetTransparent(2, 0xf);
490 		GenericTilemapSetOffsets(0, -48, -16);
491 		GenericTilemapSetOffsets(1, -48, -16);
492 	}
493 
494 	DrvDoReset();
495 
496 	return 0;
497 }
498 
DrvExit()499 static INT32 DrvExit()
500 {
501 	GenericTilesExit();
502 
503 	ZetExit();
504 	wipingsnd_exit();
505 
506 	BurnFree(AllMem);
507 
508 	return 0;
509 }
510 
DrvPaletteInit()511 static void DrvPaletteInit()
512 {
513 	for (INT32 i = 0; i < 0x100; i++) {
514 		DrvPalette[i] = BurnHighCol(DrvColPROM[0x000 + i], DrvColPROM[0x100 + i], DrvColPROM[0x200 + i], 0);
515 	}
516 
517 	for (INT32 i = 0; i < 0x100; i++) { // firebatl
518 		DrvPalette[0x100 + i] = DrvPalette[DrvColPROM[0x300 + i]];
519 	}
520 }
521 
DrvSpriteDraw()522 static void DrvSpriteDraw()
523 {
524 	for (INT32 i = 0; i < 0x200; i += 8)
525 	{
526 		INT32 sy	=  DrvSprRAM[i+1];
527 		INT32 sx	=  DrvSprRAM[i+5] + (DrvSprRAM[i+6] << 8);
528 		INT32 code	= (DrvSprRAM[i+3] & 0x3f) + (DrvSprRAM[i+2] << 6);
529 		INT32 color	=  DrvSprRAM[i+7] & 0xf;
530 
531 		if (flipscreen) {
532 			Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code & 0xff, sx - 37, sy - 16, color, 4, 0xf, 0, DrvGfxROM0);
533 		} else {
534 			Render16x16Tile_Mask_Clip(pTransDraw, code & 0xff, sx - 37, (240 - sy) - 16, color, 4, 0xf, 0, DrvGfxROM0);
535 		}
536 	}
537 }
538 
DrvDraw()539 static INT32 DrvDraw()
540 {
541 	if (DrvRecalc) {
542 		DrvPaletteInit();
543 		DrvRecalc = 0;
544 	}
545 
546 	INT32 scrollx = video_regs[0] + (video_regs[1] << 8);
547 
548 	GenericTilemapSetScrollX(0, scrollx);
549 	GenericTilemapSetScrollX(1, scrollx);
550 
551 	GenericTilemapSetFlip(TMAP_GLOBAL, flipscreen ? TMAP_FLIPXY : 0);
552 
553 	if ((nBurnLayer & 1) == 0) BurnTransferClear();
554 
555 	if ((nBurnLayer & 1) != 0) GenericTilemapDraw(0, pTransDraw, 0);
556 	if ((nBurnLayer & 2) != 0) GenericTilemapDraw(1, pTransDraw, 0);
557 
558 	if ((nSpriteEnable & 1) != 0) DrvSpriteDraw();
559 
560 	if ((nBurnLayer & 4) != 0) GenericTilemapDraw(2, pTransDraw, 0);
561 
562 	BurnTransferCopy(DrvPalette);
563 
564 	return 0;
565 }
566 
DrvFrame()567 static INT32 DrvFrame()
568 {
569 	if (DrvReset) {
570 		DrvDoReset();
571 	}
572 
573 	{
574 		for (INT32 i = 0; i < 8; i++) {
575 			DrvInputs[i]  =  ( DrvJoy1[i] & 1) << 0;
576 			DrvInputs[i] |=  ( DrvJoy2[i] & 1) << 1;
577 			DrvInputs[i] |= ((~DrvDips[0] >> i) & 1) << 2;
578 			DrvInputs[i] |= ((~DrvDips[1] >> i) & 1) << 3;
579 		}
580 	}
581 
582 	INT32 nInterleave = 256;
583 	INT32 nCyclesTotal[2] = { 3686400 / 60, 3686400 / 60 };
584 	INT32 nCyclesDone[2] = { nExtraCycles, 0 };
585 
586 	INT32 nSndIRQ = (BurnDrvGetFlags() & BDF_ORIENTATION_VERTICAL) ? 127 : 255; // firebatl 2x / frame, clsroad 1x
587 
588 	for (INT32 i = 0; i < nInterleave; i++)
589 	{
590 		ZetOpen(0);
591 		nCyclesDone[0] += ZetRun((nCyclesTotal[0] * (i + 1) / nInterleave) - nCyclesDone[0]);
592 		if (i == 240) {
593 			if (irq_mask[0]) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
594 
595 			if (pBurnDraw) { // broken sprites on bike legs/pedals when street is on an incline fixed by drawing here
596 				BurnDrvRedraw();
597 			}
598 		}
599 		INT32 nCycles = ZetTotalCycles();
600 		ZetClose();
601 
602 		ZetOpen(1);
603 		if (sound_reset == 0) {
604 			nCyclesDone[1] += ZetRun(nCycles - ZetTotalCycles());
605 			if ((i & nSndIRQ) == nSndIRQ && irq_mask[1]) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
606 		} else {
607 			nCyclesDone[1] += (nCycles - ZetTotalCycles());
608 			ZetIdle(nCycles - ZetTotalCycles());
609 		}
610 		ZetClose();
611 	}
612 
613 	nExtraCycles = nCyclesDone[0] - nCyclesTotal[0];
614 
615 	if (pBurnSoundOut) {
616 		wipingsnd_update(pBurnSoundOut, nBurnSoundLen);
617 	}
618 
619 	return 0;
620 }
621 
DrvScan(INT32 nAction,INT32 * pnMin)622 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
623 {
624 	struct BurnArea ba;
625 
626 	if (pnMin) {
627 		*pnMin = 0x029702;
628 	}
629 
630 	if (nAction & ACB_VOLATILE) {
631 		memset(&ba, 0, sizeof(ba));
632 
633 		ba.Data	  = AllRam;
634 		ba.nLen	  = RamEnd - AllRam;
635 		ba.szName = "All Ram";
636 		BurnAcb(&ba);
637 
638 		ZetScan(nAction);
639 		wipingsnd_scan(nAction, pnMin);
640 
641 		SCAN_VAR(flipscreen);
642 		SCAN_VAR(sound_reset);
643 	}
644 
645 	return 0;
646 }
647 
648 
649 // Fire Battle
650 
651 static struct BurnRomInfo firebatlRomDesc[] = {
652 	{ "rom01.e8",		0x2000, 0x10e24ef6, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
653 	{ "rom02.d8",		0x2000, 0x47f79bee, 1 | BRF_PRG | BRF_ESS }, //  1
654 	{ "rom03.c8",		0x2000, 0x693459b9, 1 | BRF_PRG | BRF_ESS }, //  2
655 
656 	{ "rom04.r6",		0x2000, 0x5f232d9a, 2 | BRF_PRG | BRF_ESS }, //  3 Z80 #1 Code
657 
658 	{ "rom14.f4",		0x2000, 0x36a508a7, 3 | BRF_GRA },           //  4 Sprites
659 	{ "rom13.h4",		0x2000, 0xa2ec508e, 3 | BRF_GRA },           //  5
660 	{ "rom12.j4",		0x2000, 0xf80ece92, 3 | BRF_GRA },           //  6
661 	{ "rom11.k4",		0x2000, 0xb293e701, 3 | BRF_GRA },           //  7
662 
663 	{ "rom09.n4",		0x2000, 0x77ea3e39, 4 | BRF_GRA },           //  8 Background Tiles
664 	{ "rom08.p4",		0x2000, 0x1b7585dd, 4 | BRF_GRA },           //  9
665 	{ "rom07.s4",		0x2000, 0xe3ec9825, 4 | BRF_GRA },           // 10
666 	{ "rom06.u4",		0x2000, 0xd29fab5f, 4 | BRF_GRA },           // 11
667 
668 	{ "rom15.m4",		0x1000, 0x8b5464d6, 5 | BRF_GRA },           // 12 Foreground Tiles
669 
670 	{ "prom6.h1",		0x0100, 0xb117d22c, 6 | BRF_GRA },           // 13 Color data
671 	{ "prom7.f1",		0x0100, 0x9b6b4f56, 6 | BRF_GRA },           // 14
672 	{ "prom8.e1",		0x0100, 0x67cb68ae, 6 | BRF_GRA },           // 15
673 	{ "prom9.p2",		0x0100, 0xdd015b80, 6 | BRF_GRA },           // 16
674 	{ "prom10.n2",		0x0100, 0x71b768c7, 6 | BRF_GRA },           // 17
675 
676 	{ "rom05.f3",		0x2000, 0x21544cd6, 7 | BRF_SND },           // 18 Samples
677 
678 	{ "prom3.j4",		0x0100, 0xbd2c080b, 8 | BRF_GRA },           // 19 Sample PROMs
679 	{ "prom2.k2",		0x0100, 0x4017a2a6, 8 | BRF_GRA },           // 20
680 
681 	{ "prom4.s1",		0x0100, 0x06523b81, 0 | BRF_OPT },           // 21 Unused PROMs
682 	{ "prom5.p1",		0x0100, 0x75ea8f70, 0 | BRF_OPT },           // 22
683 	{ "prom11.m2",		0x0100, 0xba42a582, 0 | BRF_OPT },           // 23
684 	{ "prom12.h2",		0x0100, 0xf2540c51, 0 | BRF_OPT },           // 24
685 	{ "prom13.w8",		0x0100, 0x4e2a2781, 0 | BRF_OPT },           // 25
686 	{ "prom1.n2",		0x0020, 0x1afc04f0, 0 | BRF_OPT },           // 26
687 };
688 
689 STD_ROM_PICK(firebatl)
STD_ROM_FN(firebatl)690 STD_ROM_FN(firebatl)
691 
692 static void FirebatlPatch()
693 {
694 	// Without this the death sequence never ends so the game is unplayable after you die once,
695 	DrvZ80ROM0[0x05C6] = 0xc3;
696 	DrvZ80ROM0[0x05C7] = 0x8d;
697 	DrvZ80ROM0[0x05C8] = 0x23;
698 }
699 
FirebatlInit()700 static INT32 FirebatlInit()
701 {
702 	INT32 nRet = DrvInit(0);
703 
704 	if (nRet == 0)
705 	{
706 		FirebatlPatch();
707 	}
708 
709 	return nRet;
710 }
711 
712 struct BurnDriver BurnDrvFirebatl = {
713 	"firebatl", NULL, NULL, NULL, "1984",
714 	"Fire Battle\0", NULL, "Wood Place Inc. (Taito license)", "Miscellaneous",
715 	NULL, NULL, NULL, NULL,
716 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, GBF_VERSHOOT, 0,
717 	NULL, firebatlRomInfo, firebatlRomName, NULL, NULL, NULL, NULL, FirebatlInputInfo, FirebatlDIPInfo,
718 	FirebatlInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
719 	224, 288, 3, 4
720 };
721 
722 
723 // Clash-Road
724 
725 static struct BurnRomInfo clshroadRomDesc[] = {
726 	{ "clashr3.bin",	0x8000, 0x865c32ae, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
727 
728 	{ "clashr2.bin",	0x2000, 0xe6389ec1, 2 | BRF_PRG | BRF_ESS }, //  1 Z80 #1 Code
729 
730 	{ "clashr5.bin",	0x4000, 0x094858b8, 3 | BRF_GRA },           //  2 Sprites
731 	{ "clashr6.bin",	0x4000, 0xdaa1daf3, 3 | BRF_GRA },           //  3
732 
733 	{ "clashr8.bin",	0x4000, 0xcbb66719, 4 | BRF_GRA },           //  4 Background Tiles
734 	{ "clashr9.bin",	0x4000, 0xc15e8eed, 4 | BRF_GRA },           //  5
735 
736 	{ "clashr4.bin",	0x2000, 0x664201d9, 5 | BRF_GRA },           //  6 Foreground Tiles
737 	{ "clashr7.bin",	0x2000, 0x97973030, 5 | BRF_GRA },           //  7
738 
739 	{ "82s129.6",		0x0100, 0x38f443da, 6 | BRF_GRA },           //  8 Color data
740 	{ "82s129.7",		0x0100, 0x977fab0c, 6 | BRF_GRA },           //  9
741 	{ "82s129.8",		0x0100, 0xae7ae54d, 6 | BRF_GRA },           // 10
742 
743 	{ "clashr1.bin",	0x2000, 0x0d0a8068, 7 | BRF_SND },           // 11 Samples
744 
745 	{ "clashrd.g8",		0x0100, 0xbd2c080b, 8 | BRF_GRA },           // 12 Sample PROMs
746 	{ "clashrd.g7",		0x0100, 0x4017a2a6, 8 | BRF_GRA },           // 13
747 
748 	{ "clashrd.a2",		0x0100, 0x4e2a2781, 0 | BRF_OPT },           // 14 Unused PROMs
749 	{ "clashrd.g4",		0x0020, 0x1afc04f0, 0 | BRF_OPT },           // 15
750 	{ "clashrd.b11",	0x0020, 0xd453f2c5, 0 | BRF_OPT },           // 16
751 	{ "clashrd.g10",	0x0100, 0x73afefd0, 0 | BRF_OPT },           // 17
752 };
753 
754 STD_ROM_PICK(clshroad)
STD_ROM_FN(clshroad)755 STD_ROM_FN(clshroad)
756 
757 static INT32 ClshroadInit()
758 {
759 	return DrvInit(1);
760 }
761 
762 struct BurnDriver BurnDrvClshroad = {
763 	"clshroad", NULL, NULL, NULL, "1986",
764 	"Clash-Road\0", NULL, "Wood Place Inc.", "Miscellaneous",
765 	NULL, NULL, NULL, NULL,
766 	BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_RACING, 0,
767 	NULL, clshroadRomInfo, clshroadRomName, NULL, NULL, NULL, NULL, ClshroadInputInfo, ClshroadDIPInfo,
768 	ClshroadInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
769 	288, 224, 4, 3
770 };
771 
772 
773 // Clash-Road (Data East license)
774 
775 static struct BurnRomInfo clshroaddRomDesc[] = {
776 	{ "crdeco-3.bin",	0x8000, 0x1d54195c, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
777 
778 	{ "clashr2.bin",	0x2000, 0xe6389ec1, 2 | BRF_PRG | BRF_ESS }, //  1 Z80 #1 Code
779 
780 	{ "clashr5.bin",	0x4000, 0x094858b8, 3 | BRF_GRA },           //  2 Sprites
781 	{ "clashr6.bin",	0x4000, 0xdaa1daf3, 3 | BRF_GRA },           //  3
782 
783 	{ "clashr8.bin",	0x4000, 0xcbb66719, 4 | BRF_GRA },           //  4 Background Tiles
784 	{ "clashr9.bin",	0x4000, 0xc15e8eed, 4 | BRF_GRA },           //  5
785 
786 	{ "clashr4.bin",	0x2000, 0x664201d9, 5 | BRF_GRA },           //  6 Foreground Tiles
787 	{ "clashr7.bin",	0x2000, 0x97973030, 5 | BRF_GRA },           //  7
788 
789 	{ "82s129.6",		0x0100, 0x38f443da, 6 | BRF_GRA },           //  8 Color data
790 	{ "82s129.7",		0x0100, 0x977fab0c, 6 | BRF_GRA },           //  9
791 	{ "82s129.8",		0x0100, 0xae7ae54d, 6 | BRF_GRA },           // 10
792 
793 	{ "clashr1.bin",	0x2000, 0x0d0a8068, 7 | BRF_SND },           // 11 Samples
794 
795 	{ "clashrd.g8",		0x0100, 0xbd2c080b, 8 | BRF_GRA },           // 12 Sample PROMs
796 	{ "clashrd.g7",		0x0100, 0x4017a2a6, 8 | BRF_GRA },           // 13
797 
798 	{ "clashrd.a2",		0x0100, 0x4e2a2781, 0 | BRF_OPT },           // 14 Unused PROMs
799 	{ "clashrd.g4",		0x0020, 0x1afc04f0, 0 | BRF_OPT },           // 15
800 	{ "clashrd.b11",	0x0020, 0xd453f2c5, 0 | BRF_OPT },           // 16
801 	{ "clashrd.g10",	0x0100, 0x73afefd0, 0 | BRF_OPT },           // 17
802 };
803 
804 STD_ROM_PICK(clshroadd)
805 STD_ROM_FN(clshroadd)
806 
807 struct BurnDriver BurnDrvClshroadd = {
808 	"clshroadd", "clshroad", NULL, NULL, "1986",
809 	"Clash-Road (Data East license)\0", NULL, "Wood Place Inc. (Data East license)", "Miscellaneous",
810 	NULL, NULL, NULL, NULL,
811 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, GBF_RACING, 0,
812 	NULL, clshroaddRomInfo, clshroaddRomName, NULL, NULL, NULL, NULL, ClshroadInputInfo, ClshroadDIPInfo,
813 	ClshroadInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
814 	288, 224, 4, 3
815 };
816 
817 
818 // Clash-Road (Status license)
819 
820 static struct BurnRomInfo clshroadsRomDesc[] = {
821 	{ "cr-3",			0x8000, 0x23559df2, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
822 
823 	{ "clashr2.bin",	0x2000, 0xe6389ec1, 2 | BRF_PRG | BRF_ESS }, //  1 Z80 #1 Code
824 
825 	{ "cr-12",			0x2000, 0xe5aa4c46, 3 | BRF_GRA },           //  2 Sprites
826 	{ "cr-11",			0x2000, 0x7fc11c7c, 3 | BRF_GRA },           //  3
827 	{ "cr-10",			0x2000, 0x6b1293b7, 3 | BRF_GRA },           //  4
828 	{ "cr-9",			0x2000, 0xd219722c, 3 | BRF_GRA },           //  5
829 
830 	{ "cr-7",			0x2000, 0xe8aa7ac3, 4 | BRF_GRA },           //  6 Background Tiles
831 	{ "cr-6",			0x2000, 0x037be475, 4 | BRF_GRA },           //  7
832 	{ "cr-5",			0x2000, 0xa4151734, 4 | BRF_GRA },           //  8
833 	{ "cr-4",			0x2000, 0x5ef24757, 4 | BRF_GRA },           //  9
834 
835 	{ "cr-13",			0x2000, 0x012a6412, 5 | BRF_GRA },           // 10 Foreground Tiles
836 	{ "cr-8",			0x2000, 0x3c2b816c, 5 | BRF_GRA },           // 11
837 
838 	{ "82s129.6",		0x0100, 0x38f443da, 6 | BRF_GRA },           // 12 Color data
839 	{ "82s129.7",		0x0100, 0x977fab0c, 6 | BRF_GRA },           // 13
840 	{ "82s129.8",		0x0100, 0xae7ae54d, 6 | BRF_GRA },           // 14
841 
842 	{ "clashr1.bin",	0x2000, 0x0d0a8068, 7 | BRF_SND },           // 15 Samples
843 
844 	{ "clashrd.g8",		0x0100, 0xbd2c080b, 8 | BRF_GRA },           // 16 Sample PROMs
845 	{ "clashrd.g7",		0x0100, 0x4017a2a6, 8 | BRF_GRA },           // 17
846 
847 	{ "clashrd.a2",		0x0100, 0x4e2a2781, 0 | BRF_OPT },           // 18 Unused PROMs
848 	{ "clashrd.g4",		0x0020, 0x1afc04f0, 0 | BRF_OPT },           // 19
849 	{ "clashrd.b11",	0x0020, 0xd453f2c5, 0 | BRF_OPT },           // 20
850 	{ "clashrd.g10",	0x0100, 0x73afefd0, 0 | BRF_OPT },           // 21
851 };
852 
853 STD_ROM_PICK(clshroads)
STD_ROM_FN(clshroads)854 STD_ROM_FN(clshroads)
855 
856 static INT32 ClshroadsInit()
857 {
858 	return DrvInit(2);
859 }
860 
861 struct BurnDriver BurnDrvClshroads = {
862 	"clshroads", "clshroad", NULL, NULL, "1986",
863 	"Clash-Road (Status license)\0", NULL, "Wood Place Inc. (Status Game Corp. license)", "Miscellaneous",
864 	NULL, NULL, NULL, NULL,
865 	BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, GBF_RACING, 0,
866 	NULL, clshroadsRomInfo, clshroadsRomName, NULL, NULL, NULL, NULL, ClshroadInputInfo, ClshroadDIPInfo,
867 	ClshroadsInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
868 	288, 224, 4, 3
869 };
870