1 // FB Alpha Heavy Unit driver module
2 // Based on MAME drivery Angelo Salese, Tomasz Slanina, and David Haywood
3
4 #include "tiles_generic.h"
5 #include "z80_intf.h"
6 #include "mermaid.h"
7 #include "burn_ym2203.h"
8 #include "pandora.h"
9
10 static UINT8 *AllMem;
11 static UINT8 *MemEnd;
12 static UINT8 *AllRam;
13 static UINT8 *RamEnd;
14 static UINT8 *DrvZ80ROM0;
15 static UINT8 *DrvZ80ROM1;
16 static UINT8 *DrvZ80ROM2;
17 static UINT8 *DrvMCUROM;
18 static UINT8 *DrvGfxROM0;
19 static UINT8 *DrvGfxROM1;
20 static UINT8 *DrvSprRAM;
21 static UINT8 *DrvPandoraRAM;
22 static UINT8 *DrvZ80RAM0;
23 static UINT8 *DrvZ80RAM1;
24 static UINT8 *DrvZ80RAM2;
25 static UINT8 *DrvShareRAM;
26 static UINT8 *DrvVidRAM;
27 static UINT8 *DrvColRAM;
28 static UINT8 *DrvPalRAM;
29
30 static UINT32 *DrvPalette;
31 static UINT8 DrvRecalc;
32
33 static UINT16 scrollx;
34 static UINT16 scrolly;
35 static UINT8 soundlatch;
36 static UINT8 z80banks[3];
37
38 static INT32 nExtraCycles[4];
39
40 static UINT8 DrvJoy1[8];
41 static UINT8 DrvJoy2[8];
42 static UINT8 DrvJoy3[8];
43 static UINT8 DrvInputs[6];
44 static UINT8 DrvReset;
45
46 static struct BurnInputInfo HvyunitInputList[] = {
47 {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 2, "p1 coin" },
48 {"P1 Start", BIT_DIGITAL, DrvJoy1 + 0, "p1 start" },
49 {"P1 Up", BIT_DIGITAL, DrvJoy2 + 0, "p1 up" },
50 {"P1 Down", BIT_DIGITAL, DrvJoy2 + 1, "p1 down" },
51 {"P1 Left", BIT_DIGITAL, DrvJoy2 + 2, "p1 left" },
52 {"P1 Right", BIT_DIGITAL, DrvJoy2 + 3, "p1 right" },
53 {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire 1" },
54 {"P1 Button 2", BIT_DIGITAL, DrvJoy2 + 5, "p1 fire 2" },
55
56 {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 3, "p2 coin" },
57 {"P2 Start", BIT_DIGITAL, DrvJoy1 + 1, "p2 start" },
58 {"P2 Up", BIT_DIGITAL, DrvJoy3 + 0, "p2 up" },
59 {"P2 Down", BIT_DIGITAL, DrvJoy3 + 1, "p2 down" },
60 {"P2 Left", BIT_DIGITAL, DrvJoy3 + 2, "p2 left" },
61 {"P2 Right", BIT_DIGITAL, DrvJoy3 + 3, "p2 right" },
62 {"P2 Button 1", BIT_DIGITAL, DrvJoy3 + 4, "p2 fire 1" },
63 {"P2 Button 2", BIT_DIGITAL, DrvJoy3 + 5, "p2 fire 2" },
64
65 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
66 {"Dip A", BIT_DIPSWITCH, DrvInputs + 4, "dip" },
67 {"Dip B", BIT_DIPSWITCH, DrvInputs + 5, "dip" },
68 };
69
70 STDINPUTINFO(Hvyunit)
71
72 static struct BurnDIPInfo HvyunitDIPList[]=
73 {
74 {0x11, 0xff, 0xff, 0xfe, NULL },
75 {0x12, 0xff, 0xff, 0xf7, NULL },
76
77 {0 , 0xfe, 0 , 1, "Cabinet" },
78 {0x11, 0x01, 0x01, 0x00, "Upright" },
79 // {0x11, 0x01, 0x01, 0x01, "Cocktail" },
80
81 {0 , 0xfe, 0 , 2, "Flip Screen" },
82 {0x11, 0x01, 0x02, 0x02, "Off" },
83 {0x11, 0x01, 0x02, 0x00, "On" },
84
85 {0 , 0xfe, 0 , 2, "Service Mode" },
86 {0x11, 0x01, 0x04, 0x04, "Off" },
87 {0x11, 0x01, 0x04, 0x00, "On" },
88
89 {0 , 0xfe, 0 , 2, "Coin Mode" },
90 {0x11, 0x01, 0x08, 0x08, "Mode 1" },
91 {0x11, 0x01, 0x08, 0x00, "Mode 2" },
92
93 {0 , 0xfe, 0 , 8, "Coin A" },
94 {0x11, 0x01, 0x30, 0x20, "2 Coins 1 Credits" },
95 {0x11, 0x01, 0x30, 0x30, "1 Coin 1 Credits" },
96 {0x11, 0x01, 0x30, 0x10, "1 Coin 2 Credits" },
97 {0x11, 0x01, 0x30, 0x00, "1 Coin 6 Credits" },
98 {0x11, 0x01, 0x30, 0x20, "2 Coins 1 Credits" },
99 {0x11, 0x01, 0x30, 0x30, "1 Coin 1 Credits" },
100 {0x11, 0x01, 0x30, 0x10, "1 Coin 3 Credits" },
101 {0x11, 0x01, 0x30, 0x00, "1 Coin 4 Credits" },
102
103 {0 , 0xfe, 0 , 8, "Coin B" },
104 {0x11, 0x01, 0xc0, 0x80, "2 Coins 1 Credits" },
105 {0x11, 0x01, 0xc0, 0xc0, "1 Coin 1 Credits" },
106 {0x11, 0x01, 0xc0, 0x40, "1 Coin 2 Credits" },
107 {0x11, 0x01, 0xc0, 0x00, "1 Coin 6 Credits" },
108 {0x11, 0x01, 0xc0, 0x80, "2 Coins 1 Credits" },
109 {0x11, 0x01, 0xc0, 0xc0, "1 Coin 1 Credits" },
110 {0x11, 0x01, 0xc0, 0x40, "1 Coin 3 Credits" },
111 {0x11, 0x01, 0xc0, 0x00, "1 Coin 4 Credits" },
112
113 {0 , 0xfe, 0 , 4, "Difficulty" },
114 {0x12, 0x01, 0x03, 0x02, "Easy" },
115 {0x12, 0x01, 0x03, 0x03, "Normal" },
116 {0x12, 0x01, 0x03, 0x01, "Hard" },
117 {0x12, 0x01, 0x03, 0x00, "Hardest" },
118
119 {0 , 0xfe, 0 , 2, "Allow Continue" },
120 {0x12, 0x01, 0x04, 0x00, "Off" },
121 {0x12, 0x01, 0x04, 0x04, "On" },
122
123 {0 , 0xfe, 0 , 2, "Bonus" },
124 {0x12, 0x01, 0x08, 0x08, "Off" },
125 {0x12, 0x01, 0x08, 0x00, "On" },
126
127 {0 , 0xfe, 0 , 4, "Lives" },
128 {0x12, 0x01, 0x30, 0x30, "3" },
129 {0x12, 0x01, 0x30, 0x20, "4" },
130 {0x12, 0x01, 0x30, 0x10, "5" },
131 {0x12, 0x01, 0x30, 0x00, "7" },
132
133 {0 , 0xfe, 0 , 2, "Demo Sounds" },
134 {0x12, 0x01, 0x40, 0x00, "Off" },
135 {0x12, 0x01, 0x40, 0x40, "On" },
136 };
137
138 STDDIPINFO(Hvyunit)
139
140 static struct BurnDIPInfo HvyunitjDIPList[]=
141 {
142 {0x11, 0xff, 0xff, 0xfe, NULL },
143 {0x12, 0xff, 0xff, 0xf7, NULL },
144
145 {0 , 0xfe, 0 , 1, "Cabinet" },
146 {0x11, 0x01, 0x01, 0x00, "Upright" },
147 // {0x11, 0x01, 0x01, 0x01, "Cocktail" },
148
149 {0 , 0xfe, 0 , 2, "Flip Screen" },
150 {0x11, 0x01, 0x02, 0x02, "Off" },
151 {0x11, 0x01, 0x02, 0x00, "On" },
152
153 {0 , 0xfe, 0 , 2, "Service Mode" },
154 {0x11, 0x01, 0x04, 0x04, "Off" },
155 {0x11, 0x01, 0x04, 0x00, "On" },
156
157 {0 , 0xfe, 0 , 4, "Coin A" },
158 {0x11, 0x01, 0x30, 0x10, "2 Coins 1 Credits" },
159 {0x11, 0x01, 0x30, 0x30, "1 Coin 1 Credits" },
160 {0x11, 0x01, 0x30, 0x00, "2 Coins 3 Credits" },
161 {0x11, 0x01, 0x30, 0x20, "1 Coin 2 Credits" },
162
163 {0 , 0xfe, 0 , 4, "Coin B" },
164 {0x11, 0x01, 0xc0, 0x40, "2 Coins 1 Credits" },
165 {0x11, 0x01, 0xc0, 0xc0, "1 Coin 1 Credits" },
166 {0x11, 0x01, 0xc0, 0x00, "2 Coins 3 Credits" },
167 {0x11, 0x01, 0xc0, 0x80, "1 Coin 2 Credits" },
168
169 {0 , 0xfe, 0 , 4, "Difficulty" },
170 {0x12, 0x01, 0x03, 0x02, "Easy" },
171 {0x12, 0x01, 0x03, 0x03, "Normal" },
172 {0x12, 0x01, 0x03, 0x01, "Hard" },
173 {0x12, 0x01, 0x03, 0x00, "Hardest" },
174
175 {0 , 0xfe, 0 , 2, "Allow Continue" },
176 {0x12, 0x01, 0x04, 0x00, "Off" },
177 {0x12, 0x01, 0x04, 0x04, "On" },
178
179 {0 , 0xfe, 0 , 2, "Bonus" },
180 {0x12, 0x01, 0x08, 0x08, "Off" },
181 {0x12, 0x01, 0x08, 0x00, "On" },
182
183 {0 , 0xfe, 0 , 4, "Lives" },
184 {0x12, 0x01, 0x30, 0x30, "3" },
185 {0x12, 0x01, 0x30, 0x20, "4" },
186 {0x12, 0x01, 0x30, 0x10, "5" },
187 {0x12, 0x01, 0x30, 0x00, "7" },
188
189 {0 , 0xfe, 0 , 2, "Demo Sounds" },
190 {0x12, 0x01, 0x40, 0x00, "Off" },
191 {0x12, 0x01, 0x40, 0x40, "On" },
192 };
193
STDDIPINFO(Hvyunitj)194 STDDIPINFO(Hvyunitj)
195
196 static void __fastcall hvyunit_main_write(UINT16 address, UINT8 data)
197 {
198 if ((address & 0xf000) == 0xc000) {
199 DrvSprRAM[address & 0xfff] = data;
200
201 address = (address & 0x800) | ((address & 0xff) << 3) | ((address & 0x700) >> 8);
202
203 DrvPandoraRAM[address] = data;
204 return;
205 }
206 }
207
master_bankswitch(INT32 data)208 static void master_bankswitch(INT32 data)
209 {
210 z80banks[0] = data;
211 INT32 bank = (data & 7) * 0x4000;
212
213 ZetMapMemory(DrvZ80ROM0 + bank, 0x8000, 0xbfff, MAP_ROM);
214 }
215
hvyunit_main_write_port(UINT16 port,UINT8 data)216 static void __fastcall hvyunit_main_write_port(UINT16 port, UINT8 data)
217 {
218 switch (port & 0xff)
219 {
220 case 0x00:
221 case 0x01:
222 master_bankswitch(data);
223 return;
224
225 case 0x02:
226 {
227 ZetNmi(1);
228 }
229 return;
230 }
231 }
232
slave_bankswitch(INT32 data)233 static void slave_bankswitch(INT32 data)
234 {
235 z80banks[1] = data;
236 INT32 bank = (data & 0x03) * 0x4000;
237
238 ZetMapMemory(DrvZ80ROM1 + bank, 0x8000, 0xbfff, MAP_ROM);
239 }
240
hvyunit_sub_write_port(UINT16 port,UINT8 data)241 static void __fastcall hvyunit_sub_write_port(UINT16 port, UINT8 data)
242 {
243 switch (port & 0xff)
244 {
245 case 0x00:
246 scrollx = (scrollx & 0xff) | ((data & 0x40) << 2);
247 scrolly = (scrolly & 0xff) | ((data & 0x80) << 1);
248 slave_bankswitch(data);
249 return;
250
251 case 0x02:
252 {
253 soundlatch = data;
254 ZetNmi(2);
255 }
256 return;
257
258 case 0x04:
259 mermaidWrite(data);
260 return;
261
262 case 0x06:
263 scrolly = (scrolly & 0x100) | data;
264 return;
265
266 case 0x08:
267 scrollx = (scrollx & 0x100) | data;
268 return;
269
270 case 0x0e:
271 // coin counter
272 return;
273 }
274 }
275
hvyunit_sub_read_port(UINT16 port)276 static UINT8 __fastcall hvyunit_sub_read_port(UINT16 port)
277 {
278 switch (port & 0xff)
279 {
280 case 0x04:
281 return mermaidRead();
282
283 case 0x0c:
284 return mermaidStatus();
285 }
286
287 return 0;
288 }
289
sound_bankswitch(INT32 data)290 static void sound_bankswitch(INT32 data)
291 {
292 z80banks[2] = data;
293 INT32 bank = (data & 0x03) * 0x4000;
294
295 ZetMapMemory(DrvZ80ROM2 + bank, 0x8000, 0xbfff, MAP_ROM);
296 }
297
hvyunit_sound_write_port(UINT16 port,UINT8 data)298 static void __fastcall hvyunit_sound_write_port(UINT16 port, UINT8 data)
299 {
300 switch (port & 0xff)
301 {
302 case 0x00:
303 sound_bankswitch(data);
304 return;
305
306 case 0x02:
307 case 0x03:
308 BurnYM2203Write(0, port & 1, data);
309 return;
310 }
311 }
312
hvyunit_sound_read_port(UINT16 port)313 static UINT8 __fastcall hvyunit_sound_read_port(UINT16 port)
314 {
315 switch (port & 0xff)
316 {
317 case 0x02:
318 case 0x03:
319 return BurnYM2203Read(0, port & 1);
320
321 case 0x04:
322 return soundlatch;
323 }
324
325 return 0;
326 }
327
DrvDoReset()328 static INT32 DrvDoReset()
329 {
330 memset (AllRam, 0, RamEnd - AllRam);
331
332 ZetOpen(0);
333 ZetReset();
334 master_bankswitch(0);
335 ZetClose();
336
337 ZetOpen(1);
338 ZetReset();
339 slave_bankswitch(0);
340 ZetClose();
341
342 ZetOpen(2);
343 ZetReset();
344 sound_bankswitch(0);
345 BurnYM2203Reset();
346 ZetClose();
347
348 mermaidReset();
349
350 scrollx = 0;
351 scrolly = 0;
352 soundlatch = 0;
353
354 nExtraCycles[0] = nExtraCycles[1] = nExtraCycles[2] = nExtraCycles[3] = 0;
355
356 return 0;
357 }
358
DrvGfxDecode()359 static INT32 DrvGfxDecode()
360 {
361 static INT32 Plane[4] = { STEP4(0,1) };
362 static INT32 XOffs[16] = { STEP8(0,4), STEP8(256,4) };
363 static INT32 YOffs[16] = { STEP8(0,32), STEP8(512,32) };
364
365 UINT8 *tmp = (UINT8*)BurnMalloc(0x200000);
366 if (tmp == NULL) {
367 return 1;
368 }
369
370 memcpy (tmp, DrvGfxROM0, 0x200000);
371
372 GfxDecode(0x4000, 4, 16, 16, Plane, XOffs, YOffs, 0x400, tmp, DrvGfxROM0);
373
374 memcpy (tmp, DrvGfxROM1, 0x080000);
375
376 GfxDecode(0x1000, 4, 16, 16, Plane, XOffs, YOffs, 0x400, tmp, DrvGfxROM1);
377
378 BurnFree (tmp);
379
380 return 0;
381 }
382
MemIndex()383 static INT32 MemIndex()
384 {
385 UINT8 *Next; Next = AllMem;
386
387 DrvZ80ROM0 = Next; Next += 0x020000;
388 DrvZ80ROM1 = Next; Next += 0x010000;
389 DrvZ80ROM2 = Next; Next += 0x010000;
390
391 DrvMCUROM = Next; Next += 0x001000;
392
393 DrvGfxROM0 = Next; Next += 0x400000;
394 DrvGfxROM1 = Next; Next += 0x100000;
395
396 DrvPalette = (UINT32*)Next; Next += 0x0200 * sizeof(UINT32);
397
398 AllRam = Next;
399
400 DrvSprRAM = Next; Next += 0x001000;
401 DrvPandoraRAM = Next; Next += 0x001000;
402 DrvZ80RAM0 = Next; Next += 0x001000;
403 DrvZ80RAM1 = Next; Next += 0x001000;
404 DrvShareRAM = Next; Next += 0x002000;
405 DrvVidRAM = Next; Next += 0x000400;
406 DrvColRAM = Next; Next += 0x000400;
407 DrvPalRAM = Next; Next += 0x000400;
408 DrvZ80RAM2 = Next; Next += 0x000800;
409
410 RamEnd = Next;
411
412 MemEnd = Next;
413
414 return 0;
415 }
416
DrvInit(INT32 select)417 static INT32 DrvInit(INT32 select)
418 {
419 BurnSetRefreshRate(58);
420
421 AllMem = NULL;
422 MemIndex();
423 INT32 nLen = MemEnd - (UINT8 *)0;
424 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
425 memset(AllMem, 0, nLen);
426 MemIndex();
427
428 {
429 if (BurnLoadRom(DrvZ80ROM0 + 0x000000, 0, 1)) return 1;
430
431 if (BurnLoadRom(DrvZ80ROM1 + 0x000000, 1, 1)) return 1;
432
433 if (BurnLoadRom(DrvZ80ROM2 + 0x000000, 2, 1)) return 1;
434
435 if (BurnLoadRom(DrvMCUROM + 0x000000, 3, 1)) return 1;
436
437 switch (select)
438 {
439 case 0: // hvyunit, hvyunitjo
440 {
441 if (BurnLoadRom(DrvGfxROM0 + 0x000000, 4, 1)) return 1;
442 if (BurnLoadRom(DrvGfxROM0 + 0x100000, 5, 1)) return 1;
443 if (BurnLoadRom(DrvGfxROM0 + 0x120000, 6, 1)) return 1;
444 if (BurnLoadRom(DrvGfxROM0 + 0x140000, 7, 1)) return 1;
445 if (BurnLoadRom(DrvGfxROM0 + 0x160000, 8, 1)) return 1;
446 if (BurnLoadRom(DrvGfxROM0 + 0x180000, 9, 1)) return 1;
447 if (BurnLoadRom(DrvGfxROM0 + 0x1a0000, 10, 1)) return 1;
448 if (BurnLoadRom(DrvGfxROM0 + 0x1c0000, 11, 1)) return 1;
449
450 if (BurnLoadRom(DrvGfxROM1 + 0x00000, 12, 1)) return 1;
451 }
452 break;
453
454 case 1: // hvyunitj
455 {
456 if (BurnLoadRom(DrvGfxROM0 + 0x000000, 4, 1)) return 1;
457 if (BurnLoadRom(DrvGfxROM0 + 0x100000, 5, 1)) return 1;
458 if (BurnLoadRom(DrvGfxROM0 + 0x110000, 6, 1)) return 1;
459 if (BurnLoadRom(DrvGfxROM0 + 0x120000, 7, 1)) return 1;
460 if (BurnLoadRom(DrvGfxROM0 + 0x130000, 8, 1)) return 1;
461 if (BurnLoadRom(DrvGfxROM0 + 0x140000, 9, 1)) return 1;
462 if (BurnLoadRom(DrvGfxROM0 + 0x150000, 10, 1)) return 1;
463 if (BurnLoadRom(DrvGfxROM0 + 0x160000, 11, 1)) return 1;
464
465 if (BurnLoadRom(DrvGfxROM1 + 0x00000, 12, 1)) return 1;
466 }
467 break;
468
469 case 2: // hvyunitu
470 {
471 if (BurnLoadRom(DrvGfxROM0 + 0x000000, 4, 1)) return 1;
472 if (BurnLoadRom(DrvGfxROM0 + 0x100000, 5, 1)) return 1;
473 if (BurnLoadRom(DrvGfxROM0 + 0x120000, 6, 1)) return 1;
474 if (BurnLoadRom(DrvGfxROM0 + 0x140000, 7, 1)) return 1;
475 if (BurnLoadRom(DrvGfxROM0 + 0x160000, 8, 1)) return 1;
476
477 if (BurnLoadRom(DrvGfxROM1 + 0x00000, 9, 1)) return 1;
478 }
479 break;
480 }
481
482 DrvGfxDecode();
483 }
484
485 ZetInit(0);
486 ZetOpen(0);
487 ZetMapMemory(DrvZ80ROM0, 0x0000, 0x7fff, MAP_ROM);
488 ZetMapMemory(DrvSprRAM, 0xc000, 0xcfff, MAP_ROM);
489 ZetMapMemory(DrvZ80RAM0, 0xd000, 0xdfff, MAP_RAM);
490 ZetMapMemory(DrvShareRAM, 0xe000, 0xffff, MAP_RAM);
491 ZetSetWriteHandler(hvyunit_main_write);
492 //ZetSetReadHandler(hvyunit_main_read);
493 ZetSetOutHandler(hvyunit_main_write_port);
494 //ZetSetInHandler(hvyunit_main_read_port);
495 ZetClose();
496
497 ZetInit(1);
498 ZetOpen(1);
499 ZetMapMemory(DrvZ80ROM1, 0x0000, 0x7fff, MAP_ROM);
500 ZetMapMemory(DrvVidRAM, 0xc000, 0xc3ff, MAP_RAM);
501 ZetMapMemory(DrvColRAM, 0xc400, 0xc7ff, MAP_RAM);
502 ZetMapMemory(DrvZ80RAM1, 0xd000, 0xdfff, MAP_RAM);
503 ZetMapMemory(DrvPalRAM + 0x200, 0xd000, 0xd1ff, MAP_RAM);
504 ZetMapMemory(DrvPalRAM, 0xd800, 0xd9ff, MAP_RAM);
505 ZetMapMemory(DrvShareRAM, 0xe000, 0xffff, MAP_RAM);
506 ZetSetOutHandler(hvyunit_sub_write_port);
507 ZetSetInHandler(hvyunit_sub_read_port);
508 ZetClose();
509
510 ZetInit(2);
511 ZetOpen(2);
512 ZetMapMemory(DrvZ80ROM2, 0x0000, 0x7fff, MAP_ROM);
513 ZetMapMemory(DrvZ80RAM2, 0xc000, 0xc7ff, MAP_RAM);
514 ZetSetOutHandler(hvyunit_sound_write_port);
515 ZetSetInHandler(hvyunit_sound_read_port);
516 ZetClose();
517
518 mermaidInit(DrvMCUROM, DrvInputs);
519
520 BurnYM2203Init(1, 3000000, NULL, 0);
521 BurnTimerAttachZet(6000000);
522 BurnYM2203SetRoute(0, BURN_SND_YM2203_YM2203_ROUTE, 0.50, BURN_SND_ROUTE_BOTH);
523 BurnYM2203SetRoute(0, BURN_SND_YM2203_AY8910_ROUTE_1, 0.25, BURN_SND_ROUTE_BOTH);
524 BurnYM2203SetRoute(0, BURN_SND_YM2203_AY8910_ROUTE_2, 0.25, BURN_SND_ROUTE_BOTH);
525 BurnYM2203SetRoute(0, BURN_SND_YM2203_AY8910_ROUTE_3, 0.25, BURN_SND_ROUTE_BOTH);
526
527 GenericTilesInit();
528
529 pandora_init(DrvPandoraRAM, DrvGfxROM0, (0x400000/0x100)-1, 0x100, 0, -16);
530
531 DrvDoReset();
532
533 return 0;
534 }
535
DrvExit()536 static INT32 DrvExit()
537 {
538 pandora_exit();
539
540 GenericTilesExit();
541
542 ZetExit();
543 mermaidExit();
544
545 BurnYM2203Exit();
546
547 BurnFree(AllMem);
548
549 return 0;
550 }
551
DrvRecalcPalette()552 static void DrvRecalcPalette()
553 {
554 for (INT32 i = 0; i < 0x400/2; i++) {
555 INT32 r = DrvPalRAM[0x200+i] & 0xf;
556 INT32 g = (DrvPalRAM[i] >> 4) & 0xf;
557 INT32 b = DrvPalRAM[i] & 0xf;
558
559 DrvPalette[i] = BurnHighCol(r|r*16, g|g*16, b|b*16, 0);
560 }
561 }
562
draw_layer()563 static void draw_layer()
564 {
565 for (INT32 offs = 0; offs < 32 * 32; offs++)
566 {
567 INT32 sx = (offs & 0x1f) * 16;
568 INT32 sy = (offs / 0x20) * 16;
569
570 sx -= (scrollx + 96) & 0x1ff;
571 sy -= (scrolly + 16);
572 if (sx < -15) sx += 512;
573 if (sy < -15) sy += 512;
574 if (sx >= nScreenWidth || sy >= nScreenHeight) continue;
575
576 INT32 code = DrvVidRAM[offs] | (DrvColRAM[offs] << 8);
577 INT32 color = code >> 12;
578
579 Render16x16Tile_Clip(pTransDraw, code & 0xfff, sx, sy, color, 4, 0, DrvGfxROM1);
580 }
581 }
582
DrvDraw()583 static INT32 DrvDraw()
584 {
585 DrvRecalcPalette();
586
587 draw_layer();
588
589 pandora_flipscreen = 0;
590 pandora_update(pTransDraw);
591
592 BurnTransferCopy(DrvPalette);
593
594 return 0;
595 }
596
DrvFrame()597 static INT32 DrvFrame()
598 {
599 if (DrvReset) {
600 DrvDoReset();
601 }
602
603 ZetNewFrame();
604 // mermaid new frame
605
606 {
607 memset (DrvInputs, 0xff, 4);
608 for (INT32 i = 0; i < 8; i++) {
609 DrvInputs[2] ^= (DrvJoy1[i] & 1) << i;
610 DrvInputs[0] ^= (DrvJoy2[i] & 1) << i;
611 DrvInputs[1] ^= (DrvJoy3[i] & 1) << i;
612 }
613 }
614
615 INT32 nInterleave = 256*4;
616 INT32 nCyclesTotal[4] = { 6000000 / 58, 6000000 / 58, 6000000 / 58, 6000000 / 12 / 58 };
617 INT32 nCyclesDone[4] = { nExtraCycles[0], nExtraCycles[1], nExtraCycles[2], nExtraCycles[3] };
618
619 for (INT32 i = 0; i < nInterleave; i++) {
620
621 INT32 nSegment;
622
623 ZetOpen(0);
624 if (i == 64*4) {
625 ZetSetVector(0xff);
626 ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
627 }
628 if (i == 240*4) {
629 ZetSetVector(0xfd);
630 ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
631 }
632 nSegment = (nCyclesTotal[0] * (i + 1) / nInterleave) - nCyclesDone[0];
633 nCyclesDone[0] += ZetRun(nSegment);
634 ZetClose();
635
636 ZetOpen(1);
637 if (i == 240*4) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
638 nSegment = (nCyclesTotal[1] * (i + 1) / nInterleave) - nCyclesDone[1];
639 nCyclesDone[1] += ZetRun(nSegment);
640 ZetClose();
641
642 ZetOpen(2);
643 if (i == 240*4) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
644 BurnTimerUpdate((i + 1) * nCyclesTotal[2] / nInterleave);
645 ZetClose();
646
647 nSegment = (nCyclesTotal[3] * (i + 1) / nInterleave) - nCyclesDone[3];
648 nCyclesDone[3] += mermaidRun(nSegment);
649
650 if (i == 239*4) {
651 pandora_buffer_sprites();
652
653 if (pBurnDraw) {
654 DrvDraw();
655 }
656 }
657 }
658
659 ZetOpen(2);
660 BurnTimerEndFrame(nCyclesTotal[2]);
661
662 if (pBurnSoundOut) {
663 BurnYM2203Update(pBurnSoundOut, nBurnSoundLen);
664 }
665
666 ZetClose();
667
668 nExtraCycles[0] = nCyclesDone[0] - nCyclesTotal[0];
669 nExtraCycles[1] = nCyclesDone[1] - nCyclesTotal[1];
670 nExtraCycles[3] = nCyclesDone[3] - nCyclesTotal[3];
671
672 return 0;
673 }
674
DrvScan(INT32 nAction,INT32 * pnMin)675 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
676 {
677 struct BurnArea ba;
678
679 if (pnMin != NULL) {
680 *pnMin = 0x029672;
681 }
682
683 if (nAction & ACB_MEMORY_RAM) {
684 memset(&ba, 0, sizeof(ba));
685 ba.Data = AllRam;
686 ba.nLen = RamEnd-AllRam;
687 ba.szName = "All Ram";
688 BurnAcb(&ba);
689 }
690
691 if (nAction & ACB_DRIVER_DATA) {
692 ZetScan(nAction);
693 mermaidScan(nAction);
694
695 BurnYM2203Scan(nAction, pnMin);
696
697 SCAN_VAR(scrollx);
698 SCAN_VAR(scrolly);
699 SCAN_VAR(soundlatch);
700 SCAN_VAR(z80banks);
701 SCAN_VAR(nExtraCycles);
702 }
703
704 if (nAction & ACB_WRITE) {
705 ZetOpen(0);
706 master_bankswitch(z80banks[0]);
707 ZetClose();
708
709 ZetOpen(1);
710 slave_bankswitch(z80banks[1]);
711 ZetClose();
712
713 ZetOpen(2);
714 sound_bankswitch(z80banks[2]);
715 ZetClose();
716 }
717
718 return 0;
719 }
720
721
722 // Heavy Unit (World)
723
724 static struct BurnRomInfo hvyunitRomDesc[] = {
725 { "b73_10.5c", 0x20000, 0xca52210f, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
726
727 { "b73_11.5p", 0x10000, 0xcb451695, 2 | BRF_PRG | BRF_ESS }, // 1 Z80 #1 Code
728
729 { "b73_12.7e", 0x10000, 0xd1d24fab, 3 | BRF_PRG | BRF_ESS }, // 2 Z80 #2 Code
730
731 { "mermaid.bin", 0x00e00, 0x88c5dd27, 4 | BRF_PRG | BRF_ESS }, // 3 I80C51 (mermaid) Code
732
733 { "b73_08.2f", 0x80000, 0xf83dd808, 5 | BRF_GRA }, // 4 Sprites
734 { "b73_07.2c", 0x10000, 0x5cffa42c, 5 | BRF_GRA }, // 5
735 { "b73_06.2b", 0x10000, 0xa98e4aea, 5 | BRF_GRA }, // 6
736 { "b73_01.1b", 0x10000, 0x3a8a4489, 5 | BRF_GRA }, // 7
737 { "b73_02.1c", 0x10000, 0x025c536c, 5 | BRF_GRA }, // 8
738 { "b73_03.1d", 0x10000, 0xec6020cf, 5 | BRF_GRA }, // 9
739 { "b73_04.1f", 0x10000, 0xf7badbb2, 5 | BRF_GRA }, // 10
740 { "b73_05.1h", 0x10000, 0xb8e829d2, 5 | BRF_GRA }, // 11
741
742 { "b73_09.2p", 0x80000, 0x537c647f, 6 | BRF_GRA }, // 12 Background Tiles
743 };
744
745 STD_ROM_PICK(hvyunit)
STD_ROM_FN(hvyunit)746 STD_ROM_FN(hvyunit)
747
748 static INT32 hvyunitInit()
749 {
750 return DrvInit(0);
751 }
752
753 struct BurnDriver BurnDrvHvyunit = {
754 "hvyunit", NULL, NULL, NULL, "1988",
755 "Heavy Unit (World)\0", NULL, "Kaneko / Taito", "Miscellaneous",
756 NULL, NULL, NULL, NULL,
757 BDF_GAME_WORKING, 2, HARDWARE_KANEKO_MISC, GBF_VERSHOOT, 0,
758 NULL, hvyunitRomInfo, hvyunitRomName, NULL, NULL, NULL, NULL, HvyunitInputInfo, HvyunitDIPInfo,
759 hvyunitInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
760 256, 224, 4, 3
761 };
762
763
764 // Heavy Unit (Japan, Newer)
765
766 static struct BurnRomInfo hvyunitjRomDesc[] = {
767 { "b73_30.5c", 0x20000, 0x600af545, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
768
769 { "b73_14.5p", 0x10000, 0x0dfb51d4, 2 | BRF_PRG | BRF_ESS }, // 1 Z80 #1 Code
770
771 { "b73_12.7e", 0x10000, 0xd1d24fab, 3 | BRF_PRG | BRF_ESS }, // 2 Z80 #2 Code
772
773 { "mermaid.bin", 0x00e00, 0x88c5dd27, 4 | BRF_PRG | BRF_ESS }, // 3 I80C51 (mermaid) Code
774
775 { "b73_08.2f", 0x80000, 0xf83dd808, 5 | BRF_GRA }, // 4 Sprites
776 { "b73_07.2c", 0x10000, 0x5cffa42c, 5 | BRF_GRA }, // 5
777 { "b73_06.2b", 0x10000, 0xa98e4aea, 5 | BRF_GRA }, // 6
778 { "b73_01.1b", 0x10000, 0x3a8a4489, 5 | BRF_GRA }, // 7
779 { "b73_02.1c", 0x10000, 0x025c536c, 5 | BRF_GRA }, // 8
780 { "b73_03.1d", 0x10000, 0xec6020cf, 5 | BRF_GRA }, // 9
781 { "b73_04.1f", 0x10000, 0xf7badbb2, 5 | BRF_GRA }, // 10
782 { "b73_05.1h", 0x10000, 0xb8e829d2, 5 | BRF_GRA }, // 11
783
784 { "b73_09.2p", 0x80000, 0x537c647f, 6 | BRF_GRA }, // 12 Background Tiles
785 };
786
787 STD_ROM_PICK(hvyunitj)
STD_ROM_FN(hvyunitj)788 STD_ROM_FN(hvyunitj)
789
790 static INT32 hvyunitjInit()
791 {
792 return DrvInit(1);
793 }
794
795 struct BurnDriver BurnDrvHvyunitj = {
796 "hvyunitj", "hvyunit", NULL, NULL, "1988",
797 "Heavy Unit (Japan, Newer)\0", NULL, "Kaneko / Taito", "Miscellaneous",
798 NULL, NULL, NULL, NULL,
799 BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_KANEKO_MISC, GBF_VERSHOOT, 0,
800 NULL, hvyunitjRomInfo, hvyunitjRomName, NULL, NULL, NULL, NULL, HvyunitInputInfo, HvyunitjDIPInfo,
801 hvyunitjInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
802 256, 224, 4, 3
803 };
804
805
806 // Heavy Unit (Japan, Older)
807
808 static struct BurnRomInfo hvyunitjoRomDesc[] = {
809 { "b73_13.5c", 0x20000, 0xe2874601, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
810
811 { "b73_14.5p", 0x10000, 0x0dfb51d4, 2 | BRF_PRG | BRF_ESS }, // 1 Z80 #1 Code
812
813 { "b73_12.7e", 0x10000, 0xd1d24fab, 3 | BRF_PRG | BRF_ESS }, // 2 Z80 #2 Code
814
815 { "mermaid.bin", 0x00e00, 0x88c5dd27, 4 | BRF_PRG | BRF_ESS }, // 3 I80C51 (mermaid) Code
816
817 { "b73_08.2f", 0x80000, 0xf83dd808, 5 | BRF_GRA }, // 4 Sprites
818 { "b73_07.2c", 0x10000, 0x5cffa42c, 5 | BRF_GRA }, // 5
819 { "b73_06.2b", 0x10000, 0xa98e4aea, 5 | BRF_GRA }, // 6
820 { "b73_01.1b", 0x10000, 0x3a8a4489, 5 | BRF_GRA }, // 7
821 { "b73_02.1c", 0x10000, 0x025c536c, 5 | BRF_GRA }, // 8
822 { "b73_03.1d", 0x10000, 0xec6020cf, 5 | BRF_GRA }, // 9
823 { "b73_04.1f", 0x10000, 0xf7badbb2, 5 | BRF_GRA }, // 10
824 { "b73_05.1h", 0x10000, 0xb8e829d2, 5 | BRF_GRA }, // 11
825
826 { "b73_09.2p", 0x80000, 0x537c647f, 6 | BRF_GRA }, // 12 Background Tiles
827 };
828
829 STD_ROM_PICK(hvyunitjo)
830 STD_ROM_FN(hvyunitjo)
831
832 struct BurnDriver BurnDrvHvyunitjo = {
833 "hvyunitjo", "hvyunit", NULL, NULL, "1988",
834 "Heavy Unit (Japan, Older)\0", NULL, "Kaneko / Taito", "Miscellaneous",
835 NULL, NULL, NULL, NULL,
836 BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_KANEKO_MISC, GBF_VERSHOOT, 0,
837 NULL, hvyunitjoRomInfo, hvyunitjoRomName, NULL, NULL, NULL, NULL, HvyunitInputInfo, HvyunitjDIPInfo,
838 hvyunitInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
839 256, 224, 4, 3
840 };
841
842
843 // Heavy Unit -U.S.A. Version- (US)
844
845 static struct BurnRomInfo hvyunituRomDesc[] = {
846 { "b73_34.5c", 0x20000, 0x05c30a90, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code
847
848 { "b73_35.6p", 0x10000, 0xaed1669d, 2 | BRF_PRG | BRF_ESS }, // 1 Z80 #1 Code
849
850 { "b73_12.7e", 0x10000, 0xd1d24fab, 3 | BRF_PRG | BRF_ESS }, // 2 Z80 #2 Code
851
852 { "mermaid.bin", 0x00e00, 0x88c5dd27, 4 | BRF_PRG | BRF_ESS }, // 3 I80C51 (mermaid) Code
853
854 { "b73_08.2f", 0x80000, 0xf83dd808, 5 | BRF_GRA }, // 4 Sprites
855 { "b73_28.2c", 0x20000, 0xa02e08d6, 5 | BRF_GRA }, // 5
856 { "b73_27.2b", 0x20000, 0x8708f97c, 5 | BRF_GRA }, // 6
857 { "b73_25.0b", 0x20000, 0x2f13f81e, 5 | BRF_GRA }, // 7
858 { "b73_26.0c", 0x10000, 0xb8e829d2, 5 | BRF_GRA }, // 8
859
860 { "b73_09.2p", 0x80000, 0x537c647f, 6 | BRF_GRA }, // 9 Background Tiles
861 };
862
863 STD_ROM_PICK(hvyunitu)
STD_ROM_FN(hvyunitu)864 STD_ROM_FN(hvyunitu)
865
866 static INT32 hvyunituInit()
867 {
868 return DrvInit(2);
869 }
870
871 struct BurnDriver BurnDrvHvyunitu = {
872 "hvyunitu", "hvyunit", NULL, NULL, "1988",
873 "Heavy Unit -U.S.A. Version- (US)\0", NULL, "Kaneko / Taito", "Miscellaneous",
874 NULL, NULL, NULL, NULL,
875 BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_KANEKO_MISC, GBF_VERSHOOT, 0,
876 NULL, hvyunituRomInfo, hvyunituRomName, NULL, NULL, NULL, NULL, HvyunitInputInfo, HvyunitjDIPInfo,
877 hvyunituInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x200,
878 256, 224, 4, 3
879 };
880