1 // FinalBurn Neo Disco Boy driver module
2 // Based on MAME driver by David Haywood
3 
4 #include "tiles_generic.h"
5 #include "z80_intf.h"
6 #include "burn_ym3812.h"
7 #include "msm5205.h"
8 #include "burn_pal.h"
9 
10 static UINT8 *AllMem;
11 static UINT8 *MemEnd;
12 static UINT8 *AllRam;
13 static UINT8 *RamEnd;
14 static UINT8 *DrvZ80ROM[2];
15 static UINT8 *DrvGfxROM[3];
16 static UINT8 *DrvZ80RAM[4];
17 static UINT8 *DrvAttrRAM;
18 
19 static UINT8 bankdata[4];
20 static UINT8 soundlatch;
21 static UINT8 gfxbank;
22 static INT32 adpcm_toggle;
23 static UINT8 adpcm_data;
24 
25 static UINT8 DrvJoy1[8];
26 static UINT8 DrvJoy2[8];
27 static UINT8 DrvJoy3[8];
28 static UINT8 DrvDips[2];
29 static UINT8 DrvInputs[3];
30 static UINT8 DrvReset;
31 
32 static HoldCoin<2> hold_coin;
33 
34 static struct BurnInputInfo DiscoboyInputList[] = {
35 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 7,	"p1 coin"	},
36 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 3,	"p1 start"	},
37 	{"P1 Up",			BIT_DIGITAL,	DrvJoy2 + 7,	"p1 up"		},
38 	{"P1 Down",			BIT_DIGITAL,	DrvJoy2 + 6,	"p1 down"	},
39 	{"P1 Left",			BIT_DIGITAL,	DrvJoy2 + 5,	"p1 left"	},
40 	{"P1 Right",		BIT_DIGITAL,	DrvJoy2 + 4,	"p1 right"	},
41 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy2 + 3,	"p1 fire 1"	},
42 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy2 + 2,	"p1 fire 2"	},
43 
44 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy1 + 5,	"p2 coin"	},
45 	{"P2 Start",		BIT_DIGITAL,	DrvJoy1 + 1,	"p2 start"	},
46 	{"P2 Up",			BIT_DIGITAL,	DrvJoy3 + 7,	"p2 up"		},
47 	{"P2 Down",			BIT_DIGITAL,	DrvJoy3 + 6,	"p2 down"	},
48 	{"P2 Left",			BIT_DIGITAL,	DrvJoy3 + 5,	"p2 left"	},
49 	{"P2 Right",		BIT_DIGITAL,	DrvJoy3 + 4,	"p2 right"	},
50 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy3 + 3,	"p2 fire 1"	},
51 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy3 + 2,	"p2 fire 2"	},
52 
53 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
54 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
55 	{"Dip B",			BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
56 };
57 
58 STDINPUTINFO(Discoboy)
59 
60 static struct BurnDIPInfo DiscoboyDIPList[]=
61 {
62 	DIP_OFFSET(0x11)
63 	{0x00, 0xff, 0xff, 0xff, NULL					},
64 	{0x01, 0xff, 0xff, 0x7f, NULL					},
65 
66 	{0   , 0xfe, 0   ,    8, "Coinage"				},
67 	{0x00, 0x01, 0x07, 0x00, "4 Coins 1 Credits"	},
68 	{0x00, 0x01, 0x07, 0x01, "3 Coins 1 Credits"	},
69 	{0x00, 0x01, 0x07, 0x03, "2 Coins 1 Credits"	},
70 	{0x00, 0x01, 0x07, 0x07, "1 Coin  1 Credits"	},
71 	{0x00, 0x01, 0x07, 0x02, "2 Coins 3 Credits"	},
72 	{0x00, 0x01, 0x07, 0x06, "1 Coin  2 Credits"	},
73 	{0x00, 0x01, 0x07, 0x05, "1 Coin  3 Credits"	},
74 	{0x00, 0x01, 0x07, 0x04, "1 Coin  4 Credits"	},
75 
76 	{0   , 0xfe, 0   ,    2, "Bonus Life"			},
77 	{0x00, 0x01, 0x08, 0x08, "Every 150000"			},
78 	{0x00, 0x01, 0x08, 0x00, "Every 300000"			},
79 
80 	{0   , 0xfe, 0   ,    2, "Lives"				},
81 	{0x00, 0x01, 0x10, 0x10, "3"					},
82 	{0x00, 0x01, 0x10, 0x00, "4"					},
83 
84 	{0   , 0xfe, 0   ,    4, "Difficulty"			},
85 	{0x00, 0x01, 0x60, 0x00, "Easy"					},
86 	{0x00, 0x01, 0x60, 0x60, "Normal"				},
87 	{0x00, 0x01, 0x60, 0x40, "Hard"					},
88 	{0x00, 0x01, 0x60, 0x20, "Hardest"				},
89 
90 	{0   , 0xfe, 0   ,    2, "Service Mode"			},
91 	{0x00, 0x01, 0x80, 0x80, "Off"					},
92 	{0x00, 0x01, 0x80, 0x00, "On"					},
93 
94 	{0   , 0xfe, 0   ,    0, "Demo Sounds"			},
95 	{0x01, 0x01, 0x80, 0x80, "Off"					},
96 	{0x01, 0x01, 0x80, 0x00, "On"					},
97 };
98 
STDDIPINFO(Discoboy)99 STDDIPINFO(Discoboy)
100 
101 static void rombank_write(UINT8 data)
102 {
103 	bankdata[0] = data;
104 	gfxbank = data & 0xf0;
105 
106 	ZetMapMemory(DrvZ80ROM[0] + 0x10000 + (data & 7) * 0x4000, 0x8000, 0xbfff, MAP_ROM);
107 }
108 
rambank0_write(UINT8 data)109 static void rambank0_write(UINT8 data)
110 {
111 	bankdata[1] = data;
112 	ZetMapMemory(BurnPalRAM + ((data & 0x20) << 6), 0xc000, 0xc7ff, MAP_RAM);
113 }
114 
rambank1_write(UINT8 data)115 static void rambank1_write(UINT8 data)
116 {
117 	bankdata[2] = data;
118 	if (data < 2) {
119 		ZetMapMemory(DrvZ80RAM[1 + (data & 1)], 0xd000, 0xdfff, MAP_RAM);
120 	}
121 }
122 
discoboy_main_write_port(UINT16 port,UINT8 data)123 static void __fastcall discoboy_main_write_port(UINT16 port, UINT8 data)
124 {
125 	switch (port & 0xff)
126 	{
127 		case 0x00:
128 			rambank1_write(data);
129 		return;
130 
131 		case 0x01:
132 			rombank_write(data);
133 		return;
134 
135 		case 0x03:
136 			soundlatch = data;
137 			ZetSetIRQLine(1, 0, CPU_IRQSTATUS_HOLD);
138 		return;
139 
140 		case 0x06: // nop
141 		return;
142 
143 		case 0x07:
144 			rambank0_write(data);
145 		return;
146 	}
147 }
148 
discoboy_main_read_port(UINT16 port)149 static UINT8 __fastcall discoboy_main_read_port(UINT16 port)
150 {
151 	switch (port & 0xff)
152 	{
153 		case 0x00:
154 			return DrvDips[0];
155 
156 		case 0x01: // sys
157 		case 0x02: // p1
158 		case 0x03: // p2
159 			return DrvInputs[(port - 1) & 3];
160 
161 		case 0x04:
162 			return DrvDips[1];
163 
164 		case 0x06:
165 			return 0; // ok!
166 	}
167 
168 	return 0;
169 }
170 
sound_bankswitch(UINT8 data)171 static void sound_bankswitch(UINT8 data)
172 {
173 	bankdata[3] = data;
174 	ZetMapMemory(DrvZ80ROM[1] + (data & 7) * 0x4000, 0x8000, 0xbfff, MAP_ROM);
175 }
176 
discoboy_sound_write(UINT16 address,UINT8 data)177 static void __fastcall discoboy_sound_write(UINT16 address, UINT8 data)
178 {
179 	switch (address)
180 	{
181 		case 0xe000:
182 			MSM5205ResetWrite(0, (data >> 3) & 1);
183 			sound_bankswitch(data);
184 		return;
185 
186 		case 0xe400:
187 			adpcm_data = data;
188 		return;
189 
190 		case 0xec00:
191 		case 0xec01:
192 			BurnYM3812Write(0, address & 1, data);
193 		return;
194 	}
195 }
196 
discoboy_sound_read(UINT16 address)197 static UINT8 __fastcall discoboy_sound_read(UINT16 address)
198 {
199 	switch (address)
200 	{
201 		case 0xf800:
202 			return soundlatch;
203 	}
204 
205 	return 0;
206 }
207 
tilemap_callback(bg)208 static tilemap_callback( bg )
209 {
210 	INT32 code = DrvZ80RAM[1][offs * 2] + (DrvZ80RAM[1][offs * 2 + 1] << 8);
211 	INT32 color = DrvAttrRAM[offs];
212 	INT32 bank = 1;
213 
214 	if (code > 0x2000) {
215 		bank++;
216 		code = (code & 0x1fff) + (gfxbank & 0xc0) * 0x80;
217 	}
218 
219 	TILE_SET_INFO(bank, code, color, 0);
220 }
221 
DrvMSM5205Int()222 static void DrvMSM5205Int()
223 {
224 	MSM5205DataWrite(0, adpcm_data & 0xf);
225 	adpcm_data >>= 4;
226 	adpcm_toggle ^= 1;
227 
228 	if (adpcm_toggle) ZetNmi();
229 }
230 
DrvMSM5205SynchroniseStream(INT32 nSoundRate)231 inline static INT32 DrvMSM5205SynchroniseStream(INT32 nSoundRate)
232 {
233 	return (INT64)((double)ZetTotalCycles() * nSoundRate / 5000000);
234 }
235 
DrvSynchroniseStream(INT32 nSoundRate)236 static INT32 DrvSynchroniseStream(INT32 nSoundRate)
237 {
238 	return (INT64)((double)ZetTotalCycles() * nSoundRate / 5000000);
239 }
240 
DrvDoReset()241 static INT32 DrvDoReset()
242 {
243 	memset (AllRam, 0, RamEnd - AllRam);
244 
245 	ZetOpen(0);
246 	rombank_write(0);
247 	ZetReset();
248 	ZetClose();
249 
250 	ZetOpen(1);
251 	sound_bankswitch(0);
252 	ZetReset();
253 	BurnYM3812Reset();
254 	MSM5205Reset();
255 	ZetClose();
256 
257 	gfxbank = 0;
258 	soundlatch = 0;
259 	adpcm_toggle = 0;
260 	adpcm_data = 0;
261 
262 	hold_coin.reset();
263 
264 	return 0;
265 }
266 
MemIndex()267 static INT32 MemIndex()
268 {
269 	UINT8 *Next; Next = AllMem;
270 
271 	DrvZ80ROM[0]		= Next; Next += 0x030000;
272 	DrvZ80ROM[1]		= Next; Next += 0x020000;
273 
274 	DrvGfxROM[0]		= Next; Next += 0x200000;
275 	DrvGfxROM[1]		= Next; Next += 0x080000;
276 	DrvGfxROM[2]		= Next; Next += 0x400000;
277 
278 	BurnPalette			= (UINT32*)Next; Next += 0x800 * sizeof(UINT32);
279 
280 	AllRam				= Next;
281 
282 	BurnPalRAM			= Next; Next += 0x001000;
283 	DrvAttrRAM			= Next; Next += 0x000800;
284 	DrvZ80RAM[0]		= Next; Next += 0x002000;
285 	DrvZ80RAM[1]		= Next; Next += 0x001000;
286 	DrvZ80RAM[2]		= Next; Next += 0x001000;
287 	DrvZ80RAM[3]		= Next; Next += 0x000800;
288 
289 	RamEnd				= Next;
290 	MemEnd				= Next;
291 
292 	return 0;
293 }
294 
DrvGfxDecode()295 static INT32 DrvGfxDecode()
296 {
297 	INT32 Plane0[4]  = { 0x80000*8+4, 0x80000*8, 4, 0 };
298 	INT32 Plane1[4]  = { 0x10000*8, 0, 0x30000*8, 0x20000*8 };
299 	INT32 Plane2[4]  = { 0x40000*8, 0, 0xc0000*8, 0x80000*8 };
300 	INT32 XOffs0[16] = { STEP4(0,1), STEP4(8,1), STEP4(256,1), STEP4(256+8,1) };
301 	INT32 YOffs0[16] = { STEP16(0,16) };
302 	INT32 XOffs1[8]  = { STEP8(0,1) };
303 	INT32 YOffs1[8]  = { STEP8(0,8) };
304 
305 	UINT8 *tmp = (UINT8*)BurnMalloc(0x400000);
306 	if (tmp == NULL) {
307 		return 1;
308 	}
309 
310 	memcpy (tmp, DrvGfxROM[0], 0x100000);
311 
312 	GfxDecode(0x2000, 4, 16, 16, Plane0, XOffs0, YOffs0, 0x200, tmp, DrvGfxROM[0]);
313 
314 	memcpy (tmp, DrvGfxROM[1], 0x040000);
315 
316 	GfxDecode(0x2000, 4,  8,  8, Plane1, XOffs1, YOffs1, 0x040, tmp, DrvGfxROM[1]);
317 
318 	memcpy (tmp, DrvGfxROM[2], 0x100000);
319 
320 	GfxDecode(0x10000, 4,  8,  8, Plane2, XOffs1, YOffs1, 0x040, tmp, DrvGfxROM[2]);
321 
322 	BurnFree (tmp);
323 
324 	return 0;
325 }
326 
DrvInit()327 static INT32 DrvInit()
328 {
329 	BurnAllocMemIndex();
330 
331 	{
332 		INT32 k = 0;
333 		if (BurnLoadRom(DrvZ80ROM[0] + 0x00000, k++, 1)) return 1;
334 		if (BurnLoadRom(DrvZ80ROM[0] + 0x10000, k++, 1)) return 1;
335 
336 		if (BurnLoadRom(DrvZ80ROM[1] + 0x00000, k++, 1)) return 1;
337 		if (BurnLoadRom(DrvZ80ROM[1] + 0x10000, k++, 1)) return 1;
338 
339 		if (BurnLoadRomExt(DrvGfxROM[0] + 0x00000, k++, 1, LD_INVERT)) return 1;
340 		if (BurnLoadRomExt(DrvGfxROM[0] + 0x10000, k++, 1, LD_INVERT)) return 1;
341 		if (BurnLoadRomExt(DrvGfxROM[0] + 0x80000, k++, 1, LD_INVERT)) return 1;
342 		if (BurnLoadRomExt(DrvGfxROM[0] + 0x90000, k++, 1, LD_INVERT)) return 1;
343 
344 		if (BurnLoadRomExt(DrvGfxROM[1] + 0x00000, k++, 1, LD_INVERT)) return 1;
345 		if (BurnLoadRomExt(DrvGfxROM[1] + 0x10000, k++, 1, LD_INVERT)) return 1;
346 		if (BurnLoadRomExt(DrvGfxROM[1] + 0x20000, k++, 1, LD_INVERT)) return 1;
347 		if (BurnLoadRomExt(DrvGfxROM[1] + 0x30000, k++, 1, LD_INVERT)) return 1;
348 
349 		if (BurnLoadRomExt(DrvGfxROM[2] + 0x00000, k++, 1, LD_INVERT)) return 1;
350 		if (BurnLoadRomExt(DrvGfxROM[2] + 0x40000, k++, 1, LD_INVERT)) return 1;
351 		if (BurnLoadRomExt(DrvGfxROM[2] + 0x80000, k++, 1, LD_INVERT)) return 1;
352 		if (BurnLoadRomExt(DrvGfxROM[2] + 0xc0000, k++, 1, LD_INVERT)) return 1;
353 
354 		DrvGfxDecode();
355 	}
356 
357 	ZetInit(0);
358 	ZetOpen(0);
359 	ZetMapMemory(DrvZ80ROM[0], 		0x0000, 0x7fff, MAP_ROM);
360 	// rom bank 8000-bfff
361 	// ram bank 1 c000-c7ff
362 	ZetMapMemory(DrvAttrRAM,		0xc800, 0xcfff, MAP_RAM);
363 	// rambank 2 d000-dfff
364 	ZetMapMemory(DrvZ80RAM[0],		0xe000, 0xffff, MAP_RAM);
365 	ZetSetOutHandler(discoboy_main_write_port);
366 	ZetSetInHandler(discoboy_main_read_port);
367 	ZetClose();
368 
369 	ZetInit(1);
370 	ZetOpen(1);
371 	ZetMapMemory(DrvZ80ROM[1],		0x0000, 0x7fff, MAP_ROM);
372 	ZetMapMemory(DrvZ80RAM[3],		0xf000, 0xf7ff, MAP_RAM);
373 	ZetSetWriteHandler(discoboy_sound_write);
374 	ZetSetReadHandler(discoboy_sound_read);
375 	ZetClose();
376 
377 	BurnYM3812Init(1, 2500000, NULL, &DrvSynchroniseStream, 0);
378 	BurnTimerAttachYM3812(&ZetConfig, 5000000);
379 	BurnYM3812SetRoute(0, BURN_SND_YM3812_ROUTE, 1.00, BURN_SND_ROUTE_BOTH);
380 
381 	MSM5205Init(0, DrvMSM5205SynchroniseStream, 400000, DrvMSM5205Int, MSM5205_S96_4B, 1);
382 	MSM5205SetRoute(0, 0.65, BURN_SND_ROUTE_BOTH);
383 
384 	GenericTilesInit();
385 	GenericTilemapInit(0, TILEMAP_SCAN_ROWS, bg_map_callback, 8, 8, 64, 32);
386 	GenericTilemapSetGfx(0, DrvGfxROM[0], 4, 16, 16, 0x200000, 0, 0x7f);
387 	GenericTilemapSetGfx(1, DrvGfxROM[1], 4,  8,  8, 0x080000, 0, 0x7f);
388 	GenericTilemapSetGfx(2, DrvGfxROM[2], 4,  8,  8, 0x400000, 0, 0x7f);
389 	GenericTilemapSetOffsets(TMAP_GLOBAL, -64, -8);
390 
391 	DrvDoReset();
392 
393 	return 0;
394 }
395 
DrvExit()396 static INT32 DrvExit()
397 {
398 	MSM5205Exit();
399 	BurnYM3812Exit();
400 
401 	ZetExit();
402 	GenericTilesExit();
403 
404 	BurnFreeMemIndex();
405 
406 	return 0;
407 }
408 
DrvPaletteUpdate()409 static void DrvPaletteUpdate()
410 {
411 	for (INT32 i = 0; i < 0x1000; i += 2)
412 	{
413 		UINT16 pal = BurnPalRAM[i] | (BurnPalRAM[i + 1] << 8);
414 
415 		INT32 b = ((pal >> 0) & 0xf) << 4;
416 		INT32 g = ((pal >> 4) & 0xf) << 4;
417 		INT32 r = ((pal >> 8) & 0xf) << 4;
418 
419 		BurnPalette[(i / 2)] = BurnHighCol(r,g,b,0);
420 	}
421 }
422 
draw_sprites()423 static void draw_sprites()
424 {
425 	for (INT32 offs = 0x1000 - 0x40; offs >= 0; offs -= 0x20)
426 	{
427 		INT32 code 	=   DrvZ80RAM[2][offs + 0];
428 		INT32 attr 	=   DrvZ80RAM[2][offs + 1];
429 		INT32 sx 	=   DrvZ80RAM[2][offs + 3] + ((attr & 0x10) << 4);
430 		INT32 sy 	= ((DrvZ80RAM[2][offs + 2] + 8) & 0xff) - 8;
431 		INT32 color	=   attr & 0x0f;
432 
433 		code += (attr & 0xe0) << 3;
434 		if (code & 0x400) code += (gfxbank & 0x30) * 0x40;
435 
436 		DrawGfxMaskTile(0, 0, code, sx - 64, sy - 8, 0, 0, color, 0xf);
437 	}
438 }
439 
DrvDraw()440 static INT32 DrvDraw()
441 {
442 	if (BurnRecalc) {
443 		DrvPaletteUpdate();
444 		BurnRecalc = 1;	// force update!
445 	}
446 
447 	BurnTransferClear(0x3ff);
448 
449 	if (nBurnLayer & 1) GenericTilemapDraw(0, pTransDraw, 0);
450 
451 	if (nSpriteEnable & 1) draw_sprites();
452 
453 	BurnTransferCopy(BurnPalette);
454 
455 	return 0;
456 }
457 
DrvFrame()458 static INT32 DrvFrame()
459 {
460 	if (DrvReset) {
461 		DrvDoReset();
462 	}
463 
464 	ZetNewFrame();
465 
466 	{
467 		memset (DrvInputs, 0xff, sizeof(DrvInputs));
468 
469 		for (INT32 i = 0; i < 8; i++) {
470 			DrvInputs[0] ^= DrvJoy1[i] << i;
471 			DrvInputs[1] ^= DrvJoy2[i] << i;
472 			DrvInputs[2] ^= DrvJoy3[i] << i;
473 		}
474 
475 		hold_coin.checklow(0, DrvInputs[0], 1<<7, 1);
476 		hold_coin.checklow(1, DrvInputs[0], 1<<5, 1);
477 	}
478 
479 	INT32 nInterleave = 256;
480 	INT32 nCyclesTotal[2] = { 6000000 / 60, 5000000 / 60 };
481 	INT32 nCyclesDone[2] = { 0, 0 };
482 
483 	MSM5205NewFrame(0, 5000000, nInterleave);
484 
485 	for (INT32 i = 0; i < nInterleave; i++)
486 	{
487 		ZetOpen(0);
488 		CPU_RUN(0, Zet);
489 		if (i == (nInterleave - 1)) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
490 		ZetClose();
491 
492 		ZetOpen(1);
493 		BurnTimerUpdateYM3812((i + 1) * (nCyclesTotal[1] / nInterleave));
494 		MSM5205UpdateScanline(i);
495 		ZetClose();
496 	}
497 
498 	ZetOpen(1);
499 
500 	BurnTimerEndFrameYM3812(nCyclesTotal[1]);
501 
502 	if (pBurnSoundOut) {
503 		BurnYM3812Update(pBurnSoundOut, nBurnSoundLen);
504 		MSM5205Render(0, pBurnSoundOut, nBurnSoundLen);
505 	}
506 
507 	ZetClose();
508 
509 	if (pBurnDraw) {
510 		BurnDrvRedraw();
511 	}
512 
513 	return 0;
514 }
515 
DrvScan(INT32 nAction,INT32 * pnMin)516 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
517 {
518 	struct BurnArea ba;
519 
520 	if (pnMin) {
521 		*pnMin = 0x029707;
522 	}
523 
524 	if (nAction & ACB_VOLATILE) {
525 		memset(&ba, 0, sizeof(ba));
526 		ba.Data	  = AllRam;
527 		ba.nLen	  = RamEnd - AllRam;
528 		ba.szName = "All Ram";
529 		BurnAcb(&ba);
530 
531 		ZetScan(nAction);
532 
533 		BurnYM3812Scan(nAction, pnMin);
534 		MSM5205Scan(nAction, pnMin);
535 
536 		SCAN_VAR(bankdata);
537 		SCAN_VAR(soundlatch);
538 		SCAN_VAR(adpcm_toggle);
539 		SCAN_VAR(adpcm_data);
540 
541 		hold_coin.scan();
542 	}
543 
544 	if (nAction & ACB_WRITE)
545 	{
546 		ZetOpen(0);
547 		rombank_write(bankdata[0]);
548 		rambank0_write(bankdata[1]);
549 		rambank1_write(bankdata[2]);
550 		ZetClose();
551 
552 		ZetOpen(1);
553 		sound_bankswitch(bankdata[3]);
554 		ZetClose();
555 	}
556 
557 	return 0;
558 }
559 
560 
561 // Disco Boy
562 
563 static struct BurnRomInfo discoboyRomDesc[] = {
564 	{ "u2",				0x10000, 0x44a4fefa, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
565 	{ "u18",			0x20000, 0x88d1282d, 1 | BRF_PRG | BRF_ESS }, //  1
566 
567 	{ "2.u28",			0x10000, 0x7c2ed174, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 #1 Code
568 	{ "1.u45",			0x10000, 0xc266c6df, 2 | BRF_PRG | BRF_ESS }, //  3
569 
570 	{ "5.u94",			0x10000, 0xdbd20836, 3 | BRF_GRA },           //  4 Sprites
571 	{ "6.u124",			0x40000, 0xe20d41f8, 3 | BRF_GRA },           //  5
572 	{ "7.u95",			0x10000, 0x1d5617a2, 3 | BRF_GRA },           //  6
573 	{ "8.u125",			0x40000, 0x30be1340, 3 | BRF_GRA },           //  7
574 
575 	{ "u80",			0x10000, 0x4cc642ae, 4 | BRF_GRA },           //  8 Background Tiles
576 	{ "u81",			0x10000, 0x9e04274e, 4 | BRF_GRA },           //  9
577 	{ "u78",			0x10000, 0x04571f70, 4 | BRF_GRA },           // 10
578 	{ "u79",			0x10000, 0x646f0f83, 4 | BRF_GRA },           // 11
579 
580 	{ "u50",			0x20000, 0x1557ca92, 5 | BRF_GRA },           // 12 Banked Background Tiles
581 	{ "u5",				0x20000, 0xa07df669, 5 | BRF_GRA },           // 13
582 	{ "u46",			0x20000, 0x764ffde4, 5 | BRF_GRA },           // 14
583 	{ "u49",			0x20000, 0x0b6c0d8d, 5 | BRF_GRA },           // 15
584 };
585 
586 STD_ROM_PICK(discoboy)
587 STD_ROM_FN(discoboy)
588 
589 struct BurnDriver BurnDrvDiscoboy = {
590 	"discoboy", NULL, NULL, NULL, "1993",
591 	"Disco Boy\0", NULL, "Soft Art Co.", "Miscellaneous",
592 	NULL, NULL, NULL, NULL,
593 	BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_POST90S, GBF_SHOOT | GBF_ACTION, 0,
594 	NULL, discoboyRomInfo, discoboyRomName, NULL, NULL, NULL, NULL, DiscoboyInputInfo, DiscoboyDIPInfo,
595 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &BurnRecalc, 0x800,
596 	240, 384, 3, 4
597 };
598 
599 
600 // Disco Boy (Promat license?)
601 
602 static struct BurnRomInfo discoboypRomDesc[] = {
603 	{ "discob.u2",		0x10000, 0x7f07afd1, 1 | BRF_PRG | BRF_ESS }, //  0 Z80 #0 Code
604 	{ "discob.u18",		0x20000, 0x05f0daaf, 1 | BRF_PRG | BRF_ESS }, //  1
605 
606 	{ "discob.u28",		0x10000, 0x7c2ed174, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 #1 Code
607 	{ "discob.u45",		0x10000, 0xc266c6df, 2 | BRF_PRG | BRF_ESS }, //  3
608 
609 	{ "discob.u94",		0x10000, 0xc436f1e5, 3 | BRF_GRA },           //  4 Sprites
610 	{ "discob.u124",	0x40000, 0x0b0bf653, 3 | BRF_GRA },           //  5
611 	{ "discob.u95",		0x10000, 0xddea540e, 3 | BRF_GRA },           //  6
612 	{ "discob.u125",	0x40000, 0xfcac2cb8, 3 | BRF_GRA },           //  7
613 
614 	{ "discob.u80",		0x10000, 0x48a7ebdf, 4 | BRF_GRA },           //  8 Background Tiles
615 	{ "discob.u81",		0x10000, 0x9ca358e1, 4 | BRF_GRA },           //  9
616 	{ "discob.u78",		0x10000, 0x2b39eb08, 4 | BRF_GRA },           // 10
617 	{ "discob.u79",		0x10000, 0x77ffc6bf, 4 | BRF_GRA },           // 11
618 
619 	{ "discob.u50",		0x40000, 0xea7231db, 5 | BRF_GRA },           // 12 Banked Background Tiles
620 	{ "discob.u5",		0x40000, 0xafeefecc, 5 | BRF_GRA },           // 13
621 	{ "discob.u46",		0x40000, 0x835c513b, 5 | BRF_GRA },           // 14
622 	{ "discob.u49",		0x40000, 0x9f884db4, 5 | BRF_GRA },           // 15
623 };
624 
625 STD_ROM_PICK(discoboyp)
626 STD_ROM_FN(discoboyp)
627 
628 struct BurnDriver BurnDrvDiscoboyp = {
629 	"discoboyp", "discoboy", NULL, NULL, "1993",
630 	"Disco Boy (Promat license?)\0", NULL, "Soft Art Co.", "Miscellaneous",
631 	NULL, NULL, NULL, NULL,
632 	BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_POST90S, GBF_SHOOT | GBF_ACTION, 0,
633 	NULL, discoboypRomInfo, discoboypRomName, NULL, NULL, NULL, NULL, DiscoboyInputInfo, DiscoboyDIPInfo,
634 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &BurnRecalc, 0x800,
635 	240, 384, 3, 4
636 };
637