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