1 // FB Alpha Speed Ball / Music Ball driver module
2 // Based on MAME driver by Joseba Epalza and Andreas Naive
3
4 #include "tiles_generic.h"
5 #include "z80_intf.h"
6 #include "burn_ym3812.h"
7 #include "bitswap.h"
8
9 static UINT8 *AllMem;
10 static UINT8 *MemEnd;
11 static UINT8 *AllRam;
12 static UINT8 *RamEnd;
13 static UINT8 *DrvZ80ROM0;
14 static UINT8 *DrvZ80ROM1;
15 static UINT8 *DrvGfxROM0;
16 static UINT8 *DrvGfxROM1;
17 static UINT8 *DrvGfxROM2;
18 static UINT8 *DrvShareRAM;
19 static UINT8 *DrvZ80RAM1;
20 static UINT8 *DrvBgRAM;
21 static UINT8 *DrvFgRAM;
22 static UINT8 *DrvPalRAM;
23 static UINT8 *DrvSprRAM;
24
25 static UINT32 *DrvPalette;
26 static UINT8 DrvRecalc;
27
28 static UINT8 flipscreen;
29
30 static UINT8 DrvJoy1[8];
31 static UINT8 DrvJoy2[8];
32 static UINT8 DrvDips[2];
33 static UINT8 DrvInputs[2];
34 static UINT8 DrvReset;
35
36 static struct BurnInputInfo SpeedbalInputList[] = {
37 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 7, "p1 coin" },
38 {"P1 Start", BIT_DIGITAL, DrvJoy1 + 5, "p1 start" },
39 {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 0, "p1 fire 1" },
40 {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 1, "p1 fire 2" },
41 {"P1 Button 3", BIT_DIGITAL, DrvJoy1 + 3, "p1 fire 3" },
42 {"P1 Button 4", BIT_DIGITAL, DrvJoy1 + 2, "p1 fire 4" },
43
44 {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin" },
45 {"P2 Start", BIT_DIGITAL, DrvJoy1 + 4, "p2 start" },
46 {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 0, "p2 fire 1" },
47 {"P2 Button 2", BIT_DIGITAL, DrvJoy2 + 1, "p2 fire 2" },
48 {"P2 Button 3", BIT_DIGITAL, DrvJoy2 + 3, "p2 fire 3" },
49 {"P2 Button 4", BIT_DIGITAL, DrvJoy2 + 2, "p2 fire 4" },
50
51 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
52 {"Tilt", BIT_DIGITAL, DrvJoy2 + 4, "tilt" },
53 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
54 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
55 };
56
57 STDINPUTINFO(Speedbal)
58
59 static struct BurnDIPInfo SpeedbalDIPList[]=
60 {
61 {0x0e, 0xff, 0xff, 0xbf, NULL },
62 {0x0f, 0xff, 0xff, 0xff, NULL },
63
64 {0 , 0xfe, 0 , 4, "Coin B" },
65 {0x0e, 0x01, 0x03, 0x03, "1 Coin 2 Credits" },
66 {0x0e, 0x01, 0x03, 0x02, "1 Coin 3 Credits" },
67 {0x0e, 0x01, 0x03, 0x01, "1 Coin 4 Credits" },
68 {0x0e, 0x01, 0x03, 0x00, "1 Coin 5 Credits" },
69
70 {0 , 0xfe, 0 , 4, "Coin A" },
71 {0x0e, 0x01, 0x0c, 0x00, "4 Coins 1 Credits" },
72 {0x0e, 0x01, 0x0c, 0x04, "3 Coins 1 Credits" },
73 {0x0e, 0x01, 0x0c, 0x08, "2 Coins 1 Credits" },
74 {0x0e, 0x01, 0x0c, 0x0c, "1 Coin 1 Credits" },
75
76 {0 , 0xfe, 0 , 4, "Lives" },
77 {0x0e, 0x01, 0x30, 0x00, "2" },
78 {0x0e, 0x01, 0x30, 0x30, "3" },
79 {0x0e, 0x01, 0x30, 0x20, "4" },
80 {0x0e, 0x01, 0x30, 0x10, "5" },
81
82 {0 , 0xfe, 0 , 2, "Cabinet" },
83 {0x0e, 0x01, 0x40, 0x00, "Upright" },
84 {0x0e, 0x01, 0x40, 0x40, "Cocktail" },
85
86 {0 , 0xfe, 0 , 2, "Demo Sounds" },
87 {0x0e, 0x01, 0x80, 0x00, "Off" },
88 {0x0e, 0x01, 0x80, 0x80, "On" },
89
90 {0 , 0xfe, 0 , 8, "Bonus Life" },
91 {0x0f, 0x01, 0x07, 0x06, "70000 200000 1M" },
92 {0x0f, 0x01, 0x07, 0x07, "70000 200000" },
93 {0x0f, 0x01, 0x07, 0x03, "100000 300000 1M" },
94 {0x0f, 0x01, 0x07, 0x04, "100000 300000" },
95 {0x0f, 0x01, 0x07, 0x01, "200000 1M" },
96 {0x0f, 0x01, 0x07, 0x05, "200000" },
97 {0x0f, 0x01, 0x07, 0x02, "200000 (duplicate)" },
98 {0x0f, 0x01, 0x07, 0x00, "None" },
99
100 {0 , 0xfe, 0 , 2, "Unknown" },
101 {0x0f, 0x01, 0x08, 0x08, "Off" },
102 {0x0f, 0x01, 0x08, 0x00, "On" },
103
104 {0 , 0xfe, 0 , 4, "Difficulty 1" },
105 {0x0f, 0x01, 0x30, 0x30, "Very Easy" },
106 {0x0f, 0x01, 0x30, 0x20, "Easy" },
107 {0x0f, 0x01, 0x30, 0x10, "Difficult" },
108 {0x0f, 0x01, 0x30, 0x00, "Very Difficult" },
109
110 {0 , 0xfe, 0 , 4, "Difficulty 2" },
111 {0x0f, 0x01, 0xc0, 0xc0, "Very Easy" },
112 {0x0f, 0x01, 0xc0, 0x80, "Easy" },
113 {0x0f, 0x01, 0xc0, 0x40, "Difficult" },
114 {0x0f, 0x01, 0xc0, 0x00, "Very Difficult" },
115 };
116
117 STDDIPINFO(Speedbal)
118
119 static struct BurnDIPInfo MusicbalDIPList[]=
120 {
121 {0x0e, 0xff, 0xff, 0xbf, NULL },
122 {0x0f, 0xff, 0xff, 0xff, NULL },
123
124 {0 , 0xfe, 0 , 4, "Coin B" },
125 {0x0e, 0x01, 0x03, 0x03, "1 Coin 2 Credits" },
126 {0x0e, 0x01, 0x03, 0x02, "1 Coin 3 Credits" },
127 {0x0e, 0x01, 0x03, 0x01, "1 Coin 4 Credits" },
128 {0x0e, 0x01, 0x03, 0x00, "1 Coin 5 Credits" },
129
130 {0 , 0xfe, 0 , 4, "Coin A" },
131 {0x0e, 0x01, 0x0c, 0x00, "4 Coins 1 Credits" },
132 {0x0e, 0x01, 0x0c, 0x04, "3 Coins 1 Credits" },
133 {0x0e, 0x01, 0x0c, 0x08, "2 Coins 1 Credits" },
134 {0x0e, 0x01, 0x0c, 0x0c, "1 Coin 1 Credits" },
135
136 {0 , 0xfe, 0 , 4, "Lives" },
137 {0x0e, 0x01, 0x30, 0x00, "2" },
138 {0x0e, 0x01, 0x30, 0x30, "3" },
139 {0x0e, 0x01, 0x30, 0x20, "4" },
140 {0x0e, 0x01, 0x30, 0x10, "5" },
141
142 {0 , 0xfe, 0 , 2, "Cabinet" },
143 {0x0e, 0x01, 0x40, 0x00, "Upright" },
144 {0x0e, 0x01, 0x40, 0x40, "Cocktail" },
145
146 {0 , 0xfe, 0 , 2, "Demo Sounds" },
147 {0x0e, 0x01, 0x80, 0x00, "Off" },
148 {0x0e, 0x01, 0x80, 0x80, "On" },
149
150 {0 , 0xfe, 0 , 8, "Bonus Life" },
151 {0x0f, 0x01, 0x07, 0x03, "1M 2M 2.5M" },
152 {0x0f, 0x01, 0x07, 0x06, "1.2M 1.8M 2.5M" },
153 {0x0f, 0x01, 0x07, 0x07, "1.2M 1.8M" },
154 {0x0f, 0x01, 0x07, 0x04, "1.5M 2M" },
155 {0x0f, 0x01, 0x07, 0x05, "1.5M" },
156 {0x0f, 0x01, 0x07, 0x01, "1.8M 2.5M" },
157 {0x0f, 0x01, 0x07, 0x02, "1.8M" },
158 {0x0f, 0x01, 0x07, 0x00, "None" },
159
160 {0 , 0xfe, 0 , 2, "Unknown" },
161 {0x0f, 0x01, 0x08, 0x08, "Off" },
162 {0x0f, 0x01, 0x08, 0x00, "On" },
163
164 {0 , 0xfe, 0 , 4, "Difficulty 1" },
165 {0x0f, 0x01, 0x30, 0x30, "Very Easy" },
166 {0x0f, 0x01, 0x30, 0x20, "Easy" },
167 {0x0f, 0x01, 0x30, 0x10, "Difficult" },
168 {0x0f, 0x01, 0x30, 0x00, "Very Difficult" },
169
170 {0 , 0xfe, 0 , 4, "Difficulty 2" },
171 {0x0f, 0x01, 0xc0, 0xc0, "Very Easy" },
172 {0x0f, 0x01, 0xc0, 0x80, "Easy" },
173 {0x0f, 0x01, 0xc0, 0x40, "Difficult" },
174 {0x0f, 0x01, 0xc0, 0x00, "Very Difficult" },
175 };
176
STDDIPINFO(Musicbal)177 STDDIPINFO(Musicbal)
178
179 static void __fastcall speedbal_main_write_port(UINT16 port, UINT8 data)
180 {
181 switch (port & 0xff)
182 {
183 case 0x40:
184 // coin counter = data & 0xc0
185 flipscreen = data & 0x08;
186 return;
187
188 case 0x50:
189 // ?
190 return;
191 }
192 }
193
speedbal_main_read_port(UINT16 port)194 static UINT8 __fastcall speedbal_main_read_port(UINT16 port)
195 {
196 switch (port & 0xff)
197 {
198 case 0x00:
199 return DrvDips[1];
200
201 case 0x10:
202 return DrvDips[0];
203
204 case 0x20:
205 return DrvInputs[0];
206
207 case 0x30:
208 return DrvInputs[1];
209 }
210
211 return 0;
212 }
213
speedbal_sound_write_port(UINT16 port,UINT8 data)214 static void __fastcall speedbal_sound_write_port(UINT16 port, UINT8 data)
215 {
216 switch (port & 0xff)
217 {
218 case 0x00:
219 case 0x01:
220 BurnYM3812Write(0, port & 1, data);
221 return;
222
223 case 0x40: // led controls
224 case 0x80:
225 case 0xc1:
226 return;
227
228 case 0x82:
229 return; // nop
230 }
231 }
232
speedbal_sound_read_port(UINT16 port)233 static UINT8 __fastcall speedbal_sound_read_port(UINT16 port)
234 {
235 switch (port & 0xff)
236 {
237 case 0x00:
238 case 0x01:
239 return BurnYM3812Read(0, port & 1);
240 }
241
242 return 0;
243 }
244
tilemap_callback(bg)245 static tilemap_callback( bg )
246 {
247 offs ^= 0xf0; // flipx
248 INT32 attr = DrvBgRAM[offs * 2 + 1];
249 INT32 code = DrvBgRAM[offs * 2 + 0] + ((attr & 0x30) << 4);
250 INT32 color = attr & 0xf;
251
252 TILE_SET_INFO(1, code, color, 0);
253 *category = (color == 8) ? 1 : 0; // always comes _after_ TILE_SET_INFO()!
254 }
255
tilemap_callback(fg)256 static tilemap_callback( fg )
257 {
258 offs ^= 0x3e0; // flipx
259 INT32 attr = DrvFgRAM[offs * 2 + 1];
260 INT32 code = DrvFgRAM[offs * 2 + 0] + ((attr & 0x30) << 4);
261 INT32 color = attr & 0xf;
262
263 TILE_SET_INFO(0, code, color, 0);
264 *category = (color == 9) ? 1 : 0;
265 }
266
DrvDoReset()267 static INT32 DrvDoReset()
268 {
269 memset (AllRam, 0, RamEnd - AllRam);
270
271 ZetOpen(0);
272 ZetReset();
273 ZetClose();
274
275 ZetOpen(1);
276 ZetReset();
277 BurnYM3812Reset();
278 ZetClose();
279
280 flipscreen = 0;
281
282 return 0;
283 }
284
MemIndex()285 static INT32 MemIndex()
286 {
287 UINT8 *Next; Next = AllMem;
288
289 DrvZ80ROM0 = Next; Next += 0x010000;
290 DrvZ80ROM1 = Next; Next += 0x008000;
291
292 DrvGfxROM0 = Next; Next += 0x010000;
293 DrvGfxROM1 = Next; Next += 0x040000;
294 DrvGfxROM2 = Next; Next += 0x020000;
295
296 DrvPalette = (UINT32*)Next; Next += 0x00300 * sizeof(UINT32);
297
298 AllRam = Next;
299
300 DrvShareRAM = Next; Next += 0x00400;
301 DrvZ80RAM1 = Next; Next += 0x00400;
302 DrvBgRAM = Next; Next += 0x00200;
303 DrvFgRAM = Next; Next += 0x00800;
304
305 DrvPalRAM = Next; Next += 0x00f00;
306 DrvSprRAM = Next; Next += 0x00100;
307
308 RamEnd = Next;
309 MemEnd = Next;
310
311 return 0;
312 }
313
DrvGfxDecode()314 static INT32 DrvGfxDecode()
315 {
316 UINT8 *tmp = (UINT8*)BurnMalloc(0x80000);
317 if (tmp == NULL) {
318 return 1;
319 }
320 INT32 Planes0[4] = { 0x4000*8+4, 0x4000*8, 4, 0 };
321 INT32 XOffs0[ 8] = { STEP4(8+3,-1), STEP4(3,-1) };
322 INT32 YOffs0[ 8] = { STEP8(0,16) };
323
324 INT32 Planes1[4] = { STEP4(0,2) };
325 INT32 XOffs1[16] = { 0, 1, 56, 57, 48, 49, 40, 41, 32, 33, 24, 25, 16, 17, 8, 9 };
326 INT32 YOffs1[16] = { STEP16(0,64) };
327
328 INT32 Planes2[4] = { STEP4(0,2) };
329 INT32 XOffs2[16] = { 57, 56, 49, 48, 41, 40, 33, 32, 25, 24, 17, 16, 9, 8, 1, 0 };
330 INT32 YOffs2[16] = { STEP16(0,64) };
331
332 memcpy (tmp, DrvGfxROM0, 0x08000);
333
334 GfxDecode(0x0400, 4, 8, 8, Planes0, XOffs0, YOffs0, 0x080, tmp, DrvGfxROM0);
335
336 memcpy (tmp, DrvGfxROM1, 0x20000);
337
338 GfxDecode(0x0400, 4, 16, 16, Planes1, XOffs1, YOffs1, 0x400, tmp, DrvGfxROM1);
339
340 memcpy (tmp, DrvGfxROM2, 0x10000);
341
342 GfxDecode(0x0200, 4, 16, 16, Planes2, XOffs2, YOffs2, 0x400, tmp, DrvGfxROM2);
343
344 BurnFree (tmp);
345
346 return 0;
347 }
348
musicbalPrgDecode()349 static void musicbalPrgDecode()
350 {
351 UINT8 xt[8] = { 0x05, 0x06, 0x84, 0x84, 0x00, 0x87, 0x84, 0x84 };
352
353 INT32 swap[4][4] = {
354 { 1, 0, 7, 2 },
355 { 2, 7, 0, 1 },
356 { 7, 2, 1, 0 },
357 { 0, 2, 1, 7 }
358 };
359
360 for (INT32 i = 0; i < 0x8000; i++)
361 {
362 INT32 aidx = BIT(i,3)^(BIT(i,5)<<1)^(BIT(i,9)<<2);
363 INT32 *st = swap[xt[aidx] & 3];
364
365 DrvZ80ROM0[i] = BITSWAP08(DrvZ80ROM0[i], st[3], 6,5,4,3, st[2], st[1], st[0]) ^ xt[aidx];
366 }
367 }
368
DrvGfxDescramble()369 static void DrvGfxDescramble()
370 {
371 UINT8 *tmp = (UINT8*)BurnMalloc(0x10000);
372
373 for (INT32 i = 0; i < 0x200; i++)
374 {
375 INT32 j = BITSWAP16(i, 15,14,13,12,11,10,9,8,0,1,2,3,4,5,6,7);
376
377 memcpy (tmp + i * 128, DrvGfxROM2 + j * 128, 128);
378 }
379
380 for (INT32 i = 0; i < 0x10000; i++) {
381 DrvGfxROM2[i] = tmp[i] ^ 0xff; // copy & invert
382 }
383
384 BurnFree (tmp);
385 }
386
DrvInit(INT32 game)387 static INT32 DrvInit(INT32 game)
388 {
389 BurnSetRefreshRate(56.4);
390
391 AllMem = NULL;
392 MemIndex();
393 INT32 nLen = MemEnd - (UINT8 *)0;
394 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
395 memset(AllMem, 0, nLen);
396 MemIndex();
397
398 {
399 if (BurnLoadRom(DrvZ80ROM0 + 0x00000, 0, 1)) return 1;
400 if (BurnLoadRom(DrvZ80ROM0 + 0x08000, 1, 1)) return 1;
401
402 if (BurnLoadRom(DrvZ80ROM1 + 0x00000, 2, 1)) return 1;
403
404 if (BurnLoadRom(DrvGfxROM0 + 0x00000, 3, 1)) return 1;
405
406 if (BurnLoadRom(DrvGfxROM1 + 0x00000, 4, 1)) return 1;
407 if (BurnLoadRom(DrvGfxROM1 + 0x08000, 5, 1)) return 1;
408 if (BurnLoadRom(DrvGfxROM1 + 0x10000, 6, 1)) return 1;
409 if (BurnLoadRom(DrvGfxROM1 + 0x18000, 7, 1)) return 1;
410
411 if (BurnLoadRom(DrvGfxROM2 + 0x00000, 8, 1)) return 1;
412 if (BurnLoadRom(DrvGfxROM2 + 0x08000, 9, 1)) return 1;
413
414 if (game) musicbalPrgDecode();
415 DrvGfxDescramble();
416 DrvGfxDecode();
417 }
418
419 ZetInit(0);
420 ZetOpen(0);
421 ZetMapMemory(DrvZ80ROM0, 0x0000, 0xdbff, MAP_ROM);
422 ZetMapMemory(DrvShareRAM, 0xdc00, 0xdfff, MAP_RAM);
423 ZetMapMemory(DrvBgRAM, 0xe000, 0xe1ff, MAP_RAM);
424 ZetMapMemory(DrvFgRAM, 0xe800, 0xefff, MAP_RAM);
425 ZetMapMemory(DrvPalRAM, 0xf000, 0xfeff, MAP_RAM); // 0-5ff
426 ZetMapMemory(DrvSprRAM, 0xff00, 0xffff, MAP_RAM);
427 ZetSetOutHandler(speedbal_main_write_port);
428 ZetSetInHandler(speedbal_main_read_port);
429 ZetClose();
430
431 ZetInit(1);
432 ZetOpen(1);
433 ZetMapMemory(DrvZ80ROM1, 0x0000, 0x7fff, MAP_ROM);
434 ZetMapMemory(DrvZ80RAM1, 0xd800, 0xdbff, MAP_RAM);
435 ZetMapMemory(DrvShareRAM, 0xdc00, 0xdfff, MAP_RAM);
436 ZetSetOutHandler(speedbal_sound_write_port);
437 ZetSetInHandler(speedbal_sound_read_port);
438 ZetClose();
439
440 BurnYM3812Init(1, 4000000, NULL, 0);
441 BurnTimerAttachYM3812(&ZetConfig, 4000000);
442 BurnYM3812SetRoute(0, BURN_SND_YM3812_ROUTE, 1.00, BURN_SND_ROUTE_BOTH);
443
444 GenericTilesInit();
445 // foreground
446 GenericTilemapInit(0, TILEMAP_SCAN_COLS, fg_map_callback, 8, 8, 32, 32);
447 GenericTilemapCategoryConfig(0, 4);
448 GenericTilemapSetTransMask(0, 0, 0xffff); // fg
449 GenericTilemapSetTransMask(0, 1, 0x0001); // fg
450 GenericTilemapSetTransMask(0, 2, 0x0001); // bg
451 GenericTilemapSetTransMask(0, 3, 0x0001); // bg
452
453 // background
454 GenericTilemapInit(1, TILEMAP_SCAN_COLS, bg_map_callback, 16, 16, 16, 16);
455 GenericTilemapCategoryConfig(1, 4);
456 GenericTilemapSetTransMask(1, 0, 0xffff); // fg
457 GenericTilemapSetTransMask(1, 1, 0x00f7); // fg
458 GenericTilemapSetTransMask(1, 2, 0x0000); // bg
459 GenericTilemapSetTransMask(1, 3, 0x0000); // bg
460
461 GenericTilemapSetOffsets(TMAP_GLOBAL, 0, -16);
462
463 GenericTilemapSetGfx(0, DrvGfxROM0, 4, 8, 8, 0x10000, 0x100, 0xf);
464 GenericTilemapSetGfx(1, DrvGfxROM1, 4, 16, 16, 0x40000, 0x200, 0xf);
465
466 DrvDoReset();
467
468 return 0;
469 }
470
DrvExit()471 static INT32 DrvExit()
472 {
473 GenericTilesExit();
474
475 BurnYM3812Exit();
476
477 ZetExit();
478
479 BurnFree (AllMem);
480
481 return 0;
482 }
483
DrvPaletteUpdate()484 static void DrvPaletteUpdate() // RRRRGGGGBBBBxxxx BE
485 {
486 for (INT32 i = 0; i < 0x600; i+=2)
487 {
488 UINT8 r = DrvPalRAM[i+0] >> 4;
489 UINT8 g = DrvPalRAM[i+0] & 0xf;
490 UINT8 b = DrvPalRAM[i+1] >> 4;
491
492 DrvPalette[i/2] = BurnHighCol(r+r*16, g+g*16, b+b*16, 0);
493 }
494 }
495
draw_sprites()496 static void draw_sprites()
497 {
498 for (INT32 offs = 0; offs < 0x100; offs += 4)
499 {
500 if ((DrvSprRAM[offs + 2] & 0x80) == 0)
501 continue;
502
503 INT32 sx = 243 - DrvSprRAM[offs + 3];
504 INT32 sy = 239 - DrvSprRAM[offs + 0];
505
506 INT32 code = (DrvSprRAM[offs + 1]) | ((DrvSprRAM[offs + 2] & 0x40) << 2);
507 INT32 color = DrvSprRAM[offs + 2] & 0x0f;
508
509 if (flipscreen)
510 {
511 sx = 246 - sx;
512 sy = 238 - sy;
513 }
514
515 Draw16x16MaskTile(pTransDraw, code, sx, sy - 16, flipscreen, flipscreen, color, 4, 0, 0, DrvGfxROM2);
516 }
517 }
518
DrvDraw()519 static INT32 DrvDraw()
520 {
521 // if (DrvRecalc) {
522 DrvPaletteUpdate();
523 DrvRecalc = 1;
524 // }
525
526 BurnTransferClear();
527
528 if (nBurnLayer & 1) GenericTilemapDraw(1, pTransDraw, TMAP_DRAWLAYER1); // bg bg_mask
529 if (nBurnLayer & 2) GenericTilemapDraw(0, pTransDraw, TMAP_DRAWLAYER1); // fg bg_mask
530 if (nSpriteEnable & 1) draw_sprites();
531 if (nBurnLayer & 4) GenericTilemapDraw(1, pTransDraw, TMAP_DRAWLAYER0); // bg fg_mask
532 if (nBurnLayer & 8) GenericTilemapDraw(0, pTransDraw, TMAP_DRAWLAYER0); // fg fg_mask
533
534 BurnTransferCopy(DrvPalette);
535
536 return 0;
537 }
538
DrvFrame()539 static INT32 DrvFrame()
540 {
541 if (DrvReset) {
542 DrvDoReset();
543 }
544
545 {
546 memset (DrvInputs, 0xff, 2);
547
548 for (INT32 i = 0; i < 8; i++) {
549 DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
550 DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
551 }
552 }
553
554 ZetNewFrame();
555
556 INT32 nInterleave = 256;
557 INT32 nCyclesTotal[2] = { 40000000 / 564, 40000000 / 564 };
558 INT32 nCyclesDone[2] = { 0, 0 };
559
560 for (INT32 i = 0; i < nInterleave; i++)
561 {
562 ZetOpen(0);
563 nCyclesDone[0] += ZetRun((nCyclesTotal[0] * (i + 1) / nInterleave) - nCyclesDone[0]);
564 if (i == 240) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
565 INT32 nCycles = ZetTotalCycles();
566 ZetClose();
567
568 ZetOpen(1);
569 BurnTimerUpdateYM3812(nCycles);
570 if ((i & 0x1f) == 0x1f) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD); // 8x / frame
571 ZetClose();
572 }
573
574 ZetOpen(1);
575
576 BurnTimerEndFrameYM3812(nCyclesTotal[1]);
577
578 if (pBurnSoundOut) {
579 BurnYM3812Update(pBurnSoundOut, nBurnSoundLen);
580 }
581
582 ZetClose();
583
584 if (pBurnDraw) {
585 DrvDraw();
586 }
587
588 return 0;
589 }
590
DrvScan(INT32 nAction,INT32 * pnMin)591 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
592 {
593 struct BurnArea ba;
594
595 if (pnMin) {
596 *pnMin = 0x029705;
597 }
598
599 if (nAction & ACB_VOLATILE) {
600 memset(&ba, 0, sizeof(ba));
601
602 ba.Data = AllRam;
603 ba.nLen = RamEnd - AllRam;
604 ba.szName = "All Ram";
605 BurnAcb(&ba);
606
607 ZetScan(nAction);
608
609 BurnYM3812Scan(nAction, pnMin);
610
611 SCAN_VAR(flipscreen);
612 }
613
614 return 0;
615 }
616
617
618 // Speed Ball
619
620 static struct BurnRomInfo speedbalRomDesc[] = {
621 { "sb1.bin", 0x8000, 0x1c242e34, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
622 { "sb3.bin", 0x8000, 0x7682326a, 1 | BRF_PRG | BRF_ESS }, // 1
623
624 { "sb2.bin", 0x8000, 0xe6a6d9b7, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 #1 Code
625
626 { "sb10.bin", 0x8000, 0x36dea4bf, 3 | BRF_GRA }, // 3 Characters
627
628 { "sb9.bin", 0x8000, 0xb567e85e, 4 | BRF_GRA }, // 4 Background Tiles
629 { "sb5.bin", 0x8000, 0xb0eae4ba, 4 | BRF_GRA }, // 5
630 { "sb8.bin", 0x8000, 0xd2bfbdb6, 4 | BRF_GRA }, // 6
631 { "sb4.bin", 0x8000, 0x1d23a130, 4 | BRF_GRA }, // 7
632
633 { "sb7.bin", 0x8000, 0x9f1b33d1, 5 | BRF_GRA }, // 8 Sprites (scrambled)
634 { "sb6.bin", 0x8000, 0x0e2506eb, 5 | BRF_GRA }, // 9
635 };
636
637 STD_ROM_PICK(speedbal)
STD_ROM_FN(speedbal)638 STD_ROM_FN(speedbal)
639
640 static INT32 SpeedbalInit()
641 {
642 return DrvInit(0);
643 }
644
645 struct BurnDriver BurnDrvSpeedbal = {
646 "speedbal", NULL, NULL, NULL, "1987",
647 "Speed Ball\0", NULL, "Tecfri / Desystem S.A.", "Miscellaneous",
648 NULL, NULL, NULL, NULL,
649 BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, GBF_PINBALL, 0,
650 NULL, speedbalRomInfo, speedbalRomName, NULL, NULL, NULL, NULL, SpeedbalInputInfo, SpeedbalDIPInfo,
651 SpeedbalInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x300,
652 224, 256, 3, 4
653 };
654
655
656 // Music Ball
657
658 static struct BurnRomInfo musicbalRomDesc[] = {
659 { "01.bin", 0x8000, 0x412298a2, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code (encrypted)
660 { "03.bin", 0x8000, 0xfdf14446, 1 | BRF_PRG | BRF_ESS }, // 1
661
662 { "02.bin", 0x8000, 0xb7d3840d, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 #1 Code
663
664 { "10.bin", 0x8000, 0x5afd3c42, 3 | BRF_GRA }, // 3 Characters
665
666 { "09.bin", 0x8000, 0xdcde4233, 4 | BRF_GRA }, // 4 Background Tiles
667 { "05.bin", 0x8000, 0xe1eec437, 4 | BRF_GRA }, // 5
668 { "08.bin", 0x8000, 0x7e7af52b, 4 | BRF_GRA }, // 6
669 { "04.bin", 0x8000, 0xbf931a33, 4 | BRF_GRA }, // 7
670
671 { "07.bin", 0x8000, 0x310e1e23, 5 | BRF_GRA }, // 8 Sprites (scrambled)
672 { "06.bin", 0x8000, 0x2e7772f8, 5 | BRF_GRA }, // 9
673 };
674
675 STD_ROM_PICK(musicbal)
STD_ROM_FN(musicbal)676 STD_ROM_FN(musicbal)
677
678 static INT32 MusicbalInit()
679 {
680 return DrvInit(1);
681 }
682
683 struct BurnDriver BurnDrvMusicbal = {
684 "musicbal", NULL, NULL, NULL, "1988",
685 "Music Ball\0", NULL, "Tecfri / Desystem S.A.", "Miscellaneous",
686 NULL, NULL, NULL, NULL,
687 BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, GBF_PINBALL, 0,
688 NULL, musicbalRomInfo, musicbalRomName, NULL, NULL, NULL, NULL, SpeedbalInputInfo, MusicbalDIPInfo,
689 MusicbalInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x300,
690 224, 256, 3, 4
691 };
692