1 // FB Alpha GI Joe driver module
2 // Based on MAME driver by Olivier Galibert
3
4 #include "tiles_generic.h"
5 #include "m68000_intf.h"
6 #include "z80_intf.h"
7 #include "konamiic.h"
8 #include "burn_ym2151.h"
9 #include "k054539.h"
10 #include "eeprom.h"
11
12 static UINT8 *AllMem;
13 static UINT8 *Drv68KROM;
14 static UINT8 *DrvZ80ROM;
15 static UINT8 *DrvGfxROM0;
16 static UINT8 *DrvGfxROM1;
17 static UINT8 *DrvGfxROMExp0;
18 static UINT8 *DrvGfxROMExp1;
19 static UINT8 *DrvSndROM;
20 static UINT8 *DrvEeprom;
21 static UINT8 *AllRam;
22 static UINT8 *Drv68KRAM;
23 static UINT8 *DrvZ80RAM;
24 static UINT8 *DrvSprRAM;
25 static UINT8 *DrvPalRAM;
26 static UINT8 *RamEnd;
27 static UINT8 *MemEnd;
28
29 static UINT8 *soundlatch;
30 static UINT8 *soundlatch2;
31
32 static UINT32 *DrvPalette;
33 static UINT8 DrvRecalc;
34
35 static INT32 layerpri[4];
36 static INT32 layer_colorbase[4];
37 static INT32 sprite_colorbase;
38
39 static UINT8 DrvJoy1[16];
40 static UINT8 DrvJoy2[16];
41 static UINT8 DrvJoy3[16];
42 static UINT8 DrvJoy4[16];
43 static UINT8 DrvReset;
44 static UINT16 DrvInputs[4];
45 static UINT8 DrvDips[4];
46
47 static INT32 avac_bits[4];
48 static INT32 avac_occupancy[4];
49 static INT32 avac_vrc;
50
51 static INT32 sound_nmi_enable;
52 static INT32 irq6_timer;
53 static UINT16 control_data;
54
55 static struct BurnInputInfo GijoeInputList[] = {
56 {"P1 Coin", BIT_DIGITAL, DrvJoy2 + 0, "p1 coin"},
57 {"P1 Start", BIT_DIGITAL, DrvJoy1 + 0, "p1 start"},
58 {"P1 Up", BIT_DIGITAL, DrvJoy3 + 2, "p1 up"},
59 {"P1 Down", BIT_DIGITAL, DrvJoy3 + 3, "p1 down"},
60 {"P1 Left", BIT_DIGITAL, DrvJoy3 + 0, "p1 left"},
61 {"P1 Right", BIT_DIGITAL, DrvJoy3 + 1, "p1 right"},
62 {"P1 Button 1", BIT_DIGITAL, DrvJoy3 + 4, "p1 fire 1"},
63 {"P1 Button 2", BIT_DIGITAL, DrvJoy3 + 5, "p1 fire 2"},
64 {"P1 Button 3", BIT_DIGITAL, DrvJoy3 + 6, "p1 fire 3"},
65
66 {"P2 Coin", BIT_DIGITAL, DrvJoy2 + 1, "p2 coin"},
67 {"P2 Start", BIT_DIGITAL, DrvJoy1 + 1, "p2 start"},
68 {"P2 Up", BIT_DIGITAL, DrvJoy3 + 10, "p2 up"},
69 {"P2 Down", BIT_DIGITAL, DrvJoy3 + 11, "p2 down"},
70 {"P2 Left", BIT_DIGITAL, DrvJoy3 + 8, "p2 left"},
71 {"P2 Right", BIT_DIGITAL, DrvJoy3 + 9, "p2 right"},
72 {"P2 Button 1", BIT_DIGITAL, DrvJoy3 + 12, "p2 fire 1"},
73 {"P2 Button 2", BIT_DIGITAL, DrvJoy3 + 13, "p2 fire 2"},
74 {"P2 Button 3", BIT_DIGITAL, DrvJoy3 + 14, "p2 fire 3"},
75
76 {"P3 Coin", BIT_DIGITAL, DrvJoy2 + 2, "p3 coin"},
77 {"P3 Start", BIT_DIGITAL, DrvJoy1 + 2, "p3 start"},
78 {"P3 Up", BIT_DIGITAL, DrvJoy4 + 2, "p3 up"},
79 {"P3 Down", BIT_DIGITAL, DrvJoy4 + 3, "p3 down"},
80 {"P3 Left", BIT_DIGITAL, DrvJoy4 + 0, "p3 left"},
81 {"P3 Right", BIT_DIGITAL, DrvJoy4 + 1, "p3 right"},
82 {"P3 Button 1", BIT_DIGITAL, DrvJoy4 + 4, "p3 fire 1"},
83 {"P3 Button 2", BIT_DIGITAL, DrvJoy4 + 5, "p3 fire 2"},
84 {"P3 Button 3", BIT_DIGITAL, DrvJoy4 + 6, "p3 fire 3"},
85
86 {"P4 Coin", BIT_DIGITAL, DrvJoy2 + 3, "p4 coin"},
87 {"P4 Start", BIT_DIGITAL, DrvJoy1 + 3, "p4 start"},
88 {"P4 Up", BIT_DIGITAL, DrvJoy4 + 10, "p4 up"},
89 {"P4 Down", BIT_DIGITAL, DrvJoy4 + 11, "p4 down"},
90 {"P4 Left", BIT_DIGITAL, DrvJoy4 + 8, "p4 left"},
91 {"P4 Right", BIT_DIGITAL, DrvJoy4 + 9, "p4 right"},
92 {"P4 Button 1", BIT_DIGITAL, DrvJoy4 + 12, "p4 fire 1"},
93 {"P4 Button 2", BIT_DIGITAL, DrvJoy4 + 13, "p4 fire 2"},
94 {"P4 Button 3", BIT_DIGITAL, DrvJoy4 + 14, "p4 fire 3"},
95
96 {"Reset", BIT_DIGITAL, &DrvReset, "reset"},
97 {"Service 1", BIT_DIGITAL, DrvJoy2 + 8, "service"},
98 {"Service 2", BIT_DIGITAL, DrvJoy2 + 9, "service"},
99 {"Service 3", BIT_DIGITAL, DrvJoy2 + 10, "service"},
100 {"Service 4", BIT_DIGITAL, DrvJoy2 + 11, "service"},
101 {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip"},
102 {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip"},
103 {"Dip C", BIT_DIPSWITCH, DrvDips + 2, "dip"},
104 {"Dip D", BIT_DIPSWITCH, DrvDips + 3, "dip"},
105 };
106
107 STDINPUTINFO(Gijoe)
108
109 static struct BurnDIPInfo GijoeDIPList[]=
110 {
111 {0x29, 0xff, 0xff, 0x08, NULL },
112 {0x2a, 0xff, 0xff, 0x80, NULL },
113 {0x2b, 0xff, 0xff, 0x80, NULL },
114 {0x2c, 0xff, 0xff, 0x80, NULL },
115
116 {0 , 0xfe, 0 , 2, "Service Mode" },
117 {0x29, 0x01, 0x08, 0x08, "Off" },
118 {0x29, 0x01, 0x08, 0x00, "On" },
119
120 {0 , 0xfe, 0 , 2, "Sound" },
121 {0x2a, 0x01, 0x80, 0x80, "Mono" },
122 {0x2a, 0x01, 0x80, 0x00, "Stereo" },
123
124 {0 , 0xfe, 0 , 2, "Coin mechanism" },
125 {0x2b, 0x01, 0x80, 0x80, "Common" },
126 {0x2b, 0x01, 0x80, 0x00, "Independent" },
127
128 {0 , 0xfe, 0 , 2, "Players" },
129 {0x2c, 0x01, 0x80, 0x80, "2" },
130 {0x2c, 0x01, 0x80, 0x00, "4" },
131 };
132
STDDIPINFO(Gijoe)133 STDDIPINFO(Gijoe)
134
135 static void gijoe_objdma()
136 {
137 UINT16 *src_head, *src_tail, *dst_head, *dst_tail;
138
139 src_head = (UINT16*)DrvSprRAM;
140 src_tail = src_head + 255 * 8;
141 dst_head = (UINT16*)K053247Ram;
142 dst_tail = dst_head + 255 * 8;
143
144 for (; src_head <= src_tail; src_head += 8)
145 {
146 if (*src_head & 0x8000)
147 {
148 memcpy(dst_head, src_head, 0x10);
149 dst_head += 8;
150 }
151 else
152 {
153 *dst_tail = 0;
154 dst_tail -= 8;
155 }
156 }
157 }
158
gijoe_main_write_word(UINT32 address,UINT16 data)159 static void __fastcall gijoe_main_write_word(UINT32 address, UINT16 data)
160 {
161 if ((address & 0xfffff8) == 0x110000) {
162 K053246Write((address & 0x06) + 0, data >> 8);
163 K053246Write((address & 0x06) + 1, data&0xff);
164 return;
165 }
166
167 if ((address & 0xffc000) == 0x120000) {
168 K056832RamWriteWord(address & 0x1fff, data);
169 return;
170 }
171
172 if ((address & 0xfffff8) == 0x160000) {
173 return; // regsb
174 }
175
176 if ((address & 0xffffc0) == 0x1b0000) {
177 K056832WordWrite(address & 0x3e, data);
178 return;
179 }
180
181 switch (address)
182 {
183 case 0x1c000c:
184 *soundlatch = data;
185 break;
186
187 case 0x1d0000:
188 ZetSetIRQLine(0, CPU_IRQSTATUS_ACK);
189 return;
190 }
191 //bprintf(0, _T("%X %X\n"), address, data);
192 }
193
gijoe_main_write_byte(UINT32 address,UINT8 data)194 static void __fastcall gijoe_main_write_byte(UINT32 address, UINT8 data)
195 {
196 if ((address & 0xfffff8) == 0x110000) {
197 K053246Write((address & 0x07) ^ 0, data);
198 return;
199 }
200
201 if ((address & 0xffc000) == 0x120000) {
202 K056832RamWriteByte(address & 0x1fff, data);
203 return;
204 }
205
206 if ((address & 0xfffff8) == 0x160000) {
207 return; // regsb
208 }
209
210 if ((address & 0xffffe1) == 0x1a0001) {
211 K053251Write((address / 2) & 0xf, data);
212 return;
213 }
214
215 if ((address & 0xffffc0) == 0x1b0000) {
216 K056832ByteWrite(address & 0x3f, data);
217 return;
218 }
219
220 switch (address)
221 {
222 case 0x170000:
223 return; // watchdog
224
225 case 0x1e8001:
226 EEPROMWrite((data & 0x04), (data & 0x02), (data & 0x01));
227 K053246_set_OBJCHA_line((data & 0x40) >> 6);
228 control_data = data;
229 return;
230
231 case 0x1c000c:
232 case 0x1c000d:
233 *soundlatch = data;
234 break;
235
236 case 0x1d0000:
237 case 0x1d0001:
238 ZetSetIRQLine(0, CPU_IRQSTATUS_ACK);
239 return;
240
241 }
242 }
243
gijoe_main_read_word(UINT32 address)244 static UINT16 __fastcall gijoe_main_read_word(UINT32 address)
245 {
246 if ((address & 0xffc000) == 0x120000) {
247 return K056832RamReadWord(address & 0x1fff);
248 }
249
250 if ((address & 0xffe000) == 0x130000) {
251 return K056832RomWordRead(address);
252 }
253
254 switch (address)
255 {
256 case 0x1e0000:
257 return DrvInputs[2];
258
259 case 0x1e0002:
260 return DrvInputs[3];
261
262 case 0x1e4000:
263 return DrvInputs[1];
264
265 case 0x1e4002:
266 return (DrvInputs[0] & 0xfeff) | (EEPROMRead() ? 0x0100 : 0);
267
268 case 0x1c0014:
269 return *soundlatch2;
270
271 case 0x1f0000:
272 return K053246Read(1) + (K053246Read(0) << 8); // ?
273 }
274
275 return 0;
276 }
277
gijoe_main_read_byte(UINT32 address)278 static UINT8 __fastcall gijoe_main_read_byte(UINT32 address)
279 {
280 if ((address & 0xffc000) == 0x120000) {
281 return K056832RamReadByte(address & 0x1fff);
282 }
283
284 if ((address & 0xffe000) == 0x130000) {
285 return K056832RomWordRead(address) >> ((~address & 1) * 8);
286 }
287
288 switch (address)
289 {
290 case 0x1e0000:
291 return DrvInputs[2] >> 8;
292
293 case 0x1e0001:
294 return DrvInputs[2];
295
296 case 0x1e0002:
297 return DrvInputs[3] >> 8;
298
299 case 0x1e0003:
300 return DrvInputs[3];
301
302 case 0x1e4000:
303 return DrvInputs[1] >> 8;
304
305 case 0x1e4001:
306 return DrvInputs[1];
307
308 case 0x1e4002:
309 return ((DrvInputs[0] >> 8) & 0xfe) | (EEPROMRead() ? 0x01 : 0);
310
311 case 0x1e4003:
312 return DrvInputs[0];
313
314 case 0x1c0014:
315 case 0x1c0015:
316 return *soundlatch2;
317
318 case 0x1f0000:
319 case 0x1f0001:
320 return K053246Read((address & 1)); // ^ 1? ??
321 }
322
323 return 0;
324 }
325
gijoe_sound_write(UINT16 address,UINT8 data)326 static void __fastcall gijoe_sound_write(UINT16 address, UINT8 data)
327 {
328 if (address >= 0xf800 && address <= 0xfa2f) {
329 if (address == 0xfa2f) sound_nmi_enable = data & 0x20;
330 K054539Write(0, address & 0x3ff, data);
331 return;
332 }
333
334 switch (address)
335 {
336 case 0xfc00:
337 *soundlatch2 = data;
338 return;
339 }
340 }
341
gijoe_sound_read(UINT16 address)342 static UINT8 __fastcall gijoe_sound_read(UINT16 address)
343 {
344 if (address >= 0xf800 && address <= 0xfa2f) {
345 return K054539Read(0, address & 0x3ff);
346 }
347
348 switch (address)
349 {
350 case 0xfc02:
351 ZetSetIRQLine(0, CPU_IRQSTATUS_NONE);
352 return *soundlatch;
353 }
354
355 return 0;
356 }
357
gijoe_sprite_callback(INT32 *,INT32 * color,INT32 * priority)358 static void gijoe_sprite_callback(INT32 */*code*/, INT32 *color, INT32 *priority)
359 {
360 INT32 pri = (*color & 0x03e0) >> 4;
361
362 if (pri <= layerpri[3]) *priority = 0x0000;
363 else if (pri > layerpri[3] && pri <= layerpri[2]) *priority = 0xff00;
364 else if (pri > layerpri[2] && pri <= layerpri[1]) *priority = 0xfff0;
365 else if (pri > layerpri[1] && pri <= layerpri[0]) *priority = 0xfffc;
366 else *priority = 0xfffe;
367
368 *color = sprite_colorbase | (*color & 0x001f);
369 }
370
gijoe_tile_callback(int layer,int * code,int * color,int *)371 static void gijoe_tile_callback(int layer, int *code, int *color, int */*flags*/)
372 {
373 INT32 tile = *code;
374
375 if (tile >= 0xf000 && tile <= 0xf4ff)
376 {
377 tile &= 0x0fff;
378 if (tile < 0x0310)
379 {
380 avac_occupancy[layer] |= 0x0f00;
381 tile |= avac_bits[0];
382 }
383 else if (tile < 0x0470)
384 {
385 avac_occupancy[layer] |= 0xf000;
386 tile |= avac_bits[1];
387 }
388 else
389 {
390 avac_occupancy[layer] |= 0x00f0;
391 tile |= avac_bits[2];
392 }
393 *code = tile;
394 }
395
396 *color = (*color >> 2 & 0x0f) | layer_colorbase[layer];
397 }
398
399 static const eeprom_interface gijoe_eeprom_interface =
400 {
401 7,
402 8,
403 "011000",
404 "011100",
405 "0100100000000",
406 "0100000000000",
407 "0100110000000",
408 0,
409 0
410 };
411
DrvDoReset()412 static INT32 DrvDoReset()
413 {
414 memset (AllRam, 0, RamEnd - AllRam);
415
416 SekOpen(0);
417 SekReset();
418 SekClose();
419
420 ZetOpen(0);
421 ZetReset();
422 ZetClose();
423
424 KonamiICReset();
425
426 K054539Reset(0);
427
428 EEPROMReset();
429
430 if (EEPROMAvailable() == 0) {
431 EEPROMFill(DrvEeprom, 0, 128);
432 }
433
434 control_data = 0;
435
436 for (INT32 i = 0; i < 4; i++)
437 {
438 avac_occupancy[i] = 0;
439 avac_bits[i] = 0;
440 layer_colorbase[i] = 0;
441 layerpri[i] = 0;
442 }
443
444 avac_vrc = 0xffff;
445 sound_nmi_enable = 0;
446
447 irq6_timer = -1;
448
449 return 0;
450 }
451
MemIndex()452 static INT32 MemIndex()
453 {
454 UINT8 *Next; Next = AllMem;
455
456 Drv68KROM = Next; Next += 0x100000;
457 DrvZ80ROM = Next; Next += 0x010000;
458
459 DrvGfxROM0 = Next; Next += 0x200000;
460 DrvGfxROMExp0 = Next; Next += 0x400000;
461 DrvGfxROM1 = Next; Next += 0x400000;
462 DrvGfxROMExp1 = Next; Next += 0x800000;
463
464 DrvSndROM = Next; Next += 0x200000;
465
466 DrvEeprom = Next; Next += 0x000080;
467
468 konami_palette32 = (UINT32*)Next;
469 DrvPalette = (UINT32*)Next; Next += 0x0800 * sizeof(UINT32);
470
471 AllRam = Next;
472
473 Drv68KRAM = Next; Next += 0x010000;
474 DrvSprRAM = Next; Next += 0x001000;
475 DrvPalRAM = Next; Next += 0x001000;
476
477 DrvZ80RAM = Next; Next += 0x000800;
478
479 soundlatch = Next; Next += 0x000001;
480 soundlatch2 = Next; Next += 0x000001;
481
482 RamEnd = Next;
483 MemEnd = Next;
484
485 return 0;
486 }
487
DrvInit()488 static INT32 DrvInit()
489 {
490 GenericTilesInit();
491
492 AllMem = NULL;
493 MemIndex();
494 INT32 nLen = MemEnd - (UINT8 *)0;
495 if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
496 memset(AllMem, 0, nLen);
497 MemIndex();
498
499 {
500 if (BurnLoadRom(Drv68KROM + 0x000001, 0, 2)) return 1;
501 if (BurnLoadRom(Drv68KROM + 0x000000, 1, 2)) return 1;
502 if (BurnLoadRom(Drv68KROM + 0x080001, 2, 2)) return 1;
503 if (BurnLoadRom(Drv68KROM + 0x080000, 3, 2)) return 1;
504
505 if (BurnLoadRom(DrvZ80ROM + 0x000000, 4, 1)) return 1;
506
507 if (BurnLoadRomExt(DrvGfxROM0 + 0x000000, 5, 4, 2)) return 1;
508 if (BurnLoadRomExt(DrvGfxROM0 + 0x000002, 6, 4, 2)) return 1;
509
510 if (BurnLoadRomExt(DrvGfxROM1 + 0x000000, 7, 8, 2)) return 1;
511 if (BurnLoadRomExt(DrvGfxROM1 + 0x000002, 8, 8, 2)) return 1;
512 if (BurnLoadRomExt(DrvGfxROM1 + 0x000004, 9, 8, 2)) return 1;
513 if (BurnLoadRomExt(DrvGfxROM1 + 0x000006, 10, 8, 2)) return 1;
514
515 if (BurnLoadRom(DrvSndROM + 0x000000, 11, 1)) return 1;
516
517 if (BurnLoadRom(DrvEeprom + 0x000000, 12, 1)) return 1;
518
519 K053247GfxDecode(DrvGfxROM0, DrvGfxROMExp0, 0x200000);
520 K053247GfxDecode(DrvGfxROM1, DrvGfxROMExp1, 0x400000);
521 }
522
523 SekInit(0, 0x68000);
524 SekOpen(0);
525 SekMapMemory(Drv68KROM, 0x000000, 0x0fffff, MAP_ROM);
526 SekMapMemory(DrvSprRAM, 0x100000, 0x100fff, MAP_RAM);
527 SekMapMemory(Drv68KRAM, 0x180000, 0x18ffff, MAP_RAM);
528 SekMapMemory(DrvPalRAM, 0x190000, 0x190fff, MAP_RAM);
529 SekSetWriteWordHandler(0, gijoe_main_write_word);
530 SekSetWriteByteHandler(0, gijoe_main_write_byte);
531 SekSetReadWordHandler(0, gijoe_main_read_word);
532 SekSetReadByteHandler(0, gijoe_main_read_byte);
533 SekClose();
534
535 ZetInit(0);
536 ZetOpen(0);
537 ZetMapMemory(DrvZ80ROM, 0x0000, 0xefff, MAP_ROM);
538 ZetMapMemory(DrvZ80RAM, 0xf000, 0xf7ff, MAP_RAM);
539 ZetSetWriteHandler(gijoe_sound_write);
540 ZetSetReadHandler(gijoe_sound_read);
541 ZetClose();
542
543 EEPROMInit(&gijoe_eeprom_interface);
544
545 K056832Init(DrvGfxROM0, DrvGfxROMExp0, 0x200000, gijoe_tile_callback);
546 K056832SetGlobalOffsets(24, 16);
547
548 K053247Init(DrvGfxROM1, DrvGfxROMExp1, 0x3fffff, gijoe_sprite_callback, 1);
549 K053247SetSpriteOffset(-61, -46+10);
550
551 K054539Init(0, 48000, DrvSndROM, 0x200000);
552 K054539SetRoute(0, BURN_SND_K054539_ROUTE_1, 1.00, BURN_SND_ROUTE_LEFT);
553 K054539SetRoute(0, BURN_SND_K054539_ROUTE_2, 1.00, BURN_SND_ROUTE_RIGHT);
554
555 DrvDoReset();
556
557 return 0;
558 }
559
DrvExit()560 static INT32 DrvExit()
561 {
562 GenericTilesExit();
563
564 KonamiICExit();
565
566 SekExit();
567 ZetExit();
568
569 EEPROMExit();
570
571 K054539Exit();
572
573 BurnFree (AllMem);
574
575 return 0;
576 }
577
DrvPaletteRecalc()578 static void DrvPaletteRecalc()
579 {
580 UINT16 *pal = (UINT16*)DrvPalRAM;
581
582 for (INT32 i = 0; i < 0x1000/2; i++)
583 {
584 INT32 r = (pal[i] & 0x1f);
585 INT32 g = (pal[i] >> 5) & 0x1f;
586 INT32 b = (pal[i] >> 10) & 0x1f;
587
588 r = (r << 3) | (r >> 2);
589 g = (g << 3) | (g >> 2);
590 b = (b << 3) | (b >> 2);
591
592 DrvPalette[i] = (r << 16) + (g << 8) + b;
593 }
594 }
595
DrvDraw()596 static INT32 DrvDraw()
597 {
598 DrvPaletteRecalc();
599
600 INT32 layers[4], dirty, mask = 0, vrc_mode, vrc_new;
601
602 K056832ReadAvac(&vrc_mode, &vrc_new);
603
604 if (vrc_mode)
605 {
606 for (dirty = 0xf000; dirty; dirty >>= 4)
607 if ((avac_vrc & dirty) != (vrc_new & dirty))
608 mask |= dirty;
609
610 avac_vrc = vrc_new;
611 avac_bits[0] = vrc_new << 4 & 0xf000;
612 avac_bits[1] = vrc_new & 0xf000;
613 avac_bits[2] = vrc_new << 8 & 0xf000;
614 avac_bits[3] = vrc_new << 12 & 0xf000;
615 }
616 else
617 avac_bits[3] = avac_bits[2] = avac_bits[1] = avac_bits[0] = 0xf000;
618
619 sprite_colorbase = K053251GetPaletteIndex(0);
620
621 for (INT32 i = 0; i < 4; i++) {
622 layer_colorbase[i] = K053251GetPaletteIndex(i+1);
623 }
624
625 if (K056832ReadRegister(0x14) == 2)
626 {
627 K056832SetLayerOffsets(0, 2, 0);
628 K056832SetLayerOffsets(1, 4, 0);
629 K056832SetLayerOffsets(2, 6, 0);
630 K056832SetLayerOffsets(3, 8, 0);
631 }
632 else
633 {
634 K056832SetLayerOffsets(0, 0, 0);
635 K056832SetLayerOffsets(1, 8, 0);
636 K056832SetLayerOffsets(2, 14, 0);
637 K056832SetLayerOffsets(3, 16, 0);
638 }
639
640 KonamiClearBitmaps(0);
641
642 layers[0] = 0;
643 layerpri[0] = 0; // not sure
644 layers[1] = 1;
645 layerpri[1] = K053251GetPriority(2);
646 layers[2] = 2;
647 layerpri[2] = K053251GetPriority(3);
648 layers[3] = 3;
649 layerpri[3] = K053251GetPriority(4);
650
651 konami_sortlayers4(layers, layerpri);
652
653 if (nBurnLayer & 1) K056832Draw(layers[0], K056832_DRAW_FLAG_MIRROR, 1);
654 if (nBurnLayer & 2) K056832Draw(layers[1], K056832_DRAW_FLAG_MIRROR, 2);
655 if (nBurnLayer & 4) K056832Draw(layers[2], K056832_DRAW_FLAG_MIRROR, 4);
656 if (nBurnLayer & 8) K056832Draw(layers[3], K056832_DRAW_FLAG_MIRROR, 8);
657
658 if (nSpriteEnable & 1) K053247SpritesRender();
659
660 KonamiBlendCopy(DrvPalette);
661
662 return 0;
663 }
664
DrvFrame()665 static INT32 DrvFrame()
666 {
667 if (DrvReset) {
668 DrvDoReset();
669 }
670
671 {
672 memset (DrvInputs, 0xff, 4 * sizeof(INT16));
673 for (INT32 i = 0; i < 16; i++) {
674 DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
675 DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
676 DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
677 DrvInputs[3] ^= (DrvJoy4[i] & 1) << i;
678 }
679
680 DrvInputs[0] = (DrvInputs[0] & 0xf7ff) | ((DrvDips[0] & 0x08) << 8);
681 DrvInputs[2] = (DrvInputs[2] & 0x7f7f) | (DrvDips[1] & 0x80) | ((DrvDips[2] & 0x80) << 8);
682 DrvInputs[3] = (DrvInputs[3] & 0xff7f) | (DrvDips[3] & 0x80);
683 DrvInputs[0] &= 0x0fff;
684 DrvInputs[1] &= 0x0fff;
685 }
686
687 INT32 nInterleave = 256;
688 INT32 nCyclesTotal[2] = { 16000000 / 60, 8000000 / 60 };
689 INT32 nCyclesDone[2] = { 0, 0 };
690
691 SekOpen(0);
692 ZetOpen(0);
693
694 for (INT32 i = 0; i < nInterleave; i++) {
695 INT32 nNext, nCyclesSegment;
696
697 nNext = (i + 1) * nCyclesTotal[0] / nInterleave;
698 nCyclesSegment = nNext - nCyclesDone[0];
699 nCyclesSegment = SekRun(nCyclesSegment);
700 nCyclesDone[0] += nCyclesSegment;
701
702 if (control_data & 0x20 && irq6_timer == 0) {
703 SekSetIRQLine(6, CPU_IRQSTATUS_AUTO);
704 irq6_timer = -1;
705 } else if (irq6_timer != -1) irq6_timer--;
706
707 nNext = (i + 1) * nCyclesTotal[1] / nInterleave;
708 nCyclesSegment = nNext - nCyclesDone[1];
709 nCyclesSegment = ZetRun(nCyclesSegment);
710 nCyclesDone[1] += nCyclesSegment;
711 if ((i % (nInterleave / 8)) == ((nInterleave / 8) - 1) && sound_nmi_enable) {
712 ZetNmi();
713 }
714
715 if (i == 240) {
716 if (K056832IsIrqEnabled()) {
717 if (K053246_is_IRQ_enabled()) {
718 gijoe_objdma();
719 irq6_timer = 1; // guess
720 }
721
722 if (control_data & 0x80) {
723 SekSetIRQLine(5, CPU_IRQSTATUS_AUTO);
724 }
725 }
726 }
727 }
728
729 if (pBurnSoundOut) {
730 BurnSoundClear();
731 K054539Update(0, pBurnSoundOut, nBurnSoundLen);
732 }
733
734 ZetClose();
735 SekClose();
736
737 if (pBurnDraw) {
738 DrvDraw();
739 }
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 = 0x029732;
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 SekScan(nAction);
761 ZetScan(nAction);
762
763 K054539Scan(nAction, pnMin);
764
765 KonamiICScan(nAction);
766
767 SCAN_VAR(avac_vrc);
768 SCAN_VAR(avac_bits);
769 SCAN_VAR(avac_occupancy);
770 SCAN_VAR(sound_nmi_enable);
771 SCAN_VAR(control_data);
772 SCAN_VAR(irq6_timer);
773
774 SCAN_VAR(layerpri);
775 SCAN_VAR(layer_colorbase);
776 SCAN_VAR(sprite_colorbase);
777 }
778
779 return 0;
780 }
781
782
783 // G.I. Joe (World, EAB, set 1)
784
785 static struct BurnRomInfo gijoeRomDesc[] = {
786 { "069eab03.14e", 0x040000, 0xdd2d533f, 1 | BRF_PRG | BRF_ESS }, // 0 68K Code
787 { "069eab02.18e", 0x040000, 0x6bb11c87, 1 | BRF_PRG | BRF_ESS }, // 1
788 { "069a12.13e", 0x040000, 0x75a7585c, 1 | BRF_PRG | BRF_ESS }, // 2
789 { "069a11.16e", 0x040000, 0x3153e788, 1 | BRF_PRG | BRF_ESS }, // 3
790
791 { "069a01.7c", 0x010000, 0x74172b99, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 Code
792
793 { "069a10.18j", 0x100000, 0x4c6743ee, 3 | BRF_GRA }, // 5 K056832 Characters
794 { "069a09.16j", 0x100000, 0xe6e36b05, 3 | BRF_GRA }, // 6
795
796 { "069a08.6h", 0x100000, 0x325477d4, 4 | BRF_GRA }, // 7 K053247 Sprites
797 { "069a05.1h", 0x100000, 0xc4ab07ed, 4 | BRF_GRA }, // 8
798 { "069a07.4h", 0x100000, 0xccaa3971, 4 | BRF_GRA }, // 9
799 { "069a06.2h", 0x100000, 0x63eba8e1, 4 | BRF_GRA }, // 10
800
801 { "069a04.1e", 0x200000, 0x11d6dcd6, 5 | BRF_SND }, // 11 k054539
802
803 { "er5911.7d", 0x000080, 0xa0d50a79, 6 | BRF_OPT }, // 12 eeprom data
804 };
805
806 STD_ROM_PICK(gijoe)
807 STD_ROM_FN(gijoe)
808
809 struct BurnDriver BurnDrvGijoe = {
810 "gijoe", NULL, NULL, NULL, "1992",
811 "G.I. Joe (World, EAB, set 1)\0", NULL, "Konami", "GX069",
812 NULL, NULL, NULL, NULL,
813 BDF_GAME_WORKING, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
814 NULL, gijoeRomInfo, gijoeRomName, NULL, NULL, NULL, NULL, GijoeInputInfo, GijoeDIPInfo,
815 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
816 288, 224, 4, 3
817 };
818
819
820 // G.I. Joe (World, EB8, prototype?)
821
822 static struct BurnRomInfo gijoeeaRomDesc[] = {
823 { "rom3.14e", 0x040000, 0x0a11f63a, 1 | BRF_PRG | BRF_ESS }, // 0 68K Code
824 { "rom2.18e", 0x040000, 0x8313c559, 1 | BRF_PRG | BRF_ESS }, // 1
825 { "069a12.13e", 0x040000, 0x75a7585c, 1 | BRF_PRG | BRF_ESS }, // 2
826 { "069a11.16e", 0x040000, 0x3153e788, 1 | BRF_PRG | BRF_ESS }, // 3
827
828 { "069a01.7c", 0x010000, 0x74172b99, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 Code
829
830 { "069a10.18j", 0x100000, 0x4c6743ee, 3 | BRF_GRA }, // 5 K056832 Characters
831 { "069a09.16j", 0x100000, 0xe6e36b05, 3 | BRF_GRA }, // 6
832
833 { "069a08.6h", 0x100000, 0x325477d4, 4 | BRF_GRA }, // 7 K053247 Sprites
834 { "069a05.1h", 0x100000, 0xc4ab07ed, 4 | BRF_GRA }, // 8
835 { "069a07.4h", 0x100000, 0xccaa3971, 4 | BRF_GRA }, // 9
836 { "069a06.2h", 0x100000, 0x63eba8e1, 4 | BRF_GRA }, // 10
837
838 { "069a04.1e", 0x200000, 0x11d6dcd6, 5 | BRF_SND }, // 11 k054539
839
840 { "er5911.7d", 0x000080, 0x64f5c87b, 6 | BRF_OPT }, // 12 eeprom data
841 };
842
843 STD_ROM_PICK(gijoeea)
844 STD_ROM_FN(gijoeea)
845
846 struct BurnDriver BurnDrvGijoeea = {
847 "gijoeea", "gijoe", NULL, NULL, "1992",
848 "G.I. Joe (World, EB8, prototype?)\0", NULL, "Konami", "GX069",
849 NULL, NULL, NULL, NULL,
850 BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
851 NULL, gijoeeaRomInfo, gijoeeaRomName, NULL, NULL, NULL, NULL, GijoeInputInfo, GijoeDIPInfo,
852 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
853 288, 224, 4, 3
854 };
855
856
857 // G.I. Joe (US, UAB)
858
859 static struct BurnRomInfo gijoeuRomDesc[] = {
860 { "069uab03.14e", 0x040000, 0x25ff77d2, 1 | BRF_PRG | BRF_ESS }, // 0 68K Code
861 { "069uab02.18e", 0x040000, 0x31cced1c, 1 | BRF_PRG | BRF_ESS }, // 1
862 { "069a12.13e", 0x040000, 0x75a7585c, 1 | BRF_PRG | BRF_ESS }, // 2
863 { "069a11.16e", 0x040000, 0x3153e788, 1 | BRF_PRG | BRF_ESS }, // 3
864
865 { "069a01.7c", 0x010000, 0x74172b99, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 Code
866
867 { "069a10.18j", 0x100000, 0x4c6743ee, 3 | BRF_GRA }, // 5 K056832 Characters
868 { "069a09.16j", 0x100000, 0xe6e36b05, 3 | BRF_GRA }, // 6
869
870 { "069a08.6h", 0x100000, 0x325477d4, 4 | BRF_GRA }, // 7 K053247 Sprites
871 { "069a05.1h", 0x100000, 0xc4ab07ed, 4 | BRF_GRA }, // 8
872 { "069a07.4h", 0x100000, 0xccaa3971, 4 | BRF_GRA }, // 9
873 { "069a06.2h", 0x100000, 0x63eba8e1, 4 | BRF_GRA }, // 10
874
875 { "069a04.1e", 0x200000, 0x11d6dcd6, 5 | BRF_SND }, // 11 k054539
876
877 { "er5911.7d", 0x000080, 0xca966023, 6 | BRF_OPT }, // 12 eeprom data
878 };
879
880 STD_ROM_PICK(gijoeu)
881 STD_ROM_FN(gijoeu)
882
883 struct BurnDriver BurnDrvGijoeu = {
884 "gijoeu", "gijoe", NULL, NULL, "1992",
885 "G.I. Joe (US, UAB)\0", NULL, "Konami", "GX069",
886 NULL, NULL, NULL, NULL,
887 BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
888 NULL, gijoeuRomInfo, gijoeuRomName, NULL, NULL, NULL, NULL, GijoeInputInfo, GijoeDIPInfo,
889 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
890 288, 224, 4, 3
891 };
892
893
894 // G.I. Joe (Japan, JAA)
895
896 static struct BurnRomInfo gijoejRomDesc[] = {
897 { "069jaa03.14e", 0x040000, 0x4b398901, 1 | BRF_PRG | BRF_ESS }, // 0 68K Code
898 { "069jaa02.18e", 0x040000, 0x8bb22392, 1 | BRF_PRG | BRF_ESS }, // 1
899 { "069a12.13e", 0x040000, 0x75a7585c, 1 | BRF_PRG | BRF_ESS }, // 2
900 { "069a11.16e", 0x040000, 0x3153e788, 1 | BRF_PRG | BRF_ESS }, // 3
901
902 { "069a01.7c", 0x010000, 0x74172b99, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 Code
903
904 { "069a10.18j", 0x100000, 0x4c6743ee, 3 | BRF_GRA }, // 5 K056832 Characters
905 { "069a09.16j", 0x100000, 0xe6e36b05, 3 | BRF_GRA }, // 6
906
907 { "069a08.6h", 0x100000, 0x325477d4, 4 | BRF_GRA }, // 7 K053247 Sprites
908 { "069a05.1h", 0x100000, 0xc4ab07ed, 4 | BRF_GRA }, // 8
909 { "069a07.4h", 0x100000, 0xccaa3971, 4 | BRF_GRA }, // 9
910 { "069a06.2h", 0x100000, 0x63eba8e1, 4 | BRF_GRA }, // 10
911
912 { "069a04.1e", 0x200000, 0x11d6dcd6, 5 | BRF_SND }, // 11 k054539
913
914 { "er5911.7d", 0x000080, 0xc914fcf2, 6 | BRF_OPT }, // 12 eeprom data
915 };
916
917 STD_ROM_PICK(gijoej)
918 STD_ROM_FN(gijoej)
919
920 struct BurnDriver BurnDrvGijoej = {
921 "gijoej", "gijoe", NULL, NULL, "1992",
922 "G.I. Joe (Japan, JAA)\0", NULL, "Konami", "GX069",
923 NULL, NULL, NULL, NULL,
924 BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
925 NULL, gijoejRomInfo, gijoejRomName, NULL, NULL, NULL, NULL, GijoeInputInfo, GijoeDIPInfo,
926 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
927 288, 224, 4, 3
928 };
929
930
931 // G.I. Joe (Asia, AA)
932
933 static struct BurnRomInfo gijoeaRomDesc[] = {
934 { "069aa03.14e", 0x040000, 0x74355c6e, 1 | BRF_PRG | BRF_ESS }, // 0 68K Code
935 { "069aa02.18e", 0x040000, 0xd3dd0397, 1 | BRF_PRG | BRF_ESS }, // 1
936 { "069a12.13e", 0x040000, 0x75a7585c, 1 | BRF_PRG | BRF_ESS }, // 2
937 { "069a11.16e", 0x040000, 0x3153e788, 1 | BRF_PRG | BRF_ESS }, // 3
938
939 { "069a01.7c", 0x010000, 0x74172b99, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 Code
940
941 { "069a10.18j", 0x100000, 0x4c6743ee, 3 | BRF_GRA }, // 5 K056832 Characters
942 { "069a09.16j", 0x100000, 0xe6e36b05, 3 | BRF_GRA }, // 6
943
944 { "069a08.6h", 0x100000, 0x325477d4, 4 | BRF_GRA }, // 7 K053247 Sprites
945 { "069a05.1h", 0x100000, 0xc4ab07ed, 4 | BRF_GRA }, // 8
946 { "069a07.4h", 0x100000, 0xccaa3971, 4 | BRF_GRA }, // 9
947 { "069a06.2h", 0x100000, 0x63eba8e1, 4 | BRF_GRA }, // 10
948
949 { "069a04.1e", 0x200000, 0x11d6dcd6, 5 | BRF_SND }, // 11 k054539
950
951 { "er5911.7d", 0x000080, 0x6363513c, 6 | BRF_OPT }, // 12 eeprom data
952 };
953
954 STD_ROM_PICK(gijoea)
955 STD_ROM_FN(gijoea)
956
957 struct BurnDriver BurnDrvGijoea = {
958 "gijoea", "gijoe", NULL, NULL, "1992",
959 "G.I. Joe (Asia, AA)\0", NULL, "Konami", "GX069",
960 NULL, NULL, NULL, NULL,
961 BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_PREFIX_KONAMI, GBF_RUNGUN, 0,
962 NULL, gijoeaRomInfo, gijoeaRomName, NULL, NULL, NULL, NULL, GijoeInputInfo, GijoeDIPInfo,
963 DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x800,
964 288, 224, 4, 3
965 };