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