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