1 // FB Alpha Sand Scorpion driver module
2 // Based on MAME driver by Luca Elia
3 // Note: oc'd from 12 to 20mhz to make this game playable, for some reason its not so bad in mame... - dink
4
5 #include "tiles_generic.h"
6 #include "z80_intf.h"
7 #include "m68000_intf.h"
8 #include "msm6295.h"
9 #include "burn_ym2203.h"
10 #include "kaneko_tmap.h"
11 #include "pandora.h"
12
13 static UINT8 *AllMem;
14 static UINT8 *MemEnd;
15 static UINT8 *AllRam;
16 static UINT8 *RamEnd;
17 static UINT8 *Drv68KROM;
18 static UINT8 *DrvZ80ROM;
19 static UINT8 *DrvGfxROM0;
20 static UINT8 *DrvGfxROM1;
21 static UINT8 *DrvTransTab;
22 static UINT8 *Drv68KRAM;
23 static UINT8 *DrvZ80RAM;
24 static UINT8 *DrvPandoraRAM;
25 static UINT8 *DrvSprRAM;
26 static UINT8 *DrvPalRAM;
27 static UINT8 *DrvVideoRAM;
28 static UINT8 *DrvVidRegs;
29
30 static UINT32 *DrvPalette;
31 static UINT8 DrvRecalc;
32
33 static UINT8 nDrvZ80Bank;
34 static UINT8 soundlatch;
35 static UINT8 soundlatch2;
36 static INT32 watchdog;
37 static INT32 vblank_irq;
38 static INT32 sprite_irq;
39 static INT32 unknown_irq;
40 static INT32 latch1_full;
41 static INT32 latch2_full;
42
43 typedef struct
44 {
45 UINT16 x1p, y1p, x1s, y1s;
46 UINT16 x2p, y2p, x2s, y2s;
47 INT16 x12, y12, x21, y21;
48 UINT16 mult_a, mult_b;
49 } calc1_hit_t;
50
51 static calc1_hit_t m_hit;
52
53 static UINT8 DrvJoy1[16];
54 static UINT8 DrvJoy2[16];
55 static UINT8 DrvJoy3[16];
56 static UINT8 DrvDips[2];
57 static UINT16 DrvInputs[3];
58 static UINT8 DrvReset;
59
60 static struct BurnInputInfo SandscrpInputList[] = {
61 {"P1 Coin", BIT_DIGITAL, DrvJoy3 + 2, "p1 coin" },
62 {"P1 Start", BIT_DIGITAL, DrvJoy3 + 0, "p1 start" },
63 {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up" },
64 {"P1 Down", BIT_DIGITAL, DrvJoy1 + 1, "p1 down" },
65 {"P1 Left", BIT_DIGITAL, DrvJoy1 + 2, "p1 left" },
66 {"P1 Right", BIT_DIGITAL, DrvJoy1 + 3, "p1 right" },
67 {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 1" },
68 {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 5, "p1 fire 2" },
69
70 {"P2 Coin", BIT_DIGITAL, DrvJoy3 + 3, "p2 coin" },
71 {"P2 Start", BIT_DIGITAL, DrvJoy3 + 1, "p2 start" },
72 {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up" },
73 {"P2 Down", BIT_DIGITAL, DrvJoy2 + 1, "p2 down" },
74 {"P2 Left", BIT_DIGITAL, DrvJoy2 + 2, "p2 left" },
75 {"P2 Right", BIT_DIGITAL, DrvJoy2 + 3, "p2 right" },
76 {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p2 fire 1" },
77 {"P2 Button 2", BIT_DIGITAL, DrvJoy2 + 5, "p2 fire 2" },
78
79 {"Reset", BIT_DIGITAL, &DrvReset, "reset" },
80 {"Service", BIT_DIGITAL, DrvJoy3 + 6, "service" },
81 {"Tilt", BIT_DIGITAL, DrvJoy3 + 4, "tilt" },
82 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
83 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
84 };
85
86 STDINPUTINFO(Sandscrp)
87
88 static struct BurnDIPInfo SandscrpDIPList[]=
89 {
90 {0x13, 0xff, 0xff, 0xff, NULL },
91 {0x14, 0xff, 0xff, 0xff, NULL },
92
93 {0 , 0xfe, 0 , 4, "Lives" },
94 {0x13, 0x01, 0x03, 0x02, "1" },
95 {0x13, 0x01, 0x03, 0x01, "2" },
96 {0x13, 0x01, 0x03, 0x03, "3" },
97 {0x13, 0x01, 0x03, 0x00, "5" },
98
99 {0 , 0xfe, 0 , 4, "Bombs" },
100 {0x13, 0x01, 0x0c, 0x08, "1" },
101 {0x13, 0x01, 0x0c, 0x04, "2" },
102 {0x13, 0x01, 0x0c, 0x0c, "3" },
103 {0x13, 0x01, 0x0c, 0x00, "5" },
104
105 {0 , 0xfe, 0 , 4, "Difficulty" },
106 {0x13, 0x01, 0x30, 0x30, "Easy" },
107 {0x13, 0x01, 0x30, 0x20, "Normal" },
108 {0x13, 0x01, 0x30, 0x10, "Hard" },
109 {0x13, 0x01, 0x30, 0x00, "Hardest" },
110
111 {0 , 0xfe, 0 , 4, "Bonus Life" },
112 {0x13, 0x01, 0xc0, 0x80, "100K, 300K" },
113 {0x13, 0x01, 0xc0, 0xc0, "200K, 500K" },
114 {0x13, 0x01, 0xc0, 0x40, "500K, 1000K" },
115 {0x13, 0x01, 0xc0, 0x00, "1000K, 3000K" },
116
117 {0 , 0xfe, 0 , 16, "Coinage" },
118 {0x14, 0x01, 0x0f, 0x0a, "6 Coins 1 Credits" },
119 {0x14, 0x01, 0x0f, 0x0b, "5 Coins 1 Credits" },
120 {0x14, 0x01, 0x0f, 0x0c, "4 Coins 1 Credits" },
121 {0x14, 0x01, 0x0f, 0x0d, "3 Coins 1 Credits" },
122 {0x14, 0x01, 0x0f, 0x01, "8 Coins 3 Credits" },
123 {0x14, 0x01, 0x0f, 0x0e, "2 Coins 1 Credits" },
124 {0x14, 0x01, 0x0f, 0x02, "5 Coins 3 Credits" },
125 {0x14, 0x01, 0x0f, 0x03, "3 Coins 2 Credits" },
126 {0x14, 0x01, 0x0f, 0x0f, "1 Coin 1 Credits" },
127 {0x14, 0x01, 0x0f, 0x04, "2 Coins 3 Credits" },
128 {0x14, 0x01, 0x0f, 0x09, "1 Coin 2 Credits" },
129 {0x14, 0x01, 0x0f, 0x08, "1 Coin 3 Credits" },
130 {0x14, 0x01, 0x0f, 0x07, "1 Coin 4 Credits" },
131 {0x14, 0x01, 0x0f, 0x06, "1 Coin 5 Credits" },
132 {0x14, 0x01, 0x0f, 0x05, "1 Coin 6 Credits" },
133 {0x14, 0x01, 0x0f, 0x00, "Free Play" },
134
135 {0 , 0xfe, 0 , 2, "Flip Screen" },
136 {0x14, 0x01, 0x10, 0x10, "Off" },
137 {0x14, 0x01, 0x10, 0x00, "On" },
138
139 {0 , 0xfe, 0 , 2, "Allow Continue" },
140 {0x14, 0x01, 0x20, 0x00, "Off" },
141 {0x14, 0x01, 0x20, 0x20, "On" },
142
143 {0 , 0xfe, 0 , 2, "Demo Sounds" },
144 {0x14, 0x01, 0x40, 0x00, "Off" },
145 {0x14, 0x01, 0x40, 0x40, "On" },
146
147 {0 , 0xfe, 0 , 2, "Service Mode" },
148 {0x14, 0x01, 0x80, 0x80, "Off" },
149 {0x14, 0x01, 0x80, 0x00, "On" },
150 };
151
STDDIPINFO(Sandscrp)152 STDDIPINFO(Sandscrp)
153
154 static inline void palette_update(UINT16 offset)
155 {
156 INT32 p = *((UINT16*)(DrvPalRAM + offset));
157
158 INT32 r = (p >> 5) & 0x1f;
159 INT32 g = (p >> 10) & 0x1f;
160 INT32 b = (p >> 0) & 0x1f;
161
162 r = (r << 3) | (r >> 2);
163 g = (g << 3) | (g >> 2);
164 b = (b << 3) | (b >> 2);
165
166 DrvPalette[offset/2] = BurnHighCol(r, g, b, 0);
167 }
168
galpanib_calc_read(UINT32 offset)169 static UINT16 galpanib_calc_read(UINT32 offset) // Simulation of the CALC1 MCU
170 {
171 calc1_hit_t &hit = m_hit;
172
173 switch (offset)
174 {
175 case 0x00/2: // watchdog
176 watchdog = 0;
177 return 0;
178
179 case 0x04/2: // similar to the hit detection from SuperNova, but much simpler
180 {
181 UINT16 data = 0;
182
183 // X Absolute Collision
184 if (hit.x1p > hit.x2p) data |= 0x0200;
185 else if (hit.x1p == hit.x2p) data |= 0x0400;
186 else if (hit.x1p < hit.x2p) data |= 0x0800;
187
188 // Y Absolute Collision
189 if (hit.y1p > hit.y2p) data |= 0x2000;
190 else if (hit.y1p == hit.y2p) data |= 0x4000;
191 else if (hit.y1p < hit.y2p) data |= 0x8000;
192
193 // XY Overlap Collision
194 hit.x12 = (hit.x1p) - (hit.x2p + hit.x2s);
195 hit.y12 = (hit.y1p) - (hit.y2p + hit.y2s);
196 hit.x21 = (hit.x1p + hit.x1s) - (hit.x2p);
197 hit.y21 = (hit.y1p + hit.y1s) - (hit.y2p);
198
199 if ((hit.x12 < 0) && (hit.y12 < 0) && (hit.x21 >= 0) && (hit.y21 >= 0))
200 data |= 0x0001;
201
202 return data;
203 }
204
205 case 0x10/2:
206 return (((UINT32)hit.mult_a * (UINT32)hit.mult_b) >> 16);
207
208 case 0x12/2:
209 return (((UINT32)hit.mult_a * (UINT32)hit.mult_b) & 0xffff);
210
211
212 case 0x14/2:
213 return BurnRandom(); // really rand
214 }
215
216 return 0;
217 }
218
galpanib_calc_write(INT32 offset,UINT16 data)219 static void galpanib_calc_write(INT32 offset, UINT16 data)
220 {
221 calc1_hit_t &hit = m_hit;
222
223 switch (offset)
224 {
225 case 0x00/2: hit.x1p = data; break;
226 case 0x02/2: hit.x1s = data; break;
227 case 0x04/2: hit.y1p = data; break;
228 case 0x06/2: hit.y1s = data; break;
229 case 0x08/2: hit.x2p = data; break;
230 case 0x0a/2: hit.x2s = data; break;
231 case 0x0c/2: hit.y2p = data; break;
232 case 0x0e/2: hit.y2s = data; break;
233 case 0x10/2: hit.mult_a = data; break;
234 case 0x12/2: hit.mult_b = data; break;
235 }
236 }
237
update_irq_state()238 static void update_irq_state()
239 {
240 INT32 irq = (vblank_irq || sprite_irq || unknown_irq) ? 1 : 0;
241
242 SekSetIRQLine(1, irq ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE);
243 }
244
sandscrp_main_write_word(UINT32 address,UINT16 data)245 static void __fastcall sandscrp_main_write_word(UINT32 address, UINT16 data)
246 {
247 if ((address & 0xffffe0) == 0x200000) {
248 galpanib_calc_write((address & 0x1f) >> 1, data);
249 return;
250 }
251
252 switch (address)
253 {
254 case 0x100000:
255 if (data & 0x08) sprite_irq = 0;
256 if (data & 0x10) unknown_irq = 0;
257 if (data & 0x20) vblank_irq = 0;
258 update_irq_state();
259 return;
260
261 case 0xa00000:
262 return; // coin counter
263
264 case 0xe00000:
265 latch1_full = 1;
266 soundlatch = data & 0xff;
267 ZetNmi();
268 ZetRun(100); // ?
269 return;
270
271 case 0xe40000:
272 latch1_full = data & 0x80;
273 latch2_full = data & 0x40;
274 return;
275 }
276 }
277
sandscrp_main_write_byte(UINT32 address,UINT8 data)278 static void __fastcall sandscrp_main_write_byte(UINT32 address, UINT8 data)
279 {
280 bprintf (0, _T("MWB %5.5x %2.2x\n"), address, data);
281 }
282
sandscrp_main_read_word(UINT32 address)283 static UINT16 __fastcall sandscrp_main_read_word(UINT32 address)
284 {
285 if ((address & 0xffffe0) == 0x200000) {
286 return galpanib_calc_read((address & 0x1f) >> 1);
287 }
288
289 switch (address)
290 {
291 case 0x800000:
292 return ((sprite_irq << 3) | (unknown_irq << 4) | (vblank_irq << 5));
293
294 case 0xb00000:
295 return DrvInputs[0];
296
297 case 0xb00002:
298 return DrvInputs[1];
299
300 case 0xb00004:
301 return DrvInputs[2];
302
303 case 0xb00006:
304 return 0xffff;
305
306 case 0xe00000:
307 latch2_full = 0;
308 return soundlatch2;
309
310 case 0xe40000:
311 return (latch1_full ? 0x80 : 0) | (latch2_full ? 0x40 : 0);
312
313 case 0xec0000:
314 watchdog = 0;
315 return 0;
316 }
317
318 return 0;
319 }
320
sandscrp_main_read_byte(UINT32 address)321 static UINT8 __fastcall sandscrp_main_read_byte(UINT32 address)
322 {
323 bprintf (0, _T("MRB %5.5x\n"), address);
324
325 return 0;
326 }
327
sandscrp_pandora_write_word(UINT32 address,UINT16 data)328 static void __fastcall sandscrp_pandora_write_word(UINT32 address, UINT16 data)
329 {
330 address &= 0x1ffe;
331
332 data &= 0xff;
333
334 DrvSprRAM[address + 0] = data;
335 DrvSprRAM[address + 1] = data;
336
337 DrvPandoraRAM[address/2] = data;
338 }
339
sandscrp_pandora_write_byte(UINT32 address,UINT8 data)340 static void __fastcall sandscrp_pandora_write_byte(UINT32 address, UINT8 data)
341 {
342 address &= 0x1ffe;
343
344 DrvSprRAM[address + 0] = data;
345 DrvSprRAM[address + 1] = data;
346
347 DrvPandoraRAM[address/2] = data;
348 }
349
sandscrp_palette_write_word(UINT32 address,UINT16 data)350 static void __fastcall sandscrp_palette_write_word(UINT32 address, UINT16 data)
351 {
352 *((UINT16*)(DrvPalRAM + (address & 0xffe))) = data;
353 palette_update(address & 0xffe);
354 }
355
sandscrp_palette_write_byte(UINT32 address,UINT8 data)356 static void __fastcall sandscrp_palette_write_byte(UINT32 address, UINT8 data)
357 {
358 DrvPalRAM[(address & 0xfff) ^ 1] = data;
359 palette_update(address & 0xffe);
360 }
361
bankswitch(INT32 bank)362 static void bankswitch(INT32 bank)
363 {
364 nDrvZ80Bank = bank & 7;
365
366 ZetMapMemory(DrvZ80ROM + ((bank & 0x07) * 0x4000), 0x8000, 0xbfff, MAP_ROM);
367 }
368
sandscrp_sound_write_port(UINT16 port,UINT8 data)369 static void __fastcall sandscrp_sound_write_port(UINT16 port, UINT8 data)
370 {
371 switch (port & 0xff)
372 {
373 case 0x00:
374 bankswitch(data);
375 return;
376
377 case 0x02:
378 BurnYM2203Write(0, 0, data);
379 return;
380
381 case 0x03:
382 BurnYM2203Write(0, 1, data);
383 return;
384
385 case 0x04:
386 MSM6295Write(0, data);
387 return;
388
389 case 0x06:
390 latch2_full = 1;
391 soundlatch2 = data;
392 return;
393 }
394 }
395
sandscrp_sound_read_port(UINT16 port)396 static UINT8 __fastcall sandscrp_sound_read_port(UINT16 port)
397 {
398 switch (port & 0xff)
399 {
400 case 0x02:
401 return BurnYM2203Read(0, 0);
402
403 case 0x03:
404 return BurnYM2203Read(0, 1);
405
406 case 0x07:
407 latch1_full = 0;
408 return soundlatch;
409
410 case 0x08:
411 return (latch2_full ? 0x80 : 0) | (latch1_full ? 0x40 : 0);
412 }
413
414 return 0;
415 }
416
DrvYM2203PortA(UINT32)417 static UINT8 DrvYM2203PortA(UINT32)
418 {
419 return DrvDips[0];
420 }
421
DrvYM2203PortB(UINT32)422 static UINT8 DrvYM2203PortB(UINT32)
423 {
424 return DrvDips[1];
425 }
426
DrvFMIRQHandler(INT32,INT32 nStatus)427 static void DrvFMIRQHandler(INT32, INT32 nStatus)
428 {
429 ZetSetIRQLine(0, (nStatus) ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE);
430 }
431
DrvDoReset(INT32 full_reset)432 static INT32 DrvDoReset(INT32 full_reset)
433 {
434 if (full_reset) {
435 memset (AllRam, 0, RamEnd - AllRam);
436 }
437
438 SekOpen(0);
439 SekReset();
440 SekClose();
441
442 ZetOpen(0);
443 ZetReset();
444 BurnYM2203Reset();
445 ZetClose();
446
447 MSM6295Reset(0);
448
449 nDrvZ80Bank = 0;
450 vblank_irq = 0;
451 sprite_irq = 0;
452 unknown_irq = 0;
453 soundlatch = 0;
454 soundlatch2 = 0;
455 latch1_full = 0;
456 latch2_full = 0;
457 watchdog = 0;
458
459 return 0;
460 }
461
MemIndex()462 static INT32 MemIndex()
463 {
464 UINT8 *Next; Next = AllMem;
465
466 Drv68KROM = Next; Next += 0x080000;
467 DrvZ80ROM = Next; Next += 0x020000;
468
469 DrvGfxROM0 = Next; Next += 0x200000;
470 DrvGfxROM1 = Next; Next += 0x200000;
471
472 DrvTransTab = Next; Next += 0x400000 / 0x100;
473
474 MSM6295ROM = Next; Next += 0x040000;
475
476 AllRam = Next;
477
478 DrvZ80RAM = Next; Next += 0x002000;
479
480 Drv68KRAM = Next; Next += 0x010000;
481 DrvPandoraRAM = Next; Next += 0x002000;
482 DrvSprRAM = Next; Next += 0x002000;
483 DrvPalRAM = Next; Next += 0x001000;
484
485 DrvVideoRAM = Next; Next += 0x004000;
486 DrvVidRegs = Next; Next += 0x000400;
487
488 RamEnd = Next;
489
490 DrvPalette = (UINT32*)Next; Next += 0x0800 * sizeof(UINT32);
491
492 MemEnd = Next;
493
494 return 0;
495 }
496
DrvFillTransTable()497 static void DrvFillTransTable()
498 {
499 memset (DrvTransTab, 0, 0x4000);
500
501 for (INT32 i = 0; i < 0x400000; i+= 0x100) {
502 DrvTransTab[i/0x100] = 1; // transparent
503
504 for (INT32 j = 0; j < 0x100; j++) {
505 if (DrvGfxROM0[j + i]) {
506 DrvTransTab[i/0x100] = 0;
507 break;
508 }
509 }
510 }
511 }
512
DrvGfxDecode()513 static INT32 DrvGfxDecode()
514 {
515 static INT32 Plane[4] = { STEP4(0,1) };
516 static INT32 XOffs0[16] = { STEP4(12, -4), STEP4(28, -4), STEP4(268, -4),STEP4(284, -4) };
517 static INT32 XOffs1[16] = { STEP8(0,4), STEP8(256,4) };
518 static INT32 YOffs[16] = { STEP8(0, 32), STEP8(512, 32) };
519
520 UINT8 *tmp = (UINT8*)BurnMalloc(0x200000);
521 if (tmp == NULL) {
522 return 1;
523 }
524
525 memcpy (tmp, DrvGfxROM0, 0x200000);
526
527 GfxDecode(0x2000, 4, 16, 16, Plane, XOffs0, YOffs, 0x400, tmp, DrvGfxROM0);
528
529 memcpy (tmp, DrvGfxROM1, 0x200000);
530
531 GfxDecode(0x2000, 4, 16, 16, Plane, XOffs1, YOffs, 0x400, tmp, DrvGfxROM1);
532
533 BurnFree (tmp);
534
535 return 0;
536 }
537
DrvInit(INT32 type)538 static INT32 DrvInit(INT32 type)
539 {
540 AllMem = NULL;
541 MemIndex();
542 INT32 nLen = MemEnd - (UINT8 *)0;
543 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
544 memset(AllMem, 0, nLen);
545 MemIndex();
546
547 {
548 if (BurnLoadRom(Drv68KROM + 0x000001, 0, 2)) return 1;
549 if (BurnLoadRom(Drv68KROM + 0x000000, 1, 2)) return 1;
550
551 if (BurnLoadRom(DrvZ80ROM + 0x000000, 2, 1)) return 1;
552
553 if (type == 0) // early revisions
554 {
555 if (BurnLoadRom(DrvGfxROM0 + 0x000000, 3, 2)) return 1;
556 if (BurnLoadRom(DrvGfxROM0 + 0x000001, 4, 2)) return 1;
557
558 if (BurnLoadRom(DrvGfxROM1 + 0x000000, 5, 1)) return 1;
559 if (BurnLoadRom(DrvGfxROM1 + 0x080000, 6, 1)) return 1;
560
561 if (BurnLoadRom(MSM6295ROM + 0x000000, 7, 1)) return 1;
562 }
563 else
564 {
565 if (BurnLoadRom(DrvGfxROM0 + 0x000000, 3, 1)) return 1;
566 BurnByteswap(DrvGfxROM0, 0x200000);
567
568 if (BurnLoadRom(DrvGfxROM1 + 0x000000, 4, 1)) return 1;
569
570 if (BurnLoadRom(MSM6295ROM + 0x000000, 5, 1)) return 1;
571 }
572
573 DrvGfxDecode();
574 DrvFillTransTable();
575 }
576
577 SekInit(0, 0x68000);
578 SekOpen(0);
579 SekMapMemory(Drv68KROM, 0x000000, 0x07ffff, MAP_ROM);
580 SekMapMemory(DrvVidRegs, 0x300000, 0x30000f|0x3ff, MAP_RAM);
581 SekMapMemory(DrvVideoRAM, 0x400000, 0x403fff, MAP_RAM);
582 SekMapMemory(DrvSprRAM, 0x500000, 0x501fff, MAP_ROM);
583 SekMapMemory(DrvPalRAM, 0x600000, 0x600fff, MAP_ROM);
584 SekMapMemory(Drv68KRAM, 0x700000, 0x70ffff, MAP_RAM);
585 SekSetWriteWordHandler(0, sandscrp_main_write_word);
586 SekSetWriteByteHandler(0, sandscrp_main_write_byte);
587 SekSetReadWordHandler(0, sandscrp_main_read_word);
588 SekSetReadByteHandler(0, sandscrp_main_read_byte);
589
590 SekMapHandler(1, 0x500000, 0x501fff, MAP_WRITE);
591 SekSetWriteWordHandler(1, sandscrp_pandora_write_word);
592 SekSetWriteByteHandler(1, sandscrp_pandora_write_byte);
593
594 SekMapHandler(2, 0x600000, 0x600fff, MAP_WRITE);
595 SekSetWriteWordHandler(2, sandscrp_palette_write_word);
596 SekSetWriteByteHandler(2, sandscrp_palette_write_byte);
597 SekClose();
598
599 ZetInit(0);
600 ZetOpen(0);
601 ZetMapMemory(DrvZ80ROM, 0x0000, 0xbfff, MAP_ROM);
602 ZetMapMemory(DrvZ80RAM, 0xc000, 0xdfff, MAP_RAM);
603 ZetSetOutHandler(sandscrp_sound_write_port);
604 ZetSetInHandler(sandscrp_sound_read_port);
605 ZetClose();
606
607 BurnYM2203Init(1, 4000000, &DrvFMIRQHandler, 0);
608 BurnYM2203SetPorts(0, &DrvYM2203PortA, &DrvYM2203PortB, NULL, NULL);
609 BurnTimerAttachZet(4000000);
610 BurnYM2203SetRoute(0, BURN_SND_YM2203_YM2203_ROUTE, 0.50, BURN_SND_ROUTE_BOTH);
611 BurnYM2203SetRoute(0, BURN_SND_YM2203_AY8910_ROUTE_1, 0.25, BURN_SND_ROUTE_BOTH);
612 BurnYM2203SetRoute(0, BURN_SND_YM2203_AY8910_ROUTE_2, 0.25, BURN_SND_ROUTE_BOTH);
613 BurnYM2203SetRoute(0, BURN_SND_YM2203_AY8910_ROUTE_3, 0.25, BURN_SND_ROUTE_BOTH);
614
615 MSM6295Init(0, 2000000 / 132, 1);
616 MSM6295SetRoute(0, 0.80, BURN_SND_ROUTE_BOTH);
617
618 GenericTilesInit();
619
620 kaneko_view2_init(0, DrvVideoRAM, DrvVidRegs, DrvGfxROM0, 0x400, DrvTransTab, 91, 5);
621 pandora_init(DrvPandoraRAM, DrvGfxROM1, (0x200000/0x100)-1, 0x000, 0, -16);
622
623 DrvDoReset(1);
624
625 return 0;
626 }
627
DrvExit()628 static INT32 DrvExit()
629 {
630 BurnYM2203Exit();
631
632 MSM6295Exit(0);
633 MSM6295ROM = NULL;
634
635 SekExit();
636 ZetExit();
637
638 pandora_exit();
639 kaneko_view2_exit();
640
641 GenericTilesExit();
642
643 BurnFree (AllMem);
644
645 return 0;
646 }
647
DrvDraw()648 static INT32 DrvDraw()
649 {
650 if (DrvRecalc)
651 {
652 for (INT32 i = 0; i < 0x1000; i+=2) {
653 palette_update(i);
654 }
655
656 DrvRecalc = 0;
657 }
658
659 BurnTransferClear();
660
661 for (INT32 i = 0; i < 4; i++) {
662 kaneko_view2_draw_layer(0, 0, i);
663 kaneko_view2_draw_layer(0, 1, i);
664 }
665
666 pandora_update(pTransDraw);
667
668 for (INT32 i = 4; i < 8; i++) {
669 kaneko_view2_draw_layer(0, 0, i);
670 kaneko_view2_draw_layer(0, 1, i);
671 }
672
673 BurnTransferCopy(DrvPalette);
674
675 return 0;
676 }
677
DrvFrame()678 static INT32 DrvFrame()
679 {
680 watchdog++;
681 if (watchdog > 180) {
682 DrvDoReset(0);
683 }
684
685 if (DrvReset) {
686 DrvDoReset(1);
687 }
688
689 SekNewFrame();
690 ZetNewFrame();
691
692 {
693 memset (DrvInputs, 0xff, 3 * sizeof(UINT16));
694 for (INT32 i = 0; i < 8; i++) {
695 DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
696 DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
697 DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
698 }
699 }
700
701 INT32 nInterleave = 256;
702 INT32 nCyclesTotal[2] = { 12000000 / 60, 4000000 / 60 };
703 INT32 nCyclesDone[2] = { 0, 0 };
704
705 SekOpen(0);
706 ZetOpen(0);
707
708 for (INT32 i = 0; i < nInterleave; i++) {
709
710 nCyclesDone[0] += SekRun(((i + 1) * nCyclesTotal[0] / nInterleave) - nCyclesDone[0]);
711
712 if (i == 240) {
713 vblank_irq = 1;
714 update_irq_state();
715 }
716
717 if (i == 255) {
718 sprite_irq = 1;
719 update_irq_state();
720 }
721
722 BurnTimerUpdate((i + 1) * nCyclesTotal[1] / nInterleave);
723 }
724
725 BurnTimerEndFrame(nCyclesTotal[1]);
726
727 if (pBurnSoundOut) {
728 BurnYM2203Update(pBurnSoundOut, nBurnSoundLen);
729 MSM6295Render(0, pBurnSoundOut, nBurnSoundLen);
730 }
731
732 ZetClose();
733 SekClose();
734
735 if (pBurnDraw) {
736 DrvDraw();
737 }
738
739 pandora_buffer_sprites();
740
741 return 0;
742 }
743
DrvScan(INT32 nAction,INT32 * pnMin)744 static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
745 {
746 struct BurnArea ba;
747
748 if (pnMin) {
749 *pnMin = 0x029707;
750 }
751
752 if (nAction & ACB_VOLATILE) {
753 memset(&ba, 0, sizeof(ba));
754
755 ba.Data = AllRam;
756 ba.nLen = RamEnd - AllRam;
757 ba.szName = "All Ram";
758 BurnAcb(&ba);
759
760 ba.Data = &m_hit;
761 ba.nLen = sizeof(calc1_hit_t);
762 ba.szName = "hit calculation";
763 BurnAcb(&ba);
764
765 SekScan(nAction);
766 ZetScan(nAction);
767
768 BurnYM2203Scan(nAction, pnMin);
769 MSM6295Scan(nAction, pnMin);
770
771 SCAN_VAR(vblank_irq);
772 SCAN_VAR(sprite_irq);
773 SCAN_VAR(unknown_irq);
774 SCAN_VAR(soundlatch);
775 SCAN_VAR(soundlatch2);
776 SCAN_VAR(latch1_full);
777 SCAN_VAR(latch2_full);
778 SCAN_VAR(nDrvZ80Bank);
779
780 BurnRandomScan(nAction);
781 }
782
783 if (nAction & ACB_WRITE) {
784 ZetOpen(0);
785 bankswitch(nDrvZ80Bank);
786 ZetClose();
787
788 DrvRecalc = 1;
789 }
790
791 return 0;
792 }
793
794
795 // Sand Scorpion
796
797 static struct BurnRomInfo sandscrpRomDesc[] = {
798 { "11.bin", 0x40000, 0x9b24ab40, 1 | BRF_PRG | BRF_ESS }, // 0 68k Code
799 { "12.bin", 0x40000, 0xad12caee, 1 | BRF_PRG | BRF_ESS }, // 1
800
801 { "8.ic51", 0x20000, 0x6f3e9db1, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 Code
802
803 { "4.ic32", 0x80000, 0xb9222ff2, 3 | BRF_GRA }, // 3 Tiles
804 { "3.ic33", 0x80000, 0xadf20fa0, 3 | BRF_GRA }, // 4
805
806 { "5.ic16", 0x80000, 0x9bb675f6, 4 | BRF_GRA }, // 5 Sprites
807 { "6.ic17", 0x80000, 0x7df2f219, 4 | BRF_GRA }, // 6
808
809 { "7.ic55", 0x40000, 0x9870ab12, 5 | BRF_SND }, // 7 Samples
810 };
811
812 STD_ROM_PICK(sandscrp)
STD_ROM_FN(sandscrp)813 STD_ROM_FN(sandscrp)
814
815 static INT32 sandscrpInit()
816 {
817 return DrvInit(0);
818 }
819
820 struct BurnDriver BurnDrvSandscrp = {
821 "sandscrp", NULL, NULL, NULL, "1992",
822 "Sand Scorpion\0", NULL, "Face", "Miscellaneous",
823 NULL, NULL, NULL, NULL,
824 BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_POST90S, GBF_VERSHOOT, 0,
825 NULL, sandscrpRomInfo, sandscrpRomName, NULL, NULL, NULL, NULL, SandscrpInputInfo, SandscrpDIPInfo,
826 sandscrpInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
827 224, 256, 3, 4
828 };
829
830
831 // Sand Scorpion (Earlier)
832
833 static struct BurnRomInfo sandscrpaRomDesc[] = {
834 { "1.ic4", 0x40000, 0xc0943ae2, 1 | BRF_PRG | BRF_ESS }, // 0 68k Code
835 { "2.ic5", 0x40000, 0x6a8e0012, 1 | BRF_PRG | BRF_ESS }, // 1
836
837 { "8.ic51", 0x20000, 0x6f3e9db1, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 Code
838
839 { "4.ic32", 0x80000, 0xb9222ff2, 3 | BRF_GRA }, // 3 Tiles
840 { "3.ic33", 0x80000, 0xadf20fa0, 3 | BRF_GRA }, // 4
841
842 { "5.ic16", 0x80000, 0x9bb675f6, 4 | BRF_GRA }, // 5 Sprites
843 { "6.ic17", 0x80000, 0x7df2f219, 4 | BRF_GRA }, // 6
844
845 { "7.ic55", 0x40000, 0x9870ab12, 5 | BRF_SND }, // 7 Samples
846 };
847
848 STD_ROM_PICK(sandscrpa)
849 STD_ROM_FN(sandscrpa)
850
851 struct BurnDriver BurnDrvSandscrpa = {
852 "sandscrpa", "sandscrp", NULL, NULL, "1992",
853 "Sand Scorpion (Earlier)\0", NULL, "Face", "Miscellaneous",
854 NULL, NULL, NULL, NULL,
855 BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_POST90S, GBF_VERSHOOT, 0,
856 NULL, sandscrpaRomInfo, sandscrpaRomName, NULL, NULL, NULL, NULL, SandscrpInputInfo, SandscrpDIPInfo,
857 sandscrpInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
858 224, 256, 3, 4
859 };
860
861
862 // Sand Scorpion (Chinese Title Screen, Revised Hardware)
863
864 static struct BurnRomInfo sandscrpbRomDesc[] = {
865 { "11.ic4", 0x040000, 0x80020cab, 1 | BRF_PRG | BRF_ESS }, // 0 68k Code
866 { "12.ic5", 0x040000, 0x8df1d42f, 1 | BRF_PRG | BRF_ESS }, // 1
867
868 { "8.ic51", 0x020000, 0x6f3e9db1, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 Code
869
870 { "ss501.ic30", 0x100000, 0x0cf9f99d, 3 | BRF_GRA }, // 3 Tiles
871
872 { "ss502.ic16", 0x100000, 0xd8012ebb, 4 | BRF_GRA }, // 4 Sprites
873
874 { "7.ic55", 0x040000, 0x9870ab12, 5 | BRF_SND }, // 5 Samples
875 };
876
877 STD_ROM_PICK(sandscrpb)
STD_ROM_FN(sandscrpb)878 STD_ROM_FN(sandscrpb)
879
880 static INT32 sandscrpbInit()
881 {
882 return DrvInit(1);
883 }
884
885 struct BurnDriver BurnDrvSandscrpb = {
886 "sandscrpb", "sandscrp", NULL, NULL, "1992",
887 "Sand Scorpion (Chinese Title Screen, Revised Hardware)\0", NULL, "Face", "Miscellaneous",
888 NULL, NULL, NULL, NULL,
889 BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_POST90S, GBF_VERSHOOT, 0,
890 NULL, sandscrpbRomInfo, sandscrpbRomName, NULL, NULL, NULL, NULL, SandscrpInputInfo, SandscrpDIPInfo,
891 sandscrpbInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
892 224, 256, 3, 4
893 };
894