1 // FB Alpha One Shot One Kill driver module
2 // Based on MAME driver by David Haywood and Paul Priest
3 
4 #include "tiles_generic.h"
5 #include "m68000_intf.h"
6 #include "z80_intf.h"
7 #include "burn_gun.h"
8 #include "burn_ym3812.h"
9 #include "msm6295.h"
10 
11 static UINT8 *AllMem;
12 static UINT8 *MemEnd;
13 static UINT8 *AllRam;
14 static UINT8 *RamEnd;
15 static UINT8 *Drv68KROM;
16 static UINT8 *DrvZ80ROM;
17 static UINT8 *DrvGfxROM0;
18 static UINT8 *DrvGfxROM1;
19 static UINT8 *DrvSndROM;
20 static UINT8 *Drv68KRAM;
21 static UINT8 *DrvMgRAM;
22 static UINT8 *DrvFgRAM;
23 static UINT8 *DrvBgRAM;
24 static UINT8 *DrvSprRAM;
25 static UINT8 *DrvPalRAM;
26 static UINT8 *DrvZ80RAM;
27 
28 static UINT32 *DrvPalette;
29 static UINT8 DrvRecalc;
30 
31 static UINT8 *DrvScroll;
32 static UINT8 *soundlatch;
33 
34 static UINT8 soundbank;
35 static INT32 input_x_wobble[2] = { 0, 0 };
36 static INT32 input_x[2] = { 0, 0 };
37 static INT32 input_y[2] = { 0, 0 };
38 static UINT8 DrvJoy1[8];
39 static UINT8 DrvJoy2[8];
40 static UINT8 DrvJoy3[8];
41 static UINT8 DrvInputs[3];
42 static UINT8 DrvDips[2];
43 static UINT8 DrvReset;
44 
45 static INT32 uses_gun = 0;
46 static INT16 DrvGun0 = 0;
47 static INT16 DrvGun1 = 0;
48 static INT16 DrvGun2 = 0;
49 static INT16 DrvGun3 = 0;
50 
51 #define A(a, b, c, d) {a, b, (UINT8*)(c), d}
52 static struct BurnInputInfo OneshotInputList[] = {
53 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 3,	"p1 coin"	},
54 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 start"	},
55 	A("P1 Gun X",    	BIT_ANALOG_REL, &DrvGun0,    "mouse x-axis"	),
56 	A("P1 Gun Y",    	BIT_ANALOG_REL, &DrvGun1,    "mouse y-axis"	),
57 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy2 + 4,	"p1 fire 1"	},
58 
59 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy1 + 4,	"p2 coin"	},
60 	{"P2 Start",		BIT_DIGITAL,	DrvJoy1 + 6,	"p2 start"	},
61 	A("P2 Gun X",    	BIT_ANALOG_REL, &DrvGun2,    "p2 x-axis"	),
62 	A("P2 Gun Y",    	BIT_ANALOG_REL, &DrvGun3,    "p2 y-axis"	),
63 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy3 + 4,	"p2 fire 1"	},
64 
65 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
66 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
67 	{"Dip B",			BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
68 };
69 #undef A
70 STDINPUTINFO(Oneshot)
71 
72 static struct BurnInputInfo MaddonnaInputList[] = {
73 	{"P1 Coin",			BIT_DIGITAL,	DrvJoy1 + 3,	"p1 coin"	},
74 	{"P1 Start",		BIT_DIGITAL,	DrvJoy1 + 5,	"p1 start"	},
75 	{"P1 Up",			BIT_DIGITAL,	DrvJoy2 + 0,	"p1 up"		},
76 	{"P1 Down",			BIT_DIGITAL,	DrvJoy2 + 1,	"p1 down"	},
77 	{"P1 Left",			BIT_DIGITAL,	DrvJoy2 + 2,	"p1 left"	},
78 	{"P1 Right",		BIT_DIGITAL,	DrvJoy2 + 3,	"p1 right"	},
79 	{"P1 Button 1",		BIT_DIGITAL,	DrvJoy2 + 4,	"p1 fire 1"	},
80 	{"P1 Button 2",		BIT_DIGITAL,	DrvJoy2 + 5,	"p1 fire 2"	},
81 
82 	{"P2 Coin",			BIT_DIGITAL,	DrvJoy1 + 4,	"p2 coin"	},
83 	{"P2 Start",		BIT_DIGITAL,	DrvJoy1 + 6,	"p2 start"	},
84 	{"P2 Up",			BIT_DIGITAL,	DrvJoy3 + 0,	"p2 up"		},
85 	{"P2 Down",			BIT_DIGITAL,	DrvJoy3 + 1,	"p2 down"	},
86 	{"P2 Left",			BIT_DIGITAL,	DrvJoy3 + 2,	"p2 left"	},
87 	{"P2 Right",		BIT_DIGITAL,	DrvJoy3 + 3,	"p2 right"	},
88 	{"P2 Button 1",		BIT_DIGITAL,	DrvJoy3 + 4,	"p2 fire 1"	},
89 	{"P2 Button 2",		BIT_DIGITAL,	DrvJoy3 + 5,	"p2 fire 2"	},
90 
91 	{"Reset",			BIT_DIGITAL,	&DrvReset,		"reset"		},
92 	{"Dip A",			BIT_DIPSWITCH,	DrvDips + 0,	"dip"		},
93 	{"Dip B",			BIT_DIPSWITCH,	DrvDips + 1,	"dip"		},
94 };
95 
96 STDINPUTINFO(Maddonna)
97 
98 static struct BurnDIPInfo OneshotDIPList[]=
99 {
100 	{0x0b, 0xff, 0xff, 0x10, NULL					},
101 	{0x0c, 0xff, 0xff, 0x00, NULL					},
102 
103 	{0   , 0xfe, 0   ,    4, "Coinage"				},
104 	{0x0b, 0x01, 0x03, 0x03, "3 Coins 1 Credits"	},
105 	{0x0b, 0x01, 0x03, 0x02, "2 Coins 1 Credits"	},
106 	{0x0b, 0x01, 0x03, 0x00, "1 Coin  1 Credits"	},
107 	{0x0b, 0x01, 0x03, 0x01, "1 Coin  2 Credits"	},
108 
109 	{0   , 0xfe, 0   ,    2, "Demo Sounds"			},
110 	{0x0b, 0x01, 0x10, 0x00, "Off"					},
111 	{0x0b, 0x01, 0x10, 0x10, "On"					},
112 
113 	{0   , 0xfe, 0   ,    2, "Start Round"			},
114 	{0x0b, 0x01, 0x40, 0x00, "Gun Trigger"			},
115 	{0x0b, 0x01, 0x40, 0x40, "Start Button"			},
116 
117 	{0   , 0xfe, 0   ,    2, "Gun Test"				},
118 	{0x0b, 0x01, 0x80, 0x00, "Off"					},
119 	{0x0b, 0x01, 0x80, 0x80, "On"					},
120 
121 	{0   , 0xfe, 0   ,    4, "Lives"				},
122 	{0x0c, 0x01, 0x03, 0x01, "1"					},
123 	{0x0c, 0x01, 0x03, 0x02, "2"					},
124 	{0x0c, 0x01, 0x03, 0x00, "3"					},
125 	{0x0c, 0x01, 0x03, 0x03, "5"					},
126 
127 	{0   , 0xfe, 0   ,    4, "Difficulty"			},
128 	{0x0c, 0x01, 0x30, 0x10, "Easy"					},
129 	{0x0c, 0x01, 0x30, 0x00, "Normal"				},
130 	{0x0c, 0x01, 0x30, 0x20, "Hard"					},
131 	{0x0c, 0x01, 0x30, 0x30, "Hardest"				},
132 
133 	{0   , 0xfe, 0   ,    2, "Round Select"			},
134 	{0x0c, 0x01, 0x40, 0x40, "Off"					},
135 	{0x0c, 0x01, 0x40, 0x00, "On"					},
136 
137 	{0   , 0xfe, 0   ,    4, "Free Play"			},
138 	{0x0c, 0x01, 0x80, 0x00, "Off"					},
139 	{0x0c, 0x01, 0x80, 0x80, "On"					},
140 };
141 
142 STDDIPINFO(Oneshot)
143 
144 static struct BurnDIPInfo MaddonnaDIPList[]=
145 {
146 	{0x11, 0xff, 0xff, 0x04, NULL					},
147 	{0x12, 0xff, 0xff, 0x1a, NULL					},
148 
149 	{0   , 0xfe, 0   ,    4, "Coinage"				},
150 	{0x11, 0x01, 0x03, 0x03, "3 Coins 1 Credits"	},
151 	{0x11, 0x01, 0x03, 0x02, "2 Coins 1 Credits"	},
152 	{0x11, 0x01, 0x03, 0x01, "2 Coins 2 Credits"	},
153 	{0x11, 0x01, 0x03, 0x00, "1 Coin  1 Credits"	},
154 
155 	{0   , 0xfe, 0   ,    2, "Girl Pictures"		},
156 	{0x11, 0x01, 0x04, 0x00, "Off"					},
157 	{0x11, 0x01, 0x04, 0x04, "On"					},
158 
159 	{0   , 0xfe, 0   ,    2, "Demo Sounds"			},
160 	{0x11, 0x01, 0x10, 0x10, "Off"					},
161 	{0x11, 0x01, 0x10, 0x00, "On"					},
162 
163 	{0   , 0xfe, 0   ,    2, "Invulnerability"		},
164 	{0x11, 0x01, 0x40, 0x00, "Off"					},
165 	{0x11, 0x01, 0x40, 0x40, "On"					},
166 
167 	{0   , 0xfe, 0   ,    4, "Difficulty"			},
168 	{0x12, 0x01, 0x03, 0x00, "Easy"					},
169 	{0x12, 0x01, 0x03, 0x01, "Normal"				},
170 	{0x12, 0x01, 0x03, 0x02, "Hard"					},
171 	{0x12, 0x01, 0x03, 0x03, "Hardest"				},
172 
173 	{0   , 0xfe, 0   ,    3, "Time Per Round"		},
174 	{0x12, 0x01, 0x0c, 0x08, "80 Seconds"			},
175 	{0x12, 0x01, 0x0c, 0x04, "90 Seconds"			},
176 	{0x12, 0x01, 0x0c, 0x00, "100 Seconds"			},
177 
178 	{0   , 0xfe, 0   ,    2, "Lives"				},
179 	{0x12, 0x01, 0x10, 0x10, "3"					},
180 	{0x12, 0x01, 0x10, 0x00, "5"					},
181 
182 	{0   , 0xfe, 0   ,    4, "Hurry Up!"			},
183 	{0x12, 0x01, 0xc0, 0x00, "Off"					},
184 	{0x12, 0x01, 0xc0, 0x40, "On - 10"				},
185 	{0x12, 0x01, 0xc0, 0x80, "On - 01"				},
186 	{0x12, 0x01, 0xc0, 0xc0, "On - 11"				},
187 };
188 
STDDIPINFO(Maddonna)189 STDDIPINFO(Maddonna)
190 
191 static void oki_bankswitch(INT32 data)
192 {
193 	soundbank = data;
194 
195 	INT32 bank = ((soundbank ^ 3) & 3) * 0x40000;
196 
197 	MSM6295SetBank(0, DrvSndROM + bank, 0, 0x3ffff);
198 }
199 
oneshot_main_write_word(UINT32 address,UINT16 data)200 static void __fastcall oneshot_main_write_word(UINT32 address, UINT16 data)
201 {
202 	switch (address)
203 	{
204 		case 0x190010:
205 			*soundlatch = data;
206 		return;
207 
208 		case 0x190018:
209 			oki_bankswitch(data);
210 		return;
211 	}
212 }
213 
oneshot_main_write_byte(UINT32 address,UINT8 data)214 static void __fastcall oneshot_main_write_byte(UINT32 address, UINT8 data)
215 {
216 	switch (address)
217 	{
218 		case 0x190010:
219 			*soundlatch = data;
220 		return;
221 
222 		case 0x190018:
223 			oki_bankswitch(data);
224 		return;
225 	}
226 }
227 
oneshot_main_read_byte(UINT32 address)228 static UINT8 __fastcall oneshot_main_read_byte(UINT32 address)
229 {
230 	switch (address)
231 	{
232 		case 0x190002:
233 		case 0x190003:
234 			return *soundlatch;
235 
236 		case 0x190026:
237 		case 0x190027:
238 			input_x_wobble[0] ^= 1;
239 			return input_x[0] ^ input_x_wobble[0];
240 
241 		case 0x19002e:
242 		case 0x19002f:
243 			input_x_wobble[1] ^= 1;
244 			return input_x[1] ^ input_x_wobble[1];
245 
246 		case 0x190036:
247 		case 0x190037:
248 			return input_y[0];
249 
250 		case 0x19003e:
251 		case 0x19003f:
252 			return input_y[1];
253 
254 		case 0x19c020:
255 		case 0x19c021:
256 			return DrvDips[0];
257 
258 		case 0x19c024:
259 		case 0x19c025:
260 			return DrvDips[1];
261 
262 		case 0x19c02c:
263 		case 0x19c02d:
264 			return DrvInputs[0];
265 
266 		case 0x19c030:
267 		case 0x19c031:
268 			return DrvInputs[1];
269 
270 		case 0x19c034:
271 		case 0x19c035:
272 			return DrvInputs[2];
273 	}
274 
275 	return 0;
276 }
277 
oneshot_main_read_word(UINT32 address)278 static UINT16 __fastcall oneshot_main_read_word(UINT32 address)
279 {
280 	switch (address)
281 	{
282 		case 0x190002:
283 			return *soundlatch;
284 
285 		case 0x190026:
286 			input_x_wobble[0] ^= 1;
287 			return input_x[0] ^ input_x_wobble[0];
288 
289 		case 0x19002e:
290 			input_x_wobble[1] ^= 1;
291 			return input_x[1] ^ input_x_wobble[1];
292 
293 		case 0x190036:
294 			return input_y[0];
295 
296 		case 0x19003e:
297 			return input_y[1];
298 
299 		case 0x19c020:
300 			return DrvDips[0];
301 
302 		case 0x19c024:
303 			return DrvDips[1];
304 
305 		case 0x19c02c:
306 			return DrvInputs[0];
307 
308 		case 0x19c030:
309 			return DrvInputs[1];
310 
311 		case 0x19c034:
312 			return DrvInputs[2];
313 	}
314 
315 	return 0;
316 }
317 
oneshot_sound_write(UINT16 address,UINT8 data)318 static void __fastcall oneshot_sound_write(UINT16 address, UINT8 data)
319 {
320 	switch (address)
321 	{
322 		case 0xe000:
323 		case 0xe001:
324 			BurnYM3812Write(0, address & 1, data);
325 		return;
326 
327 		case 0xe010:
328 			MSM6295Write(0, data);
329 		return;
330 	}
331 }
332 
oneshot_sound_read(UINT16 address)333 static UINT8 __fastcall oneshot_sound_read(UINT16 address)
334 {
335 	switch (address)
336 	{
337 		case 0xe000:
338 		case 0xe001:
339 			return BurnYM3812Read(0, address & 1);
340 
341 		case 0xe010:
342 			return MSM6295Read(0);
343 	}
344 
345 	return 0;
346 }
347 
tilemap_callback(background)348 static tilemap_callback( background )
349 {
350 	UINT16 *ram = (UINT16*)DrvBgRAM;
351 
352 	TILE_SET_INFO(0, BURN_ENDIAN_SWAP_INT16(ram[offs * 2 + 1]), 0, 0);
353 }
354 
tilemap_callback(midground)355 static tilemap_callback( midground )
356 {
357 	UINT16 *ram = (UINT16*)DrvMgRAM;
358 
359 	TILE_SET_INFO(1, BURN_ENDIAN_SWAP_INT16(ram[offs * 2 + 1]), 0, 0);
360 }
361 
tilemap_callback(foreground)362 static tilemap_callback( foreground )
363 {
364 	UINT16 *ram = (UINT16*)DrvFgRAM;
365 
366 	TILE_SET_INFO(2, BURN_ENDIAN_SWAP_INT16(ram[offs * 2 + 1]), 0, 0);
367 }
368 
DrvYM3812IrqHandler(INT32,INT32 nStatus)369 static void DrvYM3812IrqHandler(INT32, INT32 nStatus)
370 {
371 	ZetSetIRQLine(0, (nStatus) ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE);
372 }
373 
DrvDoReset()374 static INT32 DrvDoReset()
375 {
376 	memset (AllRam, 0, RamEnd - AllRam);
377 
378 	SekOpen(0);
379 	SekReset();
380 	SekClose();
381 
382 	ZetOpen(0);
383 	ZetReset();
384 	oki_bankswitch(3);
385 	MSM6295Reset(0);
386 	BurnYM3812Reset();
387 	ZetClose();
388 
389 	return 0;
390 }
391 
MemIndex()392 static INT32 MemIndex()
393 {
394 	UINT8 *Next; Next = AllMem;
395 
396 	Drv68KROM		= Next; Next += 0x040000;
397 	DrvZ80ROM		= Next; Next += 0x010000;
398 
399 	DrvGfxROM0		= Next; Next += 0x400000;
400 	DrvGfxROM1		= Next; Next += 0x400000;
401 
402 	MSM6295ROM		= Next;
403 	DrvSndROM		= Next; Next += 0x100000;
404 
405 	DrvPalette		= (UINT32*)Next; Next += 0x401 * sizeof(UINT32);
406 
407 	AllRam			= Next;
408 
409 	Drv68KRAM		= Next; Next += 0x008000;
410 	DrvMgRAM		= Next; Next += 0x001000;
411 	DrvFgRAM		= Next; Next += 0x001000;
412 	DrvBgRAM		= Next; Next += 0x001000;
413 	DrvSprRAM		= Next; Next += 0x001000;
414 	DrvPalRAM		= Next; Next += 0x000800;
415 	DrvScroll		= Next; Next += 0x000400; // 1024 is minimum 68k page size
416 
417 	soundlatch		= Next; // soundlatch is first byte of z80 ram
418 	DrvZ80RAM		= Next; Next += 0x000800;
419 
420 	RamEnd			= Next;
421 	MemEnd			= Next;
422 
423 	return 0;
424 }
425 
DrvGfxDecode()426 static INT32 DrvGfxDecode()
427 {
428 	INT32 Plane[8]  = { STEP8(0,(0x80000*8)) };
429 	INT32 XOffs[16] = { STEP8(0,1), STEP8(64,1) };
430 	INT32 YOffs[16] = { STEP8(0,8), STEP8(128,8) };
431 
432 	UINT8 *tmp = (UINT8*)BurnMalloc(0x400000);
433 	if (tmp == NULL) {
434 		return 1;
435 	}
436 
437 	memcpy (tmp, DrvGfxROM0, 0x400000);
438 
439 	GfxDecode(0x04000, 8, 16, 16, Plane, XOffs, YOffs, 0x100, tmp, DrvGfxROM0);
440 	GfxDecode(0x10000, 8,  8,  8, Plane, XOffs, YOffs, 0x040, tmp, DrvGfxROM1);
441 
442 	BurnFree (tmp);
443 
444 	return 0;
445 }
446 
DrvInit(INT32 game_select)447 static INT32 DrvInit(INT32 game_select)
448 {
449 	AllMem = NULL;
450 	MemIndex();
451 	INT32 nLen = MemEnd - (UINT8 *)0;
452 	if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
453 	memset(AllMem, 0, nLen);
454 	MemIndex();
455 
456 	{
457 		if (BurnLoadRom(Drv68KROM  + 0x000001,  0, 2)) return 1;
458 		if (BurnLoadRom(Drv68KROM  + 0x000000,  1, 2)) return 1;
459 
460 		if (BurnLoadRom(DrvZ80ROM  + 0x000000,  2, 1)) return 1;
461 
462 		if (BurnLoadRom(DrvGfxROM0 + 0x000000,  3, 1)) return 1;
463 		if (BurnLoadRom(DrvGfxROM0 + 0x080000,  4, 1)) return 1;
464 		if (BurnLoadRom(DrvGfxROM0 + 0x100000,  5, 1)) return 1;
465 		if (BurnLoadRom(DrvGfxROM0 + 0x180000,  6, 1)) return 1;
466 		if (BurnLoadRom(DrvGfxROM0 + 0x200000,  7, 1)) return 1;
467 		if (BurnLoadRom(DrvGfxROM0 + 0x280000,  8, 1)) return 1;
468 		if (BurnLoadRom(DrvGfxROM0 + 0x300000,  9, 1)) return 1;
469 		if (BurnLoadRom(DrvGfxROM0 + 0x380000, 10, 1)) return 1;
470 
471 		if (game_select == 0)
472 		{
473 			if (BurnLoadRom(DrvSndROM + 0x000000, 11, 1)) return 1;
474 			if (BurnLoadRom(DrvSndROM + 0x080000, 12, 1)) return 1;
475 		}
476 
477 		DrvGfxDecode();
478 	}
479 
480 	SekInit(0, 0x68000);
481 	SekOpen(0);
482 	SekMapMemory(Drv68KROM,		0x000000, 0x03ffff, MAP_ROM);
483 	SekMapMemory(Drv68KRAM,		0x080000, 0x087fff, MAP_RAM);
484 	SekMapMemory(DrvPalRAM,		0x0c0000, 0x0c07ff, MAP_RAM);
485 	SekMapMemory(DrvSprRAM,		0x120000, 0x120fff, MAP_RAM);
486 	SekMapMemory(DrvMgRAM,		0x180000, 0x180fff, MAP_RAM);
487 	SekMapMemory(DrvFgRAM,		0x181000, 0x181fff, MAP_RAM);
488 	SekMapMemory(DrvBgRAM,		0x182000, 0x182fff, MAP_RAM);
489 	SekMapMemory(DrvScroll,		0x188000, 0x1883ff, MAP_WRITE); //0-f
490 	SekSetWriteWordHandler(0,	oneshot_main_write_word);
491 	SekSetWriteByteHandler(0,	oneshot_main_write_byte);
492 	SekSetReadWordHandler(0,	oneshot_main_read_word);
493 	SekSetReadByteHandler(0,	oneshot_main_read_byte);
494 	SekClose();
495 
496 	ZetInit(0);
497 	ZetOpen(0);
498 	ZetMapMemory(DrvZ80ROM,		0x0000, 0x7fff, MAP_ROM);
499 	ZetMapMemory(DrvZ80RAM,		0x8000, 0x87ff, MAP_RAM);
500 	ZetSetWriteHandler(oneshot_sound_write);
501 	ZetSetReadHandler(oneshot_sound_read);
502 	ZetClose();
503 
504 	BurnYM3812Init(1, 3500000, &DrvYM3812IrqHandler, 0);
505 	BurnTimerAttachYM3812(&ZetConfig, 5000000);
506 	BurnYM3812SetRoute(0, BURN_SND_YM3812_ROUTE, 1.00, BURN_SND_ROUTE_BOTH);
507 
508 	MSM6295Init(0, 1056000 / 132, 1);
509 	MSM6295SetRoute(0, (game_select ? 0 : 1.00), BURN_SND_ROUTE_BOTH);
510 
511 	GenericTilesInit();
512 	GenericTilemapInit(0, TILEMAP_SCAN_ROWS, background_map_callback, 16, 16, 32, 32);
513 	GenericTilemapInit(1, TILEMAP_SCAN_ROWS, midground_map_callback,  16, 16, 32, 32);
514 	GenericTilemapInit(2, TILEMAP_SCAN_ROWS, foreground_map_callback, 16, 16, 32, 32);
515 	GenericTilemapSetGfx(0, DrvGfxROM0, 8, 16, 16, 0x400000, 0x000, 0);
516 	GenericTilemapSetGfx(1, DrvGfxROM0, 8, 16, 16, 0x400000, 0x200, 0);
517 	GenericTilemapSetGfx(2, DrvGfxROM0, 8, 16, 16, 0x400000, 0x300, 0);
518 	GenericTilemapSetTransparent(0, 0);
519 	GenericTilemapSetTransparent(1, 0);
520 	GenericTilemapSetTransparent(2, 0);
521 
522 	if (uses_gun)
523 		BurnGunInit(2, true);
524 
525 	DrvDoReset();
526 
527 	return 0;
528 }
529 
DrvExit()530 static INT32 DrvExit()
531 {
532 	MSM6295Exit(0);
533 	BurnYM3812Exit();
534 
535 	SekExit();
536 	ZetExit();
537 
538 	if (uses_gun) {
539 		BurnGunExit();
540 		uses_gun = 0;
541 	}
542 
543 	GenericTilesExit();
544 
545 	BurnFree (AllMem);
546 
547 	return 0;
548 }
549 
DrvPaletteUpdate()550 static void DrvPaletteUpdate()
551 {
552 	UINT16 *p = (UINT16*)DrvPalRAM;
553 
554 	for (INT32 i = 0; i < 0x800/2; i++)
555 	{
556 		INT32 r = (BURN_ENDIAN_SWAP_INT16(p[i]) >>  0) & 0x1f;
557 		INT32 g = (BURN_ENDIAN_SWAP_INT16(p[i]) >>  5) & 0x1f;
558 		INT32 b = (BURN_ENDIAN_SWAP_INT16(p[i]) >> 10) & 0x1f;
559 
560 		r = (r << 3) | (r >> 2);
561 		g = (g << 3) | (g >> 2);
562 		b = (b << 3) | (b >> 2);
563 
564 		DrvPalette[i] = BurnHighCol(r,g,b,0);
565 	}
566 }
567 
draw_sprites()568 static void draw_sprites()
569 {
570 	UINT16 *source = (UINT16*)DrvSprRAM;
571 
572 	for (INT32 i = 0; i < 0x1000 / 2; i+=4)
573 	{
574 		if (source[i + 0] == BURN_ENDIAN_SWAP_INT16(0x0001))
575 			break;
576 
577 		INT32 num   = (BURN_ENDIAN_SWAP_INT16(source[i + 1]));
578 		INT32 xsize = (BURN_ENDIAN_SWAP_INT16(source[i + 2]) & 0x000f) + 1;
579 		INT32 ysize = (BURN_ENDIAN_SWAP_INT16(source[i + 3]) & 0x000f) + 1;
580 
581 		INT32 xpos  = (BURN_ENDIAN_SWAP_INT16(source[i + 2]) >> 7) - 8;
582 		INT32 ypos  = (BURN_ENDIAN_SWAP_INT16(source[i + 3]) >> 7) - 6;
583 
584 		for (INT32 blockx = 0; blockx < xsize; blockx++)
585 		{
586 			for (INT32 blocky = 0; blocky < ysize; blocky++)
587 			{
588 				Render8x8Tile_Mask_Clip(pTransDraw, num + (blocky * xsize) + blockx, xpos + blockx * 8,         ypos + blocky * 8, 0, 8, 0, 0x100, DrvGfxROM1);
589 				Render8x8Tile_Mask_Clip(pTransDraw, num + (blocky * xsize) + blockx, xpos + blockx * 8 - 0x200, ypos + blocky * 8, 0, 8, 0, 0x100, DrvGfxROM1);
590 			}
591 		}
592 	}
593 }
594 
OneshotDraw()595 static INT32 OneshotDraw()
596 {
597 	if (DrvRecalc) {
598 		DrvPaletteUpdate();
599 		DrvRecalc = 1;
600 	}
601 
602 	BurnTransferClear(0x400);
603 
604 	UINT16 *scroll = (UINT16*)DrvScroll;
605 
606 	GenericTilemapSetScrollX(1, BURN_ENDIAN_SWAP_INT16(scroll[0]) - 0x1f5);
607 	GenericTilemapSetScrollY(1, BURN_ENDIAN_SWAP_INT16(scroll[1]));
608 
609 	BurnTransferClear();
610 
611 	if (nBurnLayer & 1) GenericTilemapDraw(0, pTransDraw, 0);
612 	if (nBurnLayer & 2) GenericTilemapDraw(1, pTransDraw, 0);
613 	if (nSpriteEnable & 1) draw_sprites();
614 	if (nBurnLayer & 4) GenericTilemapDraw(2, pTransDraw, 0);
615 
616 	BurnTransferCopy(DrvPalette);
617 
618 	for (INT32 i = 0; i < nBurnGunNumPlayers; i++) {
619 		BurnGunDrawTarget(i, BurnGunX[i] >> 8, BurnGunY[i] >> 8);
620 	}
621 
622 	return 0;
623 }
624 
MaddonnaDraw()625 static INT32 MaddonnaDraw()
626 {
627 	if (DrvRecalc) {
628 		DrvPaletteUpdate();
629 		DrvRecalc = 1;
630 	}
631 
632 	BurnTransferClear(0x400);
633 
634 	UINT16 *scroll = (UINT16*)DrvScroll;
635 
636 	GenericTilemapSetScrollY(1, BURN_ENDIAN_SWAP_INT16(scroll[1]));
637 
638 	GenericTilemapDraw(1, pTransDraw, 0);
639 	GenericTilemapDraw(2, pTransDraw, 0);
640 	GenericTilemapDraw(0, pTransDraw, 0);
641 	draw_sprites();
642 
643 	BurnTransferCopy(DrvPalette);
644 
645 	return 0;
646 }
647 
DrvFrame()648 static INT32 DrvFrame()
649 {
650 	if (DrvReset) {
651 		DrvDoReset();
652 	}
653 
654 	ZetNewFrame();
655 
656 	{
657 		memset (DrvInputs, 0, 3);
658 
659 		for (INT32 i = 0; i < 8; i++) {
660 			DrvInputs[0] ^= DrvJoy1[i] << i;
661 			DrvInputs[1] ^= DrvJoy2[i] << i;
662 			DrvInputs[2] ^= DrvJoy3[i] << i;
663 		}
664 
665 		if (uses_gun) {
666 			input_x[0] = ((BurnGunReturnX(0) & 0xff) * 320 / 256) + 30;
667 			input_y[0] = ((BurnGunReturnY(0) & 0xff) * 240 / 256) - 10;
668 			if (input_y[0] < 0) input_y[0] = 0;
669 
670 			input_x[1] = ((BurnGunReturnX(1) & 0xff) * 320 / 256) + 20;
671 			input_y[1] = ((BurnGunReturnY(1) & 0xff) * 240 / 256) + 00;
672 
673 			BurnGunMakeInputs(0, (INT16)DrvGun0, (INT16)DrvGun1);
674 			BurnGunMakeInputs(1, (INT16)DrvGun2, (INT16)DrvGun3);
675 		}
676 
677 	}
678 
679 	INT32 nInterleave = 10;
680 	INT32 nCyclesTotal[2] = { 12000000 / 60, 5000000 / 60 };
681 	INT32 nCyclesDone[2] = { 0, 0 };
682 
683 	SekOpen(0);
684 	ZetOpen(0);
685 
686 	for (INT32 i = 0; i < nInterleave; i++) {
687 		nCyclesDone[0] += SekRun(nCyclesTotal[0] / nInterleave);
688 		if (i == (nInterleave - 1)) SekSetIRQLine(4, CPU_IRQSTATUS_AUTO);
689 
690 		BurnTimerUpdateYM3812((1 + i) * nCyclesTotal[1] / nInterleave);
691 	}
692 
693 	BurnTimerEndFrameYM3812(nCyclesTotal[1]);
694 
695 	if (pBurnSoundOut) {
696 		BurnYM3812Update(pBurnSoundOut, nBurnSoundLen);
697 		MSM6295Render(0, pBurnSoundOut, nBurnSoundLen);
698 	}
699 
700 	ZetClose();
701 	SekClose();
702 
703 	if (pBurnDraw) {
704 		BurnDrvRedraw();
705 	}
706 
707 	return 0;
708 }
709 
DrvScan(INT32 nAction,INT32 * pnMin)710 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
711 {
712 	struct BurnArea ba;
713 
714 	if (pnMin) {
715 		*pnMin = 0x029707;
716 	}
717 
718 	if (nAction & ACB_VOLATILE) {
719 		memset(&ba, 0, sizeof(ba));
720 
721 		ba.Data	  = AllRam;
722 		ba.nLen	  = RamEnd - AllRam;
723 		ba.szName = "All Ram";
724 		BurnAcb(&ba);
725 
726 		SekScan(nAction);
727 		ZetScan(nAction);
728 
729 		if (uses_gun) {
730 			BurnGunScan();
731 		}
732 
733 		BurnYM3812Scan(nAction, pnMin);
734 		MSM6295Scan(nAction, pnMin);
735 
736 		SCAN_VAR(soundbank);
737 	}
738 
739 	if (nAction & ACB_WRITE) {
740 		oki_bankswitch(soundbank);
741 	}
742 
743 	return 0;
744 }
745 
746 
747 // One Shot One Kill
748 
749 static struct BurnRomInfo oneshotRomDesc[] = {
750 	{ "1shot-u.a24",	0x20000, 0x0ecd33da, 1 | BRF_PRG | BRF_ESS }, //  0 68K code
751 	{ "1shot-u.a22",	0x20000, 0x26c3ae2d, 1 | BRF_PRG | BRF_ESS }, //  1
752 
753 	{ "1shot.ua2",		0x10000, 0xf655b80e, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 code
754 
755 	{ "1shot-ui.16a",	0x80000, 0xf765f9a2, 3 | BRF_GRA },           //  3 Graphics
756 	{ "1shot-ui.13a",	0x80000, 0x3361b5d8, 3 | BRF_GRA },           //  4
757 	{ "1shot-ui.11a",	0x80000, 0x8f8bd027, 3 | BRF_GRA },           //  5
758 	{ "1shot-ui.08a",	0x80000, 0x254b1701, 3 | BRF_GRA },           //  6
759 	{ "1shot-ui.16",	0x80000, 0xff246b27, 3 | BRF_GRA },           //  7
760 	{ "1shot-ui.13",	0x80000, 0x80342e83, 3 | BRF_GRA },           //  8
761 	{ "1shot-ui.11",	0x80000, 0xb8938345, 3 | BRF_GRA },           //  9
762 	{ "1shot-ui.08",	0x80000, 0xc9953bef, 3 | BRF_GRA },           // 10
763 
764 	{ "1shot.u15",		0x80000, 0xe3759a47, 4 | BRF_SND },           // 11 Samples
765 	{ "1shot.u14",		0x80000, 0x222e33f8, 4 | BRF_SND },           // 12
766 
767 	{ "1shot.mb",		0x10000, 0x6b213183, 0 | BRF_OPT },           // 13 Unknown
768 };
769 
770 STD_ROM_PICK(oneshot)
STD_ROM_FN(oneshot)771 STD_ROM_FN(oneshot)
772 
773 static INT32 OneshotInit()
774 {
775 	uses_gun = 1;
776 
777 	return DrvInit(0);
778 }
779 
780 struct BurnDriver BurnDrvOneshot = {
781 	"oneshot", NULL, NULL, NULL, "1996",
782 	"One Shot One Kill\0", NULL, "Promat", "Miscellaneous",
783 	NULL, NULL, NULL, NULL,
784 	BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_SHOOT, 0,
785 	NULL, oneshotRomInfo, oneshotRomName, NULL, NULL, NULL, NULL, OneshotInputInfo, OneshotDIPInfo,
786 	OneshotInit, DrvExit, DrvFrame, OneshotDraw, DrvScan, &DrvRecalc, 0x400,
787 	320, 240, 4, 3
788 };
789 
790 
791 // Mad Donna (set 1)
792 
793 static struct BurnRomInfo maddonnaRomDesc[] = {
794 	{ "maddonna.b16",	0x20000, 0x643f9054, 1 | BRF_PRG | BRF_ESS }, //  0 68K code
795 	{ "maddonna.b15",	0x20000, 0xe36c0e26, 1 | BRF_PRG | BRF_ESS }, //  1
796 
797 	{ "x13.ua2",		0x10000, 0xf2080071, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 code
798 
799 	{ "maddonna.b5",	0x80000, 0x838d3244, 3 | BRF_GRA },           //  3 Graphics
800 	{ "maddonna.b7",	0x80000, 0x4920d2ec, 3 | BRF_GRA },           //  4
801 	{ "maddonna.b9",	0x80000, 0x3a8a3feb, 3 | BRF_GRA },           //  5
802 	{ "maddonna.b11",	0x80000, 0x6f9b7fdf, 3 | BRF_GRA },           //  6
803 	{ "maddonna.b6",	0x80000, 0xb02e9e0e, 3 | BRF_GRA },           //  7
804 	{ "maddonna.b8",	0x80000, 0x03f1de40, 3 | BRF_GRA },           //  8
805 	{ "maddonna.b10",	0x80000, 0x87936423, 3 | BRF_GRA },           //  9
806 	{ "maddonna.b12",	0x80000, 0x879ab23c, 3 | BRF_GRA },           // 10
807 
808 	{ "x1",				0x10000, 0x6b213183, 0 | BRF_OPT },           // 11 Unknown
809 };
810 
811 STD_ROM_PICK(maddonna)
STD_ROM_FN(maddonna)812 STD_ROM_FN(maddonna)
813 
814 static INT32 MaddonnaInit()
815 {
816 	return DrvInit(1);
817 }
818 
819 struct BurnDriver BurnDrvMaddonna = {
820 	"maddonna", NULL, NULL, NULL, "1995",
821 	"Mad Donna (set 1)\0", NULL, "Tuning", "Miscellaneous",
822 	NULL, NULL, NULL, NULL,
823 	BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_MAZE, 0,
824 	NULL, maddonnaRomInfo, maddonnaRomName, NULL, NULL, NULL, NULL, MaddonnaInputInfo, MaddonnaDIPInfo,
825 	MaddonnaInit, DrvExit, DrvFrame, MaddonnaDraw, DrvScan, &DrvRecalc, 0x400,
826 	320, 240, 4, 3
827 };
828 
829 
830 // Mad Donna (set 2)
831 
832 static struct BurnRomInfo maddonnbRomDesc[] = {
833 	{ "maddonnb.b16",	0x20000, 0x00000000, 1 | BRF_NODUMP | BRF_PRG | BRF_ESS }, //  0 68K code
834 	{ "maddonnb.b15",	0x20000, 0x00000000, 1 | BRF_NODUMP | BRF_PRG | BRF_ESS }, //  1
835 
836 	{ "x13.ua2",		0x10000, 0xf2080071, 2 | BRF_PRG | BRF_ESS }, //  2 Z80 code
837 
838 	{ "x5.16a",			0x80000, 0x1aae0ad3, 3 | BRF_GRA },           //  3 Graphics
839 	{ "x7.13a",			0x80000, 0x39d13e25, 3 | BRF_GRA },           //  4
840 	{ "x9.11a",			0x80000, 0x2027faeb, 3 | BRF_GRA },           //  5
841 	{ "x11.08a",		0x80000, 0x4afcfba6, 3 | BRF_GRA },           //  6
842 	{ "x6.16",			0x80000, 0x7b893e78, 3 | BRF_GRA },           //  7
843 	{ "x8.13",			0x80000, 0xfed90a1f, 3 | BRF_GRA },           //  8
844 	{ "x10.11",			0x80000, 0x479d718c, 3 | BRF_GRA },           //  9
845 	{ "x12.08",			0x80000, 0xd56ca9f8, 3 | BRF_GRA },           // 10
846 
847 	{ "x1",				0x10000, 0x6b213183, 0 | BRF_OPT },           // 11 Unknown
848 };
849 
850 STD_ROM_PICK(maddonnb)
851 STD_ROM_FN(maddonnb)
852 
853 struct BurnDriverD BurnDrvMaddonnb = {
854 	"maddonnb", "maddonna", NULL, NULL, "1995",
855 	"Mad Donna (set 2)\0", NULL, "Tuning", "Miscellaneous",
856 	NULL, NULL, NULL, NULL,
857 	BDF_CLONE, 2, HARDWARE_MISC_POST90S, GBF_MAZE, 0,
858 	NULL, maddonnbRomInfo, maddonnbRomName, NULL, NULL, NULL, NULL, MaddonnaInputInfo, MaddonnaDIPInfo,
859 	MaddonnaInit, DrvExit, DrvFrame, MaddonnaDraw, DrvScan, &DrvRecalc, 0x400,
860 	320, 240, 4, 3
861 };
862