1 // FinalBurn Neo Dr. Tomy driver module
2 // Based on MAME driver by Pierpaolo Prazzoli
3 
4 #include "tiles_generic.h"
5 #include "m68000_intf.h"
6 #include "msm6295.h"
7 #include "burn_pal.h"
8 
9 static UINT8 *AllMem;
10 static UINT8 *MemEnd;
11 static UINT8 *RamStart;
12 static UINT8 *RamEnd;
13 static UINT8 *Drv68KROM;
14 static UINT8 *DrvGfxROM[2];
15 static UINT8 *DrvSndROM;
16 static UINT8 *DrvSprRAM;
17 static UINT8 *Drv68KRAM;
18 static UINT8 *DrvVidRAM;
19 
20 static UINT8 DrvRecalc;
21 
22 static INT32 okibank;
23 
24 static UINT8 DrvJoy1[8];
25 static UINT8 DrvJoy2[8];
26 static UINT8 DrvDips[2];
27 static UINT8 DrvInputs[2];
28 static UINT8 DrvReset;
29 
30 static struct BurnInputInfo DrvInputList[] = {
31 	{"Coin 1", 		BIT_DIGITAL  , DrvJoy1 + 6, "p1 coin"	},
32 	{"Coin 2", 		BIT_DIGITAL  , DrvJoy1 + 7, "p2 coin"	},
33 
34 	{"P1 Start", 	BIT_DIGITAL  , DrvJoy2 + 6, "p1 start"	},
35 	{"P1 Up", 		BIT_DIGITAL  , DrvJoy1 + 0, "p1 up"		},
36 	{"P1 Down", 	BIT_DIGITAL  , DrvJoy1 + 1, "p1 down"	},
37 	{"P1 Left", 	BIT_DIGITAL  , DrvJoy1 + 3, "p1 left"	},
38 	{"P1 Right", 	BIT_DIGITAL  , DrvJoy1 + 2, "p1 right"	},
39 	{"P1 Button 1", BIT_DIGITAL  , DrvJoy1 + 5, "p1 fire 1"	},
40 	{"P1 Button 2", BIT_DIGITAL  , DrvJoy1 + 4, "p1 fire 2"	},
41 
42 	{"P2 Start", 	BIT_DIGITAL  , DrvJoy2 + 7, "p2 start"	},
43 	{"P2 Up", 		BIT_DIGITAL  , DrvJoy2 + 0, "p2 up"		},
44 	{"P2 Down", 	BIT_DIGITAL  , DrvJoy2 + 1, "p2 down"	},
45 	{"P2 Left",		BIT_DIGITAL  , DrvJoy2 + 3, "p2 left" 	},
46 	{"P2 Right",	BIT_DIGITAL  , DrvJoy2 + 2, "p2 right"	},
47 	{"P2 Button 1",	BIT_DIGITAL  , DrvJoy2 + 5, "p2 fire 1"	},
48 	{"P2 Button 2",	BIT_DIGITAL  , DrvJoy2 + 4, "p2 fire 2"	},
49 
50 	{"Reset",	  	BIT_DIGITAL  , &DrvReset,   "reset"		},
51 	{"Dip 1",	  	BIT_DIPSWITCH, DrvDips + 0, "dip"		},
52 	{"Dip 2",	  	BIT_DIPSWITCH, DrvDips + 1, "dip"		},
53 };
54 
55 STDINPUTINFO(Drv)
56 
57 static struct BurnDIPInfo DrvDIPList[]=
58 {
59 	{0x11, 0xff, 0xff, 0xff, NULL 					},
60 	{0x12, 0xff, 0xff, 0xaf, NULL 					},
61 
62 	{0   , 0xfe, 0   , 11  , "Coin A" 				},
63 	{0x11, 0x01, 0x0f, 0x0a, "2 Coins 1 Credit"		},
64 	{0x11, 0x01, 0x0f, 0x07, "3 Coins 2 Credits"	},
65 	{0x11, 0x01, 0x0f, 0x00, "5 Coins 4 Credits"	},
66 	{0x11, 0x01, 0x0f, 0x0f, "1 Coin  1 Credit"		},
67 	{0x11, 0x01, 0x0f, 0x06, "3 Coins 4 Credits"	},
68 	{0x11, 0x01, 0x0f, 0x09, "2 Coins 3 Credits"	},
69 	{0x11, 0x01, 0x0f, 0x0e, "1 Coin  2 Credits"	},
70 	{0x11, 0x01, 0x0f, 0x08, "2 Coins 5 Credits"	},
71 	{0x11, 0x01, 0x0f, 0x0d, "1 Coin  3 Credits"	},
72 	{0x11, 0x01, 0x0f, 0x0c, "1 Coin  4 Credits"	},
73 	{0x11, 0x01, 0x0f, 0x0b, "1 Coin  5 Credits"	},
74 
75 	{0   , 0xfe, 0   , 11  , "Coin B" },
76 	{0x11, 0x01, 0xf0, 0xa0, "2 Coins 1 Credit" 	},
77 	{0x11, 0x01, 0xf0, 0x70, "3 Coins 2 Credits"	},
78 	{0x11, 0x01, 0xf0, 0x00, "5 Coins 4 Credits"	},
79 	{0x11, 0x01, 0xf0, 0xf0, "1 Coin  1 Credit"		},
80 	{0x11, 0x01, 0xf0, 0x60, "3 Coins 4 Credits"	},
81 	{0x11, 0x01, 0xf0, 0x90, "2 Coins 3 Credits"	},
82 	{0x11, 0x01, 0xf0, 0xe0, "1 Coin  2 Credits"	},
83 	{0x11, 0x01, 0xf0, 0x80, "2 Coins 5 Credits"	},
84 	{0x11, 0x01, 0xf0, 0xd0, "1 Coin  3 Credits"	},
85 	{0x11, 0x01, 0xf0, 0xc0, "1 Coin  4 Credits"	},
86 	{0x11, 0x01, 0xf0, 0xb0, "1 Coin  5 Credits"	},
87 
88 	{0   , 0xfe, 0   , 2   , "Time"					},
89 	{0x12, 0x01, 0x01, 0x00, "Less"					},
90 	{0x12, 0x01, 0x01, 0x01, "More"					},
91 
92 	{0   , 0xfe, 0   , 2   , "Number of Virus"		},
93 	{0x12, 0x01, 0x02, 0x02, "Less"					},
94 	{0x12, 0x01, 0x02, 0x00, "More"					},
95 
96 	{0   , 0xfe, 0   , 2   , "Test Mode"			},
97 	{0x12, 0x01, 0x08, 0x08, "Off"					},
98 	{0x12, 0x01, 0x08, 0x00, "On"					},
99 
100 	{0   , 0xfe, 0   , 2   , "Demo Sounds"			},
101 	{0x12, 0x01, 0x10, 0x10, "Off"					},
102 	{0x12, 0x01, 0x10, 0x00, "On"					},
103 
104 	{0   , 0xfe, 0   , 2   , "Language"				},
105 	{0x12, 0x01, 0x20, 0x20, "English"				},
106 	{0x12, 0x01, 0x20, 0x00, "Italian"				},
107 
108 	{0   , 0xfe, 0   , 2   , "Allow Continue"		},
109 	{0x12, 0x01, 0x40, 0x40, "No"					},
110 	{0x12, 0x01, 0x40, 0x00, "Yes"					},
111 };
112 
STDDIPINFO(Drv)113 STDDIPINFO(Drv)
114 
115 static inline void set_okibank(UINT8 data)
116 {
117 	okibank = data & 3;
118 
119 	MSM6295SetBank(0, DrvSndROM + (okibank * 0x20000), 0x20000, 0x3ffff);
120 }
121 
drtomy_read_byte(UINT32 address)122 static UINT8 __fastcall drtomy_read_byte(UINT32 address)
123 {
124 	switch (address)
125 	{
126 		case 0x700001:
127 			return DrvDips[0];
128 
129 		case 0x700003:
130 			return DrvDips[1];
131 
132 		case 0x700005:
133 			return DrvInputs[0];
134 
135 		case 0x700007:
136 			return DrvInputs[1];
137 
138 		case 0x70000f:
139 			return MSM6295Read(0);
140 	}
141 
142 	return 0;
143 }
144 
drtomy_write_byte(UINT32 address,UINT8 data)145 static void __fastcall drtomy_write_byte(UINT32 address, UINT8 data)
146 {
147 	switch (address)
148 	{
149 		case 0x70000d:
150 			set_okibank(data);
151 		return;
152 
153 		case 0x70000f:
154 			MSM6295Write(0, data);
155 		return;
156 	}
157 }
158 
drtomy_write_word(UINT32 address,UINT16 data)159 static void __fastcall drtomy_write_word(UINT32 address, UINT16 data)
160 {
161 	if ((address & 0xfff800) == 0x200000) {
162 		*((UINT16*)(BurnPalRAM + (address & 0x7fe))) = data;
163 		if (address < 0x200600) BurnPaletteWrite_xRRRRRGGGGGBBBBB(address & 0x7fe);
164 		return;
165 	}
166 }
167 
tilemap_callback(background)168 static tilemap_callback( background )
169 {
170 	UINT16 *ram = (UINT16*)(DrvVidRAM + 0x1000);
171 
172 	INT32 attr = BURN_ENDIAN_SWAP_INT16(ram[offs]);
173 
174 	TILE_SET_INFO(0, attr, attr >> 12, 0);
175 }
176 
tilemap_callback(foreground)177 static tilemap_callback( foreground )
178 {
179 	UINT16 *ram = (UINT16*)(DrvVidRAM + 0x0000);
180 
181 	INT32 attr = BURN_ENDIAN_SWAP_INT16(ram[offs]);
182 
183 	INT32 flags = ((attr & 0xfff) == 0) ? TILE_SKIP : 0;
184 
185 	TILE_SET_INFO(1, attr, attr >> 12, flags);
186 }
187 
DrvDoReset()188 static INT32 DrvDoReset()
189 {
190 	memset (RamStart, 0, RamEnd - RamStart);
191 
192 	SekOpen(0);
193 	SekReset();
194 	SekClose();
195 
196 	MSM6295Reset(0);
197 
198 	set_okibank(0);
199 
200 	return 0;
201 }
202 
MemIndex()203 static INT32 MemIndex()
204 {
205 	UINT8 *Next; Next = AllMem;
206 
207 	Drv68KROM		= Next; Next += 0x040000;
208 	DrvGfxROM[0]	= Next; Next += 0x200000;
209 	DrvGfxROM[1]	= Next; Next += 0x100000;
210 
211 	MSM6295ROM		= Next;
212 	DrvSndROM		= Next; Next += 0x080000;
213 
214 	BurnPalette		= (UINT32*)Next; Next += 0x00300 * sizeof(UINT32);
215 
216 	RamStart		= Next;
217 
218 	DrvVidRAM		= Next; Next += 0x002000;
219 	BurnPalRAM		= Next; Next += 0x000800;
220 	DrvSprRAM		= Next; Next += 0x001000;
221 	Drv68KRAM		= Next; Next += 0x004000;
222 
223 	RamEnd			= Next;
224 
225 	MemEnd			= Next;
226 
227 	return 0;
228 }
229 
DrvGfxDecode()230 static INT32 DrvGfxDecode()
231 {
232 	static INT32 Planes[4] = { STEP4(0,0x200000) };
233 	static INT32 XOffs[16] = { STEP8(0,1), STEP8(128,1) };
234 	static INT32 YOffs[16] = { STEP16(0,8) };
235 
236 	UINT8 *tmp = (UINT8*)BurnMalloc(0x100000);
237 	if (tmp == NULL) {
238 		return 1;
239 	}
240 
241 	memcpy (tmp, DrvGfxROM[0], 0x100000);
242 
243 	GfxDecode(0x8000, 4,  8,  8, Planes, XOffs, YOffs, 0x040, tmp, DrvGfxROM[0]);
244 	GfxDecode(0x1000, 4, 16, 16, Planes, XOffs, YOffs, 0x100, tmp, DrvGfxROM[1]);
245 
246 	BurnFree (tmp);
247 
248 	return 0;
249 }
250 
DrvInit()251 static INT32 DrvInit()
252 {
253 	BurnAllocMemIndex();
254 
255 	{
256 		INT32 k = 0;
257 		if (BurnLoadRom(Drv68KROM    + 0x000000, k++, 2)) return 1;
258 		if (BurnLoadRom(Drv68KROM    + 0x000001, k++, 2)) return 1;
259 
260 		if (BurnLoadRom(DrvGfxROM[0] + 0x000000, k++, 1)) return 1;
261 		if (BurnLoadRom(DrvGfxROM[0] + 0x040000, k++, 1)) return 1;
262 		if (BurnLoadRom(DrvGfxROM[0] + 0x080000, k++, 1)) return 1;
263 		if (BurnLoadRom(DrvGfxROM[0] + 0x0c0000, k++, 1)) return 1;
264 
265 		if (BurnLoadRom(DrvSndROM    + 0x000000, k++, 1)) return 1;
266 
267 		DrvGfxDecode();
268 	}
269 
270 	SekInit(0, 0x68000);
271 	SekOpen(0);
272 	SekMapMemory(Drv68KROM,		0x000000, 0x03ffff, MAP_ROM);
273 	SekMapMemory(DrvVidRAM,		0x100000, 0x101fff, MAP_RAM);
274 	SekMapMemory(BurnPalRAM,	0x200000, 0x1007ff, MAP_ROM);
275 	SekMapMemory(DrvSprRAM,		0x440000, 0x440fff, MAP_RAM);
276 	SekMapMemory(Drv68KRAM,		0xffc000, 0xffffff, MAP_RAM);
277 	SekSetWriteByteHandler(0, 	drtomy_write_byte);
278 	SekSetWriteWordHandler(0, 	drtomy_write_word);
279 	SekSetReadByteHandler(0, 	drtomy_read_byte);
280 	SekClose();
281 
282 	MSM6295Init(0, 1625000 / 132, 0);
283 	MSM6295SetBank(0, DrvSndROM, 0, 0x3ffff);
284 	MSM6295SetRoute(0, 0.80, BURN_SND_ROUTE_BOTH);
285 
286 	GenericTilesInit();
287 	GenericTilemapInit(0, TILEMAP_SCAN_ROWS, background_map_callback, 16, 16, 32, 32);
288 	GenericTilemapInit(1, TILEMAP_SCAN_ROWS, foreground_map_callback, 16, 16, 32, 32);
289 	GenericTilemapSetGfx(0, DrvGfxROM[1], 4, 16, 16, 0x100000, 0x000, 0xf);
290 	GenericTilemapSetGfx(1, DrvGfxROM[1], 4, 16, 16, 0x100000, 0x200, 0xf);
291 	GenericTilemapSetGfx(2, DrvGfxROM[0], 4,  8,  8, 0x200000, 0x100, 0xf);
292 	GenericTilemapSetOffsets(TMAP_GLOBAL, 0, -16);
293 	GenericTilemapSetTransparent(1, 0);
294 
295 	DrvDoReset();
296 
297 	return 0;
298 }
299 
DrvExit()300 static INT32 DrvExit()
301 {
302 	SekExit();
303 	GenericTilesExit();
304 	MSM6295Exit(0);
305 
306 	BurnFreeMemIndex();
307 
308 	MSM6295ROM = NULL;
309 
310 	return 0;
311 }
312 
draw_sprites()313 static void draw_sprites()
314 {
315 	UINT16 *spriteram = (UINT16*)DrvSprRAM;
316 
317 	for (INT32 i = 3; i < 0x1000/2; i+=4)
318 	{
319 		INT32 sx    = BURN_ENDIAN_SWAP_INT16(spriteram[i+2]) & 0x01ff;
320 		INT32 sy    = (240 - (BURN_ENDIAN_SWAP_INT16(spriteram[i]) & 0x00ff)) & 0x00ff;
321 		INT32 code  = BURN_ENDIAN_SWAP_INT16(spriteram[i+3]);
322 		INT32 color = (BURN_ENDIAN_SWAP_INT16(spriteram[i+2]) & 0x1e00) >> 9;
323 		INT32 attr  = (BURN_ENDIAN_SWAP_INT16(spriteram[i]) & 0xfe00) >> 9;
324 
325 		INT32 xflip = attr & 0x20;
326 		INT32 yflip = attr & 0x40;
327 		INT32 spr_size;
328 
329 		if (attr & 0x04){
330 			spr_size = 1;
331 		} else {
332 			spr_size = 2;
333 			code &= (~3);
334 		}
335 
336 		for (INT32 y = 0; y < spr_size; y++)
337 		{
338 			for (INT32 x = 0; x < spr_size; x++)
339 			{
340 				INT32 ex = xflip ? (spr_size-1-x) : x;
341 				INT32 ey = yflip ? (spr_size-1-y) : y;
342 
343 				DrawGfxMaskTile(0, 2, code + (ex * 2) + ey, sx-0x09+x*8, sy+y*8 - 16, xflip, yflip, color, 0);
344 			}
345 		}
346 	}
347 }
348 
DrvDraw()349 static INT32 DrvDraw()
350 {
351 	if (DrvRecalc) {
352 		BurnPaletteUpdate_xRRRRRGGGGGBBBBB();
353 		DrvRecalc = 0;
354 	}
355 
356 	GenericTilemapDraw(0, pTransDraw, 0);
357 	GenericTilemapDraw(1, pTransDraw, 0);
358 
359 	draw_sprites();
360 
361 	BurnTransferCopy(BurnPalette);
362 
363 	return 0;
364 }
365 
DrvFrame()366 static INT32 DrvFrame()
367 {
368 	if (DrvReset) {
369 		DrvDoReset();
370 	}
371 
372 	{
373 		memset (DrvInputs, 0xff, sizeof(DrvInputs));
374 
375 		for (INT32 i = 0; i < 8; i++) {
376 			DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
377 			DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
378 		}
379 	}
380 
381 	SekOpen(0);
382 	SekRun(12000000 / 60);
383 	SekSetIRQLine(6, CPU_IRQSTATUS_AUTO);
384 	SekClose();
385 
386 	if (pBurnSoundOut) {
387 		MSM6295Render(0, pBurnSoundOut, nBurnSoundLen);
388 	}
389 
390 	if (pBurnDraw) {
391 		BurnDrvRedraw();
392 	}
393 
394 	return 0;
395 }
396 
DrvScan(INT32 nAction,INT32 * pnMin)397 static INT32 DrvScan(INT32 nAction,INT32 *pnMin)
398 {
399 	struct BurnArea ba;
400 
401 	if (pnMin) {
402 		*pnMin = 0x029521;
403 	}
404 
405 	if (nAction & ACB_MEMORY_RAM) {
406 		memset(&ba, 0, sizeof(ba));
407 		ba.Data	  = RamStart;
408 		ba.nLen	  = RamEnd - RamStart;
409 		ba.szName = "All Ram";
410 		BurnAcb(&ba);
411 	}
412 
413 	if (nAction & ACB_DRIVER_DATA)
414 	{
415 		SekScan(nAction);
416 		MSM6295Scan(nAction, pnMin);
417 
418 		SCAN_VAR(okibank);
419 	}
420 
421 	if (nAction & ACB_WRITE) {
422 		set_okibank(okibank);
423 	}
424 
425 	return 0;
426 }
427 
428 
429 // Dr. Tomy
430 
431 static struct BurnRomInfo drtomyRomDesc[] = {
432 	{ "15.u21", 0x20000, 0x0b8d763b, 1 | BRF_PRG | BRF_ESS }, // 0 68k code
433 	{ "16.u22", 0x20000, 0x206f4d65, 1 | BRF_PRG | BRF_ESS }, // 1
434 
435 	{ "20.u80", 0x40000, 0x4d4d86ff, 2 | BRF_GRA },           // 2 Graphics
436 	{ "19.u81", 0x40000, 0x49ecbfe2, 2 | BRF_GRA },           // 3
437 	{ "18.u82", 0x40000, 0x8ee5c921, 2 | BRF_GRA },           // 4
438 	{ "17.u83", 0x40000, 0x42044b1c, 2 | BRF_GRA },           // 5
439 
440 	{ "14.u23", 0x80000, 0x479614ec, 3 | BRF_SND },           // 6 Samples
441 };
442 
443 STD_ROM_PICK(drtomy)
444 STD_ROM_FN(drtomy)
445 
446 struct BurnDriver BurnDrvDrtomy = {
447 	"drtomy", NULL, NULL, NULL, "1993",
448 	"Dr. Tomy\0", NULL, "Playmark", "Miscellaneous",
449 	NULL, NULL, NULL, NULL,
450 	BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_PUZZLE, 0,
451 	NULL, drtomyRomInfo, drtomyRomName, NULL, NULL, NULL, NULL, DrvInputInfo, DrvDIPInfo,
452 	DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x300,
453 	320, 240, 4, 3
454 };
455