diff --git a/src/burn/misc/pre90s/d_1942.cpp b/src/burn/misc/pre90s/d_1942.cpp new file mode 100644 index 0000000..38b0639 --- /dev/null +++ b/src/burn/misc/pre90s/d_1942.cpp @@ -0,0 +1,992 @@ +#include "tiles_generic.h" + +#include "driver.h" +extern "C" { + #include "ay8910.h" +} + +static unsigned char DrvInputPort0[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char DrvInputPort1[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char DrvInputPort2[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char DrvDip[2] = {0, 0}; +static unsigned char DrvInput[3] = {0x00, 0x00, 0x00}; +static unsigned char DrvReset = 0; + +static unsigned char *Mem = NULL; +static unsigned char *MemEnd = NULL; +static unsigned char *RamStart = NULL; +static unsigned char *RamEnd = NULL; +static unsigned char *DrvZ80Rom1 = NULL; +static unsigned char *DrvZ80Rom2 = NULL; +static unsigned char *DrvZ80Ram1 = NULL; +static unsigned char *DrvZ80Ram2 = NULL; +static unsigned char *DrvFgVideoRam = NULL; +static unsigned char *DrvBgVideoRam = NULL; +static unsigned char *DrvSpriteRam = NULL; +static unsigned char *DrvPromRed = NULL; +static unsigned char *DrvPromGreen = NULL; +static unsigned char *DrvPromBlue = NULL; +static unsigned char *DrvPromCharLookup = NULL; +static unsigned char *DrvPromTileLookup = NULL; +static unsigned char *DrvPromSpriteLookup = NULL; +static unsigned char *DrvChars = NULL; +static unsigned char *DrvTiles = NULL; +static unsigned char *DrvSprites = NULL; +static unsigned char *DrvTempRom = NULL; +static unsigned int *DrvPalette = NULL; +static short* pFMBuffer; +static short* pAY8910Buffer[6]; + +static unsigned char DrvRomBank; +static unsigned char DrvPaletteBank; +static unsigned char DrvBgScroll[2]; +static unsigned char DrvFlipScreen; +static unsigned char DrvSoundLatch; + +static int nCyclesDone[2], nCyclesTotal[2]; +static int nCyclesSegment; + +static struct BurnInputInfo DrvInputList[] = +{ + {"Coin 1" , BIT_DIGITAL , DrvInputPort0 + 7, "p1 coin" }, + {"Start 1" , BIT_DIGITAL , DrvInputPort0 + 0, "p1 start" }, + {"Coin 2" , BIT_DIGITAL , DrvInputPort0 + 6, "p2 coin" }, + {"Start 2" , BIT_DIGITAL , DrvInputPort0 + 1, "p2 start" }, + + {"Up" , BIT_DIGITAL , DrvInputPort1 + 3, "p1 up" }, + {"Down" , BIT_DIGITAL , DrvInputPort1 + 2, "p1 down" }, + {"Left" , BIT_DIGITAL , DrvInputPort1 + 1, "p1 left" }, + {"Right" , BIT_DIGITAL , DrvInputPort1 + 0, "p1 right" }, + {"Fire 1" , BIT_DIGITAL , DrvInputPort1 + 4, "p1 fire 1" }, + {"Fire 2" , BIT_DIGITAL , DrvInputPort1 + 5, "p1 fire 2" }, + + {"Up (Cocktail)" , BIT_DIGITAL , DrvInputPort2 + 3, "p2 up" }, + {"Down (Cocktail)" , BIT_DIGITAL , DrvInputPort2 + 2, "p2 down" }, + {"Left (Cocktail)" , BIT_DIGITAL , DrvInputPort2 + 1, "p2 left" }, + {"Right (Cocktail)" , BIT_DIGITAL , DrvInputPort2 + 0, "p2 right" }, + {"Fire 1 (Cocktail)" , BIT_DIGITAL , DrvInputPort2 + 4, "p2 fire 1" }, + {"Fire 2 (Cocktail)" , BIT_DIGITAL , DrvInputPort2 + 5, "p2 fire 2" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Service" , BIT_DIGITAL , DrvInputPort0 + 4, "service" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDip + 0 , "dip" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDip + 1 , "dip" }, +}; + + +STDINPUTINFO(Drv); + +static inline void DrvClearOpposites(unsigned char* nJoystickInputs) +{ + if ((*nJoystickInputs & 0x03) == 0x03) { + *nJoystickInputs &= ~0x03; + } + if ((*nJoystickInputs & 0x0c) == 0x0c) { + *nJoystickInputs &= ~0x0c; + } +} + +static inline void DrvMakeInputs() +{ + // Reset Inputs + DrvInput[0] = DrvInput[1] = DrvInput[2] = 0x00; + + // Compile Digital Inputs + for (int i = 0; i < 8; i++) { + DrvInput[0] |= (DrvInputPort0[i] & 1) << i; + DrvInput[1] |= (DrvInputPort1[i] & 1) << i; + DrvInput[2] |= (DrvInputPort2[i] & 1) << i; + } + + // Clear Opposites + DrvClearOpposites(&DrvInput[1]); + DrvClearOpposites(&DrvInput[2]); +} + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x12, 0xff, 0xff, 0xf7, NULL }, + {0x13, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x12, 0x01, 0x07, 0x01, "4 Coins 1 Play" }, + {0x12, 0x01, 0x07, 0x02, "3 Coins 1 Play" }, + {0x12, 0x01, 0x07, 0x04, "2 Coins 1 Play" }, + {0x12, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x12, 0x01, 0x07, 0x03, "2 Coins 3 Plays" }, + {0x12, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x12, 0x01, 0x07, 0x05, "1 Coin 4 Plays" }, + {0x12, 0x01, 0x07, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x08, 0x00, "Upright" }, + {0x12, 0x01, 0x08, 0x08, "Cocktail" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x12, 0x01, 0x30, 0x30, "20k 80k 80k+" }, + {0x12, 0x01, 0x30, 0x20, "20k 100k 100k+" }, + {0x12, 0x01, 0x30, 0x10, "30k 80k 80k+" }, + {0x12, 0x01, 0x30, 0x00, "30k 100k 100k+" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x12, 0x01, 0xc0, 0x80, "1" }, + {0x12, 0x01, 0xc0, 0x40, "2" }, + {0x12, 0x01, 0xc0, 0xc0, "3" }, + {0x12, 0x01, 0xc0, 0x00, "5" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x13, 0x01, 0x07, 0x01, "4 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x02, "3 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x04, "2 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x13, 0x01, 0x07, 0x03, "2 Coins 3 Plays" }, + {0x13, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x07, 0x05, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x07, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 2 , "Service Mode" }, + {0x13, 0x01, 0x08, 0x08, "Off" }, + {0x13, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x13, 0x01, 0x10, 0x10, "Off" }, + {0x13, 0x01, 0x10, 0x00, "On" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x13, 0x01, 0x60, 0x40, "Easy" }, + {0x13, 0x01, 0x60, 0x60, "Normal" }, + {0x13, 0x01, 0x60, 0x20, "Difficult" }, + {0x13, 0x01, 0x60, 0x00, "Very Difficult" }, + + {0 , 0xfe, 0 , 2 , "Screen Stop" }, + {0x13, 0x01, 0x80, 0x80, "Off" }, + {0x13, 0x01, 0x80, 0x00, "On" }, +}; + +STDDIPINFO(Drv); + +static struct BurnRomInfo DrvRomDesc[] = { + { "srb-03.m3", 0x04000, 0xd9dafcc3, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "srb-04.m4", 0x04000, 0xda0cf924, BRF_ESS | BRF_PRG }, // 1 + { "srb-05.m5", 0x04000, 0xd102911c, BRF_ESS | BRF_PRG }, // 2 + { "srb-06.m6", 0x02000, 0x466f8248, BRF_ESS | BRF_PRG }, // 3 + { "srb-07.m7", 0x04000, 0x0d31038c, BRF_ESS | BRF_PRG }, // 4 + + { "sr-01.c11", 0x04000, 0xbd87f06b, BRF_ESS | BRF_PRG }, // 5 Z80 #2 Program + + { "sr-02.f2", 0x02000, 0x6ebca191, BRF_GRA }, // 6 Characters + + { "sr-08.a1", 0x02000, 0x3884d9eb, BRF_GRA }, // 7 Tiles + { "sr-09.a2", 0x02000, 0x999cf6e0, BRF_GRA }, // 8 + { "sr-10.a3", 0x02000, 0x8edb273a, BRF_GRA }, // 9 + { "sr-11.a4", 0x02000, 0x3a2726c3, BRF_GRA }, // 10 + { "sr-12.a5", 0x02000, 0x1bd3d8bb, BRF_GRA }, // 11 + { "sr-13.a6", 0x02000, 0x658f02c4, BRF_GRA }, // 12 + + { "sr-14.l1", 0x04000, 0x2528bec6, BRF_GRA }, // 13 Sprites + { "sr-15.l2", 0x04000, 0xf89287aa, BRF_GRA }, // 14 + { "sr-16.n1", 0x04000, 0x024418f8, BRF_GRA }, // 15 + { "sr-17.n2", 0x04000, 0xe2c7e489, BRF_GRA }, // 16 + + { "sb-5.e8", 0x00100, 0x93ab8153, BRF_GRA }, // 17 PROMs + { "sb-6.e9", 0x00100, 0x8ab44f7d, BRF_GRA }, // 18 + { "sb-7.e10", 0x00100, 0xf4ade9a4, BRF_GRA }, // 19 + { "sb-0.f1", 0x00100, 0x6047d91b, BRF_GRA }, // 20 + { "sb-4.d6", 0x00100, 0x4858968d, BRF_GRA }, // 21 + { "sb-8.k3", 0x00100, 0xf6fad943, BRF_GRA }, // 22 + { "sb-2.d1", 0x00100, 0x8bb8b3df, BRF_GRA }, // 23 + { "sb-3.d2", 0x00100, 0x3b0c99af, BRF_GRA }, // 24 + { "sb-1.k6", 0x00100, 0x712ac508, BRF_GRA }, // 25 + { "sb-9.m11", 0x00100, 0x4921635c, BRF_GRA }, // 26 +}; + +STD_ROM_PICK(Drv); +STD_ROM_FN(Drv); + +static struct BurnRomInfo DrvaRomDesc[] = { + { "sra-03.m3", 0x04000, 0x40201bab, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "sr-04.m4", 0x04000, 0xa60ac644, BRF_ESS | BRF_PRG }, // 1 + { "sr-05.m5", 0x04000, 0x835f7b24, BRF_ESS | BRF_PRG }, // 2 + { "sr-06.m6", 0x02000, 0x821c6481, BRF_ESS | BRF_PRG }, // 3 + { "sr-07.m7", 0x04000, 0x5df525e1, BRF_ESS | BRF_PRG }, // 4 + + { "sr-01.c11", 0x04000, 0xbd87f06b, BRF_ESS | BRF_PRG }, // 5 Z80 #2 Program + + { "sr-02.f2", 0x02000, 0x6ebca191, BRF_GRA }, // 6 Characters + + { "sr-08.a1", 0x02000, 0x3884d9eb, BRF_GRA }, // 7 Tiles + { "sr-09.a2", 0x02000, 0x999cf6e0, BRF_GRA }, // 8 + { "sr-10.a3", 0x02000, 0x8edb273a, BRF_GRA }, // 9 + { "sr-11.a4", 0x02000, 0x3a2726c3, BRF_GRA }, // 10 + { "sr-12.a5", 0x02000, 0x1bd3d8bb, BRF_GRA }, // 11 + { "sr-13.a6", 0x02000, 0x658f02c4, BRF_GRA }, // 12 + + { "sr-14.l1", 0x04000, 0x2528bec6, BRF_GRA }, // 13 Sprites + { "sr-15.l2", 0x04000, 0xf89287aa, BRF_GRA }, // 14 + { "sr-16.n1", 0x04000, 0x024418f8, BRF_GRA }, // 15 + { "sr-17.n2", 0x04000, 0xe2c7e489, BRF_GRA }, // 16 + + { "sb-5.e8", 0x00100, 0x93ab8153, BRF_GRA }, // 17 PROMs + { "sb-6.e9", 0x00100, 0x8ab44f7d, BRF_GRA }, // 18 + { "sb-7.e10", 0x00100, 0xf4ade9a4, BRF_GRA }, // 19 + { "sb-0.f1", 0x00100, 0x6047d91b, BRF_GRA }, // 20 + { "sb-4.d6", 0x00100, 0x4858968d, BRF_GRA }, // 21 + { "sb-8.k3", 0x00100, 0xf6fad943, BRF_GRA }, // 22 + { "sb-2.d1", 0x00100, 0x8bb8b3df, BRF_GRA }, // 23 + { "sb-3.d2", 0x00100, 0x3b0c99af, BRF_GRA }, // 24 + { "sb-1.k6", 0x00100, 0x712ac508, BRF_GRA }, // 25 + { "sb-9.m11", 0x00100, 0x4921635c, BRF_GRA }, // 26 +}; + +STD_ROM_PICK(Drva); +STD_ROM_FN(Drva); + +static struct BurnRomInfo DrvbRomDesc[] = { + { "sr-03.m3", 0x04000, 0x612975f2, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "sr-04.m4", 0x04000, 0xa60ac644, BRF_ESS | BRF_PRG }, // 1 + { "sr-05.m5", 0x04000, 0x835f7b24, BRF_ESS | BRF_PRG }, // 2 + { "sr-06.m6", 0x02000, 0x821c6481, BRF_ESS | BRF_PRG }, // 3 + { "sr-07.m7", 0x04000, 0x5df525e1, BRF_ESS | BRF_PRG }, // 4 + + { "sr-01.c11", 0x04000, 0xbd87f06b, BRF_ESS | BRF_PRG }, // 5 Z80 #2 Program + + { "sr-02.f2", 0x02000, 0x6ebca191, BRF_GRA }, // 6 Characters + + { "sr-08.a1", 0x02000, 0x3884d9eb, BRF_GRA }, // 7 Tiles + { "sr-09.a2", 0x02000, 0x999cf6e0, BRF_GRA }, // 8 + { "sr-10.a3", 0x02000, 0x8edb273a, BRF_GRA }, // 9 + { "sr-11.a4", 0x02000, 0x3a2726c3, BRF_GRA }, // 10 + { "sr-12.a5", 0x02000, 0x1bd3d8bb, BRF_GRA }, // 11 + { "sr-13.a6", 0x02000, 0x658f02c4, BRF_GRA }, // 12 + + { "sr-14.l1", 0x04000, 0x2528bec6, BRF_GRA }, // 13 Sprites + { "sr-15.l2", 0x04000, 0xf89287aa, BRF_GRA }, // 14 + { "sr-16.n1", 0x04000, 0x024418f8, BRF_GRA }, // 15 + { "sr-17.n2", 0x04000, 0xe2c7e489, BRF_GRA }, // 16 + + { "sb-5.e8", 0x00100, 0x93ab8153, BRF_GRA }, // 17 PROMs + { "sb-6.e9", 0x00100, 0x8ab44f7d, BRF_GRA }, // 18 + { "sb-7.e10", 0x00100, 0xf4ade9a4, BRF_GRA }, // 19 + { "sb-0.f1", 0x00100, 0x6047d91b, BRF_GRA }, // 20 + { "sb-4.d6", 0x00100, 0x4858968d, BRF_GRA }, // 21 + { "sb-8.k3", 0x00100, 0xf6fad943, BRF_GRA }, // 22 + { "sb-2.d1", 0x00100, 0x8bb8b3df, BRF_GRA }, // 23 + { "sb-3.d2", 0x00100, 0x3b0c99af, BRF_GRA }, // 24 + { "sb-1.k6", 0x00100, 0x712ac508, BRF_GRA }, // 25 + { "sb-9.m11", 0x00100, 0x4921635c, BRF_GRA }, // 26 +}; + +STD_ROM_PICK(Drvb); +STD_ROM_FN(Drvb); + +static struct BurnRomInfo DrvwRomDesc[] = { + { "sw-03.m3", 0x04000, 0xafd79770, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "sw-04.m4", 0x04000, 0x933d9910, BRF_ESS | BRF_PRG }, // 1 + { "sw-05.m5", 0x04000, 0xe9a71bb6, BRF_ESS | BRF_PRG }, // 2 + { "sw-06.m6", 0x02000, 0x466f8248, BRF_ESS | BRF_PRG }, // 3 + { "sw-07.m7", 0x04000, 0xec41655e, BRF_ESS | BRF_PRG }, // 4 + + { "sr-01.c11", 0x04000, 0xbd87f06b, BRF_ESS | BRF_PRG }, // 5 Z80 #2 Program + + { "sw-02.f2", 0x02000, 0xf8e9ada2, BRF_GRA }, // 6 Characters + + { "sr-08.a1", 0x02000, 0x3884d9eb, BRF_GRA }, // 7 Tiles + { "sr-09.a2", 0x02000, 0x999cf6e0, BRF_GRA }, // 8 + { "sr-10.a3", 0x02000, 0x8edb273a, BRF_GRA }, // 9 + { "sr-11.a4", 0x02000, 0x3a2726c3, BRF_GRA }, // 10 + { "sr-12.a5", 0x02000, 0x1bd3d8bb, BRF_GRA }, // 11 + { "sr-13.a6", 0x02000, 0x658f02c4, BRF_GRA }, // 12 + + { "sr-14.l1", 0x04000, 0x2528bec6, BRF_GRA }, // 13 Sprites + { "sr-15.l2", 0x04000, 0xf89287aa, BRF_GRA }, // 14 + { "sr-16.n1", 0x04000, 0x024418f8, BRF_GRA }, // 15 + { "sr-17.n2", 0x04000, 0xe2c7e489, BRF_GRA }, // 16 + + { "sb-5.e8", 0x00100, 0x93ab8153, BRF_GRA }, // 17 PROMs + { "sb-6.e9", 0x00100, 0x8ab44f7d, BRF_GRA }, // 18 + { "sb-7.e10", 0x00100, 0xf4ade9a4, BRF_GRA }, // 19 + { "sb-0.f1", 0x00100, 0x6047d91b, BRF_GRA }, // 20 + { "sb-4.d6", 0x00100, 0x4858968d, BRF_GRA }, // 21 + { "sb-8.k3", 0x00100, 0xf6fad943, BRF_GRA }, // 22 + { "sb-2.d1", 0x00100, 0x8bb8b3df, BRF_GRA }, // 23 + { "sb-3.d2", 0x00100, 0x3b0c99af, BRF_GRA }, // 24 + { "sb-1.k6", 0x00100, 0x712ac508, BRF_GRA }, // 25 + { "sb-9.m11", 0x00100, 0x4921635c, BRF_GRA }, // 26 +}; + +STD_ROM_PICK(Drvw); +STD_ROM_FN(Drvw); + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + DrvZ80Rom1 = Next; Next += 0x1c000; + DrvZ80Rom2 = Next; Next += 0x04000; + DrvPromRed = Next; Next += 0x00100; + DrvPromGreen = Next; Next += 0x00100; + DrvPromBlue = Next; Next += 0x00100; + DrvPromCharLookup = Next; Next += 0x00100; + DrvPromTileLookup = Next; Next += 0x00100; + DrvPromSpriteLookup = Next; Next += 0x00100; + + RamStart = Next; + + DrvZ80Ram1 = Next; Next += 0x01000; + DrvZ80Ram2 = Next; Next += 0x00800; + DrvSpriteRam = Next; Next += 0x00080; + DrvFgVideoRam = Next; Next += 0x00800; + DrvBgVideoRam = Next; Next += 0x00400; + + RamEnd = Next; + + DrvChars = Next; Next += 0x200 * 8 * 8; + DrvTiles = Next; Next += 0x200 * 16 * 16; + DrvSprites = Next; Next += 0x200 * 16 * 16; + pFMBuffer = (short*)Next; Next += nBurnSoundLen * 6 * sizeof(short); + DrvPalette = (unsigned int*)Next; Next += 0x00600 * sizeof(unsigned int); + + MemEnd = Next; + + return 0; +} + +static int DrvDoReset() +{ + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + } + + for (int i = 0; i < 2; i++) { + AY8910Reset(i); + } + + DrvPaletteBank = 0; + DrvBgScroll[0] = 0; + DrvBgScroll[1] = 0; + DrvFlipScreen = 0; + DrvSoundLatch = 0; + DrvRomBank = 0; + + return 0; +} + +unsigned char __fastcall Drv1942Read1(unsigned short a) +{ + switch (a) { + case 0xc000: { + return 0xff - DrvInput[0]; + } + + case 0xc001: { + return 0xff - DrvInput[1]; + } + + case 0xc002: { + return 0xff - DrvInput[2]; + } + + case 0xc003: { + return DrvDip[0]; + } + + case 0xc004: { + return DrvDip[1]; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Read => %04X\n"), a); + } + } + + return 0; +} + +void __fastcall Drv1942Write1(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xc800: { + DrvSoundLatch = d; + return; + } + + case 0xc802: { + DrvBgScroll[0] = d; + return; + } + + case 0xc803: { + DrvBgScroll[1] = d; + return; + } + + case 0xc804: { + DrvFlipScreen = d & 0x80; + if (d & 0x10) { + ZetClose(); + ZetOpen(1); + ZetReset(); + ZetClose(); + ZetOpen(0); + } + return; + } + + case 0xc805: { + DrvPaletteBank = d; + return; + } + + case 0xc806: { + d &= 0x03; + DrvRomBank = d; + ZetMapArea(0x8000, 0xbfff, 0, DrvZ80Rom1 + 0x10000 + DrvRomBank * 0x4000 ); + ZetMapArea(0x8000, 0xbfff, 2, DrvZ80Rom1 + 0x10000 + DrvRomBank * 0x4000 ); + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Write => %04X, %02X\n"), a, d); + } + } +} + +unsigned char __fastcall Drv1942Read2(unsigned short a) +{ + switch (a) { + case 0x6000: { + return DrvSoundLatch; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Read => %04X\n"), a); + } + } + + return 0; +} + +void __fastcall Drv1942Write2(unsigned short a, unsigned char d) +{ + switch (a) { + case 0x8000: { + AY8910Write(0, 0, d); + return; + } + + case 0x8001: { + AY8910Write(0, 1, d); + return; + } + + case 0xc000: { + AY8910Write(1, 0, d); + return; + } + + case 0xc001: { + AY8910Write(1, 1, d); + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Write => %04X, %02X\n"), a, d); + } + } +} + + +static int CharPlaneOffsets[2] = { 4, 0 }; +static int CharXOffsets[8] = { 0, 1, 2, 3, 8, 9, 10, 11 }; +static int CharYOffsets[8] = { 0, 16, 32, 48, 64, 80, 96, 112 }; +static int TilePlaneOffsets[3] = { 0, 0x20000, 0x40000 }; +static int TileXOffsets[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 128, 129, 130, 131, 132, 133, 134, 135 }; +static int TileYOffsets[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }; +static int SpritePlaneOffsets[4] = { 0x40004, 0x40000, 4, 0 }; +static int SpriteXOffsets[16] = { 0, 1, 2, 3, 8, 9, 10, 11, 256, 257, 258, 259, 264, 265, 266, 267 }; +static int SpriteYOffsets[16] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240 }; + +static int DrvInit() +{ + int nRet = 0, nLen; + + // Allocate and Blank all required memory + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + DrvTempRom = (unsigned char *)malloc(0x10000); + + // Load Z80 #1 Program Roms + nRet = BurnLoadRom(DrvZ80Rom1 + 0x00000, 0, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvZ80Rom1 + 0x04000, 1, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvZ80Rom1 + 0x10000, 2, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvZ80Rom1 + 0x14000, 3, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvZ80Rom1 + 0x18000, 4, 1); if (nRet != 0) return 1; + + // Load Z80 #2 Program Roms + nRet = BurnLoadRom(DrvZ80Rom2 + 0x00000, 5, 1); if (nRet != 0) return 1; + + // Load and decode the chars + nRet = BurnLoadRom(DrvTempRom, 6, 1); if (nRet != 0) return 1; + GfxDecode(0x200, 2, 8, 8, CharPlaneOffsets, CharXOffsets, CharYOffsets, 0x80, DrvTempRom, DrvChars); + + // Load and decode the tiles + memset(DrvTempRom, 0, 0x10000); + nRet = BurnLoadRom(DrvTempRom + 0x00000, 7, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x02000, 8, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x04000, 9, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x06000, 10, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x08000, 11, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x0a000, 12, 1); if (nRet != 0) return 1; + GfxDecode(0x200, 3, 16, 16, TilePlaneOffsets, TileXOffsets, TileYOffsets, 0x100, DrvTempRom, DrvTiles); + + // Load and decode the sprites + memset(DrvTempRom, 0, 0x10000); + nRet = BurnLoadRom(DrvTempRom + 0x00000, 13, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x04000, 14, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x08000, 15, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x0c000, 16, 1); if (nRet != 0) return 1; + GfxDecode(0x200, 4, 16, 16, SpritePlaneOffsets, SpriteXOffsets, SpriteYOffsets, 0x200, DrvTempRom, DrvSprites); + + // Load the PROMs + nRet = BurnLoadRom(DrvPromRed, 17, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromGreen, 18, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromBlue, 19, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromCharLookup, 20, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromTileLookup, 21, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromSpriteLookup, 22, 1); if (nRet != 0) return 1; + + free(DrvTempRom); + + // Setup the Z80 emulation + ZetInit(2); + ZetOpen(0); + ZetSetReadHandler(Drv1942Read1); + ZetSetWriteHandler(Drv1942Write1); + ZetMapArea(0x0000, 0x7fff, 0, DrvZ80Rom1 ); + ZetMapArea(0x0000, 0x7fff, 2, DrvZ80Rom1 ); + ZetMapArea(0x8000, 0xbfff, 0, DrvZ80Rom1 + 0x10000 ); + ZetMapArea(0x8000, 0xbfff, 2, DrvZ80Rom1 + 0x10000 ); + ZetMapArea(0xcc00, 0xcc7f, 0, DrvSpriteRam ); + ZetMapArea(0xcc00, 0xcc7f, 1, DrvSpriteRam ); + ZetMapArea(0xcc00, 0xcc7f, 2, DrvSpriteRam ); + ZetMapArea(0xd000, 0xd7ff, 0, DrvFgVideoRam ); + ZetMapArea(0xd000, 0xd7ff, 1, DrvFgVideoRam ); + ZetMapArea(0xd000, 0xd7ff, 2, DrvFgVideoRam ); + ZetMapArea(0xd800, 0xdbff, 0, DrvBgVideoRam ); + ZetMapArea(0xd800, 0xdbff, 1, DrvBgVideoRam ); + ZetMapArea(0xd800, 0xdbff, 2, DrvBgVideoRam ); + ZetMapArea(0xe000, 0xefff, 0, DrvZ80Ram1 ); + ZetMapArea(0xe000, 0xefff, 1, DrvZ80Ram1 ); + ZetMapArea(0xe000, 0xefff, 2, DrvZ80Ram1 ); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetSetReadHandler(Drv1942Read2); + ZetSetWriteHandler(Drv1942Write2); + ZetMapArea(0x0000, 0x3fff, 0, DrvZ80Rom2 ); + ZetMapArea(0x0000, 0x3fff, 2, DrvZ80Rom2 ); + ZetMapArea(0x4000, 0x47ff, 0, DrvZ80Ram2 ); + ZetMapArea(0x4000, 0x47ff, 1, DrvZ80Ram2 ); + ZetMapArea(0x4000, 0x47ff, 2, DrvZ80Ram2 ); + ZetMemEnd(); + ZetClose(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + pAY8910Buffer[3] = pFMBuffer + nBurnSoundLen * 3; + pAY8910Buffer[4] = pFMBuffer + nBurnSoundLen * 4; + pAY8910Buffer[5] = pFMBuffer + nBurnSoundLen * 5; + + AY8910Init(0, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(1, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + GenericTilesInit(); + + // Reset the driver + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + + for (int i = 0; i < 2; i++) { + AY8910Exit(i); + } + + GenericTilesExit(); + + DrvPaletteBank = 0; + DrvBgScroll[0] = 0; + DrvBgScroll[1] = 0; + DrvFlipScreen = 0; + DrvSoundLatch = 0; + DrvRomBank = 0; + + free(Mem); + Mem = NULL; + + return 0; +} + +static void DrvCalcPalette() +{ + int i; + unsigned int Palette[256]; + + for (i = 0; i < 256; i++) { + int bit0, bit1, bit2, bit3, r, g, b; + + bit0 = (DrvPromRed[i] >> 0) & 0x01; + bit1 = (DrvPromRed[i] >> 1) & 0x01; + bit2 = (DrvPromRed[i] >> 2) & 0x01; + bit3 = (DrvPromRed[i] >> 3) & 0x01; + r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (DrvPromGreen[i] >> 0) & 0x01; + bit1 = (DrvPromGreen[i] >> 1) & 0x01; + bit2 = (DrvPromGreen[i] >> 2) & 0x01; + bit3 = (DrvPromGreen[i] >> 3) & 0x01; + g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (DrvPromBlue[i] >> 0) & 0x01; + bit1 = (DrvPromBlue[i] >> 1) & 0x01; + bit2 = (DrvPromBlue[i] >> 2) & 0x01; + bit3 = (DrvPromBlue[i] >> 3) & 0x01; + b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + Palette[i] = BurnHighCol(r, g, b, 0); + } + + for (i = 0; i < 256; i++) { + DrvPalette[i] = Palette[0x80 | DrvPromCharLookup[i]]; + } + + for (i = 0; i < 256; i++) { + DrvPalette[256 + i + 0] = Palette[0x00 | DrvPromTileLookup[i]]; + DrvPalette[256 + i + 256] = Palette[0x10 | DrvPromTileLookup[i]]; + DrvPalette[256 + i + 512] = Palette[0x20 | DrvPromTileLookup[i]]; + DrvPalette[256 + i + 768] = Palette[0x30 | DrvPromTileLookup[i]]; + } + + for (i = 0; i < 256; i++) { + DrvPalette[1280 + i] = Palette[0x40 | DrvPromSpriteLookup[i]]; + } +} + +static void DrvRenderBgLayer() +{ + int mx, my, Code, Colour, x, y, TileIndex, xScroll, Flip, xFlip, yFlip; + + xScroll = DrvBgScroll[0] | (DrvBgScroll[1] << 8); + xScroll &= 0x1ff; + + for (mx = 0; mx < 16; mx++) { + for (my = 0; my < 32; my++) { + TileIndex = (my * 16) + mx; + TileIndex = (TileIndex & 0x0f) | ((TileIndex & 0x01f0) << 1); + + Code = DrvBgVideoRam[TileIndex]; + Colour = DrvBgVideoRam[TileIndex + 0x10]; + Code += (Colour & 0x80) << 1; + Flip = (Colour & 0x60) >> 5; + xFlip = (Flip >> 0) & 0x01; + yFlip = (Flip >> 1) & 0x01; + Colour &= 0x1f; + + y = 16 * mx; + x = 16 * my; + x -= xScroll; + if (x < -16) x += 512; + y -= 16; + + if (x > 0 && x < 240 && y > 0 && y < 208) { + if (xFlip) { + if (yFlip) { + Render16x16Tile_FlipXY(pTransDraw, Code, x, y, Colour, 3, 256 + (0x100 * DrvPaletteBank), DrvTiles); + } else { + Render16x16Tile_FlipX(pTransDraw, Code, x, y, Colour, 3, 256 + (0x100 * DrvPaletteBank), DrvTiles); + } + } else { + if (yFlip) { + Render16x16Tile_FlipY(pTransDraw, Code, x, y, Colour, 3, 256 + (0x100 * DrvPaletteBank), DrvTiles); + } else { + Render16x16Tile(pTransDraw, Code, x, y, Colour, 3, 256 + (0x100 * DrvPaletteBank), DrvTiles); + } + } + } else { + if (xFlip) { + if (yFlip) { + Render16x16Tile_FlipXY_Clip(pTransDraw, Code, x, y, Colour, 3, 256 + (0x100 * DrvPaletteBank), DrvTiles); + } else { + Render16x16Tile_FlipX_Clip(pTransDraw, Code, x, y, Colour, 3, 256 + (0x100 * DrvPaletteBank), DrvTiles); + } + } else { + if (yFlip) { + Render16x16Tile_FlipY_Clip(pTransDraw, Code, x, y, Colour, 3, 256 + (0x100 * DrvPaletteBank), DrvTiles); + } else { + Render16x16Tile_Clip(pTransDraw, Code, x, y, Colour, 3, 256 + (0x100 * DrvPaletteBank), DrvTiles); + } + } + } + } + } +} + +static void DrvRenderSpriteLayer() +{ + int Offset; + + for (Offset = 0x80 - 4; Offset >= 0; Offset -= 4) { + int i, Code, Colour, sx, sy, Dir; + + Code = (DrvSpriteRam[Offset] & 0x7f) + (4 * (DrvSpriteRam[Offset + 1] & 0x20)) + (2 * (DrvSpriteRam[Offset] & 0x80)); + Colour = DrvSpriteRam[Offset + 1] & 0x0f; + sx = DrvSpriteRam[Offset + 3] - (0x10 * (DrvSpriteRam[Offset + 1] & 0x10)); + sy = DrvSpriteRam[Offset + 2]; + Dir = 1; + + i = (DrvSpriteRam[Offset + 1] & 0xc0) >> 6; + if (i == 2) i = 3; + + do { + Render16x16Tile_Mask_Clip(pTransDraw, Code + i, sx, (sy + (16 * i) * Dir) - 16, Colour, 4, 15, 1280, DrvSprites); + + i--; + } while (i >= 0); + } +} + +static void DrvRenderCharLayer() +{ + int mx, my, Code, Colour, x, y, TileIndex = 0; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 32; mx++) { + Code = DrvFgVideoRam[TileIndex]; + Colour = DrvFgVideoRam[TileIndex + 0x400]; + Code += (Colour & 0x80) << 1; + Colour &= 0x3f; + + x = 8 * mx; + y = 8 * my; + + y -= 16; + + if (x > 0 && x < 248 && y > 0 && y < 216) { + Render8x8Tile_Mask(pTransDraw, Code, x, y, Colour, 2, 0, 0, DrvChars); + } else { + Render8x8Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 2, 0, 0, DrvChars); + } + + TileIndex++; + } + } +} + +static void DrvDraw() +{ + BurnTransferClear(); + DrvCalcPalette(); + DrvRenderBgLayer(); + DrvRenderSpriteLayer(); + DrvRenderCharLayer(); + BurnTransferCopy(DrvPalette); +} + +static int DrvFrame() +{ + int nInterleave = 4; + int nSoundBufferPos = 0; + + if (DrvReset) DrvDoReset(); + + DrvMakeInputs(); + + nCyclesTotal[0] = 4000000 / 60; + nCyclesTotal[1] = 3000000 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run Z80 #1 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if (i == 1) ZetRaiseIrq(0xcf); + if (i == 3) ZetRaiseIrq(0xd7); + ZetClose(); + + // Run Z80 #2 + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesSegment = ZetRun(nCyclesSegment); + nCyclesDone[nCurrentCPU] += nCyclesSegment; + ZetRaiseIrq(0); + ZetClose(); + + // Render Sound Segment + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + nSoundBufferPos += nSegmentLength; + } + } + + // Make sure the buffer is entirely filled. + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) DrvDraw(); + + return 0; +} + +static int DrvScan(int nAction, int *pnMin) +{ + struct BurnArea ba; + + if (pnMin != NULL) { // Return minimum compatible version + *pnMin = 0x029672; + } + + if (nAction & ACB_MEMORY_RAM) { + memset(&ba, 0, sizeof(ba)); + ba.Data = RamStart; + ba.nLen = RamEnd-RamStart; + ba.szName = "All Ram"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + ZetScan(nAction); // Scan Z80 + AY8910Scan(nAction, pnMin); + + // Scan critical driver variables + SCAN_VAR(nCyclesDone); + SCAN_VAR(nCyclesSegment); + SCAN_VAR(DrvRomBank); + SCAN_VAR(DrvPaletteBank); + SCAN_VAR(DrvSoundLatch); + SCAN_VAR(DrvBgScroll); + SCAN_VAR(DrvFlipScreen); + SCAN_VAR(DrvDip); + SCAN_VAR(DrvInput); + } + + if (nAction & ACB_WRITE) { + ZetOpen(0); + ZetMapArea(0x8000, 0xbfff, 0, DrvZ80Rom1 + 0x10000 + DrvRomBank * 0x4000 ); + ZetMapArea(0x8000, 0xbfff, 2, DrvZ80Rom1 + 0x10000 + DrvRomBank * 0x4000 ); + ZetClose(); + } + + return 0; +} + +struct BurnDriver BurnDrvNineteen42 = { + "1942", NULL, NULL, "1984", + "1942 (Revision B)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, DrvRomInfo, DrvRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, NULL, DrvScan, + 0, NULL, NULL, NULL, NULL, 224, 256, 3, 4 +}; + +struct BurnDriver BurnDrvNineteen42a = { + "1942a", "1942", NULL, "1984", + "1942 (Revision A)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, DrvaRomInfo, DrvaRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, NULL, DrvScan, + 0, NULL, NULL, NULL, NULL, 224, 256, 3, 4 +}; + +struct BurnDriver BurnDrvNineteen42b = { + "1942b", "1942", NULL, "1984", + "1942 (First Version)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, DrvbRomInfo, DrvbRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, NULL, DrvScan, + 0, NULL, NULL, NULL, NULL, 224, 256, 3, 4 +}; + +struct BurnDriver BurnDrvNineteen42w = { + "1942w", "1942", NULL, "1985", + "1942 (Williams Electronics license)\0", NULL, "Capcom (Williams Electronics license)", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, DrvwRomInfo, DrvwRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, NULL, DrvScan, + 0, NULL, NULL, NULL, NULL, 224, 256, 3, 4 +}; diff --git a/src/burn/misc/pre90s/d_1943.cpp b/src/burn/misc/pre90s/d_1943.cpp new file mode 100644 index 0000000..abc78f9 --- /dev/null +++ b/src/burn/misc/pre90s/d_1943.cpp @@ -0,0 +1,1125 @@ +#include "tiles_generic.h" +#include "burn_ym2203.h" + +static unsigned char DrvInputPort0[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char DrvInputPort1[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char DrvInputPort2[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char DrvDip[2] = {0, 0}; +static unsigned char DrvInput[3] = {0x00, 0x00, 0x00}; +static unsigned char DrvReset = 0; + +static unsigned char *Mem = NULL; +static unsigned char *MemEnd = NULL; +static unsigned char *RamStart = NULL; +static unsigned char *RamEnd = NULL; +static unsigned char *DrvZ80Rom1 = NULL; +static unsigned char *DrvZ80Rom2 = NULL; +static unsigned char *DrvZ80Ram1 = NULL; +static unsigned char *DrvZ80Ram2 = NULL; +static unsigned char *DrvVideoRam = NULL; +static unsigned char *DrvPaletteRam = NULL; +static unsigned char *DrvSpriteRam = NULL; +static unsigned char *DrvPromRed = NULL; +static unsigned char *DrvPromGreen = NULL; +static unsigned char *DrvPromBlue = NULL; +static unsigned char *DrvPromCharLookup = NULL; +static unsigned char *DrvPromBg2Lookup = NULL; +static unsigned char *DrvPromBg2PalBank = NULL; +static unsigned char *DrvPromBgLookup = NULL; +static unsigned char *DrvPromBgPalBank = NULL; +static unsigned char *DrvPromSpriteLookup = NULL; +static unsigned char *DrvPromSpritePalBank = NULL; +static unsigned char *DrvBgTilemap = NULL; +static unsigned char *DrvBg2Tilemap = NULL; +static unsigned char *DrvChars = NULL; +static unsigned char *DrvBg2Tiles = NULL; +static unsigned char *DrvBgTiles = NULL; +static unsigned char *DrvSprites = NULL; +static unsigned char *DrvTempRom = NULL; +static unsigned int *DrvPalette = NULL; + +static unsigned char DrvSoundLatch; +static unsigned char DrvRomBank; +static unsigned char DrvBg2ScrollX[2]; +static unsigned char DrvBgScrollX[2]; +static unsigned char DrvBgScrollY; +static unsigned char DrvBg2On; +static unsigned char DrvBg1On; +static unsigned char DrvSpritesOn; +static unsigned char DrvCharsOn; + +static int nCyclesDone[2], nCyclesTotal[2]; +static int nCyclesSegment; + +static struct BurnInputInfo DrvInputList[] = +{ + {"Coin 1" , BIT_DIGITAL , DrvInputPort0 + 6, "p1 coin" }, + {"Start 1" , BIT_DIGITAL , DrvInputPort0 + 0, "p1 start" }, + {"Coin 2" , BIT_DIGITAL , DrvInputPort0 + 7, "p2 coin" }, + {"Start 2" , BIT_DIGITAL , DrvInputPort0 + 1, "p2 start" }, + + {"P1 Up" , BIT_DIGITAL , DrvInputPort1 + 3, "p1 up" }, + {"P1 Down" , BIT_DIGITAL , DrvInputPort1 + 2, "p1 down" }, + {"P1 Left" , BIT_DIGITAL , DrvInputPort1 + 1, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvInputPort1 + 0, "p1 right" }, + {"P1 Fire 1" , BIT_DIGITAL , DrvInputPort1 + 4, "p1 fire 1" }, + {"P1 Fire 2" , BIT_DIGITAL , DrvInputPort1 + 5, "p1 fire 2" }, + + {"P2 Up" , BIT_DIGITAL , DrvInputPort2 + 3, "p2 up" }, + {"P2 Down" , BIT_DIGITAL , DrvInputPort2 + 2, "p2 down" }, + {"P2 Left" , BIT_DIGITAL , DrvInputPort2 + 1, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvInputPort2 + 0, "p2 right" }, + {"Fire 1" , BIT_DIGITAL , DrvInputPort2 + 4, "p2 fire 1" }, + {"Fire 2" , BIT_DIGITAL , DrvInputPort2 + 5, "p2 fire 2" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDip + 0 , "dip" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDip + 1 , "dip" }, +}; + +STDINPUTINFO(Drv); + +static inline void DrvClearOpposites(unsigned char* nJoystickInputs) +{ + if ((*nJoystickInputs & 0x03) == 0x03) { + *nJoystickInputs &= ~0x03; + } + if ((*nJoystickInputs & 0x0c) == 0x0c) { + *nJoystickInputs &= ~0x0c; + } +} + +static inline void DrvMakeInputs() +{ + // Reset Inputs + DrvInput[0] = DrvInput[1] = DrvInput[2] = 0x00; + + // Compile Digital Inputs + for (int i = 0; i < 8; i++) { + DrvInput[0] |= (DrvInputPort0[i] & 1) << i; + DrvInput[1] |= (DrvInputPort1[i] & 1) << i; + DrvInput[2] |= (DrvInputPort2[i] & 1) << i; + } + + // Clear Opposites + DrvClearOpposites(&DrvInput[1]); + DrvClearOpposites(&DrvInput[2]); +} + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x11, 0xff, 0xff, 0xf8, NULL }, + {0x12, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 16 , "Difficulty" }, + {0x11, 0x01, 0x0f, 0x0f, "1 (Easy)" }, + {0x11, 0x01, 0x0f, 0x0e, "2" }, + {0x11, 0x01, 0x0f, 0x0d, "3" }, + {0x11, 0x01, 0x0f, 0x0c, "4" }, + {0x11, 0x01, 0x0f, 0x0b, "5" }, + {0x11, 0x01, 0x0f, 0x0a, "6" }, + {0x11, 0x01, 0x0f, 0x09, "7" }, + {0x11, 0x01, 0x0f, 0x08, "8 (Normal)" }, + {0x11, 0x01, 0x0f, 0x07, "9" }, + {0x11, 0x01, 0x0f, 0x06, "10" }, + {0x11, 0x01, 0x0f, 0x05, "11" }, + {0x11, 0x01, 0x0f, 0x04, "12" }, + {0x11, 0x01, 0x0f, 0x03, "13" }, + {0x11, 0x01, 0x0f, 0x02, "14" }, + {0x11, 0x01, 0x0f, 0x01, "15" }, + {0x11, 0x01, 0x0f, 0x00, "16 (Difficult)" }, + + {0 , 0xfe, 0 , 2 , "2 Player Game" }, + {0x11, 0x01, 0x10, 0x00, "1 Credit / 2 Players" }, + {0x11, 0x01, 0x10, 0x10, "2 Credits / 2 Players" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x11, 0x01, 0x20, 0x20, "Off" }, + {0x11, 0x01, 0x20, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x11, 0x01, 0x40, 0x40, "Off" }, + {0x11, 0x01, 0x40, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Service Mode" }, + {0x11, 0x01, 0x80, 0x80, "Off" }, + {0x11, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x12, 0x01, 0x07, 0x00, "4 Coins 1 Play" }, + {0x12, 0x01, 0x07, 0x01, "3 Coins 1 Play" }, + {0x12, 0x01, 0x07, 0x02, "2 Coins 1 Play" }, + {0x12, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x12, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x12, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x12, 0x01, 0x07, 0x04, "1 Coin 4 Plays" }, + {0x12, 0x01, 0x07, 0x03, "1 Coin 5 Plays" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x12, 0x01, 0x38, 0x00, "4 Coins 1 Play" }, + {0x12, 0x01, 0x38, 0x08, "3 Coins 1 Play" }, + {0x12, 0x01, 0x38, 0x10, "2 Coins 1 Play" }, + {0x12, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x12, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x12, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, + {0x12, 0x01, 0x38, 0x20, "1 Coin 4 Plays" }, + {0x12, 0x01, 0x38, 0x18, "1 Coin 5 Plays" }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x12, 0x01, 0x40, 0x00, "No" }, + {0x12, 0x01, 0x40, 0x40, "Yes" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x12, 0x01, 0x80, 0x00, "Off" }, + {0x12, 0x01, 0x80, 0x80, "On" }, +}; + +STDDIPINFO(Drv); + +static struct BurnRomInfo DrvRomDesc[] = { + { "1943.01", 0x08000, 0xc686cc5c, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "1943.02", 0x10000, 0xd8880a41, BRF_ESS | BRF_PRG }, // 1 + { "1943.03", 0x10000, 0x3f0ee26c, BRF_ESS | BRF_PRG }, // 2 + + { "1943.05", 0x08000, 0xee2bd2d7, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program + + { "1943.04", 0x08000, 0x46cb9d3d, BRF_GRA }, // 4 Characters + + { "1943.15", 0x08000, 0x6b1a0443, BRF_GRA }, // 5 BG Tiles + { "1943.16", 0x08000, 0x23c908c2, BRF_GRA }, // 6 + { "1943.17", 0x08000, 0x46bcdd07, BRF_GRA }, // 7 + { "1943.18", 0x08000, 0xe6ae7ba0, BRF_GRA }, // 8 + { "1943.19", 0x08000, 0x868ababc, BRF_GRA }, // 9 + { "1943.20", 0x08000, 0x0917e5d4, BRF_GRA }, // 10 + { "1943.21", 0x08000, 0x9bfb0d89, BRF_GRA }, // 11 + { "1943.22", 0x08000, 0x04f3c274, BRF_GRA }, // 12 + + { "1943.24", 0x08000, 0x11134036, BRF_GRA }, // 13 BG2 Tiles + { "1943.25", 0x08000, 0x092cf9c1, BRF_GRA }, // 14 + + { "1943.06", 0x08000, 0x97acc8af, BRF_GRA }, // 15 Sprites + { "1943.07", 0x08000, 0xd78f7197, BRF_GRA }, // 16 + { "1943.08", 0x08000, 0x1a626608, BRF_GRA }, // 17 + { "1943.09", 0x08000, 0x92408400, BRF_GRA }, // 18 + { "1943.10", 0x08000, 0x8438a44a, BRF_GRA }, // 19 + { "1943.11", 0x08000, 0x6c69351d, BRF_GRA }, // 20 + { "1943.12", 0x08000, 0x5e7efdb7, BRF_GRA }, // 21 + { "1943.13", 0x08000, 0x1143829a, BRF_GRA }, // 22 + + { "1943.14", 0x08000, 0x4d3c6401, BRF_GRA }, // 23 Tilemaps + { "1943.23", 0x08000, 0xa52aecbd, BRF_GRA }, // 24 + + { "bmprom.01", 0x00100, 0x74421f18, BRF_GRA }, // 25 PROMs + { "bmprom.02", 0x00100, 0xac27541f, BRF_GRA }, // 26 + { "bmprom.03", 0x00100, 0x251fb6ff, BRF_GRA }, // 27 + { "bmprom.05", 0x00100, 0x206713d0, BRF_GRA }, // 28 + { "bmprom.10", 0x00100, 0x33c2491c, BRF_GRA }, // 29 + { "bmprom.09", 0x00100, 0xaeea4af7, BRF_GRA }, // 30 + { "bmprom.12", 0x00100, 0xc18aa136, BRF_GRA }, // 31 + { "bmprom.11", 0x00100, 0x405aae37, BRF_GRA }, // 32 + { "bmprom.08", 0x00100, 0xc2010a9e, BRF_GRA }, // 33 + { "bmprom.07", 0x00100, 0xb56f30c3, BRF_GRA }, // 34 + { "bmprom.04", 0x00100, 0x91a8a2e1, BRF_GRA }, // 35 + { "bmprom.06", 0x00100, 0x0eaf5158, BRF_GRA }, // 36 +}; + +STD_ROM_PICK(Drv); +STD_ROM_FN(Drv); + +static struct BurnRomInfo DrvjRomDesc[] = { + { "1943jap.001", 0x08000, 0xf6935937, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "1943jap.002", 0x10000, 0xaf971575, BRF_ESS | BRF_PRG }, // 1 + { "1943jap.003", 0x10000, 0x300ec713, BRF_ESS | BRF_PRG }, // 2 + + { "1943.05", 0x08000, 0xee2bd2d7, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program + + { "1943.04", 0x08000, 0x46cb9d3d, BRF_GRA }, // 4 Characters + + { "1943.15", 0x08000, 0x6b1a0443, BRF_GRA }, // 5 BG Tiles + { "1943.16", 0x08000, 0x23c908c2, BRF_GRA }, // 6 + { "1943.17", 0x08000, 0x46bcdd07, BRF_GRA }, // 7 + { "1943.18", 0x08000, 0xe6ae7ba0, BRF_GRA }, // 8 + { "1943.19", 0x08000, 0x868ababc, BRF_GRA }, // 9 + { "1943.20", 0x08000, 0x0917e5d4, BRF_GRA }, // 10 + { "1943.21", 0x08000, 0x9bfb0d89, BRF_GRA }, // 11 + { "1943.22", 0x08000, 0x04f3c274, BRF_GRA }, // 12 + + { "1943.24", 0x08000, 0x11134036, BRF_GRA }, // 13 BG2 Tiles + { "1943.25", 0x08000, 0x092cf9c1, BRF_GRA }, // 14 + + { "1943.06", 0x08000, 0x97acc8af, BRF_GRA }, // 15 Sprites + { "1943.07", 0x08000, 0xd78f7197, BRF_GRA }, // 16 + { "1943.08", 0x08000, 0x1a626608, BRF_GRA }, // 17 + { "1943.09", 0x08000, 0x92408400, BRF_GRA }, // 18 + { "1943.10", 0x08000, 0x8438a44a, BRF_GRA }, // 19 + { "1943.11", 0x08000, 0x6c69351d, BRF_GRA }, // 20 + { "1943.12", 0x08000, 0x5e7efdb7, BRF_GRA }, // 21 + { "1943.13", 0x08000, 0x1143829a, BRF_GRA }, // 22 + + { "1943.14", 0x08000, 0x4d3c6401, BRF_GRA }, // 23 Tilemaps + { "1943.23", 0x08000, 0xa52aecbd, BRF_GRA }, // 24 + + { "bmprom.01", 0x00100, 0x74421f18, BRF_GRA }, // 25 PROMs + { "bmprom.02", 0x00100, 0xac27541f, BRF_GRA }, // 26 + { "bmprom.03", 0x00100, 0x251fb6ff, BRF_GRA }, // 27 + { "bmprom.05", 0x00100, 0x206713d0, BRF_GRA }, // 28 + { "bmprom.10", 0x00100, 0x33c2491c, BRF_GRA }, // 29 + { "bmprom.09", 0x00100, 0xaeea4af7, BRF_GRA }, // 30 + { "bmprom.12", 0x00100, 0xc18aa136, BRF_GRA }, // 31 + { "bmprom.11", 0x00100, 0x405aae37, BRF_GRA }, // 32 + { "bmprom.08", 0x00100, 0xc2010a9e, BRF_GRA }, // 33 + { "bmprom.07", 0x00100, 0xb56f30c3, BRF_GRA }, // 34 + { "bmprom.04", 0x00100, 0x91a8a2e1, BRF_GRA }, // 35 + { "bmprom.06", 0x00100, 0x0eaf5158, BRF_GRA }, // 36 +}; + +STD_ROM_PICK(Drvj); +STD_ROM_FN(Drvj); + +static struct BurnRomInfo DrvkaiRomDesc[] = { + { "1943kai.01", 0x08000, 0x7d2211db, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "1943kai.02", 0x10000, 0x2ebbc8c5, BRF_ESS | BRF_PRG }, // 1 + { "1943kai.03", 0x10000, 0x475a6ac5, BRF_ESS | BRF_PRG }, // 2 + + { "1943kai.05", 0x08000, 0x25f37957, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program + + { "1943kai.04", 0x08000, 0x884a8692, BRF_GRA }, // 4 Characters + + { "1943kai.15", 0x08000, 0x6b1a0443, BRF_GRA }, // 5 BG Tiles + { "1943kai.16", 0x08000, 0x9416fe0d, BRF_GRA }, // 6 + { "1943kai.17", 0x08000, 0x3d5acab9, BRF_GRA }, // 7 + { "1943kai.18", 0x08000, 0x7b62da1d, BRF_GRA }, // 8 + { "1943kai.19", 0x08000, 0x868ababc, BRF_GRA }, // 9 + { "1943kai.20", 0x08000, 0xb90364c1, BRF_GRA }, // 10 + { "1943kai.21", 0x08000, 0x8c7fe74a, BRF_GRA }, // 11 + { "1943kai.22", 0x08000, 0xd5ef8a0e, BRF_GRA }, // 12 + + { "1943kai.24", 0x08000, 0xbf186ef2, BRF_GRA }, // 13 BG2 Tiles + { "1943kai.25", 0x08000, 0xa755faf1, BRF_GRA }, // 14 + + { "1943kai.06", 0x08000, 0x5f7e38b3, BRF_GRA }, // 15 Sprites + { "1943kai.07", 0x08000, 0xff3751fd, BRF_GRA }, // 16 + { "1943kai.08", 0x08000, 0x159d51bd, BRF_GRA }, // 17 + { "1943kai.09", 0x08000, 0x8683e3d2, BRF_GRA }, // 18 + { "1943kai.10", 0x08000, 0x1e0d9571, BRF_GRA }, // 19 + { "1943kai.11", 0x08000, 0xf1fc5ee1, BRF_GRA }, // 20 + { "1943kai.12", 0x08000, 0x0f50c001, BRF_GRA }, // 21 + { "1943kai.13", 0x08000, 0xfd1acf8e, BRF_GRA }, // 22 + + { "1943kai.14", 0x08000, 0xcf0f5a53, BRF_GRA }, // 23 Tilemaps + { "1943kai.23", 0x08000, 0x17f77ef9, BRF_GRA }, // 24 + + { "bmk01.bin", 0x00100, 0xe001ea33, BRF_GRA }, // 25 PROMs + { "bmk02.bin", 0x00100, 0xaf34d91a, BRF_GRA }, // 26 + { "bmk03.bin", 0x00100, 0x43e9f6ef, BRF_GRA }, // 27 + { "bmk05.bin", 0x00100, 0x41878934, BRF_GRA }, // 28 + { "bmk10.bin", 0x00100, 0xde44b748, BRF_GRA }, // 29 + { "bmk09.bin", 0x00100, 0x59ea57c0, BRF_GRA }, // 30 + { "bmk12.bin", 0x00100, 0x8765f8b0, BRF_GRA }, // 31 + { "bmk11.bin", 0x00100, 0x87a8854e, BRF_GRA }, // 32 + { "bmk08.bin", 0x00100, 0xdad17e2d, BRF_GRA }, // 33 + { "bmk07.bin", 0x00100, 0x76307f8d, BRF_GRA }, // 34 + { "bmprom.04", 0x00100, 0x91a8a2e1, BRF_GRA }, // 35 + { "bmprom.06", 0x00100, 0x0eaf5158, BRF_GRA }, // 36 +}; + +STD_ROM_PICK(Drvkai); +STD_ROM_FN(Drvkai); + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + DrvZ80Rom1 = Next; Next += 0x30000; + DrvZ80Rom2 = Next; Next += 0x08000; + DrvPromRed = Next; Next += 0x00100; + DrvPromGreen = Next; Next += 0x00100; + DrvPromBlue = Next; Next += 0x00100; + DrvPromCharLookup = Next; Next += 0x00100; + DrvPromBg2Lookup = Next; Next += 0x00100; + DrvPromBg2PalBank = Next; Next += 0x00100; + DrvPromBgLookup = Next; Next += 0x00100; + DrvPromBgPalBank = Next; Next += 0x00100; + DrvPromSpriteLookup = Next; Next += 0x00100; + DrvPromSpritePalBank = Next; Next += 0x00100; + DrvBgTilemap = Next; Next += 0x08000; + DrvBg2Tilemap = Next; Next += 0x08000; + + RamStart = Next; + + DrvZ80Ram1 = Next; Next += 0x01000; + DrvZ80Ram2 = Next; Next += 0x00800; + DrvVideoRam = Next; Next += 0x00400; + DrvPaletteRam = Next; Next += 0x00400; + DrvSpriteRam = Next; Next += 0x01000; + + RamEnd = Next; + + DrvChars = Next; Next += 2048 * 8 * 8; + DrvBg2Tiles = Next; Next += 128 * 32 * 32; + DrvBgTiles = Next; Next += 512 * 32 * 32; + DrvSprites = Next; Next += 2048 * 16 * 16; + DrvPalette = (unsigned int*)Next; Next += 0x00380 * sizeof(unsigned int); + + MemEnd = Next; + + return 0; +} + +static int DrvDoReset() +{ + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + } + + BurnYM2203Reset(); + + DrvRomBank = 0; + DrvSoundLatch = 0; + DrvBg2ScrollX[0] = 0; + DrvBg2ScrollX[1] = 0; + DrvBgScrollX[0] = 0; + DrvBgScrollX[1] = 0; + DrvBgScrollY = 0; + DrvBg2On = 0; + DrvBg1On = 0; + DrvSpritesOn = 0; + DrvCharsOn = 0; + + return 0; +} + +unsigned char __fastcall Drv1943Read1(unsigned short a) +{ + switch (a) { + case 0xc000: { + return 0xff - DrvInput[0]; + } + + case 0xc001: { + return 0xff - DrvInput[1]; + } + + case 0xc002: { + return 0xff - DrvInput[2]; + } + + case 0xc003: { + return DrvDip[0]; + } + + case 0xc004: { + return DrvDip[1]; + } + + case 0xc007: { + return ZetBc(-1) >> 8; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Read => %04X\n"), a); + } + } + + return 0; +} + +void __fastcall Drv1943Write1(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xc800: { + DrvSoundLatch = d; + return; + } + + case 0xc804: { + DrvRomBank = d & 0x1c; + ZetMapArea(0x8000, 0xbfff, 0, DrvZ80Rom1 + 0x10000 + DrvRomBank * 0x1000 ); + ZetMapArea(0x8000, 0xbfff, 2, DrvZ80Rom1 + 0x10000 + DrvRomBank * 0x1000 ); + + if (d & 0x40) bprintf(PRINT_NORMAL, _T("c804 write %x\n"), d); + + DrvCharsOn = d & 0x80; + return; + } + + case 0xc806: { + // Watchdog + return; + } + + case 0xc807: { + // NOP + return; + } + + case 0xd800: { + DrvBgScrollX[0] = d; + return; + } + + case 0xd801: { + DrvBgScrollX[1] = d; + return; + } + + case 0xd802: { + DrvBgScrollY = d; + if (d) bprintf(PRINT_IMPORTANT, _T("BG Scroll Y => %02X\n"), d); + return; + } + + case 0xd803: { + DrvBg2ScrollX[0] = d; + return; + } + + case 0xd804: { + DrvBg2ScrollX[1] = d; + return; + } + + case 0xd806: { + DrvBg1On = d & 0x10; + DrvBg2On = d & 0x20; + DrvSpritesOn = d & 0x40; + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Write => %04X, %02X\n"), a, d); + } + } +} + +unsigned char __fastcall Drv1943PortRead1(unsigned short a) +{ + a &= 0xff; + + switch (a) { + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Port Read => %02X\n"), a); + } + } + + return 0; +} + +void __fastcall Drv1943PortWrite1(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Port Write => %02X, %02X\n"), a, d); + } + } +} + +unsigned char __fastcall Drv1943Read2(unsigned short a) +{ + switch (a) { + case 0xc800: { + return DrvSoundLatch; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Read => %04X\n"), a); + } + } + + return 0; +} + +void __fastcall Drv1943Write2(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xe000: { + BurnYM2203Write(0, 0, d); + return; + } + + case 0xe001: { + BurnYM2203Write(0, 1, d); + return; + } + + case 0xe002: { + BurnYM2203Write(1, 0, d); + return; + } + + case 0xe003: { + BurnYM2203Write(1, 1, d); + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Write => %04X, %02X\n"), a, d); + } + } +} + +unsigned char __fastcall Drv1943PortRead2(unsigned short a) +{ + a &= 0xff; + + switch (a) { + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Port Read => %02X\n"), a); + } + } + + return 0; +} + +void __fastcall Drv1943PortWrite2(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Port Write => %02X, %02X\n"), a, d); + } + } +} + +static int CharPlaneOffsets[2] = { 4, 0 }; +static int CharXOffsets[8] = { 0, 1, 2, 3, 8, 9, 10, 11 }; +static int CharYOffsets[8] = { 0, 16, 32, 48, 64, 80, 96, 112 }; +static int Bg2TilePlaneOffsets[4] = { 0x40004, 0x40000, 4, 0 }; +static int BgTilePlaneOffsets[4] = { 0x100004, 0x100000, 4, 0 }; +static int TileXOffsets[32] = { 0, 1, 2, 3, 8, 9, 10, 11, 512, 513, 514, 515, 520, 521, 522, 523, 1024, 1025, 1026, 1027, 1032, 1033, 1034, 1035, 1536, 1537, 1538, 1539, 1544, 1545, 1546, 1547 }; +static int TileYOffsets[32] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448, 464, 480, 496 }; +static int SpritePlaneOffsets[4] = { 0x100004, 0x100000, 4, 0 }; +static int SpriteXOffsets[16] = { 0, 1, 2, 3, 8, 9, 10, 11, 256, 257, 258, 259, 264, 265, 266, 267 }; +static int SpriteYOffsets[16] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240 }; + +inline static int DrvSynchroniseStream(int nSoundRate) +{ + return (long long)(ZetTotalCycles() * nSoundRate / 3000000); +} + +inline static double DrvGetTime() +{ + return (double)ZetTotalCycles() / 3000000; +} + +static int DrvInit() +{ + int nRet = 0, nLen; + + // Allocate and Blank all required memory + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + DrvTempRom = (unsigned char *)malloc(0x40000); + + // Load Z80 #1 Program Roms + nRet = BurnLoadRom(DrvZ80Rom1 + 0x00000, 0, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvZ80Rom1 + 0x10000, 1, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvZ80Rom1 + 0x20000, 2, 1); if (nRet != 0) return 1; + + // Load Z80 #2 Program Roms + nRet = BurnLoadRom(DrvZ80Rom2 + 0x00000, 3, 1); if (nRet != 0) return 1; + + // Load and decode the chars + nRet = BurnLoadRom(DrvTempRom, 4, 1); if (nRet != 0) return 1; + GfxDecode(2048, 2, 8, 8, CharPlaneOffsets, CharXOffsets, CharYOffsets, 0x80, DrvTempRom, DrvChars); + + // Load and decode the bg2 tiles + memset(DrvTempRom, 0, 0x40000); + nRet = BurnLoadRom(DrvTempRom + 0x00000, 13, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x08000, 14, 1); if (nRet != 0) return 1; + GfxDecode(128, 4, 32, 32, Bg2TilePlaneOffsets, TileXOffsets, TileYOffsets, 0x800, DrvTempRom, DrvBg2Tiles); + + // Load and decode the bg tiles + memset(DrvTempRom, 0, 0x40000); + nRet = BurnLoadRom(DrvTempRom + 0x00000, 5, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x08000, 6, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x10000, 7, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x18000, 8, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x20000, 9, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x28000, 10, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x30000, 11, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x38000, 12, 1); if (nRet != 0) return 1; + GfxDecode(512, 4, 32, 32, BgTilePlaneOffsets, TileXOffsets, TileYOffsets, 0x800, DrvTempRom, DrvBgTiles); + + // Load and decode the sprites + memset(DrvTempRom, 0, 0x40000); + nRet = BurnLoadRom(DrvTempRom + 0x00000, 15, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x08000, 16, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x10000, 17, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x18000, 18, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x20000, 19, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x28000, 20, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x30000, 21, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x38000, 22, 1); if (nRet != 0) return 1; + GfxDecode(2048, 4, 16, 16, SpritePlaneOffsets, SpriteXOffsets, SpriteYOffsets, 0x200, DrvTempRom, DrvSprites); + + // Load the Tilemaps + nRet = BurnLoadRom(DrvBgTilemap, 23, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvBg2Tilemap, 24, 1); if (nRet != 0) return 1; + + // Load the PROMs + nRet = BurnLoadRom(DrvPromRed, 25, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromGreen, 26, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromBlue, 27, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromCharLookup, 28, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromBgLookup, 29, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromBgPalBank, 30, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromBg2Lookup, 31, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromBg2PalBank, 32, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromSpriteLookup, 33, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvPromSpritePalBank, 34, 1); if (nRet != 0) return 1; + + free(DrvTempRom); + + // Setup the Z80 emulation + ZetInit(2); + ZetOpen(0); + ZetSetReadHandler(Drv1943Read1); + ZetSetWriteHandler(Drv1943Write1); + ZetSetInHandler(Drv1943PortRead1); + ZetSetOutHandler(Drv1943PortWrite1); + ZetMapArea(0x0000, 0x7fff, 0, DrvZ80Rom1 ); + ZetMapArea(0x0000, 0x7fff, 2, DrvZ80Rom1 ); + ZetMapArea(0x8000, 0xbfff, 0, DrvZ80Rom1 + 0x10000 ); + ZetMapArea(0x8000, 0xbfff, 2, DrvZ80Rom1 + 0x10000 ); + ZetMapArea(0xd000, 0xd3ff, 0, DrvVideoRam ); + ZetMapArea(0xd000, 0xd3ff, 1, DrvVideoRam ); + ZetMapArea(0xd000, 0xd3ff, 2, DrvVideoRam ); + ZetMapArea(0xd400, 0xd7ff, 0, DrvPaletteRam ); + ZetMapArea(0xd400, 0xd7ff, 1, DrvPaletteRam ); + ZetMapArea(0xd400, 0xd7ff, 2, DrvPaletteRam ); + ZetMapArea(0xe000, 0xefff, 0, DrvZ80Ram1 ); + ZetMapArea(0xe000, 0xefff, 1, DrvZ80Ram1 ); + ZetMapArea(0xe000, 0xefff, 2, DrvZ80Ram1 ); + ZetMapArea(0xf000, 0xffff, 0, DrvSpriteRam ); + ZetMapArea(0xf000, 0xffff, 1, DrvSpriteRam ); + ZetMapArea(0xf000, 0xffff, 2, DrvSpriteRam ); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetSetReadHandler(Drv1943Read2); + ZetSetWriteHandler(Drv1943Write2); + ZetSetInHandler(Drv1943PortRead2); + ZetSetOutHandler(Drv1943PortWrite2); + ZetMapArea(0x0000, 0x7fff, 0, DrvZ80Rom2 ); + ZetMapArea(0x0000, 0x7fff, 2, DrvZ80Rom2 ); + ZetMapArea(0xc000, 0xc7ff, 0, DrvZ80Ram2 ); + ZetMapArea(0xc000, 0xc7ff, 1, DrvZ80Ram2 ); + ZetMapArea(0xc000, 0xc7ff, 2, DrvZ80Ram2 ); + ZetMemEnd(); + ZetClose(); + + BurnYM2203Init(2, 1500000, NULL, DrvSynchroniseStream, DrvGetTime, 0); + BurnTimerAttachZet(3000000); + + GenericTilesInit(); + + // Reset the driver + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + BurnYM2203Exit(); + + GenericTilesExit(); + + DrvRomBank = 0; + DrvSoundLatch = 0; + DrvBg2ScrollX[0] = 0; + DrvBg2ScrollX[1] = 0; + DrvBgScrollX[0] = 0; + DrvBgScrollX[1] = 0; + DrvBgScrollY = 0; + DrvBg2On = 0; + DrvBg1On = 0; + DrvSpritesOn = 0; + DrvCharsOn = 0; + + free(Mem); + Mem = NULL; + + return 0; +} + +static void DrvCalcPalette() +{ + int i; + unsigned int Palette[256]; + + for (i = 0; i < 256; i++) { + int bit0, bit1, bit2, bit3, r, g, b; + + bit0 = (DrvPromRed[i] >> 0) & 0x01; + bit1 = (DrvPromRed[i] >> 1) & 0x01; + bit2 = (DrvPromRed[i] >> 2) & 0x01; + bit3 = (DrvPromRed[i] >> 3) & 0x01; + r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (DrvPromGreen[i] >> 0) & 0x01; + bit1 = (DrvPromGreen[i] >> 1) & 0x01; + bit2 = (DrvPromGreen[i] >> 2) & 0x01; + bit3 = (DrvPromGreen[i] >> 3) & 0x01; + g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (DrvPromBlue[i] >> 0) & 0x01; + bit1 = (DrvPromBlue[i] >> 1) & 0x01; + bit2 = (DrvPromBlue[i] >> 2) & 0x01; + bit3 = (DrvPromBlue[i] >> 3) & 0x01; + b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + Palette[i] = BurnHighCol(r, g, b, 0); + } + + for (i = 0; i < 0x80; i++) { + DrvPalette[i] = Palette[(DrvPromCharLookup[i] & 0x0f) | 0x40]; + } + + for (i = 0x80; i < 0x180; i++) { + DrvPalette[i] = Palette[((DrvPromBgPalBank[i - 0x80] & 0x03) << 4) | (DrvPromBgLookup[i - 0x80] & 0x0f)]; + } + + for (i = 0x180; i < 0x280; i++) { + DrvPalette[i] = Palette[((DrvPromBg2PalBank[i - 0x180] & 0x03) << 4) | (DrvPromBg2Lookup[i - 0x180] & 0x0f)]; + } + + for (i = 0x280; i < 0x380; i++) { + DrvPalette[i] = Palette[((DrvPromSpritePalBank[i - 0x280] & 0x07) << 4) | (DrvPromSpriteLookup[i - 0x280] & 0x0f) | 0x80]; + } +} + +static void DrvRenderBg2Layer() +{ + int mx, my, Offs, Attr, Code, Colour, x, y, TileIndex, xScroll, Flip, xFlip, yFlip; + + xFlip = 0; + yFlip = 0; + + xScroll = DrvBg2ScrollX[0] + (256 * DrvBg2ScrollX[1]); + + for (mx = 0; mx < 8; mx++) { + for (my = 0; my < 2048; my++) { + TileIndex = (my * 8) + mx; + + Offs = TileIndex * 2; + Attr = DrvBg2Tilemap[Offs + 1]; + Code = DrvBg2Tilemap[Offs]; + Colour = (Attr & 0x3c) >> 2; + Flip = (Attr & 0xc0) >> 6; + xFlip = (Flip >> 0) & 0x01; + yFlip = (Flip >> 1) & 0x01; + + y = 32 * mx; + x = 32 * my; + + x -= xScroll; + y -= 16; + + if (x < -32) x += 65536; + + if (x < -32 || x > 256) continue; + if (y < -32 || y > 240) continue; + + if (x > 0 && x < 224 && y > 0 && y < 192) { + if (xFlip) { + if (yFlip) { + Render32x32Tile_FlipXY(pTransDraw, Code, x, y, Colour, 4, 384, DrvBg2Tiles); + } else { + Render32x32Tile_FlipX(pTransDraw, Code, x, y, Colour, 4, 384, DrvBg2Tiles); + } + } else { + if (yFlip) { + Render32x32Tile_FlipY(pTransDraw, Code, x, y, Colour, 4, 384, DrvBg2Tiles); + } else { + Render32x32Tile(pTransDraw, Code, x, y, Colour, 4, 384, DrvBg2Tiles); + } + } + } else { + if (xFlip) { + if (yFlip) { + Render32x32Tile_FlipXY_Clip(pTransDraw, Code, x, y, Colour, 4, 384, DrvBg2Tiles); + } else { + Render32x32Tile_FlipX_Clip(pTransDraw, Code, x, y, Colour, 4, 384, DrvBg2Tiles); + } + } else { + if (yFlip) { + Render32x32Tile_FlipY_Clip(pTransDraw, Code, x, y, Colour, 4, 384, DrvBg2Tiles); + } else { + Render32x32Tile_Clip(pTransDraw, Code, x, y, Colour, 4, 384, DrvBg2Tiles); + } + } + } + } + } +} + +static void DrvRenderBgLayer() +{ + int mx, my, Offs, Attr, Code, Colour, x, y, TileIndex, xScroll, Flip, xFlip, yFlip; + + xFlip = 0; + yFlip = 0; + + xScroll = DrvBgScrollX[0] + (256 * DrvBgScrollX[1]); + + for (mx = 0; mx < 8; mx++) { + for (my = 0; my < 2048; my++) { + TileIndex = (my * 8) + mx; + + Offs = TileIndex * 2; + Attr = DrvBgTilemap[Offs + 1]; + Code = DrvBgTilemap[Offs] + ((Attr & 0x01) << 8); + Colour = (Attr & 0x3c) >> 2; + Flip = (Attr & 0xc0) >> 6; + xFlip = (Flip >> 0) & 0x01; + yFlip = (Flip >> 1) & 0x01; + + y = 32 * mx; + x = 32 * my; + + x -= xScroll; + y -= 16; + + if (x < -32) x += 65536; + + if (x < -32 || x > 256) continue; + if (y < -32 || y > 240) continue; + + if (x > 0 && x < 224 && y > 0 && y < 192) { + if (xFlip) { + if (yFlip) { + Render32x32Tile_Mask_FlipXY(pTransDraw, Code, x, y, Colour, 4, 0, 128, DrvBgTiles); + } else { + Render32x32Tile_Mask_FlipX(pTransDraw, Code, x, y, Colour, 4, 0, 128, DrvBgTiles); + } + } else { + if (yFlip) { + Render32x32Tile_Mask_FlipY(pTransDraw, Code, x, y, Colour, 4, 0, 128, DrvBgTiles); + } else { + Render32x32Tile_Mask(pTransDraw, Code, x, y, Colour, 4, 0, 128, DrvBgTiles); + } + } + } else { + if (xFlip) { + if (yFlip) { + Render32x32Tile_Mask_FlipXY_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 128, DrvBgTiles); + } else { + Render32x32Tile_Mask_FlipX_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 128, DrvBgTiles); + } + } else { + if (yFlip) { + Render32x32Tile_Mask_FlipY_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 128, DrvBgTiles); + } else { + Render32x32Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 128, DrvBgTiles); + } + } + } + } + } +} + +static void DrvRenderSprites(int Priority) +{ + int Offs; + + for (Offs = 0x1000 - 32; Offs >= 0; Offs -= 32) { + int Attr = DrvSpriteRam[Offs + 1]; + int Code = DrvSpriteRam[Offs + 0] + ((Attr & 0xe0) << 3); + int Colour = Attr & 0x0f; + int sx = DrvSpriteRam[Offs + 3] - ((Attr & 0x10) << 4); + int sy = DrvSpriteRam[Offs + 2]; + + sy -= 16; + + if (Priority) { + if (Colour != 0x0a && Colour != 0x0b) { + if (sx > 0 && sx < 240 && sy > 0 && sy < 208) { + Render16x16Tile_Mask(pTransDraw, Code, sx, sy, Colour, 4, 0, 640, DrvSprites); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 640, DrvSprites); + } + } + } else { + if (Colour == 0x0a || Colour == 0x0b) { + if (sx > 0 && sx < 240 && sy > 0 && sy < 208) { + Render16x16Tile_Mask(pTransDraw, Code, sx, sy, Colour, 4, 0, 640, DrvSprites); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 640, DrvSprites); + } + } + + } + } +} + +static void DrvRenderCharLayer() +{ + int mx, my, Attr, Code, Colour, x, y, TileIndex = 0; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 32; mx++) { + Attr = DrvPaletteRam[TileIndex]; + Code = DrvVideoRam[TileIndex] + ((Attr & 0xe0) << 3); + Colour = Attr & 0x1f; + + x = 8 * mx; + y = 8 * my; + + y -= 16; + + if (x > 0 && x < 248 && y > 0 && y < 216) { + Render8x8Tile_Mask(pTransDraw, Code, x, y, Colour, 2, 0, 0, DrvChars); + } else { + Render8x8Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 2, 0, 0, DrvChars); + } + + TileIndex++; + } + } +} + +static void DrvDraw() +{ + BurnTransferClear(); + DrvCalcPalette(); + if (DrvBg2On) DrvRenderBg2Layer(); + if (DrvSpritesOn) DrvRenderSprites(0); + if (DrvBg1On) DrvRenderBgLayer(); + if (DrvSpritesOn) DrvRenderSprites(1); + if (DrvCharsOn) DrvRenderCharLayer(); + BurnTransferCopy(DrvPalette); +} + +static int DrvFrame() +{ + int nInterleave = 25; + int nSoundBufferPos = 0; + + if (DrvReset) DrvDoReset(); + + DrvMakeInputs(); + + nCyclesTotal[0] = 6000000 / 60; + nCyclesTotal[1] = 3000000 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + ZetNewFrame(); + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run Z80 #1 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if (i == 24) ZetRaiseIrq(0); + ZetClose(); + + // Run Z80 #2 + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesSegment = ZetRun(nCyclesSegment); + nCyclesDone[nCurrentCPU] += nCyclesSegment; + if (i == 5 || i == 10 || i == 15 || i == 20) ZetRaiseIrq(0); + ZetClose(); + + // Render Sound Segment + if (pBurnSoundOut) { + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + ZetOpen(1); + BurnYM2203Update(pSoundBuf, nSegmentLength); + ZetClose(); + nSoundBufferPos += nSegmentLength; + } + } + + // Make sure the buffer is entirely filled. + if (pBurnSoundOut) { + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + ZetOpen(1); + BurnYM2203Update(pSoundBuf, nSegmentLength); + ZetClose(); + } + } + + ZetOpen(1); + BurnTimerEndFrame(nCyclesTotal[1] - nCyclesDone[1]); + ZetClose(); + + if (pBurnDraw) DrvDraw(); + + return 0; +} + +static int DrvScan(int nAction, int *pnMin) +{ + struct BurnArea ba; + + if (pnMin != NULL) { // Return minimum compatible version + *pnMin = 0x029672; + } + + if (nAction & ACB_MEMORY_RAM) { + memset(&ba, 0, sizeof(ba)); + ba.Data = RamStart; + ba.nLen = RamEnd-RamStart; + ba.szName = "All Ram"; + BurnAcb(&ba); + } + + return 0; +} + +struct BurnDriverD BurnDrvNineteen43 = { + "1943", NULL, NULL, "1987", + "1943: The Battle of Midway (US)\0", "Bad Graphics", "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, DrvRomInfo, DrvRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, NULL, DrvScan, + 0, NULL, NULL, NULL, NULL, 224, 256, 3, 4 +}; + +struct BurnDriverD BurnDrvNineteen43j = { + "1943j", "1943", NULL, "1987", + "1943: Midway Kaisen (Japan)\0", "Bad Graphics", "Capcom", "Miscellaneous", + L"1943: \u30DF\u30C3\u30C9\u30A6\u30A7\u30A4\u6D77\u6226 (Japan)\0", NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, DrvjRomInfo, DrvjRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, NULL, DrvScan, + 0, NULL, NULL, NULL, NULL, 224, 256, 3, 4 +}; + +struct BurnDriverD BurnDrvNineteen43kai = { + "1943kai", NULL, NULL, "1987", + "1943 Kai: Midway Kaisen (Japan)\0", "Bad Graphics", "Capcom", "Miscellaneous", + L"1943 \u6539: \u30DF\u30C3\u30C9\u30A6\u30A7\u30A4\u6D77\u6226 (Japan)\0", NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, DrvkaiRomInfo, DrvkaiRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, NULL, DrvScan, + 0, NULL, NULL, NULL, NULL, 224, 256, 3, 4 +}; diff --git a/src/burn/misc/pre90s/d_4enraya.cpp b/src/burn/misc/pre90s/d_4enraya.cpp new file mode 100644 index 0000000..daa36b8 --- /dev/null +++ b/src/burn/misc/pre90s/d_4enraya.cpp @@ -0,0 +1,419 @@ +/*************************************************************************** + +Based on MAME driver by Tomasz Slanina dox@space.pl + +*************************************************************************** + +RAM : + 1 x GM76c28-10 (6116) RAM + 3 x 2114 - VRAM (only 10 bits are used ) + +ROM: + 27256 + 27128 for code/data + 3x2764 for gfx + +PROM: + 82S123 32x8 + Used for system control + (d0 - connected to ROM5 /CS , d1 - ROM4 /CS, d2 - RAM /CS , d3 - to some logic(gfx control), and Z80 WAIT ) + +Memory Map : + 0x0000 - 0xbfff - ROM + 0xc000 - 0xcfff - RAM + 0xd000 - 0xdfff - VRAM mirrored write, + tilemap offset = address & 0x3ff + tile number = bits 0-7 = data, bits 8,9 = address bits 10,11 + +Video : + No scrolling , no sprites. + 32x32 Tilemap stored in VRAM (10 bits/tile (tile numebr 0-1023)) + + 3 gfx ROMS + ROM1 - R component (ROM ->(parallel in) shift register 74166 (serial out) -> jamma output + ROM2 - B component + ROM3 - G component + + Default MAME color palette is used + +Sound : + AY 3 8910 + + sound_control : + + bit 0 - BC1 + bit 1 - BC2 + bit 2 - BDIR + + bits 3-7 - not connected + +***************************************************************************/ + +#include "burnint.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +static unsigned char *Mem, *Rom, *Gfx; +static unsigned char DrvJoy1[6], DrvJoy2[6], DrvReset, DrvDips; +static short *pAY8910Buffer[3], *pFMBuffer = NULL; +static unsigned int Palette[8]; +static unsigned char soundlatch; + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 0, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy1 + 1, "p1 start" }, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 2, "p1 down", }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 3, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 4, "p1 right" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 5, "p1 fire 1"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy2 + 0, "p2 coin" }, + {"P2 start" , BIT_DIGITAL , DrvJoy2 + 1, "p2 start" }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 2, "p2 down", }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 3, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 4, "p2 right" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 5, "p2 fire 1"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, &DrvDips, "dip" }, +}; + +STDINPUTINFO(Drv); + + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x0d, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0d, 0x01, 0x01, 0x01, "Easy" }, + {0x0d, 0x01, 0x01, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x0d, 0x01, 0x02, 0x02, "Off" }, + {0x0d, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Pieces" }, + {0x0d, 0x01, 0x04, 0x04, "30" }, + {0x0d, 0x01, 0x04, 0x00, "16" }, + + {0 , 0xfe, 0 , 2 , "Speed" }, + {0x0d, 0x01, 0x08, 0x08, "Slow" }, + {0x0d, 0x01, 0x08, 0x00, "Fast" }, + + {0 , 0xfe, 0 , 4 , "Coin B" }, + {0x0d, 0x01, 0x30, 0x30, "1C 1C" }, + {0x0d, 0x01, 0x30, 0x00, "2C 3C" }, + {0x0d, 0x01, 0x30, 0x10, "1C 3C" }, + {0x0d, 0x01, 0x30, 0x20, "1C 4C" }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x0d, 0x01, 0xc0, 0x40, "2C 1C" }, + {0x0d, 0x01, 0xc0, 0xc0, "1C 1C" }, + {0x0d, 0x01, 0xc0, 0x00, "2C 3C" }, + {0x0d, 0x01, 0xc0, 0x80, "1C 2C" }, +}; + +STDDIPINFO(Drv); + + +static void sound_control_w(unsigned short, unsigned char data) +{ + static int last; + + if ((last & 0x04) == 0x04 && (data & 0x4) == 0x00) + { + if (last & 0x01) + AY8910Write(0, 0, soundlatch); + else + AY8910Write(0, 1, soundlatch); + } + + last = data; +} + + +void __fastcall enraya4_out_port(unsigned short a, unsigned char d) +{ + switch (a & 0xff) + { + case 0x23: + soundlatch = d; + break; + + case 0x33: + sound_control_w(a, d); + break; + } +} + + +unsigned char __fastcall enraya4_in_port(unsigned short a) +{ + static unsigned char nRet = 0; + + switch (a & 0xff) + { + case 0x00: + nRet = DrvDips; + break; + + case 0x01: + nRet = DrvJoy2[3]; + nRet |= DrvJoy1[3] << 1; + nRet |= DrvJoy1[2] << 2; + nRet |= DrvJoy2[4] << 3; + nRet |= DrvJoy2[2] << 4; + nRet |= DrvJoy1[4] << 5; + nRet |= DrvJoy1[5] << 6; + nRet |= DrvJoy2[5] << 7; + nRet ^= 0xff; + break; + + case 0x02: + nRet = DrvJoy1[0] << 1; + nRet |= DrvJoy2[0] << 7; + nRet |= DrvJoy1[1] << 6; + nRet |= DrvJoy2[1] << 5; + nRet ^= 0xff; + break; + } + + return nRet; +} + + +void __fastcall enraya4_write(unsigned short a, unsigned char d) +{ + if (a >= 0xd000 && a <= 0xdfff) + { + Rom[0xd000 | ((a&0x3ff) << 1) | 0] = d; + Rom[0xd000 | ((a&0x3ff) << 1) | 1] = (a & 0xc00) >> 10; + } +} + + +static int DrvDoReset() +{ + DrvReset = 0; + memset (Rom + 0xc000, 0, 0x4000); + + ZetOpen(0); + ZetReset(); + ZetClose(); + + soundlatch = 0; + AY8910Reset(0); + + return 0; +} + + +static int DrvInit() +{ + Mem = (unsigned char *)malloc( 0x16000 ); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short *)malloc (nBurnSoundLen * 3 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + Rom = Mem + 0x00000; + Gfx = Mem + 0x10000; + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + // Load Roms + { + BurnLoadRom(Rom + 0x00000, 0, 1); + BurnLoadRom(Rom + 0x08000, 1, 1); + + BurnLoadRom(Gfx + 0x00000, 2, 1); + BurnLoadRom(Gfx + 0x02000, 3, 1); + BurnLoadRom(Gfx + 0x04000, 4, 1); + + // BurnLoadRom(Prom, 5, 1); // Prom not used + } + + ZetInit(1); + ZetOpen(0); + ZetSetInHandler(enraya4_in_port); + ZetSetOutHandler(enraya4_out_port); + ZetSetWriteHandler(enraya4_write); + ZetMapArea(0x0000, 0xffff, 0, Rom); + ZetMapArea(0x0000, 0xbfff, 2, Rom); + ZetMapArea(0xc000, 0xcfff, 1, Rom + 0xc000); + ZetMemEnd(); + ZetClose(); + + // Initilize palette + { + for (int i = 0; i < 8; i++) { + Palette[i] = (i & 1) ? 0xff0000 : 0; + Palette[i] |= (i & 2) ? 0x00ff00 : 0; + Palette[i] |= (i & 4) ? 0x0000ff : 0; + } + } + + AY8910Init(0, 2000000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + return 0; +} + + +static int DrvExit() +{ + ZetExit(); + AY8910Exit(0); + + DrvReset = 0; + free (Mem); + free (pFMBuffer); + + pFMBuffer = NULL; + Mem = Rom = Gfx = NULL; + + return 0; +} + + +static int DrvDraw() +{ +#define cl(v) (v & 0x80) ? 0xff : 0 + + for (int i = 0x80; i < 0x800 - 0x80; i+=2) + { + int x1 = ((i >> 1) & 0x1f) << 3; + int y1 = ((i >> 6) << 11) - 0x1000; + + int tile_no = (Rom[0xd000 | i] | (Rom[0xd000 | i | 1] << 8)) << 3; + + for (int y = y1; y < y1 + 256 * 8; y+=256, tile_no++) + { + unsigned char r0 = Gfx[0x0000 + tile_no]; + unsigned char g0 = Gfx[0x4000 + tile_no]; + unsigned char b0 = Gfx[0x2000 + tile_no]; + + for (int x = x1; x < x1 + 8; x++) + { + PutPix(pBurnDraw + (y | x) * nBurnBpp, BurnHighCol(cl(r0), cl(g0), cl(b0), 0)); + + r0 <<= 1; + g0 <<= 1; + b0 <<= 1; + } + } + } + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetOpen(0); + ZetRun(4000000 / 60); + ZetSetIRQLine(0, 4); + ZetClose(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0xc000; + ba.nLen = 0x4000; + ba.szName = "All Ram"; + BurnAcb(&ba); + + ZetScan(nAction); // Scan Z80 + AY8910Scan(nAction, pnMin); // Scan AY8910 + + // Scan critical driver variables + SCAN_VAR(soundlatch); + } + + return 0; +} + + +// 4 En Raya + +static struct BurnRomInfo enraya4RomDesc[] = { + { "5.bin", 0x8000, 0xcf1cd151, BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "4.bin", 0x4000, 0xf9ec1be7, BRF_ESS | BRF_PRG }, // 1 + + { "1.bin", 0x2000, 0x87f92552, BRF_GRA }, // 2 Graphics + { "2.bin", 0x2000, 0x2b0a3793, BRF_GRA }, // 3 + { "3.bin", 0x2000, 0xf6940836, BRF_GRA }, // 4 + + { "1.bpr", 0x0020, 0xdcbd2352, BRF_GRA }, // 5 - not used +}; + +STD_ROM_PICK(enraya4); +STD_ROM_FN(enraya4); + +struct BurnDriver BurnDrvenraya4 = { + "4enraya", NULL, NULL, "1990", + "4 En Raya\0", NULL, "IDSA", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, enraya4RomInfo, enraya4RomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 224, 4, 3 +}; + diff --git a/src/burn/misc/pre90s/d_ambush.cpp b/src/burn/misc/pre90s/d_ambush.cpp new file mode 100644 index 0000000..d8d1bd4 --- /dev/null +++ b/src/burn/misc/pre90s/d_ambush.cpp @@ -0,0 +1,631 @@ +// Ambush FB Alpha driver module +// Based on MAME driver by Zsolt Vasvari + +#include "burnint.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +static unsigned char *Mem, *Rom, *Gfx, *Prom; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvReset, DrvDips; +static int *Palette; +static short* pFMBuffer; +static short* pAY8910Buffer[6]; + +static unsigned char ambush_colorbank, flipscreen; + +//---------------------------------------------------------------------------------- +// Inputs + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy2 + 0, "p2 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy1 + 1, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 1, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 2, "p1 up"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 4, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 5, "p1 right"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 6, "p1 fire 1"}, + {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 7, "p1 fire 2"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 2, "p2 up"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 4, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 5, "p2 right"}, + {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 6, "p2 fire 1"}, + {"P2 Button 2", BIT_DIGITAL, DrvJoy2 + 7, "p2 fire 2"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Dip Switches", BIT_DIPSWITCH, &DrvDips, "dip"}, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x11, 0xff, 0xff, 0xc0, NULL }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x11, 0x01, 0x03, 0x00, "3" }, + {0x11, 0x01, 0x03, 0x01, "4" }, + {0x11, 0x01, 0x03, 0x02, "5" }, + {0x11, 0x01, 0x03, 0x03, "6" }, + + {0 , 0xfe, 0 , 8 , "Coinage" }, + {0x11, 0x01, 0x1c, 0x14, "3 Coins 1 Credit" }, + {0x11, 0x01, 0x1c, 0x10, "2 Coins 1 Credit" }, + {0x11, 0x01, 0x1c, 0x00, "1 Coins 1 Credit" }, + {0x11, 0x01, 0x1c, 0x04, "1 Coin 2 Credits" }, + {0x11, 0x01, 0x1c, 0x18, "2 Coins 5 Credits" }, + {0x11, 0x01, 0x1c, 0x08, "1 Coin 3 Credits" }, + {0x11, 0x01, 0x1c, 0x0c, "1 Coin 4 Credits" }, + {0x11, 0x01, 0x1c, 0x1c, "Free Play / Service" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x11, 0x01, 0x20, 0x00, "Easy" }, + {0x11, 0x01, 0x20, 0x20, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x11, 0x01, 0x40, 0x40, "80000" }, + {0x11, 0x01, 0x40, 0x00, "120000" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x11, 0x01, 0x80, 0x80, "Upright" }, + {0x11, 0x01, 0x80, 0x00, "Cocktail" }, +}; + +STDDIPINFO(Drv); + +//---------------------------------------------------------------------------------- +// Memory / Port handlers + +unsigned char __fastcall ambush_read_byte(unsigned short a) +{ + switch (a) + { + case 0xa000: // watchdog reset + break; + + case 0xc800: + return DrvDips; // dips + } + + return 0; +} + +void __fastcall ambush_write_byte(unsigned short a, unsigned char d) +{ + switch (a) + { + case 0xcc00: // nop + case 0xcc01: + case 0xcc02: + case 0xcc03: + case 0xcc07: // coin counter + + break; + + case 0xcc04: // flip screen + flipscreen = d; + break; + + case 0xcc05: // color bank select + ambush_colorbank = d & 3; + break; + } +} + + +unsigned char __fastcall ambush_in_port(unsigned short a) +{ + switch (a & 0xff) + { + case 0x00: // read_0 + case 0x80: // read 1 + return AY8910Read((a >> 7) & 1); + } + + return 0; +} + +void __fastcall ambush_out_port(unsigned short a, unsigned char d) +{ + switch (a & 0xff) + { + case 0x00: // control 0 + case 0x01: // write 0 + case 0x80: // control 1 + case 0x81: // write 1 + AY8910Write((a >> 7) & 1, a & 1, d); + break; + } +} + +unsigned char AY8910_0_port0(unsigned int) +{ + unsigned char ret = 0xff; + + ret ^= DrvJoy1[7] << 0; + ret ^= DrvJoy1[6] << 1; + ret ^= DrvJoy2[7] << 2; + ret ^= DrvJoy2[6] << 3; + ret ^= DrvJoy2[1] << 4; + ret ^= DrvJoy1[1] << 5; + ret ^= DrvJoy2[0] << 6; + ret ^= DrvJoy1[0] << 7; + + return ret; +} + +unsigned char AY8910_1_port0(unsigned int) +{ + unsigned char ret = 0xff; + + ret ^= DrvJoy1[2] << 0; + ret ^= DrvJoy1[3] << 1; + ret ^= DrvJoy1[4] << 2; + ret ^= DrvJoy1[5] << 3; + ret ^= DrvJoy2[2] << 4; + ret ^= DrvJoy2[3] << 5; + ret ^= DrvJoy2[4] << 6; + ret ^= DrvJoy2[5] << 7; + + return ret; +} + +//---------------------------------------------------------------------------------- +// Initilizing functions + +static int DrvDoReset() +{ + ambush_colorbank = 0; + + memset(Rom + 0x8000, 0, 0x0400); + memset(Rom + 0xc000, 0, 0x1000); + + ZetOpen(0); + ZetReset(); + ZetClose(); + + AY8910Reset(0); + AY8910Reset(1); + + return 0; +} + +static void ambush_palette_init() +{ + int i; + unsigned char *color_prom = Prom; + + for (i = 0;i < 0x100; i++) + { + int bit0,bit1,bit2,r,g,b; + + /* red component */ + bit0 = (color_prom[i] >> 0) & 0x01; + bit1 = (color_prom[i] >> 1) & 0x01; + bit2 = (color_prom[i] >> 2) & 0x01; + r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + /* green component */ + bit0 = (color_prom[i] >> 3) & 0x01; + bit1 = (color_prom[i] >> 4) & 0x01; + bit2 = (color_prom[i] >> 5) & 0x01; + g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + /* blue component */ + bit0 = 0; + bit1 = (color_prom[i] >> 6) & 0x01; + bit2 = (color_prom[i] >> 7) & 0x01; + b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + Palette[i] = (r << 16) | (g << 8) | b; + } +} + +static void ambush_gfx_convert() +{ + unsigned char *tmp = (unsigned char *)malloc(0x4000); + + memcpy (tmp, Gfx, 0x4000); + + for (int i = 0; i < 0x10000; i++) + { + Gfx[i] = ((tmp[0x0000 + (i >> 3)] >> (i & 7)) & 1) << 1; + Gfx[i] |= ((tmp[0x2000 + (i >> 3)] >> (i & 7)) & 1); + } + + free (tmp); +} + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x10000 + 0x10000 + 0x100 + 0x400); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short*)malloc(nBurnSoundLen * 6 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + Rom = Mem + 0x00000; + Gfx = Mem + 0x10000; + Prom = Mem + 0x20000; + Palette = (int*)(Mem + 0x20100); + + { + if (BurnLoadRom(Rom + 0x0000, 0, 1)) return 1; + if (BurnLoadRom(Rom + 0x2000, 1, 1)) return 1; + if (BurnLoadRom(Rom + 0x4000, 2, 1)) return 1; + if (BurnLoadRom(Rom + 0x6000, 3, 1)) return 1; + + if (BurnLoadRom(Gfx + 0x0000, 4, 1)) return 1; + if (BurnLoadRom(Gfx + 0x2000, 5, 1)) return 1; + + if (BurnLoadRom(Prom + 0x0000, 6, 1)) return 1; + + ambush_palette_init(); + ambush_gfx_convert(); + } + + ZetInit(1); + ZetOpen(0); + ZetSetInHandler(ambush_in_port); + ZetSetOutHandler(ambush_out_port); + ZetSetReadHandler(ambush_read_byte); + ZetSetWriteHandler(ambush_write_byte); + + ZetMapArea(0x0000, 0x7fff, 0, Rom + 0x0000); + ZetMapArea(0x0000, 0x7fff, 2, Rom + 0x0000); + + ZetMapArea(0x8000, 0x87ff, 0, Rom + 0x8000); // main ram + ZetMapArea(0x8000, 0x87ff, 1, Rom + 0x8000); + ZetMapArea(0x8000, 0x87ff, 2, Rom + 0x8000); + + ZetMapArea(0xc000, 0xc7ff, 0, Rom + 0xc000); // video ram + ZetMapArea(0xc000, 0xc7ff, 1, Rom + 0xc000); + ZetMemEnd(); + ZetClose(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + pAY8910Buffer[3] = pFMBuffer + nBurnSoundLen * 3; + pAY8910Buffer[4] = pFMBuffer + nBurnSoundLen * 4; + pAY8910Buffer[5] = pFMBuffer + nBurnSoundLen * 5; + + AY8910Init(0, 1500000, nBurnSoundRate, &AY8910_0_port0, NULL, NULL, NULL); + AY8910Init(1, 1500000, nBurnSoundRate, &AY8910_1_port0, NULL, NULL, NULL); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + AY8910Exit(0); + AY8910Exit(1); + + free (pFMBuffer); + free (Mem); + + return 0; +} + +//---------------------------------------------------------------------------------- +// Drawing functions + +static void draw_tile(int code, int sx, int sy, int color, int flipx, int flipy, int transp, int spr) +{ + unsigned char *src = Gfx + code; + + for (int y = 7; y >= 0; y--) + { + for (int x = 7; x >= 0; x--, src++) + { + if (*src == 0 && transp) continue; + int pxl = Palette[color | *src]; + + int pos; + if (flipy) + pos = ((sy + 7 - y) & 0xff) * 256; + else + pos = ((sy + y) & 0xff) * 256; + + if (flipx) + pos += ((sx + 7 - x) & 0xff); + else + pos += ((sx + x) & 0xff); + + if (spr) pos ^= 0xff00; // vertical flip for sprites + + if (pos < 0x1000 || pos > 0xefff) continue; // trim garbage + pos -= 0x1000; + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } +} + +static void draw_chars(int priority) +{ + for (int offs = 0; offs < 0x400; offs++) + { + int code,sx,sy,color; + unsigned char scroll; + + sy = (offs >> 5); + sx = (offs & 0x1f); + + color = Rom[0xc100 + ((sy & 0x1c) << 3) + sx]; + + if ((color & 0x10) != priority) continue; + + scroll = ~Rom[0xc080 + sx]; + + sy = (sy << 3) + scroll; + sx = (sx << 3); + + code = (Rom[0xc400 + offs] | ((color & 0x60) << 3)) << 6; + + color = ((ambush_colorbank << 4) | (color & 0x0f)) << 2; + + draw_tile(code, sx, sy, color, 0, 1, priority >> 4, 0); + } +} + +static void draw_sprites() +{ + for (int offs = 0x200 - 4;offs >= 0;offs -= 4) + { + int code,color,sx,sy,flipx,flipy; + + sy = Rom[0xc200 + offs + 0]; + sx = Rom[0xc200 + offs + 3]; + + if ((sy == 0) || (sy == 0xff) || ((sx < 0x40) && ( Rom[0xc200 + offs + 2] & 0x10)) || + ((sx >= 0xc0) && (!(Rom[0xc200 + offs + 2] & 0x10)))) continue; // prevent wraparound + + code = ((Rom[0xc200 + offs + 1] & 0x3f) | ((Rom[0xc200 + offs + 2] & 0x60) << 1)) << 8; + + color = Rom[0xc200 + offs + 2] & 0x0f; + flipx = Rom[0xc200 + offs + 1] & 0x40; + flipy = Rom[0xc200 + offs + 1] & 0x80; + + color = (color | (ambush_colorbank << 4)) << 2; + + if (Rom[0xc200 + offs + 2] & 0x80) + { + // 16x16 sprites (four 8x8 tiles) + draw_tile(code, sx + (flipx ? 8 : 0), sy + (flipy ? 0 : 8), color, flipx, flipy, 1, 1); + code += 0x40; + + draw_tile(code, sx + (flipx ? 0 : 8), sy + (flipy ? 0 : 8), color, flipx, flipy, 1, 1); + code += 0x40; + + draw_tile(code, sx + (flipx ? 8 : 0), sy + (flipy ? 8 : 0), color, flipx, flipy, 1, 1); + code += 0x40; + + draw_tile(code, sx + (flipx ? 0 : 8), sy + (flipy ? 8 : 0), color, flipx, flipy, 1, 1); + code += 0x40; + } + else + { + // 8x8 sprites + draw_tile(code, sx + (flipx ? 8 : 0), sy + (flipy ? 8 : 0), color, flipx, flipy, 1, 1); + } + } +} + +static int DrvDraw() +{ + // set background color + { + int px = BurnHighCol(Palette[0] >> 16, Palette[0] >> 8, Palette[0], 0); + + for (int i = 0; i < 0xE000; i++) + PutPix(pBurnDraw + i * nBurnBpp, px); + } + + // draw background + draw_chars(0); + + // sprites + draw_sprites(); + + // draw foreground + draw_chars(0x10); + + return 0; +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetOpen(0); + ZetRun(4000000 / 60); + ZetRaiseIrq(0); + ZetClose(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + +//---------------------------------------------------------------------------------- +// Savestates + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0x8000; + ba.nLen = 0x0800; + ba.szName = "Work Ram"; + BurnAcb(&ba); + + memset(&ba, 0, sizeof(ba)); + ba.Data = Rom + 0xc000; + ba.nLen = 0x1000; + ba.szName = "Video Ram"; + BurnAcb(&ba); + + ZetScan(nAction); // Scan Z80 + + AY8910Scan(nAction, pnMin); // Scan AY8910 + + // Scan critical driver variables + SCAN_VAR(ambush_colorbank); + SCAN_VAR(flipscreen); + } + + return 0; +} + +//---------------------------------------------------------------------------------- +// Game drivers + +// Ambush + +static struct BurnRomInfo ambushRomDesc[] = { + { "ambush.h7", 0x2000, 0xce306563, BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "ambush.g7", 0x2000, 0x90291409, BRF_ESS | BRF_PRG }, // 1 + { "ambush.f7", 0x2000, 0xd023ca29, BRF_ESS | BRF_PRG }, // 2 + { "ambush.e7", 0x2000, 0x6cc2d3ee, BRF_ESS | BRF_PRG }, // 3 + + { "ambush.n4", 0x2000, 0xecc0dc85, BRF_GRA }, // 4 Graphics tiles + { "ambush.m4", 0x2000, 0xe86ca98a, BRF_GRA }, // 5 + + { "a.bpr", 0x0100, 0x5f27f511, BRF_GRA }, // 6 color PROMs + + { "b.bpr", 0x0100, 0x1b03fd3b, BRF_GRA }, // 7 Proms - Not used + { "13.bpr", 0x0100, 0x547e970f, BRF_GRA }, // 8 + { "14.bpr", 0x0100, 0x622a8ce7, BRF_GRA }, // 9 +}; + +STD_ROM_PICK(ambush); +STD_ROM_FN(ambush); + +struct BurnDriver BurnDrvambush = { + "ambush", NULL, NULL, "1983", + "Ambush\0", NULL, "Nippon Amuse Co-Ltd", "Ambush", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, ambushRomInfo, ambushRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 224, 4, 3 +}; + + +// Ambush (Tecfri) + +static struct BurnRomInfo ambushtRomDesc[] = { + { "a1.i7", 0x2000, 0xa7cd149d, BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "a2.g7", 0x2000, 0x8328d88a, BRF_ESS | BRF_PRG }, // 1 + { "a3.f7", 0x2000, 0x8db57ab5, BRF_ESS | BRF_PRG }, // 2 + { "a4.e7", 0x2000, 0x4a34d2a4, BRF_ESS | BRF_PRG }, // 3 + + { "fa2.n4", 0x2000, 0xe7f134ba, BRF_GRA }, // 4 Graphics tiles + { "fa1.m4", 0x2000, 0xad10969e, BRF_GRA }, // 5 + + { "a.bpr", 0x0100, 0x5f27f511, BRF_GRA }, // 6 color PROMs + + { "b.bpr", 0x0100, 0x1b03fd3b, BRF_GRA }, // 7 Proms - Not used + { "13.bpr", 0x0100, 0x547e970f, BRF_GRA }, // 8 + { "14.bpr", 0x0100, 0x622a8ce7, BRF_GRA }, // 9 +}; + +STD_ROM_PICK(ambusht); +STD_ROM_FN(ambusht); + +struct BurnDriver BurnDrvambusht = { + "ambusht", "ambush", NULL, "1983", + "Ambush (Tecfri)\0", NULL, "Tecfri", "Ambush", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, ambushtRomInfo, ambushtRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 224, 4, 3 +}; + + +// Ambush (Volt Elec co-ltd) + +static struct BurnRomInfo ambushvRomDesc[] = { + { "n1_h7.bin", 0x2000, 0x3c0833b4, BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "ambush.g7", 0x2000, 0x90291409, BRF_ESS | BRF_PRG }, // 1 + { "ambush.f7", 0x2000, 0xd023ca29, BRF_ESS | BRF_PRG }, // 2 + { "ambush.e7", 0x2000, 0x6cc2d3ee, BRF_ESS | BRF_PRG }, // 3 + + { "ambush.n4", 0x2000, 0xecc0dc85, BRF_GRA }, // 4 Graphics tiles + { "ambush.m4", 0x2000, 0xe86ca98a, BRF_GRA }, // 5 + + { "a.bpr", 0x0100, 0x5f27f511, BRF_GRA }, // 6 color PROMs + + { "b.bpr", 0x0100, 0x1b03fd3b, BRF_GRA }, // 7 Proms - Not used + { "13.bpr", 0x0100, 0x547e970f, BRF_GRA }, // 8 + { "14.bpr", 0x0100, 0x622a8ce7, BRF_GRA }, // 9 +}; + +STD_ROM_PICK(ambushv); +STD_ROM_FN(ambushv); + +struct BurnDriver BurnDrvambushv = { + "ambushv", "ambush", NULL, "1983", + "Ambush (Volt Elec co-ltd)\0", NULL, "Volt Elec co-ltd", "Ambush", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, ambushvRomInfo, ambushvRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 224, 4, 3 +}; + + diff --git a/src/burn/misc/pre90s/d_arkanoid.cpp b/src/burn/misc/pre90s/d_arkanoid.cpp new file mode 100644 index 0000000..2f38f7a --- /dev/null +++ b/src/burn/misc/pre90s/d_arkanoid.cpp @@ -0,0 +1,1751 @@ + +#include "burnint.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + + +static unsigned char *Mem, *Rom, *Gfx, *Mcu, *Prom; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvDips[1], DrvService, DrvReset, DrvTilt; +static unsigned short DrvAxis[2]; +static unsigned int nAnalogAxis[2] = {0,0}; +static short *pAY8910Buffer[3], *pFMBuffer = NULL; +static int *Palette; + +static int arkanoid_bootleg_id, tetrsark = 0; +static unsigned char arkanoid_bootleg_cmd; +static unsigned char palettebank, gfxbank; +static unsigned char arkanoid_paddle_select, arkanoid_paddle_value; + +enum { + ARKUNK=0, // unknown bootlegs + ARKANGC, + ARKANGC2, + ARKBLOCK, + ARKBLOC2, + ARKGCBL, + PADDLE2 +}; + + +//-------------------------------------------------------------------------------- + + +#define A(a, b, c, d) { a, b, (unsigned char*)(c), d } + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 0, "p1 coin" }, // 0 + {"P1 start" , BIT_DIGITAL , DrvJoy1 + 1, "p1 start" }, // 1 + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 2, "p1 fire 1"}, // 2 + + A("P1 Right / left", BIT_ANALOG_REL, DrvAxis + 0, "mouse x-axis"), + + {"P2 Coin" , BIT_DIGITAL , DrvJoy2 + 0, "p2 coin" }, // 4 + {"P2 start" , BIT_DIGITAL , DrvJoy2 + 1, "p2 start" }, // 5 + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 2, "p2 fire 1"}, // 6 + + A("P2 Right / left", BIT_ANALOG_REL, DrvAxis + 1, "mouse x-axis"), + + {"Tilt", BIT_DIGITAL, &DrvTilt, "tilt" }, // 8 + {"Service", BIT_DIGITAL, &DrvService, "diag" }, // 9 + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, // a + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, // b +}; + +STDINPUTINFO(Drv); + +static struct BurnInputInfo tetrsarkInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 0, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy1 + 1, "p1 start" }, + {"P1 down", BIT_DIGITAL, DrvJoy1 + 2, "p1 down" }, + {"P1 left", BIT_DIGITAL, DrvJoy1 + 3, "p1 left" }, + {"P1 right", BIT_DIGITAL, DrvJoy1 + 4, "p1 right" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 5, "p1 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy1 + 6, "p2 fire 2"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy2 + 0, "p2 coin" }, + {"P2 start" , BIT_DIGITAL , DrvJoy2 + 1, "p2 start" }, + {"P2 down", BIT_DIGITAL, DrvJoy2 + 2, "p2 down" }, + {"P2 left", BIT_DIGITAL, DrvJoy2 + 3, "p2 left" }, + {"P2 right", BIT_DIGITAL, DrvJoy2 + 4, "p2 right" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 5, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 6, "p2 fire 2"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, +}; + +STDINPUTINFO(tetrsark); + +static struct BurnDIPInfo arkanoidDIPList[]= +{ + // Default Values + {0x0b, 0xff, 0xff, 0x7f, NULL }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x0b, 0x01, 0x01, 0x01, "No" }, + {0x0b, 0x01, 0x01, 0x00, "Yes" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0b, 0x01, 0x02, 0x02, "Off" }, + {0x0b, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0b, 0x01, 0x08, 0x08, "Easy" }, + {0x0b, 0x01, 0x08, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x0b, 0x01, 0x10, 0x10, "20K 60K 60K+" }, + {0x0b, 0x01, 0x10, 0x00, "20K" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x0b, 0x01, 0x20, 0x20, "3" }, + {0x0b, 0x01, 0x20, 0x00, "5" }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0b, 0x01, 0xc0, 0x40, "2C 1C" }, + {0x0b, 0x01, 0xc0, 0xc0, "1C 1C" }, + {0x0b, 0x01, 0xc0, 0x80, "1C 2C" }, + {0x0b, 0x01, 0xc0, 0x00, "1C 6C" }, +}; + +STDDIPINFO(arkanoid); + +static struct BurnDIPInfo arknoidjDIPList[]= +{ + // Default Values + {0x0b, 0xff, 0xff, 0x7f, NULL }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x0b, 0x01, 0x01, 0x01, "No" }, + {0x0b, 0x01, 0x01, 0x00, "Yes" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0b, 0x01, 0x02, 0x02, "Off" }, + {0x0b, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0b, 0x01, 0x08, 0x08, "Easy" }, + {0x0b, 0x01, 0x08, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x0b, 0x01, 0x10, 0x10, "20K 60K 60K+" }, + {0x0b, 0x01, 0x10, 0x00, "20K" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x0b, 0x01, 0x20, 0x20, "3" }, + {0x0b, 0x01, 0x20, 0x00, "5" }, + + {0 , 0xfe, 0 , 2 , "Coinage" }, + {0x0b, 0x01, 0x40, 0x40, "1C 1C" }, + {0x0b, 0x01, 0x40, 0x00, "1C 2C" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0b, 0x01, 0x80, 0x00, "Upright" }, + {0x0b, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(arknoidj); + +static struct BurnDIPInfo ark1ballDIPList[]= +{ + // Default Values + {0x0b, 0xff, 0xff, 0x7f, NULL }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x0b, 0x01, 0x01, 0x01, "No" }, + {0x0b, 0x01, 0x01, 0x00, "Yes" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0b, 0x01, 0x02, 0x02, "Off" }, + {0x0b, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0b, 0x01, 0x08, 0x08, "Easy" }, + {0x0b, 0x01, 0x08, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x0b, 0x01, 0x10, 0x10, "60K 100K 60K+" }, + {0x0b, 0x01, 0x10, 0x00, "60K" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x0b, 0x01, 0x20, 0x20, "1" }, + {0x0b, 0x01, 0x20, 0x00, "2" }, + + {0 , 0xfe, 0 , 2 , "Coinage" }, + {0x0b, 0x01, 0x40, 0x40, "1C 1C" }, + {0x0b, 0x01, 0x40, 0x00, "1C 2C" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0b, 0x01, 0x80, 0x00, "Upright" }, + {0x0b, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(ark1ball); + +static struct BurnDIPInfo arkangcDIPList[]= +{ + // Default Values + {0x0b, 0xff, 0xff, 0x7f, NULL }, + + {0 , 0xfe, 0 , 2 , "Ball Speed" }, + {0x0b, 0x01, 0x01, 0x01, "Normal" }, + {0x0b, 0x01, 0x01, 0x00, "Faster" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0b, 0x01, 0x02, 0x02, "Off" }, + {0x0b, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0b, 0x01, 0x08, 0x08, "Easy" }, + {0x0b, 0x01, 0x08, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x0b, 0x01, 0x10, 0x10, "20K 60K 60K+" }, + {0x0b, 0x01, 0x10, 0x00, "20K" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x0b, 0x01, 0x20, 0x20, "3" }, + {0x0b, 0x01, 0x20, 0x00, "5" }, + + {0 , 0xfe, 0 , 2 , "Coinage" }, + {0x0b, 0x01, 0x40, 0x40, "1C 1C" }, + {0x0b, 0x01, 0x40, 0x00, "1C 2C" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0b, 0x01, 0x80, 0x00, "Upright" }, + {0x0b, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(arkangc); + +static struct BurnDIPInfo arkangc2DIPList[]= +{ + // Default Values + {0x0b, 0xff, 0xff, 0x7f, NULL }, + + {0 , 0xfe, 0 , 2 , "Ball Speed" }, + {0x0b, 0x01, 0x01, 0x01, "Slower" }, + {0x0b, 0x01, 0x01, 0x00, "Normal" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0b, 0x01, 0x02, 0x02, "Off" }, + {0x0b, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0b, 0x01, 0x08, 0x08, "Easy" }, + {0x0b, 0x01, 0x08, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x0b, 0x01, 0x10, 0x10, "20K 60K 60K+" }, + {0x0b, 0x01, 0x10, 0x00, "20K" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x0b, 0x01, 0x20, 0x20, "3" }, + {0x0b, 0x01, 0x20, 0x00, "5" }, + + {0 , 0xfe, 0 , 2 , "Coinage" }, + {0x0b, 0x01, 0x40, 0x40, "1C 1C" }, + {0x0b, 0x01, 0x40, 0x00, "1C 2C" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0b, 0x01, 0x80, 0x00, "Upright" }, + {0x0b, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(arkangc2); + +static struct BurnDIPInfo arkgcblDIPList[]= +{ + // Default Values + {0x0b, 0xff, 0xff, 0x5f, NULL }, + + {0 , 0xfe, 0 , 2 , "Round Select" }, + {0x0b, 0x01, 0x01, 0x01, "Off" }, + {0x0b, 0x01, 0x01, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0b, 0x01, 0x02, 0x02, "Off" }, + {0x0b, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0b, 0x01, 0x08, 0x08, "Easy" }, + {0x0b, 0x01, 0x08, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x0b, 0x01, 0x10, 0x10, "60K 100K 60K+" }, + {0x0b, 0x01, 0x10, 0x00, "60K" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x0b, 0x01, 0x20, 0x00, "2" }, + {0x0b, 0x01, 0x20, 0x20, "3" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0b, 0x01, 0x80, 0x00, "Upright" }, + {0x0b, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(arkgcbl); + +static struct BurnDIPInfo paddle2DIPList[]= +{ + // Default Values + {0x0b, 0xff, 0xff, 0x5f, NULL }, + + {0 , 0xfe, 0 , 2 , "Round Select" }, + {0x0b, 0x01, 0x01, 0x01, "Off" }, + {0x0b, 0x01, 0x01, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0b, 0x01, 0x02, 0x02, "Off" }, + {0x0b, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Controls ?" }, + {0x0b, 0x01, 0x04, 0x04, "Normal" }, + {0x0b, 0x01, 0x04, 0x00, "Alternate" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0b, 0x01, 0x08, 0x08, "Easy" }, + {0x0b, 0x01, 0x08, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x0b, 0x01, 0x10, 0x10, "60K 60K 60K+" }, + {0x0b, 0x01, 0x10, 0x00, "60K" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x0b, 0x01, 0x20, 0x00, "2" }, + {0x0b, 0x01, 0x20, 0x20, "3" }, + + {0 , 0xfe, 0 , 2 , "Coinage" }, + {0x0b, 0x01, 0x40, 0x40, "1C 1C" }, + {0x0b, 0x01, 0x40, 0x00, "1C 2C" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0b, 0x01, 0x80, 0x00, "Upright" }, + {0x0b, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(paddle2); + +static struct BurnDIPInfo arktayt2DIPList[]= +{ + // Default Values + {0x0b, 0xff, 0xff, 0x3f, NULL }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x0b, 0x01, 0x01, 0x01, "No" }, + {0x0b, 0x01, 0x01, 0x00, "Yes" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0b, 0x01, 0x02, 0x02, "Off" }, + {0x0b, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0b, 0x01, 0x08, 0x08, "Easy" }, + {0x0b, 0x01, 0x08, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x0b, 0x01, 0x10, 0x10, "60K 60K 60K+" }, + {0x0b, 0x01, 0x10, 0x00, "60K" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x0b, 0x01, 0x20, 0x20, "2" }, + {0x0b, 0x01, 0x20, 0x00, "3" }, + + {0 , 0xfe, 0 , 2 , "Coinage" }, + {0x0b, 0x01, 0x40, 0x00, "2C 1C" }, + {0x0b, 0x01, 0x40, 0x40, "1C 1C" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0b, 0x01, 0x80, 0x00, "Upright" }, + {0x0b, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(arktayt2); + +static struct BurnDIPInfo tetrsarkDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xf0, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x10, 0x10, "Upright" }, + {0x0f, 0x01, 0x10, 0x00, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x0f, 0x01, 0x20, 0x20, "Off" }, + {0x0f, 0x01, 0x20, 0x00, "On" }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0f, 0x01, 0xc0, 0xc0, "1C 1C" }, + {0x0f, 0x01, 0xc0, 0x80, "1C 2C" }, + {0x0f, 0x01, 0xc0, 0x40, "1C 3C" }, + {0x0f, 0x01, 0xc0, 0x00, "1C 5C" }, +}; + +STDDIPINFO(tetrsark); + + +//-------------------------------------------------------------------------------- + + +static unsigned char read_inputs(unsigned char port) +{ + unsigned char ret = 0; + + switch (port) + { + case 0x00: + ret |= DrvJoy1[1]; + ret |= DrvJoy2[1] << 1; + ret |= DrvService << 2; + ret |= DrvTilt << 3; + ret |= DrvJoy1[0] << 4; + ret |= DrvJoy2[0] << 5; + ret ^= 0x4f; + break; + + case 0x01: + ret |= DrvJoy1[2]; + ret |= DrvJoy2[2] << 2; + ret ^= 0xff; + break; + + case 0x02: // spinner + nAnalogAxis[0] -= DrvAxis[0]; + ret = (~nAnalogAxis[0] >> 8) & 0xfe; + arkanoid_paddle_value = ret; + break; + + case 0x03: // spinner + nAnalogAxis[1] -= DrvAxis[1]; + ret = (~nAnalogAxis[1] >> 8) & 0xfe; + break; + + case 0x04: // dips + ret = DrvDips[0]; + + if (tetrsark) + { + ret |= DrvJoy2[2]; + ret |= DrvJoy2[3] << 1; + ret |= DrvJoy2[4] << 2; + ret |= DrvJoy2[5] << 3; + ret ^= 0x0f; + } + break; + + case 0x05: + ret |= DrvJoy1[2]; + ret |= DrvJoy1[3] << 1; + ret |= DrvJoy1[4] << 2; + ret |= DrvJoy1[5] << 3; + ret |= DrvJoy1[1] << 4; + ret |= DrvJoy2[1] << 5; + ret |= DrvJoy1[6] << 6; + ret |= DrvJoy2[6] << 7; + ret ^= 0xff; + break; + } + + return ret; +} + + +//-------------------------------------------------------------------------------- +// AY8910 Read ports + +static unsigned char ay8910_read_port_4(unsigned int) +{ + return read_inputs(4); +} + + +static unsigned char ay8910_read_port_5(unsigned int) +{ + return read_inputs(5); +} + + +//-------------------------------------------------------------------------------- +// Read / Write handlers + + +// Kludge for some bootlegs that read this address +unsigned char __fastcall arkanoid_bootleg_f002_r() +{ + unsigned char arkanoid_bootleg_val = 0x00; + + switch (arkanoid_bootleg_id) + { + case ARKANGC: + case ARKBLOCK: + case ARKBLOC2: + case ARKANGC2: + switch (arkanoid_bootleg_cmd) + { + default: + break; + } + break; + + case ARKGCBL: + switch (arkanoid_bootleg_cmd) + { + case 0x8a: // Current level (fixed routine) + arkanoid_bootleg_val = 0xa5; + break; + case 0xff: // Avoid "BAD HARDWARE " message (fixed routine) + arkanoid_bootleg_val = 0xe2; + break; + default: + break; + } + break; + + case PADDLE2: + switch (arkanoid_bootleg_cmd) + { + case 0x24: // Avoid bad jump to 0x0066 + arkanoid_bootleg_val = 0x9b; + break; + case 0x36: // Avoid "BAD HARDWARE " message + arkanoid_bootleg_val = 0x2d; + break; + case 0x38: // Start of levels table (fixed offset) + arkanoid_bootleg_val = 0xf3; + break; + case 0x8a: // Current level (fixed routine) + arkanoid_bootleg_val = 0xa5; + break; + case 0xc3: // Avoid bad jump to 0xf000 + arkanoid_bootleg_val = 0x1d; + break; + case 0xe3: // Number of bricks left (fixed offset) + arkanoid_bootleg_val = 0x61; + break; + case 0xf7: // Avoid "U69" message + arkanoid_bootleg_val = 0x00; + break; + case 0xff: // Avoid "BAD HARDWARE " message (fixed routine) + arkanoid_bootleg_val = 0xe2; + break; + default: + break; + } + break; + + default: + break; + } + + return arkanoid_bootleg_val; +} + + +// Kludge for some bootlegs that write this address +void __fastcall arkanoid_bootleg_d018_w(unsigned short, unsigned char data) +{ + arkanoid_bootleg_cmd = 0x00; + + switch (arkanoid_bootleg_id) + { + case ARKANGC: + case ARKBLOCK: + switch (data) + { + case 0x36: // unneeded value : no call 0x2050, unused A and overwritten HL (0x0313 -> 0x0340) + if (ZetPc(-1) == 0x7c47) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x38: // unneeded value : no call 0x2050, unused A and fixed HL (0x7bd5) + if (ZetPc(-1) == 0x7b87) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x8a: // unneeded value : no call 0x2050, unused A and overwritten HL (0x7b77 -> 0x7c1c) + if (ZetPc(-1) == 0x9661) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xe3: // unneeded value : call 0x2050 but fixed A (0x00) and fixed HL (0xed83) + if (ZetPc(-1) == 0x67e3) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xf7: // unneeded value : 3 * 'NOP' at 0x034f + 2 * 'NOP' at 0x35b + if (ZetPc(-1) == 0x0349) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xff: // unneeded value : no call 0x2050, unused A and overwritten HL (0x7c4f -> 0x7d31) + if (ZetPc(-1) == 0x9670) + arkanoid_bootleg_cmd = 0x00; + break; + default: + arkanoid_bootleg_cmd = 0x00; + break; + } + break; + + case ARKANGC2: + switch (data) + { + case 0x36: // unneeded value : call 0x2050 but fixed A (0x2d) + if (ZetPc(-1) == 0x7c4c) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x38: // unneeded value : call 0x2050 but fixed A (0xf3) + if (ZetPc(-1) == 0x7b87) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x88: // unneeded value : no read back + if (ZetPc(-1) == 0x67e3) + arkanoid_bootleg_cmd = 0x00; + if (ZetPc(-1) == 0x7c47) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x89: // unneeded value : no read back + if (ZetPc(-1) == 0x67e5) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x8a: // unneeded value : call 0x2050 but fixed A (0xa5) + if (ZetPc(-1) == 0x9661) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xc0: // unneeded value : no read back + if (ZetPc(-1) == 0x67e7) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xe3: // unneeded value : call 0x2050 but fixed A (0x61) + if (ZetPc(-1) == 0x67e9) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xff: // unneeded value : call 0x2050 but fixed A (0xe2) + if (ZetPc(-1) == 0x9670) + arkanoid_bootleg_cmd = 0x00; + break; + default: + arkanoid_bootleg_cmd = 0x00; + break; + } + break; + + case ARKBLOC2: + switch (data) + { + case 0x36: // unneeded value : call 0x2050 but fixed A (0x2d) + if (ZetPc(-1) == 0x7c4c) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x38: // unneeded value : call 0x2050 but fixed A (0xf3) + if (ZetPc(-1) == 0x7b87) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x88: // unneeded value : no read back + if (ZetPc(-1) == 0x67e3) + arkanoid_bootleg_cmd = 0x00; + if (ZetPc(-1) == 0x7c47) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x89: // unneeded value : no read back + if (ZetPc(-1) == 0x67e5) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x8a: // unneeded value : call 0x2050 but unused HL and fixed DE (0x7c1c) + if (ZetPc(-1) == 0x9661) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xc0: // unneeded value : no read back + if (ZetPc(-1) == 0x67e7) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xe3: // unneeded value : call 0x2050 but fixed A (0x61) + if (ZetPc(-1) == 0x67e9) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xf7: // unneeded value : call 0x2050 but never called (check code at 0x0340) + if (ZetPc(-1) == 0x0349) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xff: // unneeded value : no call 0x2050, unused A and fixed HL (0x7d31) + if (ZetPc(-1) == 0x9670) + arkanoid_bootleg_cmd = 0x00; + break; + default: + arkanoid_bootleg_cmd = 0x00; + break; + } + break; + + case ARKGCBL: + switch (data) + { + case 0x36: // unneeded value : call 0x2050 but fixed A (0x2d) + if (ZetPc(-1) == 0x7c4c) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x38: // unneeded value : call 0x2050 but fixed A (0xf3) + if (ZetPc(-1) == 0x7b87) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x88: // unneeded value : no read back + if (ZetPc(-1) == 0x67e3) + arkanoid_bootleg_cmd = 0x00; + if (ZetPc(-1) == 0x7c47) + arkanoid_bootleg_cmd = 0x00; + case 0x89: // unneeded value : no read back + if (ZetPc(-1) == 0x67e5) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x8a: // call 0x2050 with A read from 0xf002 and wrong HL + if (ZetPc(-1) == 0x9661) + arkanoid_bootleg_cmd = data; + break; + case 0xc0: // unneeded value : no read back + if (ZetPc(-1) == 0x67e7) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xe3: // unneeded value : call 0x2050 but fixed A (0x61) + if (ZetPc(-1) == 0x67e9) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xf7: // unneeded value : 3 * 'NOP' at 0x034f + 'JR NZ,$035D' at 0x35b + if (ZetPc(-1) == 0x0349) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xff: // call 0x2050 with A read from 0xf002 and wrong HL + if (ZetPc(-1) == 0x9670) + arkanoid_bootleg_cmd = data; + break; + default: + arkanoid_bootleg_cmd = 0x00; + break; + } + break; + + case PADDLE2: + switch (data) + { + case 0x24: // A read from 0xf002 (expected to be 0x9b) + if (ZetPc(-1) == 0xbd7a) + arkanoid_bootleg_cmd = data; + break; + case 0x36: // call 0x2050 with A read from 0xf002 and wrong HL + if (ZetPc(-1) == 0x7c4c) + arkanoid_bootleg_cmd = data; + break; + case 0x38: // call 0x2050 with A read from 0xf002 and wrong HL + if (ZetPc(-1) == 0x7b87) + arkanoid_bootleg_cmd = data; + break; + case 0x88: // unneeded value : no read back + if (ZetPc(-1) == 0x67e3) + arkanoid_bootleg_cmd = 0x00; + if (ZetPc(-1) == 0x7c47) + arkanoid_bootleg_cmd = 0x00; + case 0x89: // unneeded value : no read back + if (ZetPc(-1) == 0x67e5) + arkanoid_bootleg_cmd = 0x00; + break; + case 0x8a: // call 0x2050 with A read from 0xf002 and wrong HL + if (ZetPc(-1) == 0x9661) + arkanoid_bootleg_cmd = data; + break; + case 0xc0: // unneeded value : no read back + if (ZetPc(-1) == 0x67e7) + arkanoid_bootleg_cmd = 0x00; + break; + case 0xc3: // A read from 0xf002 (expected to be 0x1d) + if (ZetPc(-1) == 0xbd8a) + arkanoid_bootleg_cmd = data; + break; + case 0xe3: // call 0x2050 with A read from 0xf002 and wrong HL + if (ZetPc(-1) == 0x67e9) + arkanoid_bootleg_cmd = data; + break; + case 0xf7: // call 0x2050 with A read from 0xf002 and wrong HL + if (ZetPc(-1) == 0x0349) + arkanoid_bootleg_cmd = data; + break; + case 0xff: // call 0x2050 with A read from 0xf002 and wrong HL + if (ZetPc(-1) == 0x9670) + arkanoid_bootleg_cmd = data; + break; + default: + arkanoid_bootleg_cmd = 0x00; + break; + } + break; + + default: + break; + } +} + +unsigned char __fastcall arkanoid_bootleg_d008_r() +{ + switch (arkanoid_bootleg_id) + { + case ARKANGC: + case ARKBLOCK: + return 0x00; + + case ARKANGC2: + return 0x02; + + case ARKBLOC2: + return (arkanoid_paddle_value < 0x40) << 5; + + case ARKGCBL: + return ((arkanoid_paddle_value < 0x40) << 5) | 0x02; + + case PADDLE2: + return ((arkanoid_paddle_value < 0x40) << 5) | 0x0f; + + default: + return 0x00; + } + + return 0; +} + + +static void __fastcall arkanoid_d008_w(unsigned short, unsigned char data) +{ + // bits 0 and 1 flip X and Y + + // bit 2 selects the input paddle + arkanoid_paddle_select = data & 0x04; + + // bit 3 is coin lockout (but not the service coin) + + // bit 4 is unknown + + // bits 5 and 6 control gfx bank and palette bank. They are used together + // so it's impossible to know which is which. + + gfxbank = (data & 0x20) >> 5; + + palettebank = (data & 0x40) >> 6; + + // bit 7 is unknown +} + + +unsigned char __fastcall arkanoid_read_byte(unsigned short a) +{ + switch (a) + { + case 0xd001: + return AY8910Read(0); + + case 0xd008: + return arkanoid_bootleg_d008_r(); + + case 0xd00c: // arkanoid_68705_input_0_r, input_port_0_r (boot) + return read_inputs(0); + + case 0xd010: + return read_inputs(1); + + case 0xd018: // arkanoid_z80_mcu_r, input_port_2_r (boot) + return read_inputs(2); + + case 0xf002: + return arkanoid_bootleg_f002_r(); + } + + return 0; +} + +void __fastcall arkanoid_write_byte(unsigned short a, unsigned char d) +{ + switch (a) + { + case 0xd000: // ay8910_control + case 0xd001: // ay8910_write_port + AY8910Write(0, a & 1, d); + break; + + case 0xd008: + arkanoid_d008_w(0, d); + break; + + case 0xd010: // watchdog + break; + + case 0xd018: // arkanoid_z80_mcu_w + arkanoid_bootleg_d018_w(0, d); + break; + } +} + + +//-------------------------------------------------------------------------------- +// Initilizing functions + + +static void arkanoid_palette_init() +{ + int i; + + for (i = 0; i < 0x200; i++) + { + int bit0,bit1,bit2,bit3,r,g,b; + + // red component + bit0 = (Prom[i + 0x000] >> 0) & 0x01; + bit1 = (Prom[i + 0x000] >> 1) & 0x01; + bit2 = (Prom[i + 0x000] >> 2) & 0x01; + bit3 = (Prom[i + 0x000] >> 3) & 0x01; + r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + // green component + bit0 = (Prom[i + 0x200] >> 0) & 0x01; + bit1 = (Prom[i + 0x200] >> 1) & 0x01; + bit2 = (Prom[i + 0x200] >> 2) & 0x01; + bit3 = (Prom[i + 0x200] >> 3) & 0x01; + g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + // blue component + bit0 = (Prom[i + 0x400] >> 0) & 0x01; + bit1 = (Prom[i + 0x400] >> 1) & 0x01; + bit2 = (Prom[i + 0x400] >> 2) & 0x01; + bit3 = (Prom[i + 0x400] >> 3) & 0x01; + b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + Palette[i] = (r << 16) | (g << 8) | b; + } +} + +static int GetRoms() +{ + char* pRomName; + struct BurnRomInfo ri; + unsigned char *RomLoad = Rom; + unsigned char *McuLoad = Mcu; + unsigned char *GfxLoad = Gfx; + unsigned char *PromLoad = Prom; + + for (int i = 0; !BurnDrvGetRomName(&pRomName, i, 0); i++) { + + BurnDrvGetRomInfo(&ri, i); + + if ((ri.nType & 7) == 1) { + if (BurnLoadRom(RomLoad, i, 1)) return 1; + RomLoad += ri.nLen; + + continue; + } + + if ((ri.nType & 7) == 2) { + if (BurnLoadRom(McuLoad, i, 1)) return 1; + McuLoad += ri.nLen; + + continue; + } + + if ((ri.nType & 7) == 3) { + if (BurnLoadRom(GfxLoad, i, 1)) return 1; + GfxLoad += ri.nLen; + + continue; + } + + if ((ri.nType & 7) == 4) { + if (BurnLoadRom(PromLoad, i, 1)) return 1; + PromLoad += ri.nLen; + + continue; + } + } + + // Convert graphics (combine bitplanes) + { + unsigned char a, b, c; + unsigned char *tmp = (unsigned char*)malloc(0x40000); + for (int i = 0; i < 0x40000; i++) + { + a = (Gfx[(i >> 3) + 0x00000] >> (i & 7)) & 1; + b = (Gfx[(i >> 3) + 0x08000] >> (i & 7)) & 1; + c = (Gfx[(i >> 3) + 0x10000] >> (i & 7)) & 1; + + tmp[i] = (c << 2) | (b << 1) | a; + } + + memcpy (Gfx, tmp, 0x40000); + free (tmp); + } + + return 0; +} + +static int DrvDoReset() +{ + DrvReset = 0; + memset (Rom + 0xc000, 0, 0x0400); + memset (Rom + 0xe000, 0, 0x1000); + + nAnalogAxis[0] = nAnalogAxis[1] = 0; + palettebank = 0; + gfxbank = 0; + arkanoid_paddle_select = 0; + arkanoid_paddle_value = 0; + + ZetOpen(0); + ZetReset(); + ZetClose(); + + AY8910Reset(0); + + return 0; +} + + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x10000 + 0x40000 + 0x800 + 0x600 + 0x800); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short *)malloc (nBurnSoundLen * 3 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + Rom = Mem + 0x00000; + Gfx = Mem + 0x10000; + Mcu = Mem + 0x50000; + Prom = Mem + 0x50800; + Palette = (int*)(Mem + 0x50e00); + + if (GetRoms()) return 1; + + arkanoid_palette_init(); + + ZetInit(1); + ZetOpen(0); + ZetSetReadHandler(arkanoid_read_byte); + ZetSetWriteHandler(arkanoid_write_byte); + ZetMapArea(0x0000, 0xbfff, 0, Rom + 0x0000); + ZetMapArea(0x0000, 0xbfff, 2, Rom + 0x0000); + ZetMapArea(0xc000, 0xc7ff, 0, Rom + 0xc000); + ZetMapArea(0xc000, 0xc7ff, 1, Rom + 0xc000); + ZetMapArea(0xc000, 0xc7ff, 2, Rom + 0xc000); + ZetMapArea(0xe000, 0xefff, 0, Rom + 0xe000); + ZetMapArea(0xe000, 0xefff, 1, Rom + 0xe000); + ZetMapArea(0xe000, 0xefff, 2, Rom + 0xe000); + ZetMapArea(0xf000, 0xffff, 2, Rom + 0xf000); + ZetMemEnd(); + ZetClose(); + +// MDRV_CPU_ADD_TAG("mcu", M68705, 3000000/M68705_CLOCK_DIVIDER) // 3 Mhz + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + AY8910Init(0, 1500000, nBurnSoundRate, &ay8910_read_port_5, &ay8910_read_port_4, NULL, NULL); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + AY8910Exit(0); + + free (Mem); + free (pFMBuffer); + + tetrsark = 0; + + return 0; +} + + +//-------------------------------------------------------------------------------- +// Drawing routine + + +static inline void draw_tile(int sy, int sx, int num, int color, int transp) +{ + unsigned char *src = Gfx + num; + + for (int x = sx + 7; x >= sx; x--) + { + for (int y = sy + 7; y >= sy; y--, src++) + { + if (!src[0] && transp) continue; + if (y > 255 || y < 0 || x > 239 || x < 16) continue; + + int pxl = Palette[color | src[0]]; + + PutPix(pBurnDraw + ((y << 8) + x) * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } +} + +static int DrvDraw() +{ + unsigned char *vram = Rom + 0xe000; + unsigned char *sram = Rom + 0xe800; + + // draw background + for (int offs = 0; offs < 0x800; offs += 2) + { + int num = vram[offs + 1] + ((vram[offs] & 0x07) << 8) + 2048 * gfxbank; + int color = ((vram[offs] & 0xf8) >> 3) + 32 * palettebank; + + int sy = (((offs >> 1) & 0x1f) << 3); + int sx = (((offs >> 6) & 0x1f) << 3) ^ 0xf8; + + draw_tile(sy, sx, num << 6, color << 3, 0); + } + + // draw foreground + for (int offs = 0; offs < 0x3f; offs += 4) + { + int num = (sram[offs + 3] + ((sram[offs + 2] & 0x03) << 8) + 1024 * gfxbank) << 1; + int color = ((sram[offs + 2] & 0xf8) >> 3) + 32 * palettebank; + + int sy = sram[offs]; + int sx = sram[offs + 1]; + + draw_tile(sy, sx + 0, (num | 1) << 6, color << 3, 1); + draw_tile(sy, sx + 8, (num | 0) << 6, color << 3, 1); + } + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) DrvDoReset(); + + int nSoundBufferPos = 0; + + ZetOpen(0); + ZetRun(6000000 / 60); + ZetRaiseIrq(0xff); + ZetClose(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) DrvDraw(); + + return 0; +} + + +//-------------------------------------------------------------------------------- +// Savestates + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0xc000; + ba.nLen = 0x0800; + ba.szName = "Main Ram"; + BurnAcb(&ba); + + ba.Data = Rom + 0xe000; + ba.nLen = 0x1000; + ba.szName = "Video Ram"; + BurnAcb(&ba); + + ZetScan(nAction); // Scan Z80 + AY8910Scan(nAction, pnMin); // Scan AY8910 + + // Scan critical driver variables + SCAN_VAR(nAnalogAxis[0]); + SCAN_VAR(nAnalogAxis[1]); + SCAN_VAR(arkanoid_bootleg_cmd); + SCAN_VAR(palettebank); + SCAN_VAR(gfxbank); + SCAN_VAR(arkanoid_paddle_select); + SCAN_VAR(arkanoid_paddle_value); + } + + return 0; +} + + +//-------------------------------------------------------------------------------- +// Game drivers + + +// Arkanoid (World) + +static struct BurnRomInfo arkanoidRomDesc[] = { + { "a75-01-1.rom", 0x8000, 0x5bcda3b0, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "a75-11.rom", 0x8000, 0xeafd7191, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "arkanoid.uc", 0x0800, 0x515d77b6, 2 | BRF_ESS | BRF_PRG }, // 2 M68705 MCU + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 3 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 4 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 5 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 6 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 7 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 8 +}; + +STD_ROM_PICK(arkanoid); +STD_ROM_FN(arkanoid); + +struct BurnDriver BurnDrvarkanoid = { + "arkanoid", NULL, NULL, "1986", + "Arkanoid (World)\0", "Unsupported MCU", "Taito Corporation Japan", "Arkanoid", + NULL, NULL, NULL, NULL, + 0, 1, HARDWARE_MISC_PRE90S, + NULL, arkanoidRomInfo, arkanoidRomName, DrvInputInfo, arkanoidDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Arkanoid (US) + +static struct BurnRomInfo arknoiduRomDesc[] = { + { "a75-19.bin", 0x8000, 0xd3ad37d7, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "a75-18.bin", 0x8000, 0xcdc08301, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "arknoidu.uc", 0x0800, 0xde518e47, 2 | BRF_ESS | BRF_PRG }, // 2 M68705 MCU + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 3 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 4 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 5 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 6 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 7 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 8 +}; + +STD_ROM_PICK(arknoidu); +STD_ROM_FN(arknoidu); + +struct BurnDriverD BurnDrvarknoidu = { + "arknoidu", "arkanoid", NULL, "1986", + "Arkanoid (US)\0", "Unsupported MCU", "Taito America Corporation (Romstar license)", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_CLONE, 1, HARDWARE_MISC_PRE90S, + NULL, arknoiduRomInfo, arknoiduRomName, DrvInputInfo, arkanoidDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Arkanoid (US, older) + +static struct BurnRomInfo arknoiuoRomDesc[] = { + { "a75-01-1.rom", 0x8000, 0x5bcda3b0, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "a75-10.rom", 0x8000, 0xa1769e15, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "arkanoid.uc", 0x0800, 0x515d77b6, 2 | BRF_ESS | BRF_PRG }, // 2 M68705 MCU + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 3 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 4 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 5 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 6 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 7 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 8 +}; + +STD_ROM_PICK(arknoiuo); +STD_ROM_FN(arknoiuo); + +struct BurnDriverD BurnDrvarknoiuo = { + "arknoiuo", "arkanoid", NULL, "1986", + "Arkanoid (US, older)\0", "Unsupported MCU", "Taito America Corporation (Romstar license)", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_CLONE, 1, HARDWARE_MISC_PRE90S, + NULL, arknoiuoRomInfo, arknoiuoRomName, DrvInputInfo, arkanoidDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Tournament Arkanoid (US) + +static struct BurnRomInfo arkatourRomDesc[] = { + { "t_ark1.bin", 0x8000, 0xe3b8faf5, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "t_ark2.bin", 0x8000, 0x326aca4d, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "arkatour.uc", 0x0800, 0xd3249559, 2 | BRF_ESS | BRF_PRG }, // 2 M68705 MCU + + { "t_ark3.bin", 0x8000, 0x5ddea3cf, 3 | BRF_GRA }, // 3 Graphics + { "t_ark4.bin", 0x8000, 0x5fcf2e85, 3 | BRF_GRA }, // 4 + { "t_ark5.bin", 0x8000, 0x7b76b192, 3 | BRF_GRA }, // 5 + + { "07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 6 Color Proms + { "08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 7 + { "09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 8 +}; + +STD_ROM_PICK(arkatour); +STD_ROM_FN(arkatour); + +struct BurnDriverD BurnDrvarkatour = { + "arkatour", "arkanoid", NULL, "1987", + "Tournament Arkanoid (US)\0", "Unsupported MCU", "Taito America Corporation (Romstar license)", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_CLONE, 1, HARDWARE_MISC_PRE90S, + NULL, arkatourRomInfo, arkatourRomName, DrvInputInfo, arkanoidDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Arkanoid (Japan) + +static struct BurnRomInfo arknoidjRomDesc[] = { + { "a75-21.rom", 0x8000, 0xbf0455fc, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "a75-22.rom", 0x8000, 0x3a2688d3, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "arknoidj.uc", 0x0800, 0x0a4abef6, 2 | BRF_ESS | BRF_PRG }, // 2 M68705 MCU + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 3 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 4 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 5 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 6 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 7 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 8 +}; + +STD_ROM_PICK(arknoidj); +STD_ROM_FN(arknoidj); + +struct BurnDriverD BurnDrvarknoidj = { + "arknoidj", "arkanoid", NULL, "1986", + "Arkanoid (Japan)\0", "Unsupported MCU", "Taito Corporation", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_CLONE, 1, HARDWARE_MISC_PRE90S, + NULL, arknoidjRomInfo, arknoidjRomName, DrvInputInfo, arknoidjDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Arkanoid (bootleg with MCU) + +static struct BurnRomInfo arkmcublRomDesc[] = { + { "e1.6d", 0x8000, 0xdd4f2b72, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "e2.6f", 0x8000, 0xbbc33ceb, 1 | BRF_ESS | BRF_PRG }, // 1 + + // MCU from the World early version ('arkanoid'), so the game is playable + { "arkmcubl.uc", 0x0800, 0x515d77b6, 2 | BRF_ESS | BRF_PRG }, // 2 M68705 MCU + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 3 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 4 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 5 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 6 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 7 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 8 + + // What is this MCU supposed to do? + { "68705p3.6i", 0x0800, 0x389a8cfb, 0 | BRF_ESS | BRF_PRG }, // 9 Another MCU? +}; + +STD_ROM_PICK(arkmcubl); +STD_ROM_FN(arkmcubl); + +struct BurnDriverD BurnDrvarkmcubl = { + "arkmcubl", "arkanoid", NULL, "1986", + "Arkanoid (bootleg with MCU)\0", "Unsupported MCU", "bootleg", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_CLONE | BDF_BOOTLEG, 1, HARDWARE_MISC_PRE90S, + NULL, arkmcublRomInfo, arkmcublRomName, DrvInputInfo, arknoidjDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Arkanoid Arkanoid (bootleg with MCU, harder) + +static struct BurnRomInfo ark1ballRomDesc[] = { + { "a-1.7d", 0x8000, 0xdd4f2b72, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "2palline.7f", 0x8000, 0xed6b62ab, 1 | BRF_ESS | BRF_PRG }, // 1 + + // MCU from the World early version ('arkanoid'), so the game is playable + { "ark1ball.uc", 0x0800, 0x515d77b6, 2 | BRF_ESS | BRF_PRG }, // 2 M68705 MCU + + { "a-3.3a", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 3 Graphics + { "a-4.3d", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 4 + { "a-5.3f", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 5 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 6 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 7 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 8 +}; + +STD_ROM_PICK(ark1ball); +STD_ROM_FN(ark1ball); + +struct BurnDriverD BurnDrvark1ball = { + "ark1ball", "arkanoid", NULL, "1986", + "Arkanoid (bootleg with MCU, harder)\0", "Unsupported MCU", "bootleg", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_CLONE | BDF_BOOTLEG, 1, HARDWARE_MISC_PRE90S, + NULL, ark1ballRomInfo, ark1ballRomName, DrvInputInfo, ark1ballDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Arkanoid (Game Corporation bootleg, set 1) + +static struct BurnRomInfo arkangcRomDesc[] = { + { "arkgc.1", 0x8000, 0xc54232e6, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "arkgc.2", 0x8000, 0x9f0d4754, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 2 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 3 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 4 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 5 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 6 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 7 +}; + +STD_ROM_PICK(arkangc); +STD_ROM_FN(arkangc); + +static int arkangcInit() +{ + arkanoid_bootleg_id = ARKANGC; + + return DrvInit(); +} + +struct BurnDriver BurnDrvarkangc = { + "arkangc", "arkanoid", NULL, "1986", + "Arkanoid (Game Corporation b`ootleg, set 1)\0", NULL, "bootleg", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 1, HARDWARE_MISC_PRE90S, + NULL, arkangcRomInfo, arkangcRomName, DrvInputInfo, arkangcDIPInfo, + arkangcInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Arkanoid (Game Corporation bootleg, set 2) + +static struct BurnRomInfo arkangc2RomDesc[] = { + { "1.81", 0x8000, 0xbd6eb996, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "2.82", 0x8000, 0x29dbe452, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 2 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 3 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 4 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 5 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 6 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 7 +}; + +STD_ROM_PICK(arkangc2); +STD_ROM_FN(arkangc2); + +static int arkangc2Init() +{ + arkanoid_bootleg_id = ARKANGC2; + + return DrvInit(); +} + +struct BurnDriver BurnDrvarkangc2 = { + "arkangc2", "arkanoid", NULL, "1986", + "Arkanoid (Game Corporation bootleg, set 2)\0", NULL, "bootleg", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 1, HARDWARE_MISC_PRE90S, + NULL, arkangc2RomInfo, arkangc2RomName, DrvInputInfo, arkangc2DIPInfo, + arkangc2Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Block (Game Corporation bootleg, set 1) + +static struct BurnRomInfo arkblockRomDesc[] = { + { "ark-6.bin", 0x8000, 0x0be015de, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "arkgc.2", 0x8000, 0x9f0d4754, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 2 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 3 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 4 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 5 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 6 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 7 +}; + +STD_ROM_PICK(arkblock); +STD_ROM_FN(arkblock); + +static int arkblockInit() +{ + arkanoid_bootleg_id = ARKBLOCK; + + return DrvInit(); +} + +struct BurnDriver BurnDrvarkblock = { + "arkblock", "arkanoid", NULL, "1986", + "Block (Game Corporation bootleg, set 1)\0", NULL, "bootleg", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 1, HARDWARE_MISC_PRE90S, + NULL, arkblockRomInfo, arkblockRomName, DrvInputInfo, arkangcDIPInfo, + arkblockInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Block (Game Corporation bootleg, set 2) + +static struct BurnRomInfo arkbloc2RomDesc[] = { + { "block01.bin", 0x8000, 0x5be667e1, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "block02.bin", 0x8000, 0x4f883ef1, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 2 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 3 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 4 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 5 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 6 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 7 +}; + +STD_ROM_PICK(arkbloc2); +STD_ROM_FN(arkbloc2); + +static int arkbloc2Init() +{ + arkanoid_bootleg_id = ARKBLOC2; + + return DrvInit(); +} + +struct BurnDriver BurnDrvarkbloc2 = { + "arkbloc2", "arkanoid", NULL, "1986", + "Block (Game Corporation bootleg, set 2)\0", NULL, "bootleg", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 1, HARDWARE_MISC_PRE90S, + NULL, arkbloc2RomInfo, arkbloc2RomName, DrvInputInfo, arkangcDIPInfo, + arkbloc2Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Arkanoid (bootleg on Block hardware) + +static struct BurnRomInfo arkgcblRomDesc[] = { + { "arkanunk.1", 0x8000, 0xb0f73900, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "arkanunk.2", 0x8000, 0x9827f297, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 2 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 3 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 4 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 5 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 6 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 7 +}; + +STD_ROM_PICK(arkgcbl); +STD_ROM_FN(arkgcbl); + +static int arkgcblInit() +{ + arkanoid_bootleg_id = ARKGCBL; + + return DrvInit(); +} + +struct BurnDriver BurnDrvarkgcbl = { + "arkgcbl", "arkanoid", NULL, "1986", + "Arkanoid (bootleg on Block hardware)\0", NULL, "bootleg", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 1, HARDWARE_MISC_PRE90S, + NULL, arkgcblRomInfo, arkgcblRomName, DrvInputInfo, arkgcblDIPInfo, + arkgcblInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Paddle 2 (bootleg on Block hardware) + +static struct BurnRomInfo paddle2RomDesc[] = { + { "paddle2.16", 0x8000, 0xa286333c, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "paddle2.17", 0x8000, 0x04c2acb5, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "a75-03.rom", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 2 Graphics + { "a75-04.rom", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 3 + { "a75-05.rom", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 4 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 5 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 6 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 7 +}; + +STD_ROM_PICK(paddle2); +STD_ROM_FN(paddle2); + +static int paddle2Init() +{ + arkanoid_bootleg_id = PADDLE2; + + return DrvInit(); +} + +struct BurnDriver BurnDrvpaddle2 = { + "paddle2", "arkanoid", NULL, "1986", + "Paddle 2 (bootleg on Block hardware)\0", NULL, "bootleg", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 1, HARDWARE_MISC_PRE90S, + NULL, paddle2RomInfo, paddle2RomName, DrvInputInfo, paddle2DIPInfo, + paddle2Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Arkanoid (Tayto bootleg) + +static struct BurnRomInfo arkataytRomDesc[] = { + { "ic81-v.3f", 0x8000, 0x154e2c6f, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "ic82-w.5f", 0x8000, 0x4fa8cefa, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "1-ic33.2c", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 2 Graphics + { "2-ic34.3c", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 3 + { "3-ic35.5c", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 4 + + { "ic73.11e", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 5 Color Proms + { "ic74.12e", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 6 + { "ic75.13e", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 7 +}; + +STD_ROM_PICK(arkatayt); +STD_ROM_FN(arkatayt); + +struct BurnDriver BurnDrvarkatayt = { + "arkatayt", "arkanoid", NULL, "1986", + "Arkanoid (Tayto bootleg)\0", NULL, "bootleg", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 1, HARDWARE_MISC_PRE90S, + NULL, arkataytRomInfo, arkataytRomName, DrvInputInfo, arknoidjDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Arkanoid (Tayto bootleg, harder) + +static struct BurnRomInfo arktayt2RomDesc[] = { + { "ic81.3f", 0x8000, 0x6e0a2b6f, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "ic82.5f", 0x8000, 0x5a97dd56, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "1-ic33.2c", 0x8000, 0x038b74ba, 3 | BRF_GRA }, // 2 Graphics + { "2-ic34.3c", 0x8000, 0x71fae199, 3 | BRF_GRA }, // 3 + { "3-ic35.5c", 0x8000, 0xc76374e2, 3 | BRF_GRA }, // 4 + + { "ic73.11e", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 5 Color Proms + { "ic74.12e", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 6 + { "ic75.13e", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 7 +}; + +STD_ROM_PICK(arktayt2); +STD_ROM_FN(arktayt2); + +struct BurnDriver BurnDrvarktayt2 = { + "arktayt2", "arkanoid", NULL, "1986", + "Arkanoid (Tayto bootleg, harder)\0", NULL, "bootleg", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 1, HARDWARE_MISC_PRE90S, + NULL, arktayt2RomInfo, arktayt2RomName, DrvInputInfo, arktayt2DIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Tetris (D.R. Korea) + +static struct BurnRomInfo tetrsarkRomDesc[] = { + { "ic17.1", 0x8000, 0x1a505eda, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "ic16.2", 0x8000, 0x157bc4df, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "ic64.3", 0x8000, 0xc3e9b290, 3 | BRF_GRA }, // 2 Graphics + { "ic63.4", 0x8000, 0xde9a368f, 3 | BRF_GRA }, // 3 + { "ic62.5", 0x8000, 0xc8e80a00, 3 | BRF_GRA }, // 4 + + { "a75-07.bpr", 0x0200, 0x0af8b289, 4 | BRF_GRA }, // 5 Color Proms + { "a75-08.bpr", 0x0200, 0xabb002fb, 4 | BRF_GRA }, // 6 + { "a75-09.bpr", 0x0200, 0xa7c6c277, 4 | BRF_GRA }, // 7 +}; + +STD_ROM_PICK(tetrsark); +STD_ROM_FN(tetrsark); + +static int tetrsarkInit() +{ + tetrsark = 1; + + int nRet = DrvInit(); + + for (int i = 0; i < 0x8000; i++) + { + Rom[i] ^= 0x94; + } + + return nRet; +} + +struct BurnDriverD BurnDrvtetrsark = { + "tetrsark", NULL, NULL, "198?", + "Tetris (D.R. Korea)\0", "Wrong colors", "D.R. Korea", "Arkanoid", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 1, HARDWARE_MISC_PRE90S, + NULL, tetrsarkRomInfo, tetrsarkRomName, tetrsarkInputInfo, tetrsarkDIPInfo, + tetrsarkInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + diff --git a/src/burn/misc/pre90s/d_bankp.cpp b/src/burn/misc/pre90s/d_bankp.cpp new file mode 100644 index 0000000..2a71e80 --- /dev/null +++ b/src/burn/misc/pre90s/d_bankp.cpp @@ -0,0 +1,609 @@ +// FB Alpha Bank Panic Driver Module +// Based on MAME driver by Nicola Salmoria + +#include "tiles_generic.h" +#include "sn76496.h" + +static unsigned char *Mem, *Rom, *Gfx0, *Gfx1, *Prom; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvJoy3[8], DrvReset, DrvDips; +static int *Palette; + +static unsigned char scroll_x, priority, flipscreen, interrupt_enable; + +static struct BurnInputInfo bankpInputList[] = { + {"Coin 1" , BIT_DIGITAL , DrvJoy1 + 5, "p1 coin" }, + {"Coin 2" , BIT_DIGITAL , DrvJoy1 + 6, "p2 coin" }, + {"Coin 3" , BIT_DIGITAL , DrvJoy1 + 6, "p3 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy2 + 5, "p1 start" }, + {"P2 Start" , BIT_DIGITAL , DrvJoy2 + 6, "p2 start" }, + + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 3, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 1, "p1 right" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 7, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 2"}, + {"P1 Button 3" , BIT_DIGITAL , DrvJoy3 + 0, "p1 fire 3"}, + + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 3, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 1, "p2 right" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 7, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 2"}, + {"P2 Button 3" , BIT_DIGITAL , DrvJoy3 + 1, "p2 fire 3"}, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, &DrvDips, "dip" }, +}; + +STDINPUTINFO(bankp); + +static struct BurnInputInfo combhInputList[] = { + {"Coin 1" , BIT_DIGITAL , DrvJoy1 + 5, "p1 coin" }, + {"Coin 2" , BIT_DIGITAL , DrvJoy1 + 6, "p2 coin" }, + {"Coin 3" , BIT_DIGITAL , DrvJoy1 + 6, "p3 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy2 + 5, "p1 start" }, + {"P2 Start" , BIT_DIGITAL , DrvJoy2 + 6, "p2 start" }, + + {"P1 Up" , BIT_DIGITAL , DrvJoy1 + 0, "p1 up" }, + {"P1 Down" , BIT_DIGITAL , DrvJoy1 + 2, "p1 down" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 7, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 2"}, + {"P1 Button 3" , BIT_DIGITAL , DrvJoy3 + 0, "p1 fire 3"}, + + {"P2 Up" , BIT_DIGITAL , DrvJoy2 + 0, "p2 up" }, + {"P2 Down" , BIT_DIGITAL , DrvJoy2 + 2, "p2 down" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 7, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 2"}, + {"P2 Button 3" , BIT_DIGITAL , DrvJoy3 + 1, "p2 fire 3"}, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, &DrvDips, "dip" }, + +}; + +STDINPUTINFO(combh); + +static struct BurnDIPInfo bankpDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0x41, NULL }, + + {0 , 0xfe, 0 , 4 , "Coin A/B" }, + {0x10, 0x01, 0x03, 0x03, "3C 1C" }, + {0x10, 0x01, 0x03, 0x02, "2C 1C" }, + {0x10, 0x01, 0x03, 0x01, "1C 1C" }, + {0x10, 0x01, 0x03, 0x00, "1C 2C" }, + + {0 , 0xfe, 0 , 2 , "Coin C" }, + {0x10, 0x01, 0x04, 0x04, "2C 1C" }, + {0x10, 0x01, 0x04, 0x00, "1C 1C" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x10, 0x01, 0x08, 0x00, "3" }, + {0x10, 0x01, 0x08, 0x08, "4" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x10, 0x01, 0x10, 0x00, "70K 200K 500K..." }, + {0x10, 0x01, 0x10, 0x10, "100K 400K 800K..." }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x10, 0x01, 0x20, 0x00, "Easy" }, + {0x10, 0x01, 0x20, 0x20, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x10, 0x01, 0x40, 0x00, "Off" }, + {0x10, 0x01, 0x40, 0x40, "On" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x80, 0x80, "Upright" }, + {0x10, 0x01, 0x80, 0x00, "Cocktail" }, +}; + +STDDIPINFO(bankp); + +static struct BurnDIPInfo combhDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0x40, NULL }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x10, 0x01, 0x01, 0x00, "Off" }, + {0x10, 0x01, 0x01, 0x01, "On" }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x10, 0x01, 0x06, 0x06, "2C 1C" }, + {0x10, 0x01, 0x06, 0x00, "1C 1C" }, + {0x10, 0x01, 0x06, 0x02, "1C 2C" }, + {0x10, 0x01, 0x06, 0x04, "1C 3C" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x10, 0x01, 0x08, 0x00, "3" }, + {0x10, 0x01, 0x08, 0x08, "4" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x10, 0x10, "Upright" }, + {0x10, 0x01, 0x10, 0x00, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x10, 0x01, 0x40, 0x00, "Easy" }, + {0x10, 0x01, 0x40, 0x40, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Fuel" }, + {0x10, 0x01, 0x80, 0x00, "120 Units" }, + {0x10, 0x01, 0x80, 0x80, "90 Units" }, +}; + +STDDIPINFO(combh); + +unsigned char __fastcall bankp_in(unsigned short address) +{ + unsigned char ret = 0; + + switch (address & 0xff) + { + case 0x00: + { + for (int i = 0; i < 8; i++) ret |= DrvJoy1[i] << i; + + // limit controls to 2-way + if ((ret & 0x05) == 0x05) ret &= 0xfa; + if ((ret & 0x0a) == 0x0a) ret &= 0xf5; + + return ret; + } + + case 0x01: + { + for (int i = 0; i < 8; i++) ret |= DrvJoy2[i] << i; + + // limit controls to 2-way + if ((ret & 0x05) == 0x05) ret &= 0xfa; + if ((ret & 0x0a) == 0x0a) ret &= 0xf5; + + return ret; + } + + case 0x02: + { + for (int i = 0; i < 8; i++) ret |= DrvJoy3[i] << i; + + return ret; + } + + case 0x04: + return DrvDips; + } + + return 0; +} + +void __fastcall bankp_out(unsigned short address, unsigned char data) +{ + switch (address & 0xff) + { + case 0x00: + SN76496Write(0, data); + break; + + case 0x01: + SN76496Write(1, data); + break; + + case 0x02: + SN76496Write(2, data); + break; + + case 0x05: + scroll_x = data; + break; + + case 0x07: + { + priority = data & 0x03; + + interrupt_enable = (data >> 4) & 1; + + flipscreen = data & 0x20; + } + break; + } +} + +static int DrvDoReset() +{ + DrvReset = 0; + + memset (Mem + 0xe000, 0, 0x2000); + + ZetOpen(0); + ZetReset(); + ZetClose(); + + scroll_x = 0, priority = 0, flipscreen = 0; + interrupt_enable = 0; + + return 0; +} + +static int bankp_palette_init() +{ + int i; + + unsigned int t_pal[32]; + unsigned char *color_prom = Prom; + + for (i = 0;i < 32;i++) + { + int bit0,bit1,bit2,r,g,b; + + bit0 = (*color_prom >> 0) & 0x01; + bit1 = (*color_prom >> 1) & 0x01; + bit2 = (*color_prom >> 2) & 0x01; + r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = (*color_prom >> 3) & 0x01; + bit1 = (*color_prom >> 4) & 0x01; + bit2 = (*color_prom >> 5) & 0x01; + g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = 0; + bit1 = (*color_prom >> 6) & 0x01; + bit2 = (*color_prom >> 7) & 0x01; + b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + t_pal[i] = (r << 16) | (g << 8) | b; + + color_prom++; + } + + for (i = 0;i < 32 * 4;i++) { + Palette[i] = t_pal[*color_prom & 0x0f]; + color_prom++; + } + + color_prom += 128; + + for (i = 0;i < 16 * 8;i++) { + Palette[i + 0x80] = t_pal[*color_prom & 0x0f]; + color_prom++; + } + + return 0; +} + +static int bankp_gfx_decode() +{ + unsigned char *tmp = (unsigned char*)malloc(0x10000); + if (tmp == NULL) { + return 1; + } + + memcpy (tmp, Gfx0, 0x10000); + + static int Char1PlaneOffsets[2] = { 0x00, 0x04 }; + static int Char2PlaneOffsets[3] = { 0x00, 0x20000, 0x40000 }; + static int Char1XOffsets[8] = { 0x43, 0x42, 0x41, 0x40, 0x03, 0x02, 0x01, 0x00 }; + static int Char2XOffsets[8] = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; + static int CharYOffsets[8] = { 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 }; + + GfxDecode(0x400, 2, 8, 8, Char1PlaneOffsets, Char1XOffsets, CharYOffsets, 0x080, tmp, Gfx0); + + memcpy (tmp, Gfx1, 0x10000); + + GfxDecode(0x800, 3, 8, 8, Char2PlaneOffsets, Char2XOffsets, CharYOffsets, 0x040, tmp, Gfx1); + + for (int i = 0; i < 0x20000; i++) { + Gfx1[i] |= 0x80; + } + + free (tmp); + + return 0; +} + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x10000 + 0x10000 + 0x20000 + 0x300 + 0x800); + if (Mem == NULL) { + return 1; + } + + Rom = Mem + 0x00000; + Gfx0 = Mem + 0x10000; + Gfx1 = Mem + 0x20000; + Prom = Mem + 0x40000; + Palette = (int*)(Mem + 0x40200); + + { + for (int i = 0; i < 4; i++) + if (BurnLoadRom(Rom + i * 0x4000, i + 0, 1)) return 1; + + if (BurnLoadRom(Gfx0 + 0x0000, 4, 1)) return 1; + if (BurnLoadRom(Gfx0 + 0x2000, 5, 1)) return 1; + + for (int i = 0; i < 6; i++) + if (BurnLoadRom(Gfx1 + i * 0x2000, i + 6, 1)) return 1; + + if (BurnLoadRom(Prom + 0x0000, 12, 1)) return 1; + if (BurnLoadRom(Prom + 0x0020, 13, 1)) return 1; + if (BurnLoadRom(Prom + 0x0120, 14, 1)) return 1; + + if (bankp_gfx_decode()) return 1; + bankp_palette_init(); + } + + ZetInit(1); + ZetOpen(0); + ZetSetInHandler(bankp_in); + ZetSetOutHandler(bankp_out); + ZetMapArea(0x0000, 0xdfff, 0, Rom + 0x0000); + ZetMapArea(0x0000, 0xdfff, 2, Rom + 0x0000); + ZetMapArea(0xe000, 0xefff, 0, Rom + 0xe000); + ZetMapArea(0xe000, 0xefff, 1, Rom + 0xe000); + ZetMapArea(0xe000, 0xefff, 2, Rom + 0xe000); + ZetMapArea(0xf000, 0xffff, 0, Rom + 0xf000); + ZetMapArea(0xf000, 0xffff, 1, Rom + 0xf000); + ZetMemEnd(); + ZetClose(); + + SN76489Init(0, 15468000 / 6, 0); + SN76489Init(1, 15468000 / 6, 1); + SN76489Init(2, 15468000 / 6, 1); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + + SN76496Exit(); + + free (Mem); + + scroll_x = priority = flipscreen = interrupt_enable = 0; + + Rom = Gfx0 = Gfx1 = Prom = NULL; + Palette = NULL; + + return 0; +} + + +static inline void bankp_plot_pixel(int x, int y, int color, unsigned char src, int transp) +{ + if (x > 223 || x < 0 || y > 223 || y < 0) return; + + int pxl = Palette[color | src]; + if (transp && !pxl) return; + + PutPix(pBurnDraw + (y * 224 + x) * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); +} + + +static void draw_8x8_tiles(unsigned char *gfx_base, int code, int color, int sx, int sy, int flipx, int flipy, int transp) +{ + unsigned char *src = gfx_base + (code << 6); + + if (flipy) + { + for (int y = sy + 7; y >= sy; y--) + { + if (flipx) + { + for (int x = sx + 7; x >= sx; x--, src++) { + bankp_plot_pixel(x, y, color, *src, transp); + } + } else { + for (int x = sx; x < sx + 8; x++, src++) { + bankp_plot_pixel(x, y, color, *src, transp); + } + } + } + } else { + for (int y = sy; y < sy + 8; y++) + { + if (flipx) + { + for (int x = sx + 7; x >= sx; x--, src++) { + bankp_plot_pixel(x, y, color, *src, transp); + + } + } else { + for (int x = sx; x < sx + 8; x++, src++) { + bankp_plot_pixel(x, y, color, *src, transp); + + } + } + } + } +} + +static void draw_bg_tiles(int prio) +{ + for (int offs = 0; offs < 0x400; offs++) + { + int code, color, flipx, sx, sy; + + code = Rom[0xf800 + offs] | ((Rom[0xfc00 + offs] & 7) << 8); + color = (Rom[0xfc00 + offs] >> 1) & 0x78; + flipx = Rom[0xfc00 + offs] & 0x08; + + if (flipscreen) { + sx = (~offs << 3) & 0xf8; + sy = (~offs >> 2) & 0xf8; + flipx ^= 0x08; + } else { + sx = ( offs << 3) & 0xf8; + sy = ( offs >> 2) & 0xf8; + } + + draw_8x8_tiles(Gfx1, code, color, sx - 24, sy - 16, flipx, flipscreen, prio); + } +} + +static void draw_fg_tiles(int prio) +{ + for (int offs = 0; offs < 0x400; offs++) + { + int code, color, flipx, sx, sy; + + code = Rom[0xf000 + offs] | ((Rom[0xf400 + offs] & 3) << 8); + color = (Rom[0xf400 + offs] >> 1) & 0x7c; + flipx = Rom[0xf400 + offs] & 0x04; + + if (flipscreen) { + sx = ((~offs << 3) - scroll_x) & 0xff; + sy = (~offs >> 2) & 0xf8; + flipx ^= 4; + } else { + sx = (( offs << 3) - scroll_x) & 0xff; + sy = ( offs >> 2) & 0xf8; + } + + draw_8x8_tiles(Gfx0, code, color, sx - 24, sy - 16, flipx, flipscreen, prio); + } +} + +static int DrvDraw() +{ + if (priority & 0x02) + { + draw_fg_tiles(0); + draw_bg_tiles(1); + } else { + draw_bg_tiles(0); + draw_fg_tiles(1); + } + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetOpen(0); + ZetRun(2578000 / 60); + if (interrupt_enable) ZetNmi(); + ZetClose(); + + SN76496Update(0, pBurnSoundOut, nBurnSoundLen); + SN76496Update(1, pBurnSoundOut, nBurnSoundLen); + SN76496Update(2, pBurnSoundOut, nBurnSoundLen); + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0xe000; + ba.nLen = 0x2000; + ba.szName = "All Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + + SCAN_VAR(scroll_x); + SCAN_VAR(priority); + SCAN_VAR(flipscreen); + SCAN_VAR(interrupt_enable); + } + + return 0; +} + +// Bank Panic + +static struct BurnRomInfo bankpRomDesc[] = { + { "epr-6175.7e", 0x4000, 0x044552b8, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "epr-6174.7f", 0x4000, 0xd29b1598, 1 | BRF_ESS | BRF_PRG }, // 1 + { "epr-6173.7h", 0x4000, 0xb8405d38, 1 | BRF_ESS | BRF_PRG }, // 2 + { "epr-6176.7d", 0x2000, 0xc98ac200, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "epr-6165.5l", 0x2000, 0xaef34a93, 2 | BRF_GRA }, // 4 Playfield #1 chars + { "epr-6166.5k", 0x2000, 0xca13cb11, 2 | BRF_GRA }, // 5 + + { "epr-6172.5b", 0x2000, 0xc4c4878b, 3 | BRF_GRA }, // 6 Playfield #2 chars + { "epr-6171.5d", 0x2000, 0xa18165a1, 3 | BRF_GRA }, // 7 + { "epr-6170.5e", 0x2000, 0xb58aa8fa, 3 | BRF_GRA }, // 8 + { "epr-6169.5f", 0x2000, 0x1aa37fce, 3 | BRF_GRA }, // 9 + { "epr-6168.5h", 0x2000, 0x05f3a867, 3 | BRF_GRA }, // 10 + { "epr-6167.5i", 0x2000, 0x3fa337e1, 3 | BRF_GRA }, // 11 + + { "pr-6177.8a", 0x0020, 0xeb70c5ae, 4 | BRF_GRA }, // 12 Palette + { "pr-6178.6f", 0x0100, 0x0acca001, 4 | BRF_GRA }, // 13 Charset #1 lut + { "pr-6179.5a", 0x0100, 0xe53bafdb, 4 | BRF_GRA }, // 14 Charset #2 lut + + { "315-5074.2c.bin", 0x025b, 0x2e57bbba, 0 | BRF_OPT }, // 15 + { "315-5073.pal16l4", 0x0001, 0x00000000, 0 | BRF_OPT | BRF_NODUMP }, // 16 read protected +}; + +STD_ROM_PICK(bankp); +STD_ROM_FN(bankp); + +struct BurnDriver BurnDrvbankp = { + "bankp", NULL, NULL, "1984", + "Bank Panic\0", NULL, "[Sanritsu] Sega", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, bankpRomInfo, bankpRomName, bankpInputInfo, bankpDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 224, 3, 4 +}; + +// Combat Hawk + +static struct BurnRomInfo combhRomDesc[] = { + { "epr-10904.7e", 0x4000, 0x4b106335, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "epr-10905.7f", 0x4000, 0xa76fc390, 1 | BRF_ESS | BRF_PRG }, // 1 + { "epr-10906.7h", 0x4000, 0x16d54885, 1 | BRF_ESS | BRF_PRG }, // 2 + { "epr-10903.7d", 0x2000, 0xb7a59cab, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "epr-10914.5l", 0x2000, 0x7d7a2340, 2 | BRF_GRA }, // 4 Playfield #1 chars + { "epr-10913.5k", 0x2000, 0xd5c1a8ae, 2 | BRF_GRA }, // 5 + + { "epr-10907.5b", 0x2000, 0x08e5eea3, 3 | BRF_GRA }, // 6 Playfield #2 chars + { "epr-10908.5d", 0x2000, 0xd9e413f5, 3 | BRF_GRA }, // 7 + { "epr-10909.5e", 0x2000, 0xfec7962c, 3 | BRF_GRA }, // 8 + { "epr-10910.5f", 0x2000, 0x33db0fa7, 3 | BRF_GRA }, // 9 + { "epr-10911.5h", 0x2000, 0x565d9e6d, 3 | BRF_GRA }, // 10 + { "epr-10912.5i", 0x2000, 0xcbe22738, 3 | BRF_GRA }, // 11 + + { "pr-10900.8a", 0x0020, 0xf95fcd66, 4 | BRF_GRA }, // 12 Palette + { "pr-10901.6f", 0x0100, 0x6fd981c8, 4 | BRF_GRA }, // 13 Charset #1 lut + { "pr-10902.5a", 0x0100, 0x84d6bded, 4 | BRF_GRA }, // 14 Charset #2 lut + + { "315-5074.2c.bin", 0x025b, 0x2e57bbba, 0 | BRF_OPT }, // 15 + { "315-5073.pal16l4", 0x0001, 0x00000000, 0 | BRF_OPT | BRF_NODUMP }, // 16 read protected +}; + +STD_ROM_PICK(combh); +STD_ROM_FN(combh); + +struct BurnDriver BurnDrvcombh = { + "combh", NULL, NULL, "1987", + "Combat Hawk\0", NULL, "Sega / Sanritsu", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, combhRomInfo, combhRomName, combhInputInfo, combhDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 224, 3, 4 +}; + diff --git a/src/burn/misc/pre90s/d_bionicc.cpp b/src/burn/misc/pre90s/d_bionicc.cpp new file mode 100644 index 0000000..0f6291f --- /dev/null +++ b/src/burn/misc/pre90s/d_bionicc.cpp @@ -0,0 +1,937 @@ +// FB Alpha Bionic Commando driver module +// Based on MAME driver by Steven Frew, Phil Stroffolino, and Paul Leaman + +#include "tiles_generic.h" +#include "burn_ym2151.h" + +static unsigned char DrvJoy1[8]; +static unsigned char DrvJoy2[8]; +static unsigned char DrvJoy3[8]; +static unsigned char DrvInputs[3]; +static unsigned char DrvReset; +static unsigned char DrvDips[2]; + +static unsigned char *Mem, *MemEnd; +static unsigned char *AllRam, *RamEnd; +static unsigned char *Drv68KROM; +static unsigned char *Drv68KRAM0; +static unsigned char *DrvTextRAM; +static unsigned char *DrvVidRAM0; +static unsigned char *DrvVidRAM1; +static unsigned char *DrvPalRAM; +static unsigned char *Drv68KRAM1; +static unsigned char *DrvGfxROM0; +static unsigned char *DrvGfxROM1; +static unsigned char *DrvGfxROM2; +static unsigned char *DrvGfxROM3; +static unsigned char *DrvZ80ROM; +static unsigned char *DrvZ80RAM; +static unsigned char *DrvSprBuf; + +static unsigned int *DrvPalette; +static unsigned int *Palette; +static unsigned char DrvRecalc; + + +static unsigned char *soundlatch; + +static int flipscreen; + +static int fg_scroll_x; +static int fg_scroll_y; +static int bg_scroll_x; +static int bg_scroll_y; + +static int fg_enable; +static int bg_enable; + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1" , BIT_DIGITAL , DrvJoy1 + 6, "p1 coin" }, + {"Coin 2" , BIT_DIGITAL , DrvJoy1 + 7, "p2 coin" }, + + {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 5, "p1 start" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy2 + 3, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy2 + 2, "p1 right" }, + {"P1 Down", BIT_DIGITAL , DrvJoy2 + 4, "p1 down", }, + {"P1 Up", BIT_DIGITAL , DrvJoy2 + 5, "p1 up", }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy2 + 1, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy2 + 0, "p1 fire 2"}, + + {"P2 Start" , BIT_DIGITAL , DrvJoy1 + 4, "p2 start" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy3 + 3, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy3 + 2, "p2 right" }, + {"P2 Down", BIT_DIGITAL, DrvJoy3 + 4, "p2 down", }, + {"P2 Up", BIT_DIGITAL, DrvJoy3 + 5, "p2 up", }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy3 + 1, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy3 + 0, "p2 fire 2"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + {0x11, 0xff, 0xff, 0xff, NULL }, + {0x12, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 8 , "Coin_A" }, + {0x11, 0x01, 0x07, 0x00, "4 Coins 1 Credit " }, + {0x11, 0x01, 0x07, 0x01, "3 Coins 1 Credit " }, + {0x11, 0x01, 0x07, 0x02, "2 Coins 1 Credit " }, + {0x11, 0x01, 0x07, 0x07, "1 Coin 1 Credit " }, + {0x11, 0x01, 0x07, 0x06, "1 Coin 2 Credits" }, + {0x11, 0x01, 0x07, 0x05, "1 Coin 3 Credits" }, + {0x11, 0x01, 0x07, 0x04, "1 Coin 4 Credits" }, + {0x11, 0x01, 0x07, 0x03, "1 Coin 6 Credits" }, + + {0 , 0xfe, 0 , 8 , "Coin_B" }, + {0x11, 0x01, 0x38, 0x00, "4 Coins 1 Credit " }, + {0x11, 0x01, 0x38, 0x08, "3 Coins 1 Credit " }, + {0x11, 0x01, 0x38, 0x10, "2 Coins 1 Credit " }, + {0x11, 0x01, 0x38, 0x38, "1 Coin 1 Credit " }, + {0x11, 0x01, 0x38, 0x30, "1 Coin 2 Credits" }, + {0x11, 0x01, 0x38, 0x28, "1 Coin 3 Credits" }, + {0x11, 0x01, 0x38, 0x20, "1 Coin 4 Credits" }, + {0x11, 0x01, 0x38, 0x18, "1 Coin 6 Credits" }, + + {0 , 0xfe, 0 , 2 , "Service Mode" }, + {0x11, 0x01, 0x40, 0x40, "Off" }, + {0x11, 0x01, 0x40, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x11, 0x01, 0x80, 0x80, "Off" }, + {0x11, 0x01, 0x80, 0x00, "On" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x12, 0x01, 0x03, 0x03, "3" }, + {0x12, 0x01, 0x03, 0x02, "4" }, + {0x12, 0x01, 0x03, 0x01, "5" }, + {0x12, 0x01, 0x03, 0x00, "7" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x04, 0x04, "Upright" }, + {0x12, 0x01, 0x04, 0x00, "Cocktail" }, + + {0 , 0xfe, 0 , 4 , "Bonus_Life" }, + {0x12, 0x01, 0x18, 0x18, "20K, 40K, every 60K" }, + {0x12, 0x01, 0x18, 0x10, "30K, 50K, every 70K" }, + {0x12, 0x01, 0x18, 0x08, "20K and 60K only" }, + {0x12, 0x01, 0x18, 0x00, "30K and 70K only" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x12, 0x01, 0x60, 0x40, "Easy" }, + {0x12, 0x01, 0x60, 0x60, "Medium" }, + {0x12, 0x01, 0x60, 0x20, "Hard" }, + {0x12, 0x01, 0x60, 0x00, "Hardest" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x12, 0x01, 0x80, 0x80, "Off" }, + {0x12, 0x01, 0x80, 0x00, "On" }, +}; + +STDDIPINFO(Drv); + +static void bionicc_palette_write(int offset) +{ + offset >>= 1; + + int r, g, b, bright; + int data = *((unsigned short*)(DrvPalRAM + (offset << 1))); + + bright = (data&0x0f); + + r = ((data>>12)&0x0f) * 0x11; + g = ((data>>8 )&0x0f) * 0x11; + b = ((data>>4 )&0x0f) * 0x11; + + if ((bright & 0x08) == 0) + { + r = r * (0x07 + bright) / 0x0e; + g = g * (0x07 + bright) / 0x0e; + b = b * (0x07 + bright) / 0x0e; + } + + Palette[offset] = (r << 16) | (g << 8) | b; + DrvPalette[offset] = BurnHighCol(r, g, b, 0); +} + +void __fastcall bionicc_write_byte(unsigned int address, unsigned char data) +{ + if ((address & 0xfffff800) == 0xff8000) { + address &= 0x7ff; + + DrvPalRAM[address ^ 1] = data; + + bionicc_palette_write(address); + + return; + } + + switch (address) + { + case 0xfe4000: + case 0xfe4001: + flipscreen = data & 0x01; + fg_enable = data & 0x10; + bg_enable = data & 0x20; + return; + } +} + +void __fastcall bionicc_write_word(unsigned int address, unsigned short data) +{ + if ((address & 0xfffff800) == 0xff8000) { + address &= 0x7ff; + + *((unsigned short*)(DrvPalRAM + address)) = data; + + bionicc_palette_write(address); + + return; + } + + switch (address) + { + case 0xfe8010: + fg_scroll_x = data & 0x3ff; + return; + + case 0xfe8012: + fg_scroll_y = data & 0x3ff; + return; + + case 0xfe8014: + bg_scroll_x = data & 0x1ff; + return; + + case 0xfe8016: + bg_scroll_y = data & 0x1ff; + return; + + case 0xfe801a: + unsigned short *inp = (unsigned short*)(Drv68KRAM1 + 0x3ffa); + inp[0] = (DrvInputs[0] >> 4) ^ 0x0f; + inp[1] = DrvInputs[2] ^ 0xff; + inp[2] = DrvInputs[1] ^ 0xff; + return; + } +} + +unsigned char __fastcall bionicc_read_byte(unsigned int address) +{ + switch (address) + { + case 0xfe4000: + return DrvInputs[0]; + + case 0xfe4001: + return 0xff; + + case 0xfe4002: + return DrvDips[0]; + + case 0xfe4003: + return DrvDips[1]; + } + + return 0; +} + +unsigned short __fastcall bionicc_read_word(unsigned int address) +{ + switch (address) + { + case 0xfe4000: + return 0x00ff | (DrvInputs[0] << 8); + + case 0xfe4002: + return DrvDips[0] | (DrvDips[1] << 8); + } + + return 0; +} + +unsigned char __fastcall bionicc_sound_read(unsigned short address) +{ + switch (address) + { + case 0x8001: + return BurnYM2151ReadStatus(); + + case 0xa000: + return *soundlatch; + } + + return 0; +} + +void __fastcall bionicc_sound_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0x8000: + BurnYM2151SelectRegister(data); + return; + + case 0x8001: + BurnYM2151WriteRegister(data); + return; + } +} + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + Drv68KROM = Next; Next += 0x0040000; + DrvZ80ROM = Next; Next += 0x0008000; + + DrvGfxROM0 = Next; Next += 0x0020000; + DrvGfxROM1 = Next; Next += 0x0020000; + DrvGfxROM2 = Next; Next += 0x0080000; + DrvGfxROM3 = Next; Next += 0x0080000; + + DrvPalette = (unsigned int*)Next; Next += 0x00400 * sizeof(int); + + AllRam = Next; + + Drv68KRAM0 = Next; Next += 0x0004000; + Drv68KRAM1 = Next; Next += 0x0004000; + DrvPalRAM = Next; Next += 0x0000800; + DrvTextRAM = Next; Next += 0x0001000; + DrvVidRAM0 = Next; Next += 0x0004000; + DrvVidRAM1 = Next; Next += 0x0004000; + + DrvSprBuf = Next; Next += 0x0000500; + + DrvZ80RAM = Next; Next += 0x0000800; + + Palette = (unsigned int*)Next; Next += 0x00400 * sizeof(int); + + RamEnd = Next; + + MemEnd = Next; + + return 0; +} + +static int DrvDoReset() +{ + DrvReset = 0; + + memset (AllRam, 0, RamEnd - AllRam); + + fg_scroll_x = 0; + fg_scroll_y = 0; + bg_scroll_x = 0; + bg_scroll_y = 0; + + soundlatch = Drv68KRAM1 + 0x3ff8; + flipscreen = 0; + + fg_enable = 0; + bg_enable = 0; + + SekOpen(0); + SekReset(); + SekClose(); + ZetOpen(0); + ZetReset(); + ZetClose(); + + BurnYM2151Reset(); + + return 0; +} + +static int DrvGfxDecode() +{ + unsigned char *tmp = (unsigned char*)malloc(0x40000); + if (tmp == NULL) { + return 1; + } + + static int CharPlanes[2] = { 0x000004, 0x000000 }; + static int Tile0Planes[4] = { 0x040004, 0x040000, 0x000004, 0x000000 }; + static int Tile1Planes[4] = { 0x100004, 0x100000, 0x000004, 0x000000 }; + static int SpriPlanes[4] = { 0x180000, 0x100000, 0x080000, 0x000000 }; + static int CharXOffsets[16] = { 0x000, 0x001, 0x002, 0x003, 0x008, 0x009, 0x00a, 0x00b, + 0x100, 0x101, 0x102, 0x103, 0x108, 0x109, 0x10a, 0x10b }; + static int SpriXOffsets[16] = { 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, + 0x080, 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087 }; + static int CharYOffsets[16] = { 0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, + 0x080, 0x090, 0x0a0, 0x0b0, 0x0c0, 0x0d0, 0x0e0, 0x0f0 }; + static int SpriYOffsets[16] = { 0x000, 0x008, 0x010, 0x018, 0x020, 0x028, 0x030, 0x038, + 0x040, 0x048, 0x050, 0x058, 0x060, 0x068, 0x070, 0x078 }; + + memcpy (tmp, DrvGfxROM0, 0x08000); + + GfxDecode(0x00400, 2, 8, 8, CharPlanes, CharXOffsets, CharYOffsets, 0x080, tmp, DrvGfxROM0); + + memcpy (tmp, DrvGfxROM1, 0x10000); + + GfxDecode(0x00800, 4, 8, 8, Tile0Planes, CharXOffsets, CharYOffsets, 0x080, tmp, DrvGfxROM1); + + memcpy (tmp, DrvGfxROM2, 0x40000); + + GfxDecode(0x00800, 4, 16, 16, Tile1Planes, CharXOffsets, CharYOffsets, 0x200, tmp, DrvGfxROM2); + + memcpy (tmp, DrvGfxROM3, 0x40000); + + GfxDecode(0x00800, 4, 16, 16, SpriPlanes, SpriXOffsets, SpriYOffsets, 0x100, tmp, DrvGfxROM3); + + free (tmp); + + return 0; +} + +static int DrvInit() +{ + int nLen; + + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + { + if (BurnLoadRom(Drv68KROM + 0x00001, 0, 2)) return 1; + if (BurnLoadRom(Drv68KROM + 0x00000, 1, 2)) return 1; + if (BurnLoadRom(Drv68KROM + 0x20001, 2, 2)) return 1; + if (BurnLoadRom(Drv68KROM + 0x20000, 3, 2)) return 1; + + if (BurnLoadRom(DrvZ80ROM, 4, 1)) return 1; + + if (BurnLoadRom(DrvGfxROM0, 5, 1)) return 1; + + if (BurnLoadRom(DrvGfxROM1 + 0x0000, 6, 1)) return 1; + if (BurnLoadRom(DrvGfxROM1 + 0x8000, 7, 1)) return 1; + + for (int i = 0; i < 8; i++) { + if (BurnLoadRom(DrvGfxROM2 + i * 0x8000, i + 8, 1)) return 1; + if (BurnLoadRom(DrvGfxROM3 + i * 0x8000, i + 16, 1)) return 1; + } + + if (DrvGfxDecode()) return 1; + } + + SekInit(0, 0x68000); + SekOpen(0); + SekMapMemory(Drv68KROM, 0x000000, 0x03ffff, SM_ROM); + SekMapMemory(Drv68KRAM0, 0xfe0000, 0xfe3fff, SM_RAM); + SekMapMemory(DrvTextRAM, 0xfec000, 0xfecfff, SM_RAM); + SekMapMemory(DrvVidRAM0, 0xff0000, 0xff3fff, SM_RAM); + SekMapMemory(DrvVidRAM1, 0xff4000, 0xff7fff, SM_RAM); + SekMapMemory(DrvPalRAM, 0xff8000, 0xff87ff, SM_ROM); + SekMapMemory(Drv68KRAM1, 0xffc000, 0xffffff, SM_RAM); + SekSetReadByteHandler(0, bionicc_read_byte); + SekSetReadWordHandler(0, bionicc_read_word); + SekSetWriteByteHandler(0, bionicc_write_byte); + SekSetWriteWordHandler(0, bionicc_write_word); + SekClose(); + + ZetInit(1); + ZetOpen(0); + ZetMapArea(0x0000, 0x7fff, 0, DrvZ80ROM); + ZetMapArea(0x0000, 0x7fff, 2, DrvZ80ROM); + ZetMapArea(0xc000, 0xc7ff, 0, DrvZ80RAM); + ZetMapArea(0xc000, 0xc7ff, 1, DrvZ80RAM); + ZetMapArea(0xc000, 0xc7ff, 2, DrvZ80RAM); + ZetSetWriteHandler(bionicc_sound_write); + ZetSetReadHandler(bionicc_sound_read); + ZetMemEnd(); + ZetClose(); + + BurnYM2151Init(3579545, 100.0); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + BurnYM2151Exit(); + SekExit(); + ZetExit(); + + free (Mem); + + GenericTilesExit(); + + return 0; +} + +static void draw_foreground(int priority) +{ + unsigned short *vidram = (unsigned short*)DrvVidRAM0; + + for (int offs = 0; offs < 0x4000 / 4; offs++) + { + int sx = (offs & 0x3f) << 4; + int sy = (offs >> 6) << 4; + + sx -= fg_scroll_x; + sy -= fg_scroll_y; + + if (sx < -15) sx += 0x400; + if (sy < -15) sy += 0x400; + if (sx < -15 || sx > 255 || sy < 1 || sy > 239) continue; + sy -= 16; + + int attr = vidram[(offs << 1) | 1]; + int code = (vidram[offs << 1] & 0xff) | ((attr & 0x07) << 8); + int color = (attr & 0x18) >> 3; + int flipx = attr & 0x80; + int flipy = attr & 0x40; + int prior = (attr & 0x20) >> 5; + + if ((attr & 0xc0) == 0xc0) { + flipx = 0; + flipy = 0; + prior = 2; + } + + if (prior != priority) continue; + + if (flipy) { + if (flipx) { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 15, 0x100, DrvGfxROM2); + } else { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 15, 0x100, DrvGfxROM2); + } + } else { + if (flipx) { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 15, 0x100, DrvGfxROM2); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 15, 0x100, DrvGfxROM2); + } + } + } +} + +static int DrvDraw() +{ + if (DrvRecalc) { + for (int i = 0; i < 0x400; i++) { + int rgb = Palette[i]; + DrvPalette[i] = BurnHighCol(rgb >> 16, rgb >> 8, rgb, 0); + } + } + + memset (pTransDraw, 0, nScreenHeight * nScreenWidth * 2); + + if (fg_enable) { + draw_foreground(2); + } + + if (bg_enable) + { + unsigned short *vidram = (unsigned short*)DrvVidRAM1; + + for (int offs = 0; offs < 0x4000 / 4; offs++) + { + int sx = (offs & 0x3f) << 3; + int sy = (offs >> 6) << 3; + + sx -= bg_scroll_x; + sy -= bg_scroll_y; + + if (sx < -7) sx += 0x200; + if (sy < -7) sy += 0x200; + if (sy < 9 || sy > 239 || sx < -7 || sx > 255) continue; + sy -= 16; + + int attr = vidram[(offs << 1) | 1]; + int code = (vidram[offs << 1] & 0xff) | ((attr & 0x07) << 8); + int color = (attr & 0x18) >> 3; + int flipx = attr & 0x80; + int flipy = attr & 0x40; + + if (flipy) { + if (flipx) { + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 15, 0x000, DrvGfxROM1); + } else { + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 15, 0x000, DrvGfxROM1); + } + } else { + if (flipx) { + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 15, 0x000, DrvGfxROM1); + } else { + Render8x8Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 15, 0x000, DrvGfxROM1); + } + } + } + } + + if (fg_enable) { + draw_foreground(0); + } + + { + unsigned short *vidram = (unsigned short*)DrvSprBuf; + + for (int offs = (0x500-8)/2; offs >= 0; offs -= 4) + { + int code = vidram[offs] & 0x7ff; + + if (code != 0x7ff) + { + int attr = vidram[offs+1]; + int color = (attr&0x3C)>>2; + int flipx = attr & 0x02; + int sx = (short)vidram[offs+3]; + int sy = (short)vidram[offs+2]; + if(sy>512-16) sy-=512; + + if (sx < -15 || sx > 255 || sy < 1 || sy > 239) continue; + + sy -= 16; + + if (flipx) { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 15, 0x200, DrvGfxROM3); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 15, 0x200, DrvGfxROM3); + } + } + } + } + + if (fg_enable) { + draw_foreground(1); + } + + { + unsigned short *vidram = (unsigned short*)DrvTextRAM; + + for (int offs = 0; offs < 0x800 / 2; offs++) + { + int sx = (offs << 3) & 0xf8; + int sy = (offs >> 2) & 0xf8; + sy -= 16; + if (sy < 0 || sy > 223) continue; + + int attr = vidram[offs + 0x400]; + int code = (vidram[offs] & 0xff) | ((attr & 0xc0) << 2); + int color = attr & 0x3f; + + Render8x8Tile_Mask(pTransDraw, code, sx, sy, color, 2, 3, 0x300, DrvGfxROM0); + } + } + + if (flipscreen) { + int nSize = (nScreenWidth * nScreenHeight) - 1; + for (int i = 0; i < nSize >> 1; i++) { + int n = pTransDraw[i]; + pTransDraw[i] = pTransDraw[nSize - i]; + pTransDraw[nSize - i] = n; + } + } + + BurnTransferCopy(DrvPalette); + + return 0; +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + { + DrvInputs[0] = DrvInputs[1] = DrvInputs[2] = 0xff; + + for (int i = 0; i < 8; i++) { + DrvInputs[0] ^= DrvJoy1[i] << i; + DrvInputs[1] ^= DrvJoy2[i] << i; + DrvInputs[2] ^= DrvJoy3[i] << i; + } + } + + int nSoundBufferPos = 0; + int nInterleave = 8; + int nTotalCycles[2] = { 12000000 / 60, 3579545 / 60 }; + + ZetNewFrame(); + + SekOpen(0); + ZetOpen(0); + + for (int i = 0; i < nInterleave; i++) + { + nTotalCycles[0] -= SekRun(nTotalCycles[0] / (nInterleave - i)); + if (i != (nInterleave - 1)) SekSetIRQLine(4, SEK_IRQSTATUS_AUTO); + + nTotalCycles[1] -= ZetRun(nTotalCycles[1] / (nInterleave - i)); + if ((i & 1) == 1) ZetNmi(); + + if (pBurnSoundOut) { + int nSegmentLength = nBurnSoundLen / nInterleave; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + BurnYM2151Render(pSoundBuf, nSegmentLength); + nSoundBufferPos += nSegmentLength; + } + } + + SekSetIRQLine(2, SEK_IRQSTATUS_AUTO); + + if (pBurnSoundOut) { + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + BurnYM2151Render(pSoundBuf, nSegmentLength); + } + + ZetClose(); + SekClose(); + + if (pBurnDraw) { + DrvDraw(); + } + + // Lag sprites 1 frame + memcpy (DrvSprBuf, Drv68KRAM0 + 0x800, 0x500); + + return 0; +} + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029682; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + ba.Data = AllRam; + ba.nLen = RamEnd - AllRam; + ba.szName = "All RAM"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + SekScan(nAction); + ZetScan(nAction); + + BurnYM2151Scan(nAction); + + SCAN_VAR(fg_scroll_x); + SCAN_VAR(fg_scroll_y); + SCAN_VAR(bg_scroll_x); + SCAN_VAR(bg_scroll_y); + SCAN_VAR(fg_enable); + SCAN_VAR(bg_enable); + SCAN_VAR(flipscreen); + } + + return 0; +} + +// Bionic Commando (Euro) + +static struct BurnRomInfo bioniccRomDesc[] = { + { "tse_02.1a", 0x10000, 0xe4aeefaa, 1 | BRF_PRG | BRF_ESS }, // 0 68k Code + { "tse_04.1b", 0x10000, 0xd0c8ec75, 1 | BRF_PRG | BRF_ESS }, // 1 + { "tse_03.2a", 0x10000, 0xb2ac0a45, 1 | BRF_PRG | BRF_ESS }, // 2 + { "tse_05.2b", 0x10000, 0xa79cb406, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "ts_01b.4e", 0x08000, 0xa9a6cafa, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 Code + + { "tsu_08.8l", 0x08000, 0x9bf0b7a2, 3 | BRF_GRA }, // 5 Characters + + { "tsu_07.5l", 0x08000, 0x9469efa4, 4 | BRF_GRA }, // 6 Background Tiles + { "tsu_06.4l", 0x08000, 0x40bf0eb4, 4 | BRF_GRA }, // 7 + + { "ts_12.17f", 0x08000, 0xe4b4619e, 5 | BRF_GRA }, // 8 Foreground Tiles + { "ts_11.15f", 0x08000, 0xab30237a, 5 | BRF_GRA }, // 9 + { "ts_17.17g", 0x08000, 0xdeb657e4, 5 | BRF_GRA }, // 10 + { "ts_16.15g", 0x08000, 0xd363b5f9, 5 | BRF_GRA }, // 11 + { "ts_13.18f", 0x08000, 0xa8f5a004, 5 | BRF_GRA }, // 12 + { "ts_18.18g", 0x08000, 0x3b36948c, 5 | BRF_GRA }, // 13 + { "ts_23.18j", 0x08000, 0xbbfbe58a, 5 | BRF_GRA }, // 14 + { "ts_24.18k", 0x08000, 0xf156e564, 5 | BRF_GRA }, // 15 + + { "tse_10.13f", 0x08000, 0xd28eeacc, 6 | BRF_GRA }, // 16 Sprites + { "tsu_09.11f", 0x08000, 0x6a049292, 6 | BRF_GRA }, // 17 + { "tse_15.13g", 0x08000, 0x9b5593c0, 6 | BRF_GRA }, // 18 + { "tsu_14.11g", 0x08000, 0x46b2ad83, 6 | BRF_GRA }, // 19 + { "tse_20.13j", 0x08000, 0xb03db778, 6 | BRF_GRA }, // 20 + { "tsu_19.11j", 0x08000, 0xb5c82722, 6 | BRF_GRA }, // 21 + { "tse_22.17j", 0x08000, 0xd4dedeb3, 6 | BRF_GRA }, // 22 + { "tsu_21.15j", 0x08000, 0x98777006, 6 | BRF_GRA }, // 23 + + { "63s141.18f", 0x00100, 0xb58d0023, 0 | BRF_OPT }, // 24 Priority (not used) +}; + +STD_ROM_PICK(bionicc); +STD_ROM_FN(bionicc); + +struct BurnDriver BurnDrvbionicc = { + "bionicc", NULL, NULL, "1987", + "Bionic Commando (Euro)\0", NULL, "Capcom", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, bioniccRomInfo, bioniccRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalc, + 256, 224, 4, 3 +}; + + +// Bionic Commando (US set 1) + +static struct BurnRomInfo bionicc1RomDesc[] = { + { "tsu_02b.1a", 0x10000, 0xcf965a0a, 1 | BRF_PRG | BRF_ESS }, // 0 68k Code + { "tsu_04b.1b", 0x10000, 0xc9884bfb, 1 | BRF_PRG | BRF_ESS }, // 1 + { "tsu_03b.2a", 0x10000, 0x4e157ae2, 1 | BRF_PRG | BRF_ESS }, // 2 + { "tsu_05b.2b", 0x10000, 0xe66ca0f9, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "ts_01b.4e", 0x08000, 0xa9a6cafa, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 Code + + { "tsu_08.8l", 0x08000, 0x9bf0b7a2, 3 | BRF_GRA }, // 5 Characters + + { "tsu_07.5l", 0x08000, 0x9469efa4, 4 | BRF_GRA }, // 6 Background Tiles + { "tsu_06.4l", 0x08000, 0x40bf0eb4, 4 | BRF_GRA }, // 7 + + { "ts_12.17f", 0x08000, 0xe4b4619e, 5 | BRF_GRA }, // 8 Foreground Tiles + { "ts_11.15f", 0x08000, 0xab30237a, 5 | BRF_GRA }, // 9 + { "ts_17.17g", 0x08000, 0xdeb657e4, 5 | BRF_GRA }, // 10 + { "ts_16.15g", 0x08000, 0xd363b5f9, 5 | BRF_GRA }, // 11 + { "ts_13.18f", 0x08000, 0xa8f5a004, 5 | BRF_GRA }, // 12 + { "ts_18.18g", 0x08000, 0x3b36948c, 5 | BRF_GRA }, // 13 + { "ts_23.18j", 0x08000, 0xbbfbe58a, 5 | BRF_GRA }, // 14 + { "ts_24.18k", 0x08000, 0xf156e564, 5 | BRF_GRA }, // 15 + + { "tsu_10.13f", 0x08000, 0xf1180d02, 6 | BRF_GRA }, // 16 Sprites + { "tsu_09.11f", 0x08000, 0x6a049292, 6 | BRF_GRA }, // 17 + { "tsu_15.13g", 0x08000, 0xea912701, 6 | BRF_GRA }, // 18 + { "tsu_14.11g", 0x08000, 0x46b2ad83, 6 | BRF_GRA }, // 19 + { "tsu_20.13j", 0x08000, 0x17857ad2, 6 | BRF_GRA }, // 20 + { "tsu_19.11j", 0x08000, 0xb5c82722, 6 | BRF_GRA }, // 21 + { "tsu_22.17j", 0x08000, 0x5ee1ae6a, 6 | BRF_GRA }, // 22 + { "tsu_21.15j", 0x08000, 0x98777006, 6 | BRF_GRA }, // 23 + + { "63s141.18f", 0x00100, 0xb58d0023, 0 | BRF_OPT }, // 24 Priority (not used) +}; + +STD_ROM_PICK(bionicc1); +STD_ROM_FN(bionicc1); + +struct BurnDriver BurnDrvbionicc1 = { + "bionicc1", "bionicc", NULL, "1987", + "Bionic Commando (US set 1)\0", NULL, "Capcom", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, bionicc1RomInfo, bionicc1RomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalc, + 256, 224, 4, 3 +}; + + +// Bionic Commando (US set 2) + +static struct BurnRomInfo bionicc2RomDesc[] = { + { "tsu_02.1a", 0x10000, 0xf2528f08, 1 | BRF_PRG | BRF_ESS }, // 0 68k Code + { "tsu_04.1b", 0x10000, 0x38b1c7e4, 1 | BRF_PRG | BRF_ESS }, // 1 + { "tsu_03.2a", 0x10000, 0x72c3b76f, 1 | BRF_PRG | BRF_ESS }, // 2 + { "tsu_05.2b", 0x10000, 0x70621f83, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "ts_01b.4e", 0x08000, 0xa9a6cafa, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 Code + + { "tsu_08.8l", 0x08000, 0x9bf0b7a2, 3 | BRF_GRA }, // 5 Characters + + { "tsu_07.5l", 0x08000, 0x9469efa4, 4 | BRF_GRA }, // 6 Background Tiles + { "tsu_06.4l", 0x08000, 0x40bf0eb4, 4 | BRF_GRA }, // 7 + + { "ts_12.17f", 0x08000, 0xe4b4619e, 5 | BRF_GRA }, // 8 Foreground Tiles + { "ts_11.15f", 0x08000, 0xab30237a, 5 | BRF_GRA }, // 9 + { "ts_17.17g", 0x08000, 0xdeb657e4, 5 | BRF_GRA }, // 10 + { "ts_16.15g", 0x08000, 0xd363b5f9, 5 | BRF_GRA }, // 11 + { "ts_13.18f", 0x08000, 0xa8f5a004, 5 | BRF_GRA }, // 12 + { "ts_18.18g", 0x08000, 0x3b36948c, 5 | BRF_GRA }, // 13 + { "ts_23.18j", 0x08000, 0xbbfbe58a, 5 | BRF_GRA }, // 14 + { "ts_24.18k", 0x08000, 0xf156e564, 5 | BRF_GRA }, // 15 + + { "tsu_10.13f", 0x08000, 0xf1180d02, 6 | BRF_GRA }, // 16 Sprites + { "tsu_09.11f", 0x08000, 0x6a049292, 6 | BRF_GRA }, // 17 + { "tsu_15.13g", 0x08000, 0xea912701, 6 | BRF_GRA }, // 18 + { "tsu_14.11g", 0x08000, 0x46b2ad83, 6 | BRF_GRA }, // 19 + { "tsu_20.13j", 0x08000, 0x17857ad2, 6 | BRF_GRA }, // 20 + { "tsu_19.11j", 0x08000, 0xb5c82722, 6 | BRF_GRA }, // 21 + { "tsu_22.17j", 0x08000, 0x5ee1ae6a, 6 | BRF_GRA }, // 22 + { "tsu_21.15j", 0x08000, 0x98777006, 6 | BRF_GRA }, // 23 + + { "63s141.18f", 0x00100, 0xb58d0023, 0 | BRF_OPT }, // 24 Priority (not used) +}; + +STD_ROM_PICK(bionicc2); +STD_ROM_FN(bionicc2); + +struct BurnDriver BurnDrvbionicc2 = { + "bionicc2", "bionicc", NULL, "1987", + "Bionic Commando (US set 2)\0", NULL, "Capcom", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, bionicc2RomInfo, bionicc2RomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalc, + 256, 224, 4, 3 +}; + + +// Top Secret (Japan) + +static struct BurnRomInfo topsecrtRomDesc[] = { + { "ts_02.1a", 0x10000, 0xb2fe1ddb, 1 | BRF_PRG | BRF_ESS }, // 0 68k Code + { "ts_04.1b", 0x10000, 0x427a003d, 1 | BRF_PRG | BRF_ESS }, // 1 + { "ts_03.2a", 0x10000, 0x27f04bb6, 1 | BRF_PRG | BRF_ESS }, // 2 + { "ts_05.2b", 0x10000, 0xc01547b1, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "ts_01.4e", 0x08000, 0x8ea07917, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 Code + + { "ts_08.8l", 0x08000, 0x96ad379e, 3 | BRF_GRA }, // 5 Characters + + { "ts_07.5l", 0x08000, 0x25cdf8b2, 4 | BRF_GRA }, // 6 Background Tiles + { "ts_06.4l", 0x08000, 0x314fb12d, 4 | BRF_GRA }, // 7 + + { "ts_12.17f", 0x08000, 0xe4b4619e, 5 | BRF_GRA }, // 8 Foreground Tiles + { "ts_11.15f", 0x08000, 0xab30237a, 5 | BRF_GRA }, // 9 + { "ts_17.17g", 0x08000, 0xdeb657e4, 5 | BRF_GRA }, // 10 + { "ts_16.15g", 0x08000, 0xd363b5f9, 5 | BRF_GRA }, // 11 + { "ts_13.18f", 0x08000, 0xa8f5a004, 5 | BRF_GRA }, // 12 + { "ts_18.18g", 0x08000, 0x3b36948c, 5 | BRF_GRA }, // 13 + { "ts_23.18j", 0x08000, 0xbbfbe58a, 5 | BRF_GRA }, // 14 + { "ts_24.18k", 0x08000, 0xf156e564, 5 | BRF_GRA }, // 15 + + { "ts_10.13f", 0x08000, 0xc3587d05, 6 | BRF_GRA }, // 16 Sprites + { "ts_09.11f", 0x08000, 0x6b63eef2, 6 | BRF_GRA }, // 17 + { "ts_15.13g", 0x08000, 0xdb8cebb0, 6 | BRF_GRA }, // 18 + { "ts_14.11g", 0x08000, 0xe2e41abf, 6 | BRF_GRA }, // 19 + { "ts_20.13j", 0x08000, 0xbfd1a695, 6 | BRF_GRA }, // 20 + { "ts_19.11j", 0x08000, 0x928b669e, 6 | BRF_GRA }, // 21 + { "ts_22.17j", 0x08000, 0x3fe05d9a, 6 | BRF_GRA }, // 22 + { "ts_21.15j", 0x08000, 0x27a9bb7c, 6 | BRF_GRA }, // 23 + + { "63s141.18f", 0x00100, 0xb58d0023, 0 | BRF_OPT }, // 24 Priority (not used) +}; + +STD_ROM_PICK(topsecrt); +STD_ROM_FN(topsecrt); + +struct BurnDriver BurnDrvtopsecrt = { + "topsecrt", "bionicc", NULL, "1987", + "Top Secret (Japan)\0", NULL, "Capcom", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, topsecrtRomInfo, topsecrtRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalc, + 256, 224, 4, 3 +}; diff --git a/src/burn/misc/pre90s/d_bombjack.cpp b/src/burn/misc/pre90s/d_bombjack.cpp new file mode 100644 index 0000000..68ce7d5 --- /dev/null +++ b/src/burn/misc/pre90s/d_bombjack.cpp @@ -0,0 +1,969 @@ +#include "tiles_generic.h" + +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +unsigned char DrvJoy1[7] = {0, 0, 0, 0, 0, 0, 0}; +unsigned char DrvJoy2[7] = {0, 0, 0, 0, 0, 0, 0}; +unsigned char BjDip[2] = {0, 0}; +static unsigned char DrvReset = 0; +static int bombjackIRQ = 0; +static int latch; + +static int nCyclesDone[2], nCyclesTotal[2]; +static int nCyclesSegment; + +static unsigned char *Mem = NULL; +static unsigned char *MemEnd = NULL; +static unsigned char *RamStart = NULL; +static unsigned char *RamEnd = NULL; +static unsigned char *BjGfx = NULL; +static unsigned char *BjMap = NULL; +static unsigned char *BjRom = NULL; +static unsigned char *BjRam = NULL; +static unsigned char *BjColRam = NULL; +static unsigned char *BjVidRam = NULL; +static unsigned char *BjSprRam = NULL; + +// sound cpu +static unsigned char *SndRom = NULL; +static unsigned char *SndRam = NULL; + +// graphics tiles +static unsigned char *text = NULL; +static unsigned char *sprites = NULL; +static unsigned char *tiles = NULL; + +// pallete +static unsigned char *BjPalSrc = NULL; +static unsigned int *BjPalReal = NULL; + +static short* pFMBuffer; +static short* pAY8910Buffer[9]; + +// Dip Switch and Input Definitions +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 0, "p1 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 1, "p1 start" }, + + {"P1 Up" , BIT_DIGITAL , DrvJoy1 + 2, "p1 up" }, + {"P1 Down" , BIT_DIGITAL , DrvJoy1 + 3, "p1 down" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 4, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 5, "p1 right" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 6, "p1 fire 1"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy2 + 0, "p2 coin" }, + {"P2 Start" , BIT_DIGITAL , DrvJoy2 + 1, "p2 start" }, + + {"P2 Up" , BIT_DIGITAL , DrvJoy2 + 2, "p2 up" }, + {"P2 Down" , BIT_DIGITAL , DrvJoy2 + 3, "p2 down" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 4, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 5, "p2 right" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 6, "p2 fire 1"}, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip Sw(1)" , BIT_DIPSWITCH, BjDip + 0 , "dip" }, + {"Dip Sw(2)" , BIT_DIPSWITCH, BjDip + 1 , "dip" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo BjDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xc0, NULL}, + {0x10, 0xff, 0xff, 0x00, NULL}, + + // Dip Sw(1) + {0, 0xfe, 0, 4, "Coin A"}, + {0x0f, 0x01, 0x03, 0x00, "1 coin 1 credit"}, + {0x0f, 0x01, 0x03, 0x01, "1 coin 2 credits"}, + {0x0f, 0x01, 0x03, 0x02, "1 coin 3 credits"}, + {0x0f, 0x01, 0x03, 0x03, "1 coin 6 credits"}, + + {0, 0xfe, 0, 4, "Coin B"}, + {0x0f, 0x01, 0x0c, 0x04, "2 coins 1 credit"}, + {0x0f, 0x01, 0x0c, 0x00, "1 coin 1 credit"}, + {0x0f, 0x01, 0x0c, 0x08, "1 coin 2 credits"}, + {0x0f, 0x01, 0x0c, 0x0c, "1 coin 3 credits"}, + + {0, 0xfe, 0, 4, "Lives"}, + {0x0f, 0x01, 0x30, 0x30, "2"}, + {0x0f, 0x01, 0x30, 0x00, "3"}, + {0x0f, 0x01, 0x30, 0x10, "4"}, + {0x0f, 0x01, 0x30, 0x20, "5"}, + + {0, 0xfe, 0, 2, "Cabinet"}, + {0x0f, 0x01, 0x40, 0x40, "Upright"}, + {0x0f, 0x01, 0x40, 0x00, "Cocktail"}, + + {0, 0xfe, 0, 2, "Demo sounds"}, + {0x0f, 0x01, 0x80, 0x00, "Off"}, + {0x0f, 0x01, 0x80, 0x80, "On"}, + + // Dip Sw(2) + {0, 0xfe, 0, 4, "Initial high score"}, + {0x10, 0x01, 0x07, 0x00, "10000"}, + {0x10, 0x01, 0x07, 0x01, "100000"}, + {0x10, 0x01, 0x07, 0x02, "30000"}, + {0x10, 0x01, 0x07, 0x03, "50000"}, + {0x10, 0x01, 0x07, 0x04, "100000"}, + {0x10, 0x01, 0x07, 0x05, "50000"}, + {0x10, 0x01, 0x07, 0x06, "100000"}, + {0x10, 0x01, 0x07, 0x07, "50000"}, + + {0, 0xfe, 0, 4, "Bird speed"}, + {0x10, 0x01, 0x18, 0x00, "Easy"}, + {0x10, 0x01, 0x18, 0x08, "Medium"}, + {0x10, 0x01, 0x18, 0x10, "Hard"}, + {0x10, 0x01, 0x18, 0x18, "Hardest"}, + + {0, 0xfe, 0, 4, "Enemies number & speed"}, + {0x10, 0x01, 0x60, 0x20, "Easy"}, + {0x10, 0x01, 0x60, 0x00, "Medium"}, + {0x10, 0x01, 0x60, 0x40, "Hard"}, + {0x10, 0x01, 0x60, 0x60, "Hardest"}, + + {0, 0xfe, 0, 2, "Special coin"}, + {0x10, 0x01, 0x80, 0x00, "Easy"}, + {0x10, 0x01, 0x80, 0x80, "Hard"}, +}; + +STDDIPINFO(Bj); + +// Bomb Jack (set 1) +static struct BurnRomInfo BombjackRomDesc[] = { + { "09_j01b.bin", 0x2000, 0xc668dc30, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "10_l01b.bin", 0x2000, 0x52a1e5fb, BRF_ESS | BRF_PRG }, // 1 + { "11_m01b.bin", 0x2000, 0xb68a062a, BRF_ESS | BRF_PRG }, // 2 + { "12_n01b.bin", 0x2000, 0x1d3ecee5, BRF_ESS | BRF_PRG }, // 3 + { "13.1r", 0x2000, 0x70e0244d, BRF_ESS | BRF_PRG }, // 4 + + // graphics 3 bit planes: + { "03_e08t.bin", 0x1000, 0x9f0470d5, BRF_GRA }, // chars + { "04_h08t.bin", 0x1000, 0x81ec12e6, BRF_GRA }, + { "05_k08t.bin", 0x1000, 0xe87ec8b1, BRF_GRA }, + + { "14_j07b.bin", 0x2000, 0x101c858d, BRF_GRA }, // sprites + { "15_l07b.bin", 0x2000, 0x013f58f2, BRF_GRA }, + { "16_m07b.bin", 0x2000, 0x94694097, BRF_GRA }, + + { "06_l08t.bin", 0x2000, 0x51eebd89, BRF_GRA }, // background tiles + { "07_n08t.bin", 0x2000, 0x9dd98e9d, BRF_GRA }, + { "08_r08t.bin", 0x2000, 0x3155ee7d, BRF_GRA }, + + { "02_p04t.bin", 0x1000, 0x398d4a02, BRF_GRA }, // background tilemaps + + { "01_h03t.bin", 0x2000, 0x8407917d, BRF_ESS | BRF_SND }, // sound CPU +}; + +STD_ROM_PICK(Bombjack); +STD_ROM_FN(Bombjack); + + +// Bomb Jack (set 2) +static struct BurnRomInfo Bombjac2RomDesc[] = { + { "09_j01b.bin", 0x2000, 0xc668dc30, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "10_l01b.bin", 0x2000, 0x52a1e5fb, BRF_ESS | BRF_PRG }, // 1 + { "11_m01b.bin", 0x2000, 0xb68a062a, BRF_ESS | BRF_PRG }, // 2 + { "12_n01b.bin", 0x2000, 0x1d3ecee5, BRF_ESS | BRF_PRG }, // 3 + { "13_r01b.bin", 0x2000, 0xbcafdd29, BRF_ESS | BRF_PRG }, // 4 + + // graphics 3 bit planes: + { "03_e08t.bin", 0x1000, 0x9f0470d5, BRF_GRA }, // chars + { "04_h08t.bin", 0x1000, 0x81ec12e6, BRF_GRA }, + { "05_k08t.bin", 0x1000, 0xe87ec8b1, BRF_GRA }, + + { "14_j07b.bin", 0x2000, 0x101c858d, BRF_GRA }, // sprites + { "15_l07b.bin", 0x2000, 0x013f58f2, BRF_GRA }, + { "16_m07b.bin", 0x2000, 0x94694097, BRF_GRA }, + + { "06_l08t.bin", 0x2000, 0x51eebd89, BRF_GRA }, // background tiles + { "07_n08t.bin", 0x2000, 0x9dd98e9d, BRF_GRA }, + { "08_r08t.bin", 0x2000, 0x3155ee7d, BRF_GRA }, + + { "02_p04t.bin", 0x1000, 0x398d4a02, BRF_GRA }, // background tilemaps + + { "01_h03t.bin", 0x2000, 0x8407917d, BRF_ESS | BRF_SND }, // sound CPU +}; + +STD_ROM_PICK(Bombjac2); +STD_ROM_FN(Bombjac2); + + +static int DrvDoReset() +{ + bombjackIRQ = 0; + latch = 0; + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + } + + for (int i = 0; i < 3; i++) { + AY8910Reset(i); + } + return 0; +} + + +unsigned char __fastcall BjMemRead(unsigned short addr) +{ + unsigned char inputs=0; + + if (addr==0xb000) { + if (DrvJoy1[5]) + inputs|=0x01; + if (DrvJoy1[4]) + inputs|=0x02; + if (DrvJoy1[2]) + inputs|=0x04; + if (DrvJoy1[3]) + inputs|=0x08; + if (DrvJoy1[6]) + inputs|=0x10; + return inputs; + } + if (addr==0xb001) { + if (DrvJoy2[5]) + inputs|=0x01; + if (DrvJoy2[4]) + inputs|=0x02; + if (DrvJoy2[2]) + inputs|=0x04; + if (DrvJoy2[3]) + inputs|=0x08; + if (DrvJoy2[6]) + inputs|=0x10; + return inputs; + } + if (addr==0xb002) { + if (DrvJoy1[0]) + inputs|=0x01; + if (DrvJoy1[1]) + inputs|=0x04; + if (DrvJoy2[0]) + inputs|=0x02; + if (DrvJoy2[1]) + inputs|=0x08; + return inputs; + } + if (addr==0xb004) { + return BjDip[0]; // Dip Sw(1) + } + if (addr==0xb005) { + return BjDip[1]; // Dip Sw(2) + } + return 0; +} + +void __fastcall BjMemWrite(unsigned short addr,unsigned char val) +{ + if (addr==0xb000) + { + bombjackIRQ = val; + } + if(addr==0xb800) + { + latch=val; + return; + } + BjRam[addr]=val; +} + +unsigned char __fastcall SndMemRead(unsigned short a) +{ + if (a==0xFF00) + { + return 0x7f; + } + if(a==0x6000) + { + int res; + res = latch; + latch = 0; + return res; + } + return 0; +} + + + +void __fastcall SndPortWrite(unsigned short a, unsigned char d) +{ + a &= 0xff; + switch (a) { + case 0x00: { + AY8910Write(0, 0, d); + return; + } + case 0x01: { + AY8910Write(0, 1, d); + return; + } + case 0x10: { + AY8910Write(1, 0, d); + return; + } + case 0x11: { + AY8910Write(1, 1, d); + return; + } + case 0x80: { + AY8910Write(2, 0, d); + return; + } + case 0x81: { + AY8910Write(2, 1, d); + return; + } + } +} + +int BjZInit() +{ + // Init the z80 + ZetInit(2); + // Main CPU setup + ZetOpen(0); + + ZetMapArea (0x0000,0x7fff,0,BjRom+0x0000); // Direct Read from ROM + ZetMapArea (0x0000,0x7fff,2,BjRom+0x0000); // Direct Fetch from ROM + ZetMapArea (0xc000,0xdfff,0,BjRom+0x8000); // Direct Read from ROM + ZetMapArea (0xc000,0xdfff,2,BjRom+0x8000); // Direct Fetch from ROM + + ZetMapArea (0x8000,0x8fff,0,BjRam+0x8000); + ZetMapArea (0x8000,0x8fff,1,BjRam+0x8000); + + ZetMapArea (0x9000,0x93ff,0,BjVidRam); + ZetMapArea (0x9000,0x93ff,1,BjVidRam); + + ZetMapArea (0x9400,0x97ff,0,BjColRam); + ZetMapArea (0x9400,0x97ff,1,BjColRam); + + ZetMapArea (0x9820,0x987f,0,BjSprRam); + ZetMapArea (0x9820,0x987f,1,BjSprRam); + + ZetMapArea (0x9c00,0x9cff,0,BjPalSrc); + ZetMapArea (0x9c00,0x9cff,1,BjPalSrc); + + ZetMapArea (0x9e00,0x9e00,0,BjRam+0x9e00); + ZetMapArea (0x9e00,0x9e00,1,BjRam+0x9e00); + + // ZetMapArea (0xb000,0xb000,0,BjRam+0xb000); + // ZetMapArea (0xb000,0xb000,1,BjRam+0xb000); + + // ZetMapArea (0xb800,0xb800,0,BjRam+0xb800); + // ZetMapArea (0xb800,0xb800,1,BjRam+0xb800); + + ZetSetReadHandler(BjMemRead); + ZetSetWriteHandler(BjMemWrite); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetMapArea (0x0000,0x1fff,0,SndRom); // Direct Read from ROM + ZetMapArea (0x0000,0x1fff,2,SndRom); // Direct Fetch from ROM + ZetMapArea (0x4000,0x43ff,0,SndRam); + ZetMapArea (0x4000,0x43ff,1,SndRam); + ZetMapArea (0x4000,0x43ff,2,SndRam); // fetch from ram? + ZetMapArea (0xff00,0xffff,0,SndRam); + ZetMapArea (0xff00,0xffff,1,SndRam); + ZetMapArea (0xff00,0xffff,2,SndRam); // more fetch from ram? What the hell . . + + // ZetMapArea (0x6000,0x6000,0,BjRam+0xb800); + // ZetMapArea (0x6000,0x6000,1,BjRam+0xb800); + ZetSetReadHandler(SndMemRead); + ZetSetOutHandler(SndPortWrite); + ZetMemEnd(); + ZetClose(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + pAY8910Buffer[3] = pFMBuffer + nBurnSoundLen * 3; + pAY8910Buffer[4] = pFMBuffer + nBurnSoundLen * 4; + pAY8910Buffer[5] = pFMBuffer + nBurnSoundLen * 5; + pAY8910Buffer[6] = pFMBuffer + nBurnSoundLen * 6; + pAY8910Buffer[7] = pFMBuffer + nBurnSoundLen * 7; + pAY8910Buffer[8] = pFMBuffer + nBurnSoundLen * 8; + + AY8910Init(0, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(1, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(2, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + // remember to do ZetReset() in main driver + + DrvDoReset(); + return 0; +} + + + +void DecodeTiles(unsigned char *TilePointer, int num,int off1,int off2, int off3) +{ + int c,y,x,dat1,dat2,dat3,col; + for (c=0;c>=1; + dat2>>=1; + dat3>>=1; + } + } + } +} + + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + BjRom = Next; Next += 0x10000; + BjGfx = Next; Next += 0x0f000; + BjMap = Next; Next += 0x01000; + SndRom = Next; Next += 0x02000; + RamStart = Next; + BjRam = Next; Next += 0x10000; + SndRam = Next; Next += 0x01000; + BjPalSrc = Next; Next += 0x00100; + BjVidRam = Next; Next += 0x00400; + BjColRam = Next; Next += 0x00400; + BjSprRam = Next; Next += 0x00060; + RamEnd = Next; + text = Next; Next += 512 * 8 * 8; + sprites = Next; Next += 1024 * 8 * 8; + tiles = Next; Next += 1024 * 8 * 8; + pFMBuffer = (short*)Next; Next += nBurnSoundLen * 9 * sizeof(short); + BjPalReal = (unsigned int*)Next; Next += 0x0080 * sizeof(unsigned int); + MemEnd = Next; + + return 0; +} + + +int BjInit() +{ + // Allocate and Blank all required memory + Mem = NULL; + MemIndex(); + int nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + for (int i =0; i<5 ; i++) + { + BurnLoadRom(BjRom+(0x2000*i),i,1); // load code roms + } + + for (int i=0;i<3;i++) + { + BurnLoadRom(BjGfx+(0x1000*i),i+5,1); + } + + BurnLoadRom(BjGfx+0x3000,8,1); + BurnLoadRom(BjGfx+0x5000,9,1); + BurnLoadRom(BjGfx+0x7000,10,1); + + BurnLoadRom(BjGfx+0x9000,11,1); + BurnLoadRom(BjGfx+0xB000,12,1); + BurnLoadRom(BjGfx+0xD000,13,1); + + BurnLoadRom(BjMap,14,1); // load Background tile maps + BurnLoadRom(SndRom,15,1); // load Sound CPU + + // Set memory access & Init + BjZInit(); + + DecodeTiles(text,512,0,0x1000,0x2000); + DecodeTiles(sprites,1024,0x7000,0x5000,0x3000); + DecodeTiles(tiles,1024,0x9000,0xB000,0xD000); + // done + + GenericTilesInit(); + + DrvDoReset(); + return 0; +} + +int BjExit() +{ + ZetExit(); + + for (int i = 0; i < 3; i++) { + AY8910Exit(i); + } + + GenericTilesExit(); + free(Mem); + Mem = NULL; + return 0; +} + +static unsigned int CalcCol(unsigned short nColour) +{ + int r, g, b; + + r = (nColour >> 0) & 0x0f; + g = (nColour >> 4) & 0x0f; + b = (nColour >> 8) & 0x0f; + + r = (r << 4) | r; + g = (g << 4) | g; + b = (b << 4) | b; + + return BurnHighCol(r, g, b, 0); +} + +int CalcAll() +{ + for (int i = 0; i < 0x100; i++) { + BjPalReal[i / 2] = CalcCol(BjPalSrc[i & ~1] | (BjPalSrc[i | 1] << 8)); + } + + return 0; +} + +void BjRenderFgLayer() +{ + for (int tileCount = 0; tileCount < 1024 ;tileCount++) + { + int code = BjVidRam[tileCount] + 16 * (BjColRam[tileCount] & 0x10); + int color = BjColRam[tileCount] & 0x0f; + int sy = (tileCount % 32); + int sx = 31 - (tileCount / 32); + + sx<<=3; + sx-=16; + sy<<=3; + if (sx >= 0 && sx < 215 && sy >= 0 && sy < 246) + { + Render8x8Tile_Mask(pTransDraw, code,sx,sy,color, 3, 0, 0, text); + } + else + { + Render8x8Tile_Mask_Clip(pTransDraw, code,sx,sy,color, 3, 0, 0, text); + } + } +} + + +void BjRenderBgLayer() +{ + for (int tileCount = 0; tileCount < 256;tileCount++) { + int FlipX; + + int BgSel=BjRam[0x9e00]; + + int offs = (BgSel & 0x07) * 0x200 + tileCount; + int Code = (BgSel & 0x10) ? BjMap[offs] : 0; + + int attr = BjMap[offs + 0x100]; + int Colour = attr & 0x0f; + //int flags = (attr & 0x80) ? TILE_FLIPY : 0; + + + int sy = (tileCount % 16); + int sx = 15 - (tileCount / 16); + FlipX = attr & 0x80; + + /*if (SolomonFlipScreen) { + sx = 31 - sx; + sy = 31 - sy; + FlipX = !FlipX; + FlipY = !FlipY; + }*/ + + sx <<= 4; + sx -=16; + sy <<= 4; + Code <<= 2; + if (sx >= 0 && sx < 215 && sy >= 0 && sy < 246) { + + if (FlipX&0x80) + { + Render8x8Tile_Mask(pTransDraw, Code+0,sx+8,sy+0, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask(pTransDraw, Code+1,sx+8,sy+8, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask(pTransDraw, Code+2,sx+0,sy+0, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask(pTransDraw, Code+3,sx+0,sy+8, Colour, 3, 0, 0, tiles); + + } + else + { + Render8x8Tile_Mask(pTransDraw, Code+0,sx+8,sy+0, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask(pTransDraw, Code+1,sx+8,sy+8, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask(pTransDraw, Code+2,sx+0,sy+0, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask(pTransDraw, Code+3,sx+0,sy+8, Colour, 3, 0, 0, tiles); + } + + } else { + + if (FlipX&0x80) + { + Render8x8Tile_Mask_Clip(pTransDraw, Code+0,sx+8,sy+0, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask_Clip(pTransDraw, Code+1,sx+8,sy+8, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask_Clip(pTransDraw, Code+2,sx+0,sy+0, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask_Clip(pTransDraw, Code+3,sx+0,sy+8, Colour, 3, 0, 0, tiles); + + } + else + { + Render8x8Tile_Mask_Clip(pTransDraw, Code+0,sx+8,sy+0, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask_Clip(pTransDraw, Code+1,sx+8,sy+8, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask_Clip(pTransDraw, Code+2,sx+0,sy+0, Colour, 3, 0, 0, tiles); + Render8x8Tile_Mask_Clip(pTransDraw, Code+3,sx+0,sy+8, Colour, 3, 0, 0, tiles); + } + + } + } +} + + +static void BjDrawSprites() +{ + int offs; + + for (offs = 0x60 - 4; offs >= 0; offs -= 4) + { + + /* + abbbbbbb cdefgggg hhhhhhhh iiiiiiii + + a use big sprites (32x32 instead of 16x16) + bbbbbbb sprite code + c x flip + d y flip (used only in death sequence?) + e ? (set when big sprites are selected) + f ? (set only when the bonus (B) materializes?) + gggg color + hhhhhhhh x position + iiiiiiii y position + */ + int sx,sy,flipx,flipy, code, colour, big; + + + sy = BjSprRam[offs+3]; + if (BjSprRam[offs] & 0x80) + sx = BjSprRam[offs+2]; + else + sx = BjSprRam[offs+2]; + flipx = BjSprRam[offs+1] & 0x80; + flipy = BjSprRam[offs+1] & 0x40; + + code = BjSprRam[offs] & 0x7f; + colour = (BjSprRam[offs+1] & 0x0f); + big = (BjSprRam[offs] & 0x80); + + //sy -= 32; + + sx -=16; + if (!big) + { + code <<= 2; + if (sx >= 0 && sx < 215 && sy >= 0 && sy < 246) { + if (!flipy) { + if (!flipx) { + Render8x8Tile_Mask(pTransDraw, code + 0, sx + 8, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code + 1, sx + 8, sy + 8, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code + 2, sx + 0, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code + 3, sx + 0, sy + 8, colour, 3, 0, 0, sprites); + } else { + Render8x8Tile_Mask_FlipX(pTransDraw, code + 2, sx + 8, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipX(pTransDraw, code + 3, sx + 8, sy + 8, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipX(pTransDraw, code + 0, sx + 0, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipX(pTransDraw, code + 1, sx + 0, sy + 8, colour, 3, 0, 0, sprites); + } + } else { + if (!flipx) { + Render8x8Tile_Mask_FlipY(pTransDraw, code + 1, sx + 8, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipY(pTransDraw, code + 0, sx + 8, sy + 8, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipY(pTransDraw, code + 3, sx + 0, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipY(pTransDraw, code + 2, sx + 0, sy + 8, colour, 3, 0, 0, sprites); + } else { + Render8x8Tile_Mask_FlipXY(pTransDraw, code + 3, sx + 8, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipXY(pTransDraw, code + 2, sx + 8, sy + 8, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipXY(pTransDraw, code + 1, sx + 0, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipXY(pTransDraw, code + 0, sx + 0, sy + 8, colour, 3, 0, 0, sprites); + } + } + } else { + if (!flipy) { + if (!flipx) { + Render8x8Tile_Mask_Clip(pTransDraw, code + 0, sx + 8, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code + 1, sx + 8, sy + 8, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code + 2, sx + 0, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code + 3, sx + 0, sy + 8, colour, 3, 0, 0, sprites); + } else { + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code + 2, sx + 8, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code + 3, sx + 8, sy + 8, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code + 0, sx + 0, sy + 0, colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code + 1, sx + 0, sy + 8, colour, 3, 0, 0, sprites); + } + } else { + if (!flipx) { + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code + 1, sx + 0, sy + 0, colour, 4, 0, 0, sprites); + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code + 0, sx + 0, sy + 8, colour, 4, 0, 0, sprites); + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code + 3, sx + 8, sy + 0, colour, 4, 0, 0, sprites); + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code + 2, sx + 8, sy + 8, colour, 4, 0, 0, sprites); + } else { + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code + 3, sx + 8, sy + 0, colour, 4, 0, 0, sprites); + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code + 2, sx + 8, sy + 8, colour, 4, 0, 0, sprites); + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code + 1, sx + 0, sy + 0, colour, 4, 0, 0, sprites); + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code + 0, sx + 0, sy + 8, colour, 4, 0, 0, sprites); + } + } + } + } + else + { + code&=31; + code <<= 4; + sx-=1; + if (sx >= 0 && sx < 215 && sy >= 0 && sy < 246) + { + if (!flipy) + { + if (!flipx) { + Render8x8Tile_Mask(pTransDraw, code+512,sx+8+16,sy,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+513,sx+8+16,sy+8,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+514,sx+16,sy,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+515,sx+16,sy+8,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+516,sx+8+16,sy+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+517,sx+8+16,sy+8+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+518,sx+16,sy+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+519,sx+16,sy+8+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+520,sx+8,sy,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+521,sx+8,sy+8,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+522,sx,sy,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+523,sx,sy+8,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+524,sx+8,sy+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+525,sx+8,sy+8+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+526,sx,sy+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask(pTransDraw, code+527,sx,sy+8+16,colour, 3, 0, 0, sprites); + } + } + } + else + { + if (!flipy) + { + if (!flipx) { + Render8x8Tile_Mask_Clip(pTransDraw, code+512,sx+8+16,sy,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+513,sx+8+16,sy+8,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+514,sx+16,sy,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+515,sx+16,sy+8,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+516,sx+8+16,sy+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+517,sx+8+16,sy+8+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+518,sx+16,sy+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+519,sx+16,sy+8+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+520,sx+8,sy,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+521,sx+8,sy+8,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+522,sx,sy,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+523,sx,sy+8,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+524,sx+8,sy+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+525,sx+8,sy+8+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+526,sx,sy+16,colour, 3, 0, 0, sprites); + Render8x8Tile_Mask_Clip(pTransDraw, code+527,sx,sy+8+16,colour, 3, 0, 0, sprites); + } + } + } + } + } +} + +int BjFrame() +{ + if (DrvReset) { // Reset machine + DrvDoReset(); + } + + int nInterleave = 10; + int nSoundBufferPos = 0; + + nCyclesTotal[0] = 4000000 / 60; + nCyclesTotal[1] = 3072000 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run Z80 #1 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if (i == 1) + { + if(bombjackIRQ) + { + ZetNmi(); + } + } + ZetClose(); + + // Run Z80 #2 + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesSegment = ZetRun(nCyclesSegment); + nCyclesDone[nCurrentCPU] += nCyclesSegment; + ZetClose(); + + // Render Sound Segment + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + AY8910Update(2, &pAY8910Buffer[6], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + nSample += pAY8910Buffer[6][n] >> 2; + nSample += pAY8910Buffer[7][n] >> 2; + nSample += pAY8910Buffer[8][n] >> 2; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + nSoundBufferPos += nSegmentLength; + } + } + + // Make sure the buffer is entirely filled. + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + AY8910Update(2, &pAY8910Buffer[6], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + nSample += pAY8910Buffer[6][n] >> 2; + nSample += pAY8910Buffer[7][n] >> 2; + nSample += pAY8910Buffer[8][n] >> 2; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + /*ZetOpen(0); + if (BjRam[0xb000]) + ZetNmi(); + ZetClose();*/ + + ZetOpen(1); + ZetNmi(); + ZetClose(); + + + if (pBurnDraw != NULL) + { + BurnTransferClear(); + CalcAll(); + + BjRenderBgLayer(); + BjRenderFgLayer(); + BjDrawSprites(); + BurnTransferCopy(BjPalReal); + } + return 0; +} + +static int BjScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + ba.Data = RamStart; + ba.nLen = RamEnd-RamStart; + ba.szName = "All Ram"; + BurnAcb(&ba); + + ZetScan(nAction); // Scan Z80 + + // Scan critical driver variables + SCAN_VAR(bombjackIRQ); + SCAN_VAR(latch); + SCAN_VAR(DrvJoy1); + SCAN_VAR(DrvJoy2); + SCAN_VAR(BjDip); + } + + return 0; +} + +struct BurnDriver BurnDrvBombjack = { + "bombjack", NULL, NULL, "1984", + "Bomb Jack (set 1)\0", NULL, "Tehkan", "Bomb Jack", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING,2,HARDWARE_MISC_PRE90S, + NULL,BombjackRomInfo,BombjackRomName,DrvInputInfo,BjDIPInfo, + BjInit,BjExit,BjFrame,NULL,BjScan, + 0, NULL, NULL, NULL, NULL,224,256,3,4 +}; + +struct BurnDriver BurnDrvBombjac2 = { + "bombjac2", "bombjack", NULL, "1984", + "Bomb Jack (set 2)\0", NULL, "Tehkan", "Bomb Jack", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE,2,HARDWARE_MISC_PRE90S, + NULL,Bombjac2RomInfo,Bombjac2RomName,DrvInputInfo,BjDIPInfo, + BjInit,BjExit,BjFrame,NULL,BjScan, + 0, NULL, NULL, NULL, NULL,224,256,3,4 +}; diff --git a/src/burn/misc/pre90s/d_dotrikun.cpp b/src/burn/misc/pre90s/d_dotrikun.cpp new file mode 100644 index 0000000..af46091 --- /dev/null +++ b/src/burn/misc/pre90s/d_dotrikun.cpp @@ -0,0 +1,231 @@ + +/* +Dottori Kun (Head On's mini game) +(c)1990 SEGA + +CPU : Z-80 (4MHz) +SOUND : (none) + +14479.MPR ; PRG (FIRST VER) +14479A.MPR ; PRG (NEW VER) + +* This game is only for the test of cabinet +* BackRaster = WHITE on the FIRST version. +* BackRaster = BLACK on the NEW version. +* On the NEW version, push COIN-SW as TEST MODE. +* 0000-3FFF:ROM 8000-85FF:VRAM(128x96) 8600-87FF:WORK-RAM + +Based on MAME driver by Takahiro Nogi +*/ + +#include "burnint.h" + + +static unsigned char DrvJoy[8], DrvReset, *Mem, nColor; + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Up", BIT_DIGITAL, DrvJoy + 0, "p1 up" }, + {"P1 Down", BIT_DIGITAL, DrvJoy + 1, "p1 down", }, + {"P1 Left" , BIT_DIGITAL , DrvJoy + 2, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy + 3, "p1 right" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy + 4, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy + 5, "p1 fire 2"}, + {"P1 start" , BIT_DIGITAL , DrvJoy + 6, "p1 start" }, + {"P1 Coin" , BIT_DIGITAL , DrvJoy + 7, "p1 coin" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, +}; + +STDINPUTINFO(Drv); + + +unsigned char __fastcall dotrikun_in_port(unsigned short a) +{ + a &= 0xff; + + if (a == 0) { + unsigned char ret = 0; + for (int i = 0; i < 8; i++) ret |= DrvJoy[i] << i; + + return ~ret; + } + + return 0; +} + + +void __fastcall dotrikun_out_port(unsigned short a, unsigned char d) +{ + a &= 0xff; + + if (a == 0) { + nColor = d; + } +} + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + ba.Data = Mem + 0x4000; + ba.nLen = 0x0800; + ba.szName = "All Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + + SCAN_VAR(nColor); + } + + return 0; +} + + +static int DrvDoReset() +{ + DrvReset = 0; + memset (Mem + 0x4000, 0, 0x0800); + + ZetOpen(0); + ZetReset(); + ZetClose(); + + return 0; +} + + +static int DrvDraw() +{ +#define sw(n) ((nColor >> n) & 1 ? 0xff : 0) +#define color() BurnHighCol(pen >> 16, pen >> 8, pen, 0) + + unsigned int back_pen = (sw(3) << 16) | (sw(4) << 8) | sw(5); + unsigned int fore_pen = (sw(0) << 16) | (sw(1) << 8) | sw(2); + + for (int offs = 0; offs < 0x0600; offs++) + { + unsigned char x = offs << 4; + unsigned char y = offs >> 4 << 1; + unsigned char data = Mem[0x4000 + offs]; + + for (int i = 0; i < 8; i++) + { + unsigned int pen = (data & 0x80) ? fore_pen : back_pen; + + PutPix(pBurnDraw + (x + 0 + (y + 0) * 256) * nBurnBpp, color()); + PutPix(pBurnDraw + (x + 1 + (y + 0) * 256) * nBurnBpp, color()); + PutPix(pBurnDraw + (x + 0 + (y + 1) * 256) * nBurnBpp, color()); + PutPix(pBurnDraw + (x + 1 + (y + 1) * 256) * nBurnBpp, color()); + + x = x + 2; + data = data << 1; + } + } + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetOpen(0); + ZetRun(4000000 / 60); + ZetRaiseIrq(0); + ZetClose(); + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +static int DrvInit() +{ + Mem = (unsigned char*)malloc ( 0x4800 ); + if (Mem == NULL) { + return 1; + } + + if (BurnLoadRom(Mem, 0, 1)) return 1; + + ZetInit(1); + ZetOpen(0); + ZetMapArea (0x0000, 0x3fff, 0, Mem + 0x0000); // Read ROM + ZetMapArea (0x0000, 0x3fff, 2, Mem + 0x0000); // Fetch ROM + ZetMapArea (0x8000, 0x87ff, 0, Mem + 0x4000); // Read RAM + ZetMapArea (0x8000, 0x87ff, 1, Mem + 0x4000); // Write RAM + ZetMemEnd(); + ZetSetInHandler(dotrikun_in_port); + ZetSetOutHandler(dotrikun_out_port); + ZetClose(); + + DrvDoReset(); + return 0; +} + + +static int DrvExit() +{ + ZetExit(); + + DrvReset = 0; + free (Mem); + Mem = NULL; + + return 0; +} + + +// Dottori Kun (new version) + +static struct BurnRomInfo dotrikunRomDesc[] = { + { "14479a.mpr", 0x4000, 0xb77a50db, BRF_ESS | BRF_PRG }, // Z80 code +}; + +STD_ROM_PICK(dotrikun); +STD_ROM_FN(dotrikun); + +struct BurnDriver BurnDrvdotrikun = { + "dotrikun", NULL, NULL, "1990", + "Dottori Kun (new version)\0", NULL, "Sega", "Test Hardware", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 1, HARDWARE_MISC_PRE90S, + NULL, dotrikunRomInfo, dotrikunRomName, DrvInputInfo, NULL, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 192, 4, 3 +}; + + +// Dottori Kun (old version) + +static struct BurnRomInfo dotriku2RomDesc[] = { + { "14479.mpr", 0x4000, 0xa6aa7fa5, BRF_ESS | BRF_PRG }, // Z80 code +}; + +STD_ROM_PICK(dotriku2); +STD_ROM_FN(dotriku2); + +struct BurnDriver BurnDrvdotriku2 = { + "dotriku2", "dotrikun", NULL, "1990", + "Dottori Kun (old version)\0", NULL, "Sega", "Test Hardware", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 1, HARDWARE_MISC_PRE90S, + NULL, dotriku2RomInfo, dotriku2RomName, DrvInputInfo, NULL, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 192, 4, 3 +}; + + diff --git a/src/burn/misc/pre90s/d_epos.cpp b/src/burn/misc/pre90s/d_epos.cpp new file mode 100644 index 0000000..400ac44 --- /dev/null +++ b/src/burn/misc/pre90s/d_epos.cpp @@ -0,0 +1,701 @@ + +#include "burnint.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} +#include "bitswap.h" + +static unsigned int pens[0x20]; +static unsigned char *eposMem = NULL; +static unsigned char *eposRom, *eposRam; +static unsigned char DrvReset, DrvDips, palette; +static unsigned char DrvJoy[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static short* pAY8910Buffer[3]; +static short *pFMBuffer = NULL; + +//---------------------------------------------------------------------------------------------- +// Game inputs + +static struct BurnInputInfo DrvInputList[] = { + {"Coin", BIT_DIGITAL, DrvJoy + 0, "p1 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy + 1, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy + 2, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy + 7, "p1 up"}, + {"P1 Down", BIT_DIGITAL, DrvJoy + 8, "p1 down"}, + {"P1 Left", BIT_DIGITAL, DrvJoy + 4, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy + 3, "p1 right"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy + 5, "p1 fire 1"}, + {"P1 Button 2", BIT_DIGITAL, DrvJoy + 6, "p1 fire 2"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Service Mode", BIT_DIGITAL, DrvJoy + 10, "diag"}, + {"Dip Switches", BIT_DIPSWITCH, &DrvDips, "dip"}, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo megadonDIPList[] = +{ + // Defaults + {0x0B, 0xFF, 0xFF, 0x00, NULL}, + + {0, 0xFE, 0, 2, "Coinage"}, + {0x0B, 0x01, 0x01, 0x00, "1 Coin 1 Credit"}, + {0x0B, 0x01, 0x01, 0x01, "1 Coin 2 Credits"}, + + {0, 0xFE, 0, 2, "Fuel Consumption"}, + {0x0B, 0x01, 0x02, 0x00, "Slow"}, + {0x0B, 0x01, 0x02, 0x02, "Fast"}, + + {0, 0xFE, 0, 2, "Rotation"}, + {0x0B, 0x01, 0x04, 0x04, "Slow"}, + {0x0B, 0x01, 0x04, 0x00, "Fast"}, + + {0, 0xFE, 0, 2, "ERG"}, + {0x0B, 0x01, 0x08, 0x08, "Easy"}, + {0x0B, 0x01, 0x08, 0x00, "Hard"}, + + {0, 0xFE, 0, 2, "Enemy Fire Rate"}, + {0x0B, 0x01, 0x20, 0x20, "Slow"}, + {0x0B, 0x01, 0x20, 0x00, "Fast"}, + + {0, 0xFE, 0, 4, "Lives"}, + {0x0B, 0x01, 0x50, 0x00, "3"}, + {0x0B, 0x01, 0x50, 0x10, "4"}, + {0x0B, 0x01, 0x50, 0x40, "5"}, + {0x0B, 0x01, 0x50, 0x50, "6"}, + + {0, 0xFE, 0, 2, "Game Mode"}, + {0x0B, 0x01, 0x80, 0x00, "Arcade"}, + {0x0B, 0x01, 0x80, 0x80, "Contest"}, +}; + +STDDIPINFO(megadon); + +static struct BurnDIPInfo suprglobDIPList[] = +{ + // Defaults + {0x0B, 0xFF, 0xFF, 0x00, NULL}, + + {0, 0xFE, 0, 2, "Coinage"}, + {0x0B, 0x01, 0x01, 0x00, "1 Coin 1 Credit"}, + {0x0B, 0x01, 0x01, 0x01, "1 Coin 2 Credits"}, + + {0, 0xFE, 0, 8, "Difficulty"}, + {0x0B, 0x01, 0x26, 0x00, "1"}, + {0x0B, 0x01, 0x26, 0x02, "2"}, + {0x0B, 0x01, 0x26, 0x20, "3"}, + {0x0B, 0x01, 0x26, 0x22, "4"}, + {0x0B, 0x01, 0x26, 0x04, "5"}, + {0x0B, 0x01, 0x26, 0x06, "6"}, + {0x0B, 0x01, 0x26, 0x24, "7"}, + {0x0B, 0x01, 0x26, 0x26, "8"}, + + // Extra Glob condition + {0, 0xFE, 0, 2, "Bonus Life"}, + {0x0B, 0x02, 0x08, 0x00, "20000 pts"}, + {0x0B, 0x00, 0x26, 0x00, NULL}, + {0x0B, 0x02, 0x08, 0x08, "100000 pts"}, + {0x0B, 0x00, 0x26, 0x00, NULL}, + {0, 0xFE, 0, 2, "Bonus Life"}, + {0x0B, 0x02, 0x08, 0x00, "30000 pts"}, + {0x0B, 0x00, 0x26, 0x02, NULL}, + {0x0B, 0x02, 0x08, 0x08, "110000 pts"}, + {0x0B, 0x00, 0x26, 0x02, NULL}, + {0, 0xFE, 0, 2, "Bonus Life"}, + {0x0B, 0x02, 0x08, 0x00, "40000 pts"}, + {0x0B, 0x00, 0x26, 0x20, NULL}, + {0x0B, 0x02, 0x08, 0x08, "120000 pts"}, + {0x0B, 0x00, 0x26, 0x20, NULL}, + {0, 0xFE, 0, 2, "Bonus Life"}, + {0x0B, 0x02, 0x08, 0x00, "50000 pts"}, + {0x0B, 0x00, 0x26, 0x22, NULL}, + {0x0B, 0x02, 0x08, 0x08, "130000 pts"}, + {0x0B, 0x00, 0x26, 0x22, NULL}, + {0, 0xFE, 0, 2, "Bonus Life"}, + {0x0B, 0x02, 0x08, 0x00, "60000 pts"}, + {0x0B, 0x00, 0x26, 0x04, NULL}, + {0x0B, 0x02, 0x08, 0x08, "140000 pts"}, + {0x0B, 0x00, 0x26, 0x04, NULL}, + {0, 0xFE, 0, 2, "Bonus Life"}, + {0x0B, 0x02, 0x08, 0x00, "70000 pts"}, + {0x0B, 0x00, 0x26, 0x06, NULL}, + {0x0B, 0x02, 0x08, 0x08, "150000 pts"}, + {0x0B, 0x00, 0x26, 0x06, NULL}, + {0, 0xFE, 0, 2, "Bonus Life"}, + {0x0B, 0x02, 0x08, 0x00, "80000 pts"}, + {0x0B, 0x00, 0x26, 0x24, NULL}, + {0x0B, 0x02, 0x08, 0x08, "160000 pts"}, + {0x0B, 0x00, 0x26, 0x24, NULL}, + {0, 0xFE, 0, 2, "Bonus Life"}, + {0x0B, 0x02, 0x08, 0x00, "90000 pts"}, + {0x0B, 0x00, 0x26, 0x26, NULL}, + {0x0B, 0x02, 0x08, 0x08, "170000 pts"}, + {0x0B, 0x00, 0x26, 0x26, NULL}, + + {0, 0xFE, 0, 4, "Lives"}, + {0x0B, 0x01, 0x50, 0x00, "3"}, + {0x0B, 0x01, 0x50, 0x10, "4"}, + {0x0B, 0x01, 0x50, 0x40, "5"}, + {0x0B, 0x01, 0x50, 0x50, "6"}, + + {0, 0xFE, 0, 2, "Demo Sounds"}, + {0x0B, 0x01, 0x80, 0x80, "Off"}, + {0x0B, 0x01, 0x80, 0x00, "On"}, + +}; + +STDDIPINFO(suprglob); + +static struct BurnDIPInfo igmoDIPList[] = +{ + // Defaults + {0x0B, 0xFF, 0xFF, 0x00, NULL}, + + {0, 0xFE, 0, 2, "Coinage"}, + {0x0B, 0x01, 0x01, 0x00, "1 Coin 1 Credit"}, + {0x0B, 0x01, 0x01, 0x01, "1 Coin 2 Credits"}, + + {0, 0xFE, 0, 4, "Bonus Life"}, + {0x0B, 0x01, 0x22, 0x00, "20000"}, + {0x0B, 0x01, 0x22, 0x02, "40000"}, + {0x0B, 0x01, 0x22, 0x20, "60000"}, + {0x0B, 0x01, 0x22, 0x22, "80000"}, + + {0, 0xFE, 0, 8, "Difficulty"}, + {0x0B, 0x01, 0x8c, 0x00, "1"}, + {0x0B, 0x01, 0x8c, 0x04, "2"}, + {0x0B, 0x01, 0x8c, 0x08, "3"}, + {0x0B, 0x01, 0x8c, 0x0c, "4"}, + {0x0B, 0x01, 0x8c, 0x80, "5"}, + {0x0B, 0x01, 0x8c, 0x84, "6"}, + {0x0B, 0x01, 0x8c, 0x88, "7"}, + {0x0B, 0x01, 0x8c, 0x8c, "8"}, + + {0, 0xFE, 0, 4, "Lives"}, + {0x0B, 0x01, 0x50, 0x00, "3"}, + {0x0B, 0x01, 0x50, 0x10, "4"}, + {0x0B, 0x01, 0x50, 0x40, "5"}, + {0x0B, 0x01, 0x50, 0x50, "6"}, +}; + +STDDIPINFO(igmo); + + +//---------------------------------------------------------------------------------------------- +// Hardware emulation + +unsigned char __fastcall epos_read_port(unsigned short a) +{ + unsigned char ret; + + switch (a & 0xff) + { + case 0x00: + return DrvDips; + + case 0x01: + ret = DrvJoy[9]; // highest 2 bits used as protection + ret |= DrvJoy[10] << 4; // service mode + ret |= DrvJoy[0]; + ret |= DrvJoy[1] << 2; + ret |= DrvJoy[2] << 3; + + return ret ^ 0x3e; + + case 0x02: + ret = DrvJoy[3]; + ret |= DrvJoy[4] << 1; + ret |= DrvJoy[5] << 2; + ret |= DrvJoy[6] << 3; + ret |= DrvJoy[7] << 4; + ret |= DrvJoy[8] << 5; + + return ret ^ 0xff; + + case 0x03: + return 0; // input 3, not used + } + + return a; +} + + +void __fastcall epos_write_port(unsigned short a, unsigned char d) +{ + switch (a & 0xff) + { + case 0x00: // watchdog + break; + + case 0x01: // choose palette + palette = (d << 1) & 0x10; + break; + + case 0x02: // AY8910 write port 0 + AY8910Write(0, 1, d); + break; + + case 0x06: // AY8910 control port 0 + AY8910Write(0, 0, d); + break; + } +} + + +static int DrvDoReset() +{ + memset (eposRam, 0, 0x08800); + palette = 0; + DrvReset = 0; + + ZetOpen(0); + ZetReset(); + ZetClose(); + + AY8910Reset(0); + + return 0; +} + + +static int DrvInit() +{ + eposMem = (unsigned char *)calloc(1, 0x10000); + if (eposMem == NULL) { + return 1; + } + + pFMBuffer = (short *)malloc (nBurnSoundLen * 3 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + eposRom = eposMem; + eposRam = eposMem + 0x07800; + + // Load program Roms + for (int i = 0; i < 8; i++) { + if (BurnLoadRom(eposRom + i * 0x1000, i, 1)) return 1; + } + + // Load palette Prom + { + unsigned char prom[32] = { // in case the set lacks a prom dump + 0x00, 0xE1, 0xC3, 0xFC, 0xEC, 0xF8, 0x34, 0xFF, + 0x17, 0xF0, 0xEE, 0xEF, 0xAC, 0xC2, 0x1C, 0x07, + 0x00, 0xE1, 0xC3, 0xFC, 0xEC, 0xF8, 0x34, 0xFF, + 0x17, 0xF0, 0xEE, 0xEF, 0xAC, 0xC2, 0x1C, 0x07 + }; + + BurnLoadRom(prom, 8, 1); + + // Pre-calculate colors + for (int i = 0; i < 0x20; i++) { + pens[i] = BITSWAP24(prom[i], 7,6,5,7,6,6,7,5,4,3,2,4,3,3,4,2,1,0,1,0,1,1,0,1); + } + } + + + ZetInit(1); + ZetOpen(0); + + ZetMapArea(0x0000, 0xffff, 0, eposRom); // Read entire memory space + ZetMapArea(0x0000, 0xffff, 2, eposRom); // Fetch entire memory space + ZetMapArea(0x7800, 0xffff, 1, eposRam); // Allow writing in 0x7800 - 0xffff + + ZetMemEnd(); + + ZetSetInHandler(epos_read_port); + ZetSetOutHandler(epos_write_port); + + ZetClose(); + + // set protected bits + DrvJoy[9] = 0xc0; + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "suprglob") || + !strncmp(BurnDrvGetTextA(DRV_NAME), "theglob", 7)) + DrvJoy[9] = 0x80; + + // Snd + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + AY8910Init(0, 2750000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + AY8910Exit(0); + ZetExit(); + + free (pFMBuffer); + free (eposMem); + + pFMBuffer = NULL; + eposMem = eposRom = eposRam = NULL; + + return 0; +} + +static int DrvDraw() +{ +#define color(x) BurnHighCol((pens[palette | x] >> 16), (pens[palette | x] >> 8), pens[palette | x], 0) + + for (int i = 0; i < 0x8000; i++) + { + int x = (i % 136) * 2; + int y = (i / 136); + if (y > 235) continue; // screen is actually 240 pixels wide + y *= 272; + + PutPix(pBurnDraw + (x + y + 0) * nBurnBpp, color(eposRam[i + 0x800] & 0x0f)); + PutPix(pBurnDraw + (x + y + 1) * nBurnBpp, color(eposRam[i + 0x800] >> 0x04)); + } + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) DrvDoReset(); + + int nSoundBufferPos = 0; + + ZetOpen(0); + ZetRun(2750000 / 60); + ZetRaiseIrq(0xff); + ZetClose(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) DrvDraw(); + + return 0; +} + + +// Savestates +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + ba.Data = eposRam; + ba.nLen = 0x08800; + ba.szName = "All Ram"; + BurnAcb(&ba); + + ZetScan(nAction); // Scan Z80 + + AY8910Scan(nAction, pnMin); // Scan AY8910 + + // Scan critical driver variables + SCAN_VAR(palette); + } + + return 0; +} + + + +//---------------------------------------------------------------------------------------------- +// Drivers + + +// Megadon + +static struct BurnRomInfo megadonRomDesc[] = { + { "2732u10b.bin", 0x1000, 0xaf8fbe80, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "2732u09b.bin", 0x1000, 0x097d1e73, BRF_ESS | BRF_PRG }, // 1 + { "2732u08b.bin", 0x1000, 0x526784da, BRF_ESS | BRF_PRG }, // 2 + { "2732u07b.bin", 0x1000, 0x5b060910, BRF_ESS | BRF_PRG }, // 3 + { "2732u06b.bin", 0x1000, 0x8ac8af6d, BRF_ESS | BRF_PRG }, // 4 + { "2732u05b.bin", 0x1000, 0x052bb603, BRF_ESS | BRF_PRG }, // 5 + { "2732u04b.bin", 0x1000, 0x9b8b7e92, BRF_ESS | BRF_PRG }, // 6 + { "2716u11b.bin", 0x0800, 0x599b8b61, BRF_ESS | BRF_PRG }, // 7 + + { "74s288.bin", 0x0020, 0xc779ea99, BRF_GRA }, // 8 Color PROM +}; + +STD_ROM_PICK(megadon); +STD_ROM_FN(megadon); + +struct BurnDriver BurnDrvMegadon = { + "megadon", NULL, NULL, "1982", + "Megadon\0", NULL, "Epos Corporation (Photar Industries License)", "EPOS Tristar", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, megadonRomInfo, megadonRomName, DrvInputInfo, megadonDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 236, 272, 3, 4 +}; + + +// Catapult + +static struct BurnRomInfo catapultRomDesc[] = { + { "co3223.u10", 0x1000, 0x50abcfd2, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "co3223.u09", 0x1000, 0xfd5a9a1c, BRF_ESS | BRF_PRG }, // 1 + { "co3223.u08", 0x1000, 0x4bfc36f3, BRF_ESS | BRF_PRG }, // 2 BADADDR xxxx-xxxxxxx + { "co3223.u07", 0x1000, 0x4113bb99, BRF_ESS | BRF_PRG }, // 3 + { "co3223.u06", 0x1000, 0x966bb9f5, BRF_ESS | BRF_PRG }, // 4 + { "co3223.u05", 0x1000, 0x65f9fb9a, BRF_ESS | BRF_PRG }, // 5 + { "co3223.u04", 0x1000, 0x648453bc, BRF_ESS | BRF_PRG }, // 6 + { "co3223.u11", 0x0800, 0x08fb8c28, BRF_ESS | BRF_PRG }, // 7 + + { "co3223.u66", 0x0020, 0xe7de76a7, BRF_GRA }, // 8 Color PROM +}; + +STD_ROM_PICK(catapult); +STD_ROM_FN(catapult); + +struct BurnDriverD BurnDrvCatapult = { + "catapult", NULL, NULL, "1982", + "Catapult\0", "Bad dump", "Epos Corporation", "EPOS Tristar", + NULL, NULL, NULL, NULL, + BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, catapultRomInfo, catapultRomName, DrvInputInfo, igmoDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 236, 272, 6, 9 +}; + + +// Super Glob + +static struct BurnRomInfo suprglobRomDesc[] = { + { "u10", 0x1000, 0xc0141324, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "u9", 0x1000, 0x58be8128, BRF_ESS | BRF_PRG }, // 1 + { "u8", 0x1000, 0x6d088c16, BRF_ESS | BRF_PRG }, // 2 + { "u7", 0x1000, 0xb2768203, BRF_ESS | BRF_PRG }, // 3 + { "u6", 0x1000, 0x976c8f46, BRF_ESS | BRF_PRG }, // 4 + { "u5", 0x1000, 0x340f5290, BRF_ESS | BRF_PRG }, // 5 + { "u4", 0x1000, 0x173bd589, BRF_ESS | BRF_PRG }, // 6 + { "u11", 0x0800, 0xd45b740d, BRF_ESS | BRF_PRG }, // 7 + + { "82s123.u66", 0x0020, 0xf4f6ddc5, BRF_GRA }, // 8 Color PROM +}; + +STD_ROM_PICK(suprglob); +STD_ROM_FN(suprglob); + +struct BurnDriver BurnDrvSuprglob = { + "suprglob", NULL, NULL, "1983", + "Super Glob\0", NULL, "Epos Corporation", "EPOS Tristar", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, suprglobRomInfo, suprglobRomName, DrvInputInfo, suprglobDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 236, 272, 3, 4 +}; + + +// The Glob + +static struct BurnRomInfo theglobRomDesc[] = { + { "globu10.bin", 0x1000, 0x08fdb495, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "globu9.bin", 0x1000, 0x827cd56c, BRF_ESS | BRF_PRG }, // 1 + { "globu8.bin", 0x1000, 0xd1219966, BRF_ESS | BRF_PRG }, // 2 + { "globu7.bin", 0x1000, 0xb1649da7, BRF_ESS | BRF_PRG }, // 3 + { "globu6.bin", 0x1000, 0xb3457e67, BRF_ESS | BRF_PRG }, // 4 + { "globu5.bin", 0x1000, 0x89d582cd, BRF_ESS | BRF_PRG }, // 5 + { "globu4.bin", 0x1000, 0x7ee9fdeb, BRF_ESS | BRF_PRG }, // 6 + { "globu11.bin", 0x0800, 0x9e05dee3, BRF_ESS | BRF_PRG }, // 7 + + { "82s123.u66", 0x0020, 0xf4f6ddc5, BRF_GRA }, // 8 Color PROM +}; + +STD_ROM_PICK(theglob); +STD_ROM_FN(theglob); + +struct BurnDriver BurnDrvTheglob = { + "theglob", "suprglob", NULL, "1983", + "The Glob\0", NULL, "Epos Corporation", "EPOS Tristar", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, theglobRomInfo, theglobRomName, DrvInputInfo, suprglobDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 236, 272, 3, 4 +}; + + +// The Glob (earlier) + +static struct BurnRomInfo theglob2RomDesc[] = { + { "611293.u10", 0x1000, 0x870af7ce, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "611293.u9", 0x1000, 0xa3679782, BRF_ESS | BRF_PRG }, // 1 + { "611293.u8", 0x1000, 0x67499d1a, BRF_ESS | BRF_PRG }, // 2 + { "611293.u7", 0x1000, 0x55e53aac, BRF_ESS | BRF_PRG }, // 3 + { "611293.u6", 0x1000, 0xc64ad743, BRF_ESS | BRF_PRG }, // 4 + { "611293.u5", 0x1000, 0xf93c3203, BRF_ESS | BRF_PRG }, // 5 + { "611293.u4", 0x1000, 0xceea0018, BRF_ESS | BRF_PRG }, // 6 + { "611293.u11", 0x0800, 0x6ac83f9b, BRF_ESS | BRF_PRG }, // 7 + + { "82s123.u66", 0x0020, 0xf4f6ddc5, BRF_GRA }, // 8 Color PROM +}; + +STD_ROM_PICK(theglob2); +STD_ROM_FN(theglob2); + +struct BurnDriver BurnDrvTheglob2 = { + "theglob2", "suprglob", NULL, "1983", + "The Glob (earlier)\0", NULL, "Epos Corporation", "EPOS Tristar", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, theglob2RomInfo, theglob2RomName, DrvInputInfo, suprglobDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 236, 272, 3, 4 +}; + + +// The Glob (set 3) + +static struct BurnRomInfo theglob3RomDesc[] = { + { "theglob3.u10", 0x1000, 0x969cfaf6, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "theglob3.u9", 0x1000, 0x8e6c010a, BRF_ESS | BRF_PRG }, // 1 + { "theglob3.u8", 0x1000, 0x1c1ca5c8, BRF_ESS | BRF_PRG }, // 2 + { "theglob3.u7", 0x1000, 0xa54b9d22, BRF_ESS | BRF_PRG }, // 3 + { "theglob3.u6", 0x1000, 0x5a6f82a9, BRF_ESS | BRF_PRG }, // 4 + { "theglob3.u5", 0x1000, 0x72f935db, BRF_ESS | BRF_PRG }, // 5 + { "theglob3.u4", 0x1000, 0x81db53ad, BRF_ESS | BRF_PRG }, // 6 + { "theglob3.u11", 0x0800, 0x0e2e6359, BRF_ESS | BRF_PRG }, // 7 + + { "82s123.u66", 0x0020, 0xf4f6ddc5, BRF_GRA }, // 8 Color PROM +}; + +STD_ROM_PICK(theglob3); +STD_ROM_FN(theglob3); + +struct BurnDriver BurnDrvTheglob3 = { + "theglob3", "suprglob", NULL, "1983", + "The Glob (set 3)\0", NULL, "Epos Corporation", "EPOS Tristar", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, theglob3RomInfo, theglob3RomName, DrvInputInfo, suprglobDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 236, 272, 3, 4 +}; + + +// IGMO + +static struct BurnRomInfo igmoRomDesc[] = { + { "igmo-u10.732", 0x1000, 0xa9f691a4, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "igmo-u9.732", 0x1000, 0x3c133c97, BRF_ESS | BRF_PRG }, // 1 + { "igmo-u8.732", 0x1000, 0x5692f8d8, BRF_ESS | BRF_PRG }, // 2 + { "igmo-u7.732", 0x1000, 0x630ae2ed, BRF_ESS | BRF_PRG }, // 3 + { "igmo-u6.732", 0x1000, 0xd3f20e1d, BRF_ESS | BRF_PRG }, // 4 + { "igmo-u5.732", 0x1000, 0xe26bb391, BRF_ESS | BRF_PRG }, // 5 + { "igmo-u4.732", 0x1000, 0x762a4417, BRF_ESS | BRF_PRG }, // 6 + { "igmo-u11.716", 0x0800, 0x8c675837, BRF_ESS | BRF_PRG }, // 7 + + { "82s123.u66", 0x0020, 0x00000000, BRF_GRA | BRF_NODUMP }, // 8 missing +}; + +STD_ROM_PICK(igmo); +STD_ROM_FN(igmo); + +struct BurnDriver BurnDrvIgmo = { + "igmo", NULL, NULL, "1984", + "IGMO\0", "Missing color Prom (Incorrect Color)", "Epos Corporation", "EPOS Tristar", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, igmoRomInfo, igmoRomName, DrvInputInfo, igmoDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 236, 272, 3, 4 +}; + + +// The Dealer + +static struct BurnRomInfo dealerRomDesc[] = { + { "u1.bin", 0x2000, 0xe06f3563, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "u2.bin", 0x2000, 0x726bbbd6, BRF_ESS | BRF_PRG }, // 1 + { "u3.bin", 0x2000, 0xab721455, BRF_ESS | BRF_PRG }, // 2 + { "u4.bin", 0x2000, 0xddb903e4, BRF_ESS | BRF_PRG }, // 3 + + { "82s123.u66", 0x0020, 0x00000000, BRF_GRA | BRF_NODUMP }, // 4 missing +}; + +STD_ROM_PICK(dealer); +STD_ROM_FN(dealer); + +int dealerInit() +{ + return 1; +} + +struct BurnDriverD BurnDrvDealer = { + "dealer", NULL, NULL, "198?", + "The Dealer\0", "Bad dump", "Epos Corporation", "EPOS Tristar", + NULL, NULL, NULL, NULL, + BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, dealerRomInfo, dealerRomName, DrvInputInfo, igmoDIPInfo, + dealerInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 236, 272, 3, 4 +}; + + +// Revenger + +static struct BurnRomInfo revengerRomDesc[] = { + { "r06124.u1", 0x2000, 0xfad1a2a5, BRF_ESS | BRF_PRG }, // 0 Z80 code + { "r06124.u2", 0x2000, 0xa8e0ee7b, BRF_ESS | BRF_PRG }, // 1 + { "r06124.u3", 0x2000, 0xcca414a5, BRF_ESS | BRF_PRG }, // 2 + { "r06124.u4", 0x2000, 0x0b81c303, BRF_ESS | BRF_PRG }, // 3 + + { "82s123.u66", 0x0020, 0x00000000, BRF_GRA | BRF_NODUMP }, // 4 missing +}; + +STD_ROM_PICK(revenger); +STD_ROM_FN(revenger); + +struct BurnDriverD BurnDrvRevenger = { + "revenger", NULL, NULL, "1984", + "Revenger\0", "Bad dump", "Epos Corporation", "EPOS Tristar", + NULL, NULL, NULL, NULL, + BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, revengerRomInfo, revengerRomName, DrvInputInfo, igmoDIPInfo, + dealerInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 236, 272, 3, 4 +}; diff --git a/src/burn/misc/pre90s/d_exedexes.cpp b/src/burn/misc/pre90s/d_exedexes.cpp new file mode 100644 index 0000000..27ab811 --- /dev/null +++ b/src/burn/misc/pre90s/d_exedexes.cpp @@ -0,0 +1,817 @@ +// FB Alpha Exed Exes driver module +// Based on MAME driver by Richard Davies, Paul Swan, and various others + +#include "tiles_generic.h" +#include "sn76496.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +static unsigned char *Mem, *MemEnd; +static unsigned char *Rom0, *Rom1, *Gfx0, *Gfx1, *Gfx2, *Gfx3, *Gfx4, *Prom; +static short *pAY8910Buffer[3], *pFMBuffer = NULL; +static unsigned int *Palette, *DrvPalette; +static unsigned char DrvRecalc; + +static unsigned char *fg_tile_transp; + +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvJoy3[8], DrvDips[2], DrvInputs[3], DrvReset; + +static unsigned char exedexes_soundlatch; + +static unsigned char exedexes_txt_enable; +static unsigned char exedexes_obj_enable; +static unsigned char exedexes_bg_enable; +static unsigned char exedexes_fg_enable; + +static unsigned short exedexes_nbg_yscroll; +static unsigned short exedexes_nbg_xscroll; +static unsigned short exedexes_bg_xscroll; + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1" , BIT_DIGITAL , DrvJoy1 + 6, "p1 coin" }, + {"Coin 2" , BIT_DIGITAL , DrvJoy1 + 7, "p2 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 0, "p1 start" }, + {"P2 Start" , BIT_DIGITAL , DrvJoy1 + 1, "p2 start" }, + + {"P1 Right" , BIT_DIGITAL , DrvJoy2 + 0, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy2 + 1, "p1 left" }, + {"P1 Down" , BIT_DIGITAL , DrvJoy2 + 2, "p1 down" }, + {"P1 Up" , BIT_DIGITAL , DrvJoy2 + 3, "p1 up" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy2 + 5, "p1 fire 2"}, + + {"P2 Right" , BIT_DIGITAL , DrvJoy3 + 0, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy3 + 1, "p2 left" }, + {"P2 Down" , BIT_DIGITAL , DrvJoy3 + 2, "p2 down" }, + {"P2 Up" , BIT_DIGITAL , DrvJoy3 + 3, "p2 up" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy3 + 4, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy3 + 5, "p2 fire 2"}, + + {"Service" , BIT_DIGITAL , DrvJoy1 + 5, "service" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDips + 0, "dip 1" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDips + 1, "dip 2" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x12, 0xff, 0xff, 0xdf, NULL }, + {0x13, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x12, 0x01, 0x03, 0x02, "Easy" }, + {0x12, 0x01, 0x03, 0x03, "Normal" }, + {0x12, 0x01, 0x03, 0x01, "Hard" }, + {0x12, 0x01, 0x03, 0x00, "Hardest" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x12, 0x01, 0x0c, 0x08, "1" }, + {0x12, 0x01, 0x0c, 0x04, "2" }, + {0x12, 0x01, 0x0c, 0x0c, "3" }, + {0x12, 0x01, 0x0c, 0x00, "5" }, + + {0 , 0xfe, 0 , 2 , "2 Players Game" }, + {0x12, 0x01, 0x10, 0x00, "1 Credit" }, + {0x12, 0x01, 0x10, 0x10, "2 Credits" }, + + {0 , 0xfe, 0 , 2 , "Language" }, + {0x12, 0x01, 0x20, 0x00, "English" }, + {0x12, 0x01, 0x20, 0x20, "Japanese" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x12, 0x01, 0x40, 0x40, "Off" }, + {0x12, 0x01, 0x40, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Service Mode" }, + {0x12, 0x01, 0x80, 0x80, "Off" }, + {0x12, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x13, 0x01, 0x07, 0x00, "4 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x01, "3 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x02, "2 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x13, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x07, 0x04, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x07, 0x03, "1 Coin 5 Plays" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x13, 0x01, 0x38, 0x00, "4 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x08, "3 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x10, "2 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x13, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x38, 0x20, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x38, 0x18, "1 Coin 5 Plays" }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x13, 0x01, 0x40, 0x00, "No" }, + {0x13, 0x01, 0x40, 0x40, "Yes" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x13, 0x01, 0x80, 0x00, "Off" }, + {0x13, 0x01, 0x80, 0x80, "On" }, +}; + +STDDIPINFO(Drv); + +unsigned char __fastcall exedexes_cpu0_read(unsigned short address) +{ + switch (address) + { + case 0xc000: + case 0xc001: + case 0xc002: + return DrvInputs[address & 3]; + + case 0xc003: + case 0xc004: + return DrvDips[~address & 1]; + } + + return 0; +} + +void __fastcall exedexes_cpu0_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0xc800: + exedexes_soundlatch = data; + break; + + case 0xc804: + exedexes_txt_enable = data >> 7; + break; + + case 0xc806: + break; + + case 0xd800: + exedexes_nbg_yscroll = (exedexes_nbg_yscroll & 0xff00) | (data << 0); + break; + + case 0xd801: + exedexes_nbg_yscroll = (exedexes_nbg_yscroll & 0x00ff) | (data << 8); + break; + + case 0xd802: + exedexes_nbg_xscroll = (exedexes_nbg_xscroll & 0xff00) | (data << 0); + break; + + case 0xd803: + exedexes_nbg_xscroll = (exedexes_nbg_xscroll & 0x00ff) | (data << 8); + break; + + case 0xd804: + exedexes_bg_xscroll = (exedexes_bg_xscroll & 0xff00) | (data << 0); + break; + + case 0xd805: + exedexes_bg_xscroll = (exedexes_bg_xscroll & 0x00ff) | (data << 8); + break; + + case 0xd807: + exedexes_bg_enable = (data >> 4) & 1; + exedexes_fg_enable = (data >> 5) & 1; + exedexes_obj_enable = (data >> 6) & 1; + break; + } +} + +unsigned char __fastcall exedexes_cpu1_read(unsigned short address) +{ + switch (address) + { + case 0x6000: + return exedexes_soundlatch; + } + + return 0; +} + +void __fastcall exedexes_cpu1_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0x8000: + case 0x8001: + AY8910Write(0, address & 1, data); + break; + + case 0x8002: + case 0x8003: + SN76496Write(address & 1, data); + break; + } +} + +static inline void DrvMakeInputs() +{ + DrvInputs[0] = DrvInputs[1] = DrvInputs[2] = 0xff; + + for (int i = 0; i < 8; i++) { + DrvInputs[0] ^= (DrvJoy1[i] & 1) << i; + DrvInputs[1] ^= (DrvJoy2[i] & 1) << i; + DrvInputs[2] ^= (DrvJoy3[i] & 1) << i; + } +} + +static int DrvDoReset() +{ + DrvReset = 0; + + memset (Rom0 + 0xd000, 0, 0x3000); + memset (Rom1 + 0x4000, 0, 0x0800); + + exedexes_soundlatch = 0; + exedexes_txt_enable = 0; + exedexes_obj_enable = 0; + exedexes_bg_enable = 0; + exedexes_fg_enable = 0; + exedexes_nbg_yscroll = 0; + exedexes_nbg_xscroll = 0; + exedexes_bg_xscroll = 0; + + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + } + + AY8910Reset(0); + + return 0; +} + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + Rom0 = Next; Next += 0x10000; + Rom1 = Next; Next += 0x05000; + + Gfx0 = Next; Next += 0x08000; + Gfx1 = Next; Next += 0x10000; + Gfx2 = Next; Next += 0x10000; + Gfx3 = Next; Next += 0x10000; + + Gfx4 = Next; Next += 0x06000; + + Prom = Next; Next += 0x00800; + + fg_tile_transp = Next; Next += 0x00100; + + Palette = (unsigned int*)Next; Next += 0x00400 * sizeof(unsigned int); + DrvPalette = (unsigned int*)Next; Next += 0x00400 * sizeof(unsigned int); + + pFMBuffer = (short*)Next; Next += (nBurnSoundLen * 3 * sizeof(short)); + + MemEnd = Next; + + return 0; +} + +static int PaletteInit() +{ + unsigned int *tmp = (unsigned int*)malloc(0x100 * sizeof(int)); + if (tmp == NULL) { + return 1; + } + + for (int i = 0; i < 0x100; i++) + { + int r = Prom[i + 0x000]; + int g = Prom[i + 0x100]; + int b = Prom[i + 0x200]; + + tmp[i] = (r << 20) | (r << 16) | (g << 12) | (g << 8) | (b << 4) | b; + } + + Prom += 0x300; + + for (int i = 0; i < 0x100; i++) { + Palette[i] = tmp[Prom[i] | 0xc0]; + } + + for (int i = 0x100; i < 0x200; i++) { + Palette[i] = tmp[Prom[i] | 0x00]; + } + + for (int i = 0x200; i < 0x300; i++) { + Palette[i] = tmp[Prom[i] | 0x40]; + } + + for (int i = 0x300; i < 0x400; i++) { + int entry = Prom[i] | (Prom[i + 0x100] << 4) | 0x80; + Palette[i] = tmp[entry]; + } + + free (tmp); + + return 0; +} + +static int GraphicsDecode() +{ + static int TilePlanes[2] = { 0x004, 0x000 }; + static int SpriPlanes[4] = { 0x20004, 0x20000, 0x00004, 0x00000 }; + static int TileXOffs[32] = { 0x000, 0x001, 0x002, 0x003, 0x008, 0x009, 0x00a, 0x00b, + 0x200, 0x201, 0x202, 0x203, 0x208, 0x209, 0x20a, 0x20b, + 0x400, 0x401, 0x402, 0x403, 0x408, 0x409, 0x40a, 0x40b, + 0x600, 0x601, 0x602, 0x603, 0x608, 0x609, 0x60a, 0x60b }; + static int SpriXOffs[16] = { 0x000, 0x001, 0x002, 0x003, 0x008, 0x009, 0x00a, 0x00b, + 0x100, 0x101, 0x102, 0x103, 0x108, 0x109, 0x10a, 0x10b }; + static int TileYOffs[32] = { 0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, + 0x080, 0x090, 0x0a0, 0x0b0, 0x0c0, 0x0d0, 0x0e0, 0x0f0, + 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160, 0x170, + 0x180, 0x190, 0x1a0, 0x1b0, 0x1c0, 0x1d0, 0x1e0, 0x1f0 }; + + unsigned char *tmp = (unsigned char*)malloc(0x8000); + if (tmp == NULL) { + return 1; + } + + memcpy (tmp, Gfx0, 0x02000); + + GfxDecode(0x200, 2, 8, 8, TilePlanes, TileXOffs, TileYOffs, 0x080, tmp, Gfx0); + + memcpy (tmp, Gfx1, 0x04000); + + GfxDecode(0x040, 2, 32, 32, TilePlanes, TileXOffs, TileYOffs, 0x800, tmp, Gfx1); + + memcpy (tmp, Gfx2, 0x08000); + + GfxDecode(0x100, 4, 16, 16, SpriPlanes, SpriXOffs, TileYOffs, 0x200, tmp, Gfx2); + + memcpy (tmp, Gfx3, 0x08000); + + GfxDecode(0x100, 4, 16, 16, SpriPlanes, SpriXOffs, TileYOffs, 0x200, tmp, Gfx3); + + for (int i = 0; i < 0x10000; i++) { + if (Gfx2[i]) fg_tile_transp[i>>8] = 1; + } + + free (tmp); + + return 0; +} + +static int DrvInit() +{ + int nLen; + + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + for (int i = 0; i < 3; i++) { + pAY8910Buffer[i] = pFMBuffer + nBurnSoundLen * i; + } + + { + for (int i = 0; i < 3; i++) { + if (BurnLoadRom(Rom0 + i * 0x4000, i + 0, 1)) return 1; + } + + if (BurnLoadRom(Rom1, 3, 1)) return 1; + if (BurnLoadRom(Gfx0, 4, 1)) return 1; + if (BurnLoadRom(Gfx1, 5, 1)) return 1; + + for (int i = 0; i < 2; i++) { + if (BurnLoadRom(Gfx2 + i * 0x4000, i + 6, 1)) return 1; + if (BurnLoadRom(Gfx3 + i * 0x4000, i + 8, 1)) return 1; + if (BurnLoadRom(Gfx4 + i * 0x4000, i + 10, 1)) return 1; + } + + for (int i = 0; i < 8; i++) { + if (BurnLoadRom(Prom + i * 0x0100, i + 12, 1)) return 1; + } + + if (GraphicsDecode()) return 1; + if (PaletteInit()) return 1; + } + + ZetInit(2); + ZetOpen(0); + ZetMapArea(0x0000, 0xbfff, 0, Rom0 + 0x0000); + ZetMapArea(0x0000, 0xbfff, 2, Rom0 + 0x0000); + ZetMapArea(0xd000, 0xd7ff, 0, Rom0 + 0xd000); + ZetMapArea(0xd000, 0xd7ff, 1, Rom0 + 0xd000); + ZetMapArea(0xe000, 0xefff, 0, Rom0 + 0xe000); + ZetMapArea(0xe000, 0xefff, 1, Rom0 + 0xe000); + ZetMapArea(0xe000, 0xefff, 2, Rom0 + 0xe000); + ZetMapArea(0xf000, 0xffff, 0, Rom0 + 0xf000); + ZetMapArea(0xf000, 0xffff, 1, Rom0 + 0xf000); + ZetSetWriteHandler(exedexes_cpu0_write); + ZetSetReadHandler(exedexes_cpu0_read); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetMapArea(0x0000, 0x3fff, 0, Rom1 + 0x0000); + ZetMapArea(0x0000, 0x3fff, 2, Rom1 + 0x0000); + ZetMapArea(0x4000, 0x47ff, 0, Rom1 + 0x4000); + ZetMapArea(0x4000, 0x47ff, 1, Rom1 + 0x4000); + ZetMapArea(0x4000, 0x47ff, 2, Rom1 + 0x4000); + ZetSetWriteHandler(exedexes_cpu1_write); + ZetSetReadHandler(exedexes_cpu1_read); + ZetMemEnd(); + ZetClose(); + + AY8910Init(0, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + SN76489Init(0, 3000000, 0); + SN76489Init(1, 3000000, 1); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + AY8910Exit(0); + SN76496Exit(); + ZetExit(); + GenericTilesExit(); + + free (Mem); + + Mem = MemEnd = Rom0 = Rom1 = NULL; + Gfx0 = Gfx1 = Gfx2 = Gfx3 = Gfx4 = Prom = NULL; + for (int i = 0; i < 3; i++) pAY8910Buffer[3] = NULL; + Palette = DrvPalette = NULL; + fg_tile_transp = NULL; + pFMBuffer = NULL; + DrvRecalc = 0; + + return 0; +} + + +static void draw_sprites(int priority) +{ + if (!exedexes_obj_enable) return; + + for (int offs = 0x0fe0; offs >= 0; offs -= 0x20) + { + if ((Rom0[0xf000 + offs + 1] & 0x40) == priority) + { + int code = Rom0[0xf000 + offs]; + int color = Rom0[0xf001 + offs] & 0x0f; + int flipx = Rom0[0xf001 + offs] & 0x10; + int flipy = Rom0[0xf001 + offs] & 0x20; + int sx = Rom0[0xf003 + offs] - ((Rom0[0xf001 + offs] & 0x80) << 1); + int sy = Rom0[0xf002 + offs] - 0x10; + + if (flipy) { + if (flipx) { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x300, Gfx3); + } else { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x300, Gfx3); + } + } else { + if (flipx) { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x300, Gfx3); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x300, Gfx3); + } + } + } + } +} + +static inline void draw_8x8(int sx, int sy, int code, int color) +{ + unsigned char *src = Gfx0 + (code << 6); + color <<= 2; + + for (int y = sy; y < sy + 8; y++) { + for (int x = sx; x < sx + 8; x++, src++) { + if (y < 0 || x < 0 || y >= nScreenHeight || x >= nScreenWidth) continue; + + int pxl = color | *src; + if (Prom[pxl] == 0x0f) continue; + + pTransDraw[(y * nScreenWidth) + x] = pxl; + } + } +} + +static int DrvDraw() +{ + if (DrvRecalc) { + for (int i = 0; i < 0x400; i++) { + int col = Palette[i]; + DrvPalette[i] = BurnHighCol(col >> 16, col >> 8, col, 0); + } + } + + if (exedexes_bg_enable) + { + for (int i = 0; i < 16 * 8; i++) { + int sx = ((i & 0x0f) << 5); + int sy = (i >> 4) << 5; + + int sxscr = sx + exedexes_bg_xscroll; + + sx -= (exedexes_bg_xscroll & 0x1f); + + if (sx > 0x100) continue; + sy -= 0x10; + + int offset = ((sxscr & 0xe0) >> 5) | ((sy & 0xe0) >> 2) | ((sxscr & 0x3f00) >> 1) | 0x4000; + + int attr = Gfx4[offset]; + int color = Gfx4[offset + 0x40]; + int code = attr & 0x3f; + int flipx = attr & 0x40; + int flipy = attr & 0x80; + + if (flipy) { + if (flipx) { + Render32x32Tile_FlipXY_Clip(pTransDraw, code, sx, sy, color, 2, 0x100, Gfx1); + } else { + Render32x32Tile_FlipY_Clip(pTransDraw, code, sx, sy, color, 2, 0x100, Gfx1); + } + } else { + if (flipx) { + Render32x32Tile_FlipX_Clip(pTransDraw, code, sx, sy, color, 2, 0x100, Gfx1); + } else { + Render32x32Tile_Clip(pTransDraw, code, sx, sy, color, 2, 0x100, Gfx1); + } + } + } + } else { + memset(pTransDraw, 0, nScreenWidth * nScreenHeight * sizeof (short)); + } + + draw_sprites(0x40); + + if (exedexes_fg_enable) + { + for (int i = 0; i < 32 * 16; i++) { + int sx = (i & 0x1f) << 4; + int sy = (i >> 5) << 4; + + int vx = sx + exedexes_nbg_yscroll; + int vy = sy + exedexes_nbg_xscroll; + + sx -= exedexes_nbg_yscroll & 0x0f; + sy -= exedexes_nbg_xscroll & 0x0f; + + if (sx > 0x100) continue; + + int offset = ((vx & 0xf0) >> 4) | (vy & 0xf0) | (vx & 0x700) | ((vy & 0x700) << 3); + + int code = Gfx4[offset]; + + if (!fg_tile_transp[code]) continue; + sy -= 0x10; + + Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, 0, 2, 0, 0x200, Gfx2); + } + } + + draw_sprites(0); + + if (exedexes_txt_enable) + { + for (int i = 0x40; i < 0x3c0; i++) { + int sx = (i & 0x1f) << 3; + int sy = ((i >> 5) << 3) - 0x10; + int code = Rom0[0xd000 | i] | ((Rom0[0xd400 | i] & 0x80) << 1); + int color = Rom0[0xd400 | i] & 0x3f; + + if (code == 0x0024) continue; + + draw_8x8(sx, sy, code, color); + //Render8x8Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 2, 0, 0, Gfx0); + } + } + + BurnTransferCopy(DrvPalette); + + return 0; +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + DrvMakeInputs(); + + int nInterleave = 16; + int nCyclesDone[2] = { 0, 0 }; + int nCyclesTotal[2] = { 4000000 / 60, 3000000 / 60 }; + + for (int i = 0; i < nInterleave; i++) + { + int nCycleSegment; + + ZetOpen(0); + nCycleSegment = (nCyclesTotal[0] - nCyclesDone[0]) / (nInterleave - i); + nCyclesDone[0] += ZetRun(nCycleSegment); + if (i == ((nInterleave / 2) - 1)) ZetRaiseIrq(0xd7); + if (i == ( nInterleave - 1)) ZetRaiseIrq(0xcf); + ZetClose(); + + ZetOpen(1); + nCycleSegment = (nCyclesTotal[1] - nCyclesDone[1]) / (nInterleave - i); + nCyclesDone[1] += ZetRun(nCycleSegment); + if ((i & 3) == 3) ZetRaiseIrq(0); + ZetClose(); + } + + if (pBurnSoundOut) { + SN76496Update(0, pBurnSoundOut, nBurnSoundLen); + SN76496Update(1, pBurnSoundOut, nBurnSoundLen); + + int nSample; + if (nBurnSoundLen) { + AY8910Update(0, &pAY8910Buffer[0], nBurnSoundLen); + for (int n = 0; n < nBurnSoundLen; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample >>= 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pBurnSoundOut[(n << 1) | 0] |= nSample; + pBurnSoundOut[(n << 1) | 1] |= nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom0 + 0xd000; + ba.nLen = 0x3000; + ba.szName = "All CPU #0 Ram"; + BurnAcb(&ba); + + ba.Data = Rom1 + 0x4000; + ba.nLen = 0x0800; + ba.szName = "All CPU #1 Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + AY8910Scan(nAction, pnMin); + SN76496Scan(nAction, pnMin); + + SCAN_VAR(exedexes_soundlatch); + SCAN_VAR(exedexes_txt_enable); + SCAN_VAR(exedexes_obj_enable); + SCAN_VAR(exedexes_bg_enable); + SCAN_VAR(exedexes_fg_enable); + SCAN_VAR(exedexes_nbg_yscroll); + SCAN_VAR(exedexes_nbg_xscroll); + SCAN_VAR(exedexes_bg_xscroll); + } + + return 0; +} + + +// Exed Exes + +static struct BurnRomInfo exedexesRomDesc[] = { + { "11m_ee04.bin", 0x4000, 0x44140dbd, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "10m_ee03.bin", 0x4000, 0xbf72cfba, 1 | BRF_PRG | BRF_ESS }, // 1 + { "09m_ee02.bin", 0x4000, 0x7ad95e2f, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "11e_ee01.bin", 0x4000, 0x73cdf3b2, 2 | BRF_PRG | BRF_ESS }, // 3 Z80 #1 Code + + { "05c_ee00.bin", 0x2000, 0xcadb75bd, 3 | BRF_GRA }, // 4 Characters + + { "h01_ee08.bin", 0x4000, 0x96a65c1d, 4 | BRF_GRA }, // 5 32x32 tiles + + { "a03_ee06.bin", 0x4000, 0x6039bdd1, 5 | BRF_GRA }, // 6 16x16 tiles + { "a02_ee05.bin", 0x4000, 0xb32d8252, 5 | BRF_GRA }, // 7 + + { "j11_ee10.bin", 0x4000, 0xbc83e265, 6 | BRF_GRA }, // 8 Sprites + { "j12_ee11.bin", 0x4000, 0x0e0f300d, 6 | BRF_GRA }, // 9 + + { "c01_ee07.bin", 0x4000, 0x3625a68d, 7 | BRF_GRA }, // 10 Tile Maps + { "h04_ee09.bin", 0x2000, 0x6057c907, 7 | BRF_GRA }, // 11 + + { "02d_e-02.bin", 0x0100, 0x8d0d5935, 8 | BRF_GRA }, // 12 Color Proms + { "03d_e-03.bin", 0x0100, 0xd3c17efc, 8 | BRF_GRA }, // 13 + { "04d_e-04.bin", 0x0100, 0x58ba964c, 8 | BRF_GRA }, // 14 + { "06f_e-05.bin", 0x0100, 0x35a03579, 8 | BRF_GRA }, // 15 + { "l04_e-10.bin", 0x0100, 0x1dfad87a, 8 | BRF_GRA }, // 16 + { "c04_e-07.bin", 0x0100, 0x850064e0, 8 | BRF_GRA }, // 17 + { "l09_e-11.bin", 0x0100, 0x2bb68710, 8 | BRF_GRA }, // 18 + { "l10_e-12.bin", 0x0100, 0x173184ef, 8 | BRF_GRA }, // 19 + + { "06l_e-06.bin", 0x0100, 0x712ac508, 0 | BRF_OPT }, // 20 Misc. Proms + { "k06_e-08.bin", 0x0100, 0x0eaf5158, 0 | BRF_OPT }, // 21 + { "l03_e-09.bin", 0x0100, 0x0d968558, 0 | BRF_OPT }, // 22 + { "03e_e-01.bin", 0x0020, 0x1acee376, 0 | BRF_OPT }, // 23 +}; + +STD_ROM_PICK(exedexes); +STD_ROM_FN(exedexes); + +struct BurnDriver BurnDrvExedexes = { + "exedexes", NULL, NULL, "1985", + "Exed Exes\0", NULL, "Capcom", "Miscellaneous", + L"Exed Exes\0\u30A8\u30B0\u30BC\u30C9 \u30A8\u30B0\u30BC\u30B9\0", NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, exedexesRomInfo, exedexesRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalc, + 224, 256, 3, 4 +}; + + +// Savage Bees + +static struct BurnRomInfo savgbeesRomDesc[] = { + { "ee04e.11m", 0x4000, 0xc0caf442, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "ee03e.10m", 0x4000, 0x9cd70ae1, 1 | BRF_PRG | BRF_ESS }, // 1 + { "ee02e.9m", 0x4000, 0xa04e6368, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "ee01e.11e", 0x4000, 0x93d3f952, 2 | BRF_PRG | BRF_ESS }, // 3 Z80 #1 Code + + { "ee00e.5c", 0x2000, 0x5972f95f, 3 | BRF_GRA }, // 4 Characters + + { "h01_ee08.bin", 0x4000, 0x96a65c1d, 4 | BRF_GRA }, // 5 32x32 tiles + + { "a03_ee06.bin", 0x4000, 0x6039bdd1, 5 | BRF_GRA }, // 6 16x16 tiles + { "a02_ee05.bin", 0x4000, 0xb32d8252, 5 | BRF_GRA }, // 7 + + { "j11_ee10.bin", 0x4000, 0xbc83e265, 6 | BRF_GRA }, // 8 Sprites + { "j12_ee11.bin", 0x4000, 0x0e0f300d, 6 | BRF_GRA }, // 9 + + { "c01_ee07.bin", 0x4000, 0x3625a68d, 7 | BRF_GRA }, // 10 Tile Maps + { "h04_ee09.bin", 0x2000, 0x6057c907, 7 | BRF_GRA }, // 11 + + { "02d_e-02.bin", 0x0100, 0x8d0d5935, 8 | BRF_GRA }, // 12 Color Proms + { "03d_e-03.bin", 0x0100, 0xd3c17efc, 8 | BRF_GRA }, // 13 + { "04d_e-04.bin", 0x0100, 0x58ba964c, 8 | BRF_GRA }, // 14 + { "06f_e-05.bin", 0x0100, 0x35a03579, 8 | BRF_GRA }, // 15 + { "l04_e-10.bin", 0x0100, 0x1dfad87a, 8 | BRF_GRA }, // 16 + { "c04_e-07.bin", 0x0100, 0x850064e0, 8 | BRF_GRA }, // 17 + { "l09_e-11.bin", 0x0100, 0x2bb68710, 8 | BRF_GRA }, // 18 + { "l10_e-12.bin", 0x0100, 0x173184ef, 8 | BRF_GRA }, // 19 + + { "06l_e-06.bin", 0x0100, 0x712ac508, 0 | BRF_OPT }, // 20 Misc. Proms + { "k06_e-08.bin", 0x0100, 0x0eaf5158, 0 | BRF_OPT }, // 21 + { "l03_e-09.bin", 0x0100, 0x0d968558, 0 | BRF_OPT }, // 22 + { "03e_e-01.bin", 0x0020, 0x1acee376, 0 | BRF_OPT }, // 23 +}; + +STD_ROM_PICK(savgbees); +STD_ROM_FN(savgbees); + +struct BurnDriver BurnDrvSavgbees = { + "savgbees", "exedexes", NULL, "1985", + "Savage Bees\0", NULL, "Capcom (Memetron license)", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, savgbeesRomInfo, savgbeesRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalc, + 224, 256, 3, 4 +}; diff --git a/src/burn/misc/pre90s/d_funkybee.cpp b/src/burn/misc/pre90s/d_funkybee.cpp new file mode 100644 index 0000000..a338e97 --- /dev/null +++ b/src/burn/misc/pre90s/d_funkybee.cpp @@ -0,0 +1,759 @@ +// FB Alpha Funky Bee Driver Module +// Based on MAME driver by Zsolt Vasvari + +#include "tiles_generic.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +static unsigned char *Mem, *MemEnd, *Rom, *Gfx, *Prom; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvJoy3[8], DrvDips[2], DrvReset; +static unsigned int *Palette, *DrvPal; +static unsigned char DrvRecalcPal; + +static short *pAY8910Buffer[3], *pFMBuffer = NULL; +static int skylancr = 0; + +static int funkybee_gfx_bank, funkybee_scroll_x, funkybee_flipscreen; + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 0, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy1 + 3, "p1 start" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy2 + 0, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy2 + 1, "p1 right" }, + {"P1 Up", BIT_DIGITAL, DrvJoy2 + 2, "p1 up", }, + {"P1 Down", BIT_DIGITAL, DrvJoy2 + 3, "p1 down", }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p1 fire 1"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy1 + 1, "p2 coin" }, + {"P2 start" , BIT_DIGITAL , DrvJoy1 + 4, "p2 start" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy3 + 0, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy3 + 1, "p2 right" }, + {"P2 Up", BIT_DIGITAL, DrvJoy3 + 2, "p2 up", }, + {"P2 Down", BIT_DIGITAL, DrvJoy3 + 3, "p2 down", }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy3 + 4, "p2 fire 1"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo funkybeeDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x20, NULL }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x0f, 0x01, 0x20, 0x20, "Off" }, + {0x0f, 0x01, 0x20, 0x00, "On" }, + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x10, 0x01, 0x03, 0x03, "1C 1C" }, + {0x10, 0x01, 0x03, 0x02, "1C 2C" }, + {0x10, 0x01, 0x03, 0x01, "1C 3C" }, + {0x10, 0x01, 0x03, 0x00, "1C 4C" }, + + {0 , 0xfe, 0 , 4 , "Coin B" }, + {0x10, 0x01, 0x0c, 0x08, "2C 1C" }, + {0x10, 0x01, 0x0c, 0x0c, "1C 1C" }, + {0x10, 0x01, 0x0c, 0x04, "2C 3C" }, + {0x10, 0x01, 0x0c, 0x00, "1C 6C" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x10, 0x01, 0x30, 0x30, "3" }, + {0x10, 0x01, 0x30, 0x20, "4" }, + {0x10, 0x01, 0x30, 0x10, "5" }, + {0x10, 0x01, 0x30, 0x00, "6" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x10, 0x01, 0x40, 0x40, "20000" }, + {0x10, 0x01, 0x40, 0x00, "None" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x80, 0x00, "Upright" }, + {0x10, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(funkybee); + + +static struct BurnDIPInfo funkbeebDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x20, NULL }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x0f, 0x01, 0x20, 0x20, "Off" }, + {0x0f, 0x01, 0x20, 0x00, "On" }, + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x10, 0x01, 0x03, 0x03, "1C 1C" }, + {0x10, 0x01, 0x03, 0x02, "1C 2C" }, + {0x10, 0x01, 0x03, 0x01, "1C 3C" }, + {0x10, 0x01, 0x03, 0x00, "1C 4C" }, + + {0 , 0xfe, 0 , 4 , "Coin B" }, + {0x10, 0x01, 0x0c, 0x08, "2C 1C" }, + {0x10, 0x01, 0x0c, 0x0c, "1C 1C" }, + {0x10, 0x01, 0x0c, 0x04, "2C 3C" }, + {0x10, 0x01, 0x0c, 0x00, "1C 6C" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x10, 0x01, 0x30, 0x30, "1" }, + {0x10, 0x01, 0x30, 0x20, "2" }, + {0x10, 0x01, 0x30, 0x10, "3" }, + {0x10, 0x01, 0x30, 0x00, "4" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x10, 0x01, 0x40, 0x40, "20000" }, + {0x10, 0x01, 0x40, 0x00, "None" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x80, 0x00, "Upright" }, + {0x10, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(funkbeeb); + +static struct BurnDIPInfo skylancrDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x20, NULL }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x0f, 0x01, 0x20, 0x20, "Off" }, + {0x0f, 0x01, 0x20, 0x00, "On" }, + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x10, 0x01, 0x03, 0x03, "1C 1C" }, + {0x10, 0x01, 0x03, 0x02, "1C 2C" }, + {0x10, 0x01, 0x03, 0x01, "1C 3C" }, + {0x10, 0x01, 0x03, 0x00, "1C 6C" }, + + {0 , 0xfe, 0 , 4 , "Coin B" }, + {0x10, 0x01, 0x0c, 0x08, "2C 1C" }, + {0x10, 0x01, 0x0c, 0x0c, "1C 1C" }, + {0x10, 0x01, 0x0c, 0x04, "2C 3C" }, + {0x10, 0x01, 0x0c, 0x00, "1C 6C" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x10, 0x01, 0x30, 0x30, "1" }, + {0x10, 0x01, 0x30, 0x20, "2" }, + {0x10, 0x01, 0x30, 0x10, "3" }, + {0x10, 0x01, 0x30, 0x00, "4" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x10, 0x01, 0x40, 0x40, "20000" }, + {0x10, 0x01, 0x40, 0x00, "None" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x80, 0x00, "Upright" }, + {0x10, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(skylancr); + +static struct BurnDIPInfo skylanceDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x20, NULL }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x0f, 0x01, 0x20, 0x20, "Off" }, + {0x0f, 0x01, 0x20, 0x00, "On" }, + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x10, 0x01, 0x03, 0x03, "1C 1C" }, + {0x10, 0x01, 0x03, 0x02, "1C 2C" }, + {0x10, 0x01, 0x03, 0x01, "1C 3C" }, + {0x10, 0x01, 0x03, 0x00, "1C 6C" }, + + {0 , 0xfe, 0 , 4 , "Coin B" }, + {0x10, 0x01, 0x0c, 0x08, "2C 1C" }, + {0x10, 0x01, 0x0c, 0x0c, "1C 1C" }, + {0x10, 0x01, 0x0c, 0x04, "2C 3C" }, + {0x10, 0x01, 0x0c, 0x00, "1C 6C" }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x10, 0x01, 0x30, 0x30, "3" }, + {0x10, 0x01, 0x30, 0x20, "4" }, + {0x10, 0x01, 0x30, 0x10, "5" }, + {0x10, 0x01, 0x30, 0x00, "64" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x10, 0x01, 0x40, 0x40, "20000 50000" }, + {0x10, 0x01, 0x40, 0x00, "40000 70000" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x80, 0x00, "Upright" }, + {0x10, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(skylance); + + +unsigned char __fastcall funkybee_read(unsigned short address) +{ + unsigned char ret = 0; + + switch (address) + { + case 0xf000: + ZetSetIRQLine(0, ZET_IRQSTATUS_ACK); + return 0; + + case 0xf800: + { + for (int i = 0; i < 8; i++) + ret |= DrvJoy1[i] << i; + + return ret | DrvDips[0]; + } + + case 0xf801: + { + for (int i = 0; i < 8; i++) + ret |= DrvJoy2[i] << i; + + return ret; + + } + + case 0xf802: + { + for (int i = 0; i < 8; i++) + ret |= DrvJoy3[i] << i; + + return ret; + } + } + + return 0; +} + +void __fastcall funkybee_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0xe000: + funkybee_scroll_x = data; + break; + + case 0xe800: + funkybee_flipscreen = data & 1; + break; + + case 0xe802: // coin counter + case 0xe803: + break; + + case 0xe805: + funkybee_gfx_bank = (data & 1) << 9; + break; + + case 0xf800: // watchdog + break; + } +} + +unsigned char __fastcall funkybee_in_port(unsigned short address) +{ + switch (address & 0xff) + { + case 0x02: + return AY8910Read(0); + } + + return 0; +} + +void __fastcall funkybee_out_port(unsigned short address, unsigned char data) +{ + switch (address & 0xff) + { + case 0x00: + case 0x01: + AY8910Write(0, address & 1, data); + break; + } +} + +static unsigned char funkybee_ay8910_read_A(unsigned int) +{ + return DrvDips[1]; +} + +static int DrvDoReset() +{ + DrvReset = 0; + memset (Rom + 0x8000, 0, 0x0800); + memset (Rom + 0xa000, 0, 0x4000); + + funkybee_gfx_bank = 0; + funkybee_scroll_x = 0; + funkybee_flipscreen = 0; + ZetOpen(0); + ZetReset(); + ZetClose(); + + return 0; +} + +static void funkybee_gfx_decode() +{ + unsigned char *tmp = (unsigned char*)malloc(0x4000); + if (tmp == NULL) { + return; + } + + static int PlaneOffsets[2] = { 0, 4 }; + + static int XOffsets[8] = { + 0, 1, 2, 3, 64, 65, 66, 67 + }; + + static int YOffsets[32] = { + 0, 8, 16, 24, 32, 40, 48, 56, 128, 136, 144, 152, 160, 168, 176, 184, + 256, 264, 272, 280, 288, 296, 304, 312, 384, 392, 400, 408, 416, 424, 432, 440 + }; + + memcpy (tmp, Gfx, 0x4000); + + GfxDecode(0x400, 2, 8, 8, PlaneOffsets, XOffsets, YOffsets, 0x080, tmp, Gfx + 0x00000); + GfxDecode(0x100, 2, 8, 32, PlaneOffsets, XOffsets, YOffsets, 0x200, tmp, Gfx + 0x10000); + + free (tmp); +} + +static void funkybee_palette_init() +{ + for (int i = 0; i < 32; i++) + { + int bit0,bit1,bit2,r,g,b; + + bit0 = (Prom[i] >> 0) & 0x01; + bit1 = (Prom[i] >> 1) & 0x01; + bit2 = (Prom[i] >> 2) & 0x01; + r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = (Prom[i] >> 3) & 0x01; + bit1 = (Prom[i] >> 4) & 0x01; + bit2 = (Prom[i] >> 5) & 0x01; + g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = 0; + bit1 = (Prom[i] >> 6) & 0x01; + bit2 = (Prom[i] >> 7) & 0x01; + b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + Palette[i] = (r << 16) | (g << 8) | b; + } +} + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + Rom = Next; Next += 0x10000; + Gfx = Next; Next += 0x20000; + Prom = Next; Next += 0x00020; + + pFMBuffer = (short*)Next; Next += nBurnSoundLen * 3 * sizeof(short); + + Palette = (unsigned int*)Next; Next += 0x00020 * sizeof(unsigned int); + DrvPal = (unsigned int*)Next; Next += 0x00020 * sizeof(unsigned int); + + MemEnd = Next; + + return 0; +} + +static int DrvInit() +{ + int nLen; + + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + if (skylancr) + { + if (BurnLoadRom(Rom + 0x0000, 0, 1)) return 1; + if (BurnLoadRom(Rom + 0x2000, 1, 1)) return 1; + if (BurnLoadRom(Rom + 0x4000, 2, 1)) return 1; + if (BurnLoadRom(Gfx + 0x0000, 3, 1)) return 1; + if (BurnLoadRom(Gfx + 0x2000, 4, 1)) return 1; + if (BurnLoadRom(Prom + 0x0000, 5, 1)) return 1; + } else { + if (BurnLoadRom(Rom + 0x0000, 0, 1)) return 1; + if (BurnLoadRom(Rom + 0x1000, 1, 1)) return 1; + if (BurnLoadRom(Rom + 0x2000, 2, 1)) return 1; + if (BurnLoadRom(Rom + 0x3000, 3, 1)) return 1; + if (BurnLoadRom(Gfx + 0x0000, 4, 1)) return 1; + if (BurnLoadRom(Gfx + 0x2000, 5, 1)) return 1; + if (BurnLoadRom(Prom + 0x0000, 6, 1)) return 1; + } + + funkybee_gfx_decode(); + funkybee_palette_init(); + + ZetInit(1); + ZetOpen(0); + ZetSetReadHandler(funkybee_read); + ZetSetWriteHandler(funkybee_write); + ZetSetInHandler(funkybee_in_port); + ZetSetOutHandler(funkybee_out_port); + ZetMapArea(0x0000, 0x4fff, 0, Rom + 0x0000); + ZetMapArea(0x0000, 0x4fff, 2, Rom + 0x0000); + ZetMapArea(0x8000, 0x87ff, 0, Rom + 0x8000); + ZetMapArea(0x8000, 0x87ff, 1, Rom + 0x8000); + ZetMapArea(0x8000, 0x87ff, 2, Rom + 0x8000); + ZetMapArea(0xa000, 0xdfff, 0, Rom + 0xa000); + ZetMapArea(0xa000, 0xdfff, 1, Rom + 0xa000); + ZetMemEnd(); + ZetClose(); + + AY8910Init(0, 1500000, nBurnSoundRate, &funkybee_ay8910_read_A, NULL, NULL, NULL); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + skylancr = 0; + + ZetExit(); + AY8910Exit(0); + GenericTilesExit(); + + free (Mem); + + Palette = DrvPal = NULL; + + pFMBuffer = NULL; + Mem = MemEnd = Rom = Gfx = Prom = NULL; + + funkybee_gfx_bank = 0; + funkybee_scroll_x = 0; + funkybee_flipscreen = 0; + DrvRecalcPal = 0; + + return 0; +} + +static int DrvDraw() +{ + if (DrvRecalcPal) { + for (int i = 0; i < 32; i++) { + unsigned int col = Palette[i]; + DrvPal[i] = BurnHighCol(col >> 16, col >> 8, col, 0); + } + } + + for (int offa = 0; offa < 0x1c00; offa += 0x100) + { + for (int offb = 0; offb < 0x20; offb++) + { + int sy = (offa >> 5) ^ (funkybee_flipscreen * 0xf8); + int sx = (offb << 3) ^ (funkybee_flipscreen * 0xf8); + + sx = (sx - funkybee_scroll_x) & 0xff; + + int offs = offa + offb; + + int code = Rom[0xa000 + offs] + ((Rom[0xc000 + offs] & 0x80) << 1) + funkybee_gfx_bank; + int color = Rom[0xc000 + offs] & 0x03; + + if (funkybee_flipscreen) + Render8x8Tile_FlipXY_Clip(pTransDraw, code, sx - 8, sy - 32, color, 2, 0, Gfx); + else + Render8x8Tile_Clip(pTransDraw, code, sx - 12, sy, color, 2, 0, Gfx); + } + } + + for (int offs = 0x0f; offs >= 0; offs--) + { + int attr = Rom[0xbe00 + offs]; + int code = (attr >> 2) | ((attr & 2) << 5); + int color = 4 | (Rom[0xde10 + offs] & 3); + int flipy = attr & 1; + int flipx = funkybee_flipscreen; + int sx = Rom[0xbe10 + offs] - 12; + int sy = 224 - Rom[0xde00 + offs]; + + code = (code << 2) + funkybee_gfx_bank; + + if (flipy) { + if (flipx) { + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code + 0, sx, sy + 24, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code + 1, sx, sy + 16, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code + 2, sx, sy + 8, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code + 3, sx, sy + 0, color, 2, 0, 0, Gfx); + } else { + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code + 0, sx, sy + 24, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code + 1, sx, sy + 16, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code + 2, sx, sy + 8, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, code + 3, sx, sy + 0, color, 2, 0, 0, Gfx); + } + } else { + if (flipx) { + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code + 0, sx, sy + 0, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code + 1, sx, sy + 8, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code + 2, sx, sy + 16, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, code + 3, sx, sy + 24, color, 2, 0, 0, Gfx); + } else { + Render8x8Tile_Mask_Clip(pTransDraw, code + 0, sx, sy + 0, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_Clip(pTransDraw, code + 1, sx, sy + 8, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_Clip(pTransDraw, code + 2, sx, sy + 16, color, 2, 0, 0, Gfx); + Render8x8Tile_Mask_Clip(pTransDraw, code + 3, sx, sy + 24, color, 2, 0, 0, Gfx); + } + } + } + + for (int offs = 0x1f;offs >= 0;offs--) + { + int code = Rom[0xbc00 + offs] + funkybee_gfx_bank; + int color = Rom[0xdf10] & 0x03; + int sx = Rom[0xbf10]; + int sy = offs << 3; + + if (funkybee_flipscreen) + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code, (232 - sx) + 4, sy ^ 0xf8, color, 2, 0, 0, Gfx); + else + Render8x8Tile_Mask_Clip(pTransDraw, code, sx - 12, sy, color, 2, 0, 0, Gfx); + + code = Rom[0xbd00 + offs] + funkybee_gfx_bank; + color = Rom[0xdf11] & 0x03; + sx = Rom[0xbf11]; + sy = offs << 3; + + if (funkybee_flipscreen) + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, code, (232 - sx) + 4, sy ^ 0xf8, color, 2, 0, 0, Gfx); + else + Render8x8Tile_Mask_Clip(pTransDraw, code, sx - 12, sy, color, 2, 0, 0, Gfx); + } + + BurnTransferCopy(DrvPal); + + return 0; +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetOpen(0); + ZetRun(3072000 / 60); + ZetRaiseIrq(0); + ZetClose(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0x8000; + ba.nLen = 0x0800; + ba.szName = "Work Ram"; + BurnAcb(&ba); + + ba.Data = Rom + 0xa000; + ba.nLen = 0x4000; + ba.szName = "Video Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + AY8910Scan(nAction, pnMin); + + SCAN_VAR(funkybee_gfx_bank); + SCAN_VAR(funkybee_scroll_x); + SCAN_VAR(funkybee_flipscreen); + } + + return 0; +} + +// Funky Bee + +static struct BurnRomInfo funkybeeRomDesc[] = { + { "funkybee.1", 0x1000, 0x3372cb33, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "funkybee.3", 0x1000, 0x7bf7c62f, 1 | BRF_PRG | BRF_ESS }, // 1 + { "funkybee.2", 0x1000, 0x8cc0fe8e, 1 | BRF_PRG | BRF_ESS }, // 2 + { "funkybee.4", 0x1000, 0x1e1aac26, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "funkybee.5", 0x2000, 0x86126655, 2 | BRF_GRA }, // 4 Graphics tiles + { "funkybee.6", 0x2000, 0x5fffd323, 2 | BRF_GRA }, // 5 + + { "funkybee.clr", 0x0020, 0xe2cf5fe2, 3 | BRF_GRA }, // 6 Color prom +}; + +STD_ROM_PICK(funkybee); +STD_ROM_FN(funkybee); + +struct BurnDriver BurnDrvfunkybee = { + "funkybee", NULL, NULL, "1982", + "Funky Bee\0", NULL, "Orca", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, funkybeeRomInfo, funkybeeRomName, DrvInputInfo, funkybeeDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 224, 232, 3, 4 +}; + + +// Funky Bee (bootleg, harder) + +static struct BurnRomInfo funkbeebRomDesc[] = { + { "senza_orca.fb1", 0x1000, 0x7f2e7f85, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "funkybee.3", 0x1000, 0x7bf7c62f, 1 | BRF_PRG | BRF_ESS }, // 1 + { "funkybee.2", 0x1000, 0x8cc0fe8e, 1 | BRF_PRG | BRF_ESS }, // 2 + { "senza_orca.fb4", 0x1000, 0x53c2db3b, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "funkybee.5", 0x2000, 0x86126655, 2 | BRF_GRA }, // 4 Graphics tiles + { "funkybee.6", 0x2000, 0x5fffd323, 2 | BRF_GRA }, // 5 + + { "funkybee.clr", 0x0020, 0xe2cf5fe2, 3 | BRF_GRA }, // 6 Color prom +}; + +STD_ROM_PICK(funkbeeb); +STD_ROM_FN(funkbeeb); + +struct BurnDriver BurnDrvfunkbeeb = { + "funkbeeb", "funkybee", NULL, "1982", + "Funky Bee (bootleg, harder)\0", NULL, "bootleg", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, funkbeebRomInfo, funkbeebRomName, DrvInputInfo, funkbeebDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 224, 232, 3, 4 +}; + + +// Sky Lancer + +static struct BurnRomInfo skylancrRomDesc[] = { + { "1sl.5a", 0x2000, 0xe80b315e, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "2sl.5c", 0x2000, 0x9d70567b, 1 | BRF_PRG | BRF_ESS }, // 1 + { "3sl.5d", 0x2000, 0x64c39457, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "4sl.6a", 0x2000, 0x9b4469a5, 2 | BRF_GRA }, // 3 Graphics tiles + { "5sl.6c", 0x2000, 0x29afa134, 2 | BRF_GRA }, // 4 + + { "18s030.1a", 0x0020, 0xe645bacb, 3 | BRF_GRA }, // 5 Color prom +}; + +STD_ROM_PICK(skylancr); +STD_ROM_FN(skylancr); + +static int skylancrInit() +{ + skylancr = 1; + + return DrvInit(); +} + +struct BurnDriver BurnDrvskylancr = { + "skylancr", NULL, NULL, "1983", + "Sky Lancer\0", NULL, "Orca", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, skylancrRomInfo, skylancrRomName, DrvInputInfo, skylancrDIPInfo, + skylancrInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 224, 232, 3, 4 +}; + + +// Sky Lancer (Esco Trading Co license) + +static struct BurnRomInfo skylanceRomDesc[] = { + { "1.5a", 0x2000, 0x82d55824, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "2.5c", 0x2000, 0xdff3a682, 1 | BRF_PRG | BRF_ESS }, // 1 + { "3.5d", 0x1000, 0x7c006ee6, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "4.6a", 0x2000, 0x0f8ede07, 2 | BRF_GRA }, // 3 Graphics tiles + { "5.6b", 0x2000, 0x24cec070, 2 | BRF_GRA }, // 4 + + { "18s030.1a", 0x0020, 0xe645bacb, 3 | BRF_GRA }, // 5 Color prom +}; + +STD_ROM_PICK(skylance); +STD_ROM_FN(skylance); + +struct BurnDriver BurnDrvskylance = { + "skylance", "skylancr", NULL, "1983", + "Sky Lancer (Esco Trading Co license)\0", NULL, "Orca (Esco Trading Co license)", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, skylanceRomInfo, skylanceRomName, DrvInputInfo, skylanceDIPInfo, + skylancrInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 224, 232, 3, 4 +}; diff --git a/src/burn/misc/pre90s/d_gberet.cpp b/src/burn/misc/pre90s/d_gberet.cpp new file mode 100644 index 0000000..882d07e --- /dev/null +++ b/src/burn/misc/pre90s/d_gberet.cpp @@ -0,0 +1,1107 @@ +// FB Alpha Green Beret driver module +// Based on MAME driver by Nicola Salmoria + +#include "tiles_generic.h" +#include "sn76496.h" + +static unsigned char *Mem, *MemEnd, *Rom, *Gfx0, *Gfx1, *Prom; +static unsigned int *Palette, *DrvPalette; +static unsigned char DrvRecalcPal; + +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvJoy3[8], DrvDips[4], DrvReset; + +static unsigned char nmi_enable, irq_enable; +static unsigned short gberetb_scroll; +static unsigned char flipscreen; +static unsigned char gberet_spritebank; +static int mrgoemon_bank; + +static int game_type = 0; // 0 gberet / rushatck, 1 gberetb, 2 mrgoemon + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1" , BIT_DIGITAL , DrvJoy3 + 0, "p1 coin" }, + {"Coin 2" , BIT_DIGITAL , DrvJoy3 + 1, "p2 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy3 + 3, "p1 start" }, + {"P2 Start" , BIT_DIGITAL , DrvJoy3 + 4, "p2 start" }, + + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 0, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 1, "p1 right" }, + {"P1 Up" , BIT_DIGITAL , DrvJoy1 + 2, "p1 up" }, + {"P1 Down" , BIT_DIGITAL , DrvJoy1 + 3, "p1 down" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 1" }, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 5, "p1 fire 2" }, + + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 0, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 1, "p2 right" }, + {"P2 Up" , BIT_DIGITAL , DrvJoy2 + 2, "p2 up" }, + {"P2 Down" , BIT_DIGITAL , DrvJoy2 + 3, "p2 down" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 1" }, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 5, "p2 fire 2" }, + + {"Service" , BIT_DIGITAL , DrvJoy3 + 2, "service" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDips + 1, "dip" }, + {"Dip 3" , BIT_DIPSWITCH, DrvDips + 2, "dip" }, + +}; + +STDINPUTINFO(Drv); + +static struct BurnInputInfo gberetbInputList[] = { + {"Coin 1" , BIT_DIGITAL , DrvJoy3 + 7, "p1 coin" }, + {"Coin 2" , BIT_DIGITAL , DrvJoy3 + 6, "p2 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy3 + 5, "p1 start" }, + {"P2 Start" , BIT_DIGITAL , DrvJoy3 + 4, "p2 start" }, + + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 0, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 1, "p1 right" }, + {"P1 Up" , BIT_DIGITAL , DrvJoy1 + 2, "p1 up" }, + {"P1 Down" , BIT_DIGITAL , DrvJoy1 + 3, "p1 down" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 1" }, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 5, "p1 fire 2" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDips + 3, "dip" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDips + 2, "dip" }, +}; + +STDINPUTINFO(gberetb); + +static struct BurnDIPInfo gberetDIPList[]= +{ + {0x12, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 16 , "Coin A" }, + {0x12, 0x01, 0x0f, 0x02, "4 Coins 1 Credit" }, + {0x12, 0x01, 0x0f, 0x05, "3 Coins 1 Credit" }, + {0x12, 0x01, 0x0f, 0x08, "2 Coins 1 Credit" }, + {0x12, 0x01, 0x0f, 0x04, "3 Coins 2 Credits" }, + {0x12, 0x01, 0x0f, 0x01, "4 Coins 3 Credits" }, + {0x12, 0x01, 0x0f, 0x0f, "1 Coin 1 Credit" }, + {0x12, 0x01, 0x0f, 0x03, "3 Coins 4 Credits" }, + {0x12, 0x01, 0x0f, 0x07, "2 Coins 3 Credits" }, + {0x12, 0x01, 0x0f, 0x0e, "1 Coin 2 Credits" }, + {0x12, 0x01, 0x0f, 0x06, "2 Coins 5 Credits" }, + {0x12, 0x01, 0x0f, 0x0d, "1 Coin 3 Credits" }, + {0x12, 0x01, 0x0f, 0x0c, "1 Coin 4 Credits" }, + {0x12, 0x01, 0x0f, 0x0b, "1 Coin 5 Credits" }, + {0x12, 0x01, 0x0f, 0x0a, "1 Coin 6 Credits" }, + {0x12, 0x01, 0x0f, 0x09, "1 Coin 7 Credits" }, + {0x12, 0x01, 0x0f, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 15 , "Coin B" }, + {0x12, 0x82, 0xf0, 0x20, "4 Coins 1 Credit" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x50, "3 Coins 1 Credit" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x80, "2 Coins 1 Credit" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x40, "3 Coins 2 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x10, "4 Coins 3 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xf0, "1 Coin 1 Credit" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x30, "3 Coins 4 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x70, "2 Coins 3 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xe0, "1 Coin 2 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x60, "2 Coins 5 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xd0, "1 Coin 3 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xc0, "1 Coin 4 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xb0, "1 Coin 5 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xa0, "1 Coin 6 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x90, "1 Coin 7 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + + {0x13, 0xff, 0xff, 0x4a, NULL }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x13, 0x01, 0x03, 0x03, "2" }, + {0x13, 0x01, 0x03, 0x02, "3" }, + {0x13, 0x01, 0x03, 0x01, "5" }, + {0x13, 0x01, 0x03, 0x00, "7" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x13, 0x01, 0x04, 0x00, "Upright" }, + {0x13, 0x01, 0x04, 0x04, "Cocktail" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x13, 0x01, 0x18, 0x18, "30K 70K 70K+" }, + {0x13, 0x01, 0x18, 0x10, "40K 80K 80K+" }, + {0x13, 0x01, 0x18, 0x08, "50K 100K 100K+" }, + {0x13, 0x01, 0x18, 0x00, "50K 200K 200K+" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x13, 0x01, 0x60, 0x60, "Easy" }, + {0x13, 0x01, 0x60, 0x40, "Normal" }, + {0x13, 0x01, 0x60, 0x20, "Difficult" }, + {0x13, 0x01, 0x60, 0x00, "Very Difficult" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x13, 0x01, 0x80, 0x80, "Off" }, + {0x13, 0x01, 0x80, 0x00, "On" }, + + {0x14, 0xff, 0xff, 0x0f, NULL }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x14, 0x01, 0x01, 0x01, "Off" }, + {0x14, 0x01, 0x01, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Upright Controls" }, + {0x14, 0x01, 0x02, 0x02, "Single" }, + {0x14, 0x01, 0x02, 0x00, "Dual" }, +}; + +STDDIPINFO(gberet); + +static struct BurnDIPInfo gberetbDIPList[]= +{ + {0x0b, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 16 , "Coin A" }, + {0x0b, 0x01, 0x0f, 0x02, "4 Coins 1 Credit" }, + {0x0b, 0x01, 0x0f, 0x05, "3 Coins 1 Credit" }, + {0x0b, 0x01, 0x0f, 0x08, "2 Coins 1 Credit" }, + {0x0b, 0x01, 0x0f, 0x04, "3 Coins 2 Credits" }, + {0x0b, 0x01, 0x0f, 0x01, "4 Coins 3 Credits" }, + {0x0b, 0x01, 0x0f, 0x0f, "1 Coin 1 Credit" }, + {0x0b, 0x01, 0x0f, 0x03, "3 Coins 4 Credits" }, + {0x0b, 0x01, 0x0f, 0x07, "2 Coins 3 Credits" }, + {0x0b, 0x01, 0x0f, 0x0e, "1 Coin 2 Credits" }, + {0x0b, 0x01, 0x0f, 0x06, "2 Coins 5 Credits" }, + {0x0b, 0x01, 0x0f, 0x0d, "1 Coin 3 Credits" }, + {0x0b, 0x01, 0x0f, 0x0c, "1 Coin 4 Credits" }, + {0x0b, 0x01, 0x0f, 0x0b, "1 Coin 5 Credits" }, + {0x0b, 0x01, 0x0f, 0x0a, "1 Coin 6 Credits" }, + {0x0b, 0x01, 0x0f, 0x09, "1 Coin 7 Credits" }, + {0x0b, 0x01, 0x0f, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 15 , "Coin B" }, + {0x0b, 0x82, 0xf0, 0x20, "4 Coins 1 Credit" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0x50, "3 Coins 1 Credit" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0x80, "2 Coins 1 Credit" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0x40, "3 Coins 2 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0x10, "4 Coins 3 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0xf0, "1 Coin 1 Credit" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0x30, "3 Coins 4 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0x70, "2 Coins 3 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0xe0, "1 Coin 2 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0x60, "2 Coins 5 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0xd0, "1 Coin 3 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0xc0, "1 Coin 4 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0xb0, "1 Coin 5 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0xa0, "1 Coin 6 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + {0x0b, 0x82, 0xf0, 0x90, "1 Coin 7 Credits" }, + {0x0b, 0x00, 0x0f, 0x00, NULL }, + + {0x0c, 0xff, 0xff, 0x4a, NULL }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0c, 0x01, 0x03, 0x03, "2" }, + {0x0c, 0x01, 0x03, 0x02, "3" }, + {0x0c, 0x01, 0x03, 0x01, "5" }, + {0x0c, 0x01, 0x03, 0x00, "7" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0c, 0x01, 0x04, 0x00, "Upright" }, + {0x0c, 0x01, 0x04, 0x04, "Cocktail" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x0c, 0x01, 0x18, 0x18, "30K 70K 70K+" }, + {0x0c, 0x01, 0x18, 0x10, "40K 80K 80K+" }, + {0x0c, 0x01, 0x18, 0x08, "50K 100K 100K+" }, + {0x0c, 0x01, 0x18, 0x00, "50K 200K 200K+" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x0c, 0x01, 0x60, 0x60, "Easy" }, + {0x0c, 0x01, 0x60, 0x40, "Normal" }, + {0x0c, 0x01, 0x60, 0x20, "Difficult" }, + {0x0c, 0x01, 0x60, 0x00, "Very Difficult" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x0c, 0x01, 0x80, 0x80, "Off" }, + {0x0c, 0x01, 0x80, 0x00, "On" }, +}; + +STDDIPINFO(gberetb); + +static struct BurnDIPInfo mrgoemonDIPList[]= +{ + {0x12, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 16 , "Coin A" }, + {0x12, 0x01, 0x0f, 0x02, "4 Coins 1 Credit" }, + {0x12, 0x01, 0x0f, 0x05, "3 Coins 1 Credit" }, + {0x12, 0x01, 0x0f, 0x08, "2 Coins 1 Credit" }, + {0x12, 0x01, 0x0f, 0x04, "3 Coins 2 Credits" }, + {0x12, 0x01, 0x0f, 0x01, "4 Coins 3 Credits" }, + {0x12, 0x01, 0x0f, 0x0f, "1 Coin 1 Credit" }, + {0x12, 0x01, 0x0f, 0x03, "3 Coins 4 Credits" }, + {0x12, 0x01, 0x0f, 0x07, "2 Coins 3 Credits" }, + {0x12, 0x01, 0x0f, 0x0e, "1 Coin 2 Credits" }, + {0x12, 0x01, 0x0f, 0x06, "2 Coins 5 Credits" }, + {0x12, 0x01, 0x0f, 0x0d, "1 Coin 3 Credits" }, + {0x12, 0x01, 0x0f, 0x0c, "1 Coin 4 Credits" }, + {0x12, 0x01, 0x0f, 0x0b, "1 Coin 5 Credits" }, + {0x12, 0x01, 0x0f, 0x0a, "1 Coin 6 Credits" }, + {0x12, 0x01, 0x0f, 0x09, "1 Coin 7 Credits" }, + {0x12, 0x01, 0x0f, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 15 , "Coin B" }, + {0x12, 0x82, 0xf0, 0x20, "4 Coins 1 Credit" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x50, "3 Coins 1 Credit" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x80, "2 Coins 1 Credit" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x40, "3 Coins 2 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x10, "4 Coins 3 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xf0, "1 Coin 1 Credit" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x30, "3 Coins 4 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x70, "2 Coins 3 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xe0, "1 Coin 2 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x60, "2 Coins 5 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xd0, "1 Coin 3 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xc0, "1 Coin 4 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xb0, "1 Coin 5 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0xa0, "1 Coin 6 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + {0x12, 0x82, 0xf0, 0x90, "1 Coin 7 Credits" }, + {0x12, 0x00, 0x0f, 0x00, NULL }, + + {0x13, 0xff, 0xff, 0x4a, NULL }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x13, 0x01, 0x03, 0x03, "2" }, + {0x13, 0x01, 0x03, 0x02, "3" }, + {0x13, 0x01, 0x03, 0x01, "5" }, + {0x13, 0x01, 0x03, 0x00, "7" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x13, 0x01, 0x04, 0x00, "Upright" }, + {0x13, 0x01, 0x04, 0x04, "Cocktail" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x13, 0x01, 0x18, 0x18, "20K 60K+" }, + {0x13, 0x01, 0x18, 0x10, "30K 70K+" }, + {0x13, 0x01, 0x18, 0x08, "40K 80K+" }, + {0x13, 0x01, 0x18, 0x00, "50K 90K+" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x13, 0x01, 0x60, 0x60, "Easy" }, + {0x13, 0x01, 0x60, 0x40, "Normal" }, + {0x13, 0x01, 0x60, 0x20, "Difficult" }, + {0x13, 0x01, 0x60, 0x00, "Very Difficult" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x13, 0x01, 0x80, 0x80, "Off" }, + {0x13, 0x01, 0x80, 0x00, "On" }, + + {0x14, 0xff, 0xff, 0x0f, NULL }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x14, 0x01, 0x01, 0x01, "Off" }, + {0x14, 0x01, 0x01, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Upright Controls" }, + {0x14, 0x01, 0x02, 0x02, "Single" }, + {0x14, 0x01, 0x02, 0x00, "Dual" }, + + {0 , 0xfe, 0 , 2 , "Service Mode" }, + {0x14, 0x01, 0x04, 0x04, "Off" }, + {0x14, 0x01, 0x04, 0x00, "On" }, +}; + +STDDIPINFO(mrgoemon); + +static void mrgoemon_bankswitch(int nBank) +{ + mrgoemon_bank = nBank; + ZetMapArea(0xf800, 0xffff, 0, Rom + 0x10000 + mrgoemon_bank); + ZetMapArea(0xf800, 0xffff, 2, Rom + 0x10000 + mrgoemon_bank); +} + +void __fastcall gberet_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0xe040: + case 0xe041: + case 0xe042: + return; + + case 0xe043: + gberet_spritebank = data; + return; + + case 0xe044: + { + nmi_enable = data & 0x01; + irq_enable = data & ((game_type & 2) ? 0x02 : 0x04); + + flipscreen = data & 0x08; + } + return; + + case 0xf000: + { + // Coin counters + + if (game_type == 2) { + mrgoemon_bankswitch((data >> 5) << 11); + } + } + return; + + case 0xf400: + SN76496Write(0, data); + return; + + case 0xf600: // watchdog + return; + + case 0xf900: + case 0xf901: + gberetb_scroll = (((address & 1) << 8) | data) + 0x38; + return; + } + + if (address >= 0xe000 && address <= 0xe03f) { + Rom[address] = data; + return; + } + + if (game_type != 1) return; + + if (address >= 0xe900 && address <= 0xe9ff) { + Rom[address] = data; + return; + } +} + +unsigned char __fastcall gberet_read(unsigned short address) +{ + unsigned char nRet = 0xff; + + switch (address) + { + case 0xf200: + return DrvDips[1]; + + case 0xf400: + return DrvDips[2]; + + case 0xf600: + return DrvDips[0]; + + case 0xf601: + { + if (game_type & 1) return DrvDips[3]; + + for (int i = 0; i < 8; i++) nRet ^= DrvJoy2[i] << i; + + return nRet; + } + + + case 0xf602: + { + for (int i = 0; i < 8; i++) nRet ^= DrvJoy1[i] << i; + + return nRet; + } + + + case 0xf603: + { + for (int i = 0; i < 8; i++) nRet ^= DrvJoy3[i] << i; + + return nRet; + } + } + + if (address >= 0xe000 && address <= 0xe03f) { + return Rom[address]; + } + + if (game_type != 1) return 0; + + if (address >= 0xe900 && address <= 0xe9ff) { + return Rom[address]; + } + + return 0; +} + +static int DrvDoReset() +{ + DrvReset = 0; + + flipscreen = 0; + nmi_enable = 0; + irq_enable = 0; + mrgoemon_bank = 0; + gberetb_scroll = 0; + gberet_spritebank = 0; + + ZetOpen(0); + ZetReset(); + + if (game_type & 2) { + mrgoemon_bankswitch(0); + } + + ZetClose(); + + return 0; +} + + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + Rom = Next; Next += 0x14000; + + Gfx0 = Next; Next += 0x08000; + Gfx1 = Next; Next += 0x20000; + + Prom = Next; Next += 0x00220; + + Palette = (unsigned int*)Next; Next += 0x00200 * sizeof(unsigned int); + DrvPalette = (unsigned int*)Next; Next += 0x00200 * sizeof(unsigned int); + + MemEnd = Next; + + return 0; +} + +static void DrvCreatePalette() +{ + unsigned int tmp[0x20]; + + for (int i = 0; i < 0x20; i++) + { + int bit0, bit1, bit2; + int r, g, b; + + bit0 = (Prom[i] >> 0) & 0x01; + bit1 = (Prom[i] >> 1) & 0x01; + bit2 = (Prom[i] >> 2) & 0x01; + r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = (Prom[i] >> 3) & 0x01; + bit1 = (Prom[i] >> 4) & 0x01; + bit2 = (Prom[i] >> 5) & 0x01; + g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = 0; + bit1 = (Prom[i] >> 6) & 0x01; + bit2 = (Prom[i] >> 7) & 0x01; + b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + tmp[i] = (r << 16) | (g << 8) | b; + } + + Prom += 0x20; + + for (int i = 0; i < 0x100; i++) + { + unsigned char ctabentry; + + ctabentry = (Prom[0x000 + i] & 0x0f) | 0x10; + Palette[0x000 + i] = tmp[ctabentry]; + + ctabentry = (Prom[0x100 + i] & 0x0f); + Palette[0x100 + i] = tmp[ctabentry]; + } +} + +static void Graphics_Decode(int *CharPlanes, int *CharXOffs, int *CharYOffs, int *SprPlanes, int *SprXOffs, int *SprYOffs, int SprMod) +{ + unsigned char *tmp = (unsigned char*)malloc(0x10000); + if (tmp == NULL) { + return; + } + + memcpy (tmp, Gfx0, 0x4000); + + GfxDecode(0x200, 4, 8, 8, CharPlanes, CharXOffs, CharYOffs, 0x100, tmp, Gfx0); + + memcpy (tmp, Gfx1, 0x10000); + + GfxDecode(0x200, 4, 16, 16, SprPlanes, SprXOffs, SprYOffs, SprMod, tmp, Gfx1); + + free (tmp); +} + +static void DrvGfxDecode() +{ + static int Planes[4] = { 0, 1, 2, 3 }; + static int XOffs[16] = { 0, 4, 8, 12, 16, 20, 24, 28, 256, 260, 264, 268, 272, 276, 280, 284 }; + static int YOffs[16] = { 0, 32, 64, 96, 128, 160, 192, 224, 512, 544, 576, 608, 640, 672, 704, 736 }; + + Graphics_Decode(Planes, XOffs, YOffs, Planes, XOffs, YOffs, 0x400); +} + +static void BootGfxDecode() +{ + static int CharPlanes[4] = { 0, 1, 2, 3 }; + static int CharXOffs[8] = { 24, 28, 0, 4, 8, 12, 16, 20 }; + static int CharYOffs[8] = { 0, 32, 64, 96, 128, 160, 192, 224 }; + static int SpriPlanes[4] = { 0, 0x20000, 0x40000, 0x60000 }; + static int SpriXOffs[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 128, 129, 130, 131, 132, 133, 134, 135 }; + static int SpriYOffs[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }; + + Graphics_Decode(CharPlanes, CharXOffs, CharYOffs, SpriPlanes, SpriXOffs, SpriYOffs, 0x100); +} + +static int GetRoms() +{ + char* pRomName; + struct BurnRomInfo ri; + unsigned char *Load0 = Rom; + unsigned char *Load1 = Gfx0; + unsigned char *Load2 = Gfx1; + unsigned char *Load3 = Prom; + + for (int i = 0; !BurnDrvGetRomName(&pRomName, i, 0); i++) { + + BurnDrvGetRomInfo(&ri, i); + + if ((ri.nType & 7) == 1) { + if (BurnLoadRom(Load0, i, 1)) return 1; + Load0 += ri.nLen; + + continue; + } + + if ((ri.nType & 7) == 2) { + if (BurnLoadRom(Load1, i, 1)) return 1; + Load1 += ri.nLen; + + continue; + } + + if ((ri.nType & 7) == 3) { + if (BurnLoadRom(Load2, i, 1)) return 1; + Load2 += ri.nLen; + + continue; + } + + if ((ri.nType & 7) == 4) { + if (BurnLoadRom(Load3, i, 1)) return 1; + Load3 += ri.nLen; + + continue; + } + } + + if (game_type == 2) { + memcpy (Rom + 0x10000, Rom + 0x0c000, 0x04000); + memset (Rom + 0x0c000, 0, 0x04000); + } + + return 0; +} + +static int DrvInit() +{ + int nLen; + + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + if (GetRoms()) return 1; + + if (game_type == 1) { + BootGfxDecode(); + } else { + DrvGfxDecode(); + } + DrvCreatePalette(); + + ZetInit(1); + ZetOpen(0); + ZetSetReadHandler(gberet_read); + ZetSetWriteHandler(gberet_write); + ZetMapArea(0x0000, 0xbfff, 0, Rom + 0x0000); + ZetMapArea(0x0000, 0xbfff, 2, Rom + 0x0000); + ZetMapArea(0xc000, 0xcfff, 0, Rom + 0xc000); + ZetMapArea(0xc000, 0xcfff, 1, Rom + 0xc000); + ZetMapArea(0xd000, 0xd0ff, 0, Rom + 0xd000); + ZetMapArea(0xd000, 0xd0ff, 1, Rom + 0xd000); + ZetMapArea(0xd100, 0xd1ff, 0, Rom + 0xd100); + ZetMapArea(0xd100, 0xd1ff, 1, Rom + 0xd100); + ZetMapArea(0xd200, 0xdfff, 0, Rom + 0xd200); + ZetMapArea(0xd200, 0xdfff, 1, Rom + 0xd200); + ZetMapArea(0xd200, 0xdfff, 2, Rom + 0xd200); + if (game_type == 2) { + ZetMapArea(0xe800, 0xe8ff, 0, Rom + 0xe800); + ZetMapArea(0xe800, 0xe8ff, 1, Rom + 0xe800); + ZetMapArea(0xe800, 0xe8ff, 2, Rom + 0xe800); + } + ZetMemEnd(); + ZetClose(); + + SN76489Init(0, 18432000 / 12, 0); + + DrvDoReset(); + + if (game_type == 0) { + BurnSetRefreshRate(30.0); + } + + GenericTilesInit(); + + return 0; +} + +static int DrvExit() +{ + GenericTilesExit(); + + ZetExit(); + + free (Rom); + + game_type = 0; + + + return 0; +} + +static inline void put_pixel(int x, int y, int src, int color) +{ + int pxl = color | src; + + if (y < 0 || x < 0 || x >= nScreenWidth || y >= nScreenHeight | !Prom[pxl]) return; + + pTransDraw[(y * nScreenWidth) + x] = pxl; +} + +static void gberet_draw_16x16(int num, int sx, int sy, int color, int flipx, int flipy) +{ + color |= 0x100; + unsigned char *src = Gfx1 + (num << 8); + + if (flipy) { + if (flipx) { + for (int y = sy + 15; y >= sy; y--) { + for (int x = sx + 15; x >= sx; x--, src++) { + put_pixel(x, y, *src, color); + } + } + } else { + for (int y = sy + 15; y >= sy; y--) { + for (int x = sx; x < sx + 16; x++, src++) { + put_pixel(x, y, *src, color); + } + } + } + } else { + if (flipx) { + for (int y = sy; y < sy + 16; y++) { + for (int x = sx + 15; x >= sx; x--, src++) { + put_pixel(x, y, *src, color); + } + } + } else { + for (int y = sy; y < sy + 16; y++) { + for (int x = sx; x < sx + 16; x++, src++) { + put_pixel(x, y, *src, color); + } + } + } + } +} + +static void gberet_draw_sprites() +{ + unsigned char *sr = Rom + 0xd000 + ((~gberet_spritebank & 8) << 5); + + for (int offs = 0; offs < 0xc0; offs += 4) + { + if (sr[offs + 3]) + { + int attr = sr[offs + 1]; + int code = sr[offs + 0] + ((attr & 0x40) << 2); + int sx = sr[offs + 2] - 2 * (attr & 0x80); + int sy = sr[offs + 3]; + int color = (attr & 0x0f) << 4; + int flipx = attr & 0x10; + int flipy = attr & 0x20; + + if (flipscreen) + { + sx = 240 - sx; + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } + + sy -= 16; + sx -= 8; + + gberet_draw_16x16(code, sx, sy, color, flipx, flipy); + } + } +} + +static void gberetb_draw_sprites() +{ + for (int offs = 0x100 - 4; offs >= 0; offs -= 4) + { + if (Rom[0xe901 + offs]) + { + int attr = Rom[0xe903 + offs]; + int code = Rom[0xe900 + offs] + ((attr & 0x40) << 2); + int sx = Rom[0xe902 + offs] - 2 * (attr & 0x80); + int sy = 240 - Rom[0xe901 + offs]; + int color = (attr & 0x0f) << 4; + int flipx = attr & 0x10; + int flipy = attr & 0x20; + + if (flipscreen) + { + sx = 240 - sx; + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } + + sy -= 16; + sx -= 8; + + gberet_draw_16x16(code, sx, sy, color, flipx, flipy); + } + } +} + +static int DrvDraw() +{ + if (DrvRecalcPal) { + for (int i = 0; i < 0x200; i++) { + DrvPalette[i] = BurnHighCol(Palette[i] >> 16, Palette[i] >> 8, Palette[i], 0); + } + } + + for (int offs = 0x40; offs < 0x7c0; offs++) + { + int sx = (offs & 0x3f) << 3; + int sy = (offs >> 3) & 0xf8; + int attr = Rom[0xc000 + offs]; + int code = Rom[0xc800 + offs] + ((attr & 0x40) << 2); + int color = attr & 0x0f; + int flipy = attr & 0x20; + int flipx = attr & 0x10; + + int scroll = 0; + + if (game_type & 1) { + if (sy > 0x2f && sy < 0xe8) { + scroll = gberetb_scroll; + } + } else { + scroll = Rom[0xe000 | (sy >> 3)] | (Rom[0xe020 | (sy >> 3)] << 8); + } + + sx -= scroll; + sx += (sx >> 21) & 0x200; + + if (flipscreen) { + sx = 248 - sx; + sy = 248 - sy; + flipx = !flipx; + flipy = !flipy; + } + + sy -= 16; + sx -= 8; + + if (sx < -7 || sx >= 0x100 || sy < 0 || sy > 223) continue; + + if (flipy) { + if (flipx) { + Render8x8Tile_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0, Gfx0); + } else { + Render8x8Tile_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0, Gfx0); + } + } else { + if (flipx) { + Render8x8Tile_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0, Gfx0); + } else { + Render8x8Tile_Clip(pTransDraw, code, sx, sy, color, 4, 0, Gfx0); + + } + } + } + + if (game_type & 1) { + gberetb_draw_sprites(); + } else { + gberet_draw_sprites(); + } + + BurnTransferCopy(DrvPalette); + + return 0; +} + +static int DrvFrame() +{ + int nInterleave = game_type ? 16 : 32; + + if (DrvReset) { + DrvDoReset(); + } + + ZetOpen(0); + + int nCyclesDone, nCyclesTotal; + + nCyclesDone = 0; + nCyclesTotal = 3072000 / (nBurnFPS / 256); + + for (int i = 0; i < nInterleave; i++) + { + int nCyclesSegment = (nCyclesTotal - nCyclesDone) / (nInterleave - i); + + nCyclesDone = ZetRun(nCyclesSegment); + + if (irq_enable && i == (nInterleave - 1)) { + ZetRaiseIrq(0); + } + + if (nmi_enable && (i & 1)) { + ZetNmi(); + } + } + + ZetClose(); + + if (pBurnSoundOut) { + SN76496Update(0, pBurnSoundOut, nBurnSoundLen); + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029675; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0xc000; + ba.nLen = 0x4000; + ba.szName = "All Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + + SCAN_VAR(nmi_enable); + SCAN_VAR(irq_enable); + SCAN_VAR(flipscreen); + SCAN_VAR(mrgoemon_bank); + SCAN_VAR(gberetb_scroll); + SCAN_VAR(gberet_spritebank); + + ZetOpen(0); + mrgoemon_bankswitch(mrgoemon_bank); + ZetClose(); + } + + return 0; +} + + +// Green Beret + +static struct BurnRomInfo gberetRomDesc[] = { + { "577l03.10c", 0x4000, 0xae29e4ff, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "577l02.8c", 0x4000, 0x240836a5, 1 | BRF_PRG | BRF_ESS }, // 1 + { "577l01.7c", 0x4000, 0x41fa3e1f, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "577l07.3f", 0x4000, 0x4da7bd1b, 2 | BRF_GRA }, // 3 Characters + + { "577l06.5e", 0x4000, 0x0f1cb0ca, 3 | BRF_GRA }, // 4 Sprites + { "577l05.4e", 0x4000, 0x523a8b66, 3 | BRF_GRA }, // 5 + { "577l08.4f", 0x4000, 0x883933a4, 3 | BRF_GRA }, // 6 + { "577l04.3e", 0x4000, 0xccecda4c, 3 | BRF_GRA }, // 7 + + { "577h09.2f", 0x0020, 0xc15e7c80, 4 | BRF_GRA }, // 8 Color Proms + { "577h11.6f", 0x0100, 0x2a1a992b, 4 | BRF_GRA }, // 9 + { "577h10.5f", 0x0100, 0xe9de1e53, 4 | BRF_GRA }, // 10 +}; + +STD_ROM_PICK(gberet); +STD_ROM_FN(gberet); + +struct BurnDriver BurnDrvGberet = { + "gberet", NULL, NULL, "1985", + "Green Beret\0", NULL, "Konami", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, gberetRomInfo, gberetRomName, DrvInputInfo, gberetDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 240, 224, 4, 3 +}; + + +// Rush'n Attack (US) + +static struct BurnRomInfo rushatckRomDesc[] = { + { "577h03.10c", 0x4000, 0x4d276b52, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "577h02.8c", 0x4000, 0xb5802806, 1 | BRF_PRG | BRF_ESS }, // 1 + { "577h01.7c", 0x4000, 0xda7c8f3d, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "577h07.3f", 0x4000, 0x03f9815f, 2 | BRF_GRA }, // 3 Characters + + { "577l06.5e", 0x4000, 0x0f1cb0ca, 3 | BRF_GRA }, // 4 Sprites + { "577h05.4e", 0x4000, 0x9d028e8f, 3 | BRF_GRA }, // 5 + { "577l08.4f", 0x4000, 0x883933a4, 3 | BRF_GRA }, // 6 + { "577l04.3e", 0x4000, 0xccecda4c, 3 | BRF_GRA }, // 7 + + { "577h09.2f", 0x0020, 0xc15e7c80, 4 | BRF_GRA }, // 8 Color Proms + { "577h11.6f", 0x0100, 0x2a1a992b, 4 | BRF_GRA }, // 9 + { "577h10.5f", 0x0100, 0xe9de1e53, 4 | BRF_GRA }, // 10 +}; + +STD_ROM_PICK(rushatck); +STD_ROM_FN(rushatck); + +struct BurnDriver BurnDrvRushatck = { + "rushatck", "gberet", NULL, "1985", + "Rush'n Attack (US)\0", NULL, "Konami", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, rushatckRomInfo, rushatckRomName, DrvInputInfo, gberetDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 240, 224, 4, 3 +}; + + +// Green Beret (bootleg) + +static struct BurnRomInfo gberetbRomDesc[] = { + { "2-ic82.10g", 0x8000, 0x6d6fb494, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "3-ic81.10f", 0x4000, 0xf1520a0a, 1 | BRF_PRG | BRF_ESS }, // 1 + + { "1-ic92.12c", 0x4000, 0xb0189c87, 2 | BRF_GRA }, // 2 Characters + + { "7-1c8.2b", 0x4000, 0x86334522, 3 | BRF_GRA }, // 3 Sprites + { "6-ic9.2c", 0x4000, 0xbda50d3e, 3 | BRF_GRA }, // 4 + { "5-ic10.2d", 0x4000, 0x6a7b3881, 3 | BRF_GRA }, // 5 + { "4-ic11.2e", 0x4000, 0x3fb186c9, 3 | BRF_GRA }, // 6 + + { "577h09", 0x0020, 0xc15e7c80, 4 | BRF_GRA }, // 7 Color Proms + { "577h11.6f", 0x0100, 0x2a1a992b, 4 | BRF_GRA }, // 8 + { "577h10.5f", 0x0100, 0xe9de1e53, 4 | BRF_GRA }, // 9 +}; + +STD_ROM_PICK(gberetb); +STD_ROM_FN(gberetb); + +static int gberetbInit() +{ + game_type = 1; + + return DrvInit(); +} + +struct BurnDriver BurnDrvGberetb = { + "gberetb", "gberet", NULL, "1985", + "Green Beret (bootleg)\0", NULL, "bootleg", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_MISC_PRE90S, + NULL, gberetbRomInfo, gberetbRomName, gberetbInputInfo, gberetbDIPInfo, + gberetbInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 240, 224, 4, 3 +}; + + +// Mr. Goemon (Japan) + +static struct BurnRomInfo mrgoemonRomDesc[] = { + { "621d01.10c", 0x8000, 0xb2219c56, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "621d02.12c", 0x8000, 0xc3337a97, 1 | BRF_PRG | BRF_ESS }, // 1 + + { "621a05.6d", 0x4000, 0xf0a6dfc5, 2 | BRF_GRA }, // 2 Characters + + { "621d03.4d", 0x8000, 0x66f2b973, 3 | BRF_GRA }, // 3 Sprites + { "621d04.5d", 0x8000, 0x47df6301, 3 | BRF_GRA }, // 4 + + { "621a06.5f", 0x0020, 0x7c90de5f, 4 | BRF_GRA }, // 5 Color Proms + { "621a08.7f", 0x0100, 0x2fb244dd, 4 | BRF_GRA }, // 6 + { "621a07.6f", 0x0100, 0x3980acdc, 4 | BRF_GRA }, // 7 +}; + +STD_ROM_PICK(mrgoemon); +STD_ROM_FN(mrgoemon); + +static int mrgoemonInit() +{ + game_type = 2; + + return DrvInit(); +} + +struct BurnDriver BurnDrvMrgoemon = { + "mrgoemon", NULL, NULL, "1986", + "Mr. Goemon (Japan)\0", NULL, "Konami", "Miscellaneous", + L"Mr. Goemon \u4E94\u53F3\u885B\u9580 (Japan)\0", NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, mrgoemonRomInfo, mrgoemonRomName, DrvInputInfo, mrgoemonDIPInfo, + mrgoemonInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 240, 224, 4, 3 +}; + diff --git a/src/burn/misc/pre90s/d_gunsmoke.cpp b/src/burn/misc/pre90s/d_gunsmoke.cpp new file mode 100644 index 0000000..eaa9601 --- /dev/null +++ b/src/burn/misc/pre90s/d_gunsmoke.cpp @@ -0,0 +1,1006 @@ +// FB Alpha Gun.Smoke driver module +// Based on MAME driver by Paul Leaman + +#include "tiles_generic.h" +#include "burn_ym2203.h" + +static unsigned char *Mem, *MemEnd, *Rom0, *Rom1, *Ram; +static unsigned char *Gfx0, *Gfx1, *Gfx2, *Gfx3, *Prom; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvJoy3[8], DrvDips[2], DrvReset; +static unsigned int *Palette, *DrvPal; +static unsigned char DrvCalcPal; +static unsigned char *SprTrnsp; + +static unsigned char soundlatch; +static unsigned char flipscreen; +static int nGunsmokeBank; + +static unsigned char sprite3bank; +static unsigned char chon, bgon, objon; +static unsigned char gunsmoke_scrollx[2], gunsmoke_scrolly; + + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 6, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy1 + 0, "p1 start" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy2 + 0, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy2 + 1, "p1 left" }, + {"P1 Down" , BIT_DIGITAL , DrvJoy2 + 2, "p1 down" }, + {"P1 Up" , BIT_DIGITAL , DrvJoy2 + 3, "p1 up" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy2 + 5, "p1 fire 2"}, + {"P1 Button 3" , BIT_DIGITAL , DrvJoy2 + 6, "p1 fire 3"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy1 + 7, "p2 coin" }, + {"P2 start" , BIT_DIGITAL , DrvJoy1 + 1, "p2 start" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy3 + 0, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy3 + 1, "p2 left" }, + {"P2 Down" , BIT_DIGITAL , DrvJoy3 + 2, "p2 down" }, + {"P2 Up" , BIT_DIGITAL , DrvJoy3 + 3, "p2 up" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy3 + 4, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy3 + 5, "p2 fire 2"}, + {"P2 Button 3" , BIT_DIGITAL , DrvJoy3 + 6, "p2 fire 3"}, + + {"Service" , BIT_DIGITAL , DrvJoy1 + 4, "service" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDips + 1, "dip" }, + +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x14, 0xff, 0xff, 0xf7, NULL }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x14, 0x01, 0x03, 0x01, "30k 80k 80k+" }, + {0x14, 0x01, 0x03, 0x03, "30k 100k 100k+" }, + {0x14, 0x01, 0x03, 0x00, "30k 100k 150k+" }, + {0x14, 0x01, 0x03, 0x02, "30k 100k" }, + + {0 , 0xfe, 0 , 2 , "Demo" }, + {0x14, 0x01, 0x04, 0x00, "Off" }, + {0x14, 0x01, 0x04, 0x04, "On" }, +}; + +static struct BurnDIPInfo gunsmokaDIPList[]= +{ + // Default Values + {0x14, 0xff, 0xff, 0xf7, NULL }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x14, 0x01, 0x03, 0x01, "30k 80k 80k+" }, + {0x14, 0x01, 0x03, 0x03, "30k 100k 100k+" }, + {0x14, 0x01, 0x03, 0x00, "30k 100k 150k+" }, + {0x14, 0x01, 0x03, 0x02, "30k 100k" }, + + {0 , 0xfe, 0 , 2 , "Lifes" }, + {0x14, 0x01, 0x04, 0x04, "3" }, + {0x14, 0x01, 0x04, 0x00, "5" }, +}; + +static struct BurnDIPInfo gunsmokeDIPList[]= +{ + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x14, 0x01, 0x08, 0x00, "Upright" }, + {0x14, 0x01, 0x08, 0x08, "Cocktail" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x14, 0x01, 0x30, 0x20, "Easy" }, + {0x14, 0x01, 0x30, 0x30, "Normal" }, + {0x14, 0x01, 0x30, 0x10, "Difficult" }, + {0x14, 0x01, 0x30, 0x00, "Very Difficult" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x14, 0x01, 0x40, 0x40, "Off" }, + {0x14, 0x01, 0x40, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Service Mode" }, + {0x14, 0x01, 0x80, 0x80, "Off" }, + {0x14, 0x01, 0x80, 0x00, "On" }, + + // Default Values + {0x15, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x15, 0x01, 0x07, 0x00, "4 Coins 1 Credit" }, + {0x15, 0x01, 0x07, 0x01, "3 Coins 1 Credit" }, + {0x15, 0x01, 0x07, 0x02, "2 Coins 1 Credit" }, + {0x15, 0x01, 0x07, 0x07, "1 Coin 1 Credit" }, + {0x15, 0x01, 0x07, 0x06, "1 Coin 2 Credits" }, + {0x15, 0x01, 0x07, 0x05, "1 Coin 3 Credits" }, + {0x15, 0x01, 0x07, 0x04, "1 Coin 4 Credits" }, + {0x15, 0x01, 0x07, 0x03, "1 Coin 6 Credits" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x15, 0x01, 0x38, 0x00, "4 Coins 1 Credit" }, + {0x15, 0x01, 0x38, 0x08, "3 Coins 1 Credit" }, + {0x15, 0x01, 0x38, 0x10, "2 Coins 1 Credit" }, + {0x15, 0x01, 0x38, 0x38, "1 Coin 1 Credit" }, + {0x15, 0x01, 0x38, 0x30, "1 Coin 2 Credits" }, + {0x15, 0x01, 0x38, 0x28, "1 Coin 3 Credits" }, + {0x15, 0x01, 0x38, 0x20, "1 Coin 4 Credits" }, + {0x15, 0x01, 0x38, 0x18, "1 Coin 6 Credits" }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x15, 0x01, 0x40, 0x00, "No" }, + {0x15, 0x01, 0x40, 0x40, "Yes" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x15, 0x01, 0x80, 0x00, "Off" }, + {0x15, 0x01, 0x80, 0x80, "On" }, +}; + +STDDIPINFOEXT(Drv, Drv, gunsmoke); +STDDIPINFOEXT(gunsmoka, gunsmoka, gunsmoke); + + +static inline void gunsmoke_bankswitch(int nBank) +{ + if (nGunsmokeBank != nBank) { + nGunsmokeBank = nBank; + + ZetMapArea(0x8000, 0xbfff, 0, Rom0 + 0x10000 + nBank * 0x04000); + ZetMapArea(0x8000, 0xbfff, 2, Rom0 + 0x10000 + nBank * 0x04000); + } +} + +void __fastcall gunsmoke_cpu0_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0xc800: + soundlatch = data; + break; + + case 0xc804: + gunsmoke_bankswitch((data >> 2) & 3); + + flipscreen = data & 0x40; + chon = data & 0x80; + break; + + case 0xc806: + break; + + case 0xd800: + case 0xd801: + gunsmoke_scrollx[address & 1] = data; + break; + + case 0xd802: + case 0xd803: + gunsmoke_scrolly = data; + break; + + case 0xd806: + sprite3bank = data & 0x07; + + bgon = data & 0x10; + objon = data & 0x20; + break; + } +} + +unsigned char __fastcall gunsmoke_cpu0_read(unsigned short address) +{ + unsigned char ret = 0xff; + + switch (address) + { + case 0xc000: + { + for (int i = 0; i < 8; i++) + ret ^= DrvJoy1[i] << i; + + return ret | 0x08; + } + + case 0xc001: + { + for (int i = 0; i < 8; i++) + ret ^= DrvJoy2[i] << i; + + return ret; + } + + case 0xc002: + { + for (int i = 0; i < 8; i++) + ret ^= DrvJoy3[i] << i; + + return ret; + } + + case 0xc003: // dips + return DrvDips[0]; + + case 0xc004: + return DrvDips[1]; + + // reads at c4c9 - c4cb are part of some sort of protection or bug + case 0xc4c9: + return 0xff; + case 0xc4ca: + case 0xc4cb: + return 0; + } + + return 0; +} + +void __fastcall gunsmoke_cpu1_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0xe000: // control 0 + BurnYM2203Write(0, 0, data); + break; + + case 0xe001: // write 0 + BurnYM2203Write(0, 1, data); + break; + + case 0xe002: // control 1 + BurnYM2203Write(1, 0, data); + break; + + case 0xe003: // write 1 + BurnYM2203Write(1, 1, data); + break; + } +} + +unsigned char __fastcall gunsmoke_cpu1_read(unsigned short address) +{ + if (address == 0xc800) return soundlatch; + + return 0; +} + + +static int DrvDoReset() +{ + DrvReset = 0; + + memset (Ram, 0, 0x4000); + + nGunsmokeBank = -1; + soundlatch = 0; + flipscreen = 0; + + sprite3bank = 0; + chon = bgon = objon = 0; + gunsmoke_scrollx[0] = gunsmoke_scrollx[1] = 0; + gunsmoke_scrolly = 0; + + ZetOpen(0); + ZetReset(); + gunsmoke_bankswitch(0); + ZetClose(); + + ZetOpen(1); + ZetReset(); + ZetClose(); + + BurnYM2203Reset(); + + return 0; +} + +static int gunsmoke_palette_init() +{ + int i, ctabentry; + unsigned int tmp[0x100]; + + for (i = 0; i < 0x100; i++) + { + unsigned char r, g, b; + + r = Prom[i + 0x000] & 0x0f; + r |= r << 4; + g = Prom[i + 0x100] & 0x0f; + g |= g << 4; + b = Prom[i + 0x200] & 0x0f; + b |= b << 4; + + tmp[i] = (r << 16) | (g << 8) | b; + } + + for (i = 0; i < 0x100; i++) + { + ctabentry = Prom[0x300 + i] | 0x40; + Palette[0x000 + i] = tmp[ctabentry]; + + ctabentry = Prom[0x400 + i] | ((Prom[0x500 + i] & 0x03) << 4); + Palette[0x100 + i] = tmp[ctabentry]; + + ctabentry = Prom[0x600 + i] | ((Prom[0x700 + i] & 0x07) << 4) | 0x80; + Palette[0x200 + i] = tmp[ctabentry]; + } + + return 0; +} + +static int gunsmoke_gfx_decode() +{ + unsigned char *tmp = (unsigned char*)malloc(0x80000); + if (!tmp) return 1; + + static int Planes[4] = { 0x100004, 0x100000, 4, 0 }; + + static int CharXOffs[8] = { 11, 10, 9, 8, 3, 2, 1, 0 }; + static int CharYOffs[8] = { 112, 96, 80, 64, 48, 32, 16, 0 }; + + static int TileXOffs[32] = { 0, 1, 2, 3, 8, 9, 10, 11, + 512, 513, 514, 515, 520, 521, 522, 523, + 1024, 1025, 1026, 1027, 1032, 1033, 1034, 1035, + 1536, 1537, 1538, 1539, 1544, 1545, 1546, 1547 }; + + static int TileYOffs[32] = { 0, 16, 32, 48, 64, 80, 96, 112, + 128, 144, 160, 176, 192, 208, 224, 240, + 256, 272, 288, 304, 320, 336, 352, 368, + 384, 400, 416, 432, 448, 464, 480, 496 }; + + static int SpriXOffs[16] = { 0, 1, 2, 3, 8, 9, 10, 11, + 256, 257, 258, 259, 264, 265, 266, 267 }; + + memcpy (tmp, Gfx0, 0x04000); + GfxDecode(0x400, 2, 8, 8, Planes + 2, CharXOffs, CharYOffs, 0x080, tmp, Gfx0); + + memcpy (tmp, Gfx1, 0x40000); + GfxDecode(0x200, 4, 32, 32, Planes + 0, TileXOffs, TileYOffs, 0x800, tmp, Gfx1); + + memcpy (tmp, Gfx2, 0x40000); + GfxDecode(0x800, 4, 16, 16, Planes + 0, SpriXOffs, TileYOffs, 0x200, tmp, Gfx2); + + free (tmp); + + { + memset (SprTrnsp, 1, 0x800); + + for (int i = 0; i < 0x80000; i++) + if (Gfx2[i]) SprTrnsp[i >> 8] = 0; + } + + return 0; +} + +static int gunsmokeSynchroniseStream(int nSoundRate) +{ + return (long long)ZetTotalCycles() * nSoundRate / 3000000; +} + +static double gunsmokeGetTime() +{ + return (double)ZetTotalCycles() / 3000000; +} + + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + Rom0 = Next; Next += 0x20000; + Rom1 = Next; Next += 0x08000; + Ram = Next; Next += 0x04000; + Gfx0 = Next; Next += 0x10000; + Gfx1 = Next; Next += 0x80000; + Gfx2 = Next; Next += 0x80000; + Gfx3 = Next; Next += 0x08000; + Prom = Next; Next += 0x00800; + + SprTrnsp = Next; Next += 0x00800; + + Palette = (unsigned int*)Next; Next += 0x00300 * sizeof(unsigned int); + DrvPal = (unsigned int*)Next; Next += 0x00300 * sizeof(unsigned int); + + MemEnd = Next; + + return 0; +} + +static int DrvInit() +{ + int nLen; + + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + { + if (BurnLoadRom(Rom0 + 0x00000, 0, 1)) return 1; + if (BurnLoadRom(Rom0 + 0x10000, 1, 1)) return 1; + if (BurnLoadRom(Rom0 + 0x18000, 2, 1)) return 1; + + if (BurnLoadRom(Rom1 + 0x00000, 3, 1)) return 1; + + if (BurnLoadRom(Gfx0 + 0x00000, 4, 1)) return 1; + + if (BurnLoadRom(Gfx3 + 0x00000, 21, 1)) return 1; + + for (int i = 0; i < 8; i++) { + if (BurnLoadRom(Gfx1 + i * 0x8000, 5 + i, 1)) return 1; + if (BurnLoadRom(Gfx2 + i * 0x8000, 13 + i, 1)) return 1; + if (BurnLoadRom(Prom + i * 0x0100, 22 + i, 1)) return 1; + } + + gunsmoke_gfx_decode(); + gunsmoke_palette_init(); + } + + ZetInit(2); + ZetOpen(0); + ZetMapArea(0x0000, 0x7fff, 0, Rom0 + 0x00000); + ZetMapArea(0x0000, 0x7fff, 2, Rom0 + 0x00000); + ZetMapArea(0x8000, 0xbfff, 0, Rom0 + 0x10000); + ZetMapArea(0x8000, 0xbfff, 2, Rom0 + 0x10000); + ZetMapArea(0xd000, 0xd7ff, 0, Ram + 0x00000); + ZetMapArea(0xd000, 0xd7ff, 1, Ram + 0x00000); + ZetMapArea(0xe000, 0xefff, 0, Ram + 0x01000); + ZetMapArea(0xe000, 0xefff, 1, Ram + 0x01000); + ZetMapArea(0xe000, 0xefff, 2, Ram + 0x01000); + ZetMapArea(0xf000, 0xffff, 0, Ram + 0x02000); + ZetMapArea(0xf000, 0xffff, 1, Ram + 0x02000); + ZetSetReadHandler(gunsmoke_cpu0_read); + ZetSetWriteHandler(gunsmoke_cpu0_write); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetMapArea(0x0000, 0x7fff, 0, Rom1 + 0x00000); + ZetMapArea(0x0000, 0x7fff, 2, Rom1 + 0x00000); + ZetMapArea(0xc000, 0xc7ff, 0, Ram + 0x03000); + ZetMapArea(0xc000, 0xc7ff, 1, Ram + 0x03000); + ZetMapArea(0xc000, 0xc7ff, 2, Ram + 0x03000); + ZetSetReadHandler(gunsmoke_cpu1_read); + ZetSetWriteHandler(gunsmoke_cpu1_write); + ZetMemEnd(); + ZetClose(); + + GenericTilesInit(); + + BurnYM2203Init(2, 1500000, NULL, gunsmokeSynchroniseStream, gunsmokeGetTime, 0); + BurnTimerAttachZet(3000000); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + GenericTilesExit(); + + ZetExit(); + BurnYM2203Exit(); + + free (Mem); + + Mem = MemEnd = Rom0 = Rom1 = Ram = NULL; + Gfx0 = Gfx1 = Gfx2 = Gfx3 = Prom = NULL; + SprTrnsp = NULL; + Palette = DrvPal = NULL; + + soundlatch = flipscreen = nGunsmokeBank; + + sprite3bank = chon = bgon = objon = 0; + gunsmoke_scrollx[0] = gunsmoke_scrollx[1] = 0; + gunsmoke_scrolly = 0; + + return 0; +} + +static void draw_bg_layer() +{ + unsigned short scroll = gunsmoke_scrollx[0] + (gunsmoke_scrollx[1] << 8); + + unsigned char *tilerom = Gfx3 + ((scroll >> 1) & ~0x0f); + + for (int offs = 0; offs < 0x50; offs++) + { + int attr = tilerom[1]; + int code = tilerom[0] + ((attr & 1) << 8); + int color = (attr & 0x3c) >> 2; + int flipy = attr & 0x80; + int flipx = attr & 0x40; + + int sy = (offs & 7) << 5; + int sx = (offs >> 3) << 5; + + sy -= gunsmoke_scrolly; + sx -= (scroll & 0x1f); + + if (flipscreen) { + flipy ^= 0x80; + flipx ^= 0x40; + + sy = 224 - sy; + sx = 224 - sx; + } + + sy -= 16; + + if (flipy) { + if (flipx) { + Render32x32Tile_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0x100, Gfx1); + } else { + Render32x32Tile_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0x100, Gfx1); + } + } else { + if (flipx) { + Render32x32Tile_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0x100, Gfx1); + } else { + Render32x32Tile_Clip(pTransDraw, code, sx, sy, color, 4, 0x100, Gfx1); + } + } + + tilerom += 2; + } +} + +static void draw_fg_layer() +{ + for (int offs = 0; offs < 0x400; offs++) + { + int sx = (offs << 3) & 0xf8; + int sy = (offs >> 2) & 0xf8; + + int attr = Ram[0x0400 + offs]; + int code = Ram[0x0000 + offs] + ((attr & 0xe0) << 2); + int color = attr & 0x1f; + + if (code == 0x0024) continue; + + unsigned char *src = Gfx0 + (code << 6); + color <<= 2; + + if (flipscreen) { + sy = 240 - sy; + sx = 240 - sx; + + sy -= 8; + + for (int y = sy + 7; y >= sy; y--) + { + for (int x = sx + 7; x >= sx; x--, src++) + { + if (y < 0 || x < 0 || y > 223 || x > 255) continue; + if (!Palette[color|*src]) continue; + + pTransDraw[(y << 8) | x] = color | *src; + } + } + } else { + sy -= 16; + + for (int y = sy; y < sy + 8; y++) + { + for (int x = sx; x < sx + 8; x++, src++) + { + if (y < 0 || x < 0 || y > 223 || x > 255) continue; + if (!Palette[color|*src]) continue; + + pTransDraw[(y << 8) | x] = color | *src; + } + } + } + } +} + +static void draw_sprites() +{ + for (int offs = 0x1000 - 32; offs >= 0; offs -= 32) + { + int attr = Ram[0x2001 + offs]; + int bank = (attr & 0xc0) >> 6; + int code = Ram[0x2000 + offs]; + int color = attr & 0x0f; + int flipx = 0; + int flipy = attr & 0x10; + int sx = Ram[0x2003 + offs] - ((attr & 0x20) << 3); + int sy = Ram[0x2002 + offs]; + + if (sy == 0 || sy > 0xef) continue; + + if (bank == 3) bank += sprite3bank; + code += 256 * bank; + + if (SprTrnsp[code]) continue; + + if (flipscreen) + { + sx = 240 - sx; + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } + + sy -= 16; + + if (flipy) { + if (flipx) { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x200, Gfx2); + } else { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x200, Gfx2); + } + } else { + if (flipx) { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x200, Gfx2); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0x200, Gfx2); + } + } + } +} + +static int DrvDraw() +{ + // Recalculate palette + if (DrvCalcPal) { + for (int i = 0; i < 0x300; i++) { + unsigned int col = Palette[i]; + DrvPal[i] = BurnHighCol(col >> 16, col >> 8, col, 0); + } + } + + if (!bgon) memset (pTransDraw, 0, 224 * 256 * 2); + + if (bgon) draw_bg_layer(); + if (objon) draw_sprites(); + if (chon) draw_fg_layer(); + + BurnTransferCopy(DrvPal); + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetNewFrame(); + + int nInterleave = 12; + int nSoundBufferPos = 0; + + int nCyclesSegment; + int nCyclesDone[2], nCyclesTotal[2]; + + nCyclesTotal[0] = 4000000 / 60; + nCyclesTotal[1] = 3000000 / 60; + + nCyclesDone[0] = nCyclesDone[1] = 0; + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run Z80 #0 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if (i == (nInterleave - 1)) ZetSetIRQLine(0, ZET_IRQSTATUS_AUTO); + ZetClose(); + + // Run Z80 #1 + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if ((i % 4) == 3) ZetSetIRQLine(0, ZET_IRQSTATUS_AUTO); + ZetClose(); + + // Render Sound Segment + if (pBurnSoundOut) { + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + ZetOpen(1); + BurnYM2203Update(pSoundBuf, nSegmentLength); + ZetClose(); + nSoundBufferPos += nSegmentLength; + } + + } + + // Make sure the buffer is entirely filled. + if (pBurnSoundOut) { + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + ZetOpen(1); + BurnYM2203Update(pSoundBuf, nSegmentLength); + ZetClose(); + } + } + + ZetOpen(1); + BurnTimerEndFrame(nCyclesTotal[1] - nCyclesDone[1]); + ZetClose(); + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + + ba.Data = Ram; + ba.nLen = 0x4000; + ba.szName = "All Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + BurnYM2203Scan(nAction, pnMin); + + // Scan critical driver variables + SCAN_VAR(soundlatch); + SCAN_VAR(flipscreen); + SCAN_VAR(nGunsmokeBank); + SCAN_VAR(sprite3bank); + SCAN_VAR(chon); + SCAN_VAR(bgon); + SCAN_VAR(objon); + SCAN_VAR(gunsmoke_scrollx[0]); + SCAN_VAR(gunsmoke_scrollx[1]); + SCAN_VAR(gunsmoke_scrolly); + } + + return 0; +} + + +// Gun. Smoke (World) + +static struct BurnRomInfo gunsmokeRomDesc[] = { + { "09n_gs03.bin", 0x8000, 0x40a06cef, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "10n_gs04.bin", 0x8000, 0x8d4b423f, 1 | BRF_PRG | BRF_ESS }, // 1 + { "12n_gs05.bin", 0x8000, 0x2b5667fb, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "14h_gs02.bin", 0x8000, 0xcd7a2c38, 2 | BRF_PRG | BRF_ESS }, // 3 Z80 #1 Code + + { "11f_gs01.bin", 0x4000, 0xb61ece9b, 3 | BRF_GRA }, // 4 Character Tiles + + { "06c_gs13.bin", 0x8000, 0xf6769fc5, 4 | BRF_GRA }, // 5 32x32 Tiles + { "05c_gs12.bin", 0x8000, 0xd997b78c, 4 | BRF_GRA }, // 6 + { "04c_gs11.bin", 0x8000, 0x125ba58e, 4 | BRF_GRA }, // 7 + { "02c_gs10.bin", 0x8000, 0xf469c13c, 4 | BRF_GRA }, // 8 + { "06a_gs09.bin", 0x8000, 0x539f182d, 4 | BRF_GRA }, // 9 + { "05a_gs08.bin", 0x8000, 0xe87e526d, 4 | BRF_GRA }, // 10 + { "04a_gs07.bin", 0x8000, 0x4382c0d2, 4 | BRF_GRA }, // 11 + { "02a_gs06.bin", 0x8000, 0x4cafe7a6, 4 | BRF_GRA }, // 12 + + { "06n_gs22.bin", 0x8000, 0xdc9c508c, 5 | BRF_GRA }, // 13 Sprites + { "04n_gs21.bin", 0x8000, 0x68883749, 5 | BRF_GRA }, // 14 + { "03n_gs20.bin", 0x8000, 0x0be932ed, 5 | BRF_GRA }, // 15 + { "01n_gs19.bin", 0x8000, 0x63072f93, 5 | BRF_GRA }, // 16 + { "06l_gs18.bin", 0x8000, 0xf69a3c7c, 5 | BRF_GRA }, // 17 + { "04l_gs17.bin", 0x8000, 0x4e98562a, 5 | BRF_GRA }, // 18 + { "03l_gs16.bin", 0x8000, 0x0d99c3b3, 5 | BRF_GRA }, // 19 + { "01l_gs15.bin", 0x8000, 0x7f14270e, 5 | BRF_GRA }, // 20 + + { "11c_gs14.bin", 0x8000, 0x0af4f7eb, 6 | BRF_GRA }, // 21 Background Tilemaps + + { "03b_g-01.bin", 0x0100, 0x02f55589, 7 | BRF_GRA }, // 22 Color Proms + { "04b_g-02.bin", 0x0100, 0xe1e36dd9, 7 | BRF_GRA }, // 23 + { "05b_g-03.bin", 0x0100, 0x989399c0, 7 | BRF_GRA }, // 24 + { "09d_g-04.bin", 0x0100, 0x906612b5, 7 | BRF_GRA }, // 25 + { "14a_g-06.bin", 0x0100, 0x4a9da18b, 7 | BRF_GRA }, // 26 + { "15a_g-07.bin", 0x0100, 0xcb9394fc, 7 | BRF_GRA }, // 27 + { "09f_g-09.bin", 0x0100, 0x3cee181e, 7 | BRF_GRA }, // 28 + { "08f_g-08.bin", 0x0100, 0xef91cdd2, 7 | BRF_GRA }, // 29 + + { "02j_g-10.bin", 0x0100, 0x0eaf5158, 0 | BRF_OPT }, // 30 Video Timing + { "01f_g-05.bin", 0x0100, 0x25c90c2a, 0 | BRF_OPT }, // 31 Priority +}; + +STD_ROM_PICK(gunsmoke); +STD_ROM_FN(gunsmoke); + +struct BurnDriver BurnDrvGunsmoke = { + "gunsmoke", NULL, NULL, "1985", + "Gun. Smoke (World)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, gunsmokeRomInfo, gunsmokeRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Gun. Smoke (Japan) + +static struct BurnRomInfo gunsmokjRomDesc[] = { + { "gs03_9n.rom", 0x8000, 0xb56b5df6, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "10n_gs04.bin", 0x8000, 0x8d4b423f, 1 | BRF_PRG | BRF_ESS }, // 1 + { "12n_gs05.bin", 0x8000, 0x2b5667fb, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "14h_gs02.bin", 0x8000, 0xcd7a2c38, 2 | BRF_PRG | BRF_ESS }, // 3 Z80 #1 Code + + { "11f_gs01.bin", 0x4000, 0xb61ece9b, 3 | BRF_GRA }, // 4 Character Tiles + + { "06c_gs13.bin", 0x8000, 0xf6769fc5, 4 | BRF_GRA }, // 5 32x32 Tiles + { "05c_gs12.bin", 0x8000, 0xd997b78c, 4 | BRF_GRA }, // 6 + { "04c_gs11.bin", 0x8000, 0x125ba58e, 4 | BRF_GRA }, // 7 + { "02c_gs10.bin", 0x8000, 0xf469c13c, 4 | BRF_GRA }, // 8 + { "06a_gs09.bin", 0x8000, 0x539f182d, 4 | BRF_GRA }, // 9 + { "05a_gs08.bin", 0x8000, 0xe87e526d, 4 | BRF_GRA }, // 10 + { "04a_gs07.bin", 0x8000, 0x4382c0d2, 4 | BRF_GRA }, // 11 + { "02a_gs06.bin", 0x8000, 0x4cafe7a6, 4 | BRF_GRA }, // 12 + + { "06n_gs22.bin", 0x8000, 0xdc9c508c, 5 | BRF_GRA }, // 13 Sprites + { "04n_gs21.bin", 0x8000, 0x68883749, 5 | BRF_GRA }, // 14 + { "03n_gs20.bin", 0x8000, 0x0be932ed, 5 | BRF_GRA }, // 15 + { "01n_gs19.bin", 0x8000, 0x63072f93, 5 | BRF_GRA }, // 16 + { "06l_gs18.bin", 0x8000, 0xf69a3c7c, 5 | BRF_GRA }, // 17 + { "04l_gs17.bin", 0x8000, 0x4e98562a, 5 | BRF_GRA }, // 18 + { "03l_gs16.bin", 0x8000, 0x0d99c3b3, 5 | BRF_GRA }, // 19 + { "01l_gs15.bin", 0x8000, 0x7f14270e, 5 | BRF_GRA }, // 20 + + { "11c_gs14.bin", 0x8000, 0x0af4f7eb, 6 | BRF_GRA }, // 21 Background Tilemaps + + { "03b_g-01.bin", 0x0100, 0x02f55589, 7 | BRF_GRA }, // 22 Color Proms + { "04b_g-02.bin", 0x0100, 0xe1e36dd9, 7 | BRF_GRA }, // 23 + { "05b_g-03.bin", 0x0100, 0x989399c0, 7 | BRF_GRA }, // 24 + { "09d_g-04.bin", 0x0100, 0x906612b5, 7 | BRF_GRA }, // 25 + { "14a_g-06.bin", 0x0100, 0x4a9da18b, 7 | BRF_GRA }, // 26 + { "15a_g-07.bin", 0x0100, 0xcb9394fc, 7 | BRF_GRA }, // 27 + { "09f_g-09.bin", 0x0100, 0x3cee181e, 7 | BRF_GRA }, // 28 + { "08f_g-08.bin", 0x0100, 0xef91cdd2, 7 | BRF_GRA }, // 29 + + { "02j_g-10.bin", 0x0100, 0x0eaf5158, 0 | BRF_OPT }, // 30 Video Timing + { "01f_g-05.bin", 0x0100, 0x25c90c2a, 0 | BRF_OPT }, // 31 Priority +}; + +STD_ROM_PICK(gunsmokj); +STD_ROM_FN(gunsmokj); + +struct BurnDriver BurnDrvGunsmokj = { + "gunsmokj", "gunsmoke", NULL, "1985", + "Gun. Smoke (Japan)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, gunsmokjRomInfo, gunsmokjRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Gun. Smoke (US set 1) + +static struct BurnRomInfo gunsmokuRomDesc[] = { + { "9n_gs03.bin", 0x8000, 0x592f211b, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "10n_gs04.bin", 0x8000, 0x8d4b423f, 1 | BRF_PRG | BRF_ESS }, // 1 + { "12n_gs05.bin", 0x8000, 0x2b5667fb, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "14h_gs02.bin", 0x8000, 0xcd7a2c38, 2 | BRF_PRG | BRF_ESS }, // 3 Z80 #1 Code + + { "11f_gs01.bin", 0x4000, 0xb61ece9b, 3 | BRF_GRA }, // 4 Character Tiles + + { "06c_gs13.bin", 0x8000, 0xf6769fc5, 4 | BRF_GRA }, // 5 32x32 Tiles + { "05c_gs12.bin", 0x8000, 0xd997b78c, 4 | BRF_GRA }, // 6 + { "04c_gs11.bin", 0x8000, 0x125ba58e, 4 | BRF_GRA }, // 7 + { "02c_gs10.bin", 0x8000, 0xf469c13c, 4 | BRF_GRA }, // 8 + { "06a_gs09.bin", 0x8000, 0x539f182d, 4 | BRF_GRA }, // 9 + { "05a_gs08.bin", 0x8000, 0xe87e526d, 4 | BRF_GRA }, // 10 + { "04a_gs07.bin", 0x8000, 0x4382c0d2, 4 | BRF_GRA }, // 11 + { "02a_gs06.bin", 0x8000, 0x4cafe7a6, 4 | BRF_GRA }, // 12 + + { "06n_gs22.bin", 0x8000, 0xdc9c508c, 5 | BRF_GRA }, // 13 Sprites + { "04n_gs21.bin", 0x8000, 0x68883749, 5 | BRF_GRA }, // 14 + { "03n_gs20.bin", 0x8000, 0x0be932ed, 5 | BRF_GRA }, // 15 + { "01n_gs19.bin", 0x8000, 0x63072f93, 5 | BRF_GRA }, // 16 + { "06l_gs18.bin", 0x8000, 0xf69a3c7c, 5 | BRF_GRA }, // 17 + { "04l_gs17.bin", 0x8000, 0x4e98562a, 5 | BRF_GRA }, // 18 + { "03l_gs16.bin", 0x8000, 0x0d99c3b3, 5 | BRF_GRA }, // 19 + { "01l_gs15.bin", 0x8000, 0x7f14270e, 5 | BRF_GRA }, // 20 + + { "11c_gs14.bin", 0x8000, 0x0af4f7eb, 6 | BRF_GRA }, // 21 Background Tilemaps + + { "03b_g-01.bin", 0x0100, 0x02f55589, 7 | BRF_GRA }, // 22 Color Proms + { "04b_g-02.bin", 0x0100, 0xe1e36dd9, 7 | BRF_GRA }, // 23 + { "05b_g-03.bin", 0x0100, 0x989399c0, 7 | BRF_GRA }, // 24 + { "09d_g-04.bin", 0x0100, 0x906612b5, 7 | BRF_GRA }, // 25 + { "14a_g-06.bin", 0x0100, 0x4a9da18b, 7 | BRF_GRA }, // 26 + { "15a_g-07.bin", 0x0100, 0xcb9394fc, 7 | BRF_GRA }, // 27 + { "09f_g-09.bin", 0x0100, 0x3cee181e, 7 | BRF_GRA }, // 28 + { "08f_g-08.bin", 0x0100, 0xef91cdd2, 7 | BRF_GRA }, // 29 + + { "02j_g-10.bin", 0x0100, 0x0eaf5158, 0 | BRF_OPT }, // 30 Video Timing + { "01f_g-05.bin", 0x0100, 0x25c90c2a, 0 | BRF_OPT }, // 31 Priority +}; + +STD_ROM_PICK(gunsmoku); +STD_ROM_FN(gunsmoku); + +struct BurnDriver BurnDrvGunsmoku = { + "gunsmoku", "gunsmoke", NULL, "1985", + "Gun. Smoke (US set 1)\0", NULL, "Capcom (Romstar License)", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, gunsmokuRomInfo, gunsmokuRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Gun. Smoke (US set 2) + +static struct BurnRomInfo gunsmokaRomDesc[] = { + { "gs03.9n", 0x8000, 0x51dc3f76, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "gs04.10n", 0x8000, 0x5ecf31b8, 1 | BRF_PRG | BRF_ESS }, // 1 + { "gs05.12n", 0x8000, 0x1c9aca13, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "14h_gs02.bin", 0x8000, 0xcd7a2c38, 2 | BRF_PRG | BRF_ESS }, // 3 Z80 #1 Code + + { "11f_gs01.bin", 0x4000, 0xb61ece9b, 3 | BRF_GRA }, // 4 Character Tiles + + { "06c_gs13.bin", 0x8000, 0xf6769fc5, 4 | BRF_GRA }, // 5 32x32 Tiles + { "05c_gs12.bin", 0x8000, 0xd997b78c, 4 | BRF_GRA }, // 6 + { "04c_gs11.bin", 0x8000, 0x125ba58e, 4 | BRF_GRA }, // 7 + { "02c_gs10.bin", 0x8000, 0xf469c13c, 4 | BRF_GRA }, // 8 + { "06a_gs09.bin", 0x8000, 0x539f182d, 4 | BRF_GRA }, // 9 + { "05a_gs08.bin", 0x8000, 0xe87e526d, 4 | BRF_GRA }, // 10 + { "04a_gs07.bin", 0x8000, 0x4382c0d2, 4 | BRF_GRA }, // 11 + { "02a_gs06.bin", 0x8000, 0x4cafe7a6, 4 | BRF_GRA }, // 12 + + { "06n_gs22.bin", 0x8000, 0xdc9c508c, 5 | BRF_GRA }, // 13 Sprites + { "04n_gs21.bin", 0x8000, 0x68883749, 5 | BRF_GRA }, // 14 + { "03n_gs20.bin", 0x8000, 0x0be932ed, 5 | BRF_GRA }, // 15 + { "01n_gs19.bin", 0x8000, 0x63072f93, 5 | BRF_GRA }, // 16 + { "06l_gs18.bin", 0x8000, 0xf69a3c7c, 5 | BRF_GRA }, // 17 + { "04l_gs17.bin", 0x8000, 0x4e98562a, 5 | BRF_GRA }, // 18 + { "03l_gs16.bin", 0x8000, 0x0d99c3b3, 5 | BRF_GRA }, // 19 + { "01l_gs15.bin", 0x8000, 0x7f14270e, 5 | BRF_GRA }, // 20 + + { "11c_gs14.bin", 0x8000, 0x0af4f7eb, 6 | BRF_GRA }, // 21 Background Tilemaps + + { "03b_g-01.bin", 0x0100, 0x02f55589, 7 | BRF_GRA }, // 22 Color Proms + { "04b_g-02.bin", 0x0100, 0xe1e36dd9, 7 | BRF_GRA }, // 23 + { "05b_g-03.bin", 0x0100, 0x989399c0, 7 | BRF_GRA }, // 24 + { "09d_g-04.bin", 0x0100, 0x906612b5, 7 | BRF_GRA }, // 25 + { "14a_g-06.bin", 0x0100, 0x4a9da18b, 7 | BRF_GRA }, // 26 + { "15a_g-07.bin", 0x0100, 0xcb9394fc, 7 | BRF_GRA }, // 27 + { "09f_g-09.bin", 0x0100, 0x3cee181e, 7 | BRF_GRA }, // 28 + { "08f_g-08.bin", 0x0100, 0xef91cdd2, 7 | BRF_GRA }, // 29 + + { "02j_g-10.bin", 0x0100, 0x0eaf5158, 0 | BRF_OPT }, // 30 Video Timing + { "01f_g-05.bin", 0x0100, 0x25c90c2a, 0 | BRF_OPT }, // 31 Priority +}; + +STD_ROM_PICK(gunsmoka); +STD_ROM_FN(gunsmoka); + +struct BurnDriver BurnDrvGunsmoka = { + "gunsmoka", "gunsmoke", NULL, "1986", + "Gun. Smoke (US set 2)\0", NULL, "Capcom (Romstar License)", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, gunsmokaRomInfo, gunsmokaRomName, DrvInputInfo, gunsmokaDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + diff --git a/src/burn/misc/pre90s/d_higemaru.cpp b/src/burn/misc/pre90s/d_higemaru.cpp new file mode 100644 index 0000000..dceb3c4 --- /dev/null +++ b/src/burn/misc/pre90s/d_higemaru.cpp @@ -0,0 +1,539 @@ +// FB Alpha Pirate Ship Higemaru Module +// Based on MAME driver by Mirko Buffoni + +#include "tiles_generic.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +static unsigned char *Mem, *MemEnd, *Rom, *Gfx0, *Gfx1, *Prom; +static short *pAY8910Buffer[6], *pFMBuffer = NULL; +static unsigned int *DrvPalette, *Palette; +static unsigned char DrvRecalc = 0; + +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvJoy3[8], DrvDips[3], DrvReset; + +static int flipscreen; + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1" , BIT_DIGITAL , DrvJoy3 + 7, "p1 coin" }, + {"Coin 2" , BIT_DIGITAL , DrvJoy3 + 6, "p2 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy3 + 5, "p1 start" }, + {"P2 Start" , BIT_DIGITAL , DrvJoy3 + 4, "p2 start" }, + + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 0, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 1, "p1 left" }, + {"P1 Down" , BIT_DIGITAL , DrvJoy1 + 2, "p1 down" }, + {"P1 Up" , BIT_DIGITAL , DrvJoy1 + 3, "p1 up" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy3 + 3, "p1 fire 1"}, + + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 0, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 1, "p2 left" }, + {"P2 Down" , BIT_DIGITAL , DrvJoy2 + 2, "p2 down" }, + {"P2 Up" , BIT_DIGITAL , DrvJoy2 + 3, "p2 up" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy3 + 1, "p2 fire 1"}, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDips + 0, "dip 1" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDips + 1, "dip 2" }, + {"Dip 3" , BIT_DIPSWITCH, DrvDips + 2, "dip 3" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + {0x10, 0xff, 0xff, 0xff, NULL }, + {0x11, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x0f, 0x01, 0x04, 0x04, "Off" }, + {0x0f, 0x01, 0x04, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x10, 0x01, 0x07, 0x01, "5 Coins 1 Play" }, + {0x10, 0x01, 0x07, 0x02, "4 Coins 1 Play" }, + {0x10, 0x01, 0x07, 0x03, "3 Coins 1 Play" }, + {0x10, 0x01, 0x07, 0x04, "1 Coins 1 Play" }, + {0x10, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x10, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x10, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x10, 0x01, 0x07, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x10, 0x01, 0x38, 0x08, "5 Coins 1 Play" }, + {0x10, 0x01, 0x38, 0x10, "4 Coins 1 Play" }, + {0x10, 0x01, 0x38, 0x18, "3 Coins 1 Play" }, + {0x10, 0x01, 0x38, 0x20, "1 Coins 1 Play" }, + {0x10, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x10, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x10, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, + {0x10, 0x01, 0x38, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x10, 0x01, 0xc0, 0x80, "1" }, + {0x10, 0x01, 0xc0, 0x40, "2" }, + {0x10, 0x01, 0xc0, 0xc0, "3" }, + {0x10, 0x01, 0xc0, 0x00, "5" }, + + // Dip 3 + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x11, 0x01, 0x01, 0x00, "Upright" }, + {0x11, 0x01, 0x01, 0x01, "Cocktail" }, + + {0 , 0xfe, 0 , 8 , "Bonus Life" }, + {0x11, 0x01, 0x0e, 0x0e, "10k 50k 50k" }, + {0x11, 0x01, 0x0e, 0x0c, "10k 60k 60k" }, + {0x11, 0x01, 0x0e, 0x0a, "20k 60k 60k" }, + {0x11, 0x01, 0x0e, 0x08, "20k 70k 70k" }, + {0x11, 0x01, 0x0e, 0x06, "30k 70k 70k" }, + {0x11, 0x01, 0x0e, 0x04, "30k 80k 80k" }, + {0x11, 0x01, 0x0e, 0x02, "40k 100k 100k" }, + {0x11, 0x01, 0x0e, 0x00, "None" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x11, 0x01, 0x10, 0x00, "Off" }, + {0x11, 0x01, 0x10, 0x10, "On" }, + + {0 , 0xfe, 0 , 2 , "Demo Music" }, + {0x11, 0x01, 0x20, 0x00, "Off" }, + {0x11, 0x01, 0x20, 0x20, "On" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x11, 0x01, 0x40, 0x40, "Off" }, + {0x11, 0x01, 0x40, 0x00, "On" }, +}; + +STDDIPINFO(Drv); + +void __fastcall higemaru_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0xc800: + flipscreen = data >> 7; + break; + + case 0xc801: + case 0xc802: + AY8910Write(0, (address - 1) & 1, data); + break; + + case 0xc803: + case 0xc804: + AY8910Write(1, (address - 1) & 1, data); + break; + } +} + +unsigned char __fastcall higemaru_read(unsigned short address) +{ + unsigned char ret; + + switch (address) + { + case 0xc000: + { + ret = 0xff; + + for (int i = 0; i < 8; i++) { + ret ^= DrvJoy1[i] << i; + } + + return ret; + } + + case 0xc001: + { + ret = 0xff; + + for (int i = 0; i < 8; i++) { + ret ^= DrvJoy2[i] << i; + } + + return ret; + } + + case 0xc002: + { + ret = DrvDips[0]; + + for (int i = 0; i < 8; i++) + ret ^= DrvJoy3[i] << i; + + return ret; + } + + case 0xc003: + return DrvDips[1]; + + case 0xc004: + return DrvDips[2]; + } + + return 0; +} + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + Rom = Next; Next += 0x10000; + Gfx0 = Next; Next += 0x08000; + Gfx1 = Next; Next += 0x08000; + Prom = Next; Next += 0x00300; + + Palette = (unsigned int*)Next; Next += 0x00180 * sizeof(unsigned int); + DrvPalette = (unsigned int*)Next; Next += 0x00180 * sizeof(unsigned int); + + pFMBuffer = (short*)Next; Next += (nBurnSoundLen * 6 * sizeof(short)); + + MemEnd = Next; + + return 0; +} + +static int DrvDoReset() +{ + memset (Rom + 0xd000, 0, 0x2000); + + AY8910Reset(0); + AY8910Reset(1); + + ZetOpen(0); + ZetReset(); + ZetClose(); + + flipscreen = 0; + + return 0; +} + +static void DrvPaletteInit() +{ + unsigned int tmp[0x20]; + + for (int i = 0; i < 0x20; i++) + { + int bit0, bit1, bit2; + + bit0 = (Prom[i] >> 0) & 1; + bit1 = (Prom[i] >> 1) & 1; + bit2 = (Prom[i] >> 2) & 1; + int r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = (Prom[i] >> 3) & 1; + bit1 = (Prom[i] >> 4) & 1; + bit2 = (Prom[i] >> 5) & 1; + int g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit1 = (Prom[i] >> 6) & 1; + bit2 = (Prom[i] >> 7) & 1; + int b = 0x47 * bit1 + 0x97 * bit2; + + tmp[i] = (r << 16) | (g << 8) | b; + } + + Prom += 0x100; + + for (int i = 0; i < 0x80; i++) { + Palette[i] = tmp[Prom[i] & 0x0f]; + } + + for (int i = 0x80; i < 0x180; i++) { + Palette[i] = tmp[(Prom[i + 0x80] & 0x0f) | 0x10]; + } +} + +static int DrvGfxDecode() +{ + unsigned char *tmp = (unsigned char*)malloc(0x4000); + if (tmp == NULL) { + return 1; + } + + memcpy (tmp, Gfx0, 0x2000); + + static int Planes[4] = { 0x10004, 0x10000, 0x00004, 0x00000 }; + static int XOffs[16] = { 0x000, 0x001, 0x002, 0x003, 0x008, 0x009, 0x00a, 0x00b, + 0x100, 0x101, 0x102, 0x103, 0x108, 0x109, 0x10a, 0x10b }; + static int YOffs[16] = { 0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, + 0x080, 0x090, 0x0a0, 0x0b0, 0x0c0, 0x0d0, 0x0e0, 0x0f0 }; + + GfxDecode(0x200, 2, 8, 8, Planes + 2, XOffs, YOffs, 0x080, tmp, Gfx0); + + memcpy (tmp, Gfx1, 0x4000); + + GfxDecode(0x080, 4, 16, 16, Planes, XOffs, YOffs, 0x200, tmp, Gfx1); + + free (tmp); + + return 0; +} + +static int DrvInit() +{ + int nLen; + + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + for (int i = 0; i < 6; i++) { + pAY8910Buffer[i] = pFMBuffer + nBurnSoundLen * i; + } + + { + for (int i = 0; i < 4; i++) { + if (BurnLoadRom(Rom + i * 0x2000, i + 0, 1)) return 1; + } + + if (BurnLoadRom(Gfx0 + 0x0000, 4, 1)) return 1; + if (BurnLoadRom(Gfx1 + 0x0000, 5, 1)) return 1; + if (BurnLoadRom(Gfx1 + 0x2000, 6, 1)) return 1; + + for (int i = 0; i < 3; i++) { + if (BurnLoadRom(Prom + i * 0x100, i + 7, 1)) return 1; + } + + if (DrvGfxDecode()) return 1; + DrvPaletteInit(); + } + + ZetInit(1); + ZetOpen(0); + ZetMapArea(0x0000, 0x7fff, 0, Rom + 0x0000); + ZetMapArea(0x0000, 0x7fff, 2, Rom + 0x0000); + ZetMapArea(0xd000, 0xd7ff, 0, Rom + 0xd000); + ZetMapArea(0xd000, 0xd9ff, 1, Rom + 0xd000); + ZetMapArea(0xe000, 0xefff, 0, Rom + 0xe000); + ZetMapArea(0xe000, 0xefff, 1, Rom + 0xe000); + ZetMapArea(0xe000, 0xefff, 2, Rom + 0xe000); + ZetSetWriteHandler(higemaru_write); + ZetSetReadHandler(higemaru_read); + ZetClose(); + + AY8910Init(0, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(1, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + GenericTilesInit(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + AY8910Exit(0); + AY8910Exit(1); + GenericTilesExit(); + + free (Mem); + + Mem = MemEnd = Rom = Gfx0 = Gfx1 = Prom = NULL; + DrvPalette = Palette = NULL; + pFMBuffer = NULL; + + for (int i = 0; i < 6; i++) { + pAY8910Buffer[i] = NULL; + } + + flipscreen = 0; + DrvRecalc = 0; + + return 0; +} + + +static int DrvDraw() +{ + if (DrvRecalc) { + for (int i = 0; i < 0x100; i++) { + int color = Palette[i]; + DrvPalette[i] = BurnHighCol(color >> 16, color >> 8, color, 0); + } + } + + for (int offs = 0x40; offs < 0x3c0; offs++) + { + int sx = (offs << 3) & 0xf8; + int sy = (offs >> 2) & 0xf8; + + int code = Rom[0xd000 + offs] | ((Rom[0xd400 + offs] & 0x80) << 1); + int color = Rom[0xd400 + offs] & 0x1f; + + sy -= 16; + + if (flipscreen) { + Render8x8Tile_FlipXY_Clip(pTransDraw, code, sx ^ 0xf8, 216 - sy, color, 2, 0, Gfx0); + } else { + Render8x8Tile_Clip(pTransDraw, code, sx, sy, color, 2, 0, Gfx0); + } + } + + for (int offs = 0x170; offs >= 0; offs -= 16) + { + int code,color,sx,sy,flipx,flipy; + + code = Rom[0xd880 + offs] & 0x7f; + color = Rom[0xd884 + offs] & 0x0f; + sx = Rom[0xd88c + offs]; + sy = Rom[0xd888 + offs]; + flipx = Rom[0xd884 + offs] & 0x10; + flipy = Rom[0xd884 + offs] & 0x20; + + if (flipscreen) + { + sx = 240 - sx; + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } + + sy -= 16; + + if (flipy) { + if (flipx) { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0x0f, 0x80, Gfx1); + if (sx > 0xf0) Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code, sx - 256, sy, color, 4, 0x0f, 0x80, Gfx1); + } else { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0x0f, 0x80, Gfx1); + if (sx > 0xf0) Render16x16Tile_Mask_FlipY_Clip(pTransDraw, code, sx - 256, sy, color, 4, 0x0f, 0x80, Gfx1); + } + } else { + if (flipx) { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0x0f, 0x80, Gfx1); + if (sx > 0xf0) Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx - 256, sy, color, 4, 0x0f, 0x80, Gfx1); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 0x0f, 0x80, Gfx1); + if (sx > 0xf0) Render16x16Tile_Mask_Clip(pTransDraw, code, sx - 256, sy, color, 4, 0x0f, 0x80, Gfx1); + } + } + } + + BurnTransferCopy(DrvPalette); + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetOpen(0); + ZetRun(33333); + ZetRaiseIrq(0xd7); + ZetRun(33334); + ZetRaiseIrq(0xcf); + ZetClose(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + +static int DrvScan(int nAction, int *pnMin) +{ + struct BurnArea ba; + + if (pnMin != NULL) { + *pnMin = 0x029672; + } + + if (nAction & ACB_MEMORY_RAM) { + memset(&ba, 0, sizeof(ba)); + ba.Data = Rom + 0xd000; + ba.nLen = 0x2000; + ba.szName = "All Ram"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + ZetScan(nAction); + AY8910Scan(nAction, pnMin); + + SCAN_VAR(flipscreen); + } + + return 0; +} + + +// Pirate Ship Higemaru + +static struct BurnRomInfo higemaruRomDesc[] = { + { "hg4", 0x2000, 0xdc67a7f9, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "hg5", 0x2000, 0xf65a4b68, 1 | BRF_PRG | BRF_ESS }, // 1 + { "hg6", 0x2000, 0x5f5296aa, 1 | BRF_PRG | BRF_ESS }, // 2 + { "hg7", 0x2000, 0xdc5d455d, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "hg3", 0x2000, 0xb37b88c8, 2 | BRF_GRA }, // 4 Characters + + { "hg1", 0x2000, 0xef4c2f5d, 3 | BRF_GRA }, // 5 Sprites + { "hg2", 0x2000, 0x9133f804, 3 | BRF_GRA }, // 6 + + { "hgb3", 0x0020, 0x629cebd8, 4 | BRF_GRA }, // 7 Color Proms + { "hgb5", 0x0100, 0xdbaa4443, 4 | BRF_GRA }, // 8 + { "hgb1", 0x0100, 0x07c607ce, 4 | BRF_GRA }, // 9 + + { "hgb4", 0x0100, 0x712ac508, 0 | BRF_OPT }, // 10 Misc. Proms (not used) + { "hgb2", 0x0100, 0x4921635c, 0 | BRF_OPT }, // 11 +}; + +STD_ROM_PICK(higemaru); +STD_ROM_FN(higemaru); + +struct BurnDriver BurnDrvhigemaru = { + "higemaru", NULL, NULL, "1984", + "Pirate Ship Higemaru\0", NULL, "Capcom", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, higemaruRomInfo, higemaruRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalc, + 256, 224, 4, 3 +}; + diff --git a/src/burn/misc/pre90s/d_jack.cpp b/src/burn/misc/pre90s/d_jack.cpp index 8b13789..e85fb90 100644 --- a/src/burn/misc/pre90s/d_jack.cpp +++ b/src/burn/misc/pre90s/d_jack.cpp @@ -1 +1,1935 @@ +// FB Alpha Jack the Giantkiller driver module +// Based on MAME driver by Brad Oliver + +#include "tiles_generic.h" +#include "bitswap.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + + +static unsigned char *Mem, *Rom0, *Rom1, *Gfx, *Prom, *User; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvJoy3[8], DrvJoy4[8], DrvReset, DrvDips[2]; +static short *pAY8910Buffer[3], *pFMBuffer = NULL; +static int tri_fix, joinem, loverb, suprtriv; +static int timer_rate, flip_screen; +static unsigned int *Palette, *DrvPal; +static unsigned char DrvCalcPal; +static int snd_cpu_irq; + +static unsigned char soundlatch; +static int question_address, question_rom, remap_address[16]; +static int joinem_snd_bit; + +static struct BurnInputInfo JackInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 6, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy1 + 0, "p1 start" }, + {"p1 Up" , BIT_DIGITAL, DrvJoy2 + 0, "p1 up" }, + {"P1 Down", BIT_DIGITAL, DrvJoy2 + 1, "p1 down", }, + {"P1 Right" , BIT_DIGITAL , DrvJoy2 + 2, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy2 + 3, "p1 left" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy3 + 0, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy3 + 1, "p1 fire 2"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy1 + 5, "p2 coin" }, + {"P2 start" , BIT_DIGITAL , DrvJoy1 + 1, "p2 start" }, + {"p2 Up" , BIT_DIGITAL, DrvJoy2 + 4, "p2 up" }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 5, "p2 down", }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 6, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 7, "p2 left" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy4 + 0, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy4 + 1, "p2 fire 2"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip" }, +}; + +STDINPUTINFO(Jack); + +static struct BurnInputInfo ZzyzzyxxInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 5, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy1 + 0, "p1 start" }, + {"P1 Up" , BIT_DIGITAL , DrvJoy2 + 0, "p1 up" }, + {"P1 Down", BIT_DIGITAL, DrvJoy2 + 1, "p1 down", }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy3 + 0, "p1 fire 1"}, + + {"P2 start" , BIT_DIGITAL , DrvJoy1 + 1, "p2 start" }, + {"P2 Up" , BIT_DIGITAL , DrvJoy2 + 4, "p2 Up" }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 5, "p2 down", }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy4 + 0, "p2 fire 1"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip" }, +}; + +STDINPUTINFO(Zzyzzyxx); + +static struct BurnInputInfo FreezeInputList[] = { + {"Coin" , BIT_DIGITAL , DrvJoy1 + 5, "p1 coin" }, + {"Start 1" , BIT_DIGITAL , DrvJoy1 + 0, "p1 start" }, + {"Start 2" , BIT_DIGITAL , DrvJoy1 + 1, "p2 start" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy2 + 0, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy2 + 1, "p1 left" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy3 + 1, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy3 + 0, "p1 fire 2"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, +}; + +STDINPUTINFO(Freeze); + +static struct BurnInputInfo SucasinoInputList[] = { + {"Coin" , BIT_DIGITAL , DrvJoy1 + 6, "p1 coin" }, + + {"P1 start" , BIT_DIGITAL , DrvJoy1 + 0, "p1 start" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy2 + 2, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy2 + 3, "p1 left" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy3 + 0, "p1 fire 1"}, + + {"P2 start" , BIT_DIGITAL , DrvJoy1 + 1, "p2 start" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 6, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 7, "p2 left" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy4 + 0, "p2 fire 1"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, +}; + +STDINPUTINFO(Sucasino); + +static struct BurnInputInfo TripoolInputList[] = { + {"Select Game 1", BIT_DIGITAL , DrvJoy1 + 2, "Select Game 1"}, + {"Select Game 2", BIT_DIGITAL, DrvJoy1 + 3, "Select Game 2"}, + {"Select Game 3", BIT_DIGITAL, DrvJoy1 + 4, "Select Game 3"}, + + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 6, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy1 + 0, "p1 start" }, + {"P1 Up", BIT_DIGITAL, DrvJoy2 + 0, "p1 up" }, + {"P1 Down", BIT_DIGITAL, DrvJoy2 + 1, "p1 down", }, + {"P1 Right" , BIT_DIGITAL , DrvJoy2 + 2, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy2 + 3, "p1 left" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy3 + 0, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy3 + 1, "p1 fire 2"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy1 + 5, "p2 coin" }, + {"P2 start" , BIT_DIGITAL , DrvJoy1 + 1, "p2 start" }, + {"P1 Up", BIT_DIGITAL, DrvJoy2 + 4, "p1 up" }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 5, "p2 down", }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 6, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 7, "p2 left" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy4 + 0, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy4 + 1, "p2 fire 2"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, +}; + +STDINPUTINFO(Tripool); + +static struct BurnInputInfo JoinemInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy3 + 0, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy3 + 2, "p1 start" }, + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up", }, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 1, "p1 down", }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 2, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 3, "p1 left" }, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy3 + 1, "p2 coin" }, + {"P2 start" , BIT_DIGITAL , DrvJoy3 + 3, "p2 start" }, + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up", }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 1, "p2 down", }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 2, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 3, "p2 left" }, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip" }, +}; + +STDINPUTINFO(Joinem); + +static struct BurnInputInfo LoverboyInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy3 + 0, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy3 + 2, "p1 start" }, + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up", }, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 1, "p1 down", }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 2, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 3, "p1 left" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 1"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy3 + 1, "p2 coin" }, + {"P2 start" , BIT_DIGITAL , DrvJoy3 + 3, "p2 start" }, + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up", }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 1, "p2 down", }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 2, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 3, "p2 left" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 1"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, +}; + +STDINPUTINFO(Loverboy); + +static struct BurnInputInfo StrivInputList[] = { + {"Coin" , BIT_DIGITAL , DrvJoy3 + 1, "p1 coin" }, + + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 1, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 2, "p1 fire 2"}, + {"P1 Button 3" , BIT_DIGITAL , DrvJoy1 + 3, "p1 fire 3"}, + {"P1 Button 4" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 4"}, + + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 1, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 2, "p2 fire 2"}, + {"P2 Button 3" , BIT_DIGITAL , DrvJoy2 + 3, "p2 fire 3"}, + {"P2 Button 4" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 4"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip" }, +}; + +STDINPUTINFO(Striv); + +static struct BurnDIPInfo JackDIPList[]= +{ + // Default Values + {0x11, 0xff, 0xff, 0x00, NULL}, + {0x12, 0xff, 0xff, 0x00, NULL}, + + // DSW1 + {0 , 0xfe, 0 , 4 , "Coin B"}, + {0x11, 0x01, 0x03, 0x01, "2 coins 1 credit"}, + {0x11, 0x01, 0x03, 0x03, "4 coins 3 credits"}, + {0x11, 0x01, 0x03, 0x00, "1 coin 1 credit"}, + {0x11, 0x01, 0x03, 0x02, "1 coin 3 credits"}, + + {0 , 0xfe, 0 , 4 , "Coin A"}, + {0x11, 0x01, 0x0c, 0x00, "3 coins 1 credit"}, + {0x11, 0x01, 0x0c, 0x04, "2 coins 1 credit"}, + {0x11, 0x01, 0x0c, 0x08, "4 coins 3 credits"}, + {0x11, 0x01, 0x0c, 0x0c, "1 coin 1 credits"}, + + {0 , 0xfe, 0 , 2 , "Lives"}, + {0x11, 0x01, 0x10, 0x00, "3"}, + {0x11, 0x01, 0x10, 0x10, "5"}, + + {0 , 0xfe, 0 , 2 , "Bonus Life"}, + {0x11, 0x01, 0x20, 0x00, "Every 10000"}, + {0x11, 0x01, 0x20, 0x20, "10000 ONly"}, + + {0 , 0xfe, 0 , 2 , "Difficulty"}, + {0x11, 0x01, 0x40, 0x00, "Start on Level 1"}, + {0x11, 0x01, 0x40, 0x40, "Start on Level 13"}, + + {0 , 0xfe, 0 , 2 , "Bullets per Bean Collected"}, + {0x11, 0x01, 0x80, 0x00, "1"}, + {0x11, 0x01, 0x80, 0x80, "2"}, + + // DSW2 + {0 , 0xfe, 0 , 2 , "Cabinet"}, + {0x12, 0x01, 0x01, 0x01, "Upright"}, + {0x12, 0x01, 0x01, 0x00, "Cocktail"}, + + {0 , 0xfe, 0 , 2 , "Invulnerability (Cheat)"}, + {0x12, 0x01, 0x40, 0x00, "Off"}, + {0x12, 0x01, 0x40, 0x40, "On"}, + + {0 , 0xfe, 0 , 4 , "255 Lives (Cheat)"}, + {0x12, 0x01, 0x80, 0x00, "Off"}, + {0x12, 0x01, 0x80, 0x80, "On"}, +}; + +STDDIPINFO(Jack); + + +static struct BurnDIPInfo Jack2DIPList[]= +{ + // Default Values + {0x11, 0xff, 0xff, 0x00, NULL}, + {0x12, 0xff, 0xff, 0x00, NULL}, + + // DSW1 + {0 , 0xfe, 0 , 4 , "Coin B"}, + {0x11, 0x01, 0x03, 0x03, "4 coins 3 credits"}, + {0x11, 0x01, 0x03, 0x00, "1 coin 1 credit"}, + {0x11, 0x01, 0x03, 0x01, "1 coin 2 credits"}, + {0x11, 0x01, 0x03, 0x02, "1 coin 3 credits"}, + + {0 , 0xfe, 0 , 4 , "Coin A"}, + {0x11, 0x01, 0x0c, 0x08, "3 coins 1 credit"}, + {0x11, 0x01, 0x0c, 0x04, "2 coins 1 credit"}, + {0x11, 0x01, 0x0c, 0x0c, "4 coins 3 credits"}, + {0x11, 0x01, 0x0c, 0x00, "1 coin 1 credits"}, + + {0 , 0xfe, 0 , 2 , "Lives"}, + {0x11, 0x01, 0x10, 0x00, "3"}, + {0x11, 0x01, 0x10, 0x10, "5"}, + + {0 , 0xfe, 0 , 2 , "Bonus Life"}, + {0x11, 0x01, 0x20, 0x00, "Every 10000"}, + {0x11, 0x01, 0x20, 0x20, "10000 ONly"}, + + {0 , 0xfe, 0 , 2 , "Difficulty"}, + {0x11, 0x01, 0x40, 0x00, "Start on Level 1"}, + {0x11, 0x01, 0x40, 0x40, "Start on Level 13"}, + + {0 , 0xfe, 0 , 2 , "Bullets per Bean Collected"}, + {0x11, 0x01, 0x80, 0x00, "1"}, + {0x11, 0x01, 0x80, 0x80, "2"}, + + // DSW2 + {0 , 0xfe, 0 , 2 , "Cabinet"}, + {0x12, 0x01, 0x01, 0x01, "Upright"}, + {0x12, 0x01, 0x01, 0x00, "Cocktail"}, + + {0 , 0xfe, 0 , 2 , "Invulnerability (Cheat)"}, + {0x12, 0x01, 0x40, 0x00, "Off"}, + {0x12, 0x01, 0x40, 0x40, "On"}, + + {0 , 0xfe, 0 , 4 , "255 Lives (Cheat)"}, + {0x12, 0x01, 0x80, 0x00, "Off"}, + {0x12, 0x01, 0x80, 0x80, "On"}, +}; + +STDDIPINFO(Jack2); + +static struct BurnDIPInfo Jack3DIPList[]= +{ + // Default Values + {0x11, 0xff, 0xff, 0x00, NULL}, + {0x12, 0xff, 0xff, 0x00, NULL}, + + // DSW1 + {0 , 0xfe, 0 , 4 , "Coin B"}, + {0x11, 0x01, 0x03, 0x00, "1 coin 1 credit"}, + {0x11, 0x01, 0x03, 0x01, "1 coin 2 credits"}, + {0x11, 0x01, 0x03, 0x02, "1 coin 3 credits"}, + {0x11, 0x01, 0x03, 0x03, "1 coin 5 credits"}, + + {0 , 0xfe, 0 , 4 , "Coin A"}, + {0x11, 0x01, 0x0c, 0x0c, "4 coins 1 credit"}, + {0x11, 0x01, 0x0c, 0x08, "3 coins 1 credit"}, + {0x11, 0x01, 0x0c, 0x04, "2 coins 1 credit"}, + {0x11, 0x01, 0x0c, 0x00, "1 coin 1 credit"}, + + {0 , 0xfe, 0 , 2 , "Lives"}, + {0x11, 0x01, 0x10, 0x00, "3"}, + {0x11, 0x01, 0x10, 0x10, "5"}, + + {0 , 0xfe, 0 , 2 , "Bonus Life"}, + {0x11, 0x01, 0x20, 0x00, "Every 10000"}, + {0x11, 0x01, 0x20, 0x20, "10000 ONly"}, + + {0 , 0xfe, 0 , 2 , "Difficulty"}, + {0x11, 0x01, 0x40, 0x00, "Start on Level 1"}, + {0x11, 0x01, 0x40, 0x40, "Start on Level 13"}, + + {0 , 0xfe, 0 , 2 , "Bullets per Bean Collected"}, + {0x11, 0x01, 0x80, 0x00, "1"}, + {0x11, 0x01, 0x80, 0x80, "2"}, + + // DSW2 + {0 , 0xfe, 0 , 2 , "Cabinet"}, + {0x12, 0x01, 0x01, 0x01, "Upright"}, + {0x12, 0x01, 0x01, 0x00, "Cocktail"}, + + {0 , 0xfe, 0 , 2 , "Invulnerability (Cheat)"}, + {0x12, 0x01, 0x40, 0x00, "Off"}, + {0x12, 0x01, 0x40, 0x40, "On"}, + + {0 , 0xfe, 0 , 4 , "255 Lives (Cheat)"}, + {0x12, 0x01, 0x80, 0x00, "Off"}, + {0x12, 0x01, 0x80, 0x80, "On"}, +}; + +STDDIPINFO(Jack3); + +static struct BurnDIPInfo TreahuntDIPList[]= +{ + // Default Values + {0x11, 0xff, 0xff, 0x00, NULL}, + {0x12, 0xff, 0xff, 0x00, NULL}, + + // DSW1 + {0 , 0xfe, 0 , 4 , "Coin B"}, + {0x11, 0x01, 0x03, 0x01, "2 coins 1 credit"}, + {0x11, 0x01, 0x03, 0x03, "4 coins 3 credits"}, + {0x11, 0x01, 0x03, 0x00, "1 coin 1 credit"}, + {0x11, 0x01, 0x03, 0x02, "1 coin 3 credits"}, + + {0 , 0xfe, 0 , 4 , "Coin A"}, + {0x11, 0x01, 0x0c, 0x08, "3 coins 1 credit"}, + {0x11, 0x01, 0x0c, 0x04, "2 coins 1 credit"}, + {0x11, 0x01, 0x0c, 0x0c, "4 coins 3 credits"}, + {0x11, 0x01, 0x0c, 0x00, "1 coin 1 credit"}, + + {0 , 0xfe, 0 , 2 , "Lives"}, + {0x11, 0x01, 0x10, 0x00, "3"}, + {0x11, 0x01, 0x10, 0x10, "5"}, + + {0 , 0xfe, 0 , 2 , "Bonus Life"}, + {0x11, 0x01, 0x20, 0x00, "Every 10000"}, + {0x11, 0x01, 0x20, 0x20, "10000 ONly"}, + + {0 , 0xfe, 0 , 2 , "Difficulty"}, + {0x11, 0x01, 0x40, 0x00, "Start on Level 1"}, + {0x11, 0x01, 0x40, 0x40, "Start on Level 6"}, + + {0 , 0xfe, 0 , 2 , "Bullets per Bean Collected"}, + {0x11, 0x01, 0x80, 0x00, "5"}, + {0x11, 0x01, 0x80, 0x80, "20"}, + + // DSW2 + {0 , 0xfe, 0 , 2 , "Cabinet"}, + {0x12, 0x01, 0x01, 0x01, "Upright"}, + {0x12, 0x01, 0x01, 0x00, "Cocktail"}, + + {0 , 0xfe, 0 , 2 , "Invulnerability (Cheat)"}, + {0x12, 0x01, 0x40, 0x00, "Off"}, + {0x12, 0x01, 0x40, 0x40, "On"}, + + {0 , 0xfe, 0 , 4 , "255 Lives (Cheat)"}, + {0x12, 0x01, 0x80, 0x00, "Off"}, + {0x12, 0x01, 0x80, 0x80, "On"}, +}; + +STDDIPINFO(Treahunt); + + +static struct BurnDIPInfo ZzyzzyxxDIPList[]= +{ + // Default Values + {0x0A, 0xff, 0xff, 0x00, NULL}, + {0x0B, 0xff, 0xff, 0x00, NULL}, + + // DSW1 + {0 , 0xfe, 0 , 4 , "Coinage"}, + {0x0A, 0x01, 0x03, 0x01, "2 coins 1 credit"}, + {0x0A, 0x01, 0x03, 0x03, "4 coins 3 credits"}, + {0x0A, 0x01, 0x03, 0x00, "1 coin 1 credit"}, + {0x0A, 0x01, 0x03, 0x02, "1 coin 3 credits"}, + + {0 , 0xfe, 0 , 2 , "Lives"}, + {0x0A, 0x01, 0x04, 0x00, "3"}, + {0x0A, 0x01, 0x04, 0x04, "2"}, + + {0 , 0xfe, 0 , 2 , "Credits on Reset"}, + {0x0A, 0x01, 0x08, 0x00, "Off"}, + {0x0A, 0x01, 0x08, 0x08, "On"}, + + {0 , 0xfe, 0 , 2 , "Demo Sounds"}, + {0x0A, 0x01, 0x10, 0x10, "Off"}, + {0x0A, 0x01, 0x10, 0x00, "On"}, + + {0 , 0xfe, 0 , 2 , "Cabinet"}, + {0x0A, 0x01, 0x20, 0x20, "Upright"}, + {0x0A, 0x01, 0x20, 0x00, "Cocktail"}, + + {0 , 0xfe, 0 , 2 , "Free Play"}, + {0x0A, 0x01, 0x80, 0x00, "Off"}, + {0x0A, 0x01, 0x80, 0x80, "On"}, + + // DSW2 + {0 , 0xfe, 0 , 2 , "Bonus Life"}, + {0x0B, 0x01, 0x03, 0x02, "None"}, + {0x0B, 0x01, 0x03, 0x00, "10000 50000"}, + {0x0B, 0x01, 0x03, 0x01, "25000 100000"}, + {0x0B, 0x01, 0x03, 0x03, "100000 300000"}, + + {0 , 0xfe, 0 , 2 , "2nd Bonus Given"}, + {0x0B, 0x01, 0x04, 0x00, "No"}, + {0x0B, 0x01, 0x04, 0x04, "Yes"}, + + {0 , 0xfe, 0 , 2 , "Starting Laps"}, + {0x0B, 0x01, 0x08, 0x00, "2"}, + {0x0B, 0x01, 0x08, 0x08, "3"}, + + {0 , 0xfe, 0 , 2 , "Difficulty of Pleasing Lola"}, + {0x0B, 0x01, 0x10, 0x00, "Easy"}, + {0x0B, 0x01, 0x10, 0x10, "Hard"}, + + {0 , 0xfe, 0 , 2 , "Show Intermissions"}, + {0x0B, 0x01, 0x20, 0x00, "No"}, + {0x0B, 0x01, 0x20, 0x20, "Yes"}, + + {0 , 0xfe, 0 , 3 , "Show Intermissions"}, + {0x0B, 0x01, 0xc0, 0x00, "3 under 4000 pts"}, + {0x0B, 0x01, 0xc0, 0x80, "5 under 4000 pts"}, + {0x0B, 0x01, 0xc0, 0x40, "None"}, +}; + +STDDIPINFO(Zzyzzyxx); + +static struct BurnDIPInfo FreezeDIPList[]= +{ + // Default Values + {0x08, 0xff, 0xff, 0x00, NULL}, + + // DSW1 + {0 , 0xfe, 0 , 2 , "Flip Screen"}, + {0x08, 0x01, 0x01, 0x00, "Off"}, + {0x08, 0x01, 0x01, 0x01, "On"}, + + {0 , 0xfe, 0 , 2 , "Difficulty"}, + {0x08, 0x01, 0x04, 0x00, "Easy"}, + {0x08, 0x01, 0x04, 0x04, "Hard"}, + + {0 , 0xfe, 0 , 2 , "Lives"}, + {0x08, 0x01, 0x08, 0x00, "3"}, + {0x08, 0x01, 0x08, 0x08, "5"}, + + {0 , 0xfe, 0 , 4 , "Bonus Life"}, + {0x08, 0x01, 0x30, 0x00, "10000"}, + {0x08, 0x01, 0x30, 0x10, "10000 40000"}, + {0x08, 0x01, 0x30, 0x20, "10000 60000"}, + {0x08, 0x01, 0x30, 0x30, "20000 100000"}, + + {0 , 0xfe, 0 , 4 , "Coinage"}, + {0x08, 0x01, 0xc0, 0x80, "2 Coins 1 Credit"}, + {0x08, 0x01, 0xc0, 0x00, "1 Coin 1 Credit"}, + {0x08, 0x01, 0xc0, 0x40, "1 Coin 2 Credits"}, + {0x08, 0x01, 0xc0, 0xc0, "Free Play"}, +}; + +STDDIPINFO(Freeze); + +static struct BurnDIPInfo SucasinoDIPList[]= +{ + // Default Values + {0x0A, 0xff, 0xff, 0x00, NULL}, + + // DSW1 + {0 , 0xfe, 0 , 4 , "Coinage"}, + {0x0A, 0x01, 0x03, 0x00, "1 Coin 1 Credit"}, + {0x0A, 0x01, 0x03, 0x01, "1 Coin 2 Credits"}, + {0x0A, 0x01, 0x03, 0x02, "1 Coin 3 Credits"}, + {0x0A, 0x01, 0x03, 0x03, "1 Coin 4 Credits"}, + + {0 , 0xfe, 0 , 2 , "Cabinet"}, + {0x0A, 0x01, 0x04, 0x00, "Upright"}, + {0x0A, 0x01, 0x04, 0x04, "Cocktail"}, + + {0 , 0xfe, 0 , 2 , "Flip Screen"}, + {0x0A, 0x01, 0x08, 0x00, "Off"}, + {0x0A, 0x01, 0x08, 0x08, "On"}, +}; + +STDDIPINFO(Sucasino); + +static struct BurnDIPInfo JoinemDIPList[]= +{ + // Default Values + {0x0d, 0xff, 0xff, 0x00, NULL}, + {0x0e, 0xff, 0xff, 0x00, NULL}, + + // DSW1 + {0 , 0xfe, 0 , 4 , "Coin A"}, + {0x0d, 0x01, 0x03, 0x01, "2 coins 1 credit"}, + {0x0d, 0x01, 0x03, 0x03, "4 coins 3 credits"}, + {0x0d, 0x01, 0x03, 0x00, "1 coin 1 credit"}, + {0x0d, 0x01, 0x03, 0x02, "1 coin 3 credits"}, + + {0 , 0xfe, 0 , 4 , "Coin B"}, + {0x0d, 0x01, 0x0c, 0x08, "3 coins 1 credit"}, + {0x0d, 0x01, 0x0c, 0x04, "2 coins 1 credit"}, + {0x0d, 0x01, 0x0c, 0x0c, "4 coins 3 credits"}, + {0x0d, 0x01, 0x0c, 0x00, "1 coin 1 credit"}, + + {0 , 0xfe, 0 , 2 , "Lives"}, + {0x0d, 0x01, 0x10, 0x00, "2"}, + {0x0d, 0x01, 0x10, 0x10, "5"}, + + // DSW2 + {0 , 0xfe, 0 , 2 , "Cabinet"}, + {0x0e, 0x01, 0x01, 0x01, "Upright"}, + {0x0e, 0x01, 0x01, 0x00, "Cocktail"}, + + {0 , 0xfe, 0 , 2 , "Sound Check"}, + {0x0e, 0x01, 0x20, 0x00, "Off"}, + {0x0e, 0x01, 0x20, 0x20, "On"}, + + {0 , 0xfe, 0 , 2 , "Infinite Lives"}, + {0x0e, 0x01, 0x80, 0x00, "2"}, + {0x0e, 0x01, 0x80, 0x80, "3"}, +}; + +STDDIPINFO(Joinem); + +static struct BurnDIPInfo LoverboyDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x00, NULL}, + + // DSW1 + {0 , 0xfe, 0 , 15 , "Coin A"}, + {0x0f, 0x01, 0x0f, 0x0c, "4 Coins 1 Credit"}, + {0x0f, 0x01, 0x0f, 0x08, "3 Coins 1 Credit"}, + {0x0f, 0x01, 0x0f, 0x0d, "4 Coins 2 Credit"}, + {0x0f, 0x01, 0x0f, 0x04, "2 Coins 1 Credit"}, + {0x0f, 0x01, 0x0f, 0x09, "3 Coins 2 Credit"}, + {0x0f, 0x01, 0x0f, 0x0e, "4 Coins 3 Credit"}, + {0x0f, 0x01, 0x0f, 0x0f, "4 Coins 4 Credit"}, + {0x0f, 0x01, 0x0f, 0x0a, "3 Coins 3 Credit"}, + {0x0f, 0x01, 0x0f, 0x05, "2 Coins 2 Credit"}, + {0x0f, 0x01, 0x0f, 0x00, "1 Coins 1 Credit"}, + {0x0f, 0x01, 0x0f, 0x0b, "3 Coins 4 Credit"}, + {0x0f, 0x01, 0x0f, 0x06, "2 Coins 3 Credit"}, + {0x0f, 0x01, 0x0f, 0x07, "2 Coins 4 Credit"}, + {0x0f, 0x01, 0x0f, 0x01, "1 Coins 2 Credit"}, + {0x0f, 0x01, 0x0f, 0x02, "1 Coins 3 Credit"}, + {0x0f, 0x01, 0x0f, 0x03, "1 Coins 4 Credit"}, + + {0 , 0xfe, 0 , 2 , "Bonus"}, + {0x0f, 0x01, 0x20, 0x00, "20,000"}, + {0x0f, 0x01, 0x20, 0x20, "30,000"}, + + {0 , 0xfe, 0 , 2 , "Lives"}, + {0x0f, 0x01, 0x40, 0x00, "3"}, + {0x0f, 0x01, 0x40, 0x40, "5"}, + + {0 , 0xfe, 0 , 2 , "Cabinet"}, + {0x0f, 0x01, 0x80, 0x80, "Upright"}, + {0x0f, 0x01, 0x80, 0x00, "Cocktail"}, +}; + +STDDIPINFO(Loverboy); + +static struct BurnDIPInfo StrivDIPList[]= +{ + // Default Values + {0x0A, 0xff, 0xff, 0x80, NULL}, + + // DSW1 + {0 , 0xfe, 0 , 2 , "Monitor"}, + {0x0A, 0x01, 0x02, 0x02, "Horizontal"}, + {0x0A, 0x01, 0x02, 0x00, "Vertical"}, + + {0 , 0xfe, 0 , 8 , "Gaming Option Number"}, + {0x0A, 0x01, 0x05, 0x01, "2"}, + {0x0A, 0x01, 0x05, 0x05, "3"}, + {0x0A, 0x01, 0x05, 0x00, "4"}, + {0x0A, 0x01, 0x05, 0x04, "5"}, + {0x0A, 0x01, 0x05, 0x01, "4"}, + {0x0A, 0x01, 0x05, 0x05, "5"}, + {0x0A, 0x01, 0x05, 0x00, "6"}, + {0x0A, 0x01, 0x05, 0x04, "7"}, + + {0 , 0xfe, 0 , 2 , "Cabinet"}, + {0x0A, 0x01, 0x08, 0x08, "Upright"}, + {0x0A, 0x01, 0x08, 0x00, "Cocktail"}, + + {0 , 0xfe, 0 , 2 , "Coinage"}, + {0x0A, 0x01, 0x10, 0x00, "2 Coins 1 Credit"}, + {0x0A, 0x01, 0x10, 0x10, "1 Coin 1 Credit"}, + + {0 , 0xfe, 0 , 2 , "Gaming Options"}, + {0x0A, 0x01, 0x20, 0x20, "Number of Wrong Answer"}, + {0x0A, 0x01, 0x20, 0x00, "Number of Questions"}, + + {0 , 0xfe, 0 , 2 , "Show Correct Answer"}, + {0x0A, 0x01, 0x40, 0x00, "No"}, + {0x0A, 0x01, 0x40, 0x40, "Yes"}, +}; + +STDDIPINFO(Striv); + +static unsigned char timer_r(unsigned int) +{ + return ZetTotalCycles() / timer_rate; +} + +static unsigned char soundlatch_r(unsigned int) +{ + return soundlatch; +} + +static unsigned char __fastcall striv_question_r(unsigned short offset) +{ + if((offset & 0xc00) == 0x800) + { + remap_address[offset & 0x0f] = (offset & 0xf0) >> 4; + } + else if((offset & 0xc00) == 0xc00) + { + question_rom = offset & 7; + question_address = (offset & 0xf8) << 7; + } + else + { + unsigned char *ROM = User; + int real_address; + + real_address = question_address | (offset & 0x3f0) | remap_address[offset & 0x0f]; + + if(offset & 0x400) + real_address |= 0x8000 * (question_rom + 8); + else + real_address |= 0x8000 * question_rom; + + return ROM[real_address]; + } + + return 0; +} + +void jack_paletteram_w(unsigned short offset, unsigned char data) +{ + unsigned int *pl = Palette + (offset & 0x1f); + + Rom0[offset] = data; + + DrvCalcPal = 1; + + data ^= 0xff; + + *pl = ((data & 7) << 21) | ((data & 7) << 18) | ((data & 6) << 15); + + data >>= 3; + + *pl |= ((data & 7) << 13) | ((data & 7) << 10) | ((data & 6) << 7); + + data >>= 3; + + *pl |= ((data & 3) << 6) | ((data & 3) << 4) | ((data & 3) << 2) | (data & 3); +} + +unsigned char __fastcall jack_cpu0_read(unsigned short address) +{ + unsigned char ret = 0; + + switch (address) + { + case 0xb500: + return DrvDips[0]; + + case 0xb501: + { + ret = DrvDips[1]; + if (joinem && DrvJoy2[7] && !joinem_snd_bit) ret |= 0x20; + + return ret; + } + + case 0xb502: + { + for (int i = 0; i < 8; i++) ret |= DrvJoy1[i] << i; + + return ret; + } + + case 0xb503: + { + for (int i = 0; i < 8; i++) ret |= DrvJoy2[i] << i; + + return ret; + } + + case 0xb504: + { + for (int i = 0; i < 8; i++) ret |= DrvJoy3[i] << i; + if (joinem || loverb) ret |= 0x40; + + return ret; + } + + case 0xb505: + { + for (int i = 0; i < 8; i++) ret |= DrvJoy4[i] << i; + + return ret; + } + + case 0xb506: + case 0xb507: + flip_screen = (address & 1) ^ suprtriv; + return 0; + } + + if (suprtriv && address >= 0xc000 && address <= 0xcfff) { + return striv_question_r(address & 0x0fff); + } + + return 0; +} + +void __fastcall jack_cpu0_write(unsigned short address, unsigned char data) +{ + if (address >= 0xb600 && address <= 0xb61f) + { + jack_paletteram_w(address, data); + return; + } + + switch (address) + { + case 0xb400: + soundlatch = data; + snd_cpu_irq = 1; + break; + + case 0xb506: + flip_screen = 1; + break; + + case 0xb700: + flip_screen = data >> 7; + joinem_snd_bit = data & 1; + break; + } +} + +unsigned char __fastcall jack_in_port(unsigned short port) +{ + switch (port & 0xff) + { + case 0x40: + return AY8910Read(0); + } + + return 0; +} + +void __fastcall jack_out_port(unsigned short address, unsigned char data) +{ + switch (address & 0xff) + { + case 0x40: + AY8910Write(0, 1, data); + break; + + case 0x80: + AY8910Write(0, 0, data); + break; + } +} + +void __fastcall jack_cpu1_write() +{ +} + + +static int DrvDoReset() +{ + flip_screen = 0; + DrvReset = 0; + soundlatch = 0; + + if (loverb || joinem) { + memset (Rom0 + 0x8000, 0, 0x1000); + } else { + memset ((unsigned char*)Palette, 0, 0x400); + memset (Rom0 + 0x4000, 0, 0x1000); + } + + memset (Rom0 + 0xb000, 0, 0x1000); + memset (Rom1 + 0x4000, 0, 0x0400); + memset ((unsigned char*)remap_address, 0, 0x40); + + question_address = question_rom = 0; + joinem_snd_bit = 0; + soundlatch = 0; + + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + } + + AY8910Reset(0); + + return 0; +} + +static int GetRoms() +{ + char* pRomName; + struct BurnRomInfo ri; + unsigned char *Load0 = Rom0; + unsigned char *Load1 = Rom1; + unsigned char *Loadg = Gfx; + unsigned char *Loadt = User; + int gCount = 0; + + if (!joinem && !loverb) Loadg += 0x2000; + + for (int i = 0; !BurnDrvGetRomName(&pRomName, i, 0); i++) { + + BurnDrvGetRomInfo(&ri, i); + + if ((ri.nType & 7) == 1) { + if (ri.nLen == 0x2000) + { + if (BurnLoadRom(Load0, i, 1)) return 1; + Load0 += ri.nLen; + } + else + { + if (BurnLoadRom(Load0, i, 1)) return 1; + Load0 += ri.nLen; + + if (tri_fix && i == 0) { + Load0 += 0x1000; + } + + if (i == (3 - tri_fix)) Load0 += 0x8000; + } + + continue; + } + + if ((ri.nType & 7) == 2) { + if (BurnLoadRom(Load1, i, 1)) return 1; + Load1 += ri.nLen; + + continue; + } + + if ((ri.nType & 7) == 3) { + if (BurnLoadRom(Loadg, i, 1)) return 1; + Loadg += ri.nLen; + if (joinem) Loadg += 0x1000; + gCount++; + + continue; + } + + if ((ri.nType & 7) == 4) { + if (BurnLoadRom(Prom + 0x000, i + 0, 1)) return 1; + if (BurnLoadRom(Prom + 0x200, i + 1, 1)) return 1; + i++; + + // Roms are nibbles, (1/2 byte), #0 is low, #1 is high + for (int j = 0; j < 0x200; j++) { + Prom[j] = Prom[j] | (Prom[j + 0x200] << 4); + } + + continue; + } + + if ((ri.nType & 7) == 5) { + if (BurnLoadRom(Loadt, i, 1)) return 1; + Loadt += ri.nLen; + + continue; + } + } + + // sucasino, tripool, tripoola + if (gCount == 2) { + memcpy (Gfx + 0x4000, Gfx + 0x3000, 0x1000); + memset (Gfx + 0x3000, 0, 0x1000); + } + + return 0; +} + +static void gfx_decode() +{ + unsigned char* tmp = (unsigned char*)malloc( 0x2000 * 3 ); + if (!tmp) return; + + memcpy (tmp, Gfx, 0x6000); + + static int Planes[3] = { 0, 1024*8*8, 1024*8*8*2 }; + static int YOffs[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + static int XOffs[8] = { 56, 48, 40, 32, 24, 16, 8, 0 }; + + GfxDecode(1024, 3, 8, 8, Planes, XOffs, YOffs, 64, tmp, Gfx); + + free (tmp); +} + +static int DrvInit() +{ + Mem = (unsigned char *)malloc (0x100000); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short *)malloc (nBurnSoundLen * 3 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + Rom0 = Mem + 0x00000; + Rom1 = Mem + 0x10000; + Gfx = Mem + 0x20000; + User = Mem + 0x30000; + Prom = Mem + 0xb0000; + Palette = (unsigned int*)(Mem + 0xc0000); + DrvPal = (unsigned int*)(Mem + 0xc1000); + + GetRoms(); + + gfx_decode(); + + ZetInit(2); + ZetOpen(0); + ZetSetReadHandler(jack_cpu0_read); + ZetSetWriteHandler(jack_cpu0_write); + + if (joinem || loverb) + { + ZetMapArea(0x0000, 0x8fff, 0, Rom0 + 0x0000); + ZetMapArea(0x0000, 0x8fff, 2, Rom0 + 0x0000); + + ZetMapArea(0x8000, 0x8fff, 1, Rom0 + 0x8000); + + ZetMapArea(0xb500, 0xb5ff, 0, Rom0 + 0xb500); // controls hack + } else { + ZetMapArea(0x0000, 0x3fff, 0, Rom0 + 0x0000); + ZetMapArea(0x0000, 0x3fff, 2, Rom0 + 0x0000); + + ZetMapArea(0x4000, 0x5fff, 0, Rom0 + 0x4000); + ZetMapArea(0x4000, 0x5fff, 1, Rom0 + 0x4000); + ZetMapArea(0x4000, 0x5fff, 2, Rom0 + 0x4000); + } + + ZetMapArea(0xb000, 0xb0ff, 0, Rom0 + 0xb000); + ZetMapArea(0xb000, 0xb0ff, 1, Rom0 + 0xb000); + + ZetMapArea(0xb800, 0xbbff, 0, Rom0 + 0xb800); + ZetMapArea(0xb800, 0xbbff, 1, Rom0 + 0xb800); + + ZetMapArea(0xbc00, 0xbfff, 0, Rom0 + 0xbc00); + ZetMapArea(0xbc00, 0xbfff, 1, Rom0 + 0xbc00); + + if (suprtriv) + { + ZetMapArea(0xd000, 0xffff, 0, Rom0 + 0xc000); + ZetMapArea(0xd000, 0xffff, 2, Rom0 + 0xc000); + } else { + ZetMapArea(0xc000, 0xffff, 0, Rom0 + 0xc000); + ZetMapArea(0xc000, 0xffff, 2, Rom0 + 0xc000); + } + + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetSetInHandler(jack_in_port); + ZetSetOutHandler(jack_out_port); + ZetMapArea(0x0000, 0x1fff, 0, Rom1 + 0x0000); + ZetMapArea(0x0000, 0x1fff, 2, Rom1 + 0x0000); + ZetMapArea(0x4000, 0x43ff, 0, Rom1 + 0x4000); + ZetMapArea(0x4000, 0x43ff, 1, Rom1 + 0x4000); + ZetMapArea(0x4000, 0x43ff, 2, Rom1 + 0x4000); + ZetMemEnd(); + ZetClose(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + AY8910Init(0, 1500000, nBurnSoundRate, &soundlatch_r, &timer_r, NULL, NULL); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + AY8910Exit(0); + GenericTilesExit(); + + free (pFMBuffer); + free (Mem); + + DrvPal = Palette = NULL; + pFMBuffer = NULL; + Mem = Rom0 = Rom1 = Gfx = User = NULL; + pAY8910Buffer[0] = pAY8910Buffer[1] = pAY8910Buffer[2] = NULL; + + tri_fix = 0; + joinem = 0; + loverb = 0; + suprtriv = 0; + + return 0; +} + + +static int DrvDraw() +{ + if (DrvCalcPal) + { + for (int i = 0; i < 0x100; i++) { + unsigned int col = Palette[i]; + DrvPal[i] = BurnHighCol(col >> 16, col >> 8, col, 0); + } + DrvCalcPal = 0; + } + + unsigned char *sram = Rom0 + 0xb000; // sprite ram + unsigned char *vram = Rom0 + 0xb800; // video ram + unsigned char *cram = Rom0 + 0xbc00; // color ram + int offs, sx, sy, num, color, flipx, flipy; + + for (offs = 0; offs < 0x400; offs++) + { + sx = (offs & 0x1f) << 3; + sy = (offs >> 2) & 0xf8; + + if (joinem || loverb) { + num = vram[offs] + ((cram[offs] & 0x03) << 8); + color = (cram[offs] & 0x38) >> 2; + } else { + num = vram[offs] + ((cram[offs] & 0x18) << 5); + color = (cram[offs] & 0x07); + } + + if (flip_screen) { + Render8x8Tile_FlipXY_Clip(pTransDraw, num, sx ^ 0xf8, sy ^ 0xf8, color, 2, 0, Gfx); + } else { + sx -= 16; + Render8x8Tile_Clip(pTransDraw, num, sx, sy, color, 2, 0, Gfx); + } + } + + for (offs = 0; offs < 0x80; offs += 4) + { + sx = 248 - sram[offs]; + sy = sram[offs + 1]; + + if (joinem || loverb) { + num = sram[offs + 2] + ((sram[offs + 3] & 0x01) << 8); + color = (sram[offs + 3] & 0x38) >> 2; + } else { + num = sram[offs + 2] + ((sram[offs + 3] & 0x08) << 5); + color = (sram[offs + 3] & 0x07); + } + + flipx = sram[offs + 3] & 0x40; + flipy = sram[offs + 3] & 0x80; + + if (flip_screen) { + flipx = !flipx; + flipy = !flipy; + sx = 248 - sx; + sy = 248 - sy; + } + + sx -= 16; + + if (flipy) { + if (flipx) { + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, num, sx, sy, color, 2, 0, 0, Gfx); + } else { + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, num, sx, sy, color, 2, 0, 0, Gfx); + } + } else { + if (flipx) { + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, num, sx, sy, color, 2, 0, 0, Gfx); + } else { + Render8x8Tile_Mask_Clip(pTransDraw, num, sx, sy, color, 2, 0, 0, Gfx); + } + } + } + + BurnTransferCopy(DrvPal); + + return 0; +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + if (joinem || loverb) { + for (int i = 0; i < 6; i++) + Rom0[0xb500 + i] = jack_cpu0_read(0xb500 + i); + } + + int nInterleave = 10; + int nSoundBufferPos = 0; + + int nCyclesSegment; + int nCyclesDone[2], nCyclesTotal[2]; + + nCyclesTotal[0] = 3000000 / 60; + nCyclesTotal[1] = 1500000 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run Z80 #0 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + + if (joinem) + if (i == (nInterleave / 3) || i == ((nInterleave / 3) * 2)) + ZetRaiseIrq(0); + + if (tri_fix && i == (nInterleave / 2)) ZetRaiseIrq(0); + + if (i == (nInterleave - 1)) + { + if (joinem) { // joinem + if (!DrvJoy3[7]) ZetNmi(); + } else if (loverb) { // loverboy + ZetNmi(); + } else { // other + ZetRaiseIrq(0); + } + } + + ZetClose(); + + // Run Z80 #1 + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + if (snd_cpu_irq) { + ZetRaiseIrq(0xff); + snd_cpu_irq = 0; + } + nCyclesSegment = ZetRun(nCyclesSegment); + nCyclesDone[nCurrentCPU] += nCyclesSegment; + ZetClose(); + + // Render Sound Segment + if (pBurnSoundOut && !suprtriv) { // disable sound for suprtriv + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + nSoundBufferPos += nSegmentLength; + } + } + + // Make sure the buffer is entirely filled. + if (pBurnSoundOut && !suprtriv) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +//------------------------------------------------------------------------------------- +// Save states + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + if (joinem || loverb) { + ba.Data = Rom0 + 0x8000; + } else { + ba.Data = Rom0 + 0x4000; + } + ba.nLen = 0x01000; + ba.szName = "Main Ram"; + BurnAcb(&ba); + + memset(&ba, 0, sizeof(ba)); + ba.Data = Rom0 + 0xb000; + ba.nLen = 0x01000; + ba.szName = "Video Ram"; + BurnAcb(&ba); + + memset(&ba, 0, sizeof(ba)); + ba.Data = (unsigned char*)Palette; + ba.nLen = 0x00400; + ba.szName = "Palette"; + BurnAcb(&ba); + + memset(&ba, 0, sizeof(ba)); + ba.Data = (unsigned char*)remap_address; + ba.nLen = 0x00040; + ba.szName = "striv question addresses"; + BurnAcb(&ba); + + ZetScan(nAction); + AY8910Scan(nAction, pnMin); + + // Scan critical driver variables + SCAN_VAR(question_address); + SCAN_VAR(question_rom); + SCAN_VAR(soundlatch); + SCAN_VAR(joinem_snd_bit); + } + + return 0; +} + + +// Jack the Giantkiller (set 1) + +static struct BurnRomInfo jackRomDesc[] = { + { "j8", 0x1000, 0xc8e73998, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "jgk.j6", 0x1000, 0x36d7810e, 1 | BRF_PRG | BRF_ESS }, // 1 + { "jgk.j7", 0x1000, 0xb15ff3ee, 1 | BRF_PRG | BRF_ESS }, // 2 + { "jgk.j5", 0x1000, 0x4a63d242, 1 | BRF_PRG | BRF_ESS }, // 3 + { "jgk.j3", 0x1000, 0x605514a8, 1 | BRF_PRG | BRF_ESS }, // 4 + { "jgk.j4", 0x1000, 0xbce489b7, 1 | BRF_PRG | BRF_ESS }, // 5 + { "jgk.j2", 0x1000, 0xdb21bd55, 1 | BRF_PRG | BRF_ESS }, // 6 + { "jgk.j1", 0x1000, 0x49fffe31, 1 | BRF_PRG | BRF_ESS }, // 7 + + { "jgk.j9", 0x1000, 0xc2dc1e00, 2 | BRF_PRG | BRF_ESS }, // 8 Z80 #1 Code + + { "jgk.j12", 0x1000, 0xce726df0, 3 | BRF_GRA }, // 9 Graphics + { "jgk.j13", 0x1000, 0x6aec2c8d, 3 | BRF_GRA }, // 10 + { "jgk.j11", 0x1000, 0xfd14c525, 3 | BRF_GRA }, // 11 + { "jgk.j10", 0x1000, 0xeab890b2, 3 | BRF_GRA }, // 12 +}; + +STD_ROM_PICK(jack); +STD_ROM_FN(jack); + +static int jackInit() +{ + timer_rate = 128; + + return DrvInit(); +} + +struct BurnDriver BurnDrvjack = { + "jack", NULL, NULL, "1982", + "Jack the Giantkiller (set 1)\0", NULL, "Cinematronics", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, jackRomInfo, jackRomName, JackInputInfo, JackDIPInfo, + jackInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Jack the Giantkiller (set 2) + +static struct BurnRomInfo jack2RomDesc[] = { + { "jgk.j8", 0x1000, 0xfe229e20, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "jgk.j6", 0x1000, 0x36d7810e, 1 | BRF_PRG | BRF_ESS }, // 1 + { "jgk.j7", 0x1000, 0xb15ff3ee, 1 | BRF_PRG | BRF_ESS }, // 2 + { "jgk.j5", 0x1000, 0x4a63d242, 1 | BRF_PRG | BRF_ESS }, // 3 + { "jgk.j3", 0x1000, 0x605514a8, 1 | BRF_PRG | BRF_ESS }, // 4 + { "jgk.j4", 0x1000, 0xbce489b7, 1 | BRF_PRG | BRF_ESS }, // 5 + { "jgk.j2", 0x1000, 0xdb21bd55, 1 | BRF_PRG | BRF_ESS }, // 6 + { "jgk.j1", 0x1000, 0x49fffe31, 1 | BRF_PRG | BRF_ESS }, // 7 + + { "jgk.j9", 0x1000, 0xc2dc1e00, 2 | BRF_PRG | BRF_ESS }, // 8 Z80 #1 Code + + { "jgk.j12", 0x1000, 0xce726df0, 3 | BRF_GRA }, // 9 Graphics + { "jgk.j13", 0x1000, 0x6aec2c8d, 3 | BRF_GRA }, // 10 + { "jgk.j11", 0x1000, 0xfd14c525, 3 | BRF_GRA }, // 11 + { "jgk.j10", 0x1000, 0xeab890b2, 3 | BRF_GRA }, // 12 +}; + +STD_ROM_PICK(jack2); +STD_ROM_FN(jack2); + +struct BurnDriver BurnDrvjack2 = { + "jack2", "jack", NULL, "1982", + "Jack the Giantkiller (set 2)\0", NULL, "Cinematronics", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, jack2RomInfo, jack2RomName, JackInputInfo, Jack2DIPInfo, + jackInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Jack the Giantkiller (set 3) + +static struct BurnRomInfo jack3RomDesc[] = { + { "jack8", 0x1000, 0x632151d2, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "jack6", 0x1000, 0xf94f80d9, 1 | BRF_PRG | BRF_ESS }, // 1 + { "jack7", 0x1000, 0xc830ff1e, 1 | BRF_PRG | BRF_ESS }, // 2 + { "jack5", 0x1000, 0x8dea17e7, 1 | BRF_PRG | BRF_ESS }, // 3 + { "jgk.j3", 0x1000, 0x605514a8, 1 | BRF_PRG | BRF_ESS }, // 4 // bank 2 + { "jgk.j4", 0x1000, 0xbce489b7, 1 | BRF_PRG | BRF_ESS }, // 5 + { "jgk.j2", 0x1000, 0xdb21bd55, 1 | BRF_PRG | BRF_ESS }, // 6 + { "jack1", 0x1000, 0x7e75ea3d, 1 | BRF_PRG | BRF_ESS }, // 7 + + { "jgk.j9", 0x1000, 0xc2dc1e00, 2 | BRF_PRG | BRF_ESS }, // 8 Z80 #1 Code + + { "jack12", 0x1000, 0x80320647, 3 | BRF_GRA }, // 9 Graphics + { "jgk.j13", 0x1000, 0x6aec2c8d, 3 | BRF_GRA }, // 10 + { "jgk.j11", 0x1000, 0xfd14c525, 3 | BRF_GRA }, // 11 + { "jgk.j10", 0x1000, 0xeab890b2, 3 | BRF_GRA }, // 12 +}; + +STD_ROM_PICK(jack3); +STD_ROM_FN(jack3); + +struct BurnDriver BurnDrvjack3 = { + "jack3", "jack", NULL, "1982", + "Jack the Giantkiller (set 3)\0", NULL, "Cinematronics", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, jack3RomInfo, jack3RomName, JackInputInfo, Jack3DIPInfo, + jackInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Treasure Hunt (bootleg?) + +static struct BurnRomInfo treahuntRomDesc[] = { + { "thunt-1.f2", 0x1000, 0x0b35858c, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "thunt-2.f3", 0x1000, 0x67305a51, 1 | BRF_PRG | BRF_ESS }, // 1 + { "thunt-3.4f", 0x1000, 0xd7a969c3, 1 | BRF_PRG | BRF_ESS }, // 2 + { "thunt-4.6f", 0x1000, 0x2483f14d, 1 | BRF_PRG | BRF_ESS }, // 3 + { "thunt-5.7f", 0x1000, 0xc69d5e21, 1 | BRF_PRG | BRF_ESS }, // 4 + { "thunt-6.7e", 0x1000, 0x11bf3d49, 1 | BRF_PRG | BRF_ESS }, // 5 + { "thunt-7.6e", 0x1000, 0x7c2d6279, 1 | BRF_PRG | BRF_ESS }, // 6 + { "thunt-8.4e", 0x1000, 0xf73b86fb, 1 | BRF_PRG | BRF_ESS }, // 7 + + { "jgk.j9", 0x1000, 0xc2dc1e00, 2 | BRF_PRG | BRF_ESS }, // 8 Z80 #1 Code + + { "thunt-13.a4", 0x1000, 0xe03f1f09, 3 | BRF_GRA }, // 9 Graphics + { "thunt-12.a3", 0x1000, 0xda4ee9eb, 3 | BRF_GRA }, // 10 + { "thunt-10.a1", 0x1000, 0x51ec7934, 3 | BRF_GRA }, // 11 + { "thunt-11.a2", 0x1000, 0xf9781143, 3 | BRF_GRA }, // 12 +}; + +STD_ROM_PICK(treahunt); +STD_ROM_FN(treahunt); + +static void treahunt_decode() +{ + for (int i = 0; i < 0x4000; i++) + { + if (i & 0x1000) + { + User[i] = BITSWAP08(Rom0[i], 0, 2, 5, 1, 3, 6, 4, 7); + + if (~i & 0x04) User[i] ^= 0x81; + } + else + { + User[i] = BITSWAP08(Rom0[i], 7, 2, 5, 1, 3, 6, 4, 0) ^ 0x81; + } + } + + ZetOpen(0); + ZetMapArea(0x0000, 0x3fff, 2, User, Rom0); + ZetClose(); +} + +static int treahuntInit() +{ + timer_rate = 128; + + int nRet = DrvInit(); + + treahunt_decode(); + + return nRet; +} + +struct BurnDriver BurnDrvtreahunt = { + "treahunt", "jack", NULL, "1982", + "Treasure Hunt (bootleg?)\0", NULL, "Hara Industries", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, treahuntRomInfo, treahuntRomName, JackInputInfo, TreahuntDIPInfo, + treahuntInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Zzyzzyxx (set 1) + +static struct BurnRomInfo zzyzzyxxRomDesc[] = { + { "a.2f", 0x1000, 0xa9102e34, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "zzyzzyxx.b", 0x1000, 0xefa9d4c6, 1 | BRF_PRG | BRF_ESS }, // 1 + { "zzyzzyxx.c", 0x1000, 0xb0a365b1, 1 | BRF_PRG | BRF_ESS }, // 2 + { "zzyzzyxx.d", 0x1000, 0x5ed6dd9a, 1 | BRF_PRG | BRF_ESS }, // 3 + { "zzyzzyxx.e", 0x1000, 0x5966fdbf, 1 | BRF_PRG | BRF_ESS }, // 4 + { "f.7e", 0x1000, 0x12f24c68, 1 | BRF_PRG | BRF_ESS }, // 5 + { "g.6e", 0x1000, 0x408f2326, 1 | BRF_PRG | BRF_ESS }, // 6 + { "h.4e", 0x1000, 0xf8bbabe0, 1 | BRF_PRG | BRF_ESS }, // 7 + + { "i.5a", 0x1000, 0xc7742460, 2 | BRF_PRG | BRF_ESS }, // 8 Z80 #1 Code + { "j.6a", 0x1000, 0x72166ccd, 2 | BRF_PRG | BRF_ESS }, // 9 + + { "n.1c", 0x1000, 0x4f64538d, 3 | BRF_GRA }, // 10 Graphics + { "m.1d", 0x1000, 0x217b1402, 3 | BRF_GRA }, // 11 + { "k.1b", 0x1000, 0xb8b2b8cc, 3 | BRF_GRA }, // 12 + { "l.1a", 0x1000, 0xab421a83, 3 | BRF_GRA }, // 13 +}; + +STD_ROM_PICK(zzyzzyxx); +STD_ROM_FN(zzyzzyxx); + +static int zzyzzyxxInit() +{ + timer_rate = 1; + + return DrvInit(); +} + +struct BurnDriver BurnDrvzzyzzyxx = { + "zzyzzyxx", NULL, NULL, "1982", + "Zzyzzyxx (set 1)\0", NULL, "Cinematronics + Advanced Microcomputer Systems", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, zzyzzyxxRomInfo, zzyzzyxxRomName, ZzyzzyxxInputInfo, ZzyzzyxxDIPInfo, + zzyzzyxxInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Zzyzzyxx (set 2) + +static struct BurnRomInfo zzyzzyx2RomDesc[] = { + { "a.2f", 0x1000, 0xa9102e34, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "b.3f", 0x1000, 0x4277beab, 1 | BRF_PRG | BRF_ESS }, // 1 + { "c.4f", 0x1000, 0x72ac99e1, 1 | BRF_PRG | BRF_ESS }, // 2 + { "d.6f", 0x1000, 0x7c7eec2b, 1 | BRF_PRG | BRF_ESS }, // 3 + { "e.7f", 0x1000, 0xcffc4a68, 1 | BRF_PRG | BRF_ESS }, // 4 + { "f.7e", 0x1000, 0x12f24c68, 1 | BRF_PRG | BRF_ESS }, // 5 + { "g.6e", 0x1000, 0x408f2326, 1 | BRF_PRG | BRF_ESS }, // 6 + { "h.4e", 0x1000, 0xf8bbabe0, 1 | BRF_PRG | BRF_ESS }, // 7 + + { "i.5a", 0x1000, 0xc7742460, 2 | BRF_PRG | BRF_ESS }, // 8 Z80 #1 Code + { "j.6a", 0x1000, 0x72166ccd, 2 | BRF_PRG | BRF_ESS }, // 9 + + { "n.1c", 0x1000, 0x4f64538d, 3 | BRF_GRA }, // 10 Graphics + { "m.1d", 0x1000, 0x217b1402, 3 | BRF_GRA }, // 11 + { "k.1b", 0x1000, 0xb8b2b8cc, 3 | BRF_GRA }, // 12 + { "l.1a", 0x1000, 0xab421a83, 3 | BRF_GRA }, // 13 +}; + +STD_ROM_PICK(zzyzzyx2); +STD_ROM_FN(zzyzzyx2); + +struct BurnDriver BurnDrvzzyzzyx2 = { + "zzyzzyx2", "zzyzzyxx", NULL, "1982", + "Zzyzzyxx (set 2)\0", NULL, "Cinematronics + Advanced Microcomputer Systems", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, zzyzzyx2RomInfo, zzyzzyx2RomName, ZzyzzyxxInputInfo, ZzyzzyxxDIPInfo, + zzyzzyxxInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Brix + +static struct BurnRomInfo brixRomDesc[] = { + { "a", 0x1000, 0x050e0d70, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "b", 0x1000, 0x668118ae, 1 | BRF_PRG | BRF_ESS }, // 1 + { "c", 0x1000, 0xff5ed6cf, 1 | BRF_PRG | BRF_ESS }, // 2 + { "d", 0x1000, 0xc3ae45a9, 1 | BRF_PRG | BRF_ESS }, // 3 + { "e", 0x1000, 0xdef99fa9, 1 | BRF_PRG | BRF_ESS }, // 4 + { "f", 0x1000, 0xdde717ed, 1 | BRF_PRG | BRF_ESS }, // 5 + { "g", 0x1000, 0xadca02d8, 1 | BRF_PRG | BRF_ESS }, // 6 + { "h", 0x1000, 0xbc3b878c, 1 | BRF_PRG | BRF_ESS }, // 7 + + { "i.5a", 0x1000, 0xc7742460, 2 | BRF_PRG | BRF_ESS }, // 8 Z80 #1 Code + { "j.6a", 0x1000, 0x72166ccd, 2 | BRF_PRG | BRF_ESS }, // 9 + + { "n", 0x1000, 0x8064910e, 3 | BRF_GRA }, // 10 Graphics + { "m.1d", 0x1000, 0x217b1402, 3 | BRF_GRA }, // 11 + { "k", 0x1000, 0xc7d7e2a0, 3 | BRF_GRA }, // 12 + { "l.1a", 0x1000, 0xab421a83, 3 | BRF_GRA }, // 13 +}; + +STD_ROM_PICK(brix); +STD_ROM_FN(brix); + +struct BurnDriver BurnDrvbrix = { + "brix", "zzyzzyxx", NULL, "1982", + "Brix\0", NULL, "Cinematronics + Advanced Microcomputer Systems", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, brixRomInfo, brixRomName, ZzyzzyxxInputInfo, ZzyzzyxxDIPInfo, + zzyzzyxxInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Freeze + +static struct BurnRomInfo freezeRomDesc[] = { + { "freeze.f2", 0x1000, 0x0a431665, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "freeze.f3", 0x1000, 0x1189b8ad, 1 | BRF_PRG | BRF_ESS }, // 1 + { "freeze.f4", 0x1000, 0x10c4a5ea, 1 | BRF_PRG | BRF_ESS }, // 2 + { "freeze.f5", 0x1000, 0x16024c53, 1 | BRF_PRG | BRF_ESS }, // 3 + { "freeze.f7", 0x1000, 0xea0b0765, 1 | BRF_PRG | BRF_ESS }, // 4 + { "freeze.e7", 0x1000, 0x1155c00b, 1 | BRF_PRG | BRF_ESS }, // 5 + { "freeze.e5", 0x1000, 0x95c18d75, 1 | BRF_PRG | BRF_ESS }, // 6 + { "freeze.e4", 0x1000, 0x7e8f5afc, 1 | BRF_PRG | BRF_ESS }, // 7 + + { "freeze.a1", 0x1000, 0x7771f5b9, 2 | BRF_PRG | BRF_ESS }, // 8 Z80 #1 Code + + { "freeze.5a", 0x1000, 0x6c8a98a0, 3 | BRF_GRA }, // 9 Graphics + { "freeze.3a", 0x1000, 0x6d2125e4, 3 | BRF_GRA }, // 10 + { "freeze.1a", 0x1000, 0x3a7f2fa9, 3 | BRF_GRA }, // 11 + { "freeze.2a", 0x1000, 0xdd70ddd6, 3 | BRF_GRA }, // 12 +}; + +STD_ROM_PICK(freeze); +STD_ROM_FN(freeze); + +struct BurnDriver BurnDrvfreeze = { + "freeze", NULL, NULL, "1984", + "Freeze\0", NULL, "Cinematronics", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, freezeRomInfo, freezeRomName, FreezeInputInfo, FreezeDIPInfo, + jackInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Super Casino + +static struct BurnRomInfo sucasinoRomDesc[] = { + { "1", 0x1000, 0xe116e979, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "2", 0x1000, 0x2a2635f5, 1 | BRF_PRG | BRF_ESS }, // 1 + { "3", 0x1000, 0x69864d90, 1 | BRF_PRG | BRF_ESS }, // 2 + { "4", 0x1000, 0x174c9373, 1 | BRF_PRG | BRF_ESS }, // 3 + { "5", 0x1000, 0x115bcb1e, 1 | BRF_PRG | BRF_ESS }, // 4 + { "6", 0x1000, 0x434caa17, 1 | BRF_PRG | BRF_ESS }, // 5 + { "7", 0x1000, 0x67c68b82, 1 | BRF_PRG | BRF_ESS }, // 6 + { "8", 0x1000, 0xf5b63006, 1 | BRF_PRG | BRF_ESS }, // 7 + + { "9", 0x1000, 0x67cf8aec, 2 | BRF_PRG | BRF_ESS }, // 8 Z80 #1 Code + + { "11", 0x1000, 0xf92c4c5b, 3 | BRF_GRA }, // 9 Graphics + { "10", 0x1000, 0x3b0783ce, 3 | BRF_GRA }, // 10 +}; + +STD_ROM_PICK(sucasino); +STD_ROM_FN(sucasino); + +struct BurnDriver BurnDrvsucasino = { + "sucasino", NULL, NULL, "1984", + "Super Casino\0", NULL, "Data Amusement", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, sucasinoRomInfo, sucasinoRomName, SucasinoInputInfo, SucasinoDIPInfo, + jackInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Tri-Pool (Casino Tech) + +static struct BurnRomInfo tripoolRomDesc[] = { + { "tri73a.bin", 0x1000, 0x96893aa7, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "tri62a.bin", 0x1000, 0x3299dc65, 1 | BRF_PRG | BRF_ESS }, // 1 + { "tri52b.bin", 0x1000, 0x27ef765e, 1 | BRF_PRG | BRF_ESS }, // 2 + { "tri33c.bin", 0x1000, 0xd7ef061d, 1 | BRF_PRG | BRF_ESS }, // 3 + { "tri45c.bin", 0x1000, 0x51b813b1, 1 | BRF_PRG | BRF_ESS }, // 4 + { "tri25d.bin", 0x1000, 0x8e64512d, 1 | BRF_PRG | BRF_ESS }, // 5 + { "tri13d.bin", 0x1000, 0xad268e9b, 1 | BRF_PRG | BRF_ESS }, // 6 + + { "trisnd.bin", 0x1000, 0x945c4b8b, 2 | BRF_PRG | BRF_ESS }, // 7 Z80 #1 Code + + { "tri105a.bin", 0x1000, 0x366a753c, 3 | BRF_GRA }, // 8 Graphics + { "tri93a.bin", 0x1000, 0x35213782, 3 | BRF_GRA }, // 9 +}; + +STD_ROM_PICK(tripool); +STD_ROM_FN(tripool); + +static int tripoolInit() +{ + tri_fix = 1; + timer_rate = 128; + + return DrvInit(); +} + +struct BurnDriver BurnDrvtripool = { + "tripool", NULL, NULL, "1981", + "Tri-Pool (Casino Tech)\0", NULL, "Noma (Casino Tech license)", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, tripoolRomInfo, tripoolRomName, TripoolInputInfo, NULL, + tripoolInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Tri-Pool (Costal Games) + +static struct BurnRomInfo tripoolaRomDesc[] = { + { "tri73a.bin", 0x1000, 0x96893aa7, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "tri62a.bin", 0x1000, 0x3299dc65, 1 | BRF_PRG | BRF_ESS }, // 1 + { "tri52b.bin", 0x1000, 0x27ef765e, 1 | BRF_PRG | BRF_ESS }, // 2 + { "tri33c.bin", 0x1000, 0xd7ef061d, 1 | BRF_PRG | BRF_ESS }, // 3 + { "tri45c.bin", 0x1000, 0x51b813b1, 1 | BRF_PRG | BRF_ESS }, // 4 + { "tri25d.bin", 0x1000, 0x8e64512d, 1 | BRF_PRG | BRF_ESS }, // 5 + { "tp1ckt", 0x1000, 0x72ec43a3, 1 | BRF_PRG | BRF_ESS }, // 6 + + { "trisnd.bin", 0x1000, 0x945c4b8b, 2 | BRF_PRG | BRF_ESS }, // 7 Z80 #1 Code + + { "tri105a.bin", 0x1000, 0x366a753c, 3 | BRF_GRA }, // 8 Graphics + { "tri93a.bin", 0x1000, 0x35213782, 3 | BRF_GRA }, // 9 +}; + +STD_ROM_PICK(tripoola); +STD_ROM_FN(tripoola); + +struct BurnDriver BurnDrvtripoola = { + "tripoola", "tripool", NULL, "1981", + "Tri-Pool (Costal Games)\0", NULL, "Noma (Costal Games license)", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, tripoolaRomInfo, tripoolaRomName, TripoolInputInfo, NULL, + tripoolInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + + +// Joinem + +static struct BurnRomInfo joinemRomDesc[] = { + { "join1.r0", 0x2000, 0xb5b2e2cc, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "join2.r2", 0x2000, 0xbcf140e6, 1 | BRF_PRG | BRF_ESS }, // 1 + { "join3.r4", 0x2000, 0xfe04e4d4, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "join7.s0", 0x1000, 0xbb8a7814, 2 | BRF_PRG | BRF_ESS }, // 3 Z80 #1 Code + + { "join4.p3", 0x1000, 0x4964c82c, 3 | BRF_GRA }, // 4 Graphics + { "join5.p2", 0x1000, 0xae78fa89, 3 | BRF_GRA }, // 5 + { "join6.p1", 0x1000, 0x2b533261, 3 | BRF_GRA }, // 6 + + { "l82s129.11n", 0x0100, 0x7b724211, 4 | BRF_GRA }, // 7 Color Proms + { "h82s129.12n", 0x0100, 0x2e81c5ff, 4 | BRF_GRA }, // 8 +}; + +STD_ROM_PICK(joinem); +STD_ROM_FN(joinem); + +static void joinem_palette_init() +{ + for (int i = 0; i < 0x100; i++) + { + int bit0,bit1,bit2,r,g,b; + + bit0 = (Prom[i] >> 0) & 1; + bit1 = (Prom[i] >> 1) & 1; + bit2 = (Prom[i] >> 2) & 1; + r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = (Prom[i] >> 3) & 1; + bit1 = (Prom[i] >> 4) & 1; + bit2 = (Prom[i] >> 5) & 1; + g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = 0; + bit1 = (Prom[i] >> 6) & 1; + bit2 = (Prom[i] >> 7) & 1; + b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + Palette[i] = (r << 16) | (g << 8) | b; + } +} + +static int joinemInit() +{ + joinem = 1; + timer_rate = 1; + + int nRet = DrvInit(); + + joinem_palette_init(); + + return nRet; +} + +struct BurnDriver BurnDrvjoinem = { + "joinem", NULL, NULL, "1986", + "Joinem\0", NULL, "Global Corporation", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, joinemRomInfo, joinemRomName, JoinemInputInfo, JoinemDIPInfo, + joinemInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 240, 3, 4 +}; + + +// Lover Boy + +static struct BurnRomInfo loverboyRomDesc[] = { + { "lover.r0", 0x2000, 0xffec4e41, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "lover.r2", 0x2000, 0x04052262, 1 | BRF_PRG | BRF_ESS }, // 1 + { "lover.r4", 0x2000, 0xce5f3b49, 1 | BRF_PRG | BRF_ESS }, // 2 + { "lover.r6", 0x1000, 0x839d79b7, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "lover.s0", 0x1000, 0xec38111c, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 #1 Code + + { "lover.p3", 0x2000, 0x1a519c8f, 3 | BRF_GRA }, // 5 Graphics + { "lover.p2", 0x2000, 0xe465372f, 3 | BRF_GRA }, // 6 + { "lover.p1", 0x2000, 0xcda0d87e, 3 | BRF_GRA }, // 7 + + { "color.n11", 0x0200, 0xcf4a16ae, 4 | BRF_GRA }, // 8 Color Proms + { "color.n12", 0x0200, 0x4b11ac21, 4 | BRF_GRA }, // 9 +}; + +STD_ROM_PICK(loverboy); +STD_ROM_FN(loverboy); + +static int loverboyInit() +{ + loverb = 1; + timer_rate = 16; + + int nRet = DrvInit(); + + // Hack (Protection?) + Rom0[0x12] = 0x9d; + Rom0[0x13] = 0x01; + + joinem_palette_init(); + + return nRet; +} + +struct BurnDriver BurnDrvloverboy = { + "loverboy", NULL, NULL, "1983", + "Lover Boy\0", NULL, "G.T Enterprise Inc", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, loverboyRomInfo, loverboyRomName, LoverboyInputInfo, LoverboyDIPInfo, + loverboyInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 240, 3, 4 +}; + + +// Super Triv + +static struct BurnRomInfo strivRomDesc[] = { + { "pr1.f2", 0x1000, 0xdcf5da6e, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "pr2.4f", 0x1000, 0x921610ba, 1 | BRF_PRG | BRF_ESS }, // 1 + { "pr3.5f", 0x1000, 0xc36f0e21, 1 | BRF_PRG | BRF_ESS }, // 2 + { "pr4.6f", 0x1000, 0x0dc98a97, 1 | BRF_PRG | BRF_ESS }, // 3 + { "bc3.7e", 0x1000, 0x83f03885, 1 | BRF_PRG | BRF_ESS }, // 4 + { "bc2.6e", 0x1000, 0x75f18361, 1 | BRF_PRG | BRF_ESS }, // 5 + { "bc1.5e", 0x1000, 0x0d150385, 1 | BRF_PRG | BRF_ESS }, // 6 + + { "snd.5a", 0x1000, 0xb7ddf84f, 2 | BRF_PRG | BRF_ESS }, // 7 Z80 #1 Code + + { "chr0.1a", 0x1000, 0x8f60229b, 3 | BRF_GRA }, // 8 Graphics + { "chr2.4a", 0x1000, 0x8f982a9c, 3 | BRF_GRA }, // 9 + { "chr3.5a", 0x1000, 0x8f982a9c, 3 | BRF_GRA }, // 10 + { "chr1.2a", 0x1000, 0x7ad4358e, 3 | BRF_GRA }, // 11 + + { "rom.u6", 0x8000, 0xa32d7a28, 5 | BRF_PRG | BRF_ESS }, // 12 Question ROMs + { "rom.u7", 0x8000, 0xbc44ae18, 5 | BRF_PRG | BRF_ESS }, // 13 + { "tbfd2.u8", 0x8000, 0x9572984a, 5 | BRF_PRG | BRF_ESS }, // 14 + { "tbfd3.u9", 0x8000, 0xd904a2f1, 5 | BRF_PRG | BRF_ESS }, // 15 + { "tbfl0.u10", 0x8000, 0x680264a2, 5 | BRF_PRG | BRF_ESS }, // 16 + { "tbfl1.u11", 0x8000, 0x33e99d00, 5 | BRF_PRG | BRF_ESS }, // 17 + { "tbfl2.u12", 0x8000, 0x2e7a941f, 5 | BRF_PRG | BRF_ESS }, // 18 + { "tbft0.u13", 0x8000, 0x7d2e5e89, 5 | BRF_PRG | BRF_ESS }, // 19 + { "tbft1.u14", 0x8000, 0xd36246cf, 5 | BRF_PRG | BRF_ESS }, // 20 + { "tbfd1.u15", 0x8000, 0x745db398, 5 | BRF_PRG | BRF_ESS }, // 21 + + { "tbfd0.u21", 0x2000, 0x15b83099, 0 | BRF_OPT }, // 22 Junk +}; + +STD_ROM_PICK(striv); +STD_ROM_FN(striv); + +static int strivInit() +{ + suprtriv = 1; + timer_rate = 128; + + int nRet = DrvInit(); + + for (int i = 0; i < 0x4000; i++) + { + if (i & 0x1000) + { + if (i & 4) + Rom0[i] = BITSWAP08(Rom0[i],7,2,5,1,3,6,4,0) ^ 1; + else + Rom0[i] = BITSWAP08(Rom0[i],0,2,5,1,3,6,4,7) ^ 0x81; + } + else + { + if (i & 4) + Rom0[i] = BITSWAP08(Rom0[i],7,2,5,1,3,6,4,0) ^ 1; + else + Rom0[i] = BITSWAP08(Rom0[i],0,2,5,1,3,6,4,7); + } + } + + return nRet; +} + +struct BurnDriver BurnDrvstriv = { + "striv", NULL, NULL, "1985", + "Super Triv\0", "No sound", "Hara Industries", "Jack the Giantkiller", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, strivRomInfo, strivRomName, StrivInputInfo, StrivDIPInfo, + strivInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvCalcPal, + 224, 256, 3, 4 +}; + diff --git a/src/burn/misc/pre90s/d_kyugo.cpp b/src/burn/misc/pre90s/d_kyugo.cpp new file mode 100644 index 0000000..3daaafd --- /dev/null +++ b/src/burn/misc/pre90s/d_kyugo.cpp @@ -0,0 +1,2458 @@ +#include "tiles_generic.h" + +#include "driver.h" +extern "C" { + #include "ay8910.h" +} + +static unsigned char KyugoInputPort0[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char KyugoInputPort1[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char KyugoInputPort2[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char KyugoDip[2] = {0, 0}; +static unsigned char KyugoInput[3] = {0x00, 0x00, 0x00}; +static unsigned char KyugoReset = 0; + +static unsigned char *Mem = NULL; +static unsigned char *MemEnd = NULL; +static unsigned char *RamStart = NULL; +static unsigned char *RamEnd = NULL; +static unsigned char *KyugoZ80Rom1 = NULL; +static unsigned char *KyugoZ80Rom2 = NULL; +static unsigned char *KyugoSharedZ80Ram = NULL; +static unsigned char *KyugoZ80Ram2 = NULL; +static unsigned char *KyugoSprite1Ram = NULL; +static unsigned char *KyugoSprite2Ram = NULL; +static unsigned char *KyugoFgVideoRam = NULL; +static unsigned char *KyugoBgVideoRam = NULL; +static unsigned char *KyugoBgAttrRam = NULL; +static unsigned char *KyugoPromRed = NULL; +static unsigned char *KyugoPromGreen = NULL; +static unsigned char *KyugoPromBlue = NULL; +static unsigned char *KyugoPromCharLookup = NULL; +static unsigned char *KyugoChars = NULL; +static unsigned char *KyugoTiles = NULL; +static unsigned char *KyugoSprites = NULL; +static unsigned char *KyugoTempRom = NULL; +static unsigned int *KyugoPalette = NULL; +static short* pFMBuffer; +static short* pAY8910Buffer[6]; + +static unsigned char KyugoIRQEnable; +static unsigned char KyugoSubCPUEnable; +static unsigned char KyugoFgColour; +static unsigned char KyugoBgPaletteBank; +static unsigned char KyugoBgScrollXHi; +static unsigned char KyugoBgScrollXLo; +static unsigned char KyugoBgScrollY; +static unsigned char KyugoFlipScreen; + +static int nCyclesDone[2], nCyclesTotal[2]; +static int nCyclesSegment; + +static int KyugoNumZ80Rom1; +static int KyugoNumZ80Rom2; +static int KyugoNumSpriteRom; +static int KyugoSizeZ80Rom1; +static int KyugoSizeZ80Rom2; +static int KyugoSizeSpriteRom; + +static struct BurnInputInfo KyugoInputList[] = +{ + {"Coin 1" , BIT_DIGITAL , KyugoInputPort0 + 0, "p1 coin" }, + {"Start 1" , BIT_DIGITAL , KyugoInputPort0 + 3, "p1 start" }, + {"Coin 2" , BIT_DIGITAL , KyugoInputPort0 + 1, "p2 coin" }, + {"Start 2" , BIT_DIGITAL , KyugoInputPort0 + 4, "p2 start" }, + + {"Up" , BIT_DIGITAL , KyugoInputPort1 + 2, "p1 up" }, + {"Down" , BIT_DIGITAL , KyugoInputPort1 + 3, "p1 down" }, + {"Left" , BIT_DIGITAL , KyugoInputPort1 + 0, "p1 left" }, + {"Right" , BIT_DIGITAL , KyugoInputPort1 + 1, "p1 right" }, + {"Fire 1" , BIT_DIGITAL , KyugoInputPort1 + 4, "p1 fire 1" }, + {"Fire 2" , BIT_DIGITAL , KyugoInputPort1 + 5, "p1 fire 2" }, + + {"Up (Cocktail)" , BIT_DIGITAL , KyugoInputPort2 + 2, "p2 up" }, + {"Down (Cocktail)" , BIT_DIGITAL , KyugoInputPort2 + 3, "p2 down" }, + {"Left (Cocktail)" , BIT_DIGITAL , KyugoInputPort2 + 0, "p2 left" }, + {"Right (Cocktail)" , BIT_DIGITAL , KyugoInputPort2 + 1, "p2 right" }, + {"Fire 1 (Cocktail)" , BIT_DIGITAL , KyugoInputPort2 + 4, "p2 fire 1" }, + {"Fire 2 (Cocktail)" , BIT_DIGITAL , KyugoInputPort2 + 5, "p2 fire 2" }, + + {"Reset" , BIT_DIGITAL , &KyugoReset , "reset" }, + {"Service" , BIT_DIGITAL , KyugoInputPort0 + 2, "service" }, + {"Dip 1" , BIT_DIPSWITCH, KyugoDip + 0 , "dip" }, + {"Dip 2" , BIT_DIPSWITCH, KyugoDip + 1 , "dip" }, +}; + + +STDINPUTINFO(Kyugo); + +inline void KyugoClearOpposites(unsigned char* nJoystickInputs) +{ + if ((*nJoystickInputs & 0x03) == 0x03) { + *nJoystickInputs &= ~0x03; + } + if ((*nJoystickInputs & 0x0c) == 0x0c) { + *nJoystickInputs &= ~0x0c; + } +} + +inline void KyugoMakeInputs() +{ + // Reset Inputs + KyugoInput[0] = KyugoInput[1] = KyugoInput[2] = 0x00; + + // Compile Digital Inputs + for (int i = 0; i < 8; i++) { + KyugoInput[0] |= (KyugoInputPort0[i] & 1) << i; + KyugoInput[1] |= (KyugoInputPort1[i] & 1) << i; + KyugoInput[2] |= (KyugoInputPort2[i] & 1) << i; + } + + // Clear Opposites + KyugoClearOpposites(&KyugoInput[1]); + KyugoClearOpposites(&KyugoInput[2]); +} + +static struct BurnDIPInfo AirwolfDIPList[]= +{ + // Default Values + {0x12, 0xff, 0xff, 0xbb, NULL }, + {0x13, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x12, 0x01, 0x03, 0x03, "4" }, + {0x12, 0x01, 0x03, 0x02, "5" }, + {0x12, 0x01, 0x03, 0x01, "6" }, + {0x12, 0x01, 0x03, 0x00, "7" }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x12, 0x01, 0x04, 0x04, "Off" }, + {0x12, 0x01, 0x04, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Slow Motion" }, + {0x12, 0x01, 0x08, 0x08, "Off" }, + {0x12, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Invulnerability" }, + {0x12, 0x01, 0x10, 0x10, "Off" }, + {0x12, 0x01, 0x10, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Sound Test" }, + {0x12, 0x01, 0x20, 0x20, "Off" }, + {0x12, 0x01, 0x20, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x40, 0x00, "Upright" }, + {0x12, 0x01, 0x40, 0x40, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x12, 0x01, 0x80, 0x80, "Off" }, + {0x12, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x13, 0x01, 0x07, 0x02, "2 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x01, "3 Coins 2 Plays" }, + {0x13, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x13, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x07, 0x04, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x07, 0x03, "1 Coin 6 Plays" }, + {0x13, 0x01, 0x07, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x13, 0x01, 0x38, 0x00, "5 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x08, "4 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x10, "3 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x18, "2 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x13, 0x01, 0x38, 0x20, "3 Coins 4 Plays" }, + {0x13, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, +}; + +STDDIPINFO(Airwolf); + +static struct BurnDIPInfo SkywolfDIPList[]= +{ + // Default Values + {0x12, 0xff, 0xff, 0xbb, NULL }, + {0x13, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x12, 0x01, 0x03, 0x03, "3" }, + {0x12, 0x01, 0x03, 0x02, "4" }, + {0x12, 0x01, 0x03, 0x01, "5" }, + {0x12, 0x01, 0x03, 0x00, "6" }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x12, 0x01, 0x04, 0x04, "Off" }, + {0x12, 0x01, 0x04, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Slow Motion" }, + {0x12, 0x01, 0x08, 0x08, "Off" }, + {0x12, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Invulnerability" }, + {0x12, 0x01, 0x10, 0x10, "Off" }, + {0x12, 0x01, 0x10, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Sound Test" }, + {0x12, 0x01, 0x20, 0x20, "Off" }, + {0x12, 0x01, 0x20, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x40, 0x00, "Upright" }, + {0x12, 0x01, 0x40, 0x40, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x12, 0x01, 0x80, 0x80, "Off" }, + {0x12, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x13, 0x01, 0x07, 0x02, "2 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x01, "3 Coins 2 Plays" }, + {0x13, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x13, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x07, 0x04, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x07, 0x03, "1 Coin 6 Plays" }, + {0x13, 0x01, 0x07, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x13, 0x01, 0x38, 0x00, "5 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x08, "4 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x10, "3 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x18, "2 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x13, 0x01, 0x38, 0x20, "3 Coins 4 Plays" }, + {0x13, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, +}; + +STDDIPINFO(Skywolf); + +static struct BurnDIPInfo FlashgalDIPList[]= +{ + // Default Values + {0x12, 0xff, 0xff, 0xaf, NULL }, + {0x13, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x12, 0x01, 0x03, 0x03, "3" }, + {0x12, 0x01, 0x03, 0x02, "4" }, + {0x12, 0x01, 0x03, 0x01, "5" }, + {0x12, 0x01, 0x03, 0x00, "6" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x12, 0x01, 0x04, 0x04, "Every 50000" }, + {0x12, 0x01, 0x04, 0x00, "Every 70000" }, + + {0 , 0xfe, 0 , 2 , "Slow Motion" }, + {0x12, 0x01, 0x08, 0x08, "Off" }, + {0x12, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x12, 0x01, 0x10, 0x10, "Off" }, + {0x12, 0x01, 0x10, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Sound Test" }, + {0x12, 0x01, 0x20, 0x20, "Off" }, + {0x12, 0x01, 0x20, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x40, 0x00, "Upright" }, + {0x12, 0x01, 0x40, 0x40, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x12, 0x01, 0x80, 0x80, "Off" }, + {0x12, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x13, 0x01, 0x07, 0x02, "2 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x01, "3 Coins 2 Plays" }, + {0x13, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x13, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x07, 0x04, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x07, 0x03, "1 Coin 6 Plays" }, + {0x13, 0x01, 0x07, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x13, 0x01, 0x38, 0x00, "5 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x08, "4 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x10, "3 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x18, "2 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x13, 0x01, 0x38, 0x20, "3 Coins 4 Plays" }, + {0x13, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, +}; + +STDDIPINFO(Flashgal); + +static struct BurnDIPInfo GyrodineDIPList[]= +{ + // Default Values + {0x12, 0xff, 0xff, 0xbf, NULL }, + {0x13, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x12, 0x01, 0x03, 0x03, "3" }, + {0x12, 0x01, 0x03, 0x02, "4" }, + {0x12, 0x01, 0x03, 0x01, "5" }, + {0x12, 0x01, 0x03, 0x00, "6" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x12, 0x01, 0x10, 0x10, "Easy" }, + {0x12, 0x01, 0x10, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x12, 0x01, 0x20, 0x20, "20000 50000" }, + {0x12, 0x01, 0x20, 0x00, "40000 70000" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x40, 0x00, "Upright" }, + {0x12, 0x01, 0x40, 0x40, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x12, 0x01, 0x80, 0x80, "Off" }, + {0x12, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x13, 0x01, 0x07, 0x02, "2 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x01, "3 Coins 2 Plays" }, + {0x13, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x13, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x07, 0x04, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x07, 0x03, "1 Coin 6 Plays" }, + {0x13, 0x01, 0x07, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x13, 0x01, 0x38, 0x00, "5 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x08, "4 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x10, "3 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x18, "2 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x13, 0x01, 0x38, 0x20, "3 Coins 4 Plays" }, + {0x13, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, +}; + +STDDIPINFO(Gyrodine); + +static struct BurnDIPInfo LegendDIPList[]= +{ + // Default Values + {0x12, 0xff, 0xff, 0xbf, NULL }, + {0x13, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x12, 0x01, 0x03, 0x03, "3" }, + {0x12, 0x01, 0x03, 0x02, "4" }, + {0x12, 0x01, 0x03, 0x01, "5" }, + {0x12, 0x01, 0x03, 0x00, "6" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life / Continue" }, + {0x12, 0x01, 0x04, 0x04, "Every 50000 / No" }, + {0x12, 0x01, 0x04, 0x00, "Every 70000 / Yes" }, + + {0 , 0xfe, 0 , 2 , "Slow Motion" }, + {0x12, 0x01, 0x08, 0x08, "Off" }, + {0x12, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Sound Test" }, + {0x12, 0x01, 0x20, 0x20, "Off" }, + {0x12, 0x01, 0x20, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x40, 0x00, "Upright" }, + {0x12, 0x01, 0x40, 0x40, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x12, 0x01, 0x80, 0x80, "Off" }, + {0x12, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x13, 0x01, 0x07, 0x02, "2 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x01, "3 Coins 2 Plays" }, + {0x13, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x13, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x07, 0x04, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x07, 0x03, "1 Coin 6 Plays" }, + {0x13, 0x01, 0x07, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x13, 0x01, 0x38, 0x00, "5 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x08, "4 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x10, "3 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x18, "2 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x13, 0x01, 0x38, 0x20, "3 Coins 4 Plays" }, + {0x13, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, +}; + +STDDIPINFO(Legend); + +static struct BurnDIPInfo SonofphxDIPList[]= +{ + // Default Values + {0x12, 0xff, 0xff, 0xbf, NULL }, + {0x13, 0xff, 0xff, 0xbf, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x12, 0x01, 0x03, 0x03, "3" }, + {0x12, 0x01, 0x03, 0x02, "4" }, + {0x12, 0x01, 0x03, 0x01, "5" }, + {0x12, 0x01, 0x03, 0x00, "6" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x12, 0x01, 0x04, 0x04, "Every 50000" }, + {0x12, 0x01, 0x04, 0x00, "Every 70000" }, + + {0 , 0xfe, 0 , 2 , "Slow Motion" }, + {0x12, 0x01, 0x08, 0x08, "Off" }, + {0x12, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Invulnerability" }, + {0x12, 0x01, 0x10, 0x10, "Off" }, + {0x12, 0x01, 0x10, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Sound Test" }, + {0x12, 0x01, 0x20, 0x20, "Off" }, + {0x12, 0x01, 0x20, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x40, 0x00, "Upright" }, + {0x12, 0x01, 0x40, 0x40, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x12, 0x01, 0x80, 0x80, "Off" }, + {0x12, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x13, 0x01, 0x07, 0x02, "2 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x01, "3 Coins 2 Plays" }, + {0x13, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x13, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x07, 0x04, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x07, 0x03, "1 Coin 6 Plays" }, + {0x13, 0x01, 0x07, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x13, 0x01, 0x38, 0x00, "5 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x08, "4 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x10, "3 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x18, "2 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x13, 0x01, 0x38, 0x20, "3 Coins 4 Plays" }, + {0x13, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x13, 0x01, 0xc0, 0xc0, "Easy" }, + {0x13, 0x01, 0xc0, 0x80, "Normal" }, + {0x13, 0x01, 0xc0, 0x40, "Hard" }, + {0x13, 0x01, 0xc0, 0x00, "Hardest" }, +}; + +STDDIPINFO(Sonofphx); + +static struct BurnDIPInfo SrdmissnDIPList[]= +{ + // Default Values + {0x12, 0xff, 0xff, 0xbf, NULL }, + {0x13, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x12, 0x01, 0x03, 0x03, "3" }, + {0x12, 0x01, 0x03, 0x02, "4" }, + {0x12, 0x01, 0x03, 0x01, "5" }, + {0x12, 0x01, 0x03, 0x00, "6" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life / Continue" }, + {0x12, 0x01, 0x04, 0x04, "Every 50000 / No" }, + {0x12, 0x01, 0x04, 0x00, "Every 70000 / Yes" }, + + {0 , 0xfe, 0 , 2 , "Slow Motion" }, + {0x12, 0x01, 0x08, 0x08, "Off" }, + {0x12, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Invulnerability" }, + {0x12, 0x01, 0x10, 0x10, "Off" }, + {0x12, 0x01, 0x10, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Sound Test" }, + {0x12, 0x01, 0x20, 0x20, "Off" }, + {0x12, 0x01, 0x20, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x40, 0x00, "Upright" }, + {0x12, 0x01, 0x40, 0x40, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Freeze" }, + {0x12, 0x01, 0x80, 0x80, "Off" }, + {0x12, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x13, 0x01, 0x07, 0x02, "2 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x01, "3 Coins 2 Plays" }, + {0x13, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x13, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x07, 0x04, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x07, 0x03, "1 Coin 6 Plays" }, + {0x13, 0x01, 0x07, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x13, 0x01, 0x38, 0x00, "5 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x08, "4 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x10, "3 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x18, "2 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x13, 0x01, 0x38, 0x20, "3 Coins 4 Plays" }, + {0x13, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, +}; + +STDDIPINFO(Srdmissn); + +static struct BurnRomInfo AirwolfRomDesc[] = { + { "b.2s", 0x08000, 0x8c993cce, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + + { "a.7s", 0x08000, 0xa3c7af5c, BRF_ESS | BRF_PRG }, // 1 Z80 #2 Program + + { "f.4a", 0x01000, 0x4df44ce9, BRF_GRA }, // 2 Characters + + { "09h_14.bin", 0x02000, 0x25e57e1f, BRF_GRA }, // 3 Tiles + { "10h_13.bin", 0x02000, 0xcf0de5e9, BRF_GRA }, // 4 + { "11h_12.bin", 0x02000, 0x4050c048, BRF_GRA }, // 5 + + { "e.6a", 0x08000, 0xe8fbc7d2, BRF_GRA }, // 6 Sprites + { "d.8a", 0x08000, 0xc5d4156b, BRF_GRA }, // 7 + { "c.10a", 0x08000, 0xde91dfb1, BRF_GRA }, // 8 + + { "01j.bin", 0x00100, 0x6a94b2a3, BRF_GRA }, // 9 PROMs + { "01h.bin", 0x00100, 0xec0923d3, BRF_GRA }, // 10 + { "01f.bin", 0x00100, 0xade97052, BRF_GRA }, // 11 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 12 + + { "pal16l8a.2j", 0x00104, 0x00000000, BRF_OPT | BRF_NODUMP }, // 13 PLDs + { "epl12p6a.9j", 0x00034, 0x19808f14, BRF_OPT }, // 14 + { "epl12p6a.9k", 0x00034, 0xf5acad85, BRF_OPT }, // 15 +}; + +STD_ROM_PICK(Airwolf); +STD_ROM_FN(Airwolf); + +static struct BurnRomInfo AirwolfaRomDesc[] = { + { "airwolf.2", 0x08000, 0xbc1a8587, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + + { "airwolf.1", 0x08000, 0xa3c7af5c, BRF_ESS | BRF_PRG }, // 1 Z80 #2 Program + + { "airwolf.6", 0x02000, 0x5b0a01e9, BRF_GRA }, // 2 Characters + + { "airwolf.9", 0x02000, 0x25e57e1f, BRF_GRA }, // 3 Tiles + { "airwolf.8", 0x02000, 0xcf0de5e9, BRF_GRA }, // 4 + { "airwolf.7", 0x02000, 0x4050c048, BRF_GRA }, // 5 + + { "airwolf.5", 0x08000, 0xe8fbc7d2, BRF_GRA }, // 6 Sprites + { "airwolf.4", 0x08000, 0xc5d4156b, BRF_GRA }, // 7 + { "airwolf.3", 0x08000, 0xde91dfb1, BRF_GRA }, // 8 + + { "01j.bin", 0x00100, 0x6a94b2a3, BRF_GRA }, // 9 PROMs + { "01h.bin", 0x00100, 0xec0923d3, BRF_GRA }, // 10 + { "01f.bin", 0x00100, 0xade97052, BRF_GRA }, // 11 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 12 + + { "pal16l8a.2j", 0x00104, 0x00000000, BRF_OPT | BRF_NODUMP }, // 13 PLDs + { "epl12p6a.9j", 0x00034, 0x19808f14, BRF_OPT }, // 14 + { "epl12p6a.9k", 0x00034, 0xf5acad85, BRF_OPT }, // 15 +}; + +STD_ROM_PICK(Airwolfa); +STD_ROM_FN(Airwolfa); + +static struct BurnRomInfo SkywolfRomDesc[] = { + { "02s_03.bin", 0x04000, 0xa0891798, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "03s_04.bin", 0x04000, 0x5f515d46, BRF_ESS | BRF_PRG }, // 1 Z80 + + { "07s_01.bin", 0x04000, 0xc680a905, BRF_ESS | BRF_PRG }, // 2 Z80 #2 Program + { "08s_02.bin", 0x04000, 0x3d66bf26, BRF_ESS | BRF_PRG }, // 3 Z80 + + { "04a_11.bin", 0x01000, 0x219de9aa, BRF_GRA }, // 4 Characters + + { "09h_14.bin", 0x02000, 0x25e57e1f, BRF_GRA }, // 5 Tiles + { "10h_13.bin", 0x02000, 0xcf0de5e9, BRF_GRA }, // 6 + { "11h_12.bin", 0x02000, 0x4050c048, BRF_GRA }, // 7 + + { "06a_10.bin", 0x04000, 0x1c809383, BRF_GRA }, // 6 Sprites + { "07a_09.bin", 0x04000, 0x5665d774, BRF_GRA }, // 7 + { "08a_08.bin", 0x04000, 0x6dda8f2a, BRF_GRA }, // 8 + { "09a_07.bin", 0x04000, 0x6a21ddb8, BRF_GRA }, // 9 + { "10a_06.bin", 0x04000, 0xf2e548e0, BRF_GRA }, // 10 + { "11a_05.bin", 0x04000, 0x8681b112, BRF_GRA }, // 11 + + { "01j.bin", 0x00100, 0x6a94b2a3, BRF_GRA }, // 12 PROMs + { "01h.bin", 0x00100, 0xec0923d3, BRF_GRA }, // 13 + { "01f.bin", 0x00100, 0xade97052, BRF_GRA }, // 14 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 15 +}; + +STD_ROM_PICK(Skywolf); +STD_ROM_FN(Skywolf); + +static struct BurnRomInfo Skywolf2RomDesc[] = { + { "z80_2.bin", 0x08000, 0x34db7bda, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + + { "07s_01.bin", 0x04000, 0xc680a905, BRF_ESS | BRF_PRG }, // 1 Z80 #2 Program + { "08s_02.bin", 0x04000, 0x3d66bf26, BRF_ESS | BRF_PRG }, // 2 Z80 + + { "04a_11.bin", 0x01000, 0x219de9aa, BRF_GRA }, // 3 Characters + + { "09h_14.bin", 0x02000, 0x25e57e1f, BRF_GRA }, // 4 Tiles + { "10h_13.bin", 0x02000, 0xcf0de5e9, BRF_GRA }, // 5 + { "11h_12.bin", 0x02000, 0x4050c048, BRF_GRA }, // 6 + + { "06a_10.bin", 0x04000, 0x1c809383, BRF_GRA }, // 7 Sprites + { "07a_09.bin", 0x04000, 0x5665d774, BRF_GRA }, // 8 + { "08a_08.bin", 0x04000, 0x6dda8f2a, BRF_GRA }, // 9 + { "09a_07.bin", 0x04000, 0x6a21ddb8, BRF_GRA }, // 10 + { "10a_06.bin", 0x04000, 0xf2e548e0, BRF_GRA }, // 11 + { "11a_05.bin", 0x04000, 0x8681b112, BRF_GRA }, // 12 + + { "01j.bin", 0x00100, 0x6a94b2a3, BRF_GRA }, // 13 PROMs + { "01h.bin", 0x00100, 0xec0923d3, BRF_GRA }, // 14 + { "01f.bin", 0x00100, 0xade97052, BRF_GRA }, // 15 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 16 +}; + +STD_ROM_PICK(Skywolf2); +STD_ROM_FN(Skywolf2); + +static struct BurnRomInfo FlashgalRomDesc[] = { + { "epr-7167.4f", 0x02000, 0xcf5ad733, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "epr-7168.4h", 0x02000, 0x00c4851f, BRF_ESS | BRF_PRG }, // 1 + { "epr-7169.4j", 0x02000, 0x1ef0b8f7, BRF_ESS | BRF_PRG }, // 2 + { "epr-7170.4k", 0x02000, 0x885d53de, BRF_ESS | BRF_PRG }, // 3 + + { "epr-7163.2f", 0x02000, 0xeee2134d, BRF_ESS | BRF_PRG }, // 4 Z80 #2 Program + { "epr-7164.2h", 0x02000, 0xe5e0cd22, BRF_ESS | BRF_PRG }, // 5 + { "epr-7165.2j", 0x02000, 0x4cd3fe5e, BRF_ESS | BRF_PRG }, // 6 + { "epr-7166.2k", 0x02000, 0x552ca339, BRF_ESS | BRF_PRG }, // 7 + + { "epr-7177.4a", 0x01000, 0xdca9052f, BRF_GRA }, // 8 Characters + + { "epr-7178.9h", 0x02000, 0x2f5b62c0, BRF_GRA }, // 9 Tiles + { "epr-7179.10h", 0x02000, 0x8fbb49b5, BRF_GRA }, // 10 + { "epr-7180.11h", 0x02000, 0x26a8e5c3, BRF_GRA }, // 11 + + { "epr-7171.6a", 0x04000, 0x62caf2a1, BRF_GRA }, // 12 Sprites + { "epr-7172.7a", 0x04000, 0x10f78a10, BRF_GRA }, // 13 + { "epr-7173.8a", 0x04000, 0x36ea1d59, BRF_GRA }, // 14 + { "epr-7174.9a", 0x04000, 0xf527d837, BRF_GRA }, // 15 + { "epr-7175.10a", 0x04000, 0xba76e4c1, BRF_GRA }, // 16 + { "epr-7176.11a", 0x04000, 0xf095d619, BRF_GRA }, // 17 + + { "7161.1j", 0x00100, 0x02c4043f, BRF_GRA }, // 18 PROMs + { "7160.1h", 0x00100, 0x225938d1, BRF_GRA }, // 19 + { "7159.1f", 0x00100, 0x1e0a1cd3, BRF_GRA }, // 20 + { "7162.5j", 0x00020, 0xcce2e29f, BRF_GRA }, // 21 + { "bpr.2c", 0x00020, 0x83a39201, BRF_GRA }, // 22 +}; + +STD_ROM_PICK(Flashgal); +STD_ROM_FN(Flashgal); + +static struct BurnRomInfo FlashglaRomDesc[] = { + { "flashgal.5", 0x02000, 0xaa889ace, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "epr-7168.4h", 0x02000, 0x00c4851f, BRF_ESS | BRF_PRG }, // 1 + { "epr-7169.4j", 0x02000, 0x1ef0b8f7, BRF_ESS | BRF_PRG }, // 2 + { "epr-7170.4k", 0x02000, 0x885d53de, BRF_ESS | BRF_PRG }, // 3 + + { "flashgal.1", 0x02000, 0x55171cc1, BRF_ESS | BRF_PRG }, // 4 Z80 #2 Program + { "flashgal.2", 0x02000, 0x3fd21aac, BRF_ESS | BRF_PRG }, // 5 + { "flashgal.3", 0x02000, 0xa1223b74, BRF_ESS | BRF_PRG }, // 6 + { "flashgal.4", 0x02000, 0x04d2a05f, BRF_ESS | BRF_PRG }, // 7 + + { "epr-7177.4a", 0x01000, 0xdca9052f, BRF_GRA }, // 8 Characters + + { "epr-7178.9h", 0x02000, 0x2f5b62c0, BRF_GRA }, // 9 Tiles + { "epr-7179.10h", 0x02000, 0x8fbb49b5, BRF_GRA }, // 10 + { "epr-7180.11h", 0x02000, 0x26a8e5c3, BRF_GRA }, // 11 + + { "epr-7171.6a", 0x04000, 0x62caf2a1, BRF_GRA }, // 12 Sprites + { "epr-7172.7a", 0x04000, 0x10f78a10, BRF_GRA }, // 13 + { "epr-7173.8a", 0x04000, 0x36ea1d59, BRF_GRA }, // 14 + { "epr-7174.9a", 0x04000, 0xf527d837, BRF_GRA }, // 15 + { "epr-7175.10a", 0x04000, 0xba76e4c1, BRF_GRA }, // 16 + { "epr-7176.11a", 0x04000, 0xf095d619, BRF_GRA }, // 17 + + { "7161.1j", 0x00100, 0x02c4043f, BRF_GRA }, // 18 PROMs + { "7160.1h", 0x00100, 0x225938d1, BRF_GRA }, // 19 + { "7159.1f", 0x00100, 0x1e0a1cd3, BRF_GRA }, // 20 + { "7162.5j", 0x00020, 0xcce2e29f, BRF_GRA }, // 21 + { "bpr.2c", 0x00020, 0x83a39201, BRF_GRA }, // 22 +}; + +STD_ROM_PICK(Flashgla); +STD_ROM_FN(Flashgla); + +static struct BurnRomInfo GyrodineRomDesc[] = { + { "a21.02", 0x02000, 0xc5ec4a50, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "a21.03", 0x02000, 0x4e9323bd, BRF_ESS | BRF_PRG }, // 1 + { "a21.04", 0x02000, 0x57e659d4, BRF_ESS | BRF_PRG }, // 2 + { "a21.05", 0x02000, 0x1e7293f3, BRF_ESS | BRF_PRG }, // 3 + + { "a21.01", 0x02000, 0xb2ce0aa2, BRF_ESS | BRF_PRG }, // 4 Z80 #2 Program + + { "a21.15", 0x01000, 0xadba18d0, BRF_GRA }, // 5 Characters + + { "a21.08", 0x02000, 0xa57df1c9, BRF_GRA }, // 6 Tiles + { "a21.07", 0x02000, 0x63623ba3, BRF_GRA }, // 7 + { "a21.06", 0x02000, 0x4cc969a9, BRF_GRA }, // 8 + + { "a21.14", 0x02000, 0x9c5c4d5b, BRF_GRA }, // 9 Sprites + { "a21.13", 0x02000, 0xd36b5aad, BRF_GRA }, // 10 + { "a21.12", 0x02000, 0xf387aea2, BRF_GRA }, // 11 + { "a21.11", 0x02000, 0x87967d7d, BRF_GRA }, // 12 + { "a21.10", 0x02000, 0x59640ab4, BRF_GRA }, // 13 + { "a21.09", 0x02000, 0x22ad88d8, BRF_GRA }, // 14 + + { "a21.16", 0x00100, 0xcc25fb56, BRF_GRA }, // 15 PROMs + { "a21.17", 0x00100, 0xca054448, BRF_GRA }, // 16 + { "a21.18", 0x00100, 0x23c0c449, BRF_GRA }, // 17 + { "a21.20", 0x00020, 0xefc4985e, BRF_GRA }, // 18 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 19 +}; + +STD_ROM_PICK(Gyrodine); +STD_ROM_FN(Gyrodine); + +static struct BurnRomInfo GyrodincRomDesc[] = { + { "rom2", 0x02000, 0x85ddea38, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "a21.03", 0x02000, 0x4e9323bd, BRF_ESS | BRF_PRG }, // 1 + { "a21.04", 0x02000, 0x57e659d4, BRF_ESS | BRF_PRG }, // 2 + { "a21.05", 0x02000, 0x1e7293f3, BRF_ESS | BRF_PRG }, // 3 + + { "a21.01", 0x02000, 0xb2ce0aa2, BRF_ESS | BRF_PRG }, // 4 Z80 #2 Program + + { "a21.15", 0x01000, 0xadba18d0, BRF_GRA }, // 5 Characters + + { "a21.08", 0x02000, 0xa57df1c9, BRF_GRA }, // 6 Tiles + { "a21.07", 0x02000, 0x63623ba3, BRF_GRA }, // 7 + { "a21.06", 0x02000, 0x4cc969a9, BRF_GRA }, // 8 + + { "a21.14", 0x02000, 0x9c5c4d5b, BRF_GRA }, // 9 Sprites + { "a21.13", 0x02000, 0xd36b5aad, BRF_GRA }, // 10 + { "a21.12", 0x02000, 0xf387aea2, BRF_GRA }, // 11 + { "a21.11", 0x02000, 0x87967d7d, BRF_GRA }, // 12 + { "a21.10", 0x02000, 0x59640ab4, BRF_GRA }, // 13 + { "a21.09", 0x02000, 0x22ad88d8, BRF_GRA }, // 14 + + { "a21.16", 0x00100, 0xcc25fb56, BRF_GRA }, // 15 PROMs + { "a21.17", 0x00100, 0xca054448, BRF_GRA }, // 16 + { "a21.18", 0x00100, 0x23c0c449, BRF_GRA }, // 17 + { "a21.20", 0x00020, 0xefc4985e, BRF_GRA }, // 18 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 19 +}; + +STD_ROM_PICK(Gyrodinc); +STD_ROM_FN(Gyrodinc); + +static struct BurnRomInfo BuzzardRomDesc[] = { + { "rom2", 0x02000, 0x85ddea38, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "a21.03", 0x02000, 0x4e9323bd, BRF_ESS | BRF_PRG }, // 1 + { "a21.04", 0x02000, 0x57e659d4, BRF_ESS | BRF_PRG }, // 2 + { "a21.05", 0x02000, 0x1e7293f3, BRF_ESS | BRF_PRG }, // 3 + + { "a21.01", 0x02000, 0xb2ce0aa2, BRF_ESS | BRF_PRG }, // 4 Z80 #2 Program + + { "buzl01.bin", 0x01000, 0x65d728d0, BRF_GRA }, // 5 Characters + + { "a21.08", 0x02000, 0xa57df1c9, BRF_GRA }, // 6 Tiles + { "a21.07", 0x02000, 0x63623ba3, BRF_GRA }, // 7 + { "a21.06", 0x02000, 0x4cc969a9, BRF_GRA }, // 8 + + { "a21.14", 0x02000, 0x9c5c4d5b, BRF_GRA }, // 9 Sprites + { "a21.13", 0x02000, 0xd36b5aad, BRF_GRA }, // 10 + { "a21.12", 0x02000, 0xf387aea2, BRF_GRA }, // 11 + { "a21.11", 0x02000, 0x87967d7d, BRF_GRA }, // 12 + { "a21.10", 0x02000, 0x59640ab4, BRF_GRA }, // 13 + { "a21.09", 0x02000, 0x22ad88d8, BRF_GRA }, // 14 + + { "a21.16", 0x00100, 0xcc25fb56, BRF_GRA }, // 15 PROMs + { "a21.17", 0x00100, 0xca054448, BRF_GRA }, // 16 + { "a21.18", 0x00100, 0x23c0c449, BRF_GRA }, // 17 + { "a21.20", 0x00020, 0xefc4985e, BRF_GRA }, // 18 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 19 +}; + +STD_ROM_PICK(Buzzard); +STD_ROM_FN(Buzzard); + +static struct BurnRomInfo LegendRomDesc[] = { + { "a_r2.rom", 0x04000, 0x0cc1c4f4, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "a_r3.rom", 0x04000, 0x4b270c6b, BRF_ESS | BRF_PRG }, // 1 + + { "a_r7.rom", 0x02000, 0xabfe5eb4, BRF_ESS | BRF_PRG }, // 2 Z80 #2 Program + { "a_r8.rom", 0x02000, 0x7e7b9ba9, BRF_ESS | BRF_PRG }, // 3 + { "a_r9.rom", 0x02000, 0x66737f1e, BRF_ESS | BRF_PRG }, // 4 + { "a_n7.rom", 0x02000, 0x13915a53, BRF_ESS | BRF_PRG }, // 5 + + { "b_a4.rom", 0x01000, 0xc7dd3cf7, BRF_GRA }, // 6 Characters + + { "b_h9.rom", 0x02000, 0x1fe8644a, BRF_GRA }, // 7 Tiles + { "b_h10.rom", 0x02000, 0x5f7dc82e, BRF_GRA }, // 8 + { "b_h11.rom", 0x02000, 0x46741643, BRF_GRA }, // 9 + + { "b_a6.rom", 0x04000, 0x1689f21c, BRF_GRA }, // 10 Sprites + { "b_a7.rom", 0x04000, 0xf527c909, BRF_GRA }, // 11 + { "b_a8.rom", 0x04000, 0x8d618629, BRF_GRA }, // 12 + { "b_a9.rom", 0x04000, 0x7d7e2d55, BRF_GRA }, // 13 + { "b_a10.rom", 0x04000, 0xf12232fe, BRF_GRA }, // 14 + { "b_a11.rom", 0x04000, 0x8c09243d, BRF_GRA }, // 15 + + { "82s129.1j", 0x00100, 0x40590ac0, BRF_GRA }, // 16 PROMs + { "82s129.1h", 0x00100, 0xe542b363, BRF_GRA }, // 17 + { "82s129.1f", 0x00100, 0x75536fc8, BRF_GRA }, // 18 + { "82s123.5j", 0x00020, 0xc98f0651, BRF_GRA }, // 19 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 20 + + { "epl10p8.2j", 0x0002c, 0x8abc03bf, BRF_OPT }, // 21 PLDs + { "epl12p6.9k", 0x00034, 0x9b0bd6f8, BRF_OPT }, // 22 + { "epl12p6.9j", 0x00034, 0xdcae870d, BRF_OPT }, // 23 +}; + +STD_ROM_PICK(Legend); +STD_ROM_FN(Legend); + +static struct BurnRomInfo SonofphxRomDesc[] = { + { "5.f4", 0x02000, 0xe0d2c6cf, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "6.h4", 0x02000, 0x3a0d0336, BRF_ESS | BRF_PRG }, // 1 + { "7.j4", 0x02000, 0x57a8e900, BRF_ESS | BRF_PRG }, // 2 + + { "1.f2", 0x02000, 0xc485c621, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program + { "2.h2", 0x02000, 0xb3c6a886, BRF_ESS | BRF_PRG }, // 4 + { "3.j2", 0x02000, 0x197e314c, BRF_ESS | BRF_PRG }, // 5 + { "4.k2", 0x02000, 0x4f3695a1, BRF_ESS | BRF_PRG }, // 6 + + { "14.4a", 0x01000, 0xb3859b8b, BRF_GRA }, // 7 Characters + + { "15.9h", 0x02000, 0xc9213469, BRF_GRA }, // 8 Tiles + { "16.10h", 0x02000, 0x7de5d39e, BRF_GRA }, // 9 + { "17.11h", 0x02000, 0x0ba5f72c, BRF_GRA }, // 10 + + { "8.6a", 0x04000, 0x0e9f757e, BRF_GRA }, // 11 Sprites + { "9.7a", 0x04000, 0xf7d2e650, BRF_GRA }, // 12 + { "10.8a", 0x04000, 0xe717baf4, BRF_GRA }, // 13 + { "11.9a", 0x04000, 0x04b2250b, BRF_GRA }, // 14 + { "12.10a", 0x04000, 0xd110e140, BRF_GRA }, // 15 + { "13.11a", 0x04000, 0x8fdc713c, BRF_GRA }, // 16 + + { "b.1j", 0x00100, 0x3ea35431, BRF_GRA }, // 17 PROMs + { "g.1h", 0x00100, 0xacd7a69e, BRF_GRA }, // 18 + { "r.1f", 0x00100, 0xb7f48b41, BRF_GRA }, // 19 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 20 +}; + +STD_ROM_PICK(Sonofphx); +STD_ROM_FN(Sonofphx); + +static struct BurnRomInfo RepulseRomDesc[] = { + { "repulse.b5", 0x02000, 0xfb2b7c9d, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "repulse.b6", 0x02000, 0x99129918, BRF_ESS | BRF_PRG }, // 1 + { "7.j4", 0x02000, 0x57a8e900, BRF_ESS | BRF_PRG }, // 2 + + { "1.f2", 0x02000, 0xc485c621, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program + { "2.h2", 0x02000, 0xb3c6a886, BRF_ESS | BRF_PRG }, // 4 + { "3.j2", 0x02000, 0x197e314c, BRF_ESS | BRF_PRG }, // 5 + { "repulse.b4", 0x02000, 0x86b267f3, BRF_ESS | BRF_PRG }, // 6 + + { "repulse.a11", 0x01000, 0x8e1de90a, BRF_GRA }, // 7 Characters + + { "15.9h", 0x02000, 0xc9213469, BRF_GRA }, // 8 Tiles + { "16.10h", 0x02000, 0x7de5d39e, BRF_GRA }, // 9 + { "17.11h", 0x02000, 0x0ba5f72c, BRF_GRA }, // 10 + + { "8.6a", 0x04000, 0x0e9f757e, BRF_GRA }, // 11 Sprites + { "9.7a", 0x04000, 0xf7d2e650, BRF_GRA }, // 12 + { "10.8a", 0x04000, 0xe717baf4, BRF_GRA }, // 13 + { "11.9a", 0x04000, 0x04b2250b, BRF_GRA }, // 14 + { "12.10a", 0x04000, 0xd110e140, BRF_GRA }, // 15 + { "13.11a", 0x04000, 0x8fdc713c, BRF_GRA }, // 16 + + { "b.1j", 0x00100, 0x3ea35431, BRF_GRA }, // 17 PROMs + { "g.1h", 0x00100, 0xacd7a69e, BRF_GRA }, // 18 + { "r.1f", 0x00100, 0xb7f48b41, BRF_GRA }, // 19 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 20 +}; + +STD_ROM_PICK(Repulse); +STD_ROM_FN(Repulse); + +static struct BurnRomInfo Lstwar99RomDesc[] = { + { "1999.4f", 0x02000, 0xe3cfc09f, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "1999.4h", 0x02000, 0xfd58c6e1, BRF_ESS | BRF_PRG }, // 1 + { "7.j4", 0x02000, 0x57a8e900, BRF_ESS | BRF_PRG }, // 2 + + { "1.f2", 0x02000, 0xc485c621, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program + { "2.h2", 0x02000, 0xb3c6a886, BRF_ESS | BRF_PRG }, // 4 + { "3.j2", 0x02000, 0x197e314c, BRF_ESS | BRF_PRG }, // 5 + { "repulse.b4", 0x02000, 0x86b267f3, BRF_ESS | BRF_PRG }, // 6 + + { "1999.4a", 0x01000, 0x49a2383e, BRF_GRA }, // 7 Characters + + { "15.9h", 0x02000, 0xc9213469, BRF_GRA }, // 8 Tiles + { "16.10h", 0x02000, 0x7de5d39e, BRF_GRA }, // 9 + { "17.11h", 0x02000, 0x0ba5f72c, BRF_GRA }, // 10 + + { "8.6a", 0x04000, 0x0e9f757e, BRF_GRA }, // 11 Sprites + { "9.7a", 0x04000, 0xf7d2e650, BRF_GRA }, // 12 + { "10.8a", 0x04000, 0xe717baf4, BRF_GRA }, // 13 + { "11.9a", 0x04000, 0x04b2250b, BRF_GRA }, // 14 + { "12.10a", 0x04000, 0xd110e140, BRF_GRA }, // 15 + { "13.11a", 0x04000, 0x8fdc713c, BRF_GRA }, // 16 + + { "b.1j", 0x00100, 0x3ea35431, BRF_GRA }, // 17 PROMs + { "g.1h", 0x00100, 0xacd7a69e, BRF_GRA }, // 18 + { "r.1f", 0x00100, 0xb7f48b41, BRF_GRA }, // 19 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 20 +}; + +STD_ROM_PICK(Lstwar99); +STD_ROM_FN(Lstwar99); + +static struct BurnRomInfo Lstwra99RomDesc[] = { + { "4f.bin", 0x02000, 0xefe2908d, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "4h.bin", 0x02000, 0x5b79c342, BRF_ESS | BRF_PRG }, // 1 + { "4j.bin", 0x02000, 0xd2a62c1b, BRF_ESS | BRF_PRG }, // 2 + + { "2f.bin", 0x02000, 0xcb9d8291, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program + { "2h.bin", 0x02000, 0x24dbddc3, BRF_ESS | BRF_PRG }, // 4 + { "2j.bin", 0x02000, 0x16879c4c, BRF_ESS | BRF_PRG }, // 5 + { "repulse.b4", 0x02000, 0x86b267f3, BRF_ESS | BRF_PRG }, // 6 + + { "1999.4a", 0x01000, 0x49a2383e, BRF_GRA }, // 7 Characters + + { "9h.bin", 0x02000, 0x59993c27, BRF_GRA }, // 8 Tiles + { "10h.bin", 0x02000, 0xdfbf0280, BRF_GRA }, // 9 + { "11h.bin", 0x02000, 0xe4f29fc0, BRF_GRA }, // 10 + + { "6a.bin", 0x04000, 0x98d44410, BRF_GRA }, // 11 Sprites + { "7a.bin", 0x04000, 0x4c54d281, BRF_GRA }, // 12 + { "8a.bin", 0x04000, 0x81018101, BRF_GRA }, // 13 + { "9a.bin", 0x04000, 0x347b91fd, BRF_GRA }, // 14 + { "10a.bin", 0x04000, 0xf07de4fa, BRF_GRA }, // 15 + { "11a.bin", 0x04000, 0x34a04f48, BRF_GRA }, // 16 + + { "b.1j", 0x00100, 0x3ea35431, BRF_GRA }, // 17 PROMs + { "g.1h", 0x00100, 0xacd7a69e, BRF_GRA }, // 18 + { "r.1f", 0x00100, 0xb7f48b41, BRF_GRA }, // 19 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 20 +}; + +STD_ROM_PICK(Lstwra99); +STD_ROM_FN(Lstwra99); + +static struct BurnRomInfo Lstwrk99RomDesc[] = { + { "1999.4f", 0x02000, 0xe3cfc09f, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "1999.4h", 0x02000, 0xfd58c6e1, BRF_ESS | BRF_PRG }, // 1 + { "7.j4", 0x02000, 0x57a8e900, BRF_ESS | BRF_PRG }, // 2 + + { "1.f2", 0x02000, 0xc485c621, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program + { "2.h2", 0x02000, 0xb3c6a886, BRF_ESS | BRF_PRG }, // 4 + { "3.j2", 0x02000, 0x197e314c, BRF_ESS | BRF_PRG }, // 5 + { "repulse.b4", 0x02000, 0x86b267f3, BRF_ESS | BRF_PRG }, // 6 + + { "1999-14.rom", 0x01000, 0xb4995072, BRF_GRA }, // 7 Characters + + { "15.9h", 0x02000, 0xc9213469, BRF_GRA }, // 8 Tiles + { "16.10h", 0x02000, 0x7de5d39e, BRF_GRA }, // 9 + { "17.11h", 0x02000, 0x0ba5f72c, BRF_GRA }, // 10 + + { "8.6a", 0x04000, 0x0e9f757e, BRF_GRA }, // 11 Sprites + { "9.7a", 0x04000, 0xf7d2e650, BRF_GRA }, // 12 + { "10.8a", 0x04000, 0xe717baf4, BRF_GRA }, // 13 + { "11.9a", 0x04000, 0x04b2250b, BRF_GRA }, // 14 + { "12.10a", 0x04000, 0xd110e140, BRF_GRA }, // 15 + { "13.11a", 0x04000, 0x8fdc713c, BRF_GRA }, // 16 + + { "b.1j", 0x00100, 0x3ea35431, BRF_GRA }, // 17 PROMs + { "g.1h", 0x00100, 0xacd7a69e, BRF_GRA }, // 18 + { "r.1f", 0x00100, 0xb7f48b41, BRF_GRA }, // 19 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 20 + { "1999-00.rom", 0x00800, 0x0c0c449f, BRF_GRA }, // 21 +}; + +STD_ROM_PICK(Lstwrk99); +STD_ROM_FN(Lstwrk99); + +static struct BurnRomInfo SrdmissnRomDesc[] = { + { "5.t2", 0x04000, 0xa682b48c, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "7.t3", 0x04000, 0x1719c58c, BRF_ESS | BRF_PRG }, // 1 + + { "1.t7", 0x04000, 0xdc48595e, BRF_ESS | BRF_PRG }, // 2 Z80 #2 Program + { "3.t8", 0x04000, 0x216be1e8, BRF_ESS | BRF_PRG }, // 3 + + { "15.4a", 0x01000, 0x4961f7fd, BRF_GRA }, // 4 Characters + + { "17.9h", 0x02000, 0x41211458, BRF_GRA }, // 5 Tiles + { "18.10h", 0x02000, 0x740eccd4, BRF_GRA }, // 6 + { "16.11h", 0x02000, 0xc1f4a5db, BRF_GRA }, // 7 + + { "14.6a", 0x04000, 0x3d4c0447, BRF_GRA }, // 8 Sprites + { "13.7a", 0x04000, 0x22414a67, BRF_GRA }, // 9 + { "12.8a", 0x04000, 0x61e34283, BRF_GRA }, // 10 + { "11.9a", 0x04000, 0xbbbaffef, BRF_GRA }, // 11 + { "10.10a", 0x04000, 0xde564f97, BRF_GRA }, // 12 + { "9.11a", 0x04000, 0x890dc815, BRF_GRA }, // 13 + + { "mr.1j", 0x00100, 0x110a436e, BRF_GRA }, // 14 PROMs + { "mg.1h", 0x00100, 0x0fbfd9f0, BRF_GRA }, // 15 + { "mb.1f", 0x00100, 0xa342890c, BRF_GRA }, // 16 + { "m2.5j", 0x00020, 0x190a55ad, BRF_GRA }, // 17 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 18 +}; + +STD_ROM_PICK(Srdmissn); +STD_ROM_FN(Srdmissn); + +static struct BurnRomInfo FxRomDesc[] = { + { "fx.01", 0x04000, 0xb651754b, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "fx.02", 0x04000, 0xf3d2dcc1, BRF_ESS | BRF_PRG }, // 1 + + { "fx.03", 0x04000, 0x8907df6b, BRF_ESS | BRF_PRG }, // 2 Z80 #2 Program + { "fx.04", 0x04000, 0xc665834f, BRF_ESS | BRF_PRG }, // 3 + + { "fx.05", 0x01000, 0x4a504286, BRF_GRA }, // 4 Characters + + { "17.9h", 0x02000, 0x41211458, BRF_GRA }, // 5 Tiles + { "18.10h", 0x02000, 0x740eccd4, BRF_GRA }, // 6 + { "16.11h", 0x02000, 0xc1f4a5db, BRF_GRA }, // 7 + + { "14.6a", 0x04000, 0x3d4c0447, BRF_GRA }, // 8 Sprites + { "13.7a", 0x04000, 0x22414a67, BRF_GRA }, // 9 + { "12.8a", 0x04000, 0x61e34283, BRF_GRA }, // 10 + { "11.9a", 0x04000, 0xbbbaffef, BRF_GRA }, // 11 + { "10.10a", 0x04000, 0xde564f97, BRF_GRA }, // 12 + { "9.11a", 0x04000, 0x890dc815, BRF_GRA }, // 13 + + { "mr.1j", 0x00100, 0x110a436e, BRF_GRA }, // 14 PROMs + { "mg.1h", 0x00100, 0x0fbfd9f0, BRF_GRA }, // 15 + { "mb.1f", 0x00100, 0xa342890c, BRF_GRA }, // 16 + { "m2.5j", 0x00020, 0x190a55ad, BRF_GRA }, // 17 + { "m1.2c", 0x00020, 0x83a39201, BRF_GRA }, // 18 +}; + +STD_ROM_PICK(Fx); +STD_ROM_FN(Fx); + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + KyugoZ80Rom1 = Next; Next += 0x08000; + KyugoZ80Rom2 = Next; Next += 0x08000; + KyugoPromRed = Next; Next += 0x00100; + KyugoPromGreen = Next; Next += 0x00100; + KyugoPromBlue = Next; Next += 0x00100; + KyugoPromCharLookup = Next; Next += 0x00020; + + RamStart = Next; + + KyugoSharedZ80Ram = Next; Next += 0x00800; + KyugoZ80Ram2 = Next; Next += 0x00800; + KyugoSprite1Ram = Next; Next += 0x00800; + KyugoSprite2Ram = Next; Next += 0x00800; + KyugoFgVideoRam = Next; Next += 0x00800; + KyugoBgVideoRam = Next; Next += 0x00800; + KyugoBgAttrRam = Next; Next += 0x00800; + + RamEnd = Next; + + KyugoChars = Next; Next += 0x100 * 8 * 8; + KyugoTiles = Next; Next += 0x400 * 8 * 8; + KyugoSprites = Next; Next += 0x400 * 16 * 16; + pFMBuffer = (short*)Next; Next += nBurnSoundLen * 6 * sizeof(short); + KyugoPalette = (unsigned int*)Next; Next += 256 * sizeof(unsigned int); + + MemEnd = Next; + + return 0; +} + +static int KyugoDoReset() +{ + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + } + + for (int i = 0; i < 2; i++) { + AY8910Reset(i); + } + + KyugoIRQEnable = 0; + KyugoSubCPUEnable = 0; + KyugoFgColour = 0; + KyugoBgPaletteBank = 0; + KyugoBgScrollXHi = 0; + KyugoBgScrollXLo = 0; + KyugoBgScrollY = 0; + KyugoFlipScreen = 0; + + return 0; +} + +unsigned char __fastcall KyugoRead1(unsigned short a) +{ + if (a >= 0x9800 && a <= 0x9fff) { + return KyugoSprite2Ram[a - 0x9800] | 0xf0; + } + + switch (a) { + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Read => %04X\n"), a); + } + } + + return 0; +} + +void __fastcall KyugoWrite1(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xa800: { + KyugoBgScrollXLo = d; + return; + } + + case 0xb000: { + KyugoBgScrollXHi = d & 1; + KyugoFgColour = (d & 0x20) >> 5; + KyugoBgPaletteBank = (d & 0x40) >> 6; + return; + } + + case 0xb800: { + KyugoBgScrollY = d; + return; + } + + + case 0xe000: { + // watchdog write + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Write => %04X, %02X\n"), a, d); + } + } +} + +void __fastcall FlashgalPortWrite1(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + case 0x40: { + KyugoIRQEnable = d & 1; + return; + } + + case 0x41: { + KyugoFlipScreen = d & 1; + return; + } + + case 0x42: { + KyugoSubCPUEnable = d & 1; + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Port Write => %02X, %02X\n"), a, d); + } + } +} + +void __fastcall FlashglaPortWrite1(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + case 0xc0: { + KyugoIRQEnable = d & 1; + return; + } + + case 0xc1: { + KyugoFlipScreen = d & 1; + return; + } + + case 0xc2: { + KyugoSubCPUEnable = d & 1; + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Port Write => %02X, %02X\n"), a, d); + } + } +} + +void __fastcall GyrodinePortWrite1(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + case 0x00: { + KyugoIRQEnable = d & 1; + return; + } + + case 0x01: { + KyugoFlipScreen = d & 1; + return; + } + + case 0x02: { + KyugoSubCPUEnable = d & 1; + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Port Write => %02X, %02X\n"), a, d); + } + } +} + +void __fastcall SrdmissnPortWrite1(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + case 0x08: { + KyugoIRQEnable = d & 1; + return; + } + + case 0x09: { + KyugoFlipScreen = d & 1; + return; + } + + case 0x0a: { + KyugoSubCPUEnable = d & 1; + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Port Write => %02X, %02X\n"), a, d); + } + } +} + +unsigned char __fastcall FlashgalRead2(unsigned short a) +{ + switch (a) { + case 0xc000: { + return KyugoInput[2]; + } + + case 0xc040: { + return KyugoInput[1]; + } + + case 0xc080: { + return KyugoInput[0]; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Read => %04X\n"), a); + } + } + + return 0; +} + +unsigned char __fastcall FlashglaRead2(unsigned short a) +{ + switch (a) { + case 0xc040: { + return KyugoInput[0]; + } + + case 0xc080: { + return KyugoInput[1]; + } + + case 0xc0c0: { + return KyugoInput[2]; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Read => %04X\n"), a); + } + } + + return 0; +} + +unsigned char __fastcall GyrodineRead2(unsigned short a) +{ + switch (a) { + case 0x8000: { + return KyugoInput[2]; + } + + case 0x8040: { + return KyugoInput[1]; + } + + case 0x8080: { + return KyugoInput[0]; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Read => %04X\n"), a); + } + } + + return 0; +} + +unsigned char __fastcall SrdmissnRead2(unsigned short a) +{ + switch (a) { + case 0xf400: { + return KyugoInput[0]; + } + + case 0xf401: { + return KyugoInput[1]; + } + + case 0xf402: { + return KyugoInput[2]; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Read => %04X\n"), a); + } + } + + return 0; +} + +unsigned char __fastcall LegendRead2(unsigned short a) +{ + switch (a) { + case 0xf800: { + return KyugoInput[0]; + } + + case 0xf801: { + return KyugoInput[1]; + } + + case 0xf802: { + return KyugoInput[2]; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Read => %04X\n"), a); + } + } + + return 0; +} + +void __fastcall KyugoWrite2(unsigned short a, unsigned char d) +{ + switch (a) { + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Write => %04X, %02X\n"), a, d); + } + } +} + +unsigned char __fastcall KyugoPortRead2(unsigned short a) +{ + a &= 0xff; + + switch (a) { + case 0x02: { + return AY8910Read(0); + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Port Read => %02X\n"), a); + } + } + + return 0; +} + +unsigned char __fastcall FlashglaPortRead2(unsigned short a) +{ + a &= 0xff; + + switch (a) { + case 0x42: { + return AY8910Read(0); + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Port Read => %02X\n"), a); + } + } + + return 0; +} + +unsigned char __fastcall SrdmissnPortRead2(unsigned short a) +{ + a &= 0xff; + + switch (a) { + case 0x82: { + return AY8910Read(0); + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Port Read => %02X\n"), a); + } + } + + return 0; +} + +void __fastcall FlashgalPortWrite2(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + case 0x00: { + AY8910Write(0, 0, d); + return; + } + + case 0x01: { + AY8910Write(0, 1, d); + return; + } + + case 0x40: { + AY8910Write(1, 0, d); + return; + } + + case 0x41: { + AY8910Write(1, 1, d); + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Port Write => %02X, %02X\n"), a, d); + } + } +} + +void __fastcall FlashglaPortWrite2(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + case 0x40: { + AY8910Write(0, 0, d); + return; + } + + case 0x41: { + AY8910Write(0, 1, d); + return; + } + + case 0x80: { + AY8910Write(1, 0, d); + return; + } + + case 0x81: { + AY8910Write(1, 1, d); + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Port Write => %02X, %02X\n"), a, d); + } + } +} + +void __fastcall GyrodinePortWrite2(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + case 0x00: { + AY8910Write(0, 0, d); + return; + } + + case 0x01: { + AY8910Write(0, 1, d); + return; + } + + case 0xc0: { + AY8910Write(1, 0, d); + return; + } + + case 0xc1: { + AY8910Write(1, 1, d); + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Port Write => %02X, %02X\n"), a, d); + } + } +} + +void __fastcall SrdmissnPortWrite2(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + case 0x80: { + AY8910Write(0, 0, d); + return; + } + + case 0x81: { + AY8910Write(0, 1, d); + return; + } + + case 0x84: { + AY8910Write(1, 0, d); + return; + } + + case 0x85: { + AY8910Write(1, 1, d); + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #2 Port Write => %02X, %02X\n"), a, d); + } + } +} + +static int CharPlaneOffsets[2] = { 0, 4 }; +static int CharXOffsets[8] = { 0, 1, 2, 3, 64, 65, 66, 67 }; +static int CharYOffsets[8] = { 0, 8, 16, 24, 32, 40, 48, 56 }; +static int TilePlaneOffsets[3] = { 0, 0x10000, 0x20000 }; +static int TileXOffsets[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +static int TileYOffsets[8] = { 0, 8, 16, 24, 32, 40, 48, 56 }; +static int SpritePlaneOffsets[3] = { 0, 0x40000, 0x80000 }; +static int SpriteXOffsets[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 64, 65, 66, 67, 68, 69, 70, 71 }; +static int SpriteYOffsets[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 128, 136, 144, 152, 160, 168, 176, 184 }; + +static unsigned char KyugoDip0Read(unsigned int /*a*/) +{ + return KyugoDip[0]; +} + +static unsigned char KyugoDip1Read(unsigned int /*a*/) +{ + return KyugoDip[1]; +} + +static int KyugoInit() +{ + int nRet = 0, nLen, i; + + KyugoNumZ80Rom1 = 4; + KyugoNumZ80Rom2 = 4; + KyugoNumSpriteRom = 6; + KyugoSizeZ80Rom1 = 0x2000; + KyugoSizeZ80Rom2 = 0x2000; + KyugoSizeSpriteRom = 0x4000; + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "airwolf") || !strcmp(BurnDrvGetTextA(DRV_NAME), "airwolfa")) { + KyugoNumZ80Rom1 = 1; + KyugoNumZ80Rom2 = 1; + KyugoNumSpriteRom = 3; + KyugoSizeZ80Rom1 = 0x8000; + KyugoSizeZ80Rom2 = 0x8000; + KyugoSizeSpriteRom = 0x8000; + } + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "gyrodine") || !strcmp(BurnDrvGetTextA(DRV_NAME), "gyrodinc") || !strcmp(BurnDrvGetTextA(DRV_NAME), "buzzard")) KyugoNumZ80Rom2 = 1; + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "legend")) { + KyugoNumZ80Rom1 = 2; + KyugoNumZ80Rom2 = 4; + KyugoSizeZ80Rom1 = 0x4000; + KyugoSizeZ80Rom2 = 0x2000; + } + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "sonofphx") || !strcmp(BurnDrvGetTextA(DRV_NAME), "repulse") || !strcmp(BurnDrvGetTextA(DRV_NAME), "99lstwar") || !strcmp(BurnDrvGetTextA(DRV_NAME), "99lstwra") || !strcmp(BurnDrvGetTextA(DRV_NAME), "99lstwrk")) KyugoNumZ80Rom1 = 3; + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "skywolf") || !strcmp(BurnDrvGetTextA(DRV_NAME), "srdmissn") || !strcmp(BurnDrvGetTextA(DRV_NAME), "fx")) { + KyugoNumZ80Rom1 = 2; + KyugoNumZ80Rom2 = 2; + KyugoSizeZ80Rom1 = 0x4000; + KyugoSizeZ80Rom2 = 0x4000; + } + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "skywolf2")) { + KyugoNumZ80Rom1 = 1; + KyugoNumZ80Rom2 = 2; + KyugoSizeZ80Rom1 = 0x8000; + KyugoSizeZ80Rom2 = 0x4000; + } + + // Allocate and Blank all required memory + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + KyugoTempRom = (unsigned char *)malloc(0x18000); + + // Load Z80 #1 Program Roms + for (i = 0; i < KyugoNumZ80Rom1; i++) { + nRet = BurnLoadRom(KyugoZ80Rom1 + (KyugoSizeZ80Rom1 * i), i, 1); if (nRet != 0) return 1; + } + + // Load Z80 #2 Program Roms + for (i = KyugoNumZ80Rom1; i < KyugoNumZ80Rom2 + KyugoNumZ80Rom1; i++) { + nRet = BurnLoadRom(KyugoZ80Rom2 + (KyugoSizeZ80Rom2 * (i - KyugoNumZ80Rom1)), i, 1); if (nRet != 0) return 1; + } + + // Load and decode the chars + nRet = BurnLoadRom(KyugoTempRom, KyugoNumZ80Rom2 + KyugoNumZ80Rom1 + 0, 1); if (nRet != 0) return 1; + GfxDecode(0x100, 2, 8, 8, CharPlaneOffsets, CharXOffsets, CharYOffsets, 0x80, KyugoTempRom, KyugoChars); + + // Load and decode the tiles + memset(KyugoTempRom, 0, 0x18000); + nRet = BurnLoadRom(KyugoTempRom + 0x00000, KyugoNumZ80Rom2 + KyugoNumZ80Rom1 + 1, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(KyugoTempRom + 0x02000, KyugoNumZ80Rom2 + KyugoNumZ80Rom1 + 2, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(KyugoTempRom + 0x04000, KyugoNumZ80Rom2 + KyugoNumZ80Rom1 + 3, 1); if (nRet != 0) return 1; + GfxDecode(0x400, 3, 8, 8, TilePlaneOffsets, TileXOffsets, TileYOffsets, 0x40, KyugoTempRom, KyugoTiles); + + // Load and decode the sprites + memset(KyugoTempRom, 0, 0x18000); + for (i = KyugoNumZ80Rom2 + KyugoNumZ80Rom1 + 4; i < KyugoNumSpriteRom + KyugoNumZ80Rom2 + KyugoNumZ80Rom1 + 4; i++) { + nRet = BurnLoadRom(KyugoTempRom + (KyugoSizeSpriteRom * (i - KyugoNumZ80Rom2 - KyugoNumZ80Rom1 - 4)), i, 1); if (nRet != 0) return 1; + } + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "airwolf") || !strcmp(BurnDrvGetTextA(DRV_NAME), "airwolfa")) { + unsigned char *Temp = (unsigned char*)malloc(0x18000); + memcpy(Temp, KyugoTempRom, 0x18000); + memcpy(KyugoTempRom + 0x00000, Temp + 0x00000, 0x2000); + memcpy(KyugoTempRom + 0x04000, Temp + 0x02000, 0x2000); + memcpy(KyugoTempRom + 0x02000, Temp + 0x04000, 0x2000); + memcpy(KyugoTempRom + 0x06000, Temp + 0x06000, 0x2000); + memcpy(KyugoTempRom + 0x08000, Temp + 0x08000, 0x2000); + memcpy(KyugoTempRom + 0x0c000, Temp + 0x0a000, 0x2000); + memcpy(KyugoTempRom + 0x0a000, Temp + 0x0c000, 0x2000); + memcpy(KyugoTempRom + 0x0e000, Temp + 0x0e000, 0x2000); + memcpy(KyugoTempRom + 0x10000, Temp + 0x10000, 0x2000); + memcpy(KyugoTempRom + 0x14000, Temp + 0x12000, 0x2000); + memcpy(KyugoTempRom + 0x12000, Temp + 0x14000, 0x2000); + memcpy(KyugoTempRom + 0x16000, Temp + 0x16000, 0x2000); + free(Temp); + } + GfxDecode(0x400, 3, 16, 16, SpritePlaneOffsets, SpriteXOffsets, SpriteYOffsets, 0x100, KyugoTempRom, KyugoSprites); + + // Load the PROMs + nRet = BurnLoadRom(KyugoPromRed, KyugoNumSpriteRom + KyugoNumZ80Rom2 + KyugoNumZ80Rom1 + 4, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(KyugoPromGreen, KyugoNumSpriteRom + KyugoNumZ80Rom2 + KyugoNumZ80Rom1 + 5, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(KyugoPromBlue, KyugoNumSpriteRom + KyugoNumZ80Rom2 + KyugoNumZ80Rom1 + 6, 1); if (nRet != 0) return 1; + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "flashgal") || !strcmp(BurnDrvGetTextA(DRV_NAME), "flashgla") || !strcmp(BurnDrvGetTextA(DRV_NAME), "gyrodine") || !strcmp(BurnDrvGetTextA(DRV_NAME), "gyrodinc") || !strcmp(BurnDrvGetTextA(DRV_NAME), "buzzard") || !strcmp(BurnDrvGetTextA(DRV_NAME), "legend") || !strcmp(BurnDrvGetTextA(DRV_NAME), "srdmissn") || !strcmp(BurnDrvGetTextA(DRV_NAME), "fx")) { + nRet = BurnLoadRom(KyugoPromCharLookup, KyugoNumSpriteRom + KyugoNumZ80Rom2 + KyugoNumZ80Rom1 + 7, 1); if (nRet != 0) return 1; + } + + free(KyugoTempRom); + + // Setup the Z80 emulation + ZetInit(2); + ZetOpen(0); + ZetSetReadHandler(KyugoRead1); + ZetSetWriteHandler(KyugoWrite1); + ZetMapArea(0x0000, 0x7fff, 0, KyugoZ80Rom1 ); + ZetMapArea(0x0000, 0x7fff, 2, KyugoZ80Rom1 ); + ZetMapArea(0x8000, 0x87ff, 0, KyugoBgVideoRam ); + ZetMapArea(0x8000, 0x87ff, 1, KyugoBgVideoRam ); + ZetMapArea(0x8000, 0x87ff, 2, KyugoBgVideoRam ); + ZetMapArea(0x8800, 0x8fff, 0, KyugoBgAttrRam ); + ZetMapArea(0x8800, 0x8fff, 1, KyugoBgAttrRam ); + ZetMapArea(0x8800, 0x8fff, 2, KyugoBgAttrRam ); + ZetMapArea(0x9000, 0x97ff, 0, KyugoFgVideoRam ); + ZetMapArea(0x9000, 0x97ff, 1, KyugoFgVideoRam ); + ZetMapArea(0x9000, 0x97ff, 2, KyugoFgVideoRam ); + ZetMapArea(0x9800, 0x9fff, 1, KyugoSprite2Ram ); + ZetMapArea(0x9800, 0x9fff, 2, KyugoSprite2Ram ); + ZetMapArea(0xa000, 0xa7ff, 0, KyugoSprite1Ram ); + ZetMapArea(0xa000, 0xa7ff, 1, KyugoSprite1Ram ); + ZetMapArea(0xa000, 0xa7ff, 2, KyugoSprite1Ram ); + ZetMapArea(0xf000, 0xf7ff, 0, KyugoSharedZ80Ram ); + ZetMapArea(0xf000, 0xf7ff, 1, KyugoSharedZ80Ram ); + ZetMapArea(0xf000, 0xf7ff, 2, KyugoSharedZ80Ram ); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetSetWriteHandler(KyugoWrite2); + ZetSetInHandler(KyugoPortRead2); + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "gyrodine") || !strcmp(BurnDrvGetTextA(DRV_NAME), "gyrodinc") || !strcmp(BurnDrvGetTextA(DRV_NAME), "buzzard")) { + ZetMapArea(0x0000, 0x1fff, 0, KyugoZ80Rom2 ); + ZetMapArea(0x0000, 0x1fff, 2, KyugoZ80Rom2 ); + } else { + ZetMapArea(0x0000, 0x7fff, 0, KyugoZ80Rom2 ); + ZetMapArea(0x0000, 0x7fff, 2, KyugoZ80Rom2 ); + } + ZetMemEnd(); + ZetClose(); + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "airwolf") || !strcmp(BurnDrvGetTextA(DRV_NAME), "airwolfa") || !strcmp(BurnDrvGetTextA(DRV_NAME), "skywolf") || !strcmp(BurnDrvGetTextA(DRV_NAME), "skywolf2")) { + ZetOpen(0); + ZetSetOutHandler(SrdmissnPortWrite1); + ZetMapArea(0xe000, 0xe7ff, 0, KyugoSharedZ80Ram ); + ZetMapArea(0xe000, 0xe7ff, 1, KyugoSharedZ80Ram ); + ZetMapArea(0xe000, 0xe7ff, 2, KyugoSharedZ80Ram ); + ZetClose(); + + ZetOpen(1); + ZetSetReadHandler(SrdmissnRead2); + ZetSetInHandler(SrdmissnPortRead2); + ZetSetOutHandler(SrdmissnPortWrite2); + ZetMapArea(0x8000, 0x87ff, 0, KyugoSharedZ80Ram ); + ZetMapArea(0x8000, 0x87ff, 1, KyugoSharedZ80Ram ); + ZetMapArea(0x8000, 0x87ff, 2, KyugoSharedZ80Ram ); + ZetClose(); + } + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "flashgal")) { + ZetOpen(0); + ZetSetOutHandler(FlashgalPortWrite1); + ZetClose(); + + ZetOpen(1); + ZetSetReadHandler(FlashgalRead2); + ZetSetOutHandler(FlashgalPortWrite2); + ZetMapArea(0xa000, 0xa7ff, 0, KyugoSharedZ80Ram ); + ZetMapArea(0xa000, 0xa7ff, 1, KyugoSharedZ80Ram ); + ZetMapArea(0xa000, 0xa7ff, 2, KyugoSharedZ80Ram ); + ZetClose(); + } + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "flashgla")) { + ZetOpen(0); + ZetSetOutHandler(FlashglaPortWrite1); + ZetClose(); + + ZetOpen(1); + ZetSetReadHandler(FlashglaRead2); + ZetSetInHandler(FlashglaPortRead2); + ZetSetOutHandler(FlashglaPortWrite2); + ZetMapArea(0xe000, 0xe7ff, 0, KyugoSharedZ80Ram ); + ZetMapArea(0xe000, 0xe7ff, 1, KyugoSharedZ80Ram ); + ZetMapArea(0xe000, 0xe7ff, 2, KyugoSharedZ80Ram ); + ZetClose(); + } + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "gyrodine") || !strcmp(BurnDrvGetTextA(DRV_NAME), "gyrodinc") || !strcmp(BurnDrvGetTextA(DRV_NAME), "buzzard")) { + ZetOpen(0); + ZetSetOutHandler(GyrodinePortWrite1); + ZetClose(); + + ZetOpen(1); + ZetSetReadHandler(GyrodineRead2); + ZetSetOutHandler(GyrodinePortWrite2); + ZetMapArea(0x4000, 0x47ff, 0, KyugoSharedZ80Ram ); + ZetMapArea(0x4000, 0x47ff, 1, KyugoSharedZ80Ram ); + ZetMapArea(0x4000, 0x47ff, 2, KyugoSharedZ80Ram ); + ZetClose(); + } + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "legend")) { + ZetOpen(0); + ZetSetOutHandler(GyrodinePortWrite1); + ZetClose(); + + ZetOpen(1); + ZetSetReadHandler(LegendRead2); + ZetSetInHandler(SrdmissnPortRead2); + ZetSetOutHandler(SrdmissnPortWrite2); + ZetMapArea(0xc000, 0xc7ff, 0, KyugoSharedZ80Ram ); + ZetMapArea(0xc000, 0xc7ff, 1, KyugoSharedZ80Ram ); + ZetMapArea(0xc000, 0xc7ff, 2, KyugoSharedZ80Ram ); + ZetClose(); + } + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "sonofphx") || !strcmp(BurnDrvGetTextA(DRV_NAME), "repulse") || !strcmp(BurnDrvGetTextA(DRV_NAME), "99lstwar") || !strcmp(BurnDrvGetTextA(DRV_NAME), "99lstwra") || !strcmp(BurnDrvGetTextA(DRV_NAME), "99lstwrk")) { + ZetOpen(0); + ZetSetOutHandler(GyrodinePortWrite1); + ZetClose(); + + ZetOpen(1); + ZetSetReadHandler(FlashgalRead2); + ZetSetOutHandler(FlashgalPortWrite2); + ZetMapArea(0xa000, 0xa7ff, 0, KyugoSharedZ80Ram ); + ZetMapArea(0xa000, 0xa7ff, 1, KyugoSharedZ80Ram ); + ZetMapArea(0xa000, 0xa7ff, 2, KyugoSharedZ80Ram ); + ZetClose(); + } + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "srdmissn") || !strcmp(BurnDrvGetTextA(DRV_NAME), "fx")) { + ZetOpen(0); + ZetSetOutHandler(SrdmissnPortWrite1); + ZetMapArea(0xe000, 0xe7ff, 0, KyugoSharedZ80Ram ); + ZetMapArea(0xe000, 0xe7ff, 1, KyugoSharedZ80Ram ); + ZetMapArea(0xe000, 0xe7ff, 2, KyugoSharedZ80Ram ); + ZetClose(); + + ZetOpen(1); + ZetSetReadHandler(SrdmissnRead2); + ZetSetInHandler(SrdmissnPortRead2); + ZetSetOutHandler(SrdmissnPortWrite2); + ZetMapArea(0x8000, 0x87ff, 0, KyugoSharedZ80Ram ); + ZetMapArea(0x8000, 0x87ff, 1, KyugoSharedZ80Ram ); + ZetMapArea(0x8000, 0x87ff, 2, KyugoSharedZ80Ram ); + ZetMapArea(0x8800, 0x8fff, 0, KyugoZ80Ram2 ); + ZetMapArea(0x8800, 0x8fff, 1, KyugoZ80Ram2 ); + ZetMapArea(0x8800, 0x8fff, 2, KyugoZ80Ram2 ); + ZetClose(); + } + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + pAY8910Buffer[3] = pFMBuffer + nBurnSoundLen * 3; + pAY8910Buffer[4] = pFMBuffer + nBurnSoundLen * 4; + pAY8910Buffer[5] = pFMBuffer + nBurnSoundLen * 5; + + AY8910Init(0, 18432000 / 12, nBurnSoundRate, &KyugoDip0Read, &KyugoDip1Read, NULL, NULL); + AY8910Init(1, 18432000 / 12, nBurnSoundRate, NULL, NULL, NULL, NULL); + + + GenericTilesInit(); + + // Reset the driver + KyugoDoReset(); + + return 0; +} + +static int KyugoExit() +{ + ZetExit(); + + for (int i = 0; i < 2; i++) { + AY8910Exit(i); + } + + GenericTilesExit(); + + KyugoIRQEnable = 0; + KyugoSubCPUEnable = 0; + KyugoFgColour = 0; + KyugoBgPaletteBank = 0; + KyugoBgScrollXHi = 0; + KyugoBgScrollXLo = 0; + KyugoBgScrollY = 0; + KyugoFlipScreen = 0; + + KyugoNumZ80Rom1 = 0; + KyugoNumZ80Rom2 = 0; + KyugoNumSpriteRom = 0; + KyugoSizeZ80Rom1 = 0; + KyugoSizeZ80Rom2 = 0; + KyugoSizeSpriteRom = 0; + + free(Mem); + Mem = NULL; + + return 0; +} + +static void KyugoCalcPalette() +{ + int i; + + for (i = 0; i < 256; i++) { + int bit0, bit1, bit2, bit3, r, g, b; + + bit0 = (KyugoPromRed[i] >> 0) & 0x01; + bit1 = (KyugoPromRed[i] >> 1) & 0x01; + bit2 = (KyugoPromRed[i] >> 2) & 0x01; + bit3 = (KyugoPromRed[i] >> 3) & 0x01; + r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (KyugoPromGreen[i] >> 0) & 0x01; + bit1 = (KyugoPromGreen[i] >> 1) & 0x01; + bit2 = (KyugoPromGreen[i] >> 2) & 0x01; + bit3 = (KyugoPromGreen[i] >> 3) & 0x01; + g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (KyugoPromBlue[i] >> 0) & 0x01; + bit1 = (KyugoPromBlue[i] >> 1) & 0x01; + bit2 = (KyugoPromBlue[i] >> 2) & 0x01; + bit3 = (KyugoPromBlue[i] >> 3) & 0x01; + b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + KyugoPalette[i] = BurnHighCol(r, g, b, 0); + } +} + +static void KyugoRenderBgLayer() +{ + int mx, my, Code, Attr, Colour, x, y, TileIndex = 0, xScroll, Flip, xFlip, yFlip; + + xScroll = KyugoBgScrollXLo + (KyugoBgScrollXHi * 256); + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 64; mx++) { + Code = KyugoBgVideoRam[TileIndex]; + Attr = KyugoBgAttrRam[TileIndex]; + Code = Code | ((Attr & 0x03) << 8); + Code &= 0x3ff; + Colour = (Attr >> 4) | (KyugoBgPaletteBank << 4); + Flip = (Attr & 0x0c) >> 2; + xFlip = (Flip >> 0) & 0x01; + yFlip = (Flip >> 1) & 0x01; + + x = 8 * mx; + y = 8 * my; + + if (KyugoFlipScreen) { + xFlip = !xFlip; + yFlip = !yFlip; + y = 248 - y; + x = 504 - x; + x -= xScroll; + y += KyugoBgScrollY; + } else { + x -= xScroll; + y -= KyugoBgScrollY; + } + + if (x < -8) x += 512; + if (y < -8) y += 256; + if (y > 264) y -= 256; + + x -= 32; + y -= 16; + + if (x > 8 && x < 280 && y > 8 && y < 216) { + if (xFlip) { + if (yFlip) { + Render8x8Tile_FlipXY(pTransDraw, Code, x, y, Colour, 3, 0, KyugoTiles); + } else { + Render8x8Tile_FlipX(pTransDraw, Code, x, y, Colour, 3, 0, KyugoTiles); + } + } else { + if (yFlip) { + Render8x8Tile_FlipY(pTransDraw, Code, x, y, Colour, 3, 0, KyugoTiles); + } else { + Render8x8Tile(pTransDraw, Code, x, y, Colour, 3, 0, KyugoTiles); + } + } + } else { + if (xFlip) { + if (yFlip) { + Render8x8Tile_FlipXY_Clip(pTransDraw, Code, x, y, Colour, 3, 0, KyugoTiles); + } else { + Render8x8Tile_FlipX_Clip(pTransDraw, Code, x, y, Colour, 3, 0, KyugoTiles); + } + } else { + if (yFlip) { + Render8x8Tile_FlipY_Clip(pTransDraw, Code, x, y, Colour, 3, 0, KyugoTiles); + } else { + Render8x8Tile_Clip(pTransDraw, Code, x, y, Colour, 3, 0, KyugoTiles); + } + } + } + + TileIndex++; + } + } +} + +static void KyugoRenderSpriteLayer() +{ + unsigned char *SpriteRam_Area1 = &KyugoSprite1Ram[0x28]; + unsigned char *SpriteRam_Area2 = &KyugoSprite2Ram[0x28]; + unsigned char *SpriteRam_Area3 = &KyugoFgVideoRam[0x28]; + + int i; + + for (i = 0; i < 24; i++) { + int Offset, y, sy, sx, Colour; + + Offset = 2 * (i % 12) + 64 * (i / 12); + + sx = SpriteRam_Area3[Offset + 1] + 256 * (SpriteRam_Area2[Offset + 1] & 1); + if (sx > 320) sx -= 512; + sy = 255 - SpriteRam_Area1[Offset] + 2; + if (sy > 0xf0) sy -= 256; + if (KyugoFlipScreen) sy = 240 - sy; + sy -= 16; + + Colour = SpriteRam_Area1[Offset + 1] & 0x1f; + + for (y = 0; y < 16; y++) { + int Code, Attr, FlipX, FlipY, yPos; + + Code = SpriteRam_Area3[Offset + 128 * y]; + Attr = SpriteRam_Area2[Offset + 128 * y]; + Code = Code | ((Attr & 0x01) << 9) | ((Attr & 0x02) << 7); + Code &= 0x3ff; + + FlipX = Attr & 0x08; + FlipY = Attr & 0x04; + + yPos = sy + 16 * y; + + if (KyugoFlipScreen) { + FlipX = !FlipX; + FlipY = !FlipY; + yPos = sy - 16 * y; + } + + if (sx > 16 && sx < 272 && yPos > 16 && yPos < 208) { + if (FlipX) { + if (FlipY) { + Render16x16Tile_Mask_FlipXY(pTransDraw, Code, sx, yPos, Colour, 3, 0, 0, KyugoSprites); + } else { + Render16x16Tile_Mask_FlipX(pTransDraw, Code, sx, yPos, Colour, 3, 0, 0, KyugoSprites); + } + } else { + if (FlipY) { + Render16x16Tile_Mask_FlipY(pTransDraw, Code, sx, yPos, Colour, 3, 0, 0, KyugoSprites); + } else { + Render16x16Tile_Mask(pTransDraw, Code, sx, yPos, Colour, 3, 0, 0, KyugoSprites); + } + } + } else { + if (FlipX) { + if (FlipY) { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, Code, sx, yPos, Colour, 3, 0, 0, KyugoSprites); + } else { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, Code, sx, yPos, Colour, 3, 0, 0, KyugoSprites); + } + } else { + if (FlipY) { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, Code, sx, yPos, Colour, 3, 0, 0, KyugoSprites); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, Code, sx, yPos, Colour, 3, 0, 0, KyugoSprites); + } + } + } + } + } +} + +static void KyugoRenderCharLayer() +{ + int mx, my, Code, Colour, x, y, TileIndex = 0, FlipX = 0, FlipY = 0; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 64; mx++) { + Code = KyugoFgVideoRam[TileIndex]; + Colour = 2 * KyugoPromCharLookup[Code >> 3] + KyugoFgColour; + Code &= 0xff; + + x = 8 * mx; + y = 8 * my; + + if (KyugoFlipScreen) { + FlipX = 1; + FlipY = 1; + y = 248 - y; + x = 280 - x; + } + + y -= 16; + + if (x > 0 && x < 280 && y > 0 && y < 216) { + if (FlipX) { + if (FlipY) { + Render8x8Tile_Mask_FlipXY(pTransDraw, Code, x, y, Colour, 2, 0, 0, KyugoChars); + } else { + Render8x8Tile_Mask_FlipX(pTransDraw, Code, x, y, Colour, 2, 0, 0, KyugoChars); + } + } else { + if (FlipY) { + Render8x8Tile_Mask_FlipY(pTransDraw, Code, x, y, Colour, 2, 0, 0, KyugoChars); + } else { + Render8x8Tile_Mask(pTransDraw, Code, x, y, Colour, 2, 0, 0, KyugoChars); + } + } + } else { + if (FlipX) { + if (FlipY) { + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, Code, x, y, Colour, 2, 0, 0, KyugoChars); + } else { + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, Code, x, y, Colour, 2, 0, 0, KyugoChars); + } + } else { + if (FlipY) { + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, Code, x, y, Colour, 2, 0, 0, KyugoChars); + } else { + Render8x8Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 2, 0, 0, KyugoChars); + } + } + } + + TileIndex++; + } + } +} + +static void KyugoDraw() +{ + BurnTransferClear(); + KyugoCalcPalette(); + KyugoRenderBgLayer(); + KyugoRenderSpriteLayer(); + KyugoRenderCharLayer(); + BurnTransferCopy(KyugoPalette); +} + +static int KyugoFrame() +{ + int nInterleave = 10; + int nSoundBufferPos = 0; + + if (KyugoReset) KyugoDoReset(); + + KyugoMakeInputs(); + + nCyclesTotal[0] = (18432000 / 6) / 60; + nCyclesTotal[1] = (18432000 / 6) / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run Z80 #1 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if (i == 9 && KyugoIRQEnable) ZetNmi(); + ZetClose(); + + // Run Z80 #2 + nCurrentCPU = 1; + if (KyugoSubCPUEnable) { + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesSegment = ZetRun(nCyclesSegment); + nCyclesDone[nCurrentCPU] += nCyclesSegment; + if (i == 2 || i == 4 || i == 6 || i == 8) ZetRaiseIrq(0); + ZetClose(); + } + + // Render Sound Segment + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + nSoundBufferPos += nSegmentLength; + } + + } + + // Make sure the buffer is entirely filled. + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + + if (pBurnDraw) KyugoDraw(); + + return 0; +} + +static int KyugoScan(int nAction, int *pnMin) +{ + struct BurnArea ba; + + if (pnMin != NULL) { // Return minimum compatible version + *pnMin = 0x029674; + } + + if (nAction & ACB_MEMORY_RAM) { + memset(&ba, 0, sizeof(ba)); + ba.Data = RamStart; + ba.nLen = RamEnd-RamStart; + ba.szName = "All Ram"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + ZetScan(nAction); // Scan Z80 + AY8910Scan(nAction, pnMin); + + // Scan critical driver variables + SCAN_VAR(nCyclesDone); + SCAN_VAR(nCyclesSegment); + SCAN_VAR(KyugoDip); + SCAN_VAR(KyugoInput); + SCAN_VAR(KyugoIRQEnable); + SCAN_VAR(KyugoSubCPUEnable); + SCAN_VAR(KyugoFgColour); + SCAN_VAR(KyugoBgPaletteBank); + SCAN_VAR(KyugoBgScrollXHi); + SCAN_VAR(KyugoBgScrollXLo); + SCAN_VAR(KyugoBgScrollY); + SCAN_VAR(KyugoFlipScreen); + } + + + return 0; +} + +struct BurnDriver BurnDrvAirwolf = { + "airwolf", NULL, NULL, "1987", + "Airwolf\0", NULL, "Kyugo", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, AirwolfRomInfo, AirwolfRomName, KyugoInputInfo, AirwolfDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 288, 224, 4, 3 +}; + +struct BurnDriver BurnDrvAirwolfa = { + "airwolfa", "airwolf", NULL, "1987", + "Airwolf (US)\0", NULL, "Kyugo (UA Theatre license)", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, AirwolfaRomInfo, AirwolfaRomName, KyugoInputInfo, AirwolfDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 288, 224, 4, 3 +}; + +struct BurnDriver BurnDrvSkywolf = { + "skywolf", "airwolf", NULL, "1987", + "Sky Wolf (set 1)\0", NULL, "bootleg", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_MISC_PRE90S, + NULL, SkywolfRomInfo, SkywolfRomName, KyugoInputInfo, SkywolfDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 288, 224, 4, 3 +}; + +struct BurnDriver BurnDrvSkywolf2 = { + "skywolf2", "airwolf", NULL, "1987", + "Sky Wolf (set 2)\0", NULL, "bootleg", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_MISC_PRE90S, + NULL, Skywolf2RomInfo, Skywolf2RomName, KyugoInputInfo, AirwolfDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 288, 224, 4, 3 +}; + +struct BurnDriver BurnDrvFlashgal = { + "flashgal", NULL, NULL, "1985", + "Flashgal (set 1)\0", NULL, "Sega", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, FlashgalRomInfo, FlashgalRomName, KyugoInputInfo, FlashgalDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 288, 224, 4, 3 +}; + +struct BurnDriver BurnDrvFlashgla = { + "flashgla", "flashgal", NULL, "1985", + "Flashgal (set 2)\0", NULL, "Sega", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, FlashglaRomInfo, FlashglaRomName, KyugoInputInfo, FlashgalDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 288, 224, 4, 3 +}; + +struct BurnDriver BurnDrvGyrodine = { + "gyrodine", NULL, NULL, "1984", + "Gyrodine (Taito Corporation license)\0", NULL, "Crux (Taito Corporation license)", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, GyrodineRomInfo, GyrodineRomName, KyugoInputInfo, GyrodineDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 224, 288, 3, 4 +}; + +struct BurnDriver BurnDrvGyrodinc = { + "gyrodinc", "gyrodine", NULL, "1984", + "Gyrodine\0", NULL, "Crux", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, GyrodincRomInfo, GyrodincRomName, KyugoInputInfo, GyrodineDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 224, 288, 3, 4 +}; + +struct BurnDriver BurnDrvBuzzard = { + "buzzard", "gyrodine", NULL, "1984", + "Buzzard\0", NULL, "Crux", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, BuzzardRomInfo, BuzzardRomName, KyugoInputInfo, GyrodineDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 224, 288, 3, 4 +}; + +struct BurnDriver BurnDrvLegend = { + "legend", NULL, NULL, "1986", + "Legend\0", NULL, "Sega / Coreland", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, LegendRomInfo, LegendRomName, KyugoInputInfo, LegendDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 288, 224, 4, 3 +}; + +struct BurnDriver BurnDrvSonofphx = { + "sonofphx", NULL, NULL, "1985", + "Son of Phoenix\0", NULL, "Associated Overseas MFR, Inc", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, SonofphxRomInfo, SonofphxRomName, KyugoInputInfo, SonofphxDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 224, 288, 3, 4 +}; + +struct BurnDriver BurnDrvRepulse = { + "repulse", "sonofphx", NULL, "1985", + "Repulse\0", NULL, "Sega", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, RepulseRomInfo, RepulseRomName, KyugoInputInfo, SonofphxDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 224, 288, 3, 4 +}; + +struct BurnDriver BurnDrv99lstwar = { + "99lstwar", "sonofphx", NULL, "1985", + "'99: The Last War\0", NULL, "Proma", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, Lstwar99RomInfo, Lstwar99RomName, KyugoInputInfo, SonofphxDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 224, 288, 3, 4 +}; + +struct BurnDriver BurnDrv99lstwra = { + "99lstwra", "sonofphx", NULL, "1985", + "'99: The Last War (alternate)\0", NULL, "Proma", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, Lstwra99RomInfo, Lstwra99RomName, KyugoInputInfo, SonofphxDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 224, 288, 3, 4 +}; + +struct BurnDriver BurnDrv99lstwrk = { + "99lstwrk", "sonofphx", NULL, "1985", + "'99: The Last War (Kyugo)\0", NULL, "Kyugo", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, Lstwrk99RomInfo, Lstwrk99RomName, KyugoInputInfo, SonofphxDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 224, 288, 3, 4 +}; + +struct BurnDriver BurnDrvSrdmissn = { + "srdmissn", NULL, NULL, "1986", + "S.R.D. Mission\0", NULL, "Taito Corporation", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, SrdmissnRomInfo, SrdmissnRomName, KyugoInputInfo, SrdmissnDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 224, 288, 3, 4 +}; + +struct BurnDriver BurnDrvFx = { + "fx", "srdmissn", NULL, "1986", + "F-X\0", NULL, "bootleg", "Kyugo", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, FxRomInfo, FxRomName, KyugoInputInfo, SrdmissnDIPInfo, + KyugoInit, KyugoExit, KyugoFrame, NULL, KyugoScan, + 0, NULL, NULL, NULL, NULL, 224, 288, 3, 4 +}; diff --git a/src/burn/misc/pre90s/d_madgear.cpp b/src/burn/misc/pre90s/d_madgear.cpp new file mode 100644 index 0000000..d965e27 --- /dev/null +++ b/src/burn/misc/pre90s/d_madgear.cpp @@ -0,0 +1,1755 @@ +#include "tiles_generic.h" +#include "burn_ym2203.h" +#include "msm6295.h" + +static unsigned char DrvInputPort0[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char DrvInputPort1[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char DrvInputPort2[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char DrvDip[3] = {0, 0, 0}; +static unsigned char DrvInput[3] = {0x00, 0x00, 0x00}; +static unsigned char DrvReset = 0; + +static unsigned char *Mem = NULL; +static unsigned char *MemEnd = NULL; +static unsigned char *RamStart = NULL; +static unsigned char *RamEnd = NULL; +static unsigned char *Drv68KRom = NULL; +static unsigned char *Drv68KRam = NULL; +static unsigned char *DrvZ80Rom = NULL; +static unsigned char *DrvZ80Ram = NULL; +static unsigned char *DrvVideoRam = NULL; +static unsigned char *DrvSpriteRam = NULL; +static unsigned char *DrvSpriteRamBuffer = NULL; +static unsigned char *DrvPaletteRam = NULL; +static unsigned char *DrvScroll1Ram = NULL; +static unsigned char *DrvScroll2Ram = NULL; +static unsigned char *DrvChars = NULL; +static unsigned char *DrvBgTiles = NULL; +static unsigned char *DrvFgTiles = NULL; +static unsigned char *DrvSprites = NULL; +static unsigned char *DrvTempRom = NULL; +static unsigned int *DrvPalette = NULL; + +static UINT16 DrvFgScrollX; +static UINT16 DrvFgScrollY; +static UINT16 DrvBgScrollX; +static UINT16 DrvBgScrollY; +static unsigned char DrvSpritePriMask; +static unsigned char DrvSpriteFlipYMask; +static unsigned char DrvZ80RomBank; +static unsigned char DrvSoundLatch; + +static int nCyclesDone[2], nCyclesTotal[2]; +static int nCyclesSegment; + +static struct BurnInputInfo DrvInputList[] = +{ + {"Coin 1" , BIT_DIGITAL , DrvInputPort2 + 4, "p1 coin" }, + {"Start 1" , BIT_DIGITAL , DrvInputPort2 + 2, "p1 start" }, + {"Coin 2" , BIT_DIGITAL , DrvInputPort2 + 3, "p2 coin" }, + {"Start 2" , BIT_DIGITAL , DrvInputPort2 + 1, "p2 start" }, + + {"Up" , BIT_DIGITAL , DrvInputPort0 + 7, "p1 up" }, + {"Down" , BIT_DIGITAL , DrvInputPort0 + 6, "p1 down" }, + {"Left" , BIT_DIGITAL , DrvInputPort0 + 5, "p1 left" }, + {"Right" , BIT_DIGITAL , DrvInputPort0 + 4, "p1 right" }, + {"Fire 1" , BIT_DIGITAL , DrvInputPort0 + 3, "p1 fire 1" }, + + {"Up (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 7, "p2 up" }, + {"Down (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 6, "p2 down" }, + {"Left (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 5, "p2 left" }, + {"Right (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 4, "p2 right" }, + {"Fire 1 (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 3, "p2 fire 1" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Service" , BIT_DIGITAL , DrvInputPort2 + 7, "service" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDip + 0 , "dip" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDip + 1 , "dip" }, + {"Dip 3" , BIT_DIPSWITCH, DrvDip + 2 , "dip" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnInputInfo LastduelInputList[] = +{ + {"Coin 1" , BIT_DIGITAL , DrvInputPort2 + 7, "p1 coin" }, + {"Start 1" , BIT_DIGITAL , DrvInputPort2 + 0, "p1 start" }, + {"Coin 2" , BIT_DIGITAL , DrvInputPort2 + 6, "p2 coin" }, + {"Start 2" , BIT_DIGITAL , DrvInputPort2 + 1, "p2 start" }, + + {"Up" , BIT_DIGITAL , DrvInputPort0 + 3, "p1 up" }, + {"Down" , BIT_DIGITAL , DrvInputPort0 + 2, "p1 down" }, + {"Left" , BIT_DIGITAL , DrvInputPort0 + 1, "p1 left" }, + {"Right" , BIT_DIGITAL , DrvInputPort0 + 0, "p1 right" }, + {"Fire 1" , BIT_DIGITAL , DrvInputPort0 + 4, "p1 fire 1" }, + {"Fire 2" , BIT_DIGITAL , DrvInputPort0 + 5, "p1 fire 2" }, + + {"Up (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 3, "p2 up" }, + {"Down (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 2, "p2 down" }, + {"Left (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 1, "p2 left" }, + {"Right (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 0, "p2 right" }, + {"Fire 1 (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 4, "p2 fire 1" }, + {"Fire 2 (Cocktail)" , BIT_DIGITAL , DrvInputPort1 + 5, "p2 fire 2" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Service" , BIT_DIGITAL , DrvInputPort2 + 5, "service" }, + {"Diagnostics" , BIT_DIGITAL , DrvInputPort2 + 3, "diag" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDip + 0 , "dip" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDip + 1 , "dip" }, + {"Dip 3" , BIT_DIPSWITCH, DrvDip + 2 , "dip" }, +}; + +STDINPUTINFO(Lastduel); + +static inline void DrvClearOpposites(unsigned char* nJoystickInputs) +{ + if ((*nJoystickInputs & 0x03) == 0x03) { + *nJoystickInputs &= ~0x03; + } + if ((*nJoystickInputs & 0x0c) == 0x0c) { + *nJoystickInputs &= ~0x0c; + } +} + +static inline void DrvMakeInputs() +{ + // Reset Inputs + DrvInput[0] = DrvInput[1] = DrvInput[2] = 0x00; + + // Compile Digital Inputs + for (int i = 0; i < 8; i++) { + DrvInput[0] |= (DrvInputPort0[i] & 1) << i; + DrvInput[1] |= (DrvInputPort1[i] & 1) << i; + DrvInput[2] |= (DrvInputPort2[i] & 1) << i; + } + + // Clear Opposites + DrvClearOpposites(&DrvInput[0]); + DrvClearOpposites(&DrvInput[1]); +} + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + {0x11, 0xff, 0xff, 0xff, NULL }, + {0x12, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 2 , "Service Mode" }, + {0x10, 0x01, 0x80, 0x80, "Off" }, + {0x10, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 2 , "Allow continue" }, + {0x11, 0x01, 0x01, 0x00, "No" }, + {0x11, 0x01, 0x01, 0x01, "Yes" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x11, 0x01, 0x02, 0x02, "Off" }, + {0x11, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x11, 0x01, 0x0c, 0x08, "Easy" }, + {0x11, 0x01, 0x0c, 0x0c, "Normal" }, + {0x11, 0x01, 0x0c, 0x04, "Difficult" }, + {0x11, 0x01, 0x0c, 0x00, "Very Difficult" }, + + {0 , 0xfe, 0 , 3 , "Cabinet" }, + {0x11, 0x01, 0x30, 0x30, "Upright (One Player)" }, + {0x11, 0x01, 0x30, 0x00, "Upright (Two Players)" }, + {0x11, 0x01, 0x30, 0x10, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x11, 0x01, 0x40, 0x00, "Off" }, + {0x11, 0x01, 0x40, 0x40, "On" }, + + {0 , 0xfe, 0 , 2 , "Background Music" }, + {0x11, 0x01, 0x80, 0x00, "Off" }, + {0x11, 0x01, 0x80, 0x80, "On" }, + + // Dip3 + {0 , 0xfe, 0 , 16 , "Coin A" }, + {0x12, 0x01, 0xf0, 0x20, "6 Coins 1 Play" }, + {0x12, 0x01, 0xf0, 0x40, "5 Coins 1 Play" }, + {0x12, 0x01, 0xf0, 0x50, "4 Coins 1 Play" }, + {0x12, 0x01, 0xf0, 0x70, "3 Coins 1 Play" }, + {0x12, 0x01, 0xf0, 0x10, "8 Coins 3 Plays" }, + {0x12, 0x01, 0xf0, 0x90, "2 Coins 1 Play" }, + {0x12, 0x01, 0xf0, 0x30, "5 Coins 3 Plays" }, + {0x12, 0x01, 0xf0, 0x60, "3 Coins 2 Plays" }, + {0x12, 0x01, 0xf0, 0xf0, "1 Coin 1 Play" }, + {0x12, 0x01, 0xf0, 0x80, "2 Coins 3 Plays" }, + {0x12, 0x01, 0xf0, 0xe0, "1 Coin 2 Plays" }, + {0x12, 0x01, 0xf0, 0xd0, "1 Coin 3 Plays" }, + {0x12, 0x01, 0xf0, 0xc0, "1 Coin 4 Plays" }, + {0x12, 0x01, 0xf0, 0xb0, "1 Coin 5 Plays" }, + {0x12, 0x01, 0xf0, 0xa0, "1 Coin 6 Plays" }, + {0x12, 0x01, 0xf0, 0x00, "Freeplay" }, + + {0 , 0xfe, 0 , 15 , "Coin B" }, + {0x12, 0x01, 0x0f, 0x02, "6 Coins 1 Play" }, + {0x12, 0x01, 0x0f, 0x04, "5 Coins 1 Play" }, + {0x12, 0x01, 0x0f, 0x05, "4 Coins 1 Play" }, + {0x12, 0x01, 0x0f, 0x07, "3 Coins 1 Play" }, + {0x12, 0x01, 0x0f, 0x01, "8 Coins 3 Plays" }, + {0x12, 0x01, 0x0f, 0x09, "2 Coins 1 Play" }, + {0x12, 0x01, 0x0f, 0x03, "5 Coins 3 Plays" }, + {0x12, 0x01, 0x0f, 0x06, "3 Coins 2 Plays" }, + {0x12, 0x01, 0x0f, 0x0f, "1 Coin 1 Play" }, + {0x12, 0x01, 0x0f, 0x08, "2 Coins 3 Plays" }, + {0x12, 0x01, 0x0f, 0x0e, "1 Coin 2 Plays" }, + {0x12, 0x01, 0x0f, 0x0d, "1 Coin 3 Plays" }, + {0x12, 0x01, 0x0f, 0x0c, "1 Coin 4 Plays" }, + {0x12, 0x01, 0x0f, 0x0b, "1 Coin 5 Plays" }, + {0x12, 0x01, 0x0f, 0x0a, "1 Coin 6 Plays" }, +}; + +STDDIPINFO(Drv); + +static struct BurnDIPInfo LastduelDIPList[]= +{ + // Default Values + {0x13, 0xff, 0xff, 0xff, NULL }, + {0x14, 0xff, 0xff, 0xff, NULL }, + {0x15, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x13, 0x01, 0x07, 0x00, "4 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x01, "3 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x02, "2 Coins 1 Play" }, + {0x13, 0x01, 0x07, 0x07, "1 Coin 1 Play" }, + {0x13, 0x01, 0x07, 0x06, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x07, 0x05, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x07, 0x04, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x07, 0x03, "1 Coin 6 Plays" }, + + {0 , 0xfe, 0 , 8 , "Coin B" }, + {0x13, 0x01, 0x38, 0x00, "4 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x08, "3 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x10, "2 Coins 1 Play" }, + {0x13, 0x01, 0x38, 0x38, "1 Coin 1 Play" }, + {0x13, 0x01, 0x38, 0x30, "1 Coin 2 Plays" }, + {0x13, 0x01, 0x38, 0x28, "1 Coin 3 Plays" }, + {0x13, 0x01, 0x38, 0x20, "1 Coin 4 Plays" }, + {0x13, 0x01, 0x38, 0x18, "1 Coin 6 Plays" }, + + // Dip 2 + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x14, 0x01, 0x03, 0x02, "Easy" }, + {0x14, 0x01, 0x03, 0x03, "Normal" }, + {0x14, 0x01, 0x03, 0x01, "Difficult" }, + {0x14, 0x01, 0x03, 0x00, "Very Difficult" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x14, 0x01, 0x30, 0x20, "20000, 60000, 80000" }, + {0x14, 0x01, 0x30, 0x30, "30000, 80000, 80000" }, + {0x14, 0x01, 0x30, 0x10, "40000, 80000, 80000" }, + {0x14, 0x01, 0x30, 0x00, "40000, 80000, 100000" }, + + // Dip3 + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x15, 0x01, 0x03, 0x03, "3" }, + {0x15, 0x01, 0x03, 0x02, "4" }, + {0x15, 0x01, 0x03, 0x01, "6" }, + {0x15, 0x01, 0x03, 0x00, "8" }, + + {0 , 0xfe, 0 , 2 , "Type" }, + {0x15, 0x01, 0x04, 0x04, "Car" }, + {0x15, 0x01, 0x04, 0x00, "Plane" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x15, 0x01, 0x20, 0x00, "Off" }, + {0x15, 0x01, 0x20, 0x20, "On" }, + + {0 , 0xfe, 0 , 2 , "Allow continue" }, + {0x15, 0x01, 0x40, 0x00, "No" }, + {0x15, 0x01, 0x40, 0x40, "Yes" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x15, 0x01, 0x80, 0x80, "Off" }, + {0x15, 0x01, 0x80, 0x00, "On" }, + +}; + +STDDIPINFO(Lastduel); + +static struct BurnRomInfo DrvRomDesc[] = { + { "mg_04.rom", 0x20000, 0xb112257d, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "mg_03.rom", 0x20000, 0xb2672465, BRF_ESS | BRF_PRG }, // 1 + { "mg_02.rom", 0x20000, 0x9f5ebe16, BRF_ESS | BRF_PRG }, // 2 + { "mg_01.rom", 0x20000, 0x1cea2af0, BRF_ESS | BRF_PRG }, // 3 + + { "mg_05.rom", 0x10000, 0x2fbfc945, BRF_ESS | BRF_PRG }, // 4 Z80 Program + + { "mg_06.rom", 0x08000, 0x382ee59b, BRF_GRA }, // 5 Characters + + { "ls-12", 0x40000, 0x6c1b2c6c, BRF_GRA }, // 6 BG Tiles + + { "ls-11", 0x80000, 0x6bf81c64, BRF_GRA }, // 7 FG Tiles + + { "mg_m11.rom", 0x10000, 0xee319a64, BRF_GRA }, // 8 Sprites + { "mg_m07.rom", 0x10000, 0xe5c0b211, BRF_GRA }, // 9 + { "mg_m12.rom", 0x10000, 0x887ef120, BRF_GRA }, // 10 + { "mg_m08.rom", 0x10000, 0x59709aa3, BRF_GRA }, // 11 + { "mg_m13.rom", 0x10000, 0xeae07db4, BRF_GRA }, // 12 + { "mg_m09.rom", 0x10000, 0x40ee83eb, BRF_GRA }, // 13 + { "mg_m14.rom", 0x10000, 0x21e5424c, BRF_GRA }, // 14 + { "mg_m10.rom", 0x10000, 0xb64afb54, BRF_GRA }, // 15 + + { "ls-06", 0x20000, 0x88d39a5b, BRF_SND }, // 16 Samples + { "ls-05", 0x20000, 0xb06e03b5, BRF_SND }, // 17 + + { "63s141.14k", 0x00100, 0x7f862e1e, BRF_GRA }, // 18 PROM (Priority) +}; + +STD_ROM_PICK(Drv); +STD_ROM_FN(Drv); + +static struct BurnRomInfo DrvjRomDesc[] = { + { "mdj_04.rom", 0x20000, 0x9ebbebb1, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "mdj_03.rom", 0x20000, 0xa5579c2d, BRF_ESS | BRF_PRG }, // 1 + { "mg_02.rom", 0x20000, 0x9f5ebe16, BRF_ESS | BRF_PRG }, // 2 + { "mg_01.rom", 0x20000, 0x1cea2af0, BRF_ESS | BRF_PRG }, // 3 + + { "mg_05.rom", 0x10000, 0x2fbfc945, BRF_ESS | BRF_PRG }, // 4 Z80 Program + + { "mg_06.rom", 0x08000, 0x382ee59b, BRF_GRA }, // 5 Characters + + { "ls-12", 0x40000, 0x6c1b2c6c, BRF_GRA }, // 6 BG Tiles + + { "ls-11", 0x80000, 0x6bf81c64, BRF_GRA }, // 7 FG Tiles + + { "mg_m11.rom", 0x10000, 0xee319a64, BRF_GRA }, // 8 Sprites + { "mg_m07.rom", 0x10000, 0xe5c0b211, BRF_GRA }, // 9 + { "mg_m12.rom", 0x10000, 0x887ef120, BRF_GRA }, // 10 + { "mg_m08.rom", 0x10000, 0x59709aa3, BRF_GRA }, // 11 + { "mg_m13.rom", 0x10000, 0xeae07db4, BRF_GRA }, // 12 + { "mg_m09.rom", 0x10000, 0x40ee83eb, BRF_GRA }, // 13 + { "mg_m14.rom", 0x10000, 0x21e5424c, BRF_GRA }, // 14 + { "mg_m10.rom", 0x10000, 0xb64afb54, BRF_GRA }, // 15 + + { "ls-06", 0x20000, 0x88d39a5b, BRF_SND }, // 16 Samples + { "ls-05", 0x20000, 0xb06e03b5, BRF_SND }, // 17 + + { "63s141.14k", 0x00100, 0x7f862e1e, BRF_GRA }, // 18 PROM (Priority) +}; + +STD_ROM_PICK(Drvj); +STD_ROM_FN(Drvj); + +static struct BurnRomInfo DrvuRomDesc[] = { + { "mdu.04", 0x20000, 0x7f7f8329, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "mdu.03", 0x20000, 0x11fa542f, BRF_ESS | BRF_PRG }, // 1 + { "mg_02.rom", 0x20000, 0x9f5ebe16, BRF_ESS | BRF_PRG }, // 2 + { "mg_01.rom", 0x20000, 0x1cea2af0, BRF_ESS | BRF_PRG }, // 3 + + { "mg_05.rom", 0x10000, 0x2fbfc945, BRF_ESS | BRF_PRG }, // 4 Z80 Program + + { "06", 0x08000, 0x54bfdc02, BRF_GRA }, // 5 Characters + + { "ls-12", 0x40000, 0x6c1b2c6c, BRF_GRA }, // 6 BG Tiles + + { "ls-11", 0x80000, 0x6bf81c64, BRF_GRA }, // 7 FG Tiles + + { "mg_m11.rom", 0x10000, 0xee319a64, BRF_GRA }, // 8 Sprites + { "07", 0x10000, 0x7152b212, BRF_GRA }, // 9 + { "mg_m12.rom", 0x10000, 0x887ef120, BRF_GRA }, // 10 + { "08", 0x10000, 0x72e5d525, BRF_GRA }, // 11 + { "mg_m13.rom", 0x10000, 0xeae07db4, BRF_GRA }, // 12 + { "09", 0x10000, 0x7b5175cb, BRF_GRA }, // 13 + { "mg_m14.rom", 0x10000, 0x21e5424c, BRF_GRA }, // 14 + { "10", 0x10000, 0x6db7ca64, BRF_GRA }, // 15 + + { "ls-06", 0x20000, 0x88d39a5b, BRF_SND }, // 16 Samples + { "ls-05", 0x20000, 0xb06e03b5, BRF_SND }, // 17 + + { "63s141.14k", 0x00100, 0x7f862e1e, BRF_GRA }, // 18 PROM (Priority) +}; + +STD_ROM_PICK(Drvu); +STD_ROM_FN(Drvu); + +static struct BurnRomInfo Ledstrm2RomDesc[] = { + { "lsu-04.bin", 0x20000, 0x56a2f079, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "lsu-03.bin", 0x20000, 0x9b6408c0, BRF_ESS | BRF_PRG }, // 1 + { "ls-02.bin", 0x20000, 0x05c0285e, BRF_ESS | BRF_PRG }, // 2 + { "ls-01.bin", 0x20000, 0x8bf934dd, BRF_ESS | BRF_PRG }, // 3 + + { "ls-07.bin", 0x10000, 0x98af7838, BRF_ESS | BRF_PRG }, // 4 Z80 Program + + { "ls-08.bin", 0x08000, 0x8803cf49, BRF_GRA }, // 5 Characters + + { "ls-12", 0x40000, 0x6c1b2c6c, BRF_GRA }, // 6 BG Tiles + + { "ls-11", 0x80000, 0x6bf81c64, BRF_GRA }, // 7 FG Tiles + + { "mg_m11.rom", 0x10000, 0xee319a64, BRF_GRA }, // 8 Sprites + { "07", 0x10000, 0x7152b212, BRF_GRA }, // 9 + { "mg_m12.rom", 0x10000, 0x887ef120, BRF_GRA }, // 10 + { "08", 0x10000, 0x72e5d525, BRF_GRA }, // 11 + { "mg_m13.rom", 0x10000, 0xeae07db4, BRF_GRA }, // 12 + { "09", 0x10000, 0x7b5175cb, BRF_GRA }, // 13 + { "mg_m14.rom", 0x10000, 0x21e5424c, BRF_GRA }, // 14 + { "10", 0x10000, 0x6db7ca64, BRF_GRA }, // 15 + + { "ls-06", 0x20000, 0x88d39a5b, BRF_SND }, // 16 Samples + { "ls-05", 0x20000, 0xb06e03b5, BRF_SND }, // 17 + + { "63s141.14k", 0x00100, 0x7f862e1e, BRF_GRA }, // 18 PROM (Priority) +}; + +STD_ROM_PICK(Ledstrm2); +STD_ROM_FN(Ledstrm2); + +static struct BurnRomInfo LastduelRomDesc[] = { + { "ldu-06.rom", 0x20000, 0x4228a00b, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "ldu-05.rom", 0x20000, 0x7260434f, BRF_ESS | BRF_PRG }, // 1 + { "ldu-04.rom", 0x10000, 0x429fb964, BRF_ESS | BRF_PRG }, // 2 + { "ldu-03.rom", 0x10000, 0x5aa4df72, BRF_ESS | BRF_PRG }, // 3 + + { "ld_02.bin", 0x10000, 0x91834d0c, BRF_ESS | BRF_PRG }, // 4 Z80 Program + + { "ld_01.bin", 0x08000, 0xad3c6f87, BRF_GRA }, // 5 Characters + + { "ld_17.bin", 0x10000, 0x7188bfdd, BRF_GRA }, // 6 BG Tiles + { "ld_18.bin", 0x10000, 0xa62af66a, BRF_GRA }, // 7 + { "ld_19.bin", 0x10000, 0x4b762e50, BRF_GRA }, // 8 + { "ld_20.bin", 0x10000, 0xb140188e, BRF_GRA }, // 9 + + { "ld_28.bin", 0x10000, 0x06778248, BRF_GRA }, // 10 FG Tiles + { "ld_26.bin", 0x10000, 0xb0edac81, BRF_GRA }, // 11 + { "ld_24.bin", 0x10000, 0x66eac4df, BRF_GRA }, // 12 + { "ld_22.bin", 0x10000, 0xf80f8812, BRF_GRA }, // 13 + { "ld_27.bin", 0x10000, 0x48c78675, BRF_GRA }, // 14 + { "ld_25.bin", 0x10000, 0xc541ae9a, BRF_GRA }, // 15 + { "ld_23.bin", 0x10000, 0xd817332c, BRF_GRA }, // 16 + { "ld_21.bin", 0x10000, 0xb74f0c0e, BRF_GRA }, // 17 + + { "ld_09.bin", 0x10000, 0xf8fd5243, BRF_GRA }, // 18 Sprites + { "ld_10.bin", 0x10000, 0xb49ad746, BRF_GRA }, // 19 + { "ld_11.bin", 0x10000, 0x1a0d180e, BRF_GRA }, // 20 + { "ld_12.bin", 0x10000, 0xb2745e26, BRF_GRA }, // 21 + { "ld_15.bin", 0x10000, 0x96b13bbc, BRF_GRA }, // 22 + { "ld_16.bin", 0x10000, 0x9d80f7e6, BRF_GRA }, // 23 + { "ld_13.bin", 0x10000, 0xa1a598ac, BRF_GRA }, // 24 + { "ld_14.bin", 0x10000, 0xedf515cc, BRF_GRA }, // 25 + + { "63s141.3d", 0x00100, 0x729a1ddc, BRF_GRA }, // 26 PROM (Priority) +}; + +STD_ROM_PICK(Lastduel); +STD_ROM_FN(Lastduel); + +static struct BurnRomInfo LstduelaRomDesc[] = { + { "06", 0x20000, 0x0e71acaf, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "05", 0x20000, 0x47a85bea, BRF_ESS | BRF_PRG }, // 1 + { "04", 0x10000, 0xaa4bf001, BRF_ESS | BRF_PRG }, // 2 + { "03", 0x10000, 0xbbaac8ab, BRF_ESS | BRF_PRG }, // 3 + + { "ld_02.bin", 0x10000, 0x91834d0c, BRF_ESS | BRF_PRG }, // 4 Z80 Program + + { "ld_01.bin", 0x08000, 0xad3c6f87, BRF_GRA }, // 5 Characters + + { "ld_17.bin", 0x10000, 0x7188bfdd, BRF_GRA }, // 6 BG Tiles + { "ld_18.bin", 0x10000, 0xa62af66a, BRF_GRA }, // 7 + { "ld_19.bin", 0x10000, 0x4b762e50, BRF_GRA }, // 8 + { "ld_20.bin", 0x10000, 0xb140188e, BRF_GRA }, // 9 + + { "ld_28.bin", 0x10000, 0x06778248, BRF_GRA }, // 10 FG Tiles + { "ld_26.bin", 0x10000, 0xb0edac81, BRF_GRA }, // 11 + { "ld_24.bin", 0x10000, 0x66eac4df, BRF_GRA }, // 12 + { "ld_22.bin", 0x10000, 0xf80f8812, BRF_GRA }, // 13 + { "ld_27.bin", 0x10000, 0x48c78675, BRF_GRA }, // 14 + { "ld_25.bin", 0x10000, 0xc541ae9a, BRF_GRA }, // 15 + { "ld_23.bin", 0x10000, 0xd817332c, BRF_GRA }, // 16 + { "ld_21.bin", 0x10000, 0xb74f0c0e, BRF_GRA }, // 17 + + { "ld_09.bin", 0x10000, 0xf8fd5243, BRF_GRA }, // 18 Sprites + { "ld_10.bin", 0x10000, 0xb49ad746, BRF_GRA }, // 19 + { "ld_11.bin", 0x10000, 0x1a0d180e, BRF_GRA }, // 20 + { "ld_12.bin", 0x10000, 0xb2745e26, BRF_GRA }, // 21 + { "ld_15.bin", 0x10000, 0x96b13bbc, BRF_GRA }, // 22 + { "ld_16.bin", 0x10000, 0x9d80f7e6, BRF_GRA }, // 23 + { "ld_13.bin", 0x10000, 0xa1a598ac, BRF_GRA }, // 24 + { "ld_14.bin", 0x10000, 0xedf515cc, BRF_GRA }, // 25 + + { "63s141.3d", 0x00100, 0x729a1ddc, BRF_GRA }, // 26 PROM (Priority) +}; + +STD_ROM_PICK(Lstduela); +STD_ROM_FN(Lstduela); + +static struct BurnRomInfo LstduelbRomDesc[] = { + { "ld_08.bin", 0x10000, 0x43811a96, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "ld_07.bin", 0x10000, 0x63c30946, BRF_ESS | BRF_PRG }, // 1 + { "ld_04.bin", 0x10000, 0x46a4e0f8, BRF_ESS | BRF_PRG }, // 2 + { "ld_03.bin", 0x10000, 0x8d5f204a, BRF_ESS | BRF_PRG }, // 3 + { "ldu-04.rom", 0x10000, 0x429fb964, BRF_ESS | BRF_PRG }, // 4 + { "ldu-03.rom", 0x10000, 0x5aa4df72, BRF_ESS | BRF_PRG }, // 5 + + { "ld_02.bin", 0x10000, 0x91834d0c, BRF_ESS | BRF_PRG }, // 6 Z80 Program + + { "ld_01.bin", 0x08000, 0xad3c6f87, BRF_GRA }, // 7 Characters + + { "ld_17.bin", 0x10000, 0x7188bfdd, BRF_GRA }, // 8 BG Tiles + { "ld_18.bin", 0x10000, 0xa62af66a, BRF_GRA }, // 9 + { "ld_19.bin", 0x10000, 0x4b762e50, BRF_GRA }, // 10 + { "ld_20.bin", 0x10000, 0xb140188e, BRF_GRA }, // 11 + + { "ld_28.bin", 0x10000, 0x06778248, BRF_GRA }, // 12 FG Tiles + { "ld_26.bin", 0x10000, 0xb0edac81, BRF_GRA }, // 13 + { "ld_24.bin", 0x10000, 0x66eac4df, BRF_GRA }, // 14 + { "ld_22.bin", 0x10000, 0xf80f8812, BRF_GRA }, // 15 + { "ld_27.bin", 0x10000, 0x48c78675, BRF_GRA }, // 16 + { "ld_25.bin", 0x10000, 0xc541ae9a, BRF_GRA }, // 17 + { "ld_23.bin", 0x10000, 0xd817332c, BRF_GRA }, // 18 + { "ld_21.bin", 0x10000, 0xb74f0c0e, BRF_GRA }, // 19 + + { "ld_09.bin", 0x10000, 0xf8fd5243, BRF_GRA }, // 20 Sprites + { "ld_10.bin", 0x10000, 0xb49ad746, BRF_GRA }, // 21 + { "ld_11.bin", 0x10000, 0x1a0d180e, BRF_GRA }, // 22 + { "ld_12.bin", 0x10000, 0xb2745e26, BRF_GRA }, // 23 + { "ld_15.bin", 0x10000, 0x96b13bbc, BRF_GRA }, // 24 + { "ld_16.bin", 0x10000, 0x9d80f7e6, BRF_GRA }, // 25 + { "ld_13.bin", 0x10000, 0xa1a598ac, BRF_GRA }, // 26 + { "ld_14.bin", 0x10000, 0xedf515cc, BRF_GRA }, // 27 + + { "63s141.3d", 0x00100, 0x729a1ddc, BRF_GRA }, // 28 PROM (Priority) +}; + +STD_ROM_PICK(Lstduelb); +STD_ROM_FN(Lstduelb); + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + Drv68KRom = Next; Next += 0x80000; + DrvZ80Rom = Next; Next += 0x10000; + MSM6295ROM = Next; Next += 0x40000; + + RamStart = Next; + + Drv68KRam = Next; Next += 0x20000; + DrvZ80Ram = Next; Next += 0x00800; + DrvSpriteRam = Next; Next += 0x00800; + DrvSpriteRamBuffer = Next; Next += 0x00800; + DrvVideoRam = Next; Next += 0x02000; + DrvPaletteRam = Next; Next += 0x00800; + DrvScroll1Ram = Next; Next += 0x04000; + DrvScroll2Ram = Next; Next += 0x08000; + + RamEnd = Next; + + DrvChars = Next; Next += 0x0800 * 8 * 8; + DrvBgTiles = Next; Next += 0x0800 * 16 * 16; + DrvFgTiles = Next; Next += 0x1000 * 16 * 16; + DrvSprites = Next; Next += 0x1000 * 16 * 16; + DrvPalette = (unsigned int*)Next; Next += 0x00800 * sizeof(unsigned int); + + MemEnd = Next; + + return 0; +} + +static int DrvDoReset() +{ + SekOpen(0); + SekReset(); + SekClose(); + + ZetOpen(0); + ZetReset(); + ZetClose(); + + BurnYM2203Reset(); + + DrvFgScrollX = 0; + DrvFgScrollY = 0; + DrvBgScrollX = 0; + DrvBgScrollY = 0; + DrvZ80RomBank = 0; + DrvSoundLatch = 0; + + return 0; +} + +static int MadgearDoReset() +{ + DrvDoReset(); + + MSM6295Reset(0); + + return 0; +} + +unsigned char __fastcall Madgear68KReadByte(unsigned int a) +{ + switch (a) { + case 0xfc4000: { + return DrvDip[0]; + } + + case 0xfc4001: { + return DrvDip[1]; + } + + case 0xfc4002: { + return DrvDip[2]; + } + + case 0xfc4004: { + return 0xff - DrvInput[0]; + } + + case 0xfc4005: { + return 0xff - DrvInput[1]; + } + + case 0xfc4006: { + return 0xff - DrvInput[2]; + } + + default: { + bprintf(PRINT_NORMAL, _T("68K Read byte => %06X\n"), a); + } + } + + return 0; +} + +void __fastcall Madgear68KWriteWord(unsigned int a, unsigned short d) +{ + switch (a) { + case 0xfc4000: { + // flip + return; + } + + case 0xfc4002: { + DrvSoundLatch = d & 0xff; + return; + } + + case 0xfd0000: { + DrvFgScrollY = d & 0x1ff; + return; + } + + case 0xfd0002: { + DrvFgScrollX = d & 0x3ff; + return; + } + + case 0xfd0004: { + DrvBgScrollY = d & 0x1ff; + return; + } + + case 0xfd0006: { + DrvBgScrollX = d & 0x3ff; + return; + } + + case 0xfd0008: + case 0xfd000e: { + // ??? + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("68K Write word => %06X, %04X\n"), a, d); + } + } +} + +unsigned char __fastcall MadgearZ80Read(unsigned short a) +{ + switch (a) { + case 0xf000: { + return BurnYM2203Read(0, 0); + } + + case 0xf002: { + return BurnYM2203Read(1, 0); + } + + case 0xf006: { + return DrvSoundLatch; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 Read => %04X\n"), a); + } + } + + return 0; +} + +void __fastcall MadgearZ80Write(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xf000: { + BurnYM2203Write(0, 0, d); + return; + } + + case 0xf001: { + BurnYM2203Write(0, 1, d); + return; + } + + case 0xf002: { + BurnYM2203Write(1, 0, d); + return; + } + + case 0xf003: { + BurnYM2203Write(1, 1, d); + return; + } + + case 0xf004: { + MSM6295Command(0, d); + return; + } + + case 0xf00a: { + DrvZ80RomBank = d & 1; + ZetMapArea(0x8000, 0xbfff, 0, DrvZ80Rom + 0x8000 + DrvZ80RomBank * 0x4000 ); + ZetMapArea(0x8000, 0xbfff, 2, DrvZ80Rom + 0x8000 + DrvZ80RomBank * 0x4000 ); + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 Write => %04X, %02X\n"), a, d); + } + } +} + +void __fastcall Lastduel68KWriteByte(unsigned int a, unsigned char d) +{ + switch (a) { + case 0xfc4001: { + // flip + return; + } + + case 0xfc4003: { + DrvSoundLatch = d & 0xff; + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("68K Write byte => %06X, %02X\n"), a, d); + } + } +} + +unsigned short __fastcall Lastduel68KReadWord(unsigned int a) +{ + switch (a) { + case 0xfc4000: { + return 0xffff - ((DrvInput[1] << 8) | DrvInput[0]); + } + + case 0xfc4002: { + return 0xffff - DrvInput[2]; + } + + case 0xfc4004: { + return (DrvDip[1] << 8) | DrvDip[0]; + } + + case 0xfc4006: { + return DrvDip[2]; + } + + default: { + bprintf(PRINT_NORMAL, _T("68K Read Word => %06X\n"), a); + } + } + + return 0; +} + +void __fastcall Lastduel68KWriteWord(unsigned int a, unsigned short d) +{ + switch (a) { + case 0xfc0000: + case 0xfc0002: { + // NOP + return; + } + + case 0xfc8000: { + DrvFgScrollY = d & 0x1ff; + return; + } + + case 0xfc8002: { + DrvFgScrollX = d & 0x3ff; + return; + } + + case 0xfc8004: { + DrvBgScrollY = d & 0x1ff; + return; + } + + case 0xfc8006: { + DrvBgScrollX = d & 0x3ff; + return; + } + + case 0xfc8008: + case 0xfc800e: { + // ??? + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("68K Write word => %06X, %04X\n"), a, d); + } + } +} + +unsigned char __fastcall LastduelZ80Read(unsigned short a) +{ + switch (a) { + case 0xe800: { + return BurnYM2203Read(0, 0); + } + + case 0xf000: { + return BurnYM2203Read(1, 0); + } + + case 0xf800: { + return DrvSoundLatch; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 Read => %04X\n"), a); + } + } + + return 0; +} + +void __fastcall LastduelZ80Write(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xe800: { + BurnYM2203Write(0, 0, d); + return; + } + + case 0xe801: { + BurnYM2203Write(0, 1, d); + return; + } + + case 0xf000: { + BurnYM2203Write(1, 0, d); + return; + } + + case 0xf001: { + BurnYM2203Write(1, 1, d); + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 Write => %04X, %02X\n"), a, d); + } + } +} + +inline static void DrvYM2203IRQHandler(int, int nStatus) +{ + if (nStatus & 1) { + ZetSetIRQLine(0xff, ZET_IRQSTATUS_ACK); + } else { + ZetSetIRQLine(0, ZET_IRQSTATUS_NONE); + } +} + +inline static int DrvSynchroniseStream(int nSoundRate) +{ + return (long long)ZetTotalCycles() * nSoundRate / 3579545; +} + +inline static double DrvGetTime() +{ + return (double)ZetTotalCycles() / 3579545; +} + +static int CharPlaneOffsets[2] = { 4, 0 }; +static int CharXOffsets[8] = { 0, 1, 2, 3, 8, 9, 10, 11 }; +static int CharYOffsets[8] = { 0, 16, 32, 48, 64, 80, 96, 112 }; +static int BgTilePlaneOffsets[4] = { 12, 8, 4, 0 }; +static int FgTilePlaneOffsets[4] = { 4, 12, 0, 8 }; +static int TileXOffsets[16] = { 0, 1, 2, 3, 16, 17, 18, 19, 512, 513, 514, 515, 528, 529, 530, 531 }; +static int TileYOffsets[16] = { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480 }; +static int SpritePlaneOffsets[4] = { 0, 0x100000, 0x200000, 0x300000 }; +static int SpriteXOffsets[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 128, 129, 130, 131, 132, 133, 134, 135 }; +static int SpriteYOffsets[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }; +static int LdFgTilePlaneOffsets[4] = { 4, 0, 0x200004, 0x200000 }; +static int LdBgTilePlaneOffsets[4] = { 4, 0, 0x100004, 0x100000 }; +static int LdTileXOffsets[16] = { 0, 1, 2, 3, 8, 9, 10, 11, 256, 257, 258, 259, 264, 265, 266, 267 }; +static int LdTileYOffsets[16] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240 }; + +static int DrvInit() +{ + int nRet = 0, nLen; + + // Allocate and Blank all required memory + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + DrvTempRom = (unsigned char *)malloc(0x80000); + + // Load 68000 Program Roms + nRet = BurnLoadRom(Drv68KRom + 0x00001, 0, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x00000, 1, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x40001, 2, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x40000, 3, 2); if (nRet != 0) return 1; + + // Load Z80 Program Rom + nRet = BurnLoadRom(DrvZ80Rom, 4, 1); if (nRet != 0) return 1; + + // Load and decode the chars + nRet = BurnLoadRom(DrvTempRom, 5, 1); if (nRet != 0) return 1; + GfxDecode(0x0800, 2, 8, 8, CharPlaneOffsets, CharXOffsets, CharYOffsets, 0x80, DrvTempRom, DrvChars); + + // Load and decode the bg tiles + memset(DrvTempRom, 0, 0x80000); + nRet = BurnLoadRom(DrvTempRom, 6, 1); if (nRet != 0) return 1; + GfxDecode(0x0800, 4, 16, 16, BgTilePlaneOffsets, TileXOffsets, TileYOffsets, 0x400, DrvTempRom, DrvBgTiles); + + // Load and decode the fg tiles + memset(DrvTempRom, 0, 0x80000); + nRet = BurnLoadRom(DrvTempRom, 7, 1); if (nRet != 0) return 1; + GfxDecode(0x1000, 4, 16, 16, FgTilePlaneOffsets, TileXOffsets, TileYOffsets, 0x400, DrvTempRom, DrvFgTiles); + + // Load and decode the sprites + memset(DrvTempRom, 0, 0x80000); + nRet = BurnLoadRom(DrvTempRom + 0x00000, 8, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x10000, 9, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x20000, 10, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x30000, 11, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x40000, 12, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x50000, 13, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x60000, 14, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x70000, 15, 1); if (nRet != 0) return 1; + GfxDecode(0x1000, 4, 16, 16, SpritePlaneOffsets, SpriteXOffsets, SpriteYOffsets, 0x100, DrvTempRom, DrvSprites); + + // Load the samples + nRet = BurnLoadRom(MSM6295ROM + 0x00000, 16, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(MSM6295ROM + 0x20000, 17, 1); if (nRet != 0) return 1; + + free(DrvTempRom); + + // Setup the 68000 emulation + SekInit(0, 0x68000); + SekOpen(0); + SekMapMemory(Drv68KRom , 0x000000, 0x07ffff, SM_ROM); + SekMapMemory(DrvSpriteRam , 0xfc1800, 0xfc1fff, SM_RAM); + SekMapMemory(DrvVideoRam , 0xfc8000, 0xfc9fff, SM_RAM); + SekMapMemory(DrvPaletteRam , 0xfcc000, 0xfcc7ff, SM_RAM); + SekMapMemory(DrvScroll1Ram , 0xfd4000, 0xfd7fff, SM_RAM); + SekMapMemory(DrvScroll2Ram , 0xfd8000, 0xfdffff, SM_RAM); + SekMapMemory(Drv68KRam , 0xff0000, 0xffffff, SM_RAM); + SekSetWriteWordHandler(0, Madgear68KWriteWord); + SekSetReadByteHandler(0, Madgear68KReadByte); + SekClose(); + + // Setup the Z80 emulation + ZetInit(1); + ZetOpen(0); + ZetSetReadHandler(MadgearZ80Read); + ZetSetWriteHandler(MadgearZ80Write); + ZetMapArea(0x0000, 0x7fff, 0, DrvZ80Rom ); + ZetMapArea(0x0000, 0x7fff, 2, DrvZ80Rom ); + ZetMapArea(0x8000, 0xbfff, 0, DrvZ80Rom + 0x8000 ); + ZetMapArea(0x8000, 0xbfff, 2, DrvZ80Rom + 0x8000 ); + ZetMapArea(0xd000, 0xd7ff, 0, DrvZ80Ram ); + ZetMapArea(0xd000, 0xd7ff, 1, DrvZ80Ram ); + ZetMapArea(0xd000, 0xd7ff, 2, DrvZ80Ram ); + ZetMemEnd(); + ZetClose(); + + GenericTilesInit(); + DrvSpritePriMask = 0x10; + DrvSpriteFlipYMask = 0x80; + + BurnYM2203Init(2, 3579545, &DrvYM2203IRQHandler, DrvSynchroniseStream, DrvGetTime, 0); + BurnTimerAttachZet(3579545); + + MSM6295Init(0, 7575, 98, 1); + + // Reset the driver + MadgearDoReset(); + + return 0; +} + +static int LastduelInit() +{ + int nRet = 0, nLen, nRomOffset = 0, Lstduelb = 0; + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "lstduelb")) Lstduelb = 1; + if (Lstduelb) nRomOffset = 2; + + // Allocate and Blank all required memory + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + DrvTempRom = (unsigned char *)malloc(0x80000); + + // Load 68000 Program Roms + if (!Lstduelb) { + nRet = BurnLoadRom(Drv68KRom + 0x00001, 0, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x00000, 1, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x40001, 2, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x40000, 3, 2); if (nRet != 0) return 1; + } else { + nRet = BurnLoadRom(Drv68KRom + 0x00001, 0, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x00000, 1, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x20001, 2, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x20000, 3, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x40001, 4, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68KRom + 0x40000, 5, 2); if (nRet != 0) return 1; + } + + // Load Z80 Program Rom + nRet = BurnLoadRom(DrvZ80Rom, 4 + nRomOffset, 1); if (nRet != 0) return 1; + + // Load and decode the chars + nRet = BurnLoadRom(DrvTempRom, 5 + nRomOffset, 1); if (nRet != 0) return 1; + GfxDecode(0x0800, 2, 8, 8, CharPlaneOffsets, CharXOffsets, CharYOffsets, 0x80, DrvTempRom, DrvChars); + + // Load and decode the bg tiles + memset(DrvTempRom, 0, 0x80000); + nRet = BurnLoadRom(DrvTempRom + 0x00000, 6 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x10000, 7 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x20000, 8 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x30000, 9 + nRomOffset, 1); if (nRet != 0) return 1; + GfxDecode(0x0800, 4, 16, 16, LdBgTilePlaneOffsets, LdTileXOffsets, LdTileYOffsets, 0x200, DrvTempRom, DrvBgTiles); + + // Load and decode the fg tiles + memset(DrvTempRom, 0, 0x80000); + nRet = BurnLoadRom(DrvTempRom + 0x00000, 10 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x10000, 11 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x20000, 12 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x30000, 13 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x40000, 14 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x50000, 15 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x60000, 16 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x70000, 17 + nRomOffset, 1); if (nRet != 0) return 1; + GfxDecode(0x1000, 4, 16, 16, LdFgTilePlaneOffsets, LdTileXOffsets, LdTileYOffsets, 0x200, DrvTempRom, DrvFgTiles); + + // Load and decode the sprites + memset(DrvTempRom, 0, 0x80000); + nRet = BurnLoadRom(DrvTempRom + 0x00000, 18 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x10000, 19 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x20000, 20 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x30000, 21 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x40000, 22 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x50000, 23 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x60000, 24 + nRomOffset, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempRom + 0x70000, 25 + nRomOffset, 1); if (nRet != 0) return 1; + GfxDecode(0x1000, 4, 16, 16, SpritePlaneOffsets, SpriteXOffsets, SpriteYOffsets, 0x100, DrvTempRom, DrvSprites); + + free(DrvTempRom); + + // Setup the 68000 emulation + SekInit(0, 0x68000); + SekOpen(0); + SekMapMemory(Drv68KRom , 0x000000, 0x05ffff, SM_ROM); + SekMapMemory(DrvSpriteRam , 0xfc0800, 0xfc0fff, SM_RAM); + SekMapMemory(DrvVideoRam , 0xfcc000, 0xfcdfff, SM_RAM); + SekMapMemory(DrvScroll1Ram , 0xfd0000, 0xfd3fff, SM_RAM); + SekMapMemory(DrvScroll2Ram , 0xfd4000, 0xfd7fff, SM_RAM); + SekMapMemory(DrvPaletteRam , 0xfd8000, 0xfd87ff, SM_RAM); + SekMapMemory(Drv68KRam , 0xfe0000, 0xffffff, SM_RAM); + SekSetReadWordHandler(0, Lastduel68KReadWord); + SekSetWriteWordHandler(0, Lastduel68KWriteWord); + SekSetWriteByteHandler(0, Lastduel68KWriteByte); + SekClose(); + + // Setup the Z80 emulation + ZetInit(1); + ZetOpen(0); + ZetSetReadHandler(LastduelZ80Read); + ZetSetWriteHandler(LastduelZ80Write); + ZetMapArea(0x0000, 0xdfff, 0, DrvZ80Rom ); + ZetMapArea(0x0000, 0xdfff, 2, DrvZ80Rom ); + ZetMapArea(0xe000, 0xe7ff, 0, DrvZ80Ram ); + ZetMapArea(0xe000, 0xe7ff, 1, DrvZ80Ram ); + ZetMapArea(0xe000, 0xe7ff, 2, DrvZ80Ram ); + ZetMemEnd(); + ZetClose(); + + GenericTilesInit(); + DrvSpritePriMask = 0x00; + DrvSpriteFlipYMask = 0x40; + + BurnYM2203Init(2, 3579545, &DrvYM2203IRQHandler, DrvSynchroniseStream, DrvGetTime, 0); + BurnTimerAttachZet(3579545); + + // Reset the driver + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + SekExit(); + ZetExit(); + + BurnYM2203Exit(); + MSM6295Exit(0); + + GenericTilesExit(); + + DrvFgScrollX = 0; + DrvFgScrollY = 0; + DrvBgScrollX = 0; + DrvBgScrollY = 0; + DrvSpritePriMask = 0; + DrvSpriteFlipYMask = 0; + DrvZ80RomBank = 0; + DrvSoundLatch = 0; + + free(Mem); + Mem = NULL; + + return 0; +} + +static int MadgearExit() +{ + MSM6295Exit(0); + DrvExit(); + + return 0; +} + +inline static unsigned int CalcCol(unsigned short nColour) +{ + static const unsigned char ztable[16] = { 0x0, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11 }; + int i, r, g, b; + + i = ztable[(nColour >> 0) & 15]; + r = ((nColour >> 12) & 15) * i; + g = ((nColour >> 8) & 15) * i; + b = ((nColour >> 4) & 15) * i; + + return BurnHighCol(r, g, b, 0); +} + +static void DrvCalcPalette() +{ + int i; + unsigned short* ps; + unsigned int* pd; + + for (i = 0, ps = (unsigned short*)DrvPaletteRam, pd = DrvPalette; i < 0x800; i++, ps++, pd++) { + *pd = CalcCol(*ps); + } +} + +static void DrvRenderBgLayer() +{ + int mx, my, Code, Colour, x, y, TileIndex, Flip, xFlip, yFlip; + + UINT16 *VideoRam = (UINT16*)DrvScroll2Ram; + + for (mx = 0; mx < 32; mx++) { + for (my = 0; my < 64; my++) { + TileIndex = (my * 32) + mx; + Code = VideoRam[TileIndex] & 0x1fff; + Colour = VideoRam[TileIndex + 0x800]; + Flip = (Colour & 0x60) >> 5; + xFlip = (Flip >> 0) & 0x01; + yFlip = (Flip >> 1) & 0x01; + Colour &= 0x0f; + + y = 16 * mx; + x = 16 * my; + + x -= DrvBgScrollX; + y -= DrvBgScrollY; + if (x < -16) x += 1024; + if (y < -16) y += 512; + x -= 64; + y -= 8; + + if (x > 16 && x < 368 && y > 16 && y < 224) { + if (xFlip) { + if (yFlip) { + Render16x16Tile_FlipXY(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } else { + Render16x16Tile_FlipX(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } + } else { + if (yFlip) { + Render16x16Tile_FlipY(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } else { + Render16x16Tile(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } + } + } else { + if (xFlip) { + if (yFlip) { + Render16x16Tile_FlipXY_Clip(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } else { + Render16x16Tile_FlipX_Clip(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } + } else { + if (yFlip) { + Render16x16Tile_FlipY_Clip(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } else { + Render16x16Tile_Clip(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } + } + } + } + } +} + +static void DrvRenderFgLayer(int Priority) +{ + int mx, my, Code, Colour, x, y, TileIndex, Split, Flip, xFlip, yFlip; + + UINT16 *VideoRam = (UINT16*)DrvScroll1Ram; + + for (mx = 0; mx < 32; mx++) { + for (my = 0; my < 64; my++) { + TileIndex = (my * 32) + mx; + Code = VideoRam[TileIndex] & 0x1fff; + Colour = VideoRam[TileIndex + 0x800]; + Flip = (Colour & 0x60) >> 5; + xFlip = (Flip >> 0) & 0x01; + yFlip = (Flip >> 1) & 0x01; + Split = (Colour & 0x10) >> 4; + Colour &= 0x0f; + + if (Split != Priority) continue; + + y = 16 * mx; + x = 16 * my; + + x -= DrvFgScrollX; + y -= DrvFgScrollY; + if (x < -16) x += 1024; + if (y < -16) y += 512; + x -= 64; + y -= 8; + + if (x > 16 && x < 368 && y > 16 && y < 224) { + if (xFlip) { + if (yFlip) { + Render16x16Tile_Mask_FlipXY(pTransDraw, Code, x, y, Colour, 4, 0x0f, 0x100, DrvFgTiles); + } else { + Render16x16Tile_Mask_FlipX(pTransDraw, Code, x, y, Colour, 4, 0x0f, 0x100, DrvFgTiles); + } + } else { + if (yFlip) { + Render16x16Tile_Mask_FlipY(pTransDraw, Code, x, y, Colour, 4, 0x0f, 0x100, DrvFgTiles); + } else { + Render16x16Tile_Mask(pTransDraw, Code, x, y, Colour, 4, 0x0f, 0x100, DrvFgTiles); + } + } + } else { + if (xFlip) { + if (yFlip) { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, Code, x, y, Colour, 4, 0x0f, 0x100, DrvFgTiles); + } else { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, Code, x, y, Colour, 4, 0x0f, 0x100, DrvFgTiles); + } + } else { + if (yFlip) { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, Code, x, y, Colour, 4, 0x0f, 0x100, DrvFgTiles); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 4, 0x0f, 0x100, DrvFgTiles); + } + } + } + } + } +} + +static void LastduelRenderBgLayer() +{ + int mx, my, Code, Colour, x, y, TileIndex = 0, Flip, xFlip, yFlip; + + UINT16 *VideoRam = (UINT16*)DrvScroll2Ram; + + for (my = 0; my < 64; my++) { + for (mx = 0; mx < 64; mx++) { + Code = VideoRam[2 * TileIndex] & 0x1fff; + Colour = VideoRam[2 * TileIndex + 1]; + Flip = (Colour & 0x60) >> 5; + xFlip = (Flip >> 0) & 0x01; + yFlip = (Flip >> 1) & 0x01; + Colour &= 0x0f; + + x = 16 * mx; + y = 16 * my; + + x -= DrvBgScrollX; + y -= DrvBgScrollY; + if (x < -16) x += 1024; + if (y < -16) y += 1024; + x -= 64; + y -= 8; + + if (x > 16 && x < 368 && y > 16 && y < 224) { + if (xFlip) { + if (yFlip) { + Render16x16Tile_FlipXY(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } else { + Render16x16Tile_FlipX(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } + } else { + if (yFlip) { + Render16x16Tile_FlipY(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } else { + Render16x16Tile(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } + } + } else { + if (xFlip) { + if (yFlip) { + Render16x16Tile_FlipXY_Clip(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } else { + Render16x16Tile_FlipX_Clip(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } + } else { + if (yFlip) { + Render16x16Tile_FlipY_Clip(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } else { + Render16x16Tile_Clip(pTransDraw, Code, x, y, Colour, 4, 0, DrvBgTiles); + } + } + } + + TileIndex++; + } + } +} + +static void LastduelRenderFgLayer(int Priority) +{ + int mx, my, Code, Colour, x, y, TileIndex = 0, Split, Flip, xFlip, yFlip; + + UINT16 *VideoRam = (UINT16*)DrvScroll1Ram; + + for (my = 0; my < 64; my++) { + for (mx = 0; mx < 64; mx++) { + Code = VideoRam[2 * TileIndex] & 0x1fff; + Colour = VideoRam[2 * TileIndex + 1]; + Flip = (Colour & 0x60) >> 5; + xFlip = (Flip >> 0) & 0x01; + yFlip = (Flip >> 1) & 0x01; + Split = (Colour & 0x80) >> 7; + Colour &= 0x0f; + + if (Split != Priority) continue; + + x = 16 * mx; + y = 16 * my; + + x -= DrvFgScrollX; + y -= DrvFgScrollY; + if (x < -16) x += 1024; + if (y < -16) y += 1024; + x -= 64; + y -= 8; + + if (x > 16 && x < 368 && y > 16 && y < 224) { + if (xFlip) { + if (yFlip) { + Render16x16Tile_Mask_FlipXY(pTransDraw, Code, x, y, Colour, 4, 0, 0x100, DrvFgTiles); + } else { + Render16x16Tile_Mask_FlipX(pTransDraw, Code, x, y, Colour, 4, 0, 0x100, DrvFgTiles); + } + } else { + if (yFlip) { + Render16x16Tile_Mask_FlipY(pTransDraw, Code, x, y, Colour, 4, 0, 0x100, DrvFgTiles); + } else { + Render16x16Tile_Mask(pTransDraw, Code, x, y, Colour, 4, 0, 0x100, DrvFgTiles); + } + } + } else { + if (xFlip) { + if (yFlip) { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 0x100, DrvFgTiles); + } else { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 0x100, DrvFgTiles); + } + } else { + if (yFlip) { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 0x100, DrvFgTiles); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 0x100, DrvFgTiles); + } + } + } + + TileIndex++; + } + } +} + +static void DrvRenderSprites(int Priority) +{ + int Offset; + UINT16 *SpriteRam = (UINT16*)DrvSpriteRamBuffer; + + for (Offset = 0x400 - 4; Offset >= 0; Offset -= 4) { + int Attr, sy, sx, xFlip, yFlip, Code, Colour; + + Attr = SpriteRam[Offset + 1]; + if (DrvSpritePriMask) { + if (Priority == 1 && (Attr & DrvSpritePriMask)) continue; + if (Priority == 0 && !(Attr & DrvSpritePriMask)) continue; + } + + Code = SpriteRam[Offset] & 0xfff; + sx = SpriteRam[Offset + 3] & 0x1ff; + sy = SpriteRam[Offset + 2] & 0x1ff; + if (sy > 0x100) sy -= 0x200; + + xFlip = Attr & 0x20; + yFlip = Attr & DrvSpriteFlipYMask; + Colour = Attr & 0x0f; + + sx -= 64; + sy -= 8; + + if (sx > 16 && sx < 368 && sy > 16 && sy < 224) { + if (xFlip) { + if (yFlip) { + Render16x16Tile_Mask_FlipXY(pTransDraw, Code, sx, sy, Colour, 4, 0x0f, 0x200, DrvSprites); + } else { + Render16x16Tile_Mask_FlipX(pTransDraw, Code, sx, sy, Colour, 4, 0x0f, 0x200, DrvSprites); + } + } else { + if (yFlip) { + Render16x16Tile_Mask_FlipY(pTransDraw, Code, sx, sy, Colour, 4, 0x0f, 0x200, DrvSprites); + } else { + Render16x16Tile_Mask(pTransDraw, Code, sx, sy, Colour, 4, 0x0f, 0x200, DrvSprites); + } + } + } else { + if (xFlip) { + if (yFlip) { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0x0f, 0x200, DrvSprites); + } else { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0x0f, 0x200, DrvSprites); + } + } else { + if (yFlip) { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0x0f, 0x200, DrvSprites); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0x0f, 0x200, DrvSprites); + } + } + } + } +} + +static void DrvRenderCharLayer() +{ + int mx, my, Code, Colour, x, y, yFlip, TileIndex = 0; + + UINT16 *VideoRam = (UINT16*)DrvVideoRam; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 64; mx++) { + yFlip = 0; + Code = VideoRam[TileIndex]; + Colour = Code >> 12; + if (Code & 0x800) yFlip = 1; + Code &= 0x7ff; + + x = 8 * mx; + y = 8 * my; + + x -= 64; + y -= 8; + + if (x > 0 && x < 376 && y > 8 && y < 232) { + if (yFlip) { + Render8x8Tile_Mask_FlipY(pTransDraw, Code, x, y, Colour, 2, 3, 0x300, DrvChars); + } else { + Render8x8Tile_Mask(pTransDraw, Code, x, y, Colour, 2, 3, 0x300, DrvChars); + } + } else { + if (yFlip) { + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, Code, x, y, Colour, 2, 3, 0x300, DrvChars); + } else { + Render8x8Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 2, 3, 0x300, DrvChars); + } + } + + TileIndex++; + } + } +} + +static void DrvDraw() +{ + BurnTransferClear(); + DrvCalcPalette(); + DrvRenderBgLayer(); + DrvRenderFgLayer(0); + DrvRenderSprites(0); + DrvRenderFgLayer(1); + DrvRenderSprites(1); + DrvRenderCharLayer(); + BurnTransferCopy(DrvPalette); +} + +static void LastduelDraw() +{ + BurnTransferClear(); + DrvCalcPalette(); + LastduelRenderBgLayer(); + LastduelRenderFgLayer(0); + DrvRenderSprites(0); + LastduelRenderFgLayer(1); + DrvRenderCharLayer(); + BurnTransferCopy(DrvPalette); +} + +static int DrvFrame() +{ + int nInterleave = 10; + + if (DrvReset) MadgearDoReset(); + + DrvMakeInputs(); + + nCyclesTotal[0] = 10000000 / 60; + nCyclesTotal[1] = 3579545 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + SekNewFrame(); + ZetNewFrame(); + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run 68000 + nCurrentCPU = 0; + SekOpen(0); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += SekRun(nCyclesSegment); + if (i == 3 || i == 6) SekSetIRQLine(6, SEK_IRQSTATUS_AUTO); + SekClose(); + } + + ZetOpen(0); + BurnTimerEndFrame(nCyclesTotal[1]); + BurnYM2203Update(pBurnSoundOut, nBurnSoundLen); + ZetClose(); + MSM6295Render(0, pBurnSoundOut, nBurnSoundLen); + + if (pBurnDraw) DrvDraw(); + + SekOpen(0); + SekSetIRQLine(5, SEK_IRQSTATUS_AUTO); + SekClose(); + + memcpy(DrvSpriteRamBuffer, DrvSpriteRam, 0x800); + + return 0; +} + +static int LastduelFrame() +{ + int nInterleave = 10; + + if (DrvReset) DrvDoReset(); + + DrvMakeInputs(); + + nCyclesTotal[0] = 10000000 / 60; + nCyclesTotal[1] = 3579545 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + SekNewFrame(); + ZetNewFrame(); + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run 68000 + nCurrentCPU = 0; + SekOpen(0); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += SekRun(nCyclesSegment); + if (i == 3 || i == 6) SekSetIRQLine(4, SEK_IRQSTATUS_AUTO); + SekClose(); + } + + ZetOpen(0); + BurnTimerEndFrame(nCyclesTotal[1] - nCyclesDone[1]); + BurnYM2203Update(pBurnSoundOut, nBurnSoundLen); + ZetClose(); + + if (pBurnDraw) LastduelDraw(); + + SekOpen(0); + SekSetIRQLine(2, SEK_IRQSTATUS_AUTO); + SekClose(); + + memcpy(DrvSpriteRamBuffer, DrvSpriteRam, 0x800); + + return 0; +} + +static int DrvScan(int nAction, int *pnMin) +{ + struct BurnArea ba; + + if (pnMin != NULL) { // Return minimum compatible version + *pnMin = 0x029672; + } + + if (nAction & ACB_MEMORY_RAM) { + memset(&ba, 0, sizeof(ba)); + ba.Data = RamStart; + ba.nLen = RamEnd-RamStart; + ba.szName = "All Ram"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + SekScan(nAction); + ZetScan(nAction); // Scan Z80 + BurnYM2203Scan(nAction, pnMin); + + // Scan critical driver variables + SCAN_VAR(nCyclesDone); + SCAN_VAR(nCyclesSegment); + SCAN_VAR(DrvZ80RomBank); + SCAN_VAR(DrvSoundLatch); + SCAN_VAR(DrvFgScrollX); + SCAN_VAR(DrvFgScrollY); + SCAN_VAR(DrvBgScrollX); + SCAN_VAR(DrvBgScrollY); + SCAN_VAR(DrvDip); + SCAN_VAR(DrvInput); + } + + return 0; +} + +static int MadgearScan(int nAction, int *pnMin) +{ + int i = DrvScan(nAction, pnMin); + + if (i == 0) { + if (nAction & ACB_DRIVER_DATA) { + MSM6295Scan(0, nAction); + } + + if (nAction & ACB_WRITE) { + ZetOpen(0); + ZetMapArea(0x8000, 0xbfff, 0, DrvZ80Rom + 0x8000 + DrvZ80RomBank * 0x4000 ); + ZetMapArea(0x8000, 0xbfff, 2, DrvZ80Rom + 0x8000 + DrvZ80RomBank * 0x4000 ); + ZetClose(); + } + } + + return i; +} + +struct BurnDriver BurnDrvLastduel = { + "lastduel", NULL, NULL, "1988", + "Last Duel (US set 1)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, LastduelRomInfo, LastduelRomName, LastduelInputInfo, LastduelDIPInfo, + LastduelInit, DrvExit, LastduelFrame, NULL, DrvScan, + 0, NULL, NULL, NULL, NULL, 240, 384, 3, 4 +}; + +struct BurnDriver BurnDrvLstduela = { + "lstduela", "lastduel", NULL, "1988", + "Last Duel (US set 2)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, LstduelaRomInfo, LstduelaRomName, LastduelInputInfo, LastduelDIPInfo, + LastduelInit, DrvExit, LastduelFrame, NULL, DrvScan, + 0, NULL, NULL, NULL, NULL, 240, 384, 3, 4 +}; + +struct BurnDriver BurnDrvLstduelb = { + "lstduelb", "lastduel", NULL, "1988", + "Last Duel (bootleg)\0", NULL, "bootleg", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_BOOTLEG, 2, HARDWARE_MISC_PRE90S, + NULL, LstduelbRomInfo, LstduelbRomName, LastduelInputInfo, LastduelDIPInfo, + LastduelInit, DrvExit, LastduelFrame, NULL, DrvScan, + 0, NULL, NULL, NULL, NULL, 240, 384, 3, 4 +}; + +struct BurnDriver BurnDrvMadgear = { + "madgear", NULL, NULL, "1989", + "Mad Gear (US)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, DrvRomInfo, DrvRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, MadgearExit, DrvFrame, NULL, MadgearScan, + 0, NULL, NULL, NULL, NULL, 240, 384, 3, 4 +}; + +struct BurnDriver BurnDrvMadgearj = { + "madgearj", "madgear", NULL, "1989", + "Mad Gear (Japan)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, DrvjRomInfo, DrvjRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, MadgearExit, DrvFrame, NULL, MadgearScan, + 0, NULL, NULL, NULL, NULL, 240, 384, 3, 4 +}; + +struct BurnDriver BurnDrvMadgearu = { + "ledstorm", "madgear", NULL, "1988", + "Led Storm (US)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, DrvuRomInfo, DrvuRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, MadgearExit, DrvFrame, NULL, MadgearScan, + 0, NULL, NULL, NULL, NULL, 240, 384, 3, 4 +}; + +struct BurnDriver BurnDrvLedstrm2 = { + "ledstrm2", "madgear", NULL, "1988", + "Led Storm Rally 2011 (US)\0", NULL, "Capcom", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, Ledstrm2RomInfo, Ledstrm2RomName, DrvInputInfo, DrvDIPInfo, + DrvInit, MadgearExit, DrvFrame, NULL, MadgearScan, + 0, NULL, NULL, NULL, NULL, 240, 384, 3, 4 +}; diff --git a/src/burn/misc/pre90s/d_meijinsn.cpp b/src/burn/misc/pre90s/d_meijinsn.cpp new file mode 100644 index 0000000..c09c6a0 --- /dev/null +++ b/src/burn/misc/pre90s/d_meijinsn.cpp @@ -0,0 +1,571 @@ +// FB Alpha Meijinsen Driver Module +// Based on MAME driver by Tomasz Slanina + +#include "burnint.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +static unsigned int *Palette; +static unsigned char *Mem, *M68KRom, *Z80Rom, *Prom; +static short *pFMBuffer, *pAY8910Buffer[3]; +static unsigned char DrvJoy1[9], DrvJoy2[8], DrvReset, DrvDips; +static unsigned char soundlatch, deposits1, deposits2, credits; + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 6, "p1 coin" }, + {"Coin 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 coin" }, + {"Start 1", BIT_DIGITAL, DrvJoy1 + 7, "p1 start" }, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 7, "p2 start" }, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up" }, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 1, "p1 down" }, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right" }, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 3, "p1 left" }, + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 1" }, + {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 5, "p1 fire 2" }, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up" }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 1, "p2 down" }, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right" }, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 3, "p2 left" }, + {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p2 fire 1" }, + {"P2 Button 2", BIT_DIGITAL, DrvJoy2 + 5, "p2 fire 2" }, + + {"Clear Credit", BIT_DIGITAL, DrvJoy1 + 8, "clear credit" }, + {"Reset", BIT_DIGITAL, &DrvReset, "reset" }, + {"Dip Switches", BIT_DIPSWITCH, &DrvDips, "dip" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[] = +{ + // Defaults + {0x12, 0xFF, 0xFF, 0x00, NULL}, + + {0, 0xFE, 0, 8, "Game time (actual game)"}, + {0x12, 0x01, 0x07, 0x07, "01:00"}, + {0x12, 0x01, 0x07, 0x06, "02:00"}, + {0x12, 0x01, 0x07, 0x05, "03:00"}, + {0x12, 0x01, 0x07, 0x04, "04:00"}, + {0x12, 0x01, 0x07, 0x03, "05:00"}, + {0x12, 0x01, 0x07, 0x02, "10:00"}, + {0x12, 0x01, 0x07, 0x01, "20:00"}, + {0x12, 0x01, 0x07, 0x00, "00:30"}, + + {0, 0xFE, 0, 2, "Coinage"}, + {0x12, 0x01, 0x08, 0x08, "A 1C/1C B 1C/5C"}, + {0x12, 0x01, 0x08, 0x00, "A 1C/2C B 2C/1C"}, + + {0, 0xFE, 0, 2, "2 Player"}, + {0x12, 0x01, 0x10, 0x00, "1C"}, + {0x12, 0x01, 0x10, 0x10, "2C"}, + + {0, 0xFE, 0, 2, "Game time (tsumeshougi)"}, + {0x12, 0x01, 0x20, 0x20, "01:00"}, + {0x12, 0x01, 0x20, 0x00, "02:00"}, +}; + +STDDIPINFO(Drv); + + +unsigned short inputs(int inp) +{ + unsigned char ret = 0; + + switch (inp) + { + case 0x00: { // start + service + ret |= DrvJoy1[7] << 0; // + ret |= DrvJoy2[7] << 1; + ret |= DrvJoy1[8] << 7; // clear credit + } + break; + + case 0x01: { // player 1 controls + for (int i = 0; i < 6; i++) ret |= DrvJoy1[i] << i; + } + break; + + case 0x02: { // player 2 controls + for (int i = 0; i < 6; i++) ret |= DrvJoy2[i] << i; + } + break; + + case 0x03: { // coins + ret = (DrvJoy1[6] | (DrvJoy2[6] << 1)) ^ 3; + } + break; + + break; + } + + return ret; +} + +unsigned char soundlatch_r(unsigned int) +{ + return soundlatch; +} + +unsigned char __fastcall alpha_mcu_r(unsigned char offset) +{ + static unsigned coinvalue = 0; + static const unsigned char coinage1[2][2] = { {1, 1}, {1, 2} }; + static const unsigned char coinage2[2][2] = { {1, 5}, {2, 1} }; + + static int latch; + + switch (offset) + { + case 0x01: // Dipswitch 2 + M68KRom[0x180e44] = DrvDips & 0xff; + return 0; + + case 0x45: // Coin value + M68KRom[0x180e44] = credits & 0xff; + return 0; + + case 0x53: // Query microcontroller for coin insert + { + credits = 0; + + if ((inputs(3) & 0x03) == 0x03) latch = 0; + + M68KRom[0x180e52] = 0x22; + + if ((inputs(3) & 0x03) != 0x03 && latch == 0) + { + M68KRom[0x180e44] = 0x00; + + latch = 1; + + coinvalue = (~DrvDips>>3) & 1; + + if (~inputs(3) & 0x01) + { + deposits1++; + if (deposits1 == coinage1[coinvalue][0]) + { + credits = coinage1[coinvalue][1]; + deposits1 = 0; + } + else + credits = 0; + } + else if (~inputs(3) & 0x02) + { + deposits2++; + if (deposits2 == coinage2[coinvalue][0]) + { + credits = coinage2[coinvalue][1]; + deposits2 = 0; + } + else + credits = 0; + } + } + } + + return 0; + } + + return 0; +} + +unsigned char __fastcall meijinsn_read_byte(unsigned int a) +{ + if ((a & ~0xff) == 0x080e00) { + return alpha_mcu_r(a & 0xff); + } + + switch (a) + { + case 0x1a0000: + return inputs(0); + + case 0x1a0001: + return inputs(1); + + case 0x1c0000: + return inputs(2); + } + + return 0; +} + +void __fastcall meijinsn_write_byte(unsigned int a, unsigned char d) +{ + if (a == 0x1a0001) { + soundlatch = d & 0xff; + return; + } +} + + +unsigned char __fastcall meijinsn_in_port(unsigned short a) +{ + if ((a & 0xff) == 0x01) { // AY8910 read port + return AY8910Read(0); + } + + return 0; +} + +void __fastcall meijinsn_out_port(unsigned short a, unsigned char data) +{ + switch (a & 0xff) + { + case 0x00: // AY8910 control port + AY8910Write(0, 0, data); + break; + + case 0x01: // AY8910 write port + AY8910Write(0, 1, data); + break; + + case 0x02: // Soundlatch clear + soundlatch = 0; + break; + } +} + +static int DrvDoReset() +{ + DrvReset = 0; + + memset (M68KRom + 0x100000, 0, 0x082000); // clear 68k RAM + memset (Z80Rom + 0x008000, 0, 0x000800); // clear z80 RAM + + deposits1 = 0; + deposits2 = 0; + credits = 0; + + ZetOpen(0); + ZetReset(); + ZetClose(); + + SekOpen(0); + SekReset(); + SekClose(); + + AY8910Reset(0); + + return 0; +} + +static void Pallete_Init() +{ +#define combine_3_weights(tab,w0,w1,w2) ((int)(((tab)[0]*(w0) + (tab)[1]*(w1) + (tab)[2]*(w2)) + 0.5)) + + float weights_r[3] = { 41.697944, 73.045335, 140.256721}; + float weights_g[3] = { 41.697944, 73.045335, 140.256721}; + float weights_b[3] = { 83.228546, 159.809836, 0.000000}; + + for (int i = 0; i < 0x10; i++) + { + int bit0,bit1,bit2,r,g,b; + + // red component + bit0 = (Prom[i] >> 0) & 0x01; + bit1 = (Prom[i] >> 1) & 0x01; + bit2 = (Prom[i] >> 2) & 0x01; + r = combine_3_weights(weights_r, bit0, bit1, bit2); + + // green component + bit0 = (Prom[i] >> 3) & 0x01; + bit1 = (Prom[i] >> 4) & 0x01; + bit2 = (Prom[i] >> 5) & 0x01; + g = combine_3_weights(weights_g, bit0, bit1, bit2); + + // blue component + bit0 = (Prom[i] >> 6) & 0x01; + bit1 = (Prom[i] >> 7) & 0x01; + b = combine_3_weights(weights_b, bit0, bit1, 0); + + Palette[i] = (r << 16) | (g << 8) | b; + } +} + +static int DrvInit() +{ + Mem = (unsigned char *)malloc(0x210060); + if (Mem == NULL) { + return 1; + } + + M68KRom = Mem + 0x000000; + Z80Rom = Mem + 0x200000; + Prom = Mem + 0x210000; + Palette = (unsigned int *)(Mem + 0x210020); + + pFMBuffer = (short *)malloc (nBurnSoundLen * 3 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + // Load roms + { + int i; + for (i = 0; i < 8; i+=2) { + BurnLoadRom(M68KRom + 0x100001, i + 0, 2); + BurnLoadRom(M68KRom + 0x100000, i + 1, 2); + + memcpy (M68KRom + 0x00000 + 0x08000 * (i >> 1), M68KRom + 0x100000, 0x08000); + memcpy (M68KRom + 0x20000 + 0x08000 * (i >> 1), M68KRom + 0x108000, 0x08000); + } + + BurnLoadRom(Z80Rom + 0x00000, 8, 1); + BurnLoadRom(Z80Rom + 0x04000, 9, 1); + BurnLoadRom(Prom, 10, 1); + } + + SekInit(0, 0x68000); + SekOpen(0); + SekSetReadByteHandler(0, meijinsn_read_byte); + SekSetWriteByteHandler(0, meijinsn_write_byte); + SekMapMemory(M68KRom, 0x000000, 0x03ffff, SM_ROM); + SekMapMemory(M68KRom + 0x100000, 0x100000, 0x181fff, SM_RAM); + SekClose(); + + ZetInit(1); + ZetOpen(0); + ZetSetInHandler(meijinsn_in_port); + ZetSetOutHandler(meijinsn_out_port); + ZetMapArea(0x0000, 0xffff, 0, Z80Rom); + ZetMapArea(0x0000, 0x7fff, 2, Z80Rom); + ZetMapArea(0x8000, 0x87ff, 1, Z80Rom + 0x8000); + ZetMemEnd(); + ZetClose(); + + AY8910Init(0, 2000000, nBurnSoundRate, &soundlatch_r, NULL, NULL, NULL); + + Pallete_Init(); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + AY8910Exit(0); + SekExit(); + ZetExit(); + + free (Mem); + Palette = NULL; + free (pFMBuffer); + Mem = M68KRom = Z80Rom = Prom = NULL; + pFMBuffer = NULL; + pAY8910Buffer[0] = pAY8910Buffer[1] = pAY8910Buffer[2] = NULL; + + return 0; +} + + +static int DrvDraw() +{ + for (int i = 0; i < 0x4000; i++) + { + int sx, sy, x, data1, data2, color, data; + + sx = (i >> 6) & 0xfc; + sy = i & 0xff; + + if (sy < 16 || sy > 239 || sx < 12 || sx > 240) continue; + sx -= 12; sy = (sy - 16) * 232; + + data1 = M68KRom[0x100001 + (i << 1)]; + data2 = M68KRom[0x100000 + (i << 1)]; + + for (x = 0; x < 4; x++) + { + color = ((data1 >> x) & 1) | ((data1 >> (3 + x)) & 2); + data = ((data2 >> x) & 1) | ((data2 >> (3 + x)) & 2); + + unsigned int c = Palette[(color << 2) | data]; + + PutPix(pBurnDraw + (sy + sx + (x ^ 3)) * nBurnBpp, BurnHighCol(c >> 16, c >> 8, c, 0)); + } + } + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + int nSoundBufferPos = 0; + int nInterleave = 100; + + int nCyclesSegment; + int nCyclesDone[2], nCyclesTotal[2]; + + nCyclesTotal[0] = 9000000 / 60; + nCyclesTotal[1] = 4000000 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + SekOpen(0); + ZetOpen(0); + + for (int i = 0; i < nInterleave; i++) { + int nNext; + + // Run 68k + nNext = (i + 1) * nCyclesTotal[0] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[0]; + nCyclesDone[0] += SekRun(nCyclesSegment); + if (i == 4) SekSetIRQLine(2, SEK_IRQSTATUS_AUTO); + + // Run Z80 #1 + nNext = (i + 1) * nCyclesTotal[1] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[1]; + nCyclesSegment = ZetRun(nCyclesSegment); + nCyclesDone[1] += nCyclesSegment; + + // Render Sound Segment + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + nSoundBufferPos += nSegmentLength; + } + } + + SekSetIRQLine(1, SEK_IRQSTATUS_AUTO); + ZetSetIRQLine(0, 0xa0); + ZetClose(); + SekClose(); + + // Make sure the buffer is entirely filled. + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + ba.Data = M68KRom + 0x100000; + ba.nLen = 0x082000; + ba.szName = "Main 68K Ram"; + BurnAcb(&ba); + + memset(&ba, 0, sizeof(ba)); + ba.Data = Z80Rom + 0x8000; + ba.nLen = 0x00800; + ba.szName = "Main Z80 Ram"; + BurnAcb(&ba); + + SekScan(nAction); // Scan 68K + ZetScan(nAction); // Scan Z80 + AY8910Scan(nAction, pnMin); // Scan AY8910 + + // Scan critical driver variables + SCAN_VAR(soundlatch); + SCAN_VAR(deposits1); + SCAN_VAR(deposits2); + SCAN_VAR(credits); + } + + return 0; +} + + +// Meijinsen + +static struct BurnRomInfo meijinsnRomDesc[] = { + { "p1", 0x08000, 0x8c9697a3, BRF_PRG | BRF_ESS }, // 0 M68000 Code + { "p2", 0x08000, 0xf7da3535, BRF_PRG | BRF_ESS }, // 1 + { "p3", 0x08000, 0x0af0b266, BRF_PRG | BRF_ESS }, // 2 + { "p4", 0x08000, 0xaab159c5, BRF_PRG | BRF_ESS }, // 3 + { "p5", 0x08000, 0x0ed10a47, BRF_PRG | BRF_ESS }, // 4 + { "p6", 0x08000, 0x60b58755, BRF_PRG | BRF_ESS }, // 5 + { "p7", 0x08000, 0x604c76f1, BRF_PRG | BRF_ESS }, // 6 + { "p8", 0x08000, 0xe3eaef19, BRF_PRG | BRF_ESS }, // 7 + + { "p9", 0x04000, 0xaedfefdf, BRF_PRG | BRF_ESS }, // 8 Z80 Code + { "p10", 0x04000, 0x93b4d764, BRF_PRG | BRF_ESS }, // 9 + + { "clr", 0x00020, 0x7b95b5a7, BRF_GRA }, // 10 Color Prom +}; + +STD_ROM_PICK(meijinsn); +STD_ROM_FN(meijinsn); + +struct BurnDriver BurnDrvMeijinsn = { + "meijinsn", NULL, NULL, "1986", + "Meijinsen\0", NULL, "SNK Electronics corp.", "Miscellaneous", + L"\u540D\u4EBA\u6226\0Meijinsen\0", NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, meijinsnRomInfo, meijinsnRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 232, 224, 4, 3 +}; diff --git a/src/burn/misc/pre90s/d_minivdr.cpp b/src/burn/misc/pre90s/d_minivdr.cpp new file mode 100644 index 0000000..287c97e --- /dev/null +++ b/src/burn/misc/pre90s/d_minivdr.cpp @@ -0,0 +1,173 @@ + +/* +Minivader (Space Invaders's mini game) +(c)1990 Taito Corporation + +This is a test board sold together with the cabinet (as required by law in +Japan). It has no sound. + +Based on MAME Driver by Takahiro Nogi +*/ + +#include "burnint.h" + + +static unsigned char DrvJoy[4], DrvReset, *Mem; + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Left" , BIT_DIGITAL , DrvJoy + 0, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy + 1, "p1 right" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy + 2, "p1 fire 1"}, + {"P1 Coin" , BIT_DIGITAL , DrvJoy + 3, "p1 coin" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, +}; + +STDINPUTINFO(Drv); + + +unsigned char __fastcall MinivadrMemRead(unsigned short a) +{ + if (a == 0xe008) { + return ~(DrvJoy[0] | (DrvJoy[1] << 1) | (DrvJoy[2] << 2) | (DrvJoy[3] << 3)); + } + + return 0; +} + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + ba.Data = Mem + 0x2000; + ba.nLen = 0x2000; + ba.szName = "All Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + } + + return 0; +} + + +static int DrvDoReset() +{ + DrvReset = 0; + memset (Mem + 0x2000, 0, 0x2000); + + ZetOpen(0); + ZetReset(); + ZetClose(); + + return 0; +} + + +static int DrvDraw() +{ + int a, i, y; + unsigned char c, d, x; + + for (a = 0x200; a < 0x1e00; a++) + { + x = a << 3; + y = ((a >> 5) - 0x10) << 8; + d = Mem[0x2000 + a]; + + for (i = 0; i < 8; i++) + { + c = (d & 0x80) ? 0xff : 0; + PutPix(pBurnDraw + (x + y) * nBurnBpp, BurnHighCol(c, c, c, 0)); + + d <<= 1; + x += 1; + } + } + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetOpen(0); + ZetRun(4000000 / 60); + ZetSetIRQLine(0xFF, ZET_IRQSTATUS_AUTO); + ZetClose(); + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +static int DrvInit() +{ + Mem = (unsigned char*)malloc ( 0x4000 ); + if (Mem == NULL) { + return 1; + } + + if (BurnLoadRom(Mem, 0, 1)) return 1; + + ZetInit(1); + ZetOpen(0); + ZetMapArea (0x0000, 0x1fff, 0, Mem + 0x0000); // Read ROM + ZetMapArea (0x0000, 0x1fff, 2, Mem + 0x0000); // Fetch ROM + ZetMapArea (0xa000, 0xbfff, 0, Mem + 0x2000); // Read RAM + ZetMapArea (0xa000, 0xbfff, 1, Mem + 0x2000); // Write RAM + ZetSetReadHandler(MinivadrMemRead); + ZetMemEnd(); + ZetClose(); + + DrvDoReset(); + return 0; +} + + +static int DrvExit() +{ + ZetExit(); + + DrvReset = 0; + free (Mem); + Mem = NULL; + + return 0; +} + + +// Minivader + +static struct BurnRomInfo minivadrRomDesc[] = { + { "d26-01.bin", 0x2000, 0xa96c823d, BRF_ESS | BRF_PRG }, // Z80 code +}; + +STD_ROM_PICK(minivadr); +STD_ROM_FN(minivadr); + +struct BurnDriver BurnDrvminivadr = { + "minivadr", NULL, NULL, "1990", + "Minivader\0", NULL, "Taito Corporation", "Minivader", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 1, HARDWARE_MISC_PRE90S, + NULL, minivadrRomInfo, minivadrRomName, DrvInputInfo, NULL, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 224, 4, 3 +}; + + diff --git a/src/burn/misc/pre90s/d_mole.cpp b/src/burn/misc/pre90s/d_mole.cpp new file mode 100644 index 0000000..15a9cdf --- /dev/null +++ b/src/burn/misc/pre90s/d_mole.cpp @@ -0,0 +1,493 @@ +// Mole Attack FB Driver Module +// Based on MAME driver by Jason Nelson and Phil Stroffolino + +#include "burnint.h" +#include "m6502.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + + +//-------------------------------------------------------------------------------------- +// Variables + + +static unsigned char *Mem, *Rom, *Gfx, *BankRam; +static unsigned char DrvJoy1[12], DrvJoy2[12], DrvReset, DrvDips; +static int *Palette; +static short *pAY8910Buffer[3], *pFMBuffer = NULL; + +static int tile_bank, flipscreen; + + +//-------------------------------------------------------------------------------------- +// Inputs + +// buttons are laid out as follows: +// 7 8 9 +// 4 5 6 +// 1 2 3 + + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1" , BIT_DIGITAL, DrvJoy1 + 9, "p1 coin" }, + {"Start 1" , BIT_DIGITAL, DrvJoy1 + 10, "p1 start" }, + {"Start 2" , BIT_DIGITAL, DrvJoy2 + 10, "p2 start" }, + {"P1 button 1", BIT_DIGITAL, DrvJoy1 + 0, "p1 fire 1", }, + {"P1 button 2", BIT_DIGITAL, DrvJoy1 + 1, "p1 fire 2", }, + {"P1 button 3", BIT_DIGITAL, DrvJoy1 + 2, "p1 fire 3", }, + {"P1 button 4", BIT_DIGITAL, DrvJoy1 + 3, "p1 fire 4", }, + {"P1 button 5", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 5", }, + {"P1 button 6", BIT_DIGITAL, DrvJoy1 + 5, "p1 fire 6", }, + {"P1 button 7", BIT_DIGITAL, DrvJoy1 + 6, "p1 fire 7", }, + {"P1 button 8", BIT_DIGITAL, DrvJoy1 + 7, "p1 fire 8", }, + {"P1 button 9", BIT_DIGITAL, DrvJoy1 + 8, "p1 fire 9", }, + + {"P2 button 1", BIT_DIGITAL, DrvJoy2 + 0, "p2 fire 1", }, + {"P2 button 2", BIT_DIGITAL, DrvJoy2 + 1, "p2 fire 2", }, + {"P2 button 3", BIT_DIGITAL, DrvJoy2 + 2, "p2 fire 3", }, + {"P2 button 4", BIT_DIGITAL, DrvJoy2 + 3, "p2 fire 4", }, + {"P2 button 5", BIT_DIGITAL, DrvJoy2 + 4, "p2 fire 5", }, + {"P2 button 6", BIT_DIGITAL, DrvJoy2 + 5, "p2 fire 6", }, + {"P2 button 7", BIT_DIGITAL, DrvJoy2 + 6, "p2 fire 7", }, + {"P2 button 8", BIT_DIGITAL, DrvJoy2 + 7, "p2 fire 8", }, + {"P2 button 9", BIT_DIGITAL, DrvJoy2 + 8, "p2 fire 9", }, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, &DrvDips, "dip" }, +}; + +STDINPUTINFO(Drv); + + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x16, 0xff, 0xff, 0x00, NULL }, + + {0 , 0xfe, 0 , 2 , "Passing Points" }, + {0x16, 0x01, 0x01, 0x00, "300" }, + {0x16, 0x01, 0x01, 0x01, "400" }, + + {0 , 0xfe, 0 , 2 , "Coinage" }, + {0x16, 0x01, 0x02, 0x00, "1 Coin 1 Play" }, + {0x16, 0x01, 0x02, 0x02, "1 Coin 2 Plays" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x16, 0x01, 0x10, 0x00, "Upright" }, + {0x16, 0x01, 0x10, 0x10, "Cocktail" }, +}; + +STDDIPINFO(Drv); + + +//-------------------------------------------------------------------------------------- +// Memory handling + + +static unsigned char mole_protection_r(unsigned char offset) +{ + switch (offset) + { + case 0x08: // random mole placement + return 0xb0; + + case 0x26: + if (m6502_get_reg(M6502_REG_PC) == 0x53d7) + { + return 0x06; // bonus round + } + else // pc == 0x515b, 0x5162 + { + return 0xc6; // game start + } + + case 0x86: // game over + return 0x91; + + case 0xae: // coinage + return 0x32; + } + + return 0x00; +} + +void mole_write_byte(unsigned short address, unsigned char data) +{ + // Tile RAM + if (address >= 0x8000 && address <= 0x83ff) + { + BankRam[address & 0x3ff] = tile_bank; + Rom[address] = data; + return; + } + + switch (address) + { + case 0x0800: // ? + case 0x0820: + case 0x8c40: + case 0x8c80: + case 0x8c81: + break; + + case 0x8400: + tile_bank = data; + break; + + case 0x8c00: // ay8910_write_port + case 0x8c01: // ay8910_control_port + AY8910Write(0, ~address & 1, data); + break; + + case 0x8d00: // watchdog + break; + + case 0x8dc0: // flipscreen + flipscreen = data & 1; + break; + } +} + +unsigned char mole_read_byte(unsigned short address) +{ + unsigned char ret = 0; + + switch (address) + { + case 0x8d00: // input port 0 + return DrvDips & 0x03; + + case 0x8d40: // input port 1 + { + for (int i = 0; i < 8; i++) + ret |= DrvJoy1[i] << i; + + return ret; + } + + case 0x8d80: // input port 2 + { + ret |= DrvJoy1[8]; + ret |= DrvJoy2[0] << 1; + ret |= DrvJoy2[1] << 2; + ret |= DrvJoy2[2] << 3; + ret |= DrvDips & 0x10; + ret |= DrvJoy2[10] << 5; + ret |= DrvJoy1[10] << 6; + ret |= DrvJoy1[ 9] << 7; + + return ret; + } + + case 0x8dc0: // input port 3 + { + ret |= DrvJoy2[7]; + ret |= DrvJoy2[6] << 1; + ret |= DrvJoy2[3] << 2; + ret |= DrvJoy2[8] << 3; + ret |= DrvJoy2[5] << 4; + ret |= DrvJoy2[4] << 5; + + return ret; + } + } + + // Protection read + if (address >= 0x800 && address <= 0x8ff) + { + return mole_protection_r(address & 0xff); + } + + return 0; +} + + +//-------------------------------------------------------------------------------------- +// Initilizing functions + + +static int DrvDoReset() +{ + DrvReset = 0; + + memset (Rom + 0x0000, 0, 0x0400); + memset (Rom + 0x8000, 0, 0x0400); + memset (BankRam, 0, 0x0400); + + tile_bank = 0; + flipscreen = 0; + + m6502Open(0); + m6502Reset(); + m6502Close(); + + AY8910Reset(0); + + return 0; +} + +static void mole_palette_init() +{ + for (int i = 0; i < 8; i++) { + Palette[i] |= (i & 1) ? 0xff0000 : 0; + Palette[i] |= (i & 4) ? 0x00ff00 : 0; + Palette[i] |= (i & 2) ? 0x0000ff : 0; + } + +} + +static int mole_gfx_convert() +{ + unsigned char a, b, c; + unsigned char *tmp = (unsigned char*)malloc(0x6000); + if (tmp == NULL) { + return 1; + } + + memcpy (tmp, Gfx, 0x6000); + + for (int i = 0; i < 0x8000; i++) + { + a = (tmp[0x0000 + (i >> 3)] >> (i & 7)) & 1; + b = (tmp[0x1000 + (i >> 3)] >> (i & 7)) & 1; + c = (tmp[0x2000 + (i >> 3)] >> (i & 7)) & 1; + + Gfx[0x0007 ^ i] = (a << 2) | (b << 1) | c; + + a = (tmp[0x3000 + (i >> 3)] >> (i & 7)) & 1; + b = (tmp[0x4000 + (i >> 3)] >> (i & 7)) & 1; + c = (tmp[0x5000 + (i >> 3)] >> (i & 7)) & 1; + + Gfx[0x8007 ^ i] = (a << 2) | (b << 1) | c; + } + + free (tmp); +} + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x10000 + 0x10000 + 0x400 + 0x20); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short *)malloc (nBurnSoundLen * 3 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + memset (Mem, 0, 0x20420); + + Rom = Mem + 0x00000; + Gfx = Mem + 0x10000; + BankRam = Mem + 0x20000; + Palette = (int *)(Mem + 0x20400); + + { + BurnLoadRom(Rom + 0x5000, 0, 1); + BurnLoadRom(Rom + 0x6000, 1, 1); + BurnLoadRom(Rom + 0x7000, 2, 1); + + BurnLoadRom(Gfx + 0x0000, 3, 1); + BurnLoadRom(Gfx + 0x1000, 4, 1); + BurnLoadRom(Gfx + 0x2000, 5, 1); + BurnLoadRom(Gfx + 0x3000, 6, 1); + BurnLoadRom(Gfx + 0x4000, 7, 1); + BurnLoadRom(Gfx + 0x5000, 8, 1); + } + + mole_gfx_convert(); + mole_palette_init(); + + m6502Init(1); + m6502Open(0); + m6502MapMemory(Rom + 0x0000, 0x0000, 0x03ff, M6502_RAM); // Ram + + m6502MapMemory(Rom + 0x5000, 0x5000, 0x7fff, M6502_ROM); // Rom + m6502MapMemory(Rom + 0x5000, 0xd000, 0xffff, M6502_ROM); // Rom Mirror + + m6502SetReadHandler(mole_read_byte); + m6502SetWriteHandler(mole_write_byte); + m6502Close(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + AY8910Init(0, 2000000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + m6502Exit(); + AY8910Exit(0); + + free (Mem); + free (pFMBuffer); + + return 0; +} + + +//-------------------------------------------------------------------------------------- +// Drawing functions + + +static int DrvDraw() +{ + for (int offs = 0; offs < 0x400; offs++) + { + int sy = ((offs / 40) % 25) << 3; + int sx = (offs % 40) << 3; + + int code = ((BankRam[offs] & 3) << 14) | ((Rom[0x8000 + offs]) << 6); + + unsigned char *gfxsrc = Gfx + code; + + for (int y = sy; y < sy + 8; y++) + { + for (int x = sx; x < sx + 8; x++, gfxsrc++) + { + int pxl = Palette[*gfxsrc]; + + int pos; + + if (flipscreen) + pos = (199 - y) * 320 + (319 - x); + else + pos = y * 320 + x; + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + m6502Open(0); + m6502Run(4000000 / 60); + m6502SetIRQ(M6502_IRQ); + m6502Close(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +//-------------------------------------------------------------------------------------- +// Savestates + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0x0000; + ba.nLen = 0x0400; + ba.szName = "Work Ram"; + BurnAcb(&ba); + + ba.Data = Rom + 0x8000; + ba.nLen = 0x0400; + ba.szName = "Video Ram"; + BurnAcb(&ba); + + ba.Data = BankRam; + ba.nLen = 0x0400; + ba.szName = "Bank Ram"; + BurnAcb(&ba); + + m6502Scan(nAction); // Scan m6502 + AY8910Scan(nAction, pnMin); // Scan AY8910 + + // Scan critical driver variables + SCAN_VAR(tile_bank); + SCAN_VAR(flipscreen); + } + + return 0; +} + + +//-------------------------------------------------------------------------------------- +// Game drivers + + +// Mole Attack + +static struct BurnRomInfo moleRomDesc[] = { + { "m3a.5h", 0x1000, 0x5fbbdfef, 1 | BRF_ESS | BRF_PRG }, // 0 M6502 Code + { "m2a.7h", 0x1000, 0xf2a90642, 1 | BRF_ESS | BRF_PRG }, // 1 + { "m1a.8h", 0x1000, 0xcff0119a, 1 | BRF_ESS | BRF_PRG }, // 2 + + { "mea.4a", 0x1000, 0x49d89116, 2 | BRF_GRA }, // 3 Graphics tiles + { "mca.6a", 0x1000, 0x04e90300, 2 | BRF_GRA }, // 4 + { "maa.9a", 0x1000, 0x6ce9442b, 2 | BRF_GRA }, // 5 + { "mfa.3a", 0x1000, 0x0d0c7d13, 2 | BRF_GRA }, // 6 + { "mda.5a", 0x1000, 0x41ae1842, 2 | BRF_GRA }, // 7 + { "mba.8a", 0x1000, 0x50c43fc9, 2 | BRF_GRA }, // 8 +}; + +STD_ROM_PICK(mole); +STD_ROM_FN(mole); + +struct BurnDriver BurnDrvMole = { + "mole", NULL, NULL, "1982", + "Mole Attack\0", NULL, "Yachiyo Electronics, Ltd.", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, moleRomInfo, moleRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 320, 200, 4, 3 +}; diff --git a/src/burn/misc/pre90s/d_mrdo.cpp b/src/burn/misc/pre90s/d_mrdo.cpp new file mode 100644 index 0000000..53dec3c --- /dev/null +++ b/src/burn/misc/pre90s/d_mrdo.cpp @@ -0,0 +1,759 @@ +// FB Alpha Mr. Do! driver module +// Based on MAME driver by Nicola Salmoria + +#include "tiles_generic.h" +#include "sn76496.h" + +static unsigned char *Mem, *Rom, *Gfx0, *Gfx1, *Gfx2, *Prom; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvReset, DrvDips[2]; +static int *Palette; + +static int flipscreen, scroll_x, scroll_y; + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy2 + 6, "p1 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 5, "p1 start" }, + {"P1 Up" , BIT_DIGITAL , DrvJoy1 + 3, "p1 up" }, + {"P1 Down" , BIT_DIGITAL , DrvJoy1 + 1, "p1 down" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 0, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 2, "p1 right" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 1"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy2 + 7, "p2 coin" }, + {"P2 Start" , BIT_DIGITAL , DrvJoy1 + 6, "p2 start" }, + {"P2 Up" , BIT_DIGITAL , DrvJoy2 + 3, "p2 up" }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 1, "p2 down", }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 0, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 2, "p2 right" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 1"}, + + {"Tilt" , BIT_DIGITAL , DrvJoy1 + 7, "tilt" }, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip 1" }, + {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip 2" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0xdf, NULL }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x10, 0x01, 0x03, 0x03, "Easy" }, + {0x10, 0x01, 0x03, 0x02, "Medium" }, + {0x10, 0x01, 0x03, 0x01, "Hard" }, + {0x10, 0x01, 0x03, 0x00, "Hardest" }, + + {0 , 0xfe, 0 , 2 , "Rack Test (cheat)" }, + {0x10, 0x01, 0x04, 0x04, "Off" }, + {0x10, 0x01, 0x04, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Special" }, + {0x10, 0x01, 0x08, 0x08, "Easy" }, + {0x10, 0x01, 0x08, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Extra" }, + {0x10, 0x01, 0x10, 0x10, "Easy" }, + {0x10, 0x01, 0x10, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x20, 0x00, "Upright" }, + {0x10, 0x01, 0x20, 0x20, "Cocktail" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x10, 0x01, 0xc0, 0x00, "2" }, + {0x10, 0x01, 0xc0, 0xc0, "3" }, + {0x10, 0x01, 0xc0, 0x80, "4" }, + {0x10, 0x01, 0xc0, 0x40, "5" }, + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 11 , "Coin B" }, + {0x11, 0x01, 0x0f, 0x06, "4C_1C" }, + {0x11, 0x01, 0x0f, 0x08, "3C_1C" }, + {0x11, 0x01, 0x0f, 0x0a, "2C_1C" }, + {0x11, 0x01, 0x0f, 0x07, "3C_2C" }, + {0x11, 0x01, 0x0f, 0x0f, "1C_1C" }, + {0x11, 0x01, 0x0f, 0x09, "2C_3C" }, + {0x11, 0x01, 0x0f, 0x0e, "1C_2C" }, + {0x11, 0x01, 0x0f, 0x0d, "1C_3C" }, + {0x11, 0x01, 0x0f, 0x0c, "1C_4C" }, + {0x11, 0x01, 0x0f, 0x0b, "1C_5C" }, + {0x11, 0x01, 0x0f, 0x00, "Free_Play" }, + + {0 , 0xfe, 0 , 11 , "Coin A" }, + {0x11, 0x01, 0xf0, 0x60, "4C_1C" }, + {0x11, 0x01, 0xf0, 0x80, "3C_1C" }, + {0x11, 0x01, 0xf0, 0xa0, "2C_1C" }, + {0x11, 0x01, 0xf0, 0x70, "3C_2C" }, + {0x11, 0x01, 0xf0, 0xf0, "1C_1C" }, + {0x11, 0x01, 0xf0, 0x90, "2C_3C" }, + {0x11, 0x01, 0xf0, 0xe0, "1C_2C" }, + {0x11, 0x01, 0xf0, 0xd0, "1C_3C" }, + {0x11, 0x01, 0xf0, 0xc0, "1C_4C" }, + {0x11, 0x01, 0xf0, 0xb0, "1C_5C" }, + {0x11, 0x01, 0xf0, 0x00, "Free_Play" }, +}; + +STDDIPINFO(Drv); + +void __fastcall mrdo_write(unsigned short address, unsigned char data) +{ + if ((address & 0xf000) == 0xf000) address &= 0xf800; + + switch (address) + { + case 0x9800: + flipscreen = data & 1; + break; + + case 0x9801: + SN76496Write(0, data); + + case 0x9802: + SN76496Write(1, data); + break; + + case 0xf000: + scroll_x = data; + break; + + case 0xf800: + scroll_y = data ^ (flipscreen ? 0xff : 0); + break; + } +} + +unsigned char __fastcall mrdo_read(unsigned short address) +{ + unsigned char ret = 0xff; + + switch (address) + { + case 0x9803: // Protection + return Rom[ZetHL(-1)]; + + case 0xa000: + { + for (int i = 0; i < 8; i++) ret ^= DrvJoy1[i] << i; + return ret; + } + + case 0xa001: + { + for (int i = 0; i < 8; i++) ret ^= DrvJoy2[i] << i; + return ret; + } + + case 0xa002: + return DrvDips[0]; + + case 0xa003: + return DrvDips[1]; + } + + return 0; +} + +static int DrvDoReset() +{ + DrvReset = 0; + + memset (Rom + 0x8000, 0, 0x8000); + + flipscreen = 0; + scroll_x = scroll_y = 0; + + ZetOpen(0); + ZetReset(); + ZetClose(); + + return 0; +} + +static void mrdo_palette_init() +{ + int weight[16]; + + for (int i = 0x0f; i >= 0; i--) + { + float par = 0, pot = 0; + + if (i & 1) par += 1.0/150; + if (i & 2) par += 1.0/120; + if (i & 4) par += 1.0/100; + if (i & 8) par += 1.0/75; + if (par) + { + par = 1 / par; + pot = 200 / (200 + par) - 0.2f; + } + else pot = 0; + + weight[i] = (int)(0xff * pot / 0.684615); + } + + for (int i = 0; i < 0x100; i++) + { + int a1,a2; + int bits0, bits2; + int r, g, b; + + a1 = ((i >> 3) & 0x1c) + (i & 0x03) + 32; + a2 = ((i >> 0) & 0x1c) + (i & 0x03); + + bits0 = (Prom[a1] >> 0) & 0x03; + bits2 = (Prom[a2] >> 0) & 0x03; + r = weight[bits0 + (bits2 << 2)]; + + bits0 = (Prom[a1] >> 2) & 0x03; + bits2 = (Prom[a2] >> 2) & 0x03; + g = weight[bits0 + (bits2 << 2)]; + + bits0 = (Prom[a1] >> 4) & 0x03; + bits2 = (Prom[a2] >> 4) & 0x03; + b = weight[bits0 + (bits2 << 2)]; + + Palette[i] = (r << 16) | (g << 8) | b; + } + + for (int i = 0; i < 0x40; i++) + { + unsigned char ctbl = Prom[0x40 + (i & 0x1f)] >> ((i & 0x20) >> 3); + + Palette[0x100 + i] = Palette[ctbl & 0x0f]; + } +} + +static void mrdo_gfx_decode() +{ + static int CharPlane[2] = { 0, 0x8000 }; + static int CharXOffs[8] = { 7, 6, 5, 4, 3, 2, 1, 0 }; + static int CharYOffs[8] = { 0, 8, 16, 24, 32, 40, 48, 56 }; + + static int SpriPlane[2] = { 4, 0 }; + static int SpriXOffs[16] = { 3, 2, 1, 0, 11, 10, 9, 8, 19, 18, 17, 16, 27, 26, 25, 24 }; + static int SpriYOffs[16] = { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480 }; + + unsigned char *tmp = (unsigned char*)malloc(0x2000); + if (!tmp) return; + + memcpy (tmp, Gfx0, 0x2000); + + GfxDecode(0x200, 2, 8, 8, CharPlane, CharXOffs, CharYOffs, 0x040, tmp, Gfx0); + + memcpy (tmp, Gfx1, 0x2000); + + GfxDecode(0x200, 2, 8, 8, CharPlane, CharXOffs, CharYOffs, 0x040, tmp, Gfx1); + + memcpy (tmp, Gfx2, 0x2000); + + GfxDecode(0x080, 2, 16, 16, SpriPlane, SpriXOffs, SpriYOffs, 0x200, tmp, Gfx2); + + free (tmp); +} + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x10000 + 0x8000 + 0x8000 + 0x8000 + 0x80 + 0x500); + if (!Mem) return 1; + + Rom = Mem + 0x00000; + Gfx0 = Mem + 0x10000; + Gfx1 = Mem + 0x18000; + Gfx2 = Mem + 0x20000; + Prom = Mem + 0x28000; + Palette = (int*)(Mem + 0x28080); + + { + for (int i = 0; i < 4; i++) { + if(BurnLoadRom(Rom + i * 0x2000, 0 + i, 1)) return 1; + if(BurnLoadRom(Prom + i * 0x0020, 10 + i, 1)) return 1; + } + + for (int i = 0; i < 2; i++) { + if(BurnLoadRom(Gfx0 + i * 0x1000, 4 + i, 1)) return 1; + if(BurnLoadRom(Gfx1 + i * 0x1000, 6 + i, 1)) return 1; + if(BurnLoadRom(Gfx2 + i * 0x1000, 8 + i, 1)) return 1; + } + + mrdo_palette_init(); + mrdo_gfx_decode(); + } + + ZetInit(1); + ZetOpen(0); + ZetSetReadHandler(mrdo_read); + ZetSetWriteHandler(mrdo_write); + ZetMapArea(0x0000, 0x7fff, 0, Rom + 0x0000); + ZetMapArea(0x0000, 0x7fff, 2, Rom + 0x0000); + ZetMapArea(0x8000, 0x8fff, 0, Rom + 0x8000); + ZetMapArea(0x8000, 0x8fff, 1, Rom + 0x8000); + ZetMapArea(0x9000, 0x90ff, 1, Rom + 0x9000); + ZetMapArea(0xe000, 0xefff, 0, Rom + 0xe000); + ZetMapArea(0xe000, 0xefff, 1, Rom + 0xe000); + ZetMapArea(0xe000, 0xefff, 2, Rom + 0xe000); + ZetMemEnd(); + ZetClose(); + + BurnSetRefreshRate(5000000.0/312/262); + + SN76489Init(0, 4000000, 0); + SN76489Init(1, 4000000, 1); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + + SN76496Exit(); + + free (Mem); + + Mem = Rom = Gfx0 = Gfx1 = Gfx2 = Prom = NULL; + Palette = NULL; + + flipscreen = scroll_x = scroll_y = 0; + + return 0; +} + +static void draw_sprites() +{ + for (int offs = 0x100 - 4; offs >= 0; offs -= 4) + { + if (Rom[0x9001 + offs]) + { + int sx = Rom[0x9003 + offs]; + int sy = Rom[0x9001 + offs] ^ 0xff; + + int code = Rom[0x9000 + offs] & 0x7f; + int color = ((Rom[0x9002 + offs] & 0x0f) << 2) | 0x100; + + int flipx = Rom[0x9002 + offs] & 0x10; + int flipy = Rom[0x9002 + offs] & 0x20; + + unsigned char *src = Gfx2 + (code << 8); + + sx -= 8; + sy -= 32; + + if (flipy) + { + for (int y = sy + 15; y >= sy; y--) + { + if (flipx) + { + for (int x = sx + 15; x >= sx; x--, src++) + { + if (y < 0 || x < 0 || y > 191 || x > 239) continue; + if (!*src) continue; + + int pxl = Palette[color | *src]; + + PutPix(pBurnDraw + ((y * 240) + x) * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } else { + for (int x = sx; x < sx + 16; x++, src++) + { + if (y < 0 || x < 0 || y > 191 || x > 239) continue; + if (!*src) continue; + + int pxl = Palette[color | *src]; + + PutPix(pBurnDraw + ((y * 240) + x) * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } + } else { + for (int y = sy; y < sy + 16; y++) + { + if (flipx) + { + for (int x = sx + 15; x >= sx; x--, src++) + { + if (y < 0 || x < 0 || y > 191 || x > 239) continue; + if (!*src) continue; + + int pxl = Palette[color | *src]; + + PutPix(pBurnDraw + ((y * 240) + x) * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } else { + for (int x = sx; x < sx + 16; x++, src++) + { + if (y < 0 || x < 0 || y > 191 || x > 239) continue; + if (!*src) continue; + + int pxl = Palette[color | *src]; + + PutPix(pBurnDraw + ((y * 240) + x) * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } + } + } + } +} + +static void draw_8x8_tiles(unsigned char *vram, unsigned char *gfx_base, int scrollx, int scrolly) +{ + for (int offs = 0; offs < 0x400; offs++) + { + int sx = (offs & 0x1f) << 3; + int sy = (offs >> 2) & 0xf8; + + int code = vram[0x400 + offs] | ((vram[offs] & 0x80) << 1); + int color = (vram[offs] & 0x3f) << 2; + int forcelayer0 = vram[offs] & 0x40; + + unsigned char *src = gfx_base + (code << 6); + + sx = (unsigned char)(sx - scrollx); + sy = (unsigned char)(sy - scrolly); + + sx -= 8; + sy -= 32; + + for (int y = sy; y < sy + 8; y++) + { + for (int x = sx; x < sx + 8; x++, src++) + { + if (x < 0 || y < 0 || x > 239 || y > 191) continue; + + int pxl = Palette[color | *src]; + if (!*src && !forcelayer0) continue; + + int pos = y * 240 + x; + if (flipscreen) pos = (192 - y) * 240 + (240 - x); + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } +} + +static int DrvDraw() +{ + memset (pBurnDraw, 0, 240 * 191 * nBurnBpp); + + draw_8x8_tiles(Rom + 0x8000, Gfx1, scroll_x, scroll_y); + draw_8x8_tiles(Rom + 0x8800, Gfx0, 0, 0); + draw_sprites(); + + return 0; +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetOpen(0); + ZetRun(4000000 / 60); + ZetSetIRQLine(0, ZET_IRQSTATUS_AUTO); + ZetClose(); + + if (pBurnDraw) { + DrvDraw(); + } + + SN76496Update(0, pBurnSoundOut, nBurnSoundLen); + SN76496Update(1, pBurnSoundOut, nBurnSoundLen); + + return 0; +} + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0x8000; + ba.nLen = 0x8000; + ba.szName = "All Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + + SCAN_VAR(flipscreen); + SCAN_VAR(scroll_x); + SCAN_VAR(scroll_y); + } + + return 0; +} + + +// Mr. Do! + +static struct BurnRomInfo mrdoRomDesc[] = { + { "a4-01.bin", 0x2000, 0x03dcfba2, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "c4-02.bin", 0x2000, 0x0ecdd39c, 1 | BRF_ESS | BRF_PRG }, // 1 + { "e4-03.bin", 0x2000, 0x358f5dc2, 1 | BRF_ESS | BRF_PRG }, // 2 + { "f4-04.bin", 0x2000, 0xf4190cfc, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "s8-09.bin", 0x1000, 0xaa80c5b6, 2 | BRF_GRA }, // 4 FG Tiles + { "u8-10.bin", 0x1000, 0xd20ec85b, 2 | BRF_GRA }, // 5 + + { "r8-08.bin", 0x1000, 0xdbdc9ffa, 3 | BRF_GRA }, // 6 BG Tiles + { "n8-07.bin", 0x1000, 0x4b9973db, 3 | BRF_GRA }, // 7 + + { "h5-05.bin", 0x1000, 0xe1218cc5, 4 | BRF_GRA }, // 8 Sprite Tiles + { "k5-06.bin", 0x1000, 0xb1f68b04, 4 | BRF_GRA }, // 9 + + { "u02--2.bin", 0x0020, 0x238a65d7, 5 | BRF_GRA }, // 10 Palette (high bits) + { "t02--3.bin", 0x0020, 0xae263dc0, 5 | BRF_GRA }, // 11 Palette (low bits) + { "f10--1.bin", 0x0020, 0x16ee4ca2, 5 | BRF_GRA }, // 12 Sprite color lookup table + { "j10--4.bin", 0x0020, 0xff7fe284, 5 | BRF_GRA }, // 13 Timing (not used) +}; + +STD_ROM_PICK(mrdo); +STD_ROM_FN(mrdo); + +struct BurnDriver BurnDrvmrdo = { + "mrdo", NULL, NULL, "1982", + "Mr. Do!\0", NULL, "Universal", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, mrdoRomInfo, mrdoRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 192, 240, 3, 4 +}; + + +// Mr. Do! (Taito license) + +static struct BurnRomInfo mrdotRomDesc[] = { + { "d1", 0x2000, 0x3dcd9359, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "d2", 0x2000, 0x710058d8, 1 | BRF_ESS | BRF_PRG }, // 1 + { "d3", 0x2000, 0x467d12d8, 1 | BRF_ESS | BRF_PRG }, // 2 + { "d4", 0x2000, 0xfce9afeb, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "d9", 0x1000, 0xde4cfe66, 2 | BRF_GRA }, // 4 FG Tiles + { "d10", 0x1000, 0xa6c2f38b, 2 | BRF_GRA }, // 5 + + { "r8-08.bin", 0x1000, 0xdbdc9ffa, 3 | BRF_GRA }, // 6 BG Tiles + { "n8-07.bin", 0x1000, 0x4b9973db, 3 | BRF_GRA }, // 7 + + { "h5-05.bin", 0x1000, 0xe1218cc5, 4 | BRF_GRA }, // 8 Sprite Tiles + { "k5-06.bin", 0x1000, 0xb1f68b04, 4 | BRF_GRA }, // 9 + + { "u02--2.bin", 0x0020, 0x238a65d7, 5 | BRF_GRA }, // 10 Palette (high bits) + { "t02--3.bin", 0x0020, 0xae263dc0, 5 | BRF_GRA }, // 11 Palette (low bits) + { "f10--1.bin", 0x0020, 0x16ee4ca2, 5 | BRF_GRA }, // 12 Sprite color lookup table + { "j10--4.bin", 0x0020, 0xff7fe284, 5 | BRF_GRA }, // 13 Timing (not used) +}; + +STD_ROM_PICK(mrdot); +STD_ROM_FN(mrdot); + +struct BurnDriver BurnDrvmrdot = { + "mrdot", "mrdo", NULL, "1982", + "Mr. Do! (Taito license)\0", NULL, "Universal (Taito license)", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, mrdotRomInfo, mrdotRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 192, 240, 3, 4 +}; + +// Mr. Do! (bugfixed) + +static struct BurnRomInfo mrdofixRomDesc[] = { + { "d1", 0x2000, 0x3dcd9359, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "d2", 0x2000, 0x710058d8, 1 | BRF_ESS | BRF_PRG }, // 1 + { "dofix.d3", 0x2000, 0x3a7d039b, 1 | BRF_ESS | BRF_PRG }, // 2 + { "dofix.d4", 0x2000, 0x32db845f, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "d9", 0x1000, 0xde4cfe66, 2 | BRF_GRA }, // 4 FG Tiles + { "d10", 0x1000, 0xa6c2f38b, 2 | BRF_GRA }, // 5 + + { "r8-08.bin", 0x1000, 0xdbdc9ffa, 3 | BRF_GRA }, // 6 BG Tiles + { "n8-07.bin", 0x1000, 0x4b9973db, 3 | BRF_GRA }, // 7 + + { "h5-05.bin", 0x1000, 0xe1218cc5, 4 | BRF_GRA }, // 8 Sprite Tiles + { "k5-06.bin", 0x1000, 0xb1f68b04, 4 | BRF_GRA }, // 9 + + { "u02--2.bin", 0x0020, 0x238a65d7, 5 | BRF_GRA }, // 10 Palette (high bits) + { "t02--3.bin", 0x0020, 0xae263dc0, 5 | BRF_GRA }, // 11 Palette (low bits) + { "f10--1.bin", 0x0020, 0x16ee4ca2, 5 | BRF_GRA }, // 12 Sprite color lookup table + { "j10--4.bin", 0x0020, 0xff7fe284, 5 | BRF_GRA }, // 13 Timing (not used) +}; + +STD_ROM_PICK(mrdofix); +STD_ROM_FN(mrdofix); + +struct BurnDriver BurnDrvmrdofix = { + "mrdofix", "mrdo", NULL, "1982", + "Mr. Do! (bugfixed)\0", NULL, "Universal (Taito license)", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, mrdofixRomInfo, mrdofixRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 192, 240, 3, 4 +}; + + +// Mr. Lo! + +static struct BurnRomInfo mrloRomDesc[] = { + { "mrlo01.bin", 0x2000, 0x6f455e7d, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "d2", 0x2000, 0x710058d8, 1 | BRF_ESS | BRF_PRG }, // 1 + { "dofix.d3", 0x2000, 0x3a7d039b, 1 | BRF_ESS | BRF_PRG }, // 2 + { "mrlo04.bin", 0x2000, 0x49c10274, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "mrlo09.bin", 0x1000, 0xfdb60d0d, 2 | BRF_GRA }, // 4 FG Tiles + { "mrlo10.bin", 0x1000, 0x0492c10e, 2 | BRF_GRA }, // 5 + + { "r8-08.bin", 0x1000, 0xdbdc9ffa, 3 | BRF_GRA }, // 6 BG Tiles + { "n8-07.bin", 0x1000, 0x4b9973db, 3 | BRF_GRA }, // 7 + + { "h5-05.bin", 0x1000, 0xe1218cc5, 4 | BRF_GRA }, // 8 Sprite Tiles + { "k5-06.bin", 0x1000, 0xb1f68b04, 4 | BRF_GRA }, // 9 + + { "u02--2.bin", 0x0020, 0x238a65d7, 5 | BRF_GRA }, // 10 Palette (high bits) + { "t02--3.bin", 0x0020, 0xae263dc0, 5 | BRF_GRA }, // 11 Palette (low bits) + { "f10--1.bin", 0x0020, 0x16ee4ca2, 5 | BRF_GRA }, // 12 Sprite color lookup table + { "j10--4.bin", 0x0020, 0xff7fe284, 5 | BRF_GRA }, // 13 Timing (not used) +}; + +STD_ROM_PICK(mrlo); +STD_ROM_FN(mrlo); + +struct BurnDriver BurnDrvmrlo = { + "mrlo", "mrdo", NULL, "1982", + "Mr. Lo!\0", NULL, "Bootleg", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, mrloRomInfo, mrloRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 192, 240, 3, 4 +}; + + +// Mr. Du! + +static struct BurnRomInfo mrduRomDesc[] = { + { "d1", 0x2000, 0x3dcd9359, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "d2", 0x2000, 0x710058d8, 1 | BRF_ESS | BRF_PRG }, // 1 + { "d3", 0x2000, 0x467d12d8, 1 | BRF_ESS | BRF_PRG }, // 2 + { "du4.bin", 0x2000, 0x893bc218, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "du9.bin", 0x1000, 0x4090dcdc, 2 | BRF_GRA }, // 4 FG Tiles + { "du10.bin", 0x1000, 0x1e63ab69, 2 | BRF_GRA }, // 5 + + { "r8-08.bin", 0x1000, 0xdbdc9ffa, 3 | BRF_GRA }, // 6 BG Tiles + { "n8-07.bin", 0x1000, 0x4b9973db, 3 | BRF_GRA }, // 7 + + { "h5-05.bin", 0x1000, 0xe1218cc5, 4 | BRF_GRA }, // 8 Sprite Tiles + { "k5-06.bin", 0x1000, 0xb1f68b04, 4 | BRF_GRA }, // 9 + + { "u02--2.bin", 0x0020, 0x238a65d7, 5 | BRF_GRA }, // 10 Palette (high bits) + { "t02--3.bin", 0x0020, 0xae263dc0, 5 | BRF_GRA }, // 11 Palette (low bits) + { "f10--1.bin", 0x0020, 0x16ee4ca2, 5 | BRF_GRA }, // 12 Sprite color lookup table + { "j10--4.bin", 0x0020, 0xff7fe284, 5 | BRF_GRA }, // 13 Timing (not used) +}; + +STD_ROM_PICK(mrdu); +STD_ROM_FN(mrdu); + +struct BurnDriver BurnDrvmrdu = { + "mrdu", "mrdo", NULL, "1982", + "Mr. Du!\0", NULL, "Bootleg", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, mrduRomInfo, mrduRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 192, 240, 3, 4 +}; + + +// Mr. Do! (prototype) + +static struct BurnRomInfo mrdoyRomDesc[] = { + { "dosnow.1", 0x2000, 0xd3454e2c, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "dosnow.2", 0x2000, 0x5120a6b2, 1 | BRF_ESS | BRF_PRG }, // 1 + { "dosnow.3", 0x2000, 0x96416dbe, 1 | BRF_ESS | BRF_PRG }, // 2 + { "dosnow.4", 0x2000, 0xc05051b6, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "dosnow.9", 0x1000, 0x85d16217, 2 | BRF_GRA }, // 4 FG Tiles + { "dosnow.10", 0x1000, 0x61a7f54b, 2 | BRF_GRA }, // 5 + + { "dosnow.8", 0x1000, 0x2bd1239a, 3 | BRF_GRA }, // 6 BG Tiles + { "dosnow.7", 0x1000, 0xac8ffddf, 3 | BRF_GRA }, // 7 + + { "dosnow.5", 0x1000, 0x7662d828, 4 | BRF_GRA }, // 8 Sprite Tiles + { "dosnow.6", 0x1000, 0x413f88d1, 4 | BRF_GRA }, // 9 + + { "u02--2.bin", 0x0020, 0x238a65d7, 5 | BRF_GRA }, // 10 Palette (high bits) + { "t02--3.bin", 0x0020, 0xae263dc0, 5 | BRF_GRA }, // 11 Palette (low bits) + { "f10--1.bin", 0x0020, 0x16ee4ca2, 5 | BRF_GRA }, // 12 Sprite color lookup table + { "j10--4.bin", 0x0020, 0xff7fe284, 5 | BRF_GRA }, // 13 Timing (not used) +}; + +STD_ROM_PICK(mrdoy); +STD_ROM_FN(mrdoy); + +struct BurnDriver BurnDrvmrdoy = { + "mrdoy", "mrdo", NULL, "1982", + "Mr. Do! (prototype)\0", NULL, "Universal", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_PROTOTYPE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, mrdoyRomInfo, mrdoyRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 192, 240, 3, 4 +}; + + +// Yankee DO! + +static struct BurnRomInfo yankeedoRomDesc[] = { + { "a4-01.bin", 0x2000, 0x03dcfba2, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "yd_d2.c4", 0x2000, 0x7c9d7ce0, 1 | BRF_ESS | BRF_PRG }, // 1 + { "e4-03.bin", 0x2000, 0x358f5dc2, 1 | BRF_ESS | BRF_PRG }, // 2 + { "f4-04.bin", 0x2000, 0xf4190cfc, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "s8-09.bin", 0x1000, 0xaa80c5b6, 2 | BRF_GRA }, // 4 FG Tiles + { "u8-10.bin", 0x1000, 0xd20ec85b, 2 | BRF_GRA }, // 5 + + { "r8-08.bin", 0x1000, 0xdbdc9ffa, 3 | BRF_GRA }, // 6 BG Tiles + { "n8-07.bin", 0x1000, 0x4b9973db, 3 | BRF_GRA }, // 7 + + { "yd_d5.h5", 0x1000, 0xf530b79b, 4 | BRF_GRA }, // 8 Sprite Tiles + { "yd_d6.k5", 0x1000, 0x790579aa, 4 | BRF_GRA }, // 9 + + { "u02--2.bin", 0x0020, 0x238a65d7, 5 | BRF_GRA }, // 10 Palette (high bits) + { "t02--3.bin", 0x0020, 0xae263dc0, 5 | BRF_GRA }, // 11 Palette (low bits) + { "f10--1.bin", 0x0020, 0x16ee4ca2, 5 | BRF_GRA }, // 12 Sprite color lookup table + { "j10--4.bin", 0x0020, 0xff7fe284, 5 | BRF_GRA }, // 13 Timing (not used) +}; + +STD_ROM_PICK(yankeedo); +STD_ROM_FN(yankeedo); + +struct BurnDriver BurnDrvyankeedo = { + "yankeedo", "mrdo", NULL, "1982", + "Yankee DO!\0", NULL, "hack", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, yankeedoRomInfo, yankeedoRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 192, 240, 3, 4 +}; + diff --git a/src/burn/misc/pre90s/d_mrflea.cpp b/src/burn/misc/pre90s/d_mrflea.cpp new file mode 100644 index 0000000..09718d2 --- /dev/null +++ b/src/burn/misc/pre90s/d_mrflea.cpp @@ -0,0 +1,652 @@ +// FB Alpha Amazing Adventures of Mr. F. Lea driver module +// Based on MAME driver by Phil Stroffolino + +#include "burnint.h" +#include "bitswap.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +static unsigned char *Mem, *Rom0, *Rom1, *Ram, *Gfx0, *Gfx1; +static int *Palette; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvDips[2], DrvReset; + +static short *pFMBuffer, *pAY8910Buffer[9]; + +static int mrflea_io; +static int mrflea_main; +static int mrflea_status; +static int mrflea_select[4]; +static unsigned char mrflea_gfx_bank; + +static struct BurnInputInfo DrvInputList[] = { + {"Start 1" , BIT_DIGITAL , DrvJoy1 + 3, "p1 start" }, + {"Start 2" , BIT_DIGITAL , DrvJoy1 + 2, "p2 start" }, + {"P1 Coin" , BIT_DIGITAL , DrvJoy2 + 2, "p1 coin" }, + + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 4, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 5, "p1 left" }, + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 6, "p1 up", }, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 7, "p1 down", }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 1, "p1 fire 1"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips+0, "dip" }, + {"Dip 2", BIT_DIPSWITCH, DrvDips+1, "dip" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x09, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 4 , "Bonus" }, + {0x09, 0x01, 0x03, 0x03, "A" }, + {0x09, 0x01, 0x03, 0x02, "B" }, + {0x09, 0x01, 0x03, 0x01, "C" }, + {0x09, 0x01, 0x03, 0x00, "D" }, + + // Default Values + {0x0a, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0a, 0x01, 0x03, 0x02, "2C 1C" }, + {0x0a, 0x01, 0x03, 0x03, "1C 1C" }, + {0x0a, 0x01, 0x03, 0x00, "2C 3C" }, + {0x0a, 0x01, 0x03, 0x01, "1C 2C" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0a, 0x01, 0x0c, 0x0c, "3" }, + {0x0a, 0x01, 0x0c, 0x08, "4" }, + {0x0a, 0x01, 0x0c, 0x04, "5" }, + {0x0a, 0x01, 0x0c, 0x00, "7" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x0a, 0x01, 0x30, 0x30, "Easy" }, + {0x0a, 0x01, 0x30, 0x20, "Medium" }, + {0x0a, 0x01, 0x30, 0x10, "Hard" }, + {0x0a, 0x01, 0x30, 0x00, "Hardest" }, +}; + +STDDIPINFO(Drv); + +void __fastcall mrflea_write(unsigned short a, unsigned char d) +{ + if (a >= 0xe000 && a <= 0xe7ff) // video ram + { + Ram[0xe000 + (a & 0x3ff)] = d; + Ram[0xe400 + (a & 0x3ff)] = (a >> 10) & 1; + return; + } + + if (a >= 0xe800 && a <= 0xe83f) // palette ram + { + Ram[a] = d; + + Palette[(a >> 1) & 0x1f] = ((Ram[a | 1] & 0x0f) | (Ram[a | 1] << 4)) << 16; + Palette[(a >> 1) & 0x1f] |= ((Ram[a &~1] & 0xf0) | (Ram[a &~1] >> 4)) << 8; + Palette[(a >> 1) & 0x1f] |= ((Ram[a &~1] & 0x0f) | (Ram[a &~1] << 4)) << 0; + + return; + } + + if (a >= 0xec00 && a <= 0xecff) // sprite ram + { + if (a & 2) { // tile number + Ram[a | 1] = a & 1; + a &= 0xfffe; + } + + Ram[a] = d; + + return; + } +} + + +void __fastcall mrflea_out_port(unsigned short a, unsigned char data) +{ + switch (a & 0xff) + { + case 0x00: // watchdog? + case 0x43: + break; + + case 0x40: + { + mrflea_status |= 0x08; + mrflea_io = data; + + ZetClose(); + ZetOpen(1); + ZetRaiseIrq(0); + ZetClose(); + ZetOpen(0); + } + break; + + case 0x60: + mrflea_gfx_bank = data; + break; + } +} + +unsigned char __fastcall mrflea_in_port(unsigned short a) +{ + switch (a & 0xff) + { + case 0x41: + mrflea_status &= ~0x01; + return mrflea_main; + + break; + + case 0x42: + return (mrflea_status ^ 0x08); + break; + } + + return 0; +} + +void __fastcall mrflea_cpu1_out_port(unsigned short a, unsigned char data) +{ + switch (a & 0xff) + { + case 0x00: // watchdog + case 0x10: + case 0x11: + case 0x23: + break; + + case 0x21: + mrflea_status |= 0x01; + mrflea_main = data; + break; + + case 0x40: + AY8910Write(0, 0, mrflea_select[0]); + AY8910Write(0, 1, data); + break; + + case 0x42: + break; + + case 0x44: + AY8910Write(1, 0, mrflea_select[2]); + AY8910Write(1, 1, data); + break; + + case 0x46: + AY8910Write(2, 0, mrflea_select[3]); + AY8910Write(2, 1, data); + break; + + case 0x41: + case 0x43: + case 0x45: + case 0x47: + mrflea_select[(a >> 1) & 3] = data; + break; + } +} + +unsigned char __fastcall mrflea_cpu1_in_port(unsigned short a) +{ + unsigned char ret = 0; + + switch (a & 0xff) + { + case 0x10: + if (mrflea_status & 0x08) return 0x00; + return 0x01; + break; + + case 0x20: + mrflea_status &= ~0x08; + return mrflea_io; + + case 0x22: + return (mrflea_status ^ 0x01); + + case 0x40: + if (mrflea_select[0] == 0x0f) { + for (int i = 0; i < 8; i++) { + ret |= DrvJoy1[i] << i; + } + return ~ret; + } + if (mrflea_select[0] == 0x0e) { + for (int i = 0; i < 8; i++) { + ret |= DrvJoy2[i] << i; + } + return ~ret; + } + return 0; + + case 0x44: + if (mrflea_select[2] == 0x0f) return 0xff; + if (mrflea_select[2] == 0x0e) return 0xff; + return 0; + + case 0x42: + case 0x46: + return 0; + } + + return 0; +} + +static int DrvDoReset() +{ + memset (Ram, 0, 0x10000); + + memset (mrflea_select, 0, sizeof(int) * 4); + + mrflea_io = 0; + mrflea_main = 0; + mrflea_status = 0; + mrflea_gfx_bank = 0; + + DrvReset = 0; + + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + } + + for (int i = 0; i < 3; i++) { + AY8910Reset(i); + } + + return 0; +} + +static int convert_gfx() +{ + unsigned char *tmp = (unsigned char*)malloc(0x10000); + if (tmp == NULL) { + return 1; + } + + memcpy (tmp, Gfx0, 0x10000); + + for (int i = 0; i < 0x20000; i++) // sprites + { + Gfx0[i^0x07] = ((tmp[0x0000 + (i >> 3)] >> (i & 7)) & 1) << 3; + Gfx0[i^0x07] |= ((tmp[0x4000 + (i >> 3)] >> (i & 7)) & 1) << 2; + Gfx0[i^0x07] |= ((tmp[0x8000 + (i >> 3)] >> (i & 7)) & 1) << 1; + Gfx0[i^0x07] |= ((tmp[0xc000 + (i >> 3)] >> (i & 7)) & 1); + } + + memcpy (tmp, Gfx1, 0x10000); + + for (int i = 0; i < 0x20000; i+=2) // chars + { + Gfx1[i + 0] = (tmp[i>>1] >> 4) & 0x0f; + Gfx1[i + 1] = (tmp[i>>1] >> 0) & 0x0f; + } + + free (tmp); + + return 0; +} + + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x70000 + 128); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short*)malloc(nBurnSoundLen * 9 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + memset (Mem, 0, 0x70080); + + Rom0 = Mem + 0x000000; + Rom1 = Mem + 0x010000; + Ram = Mem + 0x020000; + Gfx0 = Mem + 0x030000; + Gfx1 = Mem + 0x050000; + Palette = (int*)(Mem + 0x70000); + + { + for (int i = 0; i < 6; i++) { + if (BurnLoadRom(Rom0 + i * 0x2000, i, 1)) return 1; + } + + if (BurnLoadRom(Rom1 + 0x0000, 6, 1)) return 1; + if (BurnLoadRom(Rom1 + 0x2000, 7, 1)) return 1; + if (BurnLoadRom(Rom1 + 0x3000, 8, 1)) return 1; + + for (int i = 0; i < 8; i++) { + if (BurnLoadRom(Gfx0 + i * 0x2000, i + 9, 1)) return 1; + if (BurnLoadRom(Gfx1 + i * 0x2000, i + 17, 1)) return 1; + } + + if (convert_gfx()) return 1; + } + + ZetInit(2); + ZetOpen(0); + ZetSetInHandler(mrflea_in_port); + ZetSetOutHandler(mrflea_out_port); + ZetSetWriteHandler(mrflea_write); + ZetMapArea(0x0000, 0xbfff, 0, Rom0 + 0x0000); + ZetMapArea(0x0000, 0xbfff, 2, Rom0 + 0x0000); + ZetMapArea(0xc000, 0xcfff, 0, Ram + 0xc000); + ZetMapArea(0xc000, 0xcfff, 1, Ram + 0xc000); + ZetMapArea(0xc000, 0xcfff, 2, Ram + 0xc000); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetSetInHandler(mrflea_cpu1_in_port); + ZetSetOutHandler(mrflea_cpu1_out_port); + ZetMapArea(0x0000, 0x3fff, 0, Rom1 + 0x0000); + ZetMapArea(0x0000, 0x3fff, 2, Rom1 + 0x0000); + ZetMapArea(0x8000, 0x80ff, 0, Ram + 0x8000); + ZetMapArea(0x8000, 0x80ff, 1, Ram + 0x8000); + ZetMapArea(0x8000, 0x80ff, 2, Ram + 0x8000); + ZetMapArea(0x9000, 0x905a, 0, Ram + 0x9000); + ZetMapArea(0x9000, 0x905a, 1, Ram + 0x9000); + ZetMapArea(0x9000, 0x905a, 2, Ram + 0x9000); + ZetMemEnd(); + ZetClose(); + + for (int i = 0; i < 9; i++) + pAY8910Buffer[i] = pFMBuffer + nBurnSoundLen * i; + + AY8910Init(0, 2000000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(1, 2000000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(2, 2000000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + free (Mem); + + free (pFMBuffer); + + Rom0 = Rom1 = Ram = Gfx0 = Gfx1 = NULL; + + pFMBuffer = NULL; + for (int i = 0; i < 9; i++) + pAY8910Buffer[i] = NULL; + + Palette = NULL; + + return 0; +} + + +static int DrvDraw() +{ + int base = ((mrflea_gfx_bank & 0x04) << 8) | ((mrflea_gfx_bank & 0x10) << 5); + + for (int i = 0; i < 0x400; i++) + { + int sy = (i >> 2) & 0xf8; + int sx = (i << 3) & 0xf8; + + if (sy >= 0xf8) continue; + + int code = base + Ram[0xe000 + i] + (Ram[0xe400 + i] << 8); + + unsigned char *src = Gfx1 + code * 64; + + for (int y = sy; y < sy + 8; y++) + { + for (int x = sx; x < sx + 8; x++, src++) + { + int pxl = Palette[*src]; + + PutPix(pBurnDraw + ((y << 8) | x) * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } + + for (int i = 0; i < 0x100; i+=4) + { + int sx = Ram[0xec00 + i + 1]; + int sy = Ram[0xec00 + i + 0] - 13; + + int code = (Ram[0xec00 + i + 2] | (Ram[0xec00 + i + 3] << 8)) << 8; + + unsigned char *src = Gfx0 + code; + + for (int y = sy; y < sy + 16; y++) + { + for (int x = sx; x < sx + 16; x++, src++) + { + if (!*src || x >= 0xff || y >= 0xf8 || y < 0) continue; + + int pxl = Palette[0x10|*src]; + + PutPix(pBurnDraw + ((y << 8) | x) * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } + + return 0; +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetNewFrame(); + + int nInterleave = 200; + int nSoundBufferPos = 0; + + int nCyclesSegment; + int nCyclesDone[2], nCyclesTotal[2]; + + nCyclesTotal[0] = 4000000 / 60; + nCyclesTotal[1] = 6000000 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run Z80 #0 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if (i == (nInterleave - 1)) ZetRaiseIrq(0); + ZetClose(); + + // Run Z80 #1 + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesSegment = ZetRun(nCyclesSegment); + nCyclesDone[nCurrentCPU] += nCyclesSegment; + if ((mrflea_status&0x08) || i == (nInterleave - 1)) ZetRaiseIrq(0); + ZetClose(); + + // Render Sound Segment + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + AY8910Update(2, &pAY8910Buffer[6], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + nSample += pAY8910Buffer[3][n]; + nSample += pAY8910Buffer[4][n]; + nSample += pAY8910Buffer[5][n]; + nSample += pAY8910Buffer[6][n]; + nSample += pAY8910Buffer[7][n]; + nSample += pAY8910Buffer[8][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + nSoundBufferPos += nSegmentLength; + } + } + + // Make sure the buffer is entirely filled. + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + AY8910Update(2, &pAY8910Buffer[6], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + nSample += pAY8910Buffer[3][n]; + nSample += pAY8910Buffer[4][n]; + nSample += pAY8910Buffer[5][n]; + nSample += pAY8910Buffer[6][n]; + nSample += pAY8910Buffer[7][n]; + nSample += pAY8910Buffer[8][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + ba.Data = Ram; + ba.nLen = 0x10000; + ba.szName = "All Ram"; + BurnAcb(&ba); + + memset(&ba, 0, sizeof(ba)); + ba.Data = (unsigned char*)Palette; + ba.nLen = 0x80 * sizeof(int); + ba.szName = "Palette"; + BurnAcb(&ba); + + ZetScan(nAction); // Scan Z80 + + AY8910Scan(nAction, pnMin); // Scan AY8910 + + // Scan critical driver variables + SCAN_VAR(mrflea_io); + SCAN_VAR(mrflea_main); + SCAN_VAR(mrflea_status); + SCAN_VAR(mrflea_gfx_bank); + SCAN_VAR(mrflea_select[0]); + SCAN_VAR(mrflea_select[1]); + SCAN_VAR(mrflea_select[2]); + SCAN_VAR(mrflea_select[3]); + } + + return 0; +} + + +// The Amazing Adventures of Mr. F. Lea + +static struct BurnRomInfo mrfleaRomDesc[] = { + { "cpu_d1", 0x2000, 0xd286217c, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 0 Code + { "cpu_d3", 0x2000, 0x95cf94bc, 1 | BRF_ESS | BRF_PRG }, // 1 + { "cpu_d5", 0x2000, 0x466ca77e, 1 | BRF_ESS | BRF_PRG }, // 2 + { "cpu_b1", 0x2000, 0x721477d6, 1 | BRF_ESS | BRF_PRG }, // 3 + { "cpu_b3", 0x2000, 0xf55b01e4, 1 | BRF_ESS | BRF_PRG }, // 4 + { "cpu_b5", 0x2000, 0x79f560aa, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "io_a11", 0x1000, 0x7a20c3ee, 2 | BRF_ESS | BRF_PRG }, // 6 Z80 1 Code + { "io_c11", 0x1000, 0x8d26e0c8, 2 | BRF_ESS | BRF_PRG }, // 7 + { "io_d11", 0x1000, 0xabd9afc0, 2 | BRF_ESS | BRF_PRG }, // 8 + + { "vd_l10", 0x2000, 0x48b2adf9, 3 | BRF_GRA }, // 9 Sprites + { "vd_l11", 0x2000, 0x2ff168c0, 3 | BRF_GRA }, // 10 + { "vd_l6", 0x2000, 0x100158ca, 3 | BRF_GRA }, // 11 + { "vd_l7", 0x2000, 0x34501577, 3 | BRF_GRA }, // 12 + { "vd_j10", 0x2000, 0x3f29b8c3, 3 | BRF_GRA }, // 13 + { "vd_j11", 0x2000, 0x39380bea, 3 | BRF_GRA }, // 14 + { "vd_j6", 0x2000, 0x2b4b110e, 3 | BRF_GRA }, // 15 + { "vd_j7", 0x2000, 0x3a3c8b1e, 3 | BRF_GRA }, // 16 + + { "vd_k1", 0x2000, 0x7540e3a7, 4 | BRF_GRA }, // 17 Characters + { "vd_k2", 0x2000, 0x6c688219, 4 | BRF_GRA }, // 18 + { "vd_k3", 0x2000, 0x15e96f3c, 4 | BRF_GRA }, // 19 + { "vd_k4", 0x2000, 0xfe5100df, 4 | BRF_GRA }, // 20 + { "vd_l1", 0x2000, 0xd1e3d056, 4 | BRF_GRA }, // 21 + { "vd_l2", 0x2000, 0x4d7fb925, 4 | BRF_GRA }, // 22 + { "vd_l3", 0x2000, 0x6d81588a, 4 | BRF_GRA }, // 23 + { "vd_l4", 0x2000, 0x423735a5, 4 | BRF_GRA }, // 24 +}; + +STD_ROM_PICK(mrflea); +STD_ROM_FN(mrflea); + +struct BurnDriver BurnDrvmrflea = { + "mrflea", NULL, NULL, "1982", + "The Amazing Adventures of Mr. F. Lea\0", NULL, "Pacific Novelty", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 1, HARDWARE_MISC_PRE90S, + NULL, mrfleaRomInfo, mrfleaRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 248, 256, 3, 4 +}; + diff --git a/src/burn/misc/pre90s/d_mystston.cpp b/src/burn/misc/pre90s/d_mystston.cpp new file mode 100644 index 0000000..ee37642 --- /dev/null +++ b/src/burn/misc/pre90s/d_mystston.cpp @@ -0,0 +1,676 @@ +// FB Alpha Mysterious Stones Driver Module +// Based on MAME driver by Nicola Salmoria + +#include "tiles_generic.h" +#include "m6502.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + + +static unsigned char *Mem, *Rom, *Gfx0, *Gfx1, *Gfx2, *Prom; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvReset, DrvDips[2]; +static short *pAY8910Buffer[6], *pFMBuffer = NULL; +static int *Palette; + +static int VBLK = 0x80; +static int soundlatch; +static unsigned char mystston_scroll_x = 0; +static int mystston_fgcolor, mystston_flipscreen; + + +//---------------------------------------------------------------------------------------------- +// Input Handlers + + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 6, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy2 + 6, "p1 start" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 0, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 1, "p1 left" }, + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 2, "p1 up", }, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down", }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 5, "p1 fire 2"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy1 + 7, "p2 coin" }, + {"P2 start" , BIT_DIGITAL , DrvJoy2 + 7, "p2 start" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 0, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 1, "p2 left" }, + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 2, "p2 up", }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down", }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 5, "p2 fire 2"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip 1" }, + {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip 2" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x11, 0xff, 0xff, 0xfb, NULL }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x11, 0x01, 0x01, 0x01, "3" }, + {0x11, 0x01, 0x01, 0x00, "5" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x11, 0x01, 0x02, 0x02, "Easy" }, + {0x11, 0x01, 0x02, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x11, 0x01, 0x04, 0x04, "Off" }, + {0x11, 0x01, 0x04, 0x00, "On" }, + + // Default Values + {0x12, 0xff, 0xff, 0x1f, NULL }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x12, 0x01, 0x03, 0x00, "2C 1C" }, + {0x12, 0x01, 0x03, 0x03, "1C 1C" }, + {0x12, 0x01, 0x03, 0x02, "1C 2C" }, + {0x12, 0x01, 0x03, 0x01, "1C 3C" }, + + {0 , 0xfe, 0 , 4 , "Coin B" }, + {0x12, 0x01, 0x0c, 0x00, "2C 1C" }, + {0x12, 0x01, 0x0c, 0x0c, "1C 1C" }, + {0x12, 0x01, 0x0c, 0x08, "1C 2C" }, + {0x12, 0x01, 0x0c, 0x04, "1C 3C" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x12, 0x01, 0x20, 0x00, "Off" }, + {0x12, 0x01, 0x20, 0x20, "On" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x40, 0x00, "Upright" }, + {0x12, 0x01, 0x40, 0x40, "Cocktail" }, +}; + +STDDIPINFO(Drv); + + +//---------------------------------------------------------------------------------------------- +// Memory Read/Write Handlers + + +static void mystston_soundcontrol_w(unsigned short, unsigned char data) +{ + static int last; + + if ((last & 0x20) == 0x20 && (data & 0x20) == 0x00) + { + if (last & 0x10) + AY8910Write(0, 0, soundlatch); + else + AY8910Write(0, 1, soundlatch); + } + + if ((last & 0x80) == 0x80 && (data & 0x80) == 0x00) + { + if (last & 0x40) + AY8910Write(1, 0, soundlatch); + else + AY8910Write(1, 1, soundlatch); + } + + last = data; +} + +unsigned char mystston_read_byte(unsigned short address) +{ + unsigned char ret = 0; + + switch (address) + { + case 0x2000: + { + for (int i = 0; i < 8; i++) + ret |= DrvJoy1[i] << i; + + return ~ret; + } + + case 0x2010: + { + for (int i = 0; i < 8; i++) + ret |= DrvJoy2[i] << i; + + return ~ret; + } + + case 0x2020: + return DrvDips[0]; + + case 0x2030: + return DrvDips[1] | VBLK; + } + + return 0; +} + +void mystston_write_byte(unsigned short address, unsigned char data) +{ +#define pal2bit(bits) (((bits & 3) << 6) | ((bits & 3) << 4) | ((bits & 3) << 2) | (bits & 3)) +#define pal3bit(bits) (((bits & 7) << 5) | ((bits & 7) << 2) | ((bits & 7) >> 1)) + + switch (address) + { + case 0x2000: + { + mystston_fgcolor = ((data & 0x01) << 1) + ((data & 0x02) >> 1); + mystston_flipscreen = (data & 0x80) ^ ((DrvDips[1] & 0x20) ? 0x80 : 0); + } + break; + + case 0x2010: + m6502SetIRQ(M6502_CLEAR); + break; + + case 0x2020: + mystston_scroll_x = data; + break; + + case 0x2030: + soundlatch = data; + break; + + case 0x2040: + mystston_soundcontrol_w(0, data); + break; + } + + if (address >= 0x2060 && address <= 0x2077) + { + Palette[address & 0x1f] = (pal3bit(data) << 16) | (pal3bit(data >> 3) << 8) | pal2bit(data >> 6); + } + +#undef pal2bit +#undef pal3bit +} + + +//---------------------------------------------------------------------------------------------- +// Initilization Routines + + +static int DrvDoReset() +{ + DrvReset = 0; + + memset (Rom, 0, 0x2000); + + VBLK = 0x80; + soundlatch = 0; + mystston_flipscreen = 0; + mystston_scroll_x = 0; + mystston_fgcolor = 0; + + AY8910Reset(0); + AY8910Reset(1); + + m6502Open(0); + m6502Reset(); + m6502Close(); + + return 0; +} + +static void mystston_palette_init() +{ + for (int i = 0; i < 32; i++) + { + int bit0, bit1, bit2, r, g, b; + + bit0 = (Prom[i] >> 0) & 0x01; + bit1 = (Prom[i] >> 1) & 0x01; + bit2 = (Prom[i] >> 2) & 0x01; + r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = (Prom[i] >> 3) & 0x01; + bit1 = (Prom[i] >> 4) & 0x01; + bit2 = (Prom[i] >> 5) & 0x01; + g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit1 = (Prom[i] >> 6) & 0x01; + bit2 = (Prom[i] >> 7) & 0x01; + b = 0x21 * 0 + 0x47 * bit1 + 0x97 * bit2; + + Palette[i + 24] = (r << 16) | (g << 8) | b; + } +} + +static int mystston_gfx_convert() +{ + static int PlaneOffsets[3] = { 0x40000, 0x20000, 0 }; + static int XOffsets[16] = { 128, 129, 130, 131, 132, 133, 134, 135, 0, 1, 2, 3, 4, 5, 6, 7 }; + static int YOffsets[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }; + + unsigned char *tmp = (unsigned char*)malloc(0x10000); + if (tmp == NULL) { + return 1; + } + + memcpy (tmp, Gfx0, 0x10000); + + GfxDecode(0x800, 3, 8, 8, PlaneOffsets, XOffsets + 8, YOffsets, 0x040, tmp, Gfx0); + GfxDecode(0x200, 3, 16, 16, PlaneOffsets, XOffsets + 0, YOffsets, 0x100, tmp, Gfx2); + + memcpy (tmp, Gfx1, 0x10000); + + GfxDecode(0x200, 3, 16, 16, PlaneOffsets, XOffsets + 0, YOffsets, 0x100, tmp, Gfx1); + + free (tmp); + + return 0; +} + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x10000 + 0x20000 + 0x20000 + 0x20000 + 0x20 + 0x38 * sizeof(int)); + if (Mem == NULL) { + return 1; + } + memset (Mem, 0, 0x70000 + 0x20); + + pFMBuffer = (short *)malloc (nBurnSoundLen * 6 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + Rom = Mem + 0x00000; + Gfx0 = Mem + 0x10000; + Gfx1 = Mem + 0x30000; + Gfx2 = Mem + 0x50000; + Prom = Mem + 0x70000; + Palette = (int*)(Mem + 0x70020); + + // Load Roms + { + for (int i = 0; i < 6; i++) { + if (BurnLoadRom(Rom + i * 0x2000 + 0x4000, i + 0, 1)) return 1; + if (BurnLoadRom(Gfx0 + i * 0x2000 + 0x0000, i + 6, 1)) return 1; + if (BurnLoadRom(Gfx1 + i * 0x2000 + 0x0000, i + 12, 1)) return 1; + } + + if (BurnLoadRom(Prom, 18, 1)) return 1; + + if(mystston_gfx_convert()) return 1; + mystston_palette_init(); + } + + m6502Init(1); + m6502Open(0); + m6502MapMemory(Rom + 0x0000, 0x0000, 0x1fff, M6502_RAM); + m6502MapMemory(Rom + 0x4000, 0x4000, 0xffff, M6502_ROM); + m6502SetReadHandler(mystston_read_byte); + m6502SetWriteHandler(mystston_write_byte); + m6502Close(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + pAY8910Buffer[3] = pFMBuffer + nBurnSoundLen * 3; + pAY8910Buffer[4] = pFMBuffer + nBurnSoundLen * 4; + pAY8910Buffer[5] = pFMBuffer + nBurnSoundLen * 5; + + AY8910Init(0, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(1, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + +// BurnSetRefreshRate(57.445); + + return 0; +} + +static int DrvExit() +{ + m6502Exit(); + AY8910Exit(0); + AY8910Exit(1); + + free (Mem); + free (pFMBuffer); + + pFMBuffer = NULL; + Palette = NULL; + Rom = Gfx0 = Gfx1 = Gfx2 = Prom = NULL; + + VBLK = 0x00; + soundlatch = 0; + mystston_scroll_x = 0; + mystston_fgcolor = mystston_flipscreen = 0; + + return 0; +} + + +//---------------------------------------------------------------------------------------------- +// Drawing Routines + + +static inline void mystston_putpix(int x, int y, unsigned char src, int color, int transp) +{ + int pos, pxl; + + if (y > 255 || x > 239 || x < 0 || (!src && transp)) return; + + if (mystston_flipscreen) + pos = ((255 - y) * 240) + (239 - x); + else + pos = (y * 240) + x; + + pxl = Palette[color | src]; + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); +} + +static void draw_16x16(int sx, int sy, unsigned char *gfx_base, int code, int color, int flipx, int flipy, int transp) +{ + unsigned char *src = gfx_base + code; + + if (flipx) + { + for (int x = sx + 15; x >= sx; x--) + { + if (flipy) + { + for (int y = sy; y < sy + 16; y++, src++) { + mystston_putpix(x, y, *src, color, transp); + } + } else { + for (int y = sy + 15; y >= sy; y--, src++) { + mystston_putpix(x, y, *src, color, transp); + } + } + } + } else { + for (int x = sx; x < sx + 16; x++) + { + if (flipy) + { + for (int y = sy; y < sy + 16; y++, src++) { + mystston_putpix(x, y, *src, color, transp); + } + } else { + for (int y = sy + 15; y >= sy; y--, src++) { + mystston_putpix(x, y, *src, color, transp); + } + } + } + } +} + +static int DrvDraw() +{ + for (int offs = 0; offs < 0x200; offs++) + { + int code = (Rom[0x1800 + offs] + ((Rom[0x1a00 + offs] & 0x01) << 8)) << 8; + int flipx = offs & 0x10; + int sx = ((offs & 0x1f) << 4) - (mystston_scroll_x + 8); + int sy = ((offs >> 5) << 4); + + draw_16x16(sx, sy, Gfx1, code, 0x10, flipx, 0, 0); + } + + for (int offs = 0; offs < 0x60; offs += 4) + { + int attr = Rom[0x0780 + offs]; + + if (attr & 0x01) + { + int code = (Rom[0x0781 + offs] + ((attr & 0x10) << 4)) << 8; + int color = attr & 0x08; + int flipy = attr & 0x04; + int flipx = attr & 0x02; + int sy = Rom[0x0783 + offs]; + int sx = (240 - Rom[0x0782 + offs]) - 9; + + draw_16x16(sx, sy, Gfx2, code, color, flipx, flipy, 1); + } + } + + for (int offs = 0; offs < 0x400; offs++) + { + int code = (Rom[0x1000 | offs] + ((Rom[0x1400 + offs] & 0x07) << 8)) << 6; + int color = (mystston_fgcolor << 3) + 0x18; + int sx = (offs & 0x1f) << 3; + int sy = (offs >> 2) & 0xf8; + if (sx >= 248 || sx < 8) continue; + sx -= 8; + + unsigned char *src = Gfx0 + code; + + for (int x = sx; x < sx + 8; x++) + { + for (int y = sy + 7; y >= sy; y--, src++) + { + if (!*src) continue; + + int pos; + if (mystston_flipscreen) + pos = ((255 - y) * 240) + (239 - x); + else + pos = (y * 240) + x; + + int pxl = Palette[color | *src]; + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } + + return 0; +} + +static void mystston_interrupt_handler(int scanline) +{ + static int coin; + int inp = (DrvJoy1[6] << 6) | (DrvJoy1[7] << 7); + + if ((~inp & 0xc0) != 0xc0) + { + if (coin == 0) + { + coin = 1; + m6502SetIRQ(M6502_NMI); + return; + } + } + else coin = 0; + + if (scanline == 8) + VBLK = 0; + + if (scanline == 248) + VBLK = 0x80; + + if ((scanline & 0x0f) == 0) + m6502SetIRQ(M6502_IRQ); +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + int nTotalCycles = (int)((double)(1500000 / 57.45)); + int nCyclesRun = 0; + + m6502Open(0); + + for (int i = 0; i < 272; i++) { + nCyclesRun += m6502Run(nTotalCycles / 272); + mystston_interrupt_handler(i); + } + + m6502Close(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +//---------------------------------------------------------------------------------------------- +// Save State + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + ba.Data = Rom + 0x0000; + ba.nLen = 0x2000; + ba.szName = "All Ram"; + BurnAcb(&ba); + + memset(&ba, 0, sizeof(ba)); + ba.Data = Mem + 0x70020; + ba.nLen = 24 * sizeof(int); + ba.szName = "Palette"; + BurnAcb(&ba); + + m6502Scan(nAction); + AY8910Scan(nAction, pnMin); + + // Scan critical driver variables + SCAN_VAR(mystston_flipscreen); + SCAN_VAR(mystston_scroll_x); + SCAN_VAR(mystston_fgcolor); + SCAN_VAR(soundlatch); + SCAN_VAR(VBLK); + } + + return 0; +} + + +//---------------------------------------------------------------------------------------------- +// Game Drivers + + +// Mysterious Stones - Dr. John's Adventure + +static struct BurnRomInfo myststonRomDesc[] = { + { "rom6.bin", 0x2000, 0x7bd9c6cd, 1 | BRF_PRG | BRF_ESS }, // 0 M6205 Code + { "rom5.bin", 0x2000, 0xa83f04a6, 1 | BRF_PRG | BRF_ESS }, // 1 + { "rom4.bin", 0x2000, 0x46c73714, 1 | BRF_PRG | BRF_ESS }, // 2 + { "rom3.bin", 0x2000, 0x34f8b8a3, 1 | BRF_PRG | BRF_ESS }, // 3 + { "rom2.bin", 0x2000, 0xbfd22cfc, 1 | BRF_PRG | BRF_ESS }, // 4 + { "rom1.bin", 0x2000, 0xfb163e38, 1 | BRF_PRG | BRF_ESS }, // 5 + + { "ms6", 0x2000, 0x85c83806, 2 | BRF_GRA }, // 6 Character + Sprite Tiles + { "ms9", 0x2000, 0xb146c6ab, 2 | BRF_GRA }, // 7 + { "ms7", 0x2000, 0xd025f84d, 2 | BRF_GRA }, // 8 + { "ms10", 0x2000, 0xd85015b5, 2 | BRF_GRA }, // 9 + { "ms8", 0x2000, 0x53765d89, 2 | BRF_GRA }, // 10 + { "ms11", 0x2000, 0x919ee527, 2 | BRF_GRA }, // 11 + + { "ms12", 0x2000, 0x72d8331d, 3 | BRF_GRA }, // 12 Sprite Tiles + { "ms13", 0x2000, 0x845a1f9b, 3 | BRF_GRA }, // 13 + { "ms14", 0x2000, 0x822874b0, 3 | BRF_GRA }, // 14 + { "ms15", 0x2000, 0x4594e53c, 3 | BRF_GRA }, // 15 + { "ms16", 0x2000, 0x2f470b0f, 3 | BRF_GRA }, // 16 + { "ms17", 0x2000, 0x38966d1b, 3 | BRF_GRA }, // 17 + + { "ic61", 0x0020, 0xe802d6cf, 4 | BRF_GRA }, // 18 Color Prom +}; + +STD_ROM_PICK(mystston); +STD_ROM_FN(mystston); + +struct BurnDriver BurnDrvmystston = { + "mystston", NULL, NULL, "1984", + "Mysterious Stones - Dr. John's Adventure\0", NULL, "Technos", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, myststonRomInfo, myststonRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 240, 256, 3, 4 +}; + + +// Mysterious Stones - Dr. Kick in Adventure + +static struct BurnRomInfo myststnoRomDesc[] = { + { "ms0", 0x2000, 0x6dacc05f, 1 | BRF_PRG | BRF_ESS }, // 0 M6205 Code + { "ms1", 0x2000, 0xa3546df7, 1 | BRF_PRG | BRF_ESS }, // 1 + { "ms2", 0x2000, 0x43bc6182, 1 | BRF_PRG | BRF_ESS }, // 2 + { "ms3", 0x2000, 0x9322222b, 1 | BRF_PRG | BRF_ESS }, // 3 + { "ms4", 0x2000, 0x47cefe9b, 1 | BRF_PRG | BRF_ESS }, // 4 + { "ms5", 0x2000, 0xb37ae12b, 1 | BRF_PRG | BRF_ESS }, // 5 + + { "ms6", 0x2000, 0x85c83806, 2 | BRF_GRA }, // 6 Character + Sprite Tiles + { "ms9", 0x2000, 0xb146c6ab, 2 | BRF_GRA }, // 7 + { "ms7", 0x2000, 0xd025f84d, 2 | BRF_GRA }, // 8 + { "ms10", 0x2000, 0xd85015b5, 2 | BRF_GRA }, // 9 + { "ms8", 0x2000, 0x53765d89, 2 | BRF_GRA }, // 10 + { "ms11", 0x2000, 0x919ee527, 2 | BRF_GRA }, // 11 + + { "ms12", 0x2000, 0x72d8331d, 3 | BRF_GRA }, // 12 Sprite Tiles + { "ms13", 0x2000, 0x845a1f9b, 3 | BRF_GRA }, // 13 + { "ms14", 0x2000, 0x822874b0, 3 | BRF_GRA }, // 14 + { "ms15", 0x2000, 0x4594e53c, 3 | BRF_GRA }, // 15 + { "ms16", 0x2000, 0x2f470b0f, 3 | BRF_GRA }, // 16 + { "ms17", 0x2000, 0x38966d1b, 3 | BRF_GRA }, // 17 + + { "ic61", 0x0020, 0xe802d6cf, 4 | BRF_GRA }, // 18 Color Prom +}; + +STD_ROM_PICK(myststno); +STD_ROM_FN(myststno); + +struct BurnDriver BurnDrvmyststno = { + "myststno", "mystston", NULL, "1984", + "Mysterious Stones - Dr. Kick in Adventure\0", NULL, "Technos", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, myststnoRomInfo, myststnoRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 240, 256, 3, 4 +}; + diff --git a/src/burn/misc/pre90s/d_pacman.cpp b/src/burn/misc/pre90s/d_pacman.cpp new file mode 100644 index 0000000..c4b8a52 --- /dev/null +++ b/src/burn/misc/pre90s/d_pacman.cpp @@ -0,0 +1,5734 @@ +// FB Alpha Puckman module +// Based on MAME driver by Nicola Salmoria and many others + +/* +To do: + +Figure out why "Highscore" isn't shown on Pacman, etc +Fix Shoot the Bull inputs +Sound + +1.1 +Fixed graphics glitches on left side of screen +Adjusted default dips (3x lives & 1C 1C) +Now uses generic tile decoding + +Thanks to LittleKaneda for the bug report :) +*/ + +#include "tiles_generic.h" +#include "bitswap.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + + +// General variables +static unsigned char *Mem, *Rom, *Gfx, *Prom, *Snd, *QRom; +static short *pAY8910Buffer[3], *pFMBuffer = NULL; +static int *Palette; + +static int screen_flip = 0, bgpriority = 0; + +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvReset, DrvDips[4]; +static unsigned short DrvAxis[2] = { 0, 0 }; +static unsigned int nAnalogAxis[2]; +static unsigned char nCharAxis[2]; + +static void (*pPacInitCallback)() = NULL; + + +// Enable per-game settings +static int mspacman = 0, cannonbp = 0, maketrax = 0; +static int piranha = 0, vanvan = 0, nmouse = 0; +static int dremshpr = 0, acitya = 0, mschamp = 0; +static int bigbucks = 0, rocktrv2 = 0, korosuke = 0; +static int alibaba = 0, crushs = 0, shootbul = 0; + +static int epos_hardware = 0; + + +// Volatile general variables +static int flipscreen; +static int nPacBank = -1; +static int interrupt_mode, interrupt_enable; +static unsigned char colortablebank, palettebank; +static unsigned char spritebank, charbank; + +// Protection variables +static int alibaba_mystery; +static unsigned char rocktrv2_prot_data[4]; +static char epos_hardware_counter; +static unsigned char mschamp_counter; +static unsigned char cannonb_bit_to_read; + + +//------------------------------------------------------------------------------------------------------ +// Inputs + + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Service Mode", BIT_DIGITAL, DrvJoy1 + 7, "diag"}, + + {"Dip Switches 1 ", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, + {"Dip Switches 4", BIT_DIPSWITCH, DrvDips + 3, "dip"}, +}; + +STDINPUTINFO(Drv); + +static struct BurnInputInfo mschampInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin"}, + {"Coin 3", BIT_DIGITAL, DrvJoy1 + 7, "p3 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, + {"Dip Switches 4", BIT_DIPSWITCH, DrvDips + 3, "dip"}, +}; + +STDINPUTINFO(mschamp); + +static struct BurnInputInfo eyesInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 7, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 7, "p2 fire"}, + + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Tilt", BIT_DIGITAL, DrvJoy1 + 6, "tilt"}, + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, +}; + +STDINPUTINFO(eyes); + +static struct BurnInputInfo theglobpInputList[] = { + {"Coin", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 button 1"}, + {"P1 Button 2", BIT_DIGITAL, DrvJoy2 + 6, "p1 button 2"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p2 button 1"}, + {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 7, "p2 button 2"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Service Mode", BIT_DIGITAL, DrvJoy1 + 7, "diag"}, + + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 1, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 0, "dip"}, +}; + +STDINPUTINFO(theglobp); + +static struct BurnInputInfo ponpokoInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P2 button 1", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Service Mode", BIT_DIGITAL, DrvJoy1 + 7, "diag"}, + + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 3, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 4", BIT_DIPSWITCH, DrvDips + 1, "dip"}, +}; + +STDINPUTINFO(ponpoko); + +static struct BurnInputInfo vanvanInputList[] = { + {"Coin", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 button 1"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p2 button 1"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Service Mode", BIT_DIGITAL, DrvJoy1 + 7, "diag"}, + + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, +}; + +STDINPUTINFO(vanvan); + +static struct BurnInputInfo vanvankInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 7, "p2 coin"}, + + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 button 1"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p2 button 1"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, +}; + +STDINPUTINFO(vanvank); + +static struct BurnInputInfo cannonbpInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 7, "p1 button 1"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P2 Button 2", BIT_DIGITAL, DrvJoy2 + 4, "p2 button 1"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, +}; + +STDINPUTINFO(cannonbp); + +static struct BurnInputInfo rocktrv2InputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + + {"Tilt", BIT_DIGITAL, DrvJoy1 + 7, "diag"}, + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 3, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 4", BIT_DIPSWITCH, DrvDips + 1, "dip"}, +}; + +STDINPUTINFO(rocktrv2); + +static struct BurnInputInfo bigbucksInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Service Mode", BIT_DIGITAL, DrvJoy1 + 7, "diag"}, + + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 1, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 0, "dip"}, +}; + +STDINPUTINFO(bigbucks); + +static struct BurnInputInfo woodpekInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 7, "p2 fire"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Service Mode", BIT_DIGITAL, DrvJoy1 + 7, "diag"}, + + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, +}; + +STDINPUTINFO(woodpek); + +static struct BurnInputInfo acityaInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 0, "p1 fire 1"}, + {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 1, "p1 fire 2"}, + {"P1 Button 3", BIT_DIGITAL, DrvJoy1 + 2, "p1 fire 3"}, + {"P1 Button 4", BIT_DIGITAL, DrvJoy1 + 3, "p1 fire 4"}, + {"P1 Button 5", BIT_DIGITAL, DrvJoy2 + 5, "p1 fire 5"}, + {"P1 Button 6", BIT_DIGITAL, DrvJoy2 + 6, "p1 fire 6"}, + + {"Service Mode 1", BIT_DIGITAL, DrvJoy1 + 4, "diag"}, + {"Service Mode 2", BIT_DIGITAL, DrvJoy2 + 4, "diag"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 1, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 0, "dip"}, +}; + +STDINPUTINFO(acitya); + +static struct BurnInputInfo bwcasinoInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 0, "p1 fire 1"}, + {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 1, "p1 fire 2"}, + {"P1 Button 3", BIT_DIGITAL, DrvJoy1 + 2, "p1 fire 3"}, + {"P1 Button 4", BIT_DIGITAL, DrvJoy1 + 3, "p1 fire 4"}, + + {"P1 Button 5", BIT_DIGITAL, DrvJoy2 + 5, "p1 fire 5"}, + {"P1 Button 6", BIT_DIGITAL, DrvJoy2 + 6, "p1 fire 6"}, + + {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 0, "p2 fire 1"}, + {"P2 Button 2", BIT_DIGITAL, DrvJoy2 + 1, "p2 fire 2"}, + {"P2 Button 3", BIT_DIGITAL, DrvJoy2 + 2, "p2 fire 3"}, + {"P2 Button 4", BIT_DIGITAL, DrvJoy2 + 3, "p2 fire 4"}, + {"P2 Button 5", BIT_DIGITAL, DrvJoy2 + 5, "p2 fire 5"}, + {"P2 Button 6", BIT_DIGITAL, DrvJoy1 + 7, "p2 fire 6"}, + + {"Service Mode ", BIT_DIGITAL, DrvJoy1 + 4, "diag"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 1, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 0, "dip"}, +}; + +STDINPUTINFO(bwcasino); + +static struct BurnInputInfo dremshprInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 7, "p2 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, + {"Dip Switches 4", BIT_DIPSWITCH, DrvDips + 3, "dip"}, +}; + +STDINPUTINFO(dremshpr); + +static struct BurnInputInfo alibabaInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 7, "p2 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 6, "p1 fire"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p2 fire"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 1, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 2, "dip"}, +}; + +STDINPUTINFO(alibaba); + +static struct BurnInputInfo jumpshotInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 fire"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P2 Button 1", BIT_DIGITAL, DrvJoy2 + 6, "p2 fire"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Service Mode", BIT_DIGITAL, DrvJoy1 + 7, "diag"}, + + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, +}; + +STDINPUTINFO(jumpshot); + +static struct BurnInputInfo korosukeInputList[] = { + {"Coin", BIT_DIGITAL, DrvJoy1 + 6, "p1 coin"}, + {"Start 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 start"}, + {"Start 2", BIT_DIGITAL, DrvJoy2 + 6, "p2 start"}, + + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 0, "p1 up"}, + {"P1 Left", BIT_DIGITAL, DrvJoy1 + 1, "p1 left"}, + {"P1 Right", BIT_DIGITAL, DrvJoy1 + 2, "p1 right"}, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 7, "p1 button 1"}, + + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 0, "p2 up"}, + {"P2 Left", BIT_DIGITAL, DrvJoy2 + 1, "p2 left"}, + {"P2 Right", BIT_DIGITAL, DrvJoy2 + 2, "p2 right"}, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down"}, + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 button 1"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + {"Service Mode", BIT_DIGITAL, DrvJoy1 + 7, "diag"}, + + {"Dip Switches 1 ", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, + {"Dip Switches 4", BIT_DIPSWITCH, DrvDips + 3, "dip"}, +}; + +STDINPUTINFO(korosuke); + +#define A(a, b, c, d) { a, b, (unsigned char*)(c), d } + +static struct BurnInputInfo shootbulInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy1 + 5, "p1 coin"}, + {"Coin 2", BIT_DIGITAL, DrvJoy1 + 6, "p2 coin"}, + {"Coin 3", BIT_DIGITAL, DrvJoy1 + 7, "p3 coin"}, + {"Start", BIT_DIGITAL, DrvJoy2 + 6, "p1 start"}, + + A("P1 X Axis", BIT_ANALOG_REL, DrvAxis + 0, "mouse x-axis"), + A("P1 Y Axis", BIT_ANALOG_REL, DrvAxis + 1, "mouse y-axis"), + + {"P1 Button A", BIT_DIGITAL, DrvJoy2 + 5, "mouse button 1"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, + + {"Dip Switches 1", BIT_DIPSWITCH, DrvDips + 2, "dip"}, + {"Dip Switches 2", BIT_DIPSWITCH, DrvDips + 0, "dip"}, + {"Dip Switches 3", BIT_DIPSWITCH, DrvDips + 1, "dip"}, +}; + +STDINPUTINFO(shootbul); + +#undef A + + +//------------------------------------------------------------------------------------------------------ +// Dip switches + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Rack Test (Cheat)" }, + {0x0f, 0x01, 0x10, 0x10, "Off" }, + {0x0f, 0x01, 0x10, 0x00, "On" }, + + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x80, 0x80, "Upright" }, + {0x10, 0x01, 0x80, 0x00, "Cocktail" }, + + + // Default Values + {0x0e, 0xff, 0xff, 0xc9, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0e, 0x01, 0x03, 0x03, "2C 1C" }, + {0x0e, 0x01, 0x03, 0x01, "1C 1C" }, + {0x0e, 0x01, 0x03, 0x02, "1C 2C" }, + {0x0e, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0e, 0x01, 0x0c, 0x00, "1" }, + {0x0e, 0x01, 0x0c, 0x04, "2" }, + {0x0e, 0x01, 0x0c, 0x08, "3" }, + {0x0e, 0x01, 0x0c, 0x0c, "5" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x0e, 0x01, 0x30, 0x00, "10000" }, + {0x0e, 0x01, 0x30, 0x10, "15000" }, + {0x0e, 0x01, 0x30, 0x20, "20000" }, + {0x0e, 0x01, 0x30, 0x30, "None" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0e, 0x01, 0x40, 0x40, "Normal" }, + {0x0e, 0x01, 0x40, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Ghost Names" }, + {0x0e, 0x01, 0x80, 0x80, "Normal" }, + {0x0e, 0x01, 0x80, 0x00, "Alternate" }, +}; + +STDDIPINFO(Drv); + +static struct BurnDIPInfo mspacmanDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Rack Test (Cheat)" }, + {0x0f, 0x01, 0x10, 0x10, "Off" }, + {0x0f, 0x01, 0x10, 0x00, "On" }, + + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x80, 0x80, "Upright" }, + {0x10, 0x01, 0x80, 0x00, "Cocktail" }, + + + // Default Values + {0x0e, 0xff, 0xff, 0xe9, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0e, 0x01, 0x03, 0x03, "2C 1C" }, + {0x0e, 0x01, 0x03, 0x01, "1C 1C" }, + {0x0e, 0x01, 0x03, 0x02, "1C 2C" }, + {0x0e, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0e, 0x01, 0x0c, 0x00, "1" }, + {0x0e, 0x01, 0x0c, 0x04, "2" }, + {0x0e, 0x01, 0x0c, 0x08, "3" }, + {0x0e, 0x01, 0x0c, 0x0c, "5" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x0e, 0x01, 0x30, 0x00, "10000" }, + {0x0e, 0x01, 0x30, 0x10, "15000" }, + {0x0e, 0x01, 0x30, 0x20, "20000" }, + {0x0e, 0x01, 0x30, 0x30, "None" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0e, 0x01, 0x40, 0x40, "Normal" }, + {0x0e, 0x01, 0x40, 0x00, "Hard" }, +}; + +STDDIPINFO(mspacman); + +static struct BurnDIPInfo mschampDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Rack Test (Cheat)" }, + {0x0f, 0x01, 0x10, 0x10, "Off" }, + {0x0f, 0x01, 0x10, 0x00, "On" }, + + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x80, 0x80, "Upright" }, + {0x10, 0x01, 0x80, 0x00, "Cocktail" }, + + + // Default Values + {0x0e, 0xff, 0xff, 0xc9, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0e, 0x01, 0x03, 0x03, "2C 1C" }, + {0x0e, 0x01, 0x03, 0x01, "1C 1C" }, + {0x0e, 0x01, 0x03, 0x02, "1C 2C" }, + {0x0e, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0e, 0x01, 0x0c, 0x00, "1" }, + {0x0e, 0x01, 0x0c, 0x04, "2" }, + {0x0e, 0x01, 0x0c, 0x08, "3" }, + {0x0e, 0x01, 0x0c, 0x0c, "5" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x0e, 0x01, 0x30, 0x00, "10000" }, + {0x0e, 0x01, 0x30, 0x10, "15000" }, + {0x0e, 0x01, 0x30, 0x20, "20000" }, + {0x0e, 0x01, 0x30, 0x30, "None" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0e, 0x01, 0x40, 0x40, "Normal" }, + {0x0e, 0x01, 0x40, 0x00, "Hard" }, + + // Default Values + {0x11, 0xff, 0xff, 0x00, NULL }, + + {0 , 0xfe, 0 , 2 , "Game" }, + {0x11, 0x01, 0x01, 0x01, "Champion Edition" }, + {0x11, 0x01, 0x01, 0x00, "Super Zola Pac Gal" }, +}; + +STDDIPINFO(mschamp); + +static struct BurnDIPInfo maketraxDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xef, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x10, 0x00, "Upright" }, + {0x0f, 0x01, 0x10, 0x10, "Cocktail" }, + + + // Default Values + {0x10, 0xff, 0x6f, 0x6f, NULL }, + + + // Default Values + {0x0e, 0xff, 0x3f, 0x31, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0e, 0x01, 0x03, 0x03, "2C 1C" }, + {0x0e, 0x01, 0x03, 0x01, "1C 1C" }, + {0x0e, 0x01, 0x03, 0x02, "1C 2C" }, + {0x0e, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0e, 0x01, 0x0c, 0x00, "3" }, + {0x0e, 0x01, 0x0c, 0x04, "4" }, + {0x0e, 0x01, 0x0c, 0x08, "5" }, + {0x0e, 0x01, 0x0c, 0x0c, "6" }, + + {0 , 0xfe, 0 , 2 , "First Pattern" }, + {0x0e, 0x01, 0x30, 0x10, "Easy" }, + {0x0e, 0x01, 0x30, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Teleport Holes" }, + {0x0e, 0x01, 0x20, 0x20, "Off" }, + {0x0e, 0x01, 0x20, 0x00, "On" }, +}; + +STDDIPINFO(maketrax); + +static struct BurnDIPInfo mbrushDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xef, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x10, 0x00, "Upright" }, + {0x0f, 0x01, 0x10, 0x10, "Cocktail" }, + + + // Default Values + {0x10, 0xff, 0x6f, 0x6f, NULL }, + + + // Default Values + {0x0e, 0xff, 0x3f, 0x39, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0e, 0x01, 0x03, 0x03, "2C 1C" }, + {0x0e, 0x01, 0x03, 0x01, "1C 1C" }, + {0x0e, 0x01, 0x03, 0x02, "1C 2C" }, + {0x0e, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0e, 0x01, 0x0c, 0x00, "1" }, + {0x0e, 0x01, 0x0c, 0x04, "2" }, + {0x0e, 0x01, 0x0c, 0x08, "3" }, + {0x0e, 0x01, 0x0c, 0x0c, "4" }, +}; + +STDDIPINFO(mbrush); + +static struct BurnDIPInfo crushsDIPList[]= +{ + // Default Values + {0x0e, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Teleport Holes" }, + {0x0f, 0x01, 0x10, 0x10, "Off" }, + {0x0f, 0x01, 0x10, 0x00, "On" }, + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x11, 0xff, 0xff, 0x00, NULL }, + + {0 , 0xfe, 0 , 16 , "Coin A" }, + {0x11, 0x01, 0x0f, 0x08, "2C 1C" }, + {0x11, 0x01, 0x0f, 0x09, "2C 2C" }, + {0x11, 0x01, 0x0f, 0x00, "1C 1C" }, + {0x11, 0x01, 0x0f, 0x0a, "2C 3C" }, + {0x11, 0x01, 0x0f, 0x0b, "2C 4C" }, + {0x11, 0x01, 0x0f, 0x01, "2C 2C" }, + {0x11, 0x01, 0x0f, 0x0c, "1C 5C" }, + {0x11, 0x01, 0x0f, 0x0d, "2C 6C" }, + {0x11, 0x01, 0x0f, 0x02, "1C 3C" }, + {0x11, 0x01, 0x0f, 0x0e, "2C 7C" }, + {0x11, 0x01, 0x0f, 0x0f, "2C 8C" }, + {0x11, 0x01, 0x0f, 0x03, "1C 4C" }, + {0x11, 0x01, 0x0f, 0x04, "1C 5C" }, + {0x11, 0x01, 0x0f, 0x05, "1C 6C" }, + {0x11, 0x01, 0x0f, 0x06, "1C 7C" }, + {0x11, 0x01, 0x0f, 0x07, "1C 8C" }, + + {0 , 0xfe, 0 , 16 , "Coin B" }, + {0x11, 0x01, 0xf0, 0x80, "2C 1C" }, + {0x11, 0x01, 0xf0, 0x90, "2C 2C" }, + {0x11, 0x01, 0xf0, 0x00, "1C 1C" }, + {0x11, 0x01, 0xf0, 0xa0, "2C 3C" }, + {0x11, 0x01, 0xf0, 0xb0, "2C 4C" }, + {0x11, 0x01, 0xf0, 0x10, "2C 2C" }, + {0x11, 0x01, 0xf0, 0xc0, "1C 5C" }, + {0x11, 0x01, 0xf0, 0xd0, "2C 6C" }, + {0x11, 0x01, 0xf0, 0x20, "1C 3C" }, + {0x11, 0x01, 0xf0, 0xe0, "2C 7C" }, + {0x11, 0x01, 0xf0, 0xf0, "2C 8C" }, + {0x11, 0x01, 0xf0, 0x30, "1C 4C" }, + {0x11, 0x01, 0xf0, 0x40, "1C 5C" }, + {0x11, 0x01, 0xf0, 0x50, "1C 6C" }, + {0x11, 0x01, 0xf0, 0x60, "1C 7C" }, + {0x11, 0x01, 0xf0, 0x70, "1C 8C" }, +}; + +STDDIPINFO(crushs); + +static struct BurnDIPInfo ponpokoDIPList[]= +{ + // Default Values + {0x12, 0xff, 0xff, 0xe0, NULL }, + + // Default Values + {0x13, 0xff, 0xff, 0x00, NULL }, + + // Default Values + {0x10, 0xff, 0xff, 0xd1, NULL }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x10, 0x01, 0x03, 0x00, "10000" }, + {0x10, 0x01, 0x03, 0x01, "30000" }, + {0x10, 0x01, 0x03, 0x02, "50000" }, + {0x10, 0x01, 0x03, 0x03, "None" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x10, 0x01, 0x30, 0x00, "2" }, + {0x10, 0x01, 0x30, 0x10, "3" }, + {0x10, 0x01, 0x30, 0x20, "4" }, + {0x10, 0x01, 0x30, 0x30, "5" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x40, 0x40, "Upright" }, + {0x10, 0x01, 0x40, 0x00, "Cocktail" }, + + // Default Values + {0x11, 0xff, 0xff, 0xb1, NULL }, + + {0 , 0xfe, 0 , 16 , "Coinage" }, + {0x11, 0x01, 0x0f, 0x00, "A 3/1 B 3/1" }, + {0x11, 0x01, 0x0f, 0x04, "A 3/1 B 1/2" }, + {0x11, 0x01, 0x0f, 0x0e, "A 3/1 B 1/4" }, + {0x11, 0x01, 0x0f, 0x0f, "A 2/1 B 2/1" }, + {0x11, 0x01, 0x0f, 0x0d, "A 2/1 B 1/1" }, + {0x11, 0x01, 0x0f, 0x07, "A 2/1 B 1/3" }, + {0x11, 0x01, 0x0f, 0x0b, "A 2/1 B 1/5" }, + {0x11, 0x01, 0x0f, 0x0c, "A 2/1 B 1/6" }, + {0x11, 0x01, 0x0f, 0x0d, "A 1/1 B 1/1" }, + {0x11, 0x01, 0x0f, 0x07, "A 1/1 B 4/5" }, + {0x11, 0x01, 0x0f, 0x0b, "A 1/1 B 2/3" }, + {0x11, 0x01, 0x0f, 0x0c, "A 1/1 B 1/3" }, + {0x11, 0x01, 0x0f, 0x08, "A 1/1 B 1/5" }, + {0x11, 0x01, 0x0f, 0x09, "A 1/1 B 1/6" }, + {0x11, 0x01, 0x0f, 0x03, "A 1/2 B 1/2" }, + {0x11, 0x01, 0x0f, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x11, 0x01, 0x40, 0x40, "Off" }, + {0x11, 0x01, 0x40, 0x00, "On" }, +}; + +STDDIPINFO(ponpoko); + +static struct BurnDIPInfo bwcasinoDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x7f, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x80, 0x00, "Upright" }, + {0x0f, 0x01, 0x80, 0x80, "Cocktail" }, + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 16 , "Hands Per Game" }, + {0x10, 0x01, 0x1e, 0x1e, "3" }, + {0x10, 0x01, 0x1e, 0x1c, "4" }, + {0x10, 0x01, 0x1e, 0x1a, "5" }, + {0x10, 0x01, 0x1e, 0x18, "6" }, + {0x10, 0x01, 0x1e, 0x16, "7" }, + {0x10, 0x01, 0x1e, 0x14, "8" }, + {0x10, 0x01, 0x1e, 0x12, "9" }, + {0x10, 0x01, 0x1e, 0x10, "10" }, + {0x10, 0x01, 0x1e, 0x0e, "11" }, + {0x10, 0x01, 0x1e, 0x0c, "12" }, + {0x10, 0x01, 0x1e, 0x0a, "13" }, + {0x10, 0x01, 0x1e, 0x07, "14" }, + {0x10, 0x01, 0x1e, 0x06, "15" }, + {0x10, 0x01, 0x1e, 0x04, "16" }, + {0x10, 0x01, 0x1e, 0x02, "17" }, + {0x10, 0x01, 0x1e, 0x00, "18" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x10, 0x01, 0x20, 0x20, "Off" }, + {0x10, 0x01, 0x20, 0x00, "On" }, + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(bwcasino); + +static struct BurnDIPInfo acityaDIPList[]= +{ + // Default Values + {0x0a, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x0b, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 16 , "Hands Per Game" }, + {0x0b, 0x01, 0x1e, 0x1e, "3" }, + {0x0b, 0x01, 0x1e, 0x1c, "4" }, + {0x0b, 0x01, 0x1e, 0x1a, "5" }, + {0x0b, 0x01, 0x1e, 0x18, "6" }, + {0x0b, 0x01, 0x1e, 0x16, "7" }, + {0x0b, 0x01, 0x1e, 0x14, "8" }, + {0x0b, 0x01, 0x1e, 0x12, "9" }, + {0x0b, 0x01, 0x1e, 0x10, "10" }, + {0x0b, 0x01, 0x1e, 0x0e, "11" }, + {0x0b, 0x01, 0x1e, 0x0c, "12" }, + {0x0b, 0x01, 0x1e, 0x0a, "13" }, + {0x0b, 0x01, 0x1e, 0x07, "14" }, + {0x0b, 0x01, 0x1e, 0x06, "15" }, + {0x0b, 0x01, 0x1e, 0x04, "16" }, + {0x0b, 0x01, 0x1e, 0x02, "17" }, + {0x0b, 0x01, 0x1e, 0x00, "18" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x0b, 0x01, 0x20, 0x20, "Off" }, + {0x0b, 0x01, 0x20, 0x00, "On" }, + + // Default Values + {0x0c, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(acitya); + +static struct BurnDIPInfo eyesDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0xfb, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x10, 0x01, 0x03, 0x01, "2C 1C" }, + {0x10, 0x01, 0x03, 0x03, "1C 1C" }, + {0x10, 0x01, 0x03, 0x02, "1C 2C" }, + {0x10, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x10, 0x01, 0x0c, 0x0c, "2" }, + {0x10, 0x01, 0x0c, 0x08, "3" }, + {0x10, 0x01, 0x0c, 0x04, "4" }, + {0x10, 0x01, 0x0c, 0x00, "5" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x10, 0x01, 0x30, 0x30, "50000" }, + {0x10, 0x01, 0x30, 0x20, "75000" }, + {0x10, 0x01, 0x30, 0x10, "100000" }, + {0x10, 0x01, 0x30, 0x00, "125000" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x40, 0x40, "Upright" }, + {0x10, 0x01, 0x40, 0x00, "Cocktail" }, + + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x12, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(eyes); + + +static struct BurnDIPInfo mrtntDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0xfb, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x10, 0x01, 0x03, 0x01, "2C 1C" }, + {0x10, 0x01, 0x03, 0x03, "1C 1C" }, + {0x10, 0x01, 0x03, 0x02, "1C 2C" }, + {0x10, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x10, 0x01, 0x0c, 0x0c, "2" }, + {0x10, 0x01, 0x0c, 0x08, "3" }, + {0x10, 0x01, 0x0c, 0x04, "4" }, + {0x10, 0x01, 0x0c, 0x00, "5" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x10, 0x01, 0x30, 0x30, "75000" }, + {0x10, 0x01, 0x30, 0x20, "100000" }, + {0x10, 0x01, 0x30, 0x10, "125000" }, + {0x10, 0x01, 0x30, 0x00, "150000" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x40, 0x40, "Upright" }, + {0x10, 0x01, 0x40, 0x00, "Cocktail" }, + + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x12, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(mrtnt); + +static struct BurnDIPInfo alibabaDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Rack Test (Cheat)" }, + {0x0f, 0x01, 0x10, 0x10, "Off" }, + {0x0f, 0x01, 0x10, 0x00, "On" }, + + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x80, 0x80, "Upright" }, + {0x10, 0x01, 0x80, 0x00, "Cocktail" }, + + + // Default Values + {0x11, 0xff, 0xff, 0xdb, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x11, 0x01, 0x03, 0x03, "2C 1C" }, + {0x11, 0x01, 0x03, 0x01, "1C 1C" }, + {0x11, 0x01, 0x03, 0x02, "1C 2C" }, + {0x11, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x11, 0x01, 0x0c, 0x00, "1" }, + {0x11, 0x01, 0x0c, 0x04, "2" }, + {0x11, 0x01, 0x0c, 0x08, "3" }, + {0x11, 0x01, 0x0c, 0x0c, "5" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x11, 0x01, 0x30, 0x00, "10000" }, + {0x11, 0x01, 0x30, 0x10, "15000" }, + {0x11, 0x01, 0x30, 0x20, "20000" }, + {0x11, 0x01, 0x30, 0x30, "None" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x11, 0x01, 0x40, 0x40, "Normal" }, + {0x11, 0x01, 0x40, 0x00, "Hard" }, +}; + +STDDIPINFO(alibaba); + +static struct BurnDIPInfo theglobpDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x80, 0x80, "Upright" }, + {0x0f, 0x01, 0x80, 0x00, "Cocktail" }, + + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x10, 0x01, 0x03, 0x03, "3" }, + {0x10, 0x01, 0x03, 0x02, "4" }, + {0x10, 0x01, 0x03, 0x01, "5" }, + {0x10, 0x01, 0x03, 0x00, "6" }, + + {0 , 0xfe, 0 , 8 , "Difficulty" }, + {0x10, 0x01, 0x1c, 0x1c, "Easiest" }, + {0x10, 0x01, 0x1c, 0x18, "Very Easy" }, + {0x10, 0x01, 0x1c, 0x14, "Easy" }, + {0x10, 0x01, 0x1c, 0x10, "Normal" }, + {0x10, 0x01, 0x1c, 0x0c, "Difficult" }, + {0x10, 0x01, 0x1c, 0x08, "Very Difficult" }, + {0x10, 0x01, 0x1c, 0x04, "Very Hard" }, + {0x10, 0x01, 0x1c, 0x00, "Hardest" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x10, 0x01, 0x20, 0x20, "Off" }, + {0x10, 0x01, 0x20, 0x00, "On" }, + + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(theglobp); + +static struct BurnDIPInfo woodpekDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Rack Test (Cheat)" }, + {0x10, 0x01, 0x10, 0x10, "Off" }, + {0x10, 0x01, 0x10, 0x00, "On" }, + + + // Default Values + {0x11, 0xff, 0xff, 0xc1, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x11, 0x01, 0x03, 0x03, "2C 1C" }, + {0x11, 0x01, 0x03, 0x01, "1C 1C" }, + {0x11, 0x01, 0x03, 0x02, "1C 2C" }, + {0x11, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x11, 0x01, 0x0c, 0x00, "3" }, + {0x11, 0x01, 0x0c, 0x04, "4" }, + {0x11, 0x01, 0x0c, 0x08, "5" }, + {0x11, 0x01, 0x0c, 0x0c, "6" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x11, 0x01, 0x30, 0x00, "5000" }, + {0x11, 0x01, 0x30, 0x10, "10000" }, + {0x11, 0x01, 0x30, 0x20, "15000" }, + {0x11, 0x01, 0x30, 0x30, "None" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x11, 0x01, 0x40, 0x40, "Upright" }, + {0x11, 0x01, 0x40, 0x00, "Cocktail" }, + + + // Default Values + {0x12, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(woodpek); + +static struct BurnDIPInfo lizwizDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x0e, 0xff, 0xff, 0xc9, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0e, 0x01, 0x03, 0x03, "2C 1C" }, + {0x0e, 0x01, 0x03, 0x01, "1C 1C" }, + {0x0e, 0x01, 0x03, 0x02, "1C 2C" }, + {0x0e, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0e, 0x01, 0x0c, 0x00, "5" }, + {0x0e, 0x01, 0x0c, 0x04, "4" }, + {0x0e, 0x01, 0x0c, 0x08, "3" }, + {0x0e, 0x01, 0x0c, 0x0c, "2" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x0e, 0x01, 0x30, 0x00, "75000" }, + {0x0e, 0x01, 0x30, 0x10, "100000" }, + {0x0e, 0x01, 0x30, 0x20, "125000" }, + {0x0e, 0x01, 0x30, 0x30, "150000" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0e, 0x01, 0x40, 0x40, "Normal" }, + {0x0e, 0x01, 0x40, 0x00, "Hard" }, +}; + +STDDIPINFO(lizwiz); + +static struct BurnDIPInfo vanvanDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xda, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x01, 0x00, "Upright" }, + {0x0f, 0x01, 0x01, 0x01, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Flip screen" }, + {0x0f, 0x01, 0x02, 0x02, "Off" }, + {0x0f, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x0f, 0x01, 0x0c, 0x08, "20k and 100k" }, + {0x0f, 0x01, 0x0c, 0x04, "40k and 140k" }, + {0x0f, 0x01, 0x0c, 0x00, "70k and 200k" }, + {0x0f, 0x01, 0x0c, 0x0c, "None" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0f, 0x01, 0x30, 0x30, "1" }, + {0x0f, 0x01, 0x30, 0x20, "2" }, + {0x0f, 0x01, 0x30, 0x10, "3" }, + {0x0f, 0x01, 0x30, 0x00, "5" }, + + {0 , 0xfe, 0 , 2 , "Coinage" }, + {0x0f, 0x01, 0xc0, 0x00, "2c_1c" }, + {0x0f, 0x01, 0xc0, 0xc0, "1C_1C" }, + {0x0f, 0x01, 0xc0, 0x80, "1c_2C" }, + {0x0f, 0x01, 0xc0, 0x40, "1C_3C" }, + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(vanvan); + +static struct BurnDIPInfo nmouseDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Rack Test (Cheat)" }, + {0x0f, 0x01, 0x10, 0x10, "Off" }, + {0x0f, 0x01, 0x10, 0x00, "On" }, + + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x80, 0x80, "Upright" }, + {0x10, 0x01, 0x80, 0x00, "Cocktail" }, + + + // Default Values + {0x0e, 0xff, 0xff, 0xc9, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0e, 0x01, 0x03, 0x03, "2C 1C" }, + {0x0e, 0x01, 0x03, 0x01, "1C 1C" }, + {0x0e, 0x01, 0x03, 0x02, "1C 2C" }, + {0x0e, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0e, 0x01, 0x0c, 0x00, "1" }, + {0x0e, 0x01, 0x0c, 0x04, "2" }, + {0x0e, 0x01, 0x0c, 0x08, "3" }, + {0x0e, 0x01, 0x0c, 0x0c, "5" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x0e, 0x01, 0x30, 0x00, "5000" }, + {0x0e, 0x01, 0x30, 0x10, "10000" }, + {0x0e, 0x01, 0x30, 0x20, "15000" }, + {0x0e, 0x01, 0x30, 0x30, "None" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x0e, 0x01, 0x40, 0x40, "Normal" }, + {0x0e, 0x01, 0x40, 0x00, "Hard" }, +}; + +STDDIPINFO(nmouse); + +static struct BurnDIPInfo jumpshotDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0xf1, NULL }, + + {0 , 0xfe, 0 , 3 , "Time" }, + {0x10, 0x01, 0x03, 0x02, "2 Minutes" }, + {0x10, 0x01, 0x03, 0x03, "3 Minutes" }, + {0x10, 0x01, 0x03, 0x01, "4 Minutes" }, + + {0 , 0xfe, 0 , 4 , "Player Skin Tone" }, + {0x10, 0x01, 0x04, 0x04, "Lighter" }, + {0x10, 0x01, 0x04, 0x00, "Darker" }, + + {0 , 0xfe, 0 , 4 , "Player Skin Tone" }, + {0x10, 0x01, 0x08, 0x08, "Lighter" }, + {0x10, 0x01, 0x08, 0x00, "Darker" }, + + {0 , 0xfe, 0 , 2 , "Free play" }, + {0x10, 0x01, 0x10, 0x10, "Off" }, + {0x10, 0x01, 0x10, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "2 Players Game" }, + {0x10, 0x01, 0x20, 0x20, "1 Credit" }, + {0x10, 0x01, 0x20, 0x00, "2 Credits" }, + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x12, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(jumpshot); + +static struct BurnDIPInfo jumpshtpDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0xf1, NULL }, + + {0 , 0xfe, 0 , 3 , "Time" }, + {0x10, 0x01, 0x03, 0x02, "Short" }, + {0x10, 0x01, 0x03, 0x03, "Average" }, + {0x10, 0x01, 0x03, 0x01, "Above Average" }, + + {0 , 0xfe, 0 , 4 , "Player Skin Tone" }, + {0x10, 0x01, 0x04, 0x04, "Lighter" }, + {0x10, 0x01, 0x04, 0x00, "Darker" }, + + {0 , 0xfe, 0 , 4 , "Player Skin Tone" }, + {0x10, 0x01, 0x08, 0x08, "Lighter" }, + {0x10, 0x01, 0x08, 0x00, "Darker" }, + + {0 , 0xfe, 0 , 2 , "Free play" }, + {0x10, 0x01, 0x10, 0x10, "Off" }, + {0x10, 0x01, 0x10, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "2 Players Game" }, + {0x10, 0x01, 0x20, 0x20, "1 Credit" }, + {0x10, 0x01, 0x20, 0x00, "2 Credits" }, + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x12, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(jumpshtp); + +static struct BurnDIPInfo dremshprDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, + + {0x12, 0xff, 0xff, 0xfe, NULL }, + + // Default Values + {0x0f, 0xff, 0xff, 0xfb, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x01, 0x01, "Upright" }, + {0x0f, 0x01, 0x01, 0x00, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0f, 0x01, 0x20, 0x20, "Off" }, + {0x0f, 0x01, 0x20, 0x00, "On" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x0f, 0x01, 0x0c, 0x08, "30000" }, + {0x0f, 0x01, 0x0c, 0x04, "50000" }, + {0x0f, 0x01, 0x0c, 0x00, "70000" }, + {0x0f, 0x01, 0x0c, 0x0c, "none" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0f, 0x01, 0x30, 0x30, "3" }, + {0x0f, 0x01, 0x30, 0x20, "4" }, + {0x0f, 0x01, 0x30, 0x10, "5" }, + {0x0f, 0x01, 0x30, 0x00, "6" }, + + {0 , 0xfe, 0, 4, "Coinage" }, + {0x0f, 0x01, 0xc0, 0x00, "2C 1C" }, + {0x0f, 0x01, 0xc0, 0xc0, "1C 1C" }, + {0x0f, 0x01, 0xc0, 0x80, "1C 2C" }, + {0x0f, 0x01, 0xc0, 0x40, "1C 3C" }, +}; + +STDDIPINFO(dremshpr); + +static struct BurnDIPInfo cannonbpDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 4 , "Display" }, + {0x0f, 0x01, 0x03, 0x03, "Scores and Progression Bars" }, + {0x0f, 0x01, 0x03, 0x01, "Scores only" }, + {0x0f, 0x01, 0x03, 0x02, "Progression Bars only" }, + {0x0f, 0x01, 0x03, 0x00, "None" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x04, 0x04, "Upright" }, + {0x0f, 0x01, 0x04, 0x00, "Cocktail" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0f, 0x01, 0x18, 0x00, "3" }, + {0x0f, 0x01, 0x18, 0x08, "4" }, + {0x0f, 0x01, 0x18, 0x10, "5" }, + {0x0f, 0x01, 0x18, 0x18, "6" }, +}; + +STDDIPINFO(cannonbp); + +static struct BurnDIPInfo rocktrv2DIPList[]= +{ + // Default Values + {0x0e, 0xff, 0x3f, 0x33, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0e, 0x01, 0x03, 0x03, "2C 1C" }, + {0x0e, 0x01, 0x03, 0x01, "1C 1C" }, + {0x0e, 0x01, 0x03, 0x02, "1C 2C" }, + {0x0e, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 8 , "Questions Per Game" }, + {0x0e, 0x01, 0x1c, 0x1c, "2" }, + {0x0e, 0x01, 0x1c, 0x18, "3" }, + {0x0e, 0x01, 0x1c, 0x14, "4" }, + {0x0e, 0x01, 0x1c, 0x10, "5" }, + {0x0e, 0x01, 0x1c, 0x0c, "6" }, + {0x0e, 0x01, 0x1c, 0x08, "7" }, + {0x0e, 0x01, 0x1c, 0x04, "8" }, + {0x0e, 0x01, 0x1c, 0x00, "9" }, + + {0 , 0xfe, 0 , 4 , "Clock Speed" }, + {0x0e, 0x01, 0x60, 0x60, "Beginner" }, + {0x0e, 0x01, 0x60, 0x40, "Intermediate" }, + {0x0e, 0x01, 0x60, 0x20, "Professional" }, + {0x0e, 0x01, 0x60, 0x00, "Super - Pro" }, + + {0 , 0xfe, 0 , 2 , "Freeze Image" }, + {0x0e, 0x01, 0x80, 0x80, "Off" }, + {0x0e, 0x01, 0x80, 0x00, "On" }, + + + // Default Values + {0x0f, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Mode" }, + {0x0f, 0x01, 0x01, 0x01, "Amusement" }, + {0x0f, 0x01, 0x01, 0x00, "Credit" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x02, 0x02, "Upright" }, + {0x0f, 0x01, 0x02, 0x00, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "K.O. Switch" }, + {0x0f, 0x01, 0x04, 0x04, "Auto" }, + {0x0f, 0x01, 0x04, 0x00, "Manual" }, + + {0 , 0xfe, 0 , 8 , "Bonus Life" }, + {0x0f, 0x01, 0x70, 0x70, "10000" }, + {0x0f, 0x01, 0x70, 0x60, "17500" }, + {0x0f, 0x01, 0x70, 0x50, "25000" }, + {0x0f, 0x01, 0x70, 0x40, "32500" }, + {0x0f, 0x01, 0x70, 0x30, "40000" }, + {0x0f, 0x01, 0x70, 0x20, "47500" }, + {0x0f, 0x01, 0x70, 0x10, "55000" }, + {0x0f, 0x01, 0x70, 0x00, "62500" }, + + {0 , 0xfe, 0 , 2 , "Music" }, + {0x0f, 0x01, 0x80, 0x80, "On" }, + {0x0f, 0x01, 0x80, 0x00, "Off" }, + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(rocktrv2); + +static struct BurnDIPInfo bigbucksDIPList[]= +{ + // Default Values + {0x0c, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Enable Adult Affairs Category" }, + {0x0c, 0x01, 0x10, 0x00, "Off" }, + {0x0c, 0x01, 0x10, 0x10, "On" }, + + + // Default Values + {0x0d, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Time to bet / answer" }, + {0x0d, 0x01, 0x01, 0x00, "15 sec. / 10 sec." }, + {0x0d, 0x01, 0x01, 0x01, "20 sec. / 15 sec." }, + + {0 , 0xfe, 0 , 2 , "Continue if player busts"}, + {0x0d, 0x01, 0x02, 0x00, "Off" }, + {0x0d, 0x01, 0x02, 0x02, "On" }, + + {0 , 0xfe, 0 , 2 , "Show correct answer" }, + {0x0d, 0x01, 0x04, 0x00, "Off" }, + {0x0d, 0x01, 0x04, 0x04, "On" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x0d, 0x01, 0x08, 0x00, "Off" }, + {0x0d, 0x01, 0x08, 0x08, "On" }, + + {0 , 0xfe, 0 , 2 , "Coinage" }, + {0x0d, 0x01, 0x10, 0x00, "2C 1C" }, + {0x0d, 0x01, 0x10, 0x10, "1C 1C" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0d, 0x01, 0x20, 0x20, "Upright" }, + {0x0d, 0x01, 0x20, 0x00, "Cocktail" }, + + // Default Values + {0x0e, 0xff, 0xff, 0xff, NULL }, +}; + +STDDIPINFO(bigbucks); + +static struct BurnDIPInfo korosukeDIPList[]= +{ + // Default Values + {0x10, 0xff, 0xff, 0xef, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x10, 0x01, 0x10, 0x00, "Upright" }, + {0x10, 0x01, 0x10, 0x10, "Cocktail" }, + + + // Default Values + {0x11, 0xff, 0x6f, 0x6f, NULL }, + + + // Default Values + {0x0f, 0xff, 0x3f, 0x31, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0f, 0x01, 0x03, 0x03, "2C 1C" }, + {0x0f, 0x01, 0x03, 0x01, "1C 1C" }, + {0x0f, 0x01, 0x03, 0x02, "1C 2C" }, + {0x0f, 0x01, 0x03, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0f, 0x01, 0x0c, 0x00, "3" }, + {0x0f, 0x01, 0x0c, 0x04, "4" }, + {0x0f, 0x01, 0x0c, 0x08, "5" }, + {0x0f, 0x01, 0x0c, 0x0c, "6" }, + + {0 , 0xfe, 0 , 2 , "First Pattern" }, + {0x0f, 0x01, 0x30, 0x10, "Easy" }, + {0x0f, 0x01, 0x30, 0x00, "Hard" }, + + {0 , 0xfe, 0 , 2 , "Teleport Holes" }, + {0x0f, 0x01, 0x20, 0x20, "Off" }, + {0x0f, 0x01, 0x20, 0x00, "On" }, +}; + +STDDIPINFO(korosuke); + +static struct BurnDIPInfo shootbulDIPList[]= +{ + // Default Values + {0x09, 0xff, 0xff, 0xff, NULL }, + + // Default Values + {0x0A, 0xff, 0xff, 0xff, NULL }, + + + // Default Values + {0x08, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 5 , "Time" }, + {0x08, 0x01, 0x03, 0x01, "Short" }, + {0x08, 0x01, 0x03, 0x07, "Average" }, + {0x08, 0x01, 0x03, 0x03, "Long" }, + {0x08, 0x01, 0x03, 0x05, "Longer" }, + {0x08, 0x01, 0x03, 0x06, "Longest" }, + + {0 , 0xfe, 0 , 2 , "Title Page Sounds" }, + {0x08, 0x01, 0x08, 0x00, "Off" }, + {0x08, 0x01, 0x08, 0x08, "On" }, +}; + +STDDIPINFO(shootbul); + + +//------------------------------------------------------------------------------------------------------ +// Read / Write / Port handlers + + +static void mschamp_set_bank(); +static void mspacman_set_bank(int nBank); +static void epos_hardware_set_bank(int nBank); +static unsigned char cannonbp_protection_r(unsigned short offset); +static unsigned char maketrax_special_port2_r(unsigned short offset); +static unsigned char maketrax_special_port3_r(unsigned short offset); +static unsigned char korosuke_special_port2_r(unsigned short offset); +static unsigned char korosuke_special_port3_r(unsigned short offset); +static unsigned char epos_hardware_decrypt_rom(unsigned short offset); + + +unsigned char __fastcall pacman_read_byte(unsigned short a) +{ + unsigned char ret = 0xff; + + if (alibaba) { + if (a >= 0x50c2 && a <= 0x50ff) { + return 0xff; + } + + if (a == 0x50c0) return rand() & 0xff; + + if (a == 0x50c1) { + alibaba_mystery++; + return (alibaba_mystery >> 10) & 1; + } + } + + if (bigbucks) { + if ((a & 0xf000) == 0x5000) { + a &= 0xffc0; + } + } + + if (cannonbp) { + if (a >= 0x3000 && a <= 0x3fff) { + return cannonbp_protection_r(a & 0xfff); + } + } + + if (korosuke) { + if (a >= 0x5080 && a <= 0x50bf) { + return korosuke_special_port2_r(a & 0x3f); + } + if (a >= 0x50c0 && a <= 0x50ff) { + return korosuke_special_port3_r(a & 0x3f); + } + } + + if (maketrax) { + if (a >= 0x5080 && a <= 0x50bf) { + return maketrax_special_port2_r(a & 0x3f); + } + + if (a >= 0x50c0 && a <= 0x50ff) { + return maketrax_special_port3_r(a & 0x3f); + } + } + + if (crushs && a == 0x5080) a = 0x5040; + + if (rocktrv2) + { + if ((a & 0xfff0) == 0x5fe0) + return (rocktrv2_prot_data[(a >> 2) & 3] >> 4); + + if (a >= 0x5040 && a <= 0x507f) a = 0x5040; + + if (a == 0x5fff) + return DrvDips[3]; + + if (a >= 0x8000) { + return QRom[(a & 0x7fff) | (nPacBank * 0x8000)]; + } + } + + switch (a) + { + case 0x5000: // input port 0 + { + ret = DrvDips[0]; + + for (int i = 0; i < 8; i++) + ret ^= DrvJoy1[i] << i; + + // Force input to act as 8-way + if (!acitya) { + if ((ret & 6) == 0) ret |= 0x06; + if ((ret & 9) == 0) ret |= 0x09; + } + + if (shootbul) ret ^= nCharAxis[0]; + return ret; + } + + case 0x5040: // input port 1 + { + ret = DrvDips[1]; + + for (int i = 0; i < 8; i++) + ret ^= DrvJoy2[i] << i; + + // Force input to act as 8-way + if (!acitya) { + if ((ret & 6) == 0) ret |= 0x06; + if ((ret & 9) == 0) ret |= 0x09; + } + + if (shootbul) ret ^= nCharAxis[1]; + + return ret; + } + break; + + case 0x5080: // input port 2 + return DrvDips[2]; + + case 0x50c0: // input port 3 + return DrvDips[3]; + } + + if (a >= 0x4800 && a <= 0x4bff) return 0xff; + + return 0; +} + +void __fastcall pacman_write_byte(unsigned short a, unsigned char data) +{ + if (alibaba) + { + if (a == 0x5000) return; + if (a == 0x50c2) { + ZetSetIRQLine(0, ZET_IRQSTATUS_NONE); + interrupt_enable = data; + return; + } + } + + if (bigbucks) + { + if (a == 0x6000) { + nPacBank = data; + return; + } + } + + if (mspacman) + { + if (a == 0x5006) + { + mspacman_set_bank(data); + return; + } + } + + if (rocktrv2) + { + if ((a & 0xfffc) == 0x5fe0) { + rocktrv2_prot_data[a & 3] = data; + return; + } + + if (a == 0x5ff0) { + nPacBank = data; + return; + } + } + + if (vanvan && a == 0x5001) { + for (int i = 0; i < 256; i++) { + if (Prom[0x100 + i] == 0) { + Palette[i] = (data & 1) ? 0xaaaaaa : 0; // gray / black + } + } + return; + } + + // sprite 2 & sound regs + if (a >= 0x5050 && a <= 0x506f) { + Rom[a] = data; + return; + } + + switch (a) + { + case 0x5000: + ZetSetIRQLine(0, ZET_IRQSTATUS_NONE); + interrupt_enable = data; + break; + + case 0x5001: + // pacman_sound_enable_w + break; + + case 0x5003: + flipscreen = (data & 1) ^ screen_flip; + break; + + case 0x5002:// nop + case 0x5007:// coin counter + case 0x50c0:// watchdog_reset_w + break; + } +} + + +unsigned char __fastcall pacman_in_port(unsigned short a) +{ + if (bigbucks) { + return QRom[(nPacBank << 16) | (a ^ 0xffff)]; + } + + a &= 0xff; + + if (crushs) { + if (a == 1) return DrvDips[3]; + if (a == 2) return DrvDips[2]; + } + + if (epos_hardware) { + return epos_hardware_decrypt_rom(a); + } + + if (mschamp && a == 0) { + return mschamp_counter++; + } + + return 0; +} + +void __fastcall pacman_out_port(unsigned short a, unsigned char data) +{ + a &= 0xff; + + if (crushs) { + if (a == 1 || a == 0) { + AY8910Write(0, ~a & 1, data); + } + return; + } + + if (dremshpr) { + if (a == 7 || a == 6) { + AY8910Write(0, ~a & 1, data); + } + return; + } + + if (rocktrv2 || alibaba || mschamp) return; + + switch (a) + { + case 0x00: + { + if (piranha) { + if (data == 0xfa) data = 0x78; + if (data == 0xfc) data = 0xfc; + } + + if (nmouse) { + if (data == 0xbf) data = 0x3c; + if (data == 0xc6) data = 0x40; + if (data == 0xfc) data = 0xfc; + } + + interrupt_mode = data; + } + break; + } +} + + +//------------------------------------------------------------------------------------------------------ +// Initilization functions + + +static int DrvDoReset() +{ + DrvReset = 0; + + interrupt_mode = 0, interrupt_enable = 0; + colortablebank = 0, palettebank = 0; + spritebank = 0, charbank = 0; + + memset (Mem + 0x4000, 0, 0x4000); + + if (epos_hardware) { + epos_hardware_counter = 0x0A + acitya; + epos_hardware_set_bank(epos_hardware_counter); + } + + if (mspacman) { + mspacman_set_bank(0); + } + + if (mschamp) { + mschamp_set_bank(); + } + + if (alibaba) { + memset (Mem + 0x9000, 0, 0x400); + } + + memset (rocktrv2_prot_data, 0, 4); + mschamp_counter = 0; + cannonb_bit_to_read = 0; + alibaba_mystery = 0; + + if (crushs || dremshpr) { + AY8910Reset(0); + } + + ZetOpen(0); + ZetReset(); + ZetClose(); + + return 0; +} + + +static void pacman_palette_init() +{ +#define combine_3_weights(tab,w0,w1,w2) \ + ((int)(((tab)[0]*(w0) + (tab)[1]*(w1) + (tab)[2]*(w2)) + 0.5)) + +#define combine_2_weights(tab,w0,w1) \ + ((int)(((tab)[0]*(w0) + (tab)[1]*(w1)) + 0.5)) + + unsigned int t_pal[32]; + unsigned char *color_prom = Prom; + unsigned char rgweights[3] = {33, 71, 151}; + unsigned char bweights[2] = {81, 174}; + + // create a lookup table for the palette + for (int i = 0; i < 32; i++) + { + int bit0, bit1, bit2; + int r, g, b; + + // red component + bit0 = (color_prom[i] >> 0) & 0x01; + bit1 = (color_prom[i] >> 1) & 0x01; + bit2 = (color_prom[i] >> 2) & 0x01; + r = combine_3_weights(rgweights, bit0, bit1, bit2); + + // green component + bit0 = (color_prom[i] >> 3) & 0x01; + bit1 = (color_prom[i] >> 4) & 0x01; + bit2 = (color_prom[i] >> 5) & 0x01; + g = combine_3_weights(rgweights, bit0, bit1, bit2); + + // blue component + bit0 = (color_prom[i] >> 6) & 0x01; + bit1 = (color_prom[i] >> 7) & 0x01; + b = combine_2_weights(bweights, bit0, bit1); + + t_pal[i] = (r << 16) | (g << 8) | b; + } + + color_prom += 256; // point to the beginning of the lookup table + + for (int i = 0; i < 256; i++) + { + unsigned char ctabentry = color_prom[i] & 0x0f; + + Palette[0x000 | i] = t_pal[ctabentry | 0x00]; + Palette[0x100 | i] = t_pal[ctabentry | 0x10]; + } +} + + +static void convert_gfx() +{ + static int PlaneOffsets[2] = { 0, 4 }; + static int XOffsets[16] = { 312, 304, 296, 288, 280, 272, 264, 256, 56, 48, 40, 32, 24, 16, 8, 0 }; + static int SpriYOffsets[16] = { 64, 65, 66, 67, 128, 129, 130, 131, 192, 193, 194, 195, 0, 1, 2, 3 }; + static int CharYOffsets[8] = { 64, 65, 66, 67, 0, 1, 2, 3 }; + + unsigned char *tmp = (unsigned char*)malloc( 0x2000 ); + if (tmp) + { + memcpy (tmp, Gfx, 0x2000); + + GfxDecode(0x100, 2, 8, 8, PlaneOffsets, XOffsets + 8, CharYOffsets, 0x080, tmp + 0x0000, Gfx + 0x0000); + GfxDecode(0x040, 2, 16, 16, PlaneOffsets, XOffsets + 0, SpriYOffsets, 0x200, tmp + 0x1000, Gfx + 0x4000); + + free (tmp); + } +} + +static int pacman_load() +{ + char* pRomName; + struct BurnRomInfo ri; + + int pOffset = 0; + unsigned char *gLoad = Gfx; + unsigned char *cLoad = Prom; + + for (int i = 0; !BurnDrvGetRomName(&pRomName, i, 0); i++) { + + BurnDrvGetRomInfo(&ri, i); + + if ((ri.nType & 7) == 1) { + if (BurnLoadRom(Rom + pOffset, i, 1)) return 1; + pOffset += ri.nLen; + + if (pOffset == 0x4000) { + pOffset = 0x8000; + } + + continue; + } + + if ((ri.nType & 7) == 2) { + if (BurnLoadRom(gLoad, i, 1)) return 1; + gLoad += ri.nLen; + + continue; + } + + if ((ri.nType & 7) == 3) { + if (BurnLoadRom(cLoad, i, 1)) return 1; + cLoad += 0x100; + + continue; + } + } + + return 0; +} + +static int DrvInit() +{ + Mem = (unsigned char*)malloc( 0x10000 + 0x20000 + 0x10000 ); + if (Mem == NULL) { + return 1; + } + + memset (Mem, 0, 0x40000); + + Rom = Mem + 0x10000; + Gfx = Mem + 0x30000; + Prom = Mem + 0x38000; + Palette = (int*)(Mem + 0x38200); + + if (pacman_load()) return 1; + + if (pPacInitCallback) { + pPacInitCallback(); + } + + convert_gfx(); + pacman_palette_init(); + + ZetInit(1); + ZetOpen(0); + ZetSetInHandler(pacman_in_port); + ZetSetOutHandler(pacman_out_port); + ZetSetReadHandler(pacman_read_byte); + ZetSetWriteHandler(pacman_write_byte); + + ZetMapArea(0x0000, 0x2fff, 0, Rom + 0x0000); + ZetMapArea(0x0000, 0x2fff, 2, Rom + 0x0000); + + if (!cannonbp) { + ZetMapArea(0x2000, 0x3fff, 0, Rom + 0x2000); + ZetMapArea(0x2000, 0x3fff, 2, Rom + 0x2000); + } + + ZetMapArea(0x4000, 0x43ff, 0, Rom + 0x4000); + ZetMapArea(0x4000, 0x43ff, 1, Rom + 0x4000); + ZetMapArea(0x4000, 0x43ff, 2, Rom + 0x4000); + + ZetMapArea(0x4400, 0x47ff, 0, Rom + 0x4400); + ZetMapArea(0x4400, 0x47ff, 1, Rom + 0x4400); + ZetMapArea(0x4400, 0x47ff, 2, Rom + 0x4400); + + // Mirror to fix "high score" in pacman + ZetMapArea(0xc000, 0xc7ff, 0, Rom + 0x4000); + ZetMapArea(0xc000, 0xc7ff, 1, Rom + 0x4000); + ZetMapArea(0xc000, 0xc7ff, 2, Rom + 0x4000); + + if (cannonbp || dremshpr || vanvan) { + ZetMapArea(0x4800, 0x4bff, 0, Rom + 0x4800); + ZetMapArea(0x4800, 0x4bff, 1, Rom + 0x4800); + ZetMapArea(0x4800, 0x4bff, 2, Rom + 0x4800); + } + + ZetMapArea(0x4c00, 0x4fff, 0, Rom + 0x4c00); + ZetMapArea(0x4c00, 0x4fff, 1, Rom + 0x4c00); + ZetMapArea(0x4c00, 0x4fff, 2, Rom + 0x4c00); + + if (rocktrv2) { + ZetMapArea(0x6000, 0x7fff, 0, Rom + 0x8000); + ZetMapArea(0x6000, 0x7fff, 2, Rom + 0x8000); + } else { + ZetMapArea(0x8000, 0xbfff, 0, Rom + 0x8000); + ZetMapArea(0x8000, 0xbfff, 2, Rom + 0x8000); + if (alibaba) ZetMapArea(0x9000, 0x93ff, 1, Rom + 0x9000); + } + + ZetMemEnd(); + ZetClose(); + + if (dremshpr || crushs) { + pFMBuffer = (short *)malloc (nBurnSoundLen * 3 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + AY8910Init(0, 1789750, nBurnSoundRate, NULL, NULL, NULL, NULL); + } + + DrvDoReset(); + + return 0; +} + + +static int DrvExit() +{ + ZetExit(); + + flipscreen = 0; + screen_flip = 0; + + pPacInitCallback = NULL; + + mspacman = cannonbp = maketrax = 0; + piranha = dremshpr = vanvan = 0; + nmouse = acitya = mschamp = 0; + bigbucks = rocktrv2 = korosuke = 0; + alibaba = crushs = 0; + shootbul = 0; + + epos_hardware = 0; + + nPacBank = -1; + + if (QRom) { + free (QRom); + } + + free (Mem); + + if (pFMBuffer) { + AY8910Exit(0); + + free (pFMBuffer); + } + + nAnalogAxis[0] = nAnalogAxis[1] = 0; + + pFMBuffer = NULL; + + pAY8910Buffer[0] = pAY8910Buffer[1] = pAY8910Buffer[2] = NULL; + + Mem = Rom = Gfx = Snd = QRom = NULL; + + return 0; +} + + +//------------------------------------------------------------------------------------------------------ +// Drawing routines + + +static inline void pac_putpix(int x, int y, int color, unsigned char src, int transp) +{ + int pos, pxl; + + if (x > 223 || x < 0 || y > 287 || y < 0) return; + + pxl = Palette[color | src]; + if (pxl == Palette[0] && transp) return; + + if (flipscreen) + pos = ((287 - y) * 224) + (223 - x); + else + pos = ((y * 224) + x); + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); +} + +static void DrawBackground(int priority) +{ + unsigned char *videoram = Rom + 0x4000; + unsigned char *colorram = Rom + 0x4400; + + for (int offs = 0x400 - 1; offs >= 0; offs-=1) + { + int num = (charbank << 8) | videoram[offs]; + int color = ((colorram[offs] & 0x1f) | (colortablebank << 5) | (palettebank << 6 )) << 2; + + unsigned char *src = Gfx + (num << 6); + + int sy = ((offs & 0x1f) + 2) << 3; + int sx = ((offs >> 5) << 3) ^ 0xf8; + + if (sx >= 0xf0 || sx <= 0x0f) { + int t = sx; + sx = (sy - 0x10) ^ 0xf8; + sy = (t ^ 8) + (t & 0x20); + } + + sx -= 0x10; + + for (int y = sy; y < sy + 8; y++) + { + for (int x = sx; x < sx + 8; x++, src++) { + pac_putpix(x, y, color, *src, 0); + } + } + } +} + +static void DrawSprites() +{ + unsigned char *spriteram = Rom + (0x4ff0 - (alibaba * 0x100)); + unsigned char *spriteram_2 = Rom + (0x5060 - (alibaba * 0x010)); + + // draw sprites + for (int offs = 0x10 - 2;offs >= 0;offs -= 2) + { + int color, sx, sy, flipx, flipy, num; + + num = ((spriteram[offs] >> 2 ) | (spritebank << 6)) << 8; + color = ((spriteram[offs + 1] & 0x1f ) | (colortablebank << 5) | (palettebank << 6 )) << 2; + + sy = (spriteram_2[offs + 1] ^ 0xff) + 0x11; + sx = (spriteram_2[offs] ^ 0xff) - 0x10; + flipy = spriteram[offs] & 1; + flipx = spriteram[offs] & 2; + + unsigned char *src = Gfx + 0x4000 + num; + + if (flipy) { + for (int y = sy + 15; y >= sy; y--) + { + if (flipx) { + for (int x = sx + 15; x >= sx; x--, src++) { + pac_putpix(x, y, color, *src, 1); + } + } else { + for (int x = sx; x < sx + 16; x++, src++) { + pac_putpix(x, y, color, *src, 1); + } + } + } + } else { + for (int y = sy; y < sy + 16; y++) + { + if (flipx) { + for (int x = sx + 15; x >= sx; x--, src++) { + pac_putpix(x, y, color, *src, 1); + } + } else { + for (int x = sx; x < sx + 16; x++, src++) { + pac_putpix(x, y, color, *src, 1); + } + } + } + } + } +} + + +static int DrvDraw() +{ + if (bgpriority) { + for (int i = 0; i < 288 * 224; i++) { + PutPix(pBurnDraw + i * nBurnBpp, BurnHighCol(Palette[0] >> 16, Palette[0] >> 8, Palette[0], 0)); + } + } else { + DrawBackground(0); + } + + DrawSprites(); + + if (bgpriority) { + DrawBackground(1); + } + return 0; +} + +static int DrvFrame() +{ + ZetNewFrame(); + + if (DrvReset) { + DrvDoReset(); + } + + // Handle analog controls + if (shootbul) + { + nAnalogAxis[0] -= DrvAxis[0]; + nAnalogAxis[1] -= DrvAxis[1]; + nCharAxis[0] = (nAnalogAxis[0] >> 12) & 0x0F; + nCharAxis[1] = (nAnalogAxis[1] >> 12) & 0x0F; + } + + ZetOpen(0); + + if (bigbucks) + { + for (int i = 0; i < 20; i++) { + ZetRun((3072000 / 60) / 20); + if (interrupt_enable) ZetRaiseIrq(0); + } + } + else + { + // two interrupts per frame for speedup cheat + ZetRun(3072000 / 60); + + if (dremshpr || vanvan) { + ZetNmi(); + } else { + if (interrupt_enable) ZetRaiseIrq(interrupt_mode); + } + } + + + ZetClose(); + + if (pBurnSoundOut && (dremshpr || crushs)) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +//------------------------------------------------------------------------------------------------------ +// Save states + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + ba.Data = Rom + 0x4000; + ba.nLen = 0x1000; + ba.szName = "Main Ram"; + BurnAcb(&ba); + + if (alibaba) { + memset(&ba, 0, sizeof(ba)); + ba.Data = Rom + 0x9000; + ba.nLen = 0x0400; + ba.szName = "Alibaba Extra Ram"; + BurnAcb(&ba); + } + + if (vanvan) { + memset(&ba, 0, sizeof(ba)); + ba.Data = (unsigned char*)Palette; + ba.nLen = 0x200 * sizeof(int); + ba.szName = "Palette"; + BurnAcb(&ba); + } + + ZetScan(nAction); + + SCAN_VAR(flipscreen); + SCAN_VAR(nPacBank); + SCAN_VAR(interrupt_mode); + SCAN_VAR(interrupt_enable); + SCAN_VAR(colortablebank); + SCAN_VAR(palettebank); + SCAN_VAR(spritebank); + SCAN_VAR(charbank); + + SCAN_VAR(alibaba_mystery); + SCAN_VAR(epos_hardware_counter); + SCAN_VAR(mschamp_counter); + SCAN_VAR(cannonb_bit_to_read); + SCAN_VAR(rocktrv2_prot_data[0]); + SCAN_VAR(rocktrv2_prot_data[1]); + SCAN_VAR(rocktrv2_prot_data[2]); + SCAN_VAR(rocktrv2_prot_data[3]); + + // Set banks for various games + if (mschamp) { + mschamp_set_bank(); + } + + if (mspacman) { + mspacman_set_bank(nPacBank); + } + + if (epos_hardware) { + epos_hardware_set_bank(nPacBank); + } + } + + return 0; +} + + +//------------------------------------------------------------------------------------------------------ +// Game drivers + + +// PuckMan (Japan set 1, Probably Bootleg) + +static struct BurnRomInfo puckmanRomDesc[] = { + { "namcopac.6e", 0x1000, 0xfee263b3, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "namcopac.6f", 0x1000, 0x39d1fc83, 1 | BRF_ESS | BRF_PRG }, // 1 + { "namcopac.6h", 0x1000, 0x02083b03, 1 | BRF_ESS | BRF_PRG }, // 2 + { "namcopac.6j", 0x1000, 0x7a36fe55, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pacman.5e", 0x1000, 0x0c944964, 2 | BRF_GRA }, // 4 Graphics + { "pacman.5f", 0x1000, 0x958fedf9, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(puckman); +STD_ROM_FN(puckman); + +struct BurnDriver BurnDrvpuckman = { + "puckman", NULL, NULL, "1980", + "PuckMan (Japan set 1, Probably Bootleg)\0", NULL, "Namco", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, puckmanRomInfo, puckmanRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// PuckMan (Japan set 1 with speedup hack) + +static struct BurnRomInfo puckmanfRomDesc[] = { + { "namcopac.6e", 0x1000, 0xfee263b3, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "nampfast.6f", 0x1000, 0x51b38db9, 1 | BRF_ESS | BRF_PRG }, // 1 + { "namcopac.6h", 0x1000, 0x02083b03, 1 | BRF_ESS | BRF_PRG }, // 2 + { "namcopac.6j", 0x1000, 0x7a36fe55, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pacman.5e", 0x1000, 0x0c944964, 2 | BRF_GRA }, // 4 Graphics + { "pacman.5f", 0x1000, 0x958fedf9, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(puckmanf); +STD_ROM_FN(puckmanf); + +struct BurnDriver BurnDrvpuckmanf = { + "puckmanf", "puckman", NULL, "1980", + "PuckMan (Japan set 1 with speedup hack)\0", NULL, "Namco", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, puckmanfRomInfo, puckmanfRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// PuckMan (Japan set 3) + +static struct BurnRomInfo puckmodRomDesc[] = { + { "namcopac.6e", 0x1000, 0xfee263b3, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "namcopac.6f", 0x1000, 0x39d1fc83, 1 | BRF_ESS | BRF_PRG }, // 1 + { "namcopac.6h", 0x1000, 0x02083b03, 1 | BRF_ESS | BRF_PRG }, // 2 + { "npacmod.6j", 0x1000, 0x7d98d5f5, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pacman.5e", 0x1000, 0x0c944964, 2 | BRF_GRA }, // 4 Graphics + { "pacman.5f", 0x1000, 0x958fedf9, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(puckmod); +STD_ROM_FN(puckmod); + +struct BurnDriver BurnDrvpuckmod = { + "puckmod", "puckman", NULL, "1981", + "PuckMan (Japan set 3)\0", NULL, "Namco", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, puckmodRomInfo, puckmodRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// PuckMan (Japan set 2) + +static struct BurnRomInfo puckmanaRomDesc[] = { + { "pacman.6e", 0x1000, 0xc1e6ab10, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacman.6f", 0x1000, 0x1a6fb2d4, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pacman.6h", 0x1000, 0xbcdd1beb, 1 | BRF_ESS | BRF_PRG }, // 2 + { "prg7", 0x0800, 0xb6289b26, 1 | BRF_ESS | BRF_PRG }, // 3 + { "prg8", 0x0800, 0x17a88c13, 1 | BRF_ESS | BRF_PRG }, // 4 + + { "chg1", 0x0800, 0x2066a0b7, 2 | BRF_GRA }, // 5 Graphics + { "chg2", 0x0800, 0x3591b89d, 2 | BRF_GRA }, // 6 + { "pacman.5f", 0x1000, 0x958fedf9, 2 | BRF_GRA }, // 7 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 8 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 9 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 10 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 11 Timing Prom (not used) +}; + +STD_ROM_PICK(puckmana); +STD_ROM_FN(puckmana); + +struct BurnDriver BurnDrvpuckmana = { + "puckmana", "puckman", NULL, "1981", + "PuckMan (Japan set 2)\0", NULL, "Namco", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, puckmanaRomInfo, puckmanaRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Pac-Man (Midway) + +static struct BurnRomInfo pacmanRomDesc[] = { + { "pacman.6e", 0x1000, 0xc1e6ab10, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacman.6f", 0x1000, 0x1a6fb2d4, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pacman.6h", 0x1000, 0xbcdd1beb, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pacman.6j", 0x1000, 0x817d94e3, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pacman.5e", 0x1000, 0x0c944964, 2 | BRF_GRA }, // 4 Graphics + { "pacman.5f", 0x1000, 0x958fedf9, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(pacman); +STD_ROM_FN(pacman); + +struct BurnDriver BurnDrvpacman = { + "pacman", "puckman", NULL, "1980", + "Pac-Man (Midway)\0", NULL, "[Namco] (Midway license)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, pacmanRomInfo, pacmanRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Pac-Man (Midway, with speedup hack) + +static struct BurnRomInfo pacmanfRomDesc[] = { + { "pacman.6e", 0x1000, 0xc1e6ab10, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacfast.6f", 0x1000, 0x720dc3ee, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pacman.6h", 0x1000, 0xbcdd1beb, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pacman.6j", 0x1000, 0x817d94e3, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pacman.5e", 0x1000, 0x0c944964, 2 | BRF_GRA }, // 4 Graphics + { "pacman.5f", 0x1000, 0x958fedf9, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(pacmanf); +STD_ROM_FN(pacmanf); + +struct BurnDriver BurnDrvpacmanf = { + "pacmanf", "puckman", NULL, "1980", + "Pac-Man (Midway, with speedup hack)\0", NULL, "[Namco] (Midway license)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, pacmanfRomInfo, pacmanfRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Hangly-Man (set 1) + +static struct BurnRomInfo hanglyRomDesc[] = { + { "hangly.6e", 0x1000, 0x5fe8610a, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "hangly.6f", 0x1000, 0x73726586, 1 | BRF_ESS | BRF_PRG }, // 1 + { "hangly.6h", 0x1000, 0x4e7ef99f, 1 | BRF_ESS | BRF_PRG }, // 2 + { "hangly.6j", 0x1000, 0x7f4147e6, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pacman.5e", 0x1000, 0x0c944964, 2 | BRF_GRA }, // 4 Graphics + { "pacman.5f", 0x1000, 0x958fedf9, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(hangly); +STD_ROM_FN(hangly); + +struct BurnDriver BurnDrvhangly = { + "hangly", "puckman", NULL, "1981", + "Hangly-Man (set 1)\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, hanglyRomInfo, hanglyRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Hangly-Man (set 2) + +static struct BurnRomInfo hangly2RomDesc[] = { + { "hangly.6e", 0x1000, 0x5fe8610a, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "hangly2.6f", 0x0800, 0x5ba228bb, 1 | BRF_ESS | BRF_PRG }, // 1 + { "hangly2.6m", 0x0800, 0xbaf5461e, 1 | BRF_ESS | BRF_PRG }, // 2 + { "hangly.6h", 0x1000, 0x4e7ef99f, 1 | BRF_ESS | BRF_PRG }, // 3 + { "hangly2.6j", 0x0800, 0x51305374, 1 | BRF_ESS | BRF_PRG }, // 4 + { "hangly2.6p", 0x0800, 0x427c9d4d, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "pacmanh.5e", 0x1000, 0x299fb17a, 2 | BRF_GRA }, // 6 Graphics + { "pacman.5f", 0x1000, 0x958fedf9, 2 | BRF_GRA }, // 7 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 8 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 9 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 10 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 11 Timing Prom (not used) +}; + +STD_ROM_PICK(hangly2); +STD_ROM_FN(hangly2); + +struct BurnDriver BurnDrvhangly2 = { + "hangly2", "puckman", NULL, "1981", + "Hangly-Man (set 2)\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, hangly2RomInfo, hangly2RomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Hangly-Man (set 3) + +static struct BurnRomInfo hangly3RomDesc[] = { + { "hm1.6e", 0x0800, 0x9d027c4a, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "hm5.6k", 0x0800, 0x194c7189, 1 | BRF_ESS | BRF_PRG }, // 1 + { "hangly2.6f", 0x0800, 0x5ba228bb, 1 | BRF_ESS | BRF_PRG }, // 2 + { "hangly2.6m", 0x0800, 0xbaf5461e, 1 | BRF_ESS | BRF_PRG }, // 3 + { "hm3.6h", 0x0800, 0x08419c4a, 1 | BRF_ESS | BRF_PRG }, // 4 + { "hm7.6n", 0x0800, 0xab74b51f, 1 | BRF_ESS | BRF_PRG }, // 5 + { "hm4.6j", 0x0800, 0x5039b082, 1 | BRF_ESS | BRF_PRG }, // 6 + { "hm8.6p", 0x0800, 0x931770d7, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "hm9.5e", 0x0800, 0x5f4be3cc, 2 | BRF_GRA }, // 8 Graphics + { "hm11.5h", 0x0800, 0x3591b89d, 2 | BRF_GRA }, // 9 + { "hm10.5f", 0x0800, 0x9e39323a, 2 | BRF_GRA }, // 10 + { "hm12.5j", 0x0800, 0x1b1d9096, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(hangly3); +STD_ROM_FN(hangly3); + +struct BurnDriver BurnDrvhangly3 = { + "hangly3", "puckman", NULL, "1981", + "Hangly-Man (set 3)\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, hangly3RomInfo, hangly3RomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Pac-Man (Midway, harder) + +static struct BurnRomInfo pacmodRomDesc[] = { + { "pacmanh.6e", 0x1000, 0x3b2ec270, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacman.6f", 0x1000, 0x1a6fb2d4, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pacmanh.6h", 0x1000, 0x18811780, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pacmanh.6j", 0x1000, 0x5c96a733, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pacmanh.5e", 0x1000, 0x299fb17a, 2 | BRF_GRA }, // 4 Graphics + { "pacman.5f", 0x1000, 0x958fedf9, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(pacmod); +STD_ROM_FN(pacmod); + +struct BurnDriver BurnDrvpacmod = { + "pacmod", "puckman", NULL, "1981", + "Pac-Man (Midway, harder)\0", NULL, "[Namco] (Midway license)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, pacmodRomInfo, pacmodRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Puckman (Falcom?) + +static struct BurnRomInfo puckmanhRomDesc[] = { + { "pm01.6e", 0x1000, 0x5fe8610a, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pm02.6f", 0x1000, 0x61d38c6c, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pm03.6h", 0x1000, 0x4e7ef99f, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pm04.6j", 0x1000, 0x8939ddd2, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pm9.5e", 0x0800, 0x2229ab07, 2 | BRF_GRA }, // 4 Graphics + { "pm11.5h", 0x0800, 0x3591b89d, 2 | BRF_GRA }, // 5 + { "pm10.5f", 0x0800, 0x9e39323a, 2 | BRF_GRA }, // 6 + { "pm12.5j", 0x0800, 0x1b1d9096, 2 | BRF_GRA }, // 7 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 8 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 9 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 10 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 11 Timing Prom (not used) +}; + +STD_ROM_PICK(puckmanh); +STD_ROM_FN(puckmanh); + +struct BurnDriver BurnDrvpuckmanh = { + "puckmanh", "puckman", NULL, "1981", + "Puckman (Falcom?)\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, puckmanhRomInfo, puckmanhRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// New Puck-X + +static struct BurnRomInfo newpuckxRomDesc[] = { + { "puckman.6e", 0x1000, 0xa8ae23c5, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacman.6f", 0x1000, 0x1a6fb2d4, 1 | BRF_ESS | BRF_PRG }, // 1 + { "puckman.6h", 0x1000, 0x197443f8, 1 | BRF_ESS | BRF_PRG }, // 2 + { "puckman.6j", 0x1000, 0x2e64a3ba, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pacman.5e", 0x1000, 0x0c944964, 2 | BRF_GRA }, // 4 Graphics + { "pacman.5f", 0x1000, 0x958fedf9, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(newpuckx); +STD_ROM_FN(newpuckx); + +struct BurnDriver BurnDrvnewpuckx = { + "newpuckx", "puckman", NULL, "1980", + "New Puck-X\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, newpuckxRomInfo, newpuckxRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Pac-Man (Hearts) + +static struct BurnRomInfo pacheartRomDesc[] = { + { "1.6e", 0x0800, 0xd844b679, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacheart.pg2", 0x0800, 0xb9152a38, 1 | BRF_ESS | BRF_PRG }, // 1 + { "2.6f", 0x0800, 0x7d177853, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pacheart.pg4", 0x0800, 0x842d6574, 1 | BRF_ESS | BRF_PRG }, // 3 + { "3.6h", 0x0800, 0x9045a44c, 1 | BRF_ESS | BRF_PRG }, // 4 + { "7.6n", 0x0800, 0x888f3c3e, 1 | BRF_ESS | BRF_PRG }, // 5 + { "pacheart.pg7", 0x0800, 0xf5265c10, 1 | BRF_ESS | BRF_PRG }, // 6 + { "pacheart.pg8", 0x0800, 0x1a21a381, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "pacheart.ch1", 0x0800, 0xc62bbabf, 2 | BRF_GRA }, // 8 Graphics + { "chg2", 0x0800, 0x3591b89d, 2 | BRF_GRA }, // 9 + { "pacheart.ch3", 0x0800, 0xca8c184c, 2 | BRF_GRA }, // 10 + { "pacheart.ch4", 0x0800, 0x1b1d9096, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(pacheart); +STD_ROM_FN(pacheart); + +struct BurnDriver BurnDrvpacheart = { + "pacheart", "puckman", NULL, "1981", + "Pac-Man (Hearts)\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, pacheartRomInfo, pacheartRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Joyman + +static struct BurnRomInfo joymanRomDesc[] = { + { "1.6e", 0x0800, 0xd844b679, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "5.6k", 0x0800, 0xab9c8f29, 1 | BRF_ESS | BRF_PRG }, // 1 + { "2.6f", 0x0800, 0x7d177853, 1 | BRF_ESS | BRF_PRG }, // 2 + { "6.6m", 0x0800, 0xb3c8d32e, 1 | BRF_ESS | BRF_PRG }, // 3 + { "3.6h", 0x0800, 0x9045a44c, 1 | BRF_ESS | BRF_PRG }, // 4 + { "7.6n", 0x0800, 0x888f3c3e, 1 | BRF_ESS | BRF_PRG }, // 5 + { "4.6j", 0x0800, 0x00b553f8, 1 | BRF_ESS | BRF_PRG }, // 6 + { "8.6p", 0x0800, 0x5d5ce992, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "9.5e", 0x0800, 0x39b557bc, 2 | BRF_GRA }, // 8 Graphics + { "11.5h", 0x0800, 0x33e0289e, 2 | BRF_GRA }, // 9 + { "10.5f", 0x0800, 0x338771a6, 2 | BRF_GRA }, // 10 + { "12.5j", 0x0800, 0xf4f0add5, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(joyman); +STD_ROM_FN(joyman); + +struct BurnDriver BurnDrvjoyman = { + "joyman", "puckman", NULL, "1982", + "Joyman\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, joymanRomInfo, joymanRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Caterpillar Pacman Hack + +static struct BurnRomInfo ctrpllrpRomDesc[] = { + { "c1.bin", 0x0800, 0x9d027c4a, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "c5.bin", 0x0800, 0xf39846d3, 1 | BRF_ESS | BRF_PRG }, // 1 + { "c2.bin", 0x0800, 0xafa149a8, 1 | BRF_ESS | BRF_PRG }, // 2 + { "c6.bin", 0x0800, 0xbaf5461e, 1 | BRF_ESS | BRF_PRG }, // 3 + { "c3.bin", 0x0800, 0x6bb282a1, 1 | BRF_ESS | BRF_PRG }, // 4 + { "c7.bin", 0x0800, 0xfa2140f5, 1 | BRF_ESS | BRF_PRG }, // 5 + { "c4.bin", 0x0800, 0x86c91e0e, 1 | BRF_ESS | BRF_PRG }, // 6 + { "c8.bin", 0x0800, 0x3d28134e, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "c9.bin", 0x0800, 0x1c4617be, 2 | BRF_GRA }, // 8 Graphics + { "c11.bin", 0x0800, 0x46f72fef, 2 | BRF_GRA }, // 9 + { "c10.bin", 0x0800, 0xba9ec199, 2 | BRF_GRA }, // 10 + { "c12.bin", 0x0800, 0x41c09655, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(ctrpllrp); +STD_ROM_FN(ctrpllrp); + +struct BurnDriver BurnDrvctrpllrp = { + "ctrpllrp", "puckman", NULL, "1982", + "Caterpillar Pacman Hack\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, ctrpllrpRomInfo, ctrpllrpRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Pac-Man Plus + +static struct BurnRomInfo pacplusRomDesc[] = { + { "pacplus.6e", 0x1000, 0xd611ef68, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacplus.6f", 0x1000, 0xc7207556, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pacplus.6h", 0x1000, 0xae379430, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pacplus.6j", 0x1000, 0x5a6dff7b, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pacplus.5e", 0x1000, 0x022c35da, 2 | BRF_GRA }, // 4 Graphics + { "pacplus.5f", 0x1000, 0x4de65cdd, 2 | BRF_GRA }, // 5 + + { "pacplus.7f", 0x0020, 0x063dd53a, 3 | BRF_GRA }, // 6 Color Proms + { "pacplus.4a", 0x0100, 0xe271a166, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(pacplus); +STD_ROM_FN(pacplus); + +static unsigned char pacplus_decrypt(int addr, unsigned char e) +{ + static const unsigned char swap_xor_table[6][9] = + { + { 7,6,5,4,3,2,1,0, 0x00 }, + { 7,6,5,4,3,2,1,0, 0x28 }, + { 6,1,3,2,5,7,0,4, 0x96 }, + { 6,1,5,2,3,7,0,4, 0xbe }, + { 0,3,7,6,4,2,1,5, 0xd5 }, + { 0,3,4,6,7,2,1,5, 0xdd } + }; + static const int picktable[32] = + { + 0,2,4,2,4,0,4,2,2,0,2,2,4,0,4,2, + 2,2,4,0,4,2,4,0,0,4,0,4,4,2,4,2 + }; + int method = 0; + const unsigned char *tbl; + + // pick method from bits 0 2 5 7 9 of the address + method = picktable[ + (addr & 0x001) | + ((addr & 0x004) >> 1) | + ((addr & 0x020) >> 3) | + ((addr & 0x080) >> 4) | + ((addr & 0x200) >> 5)]; + + // switch method if bit 11 of the address is set + if (addr & 0x800) + method ^= 1; + + tbl = swap_xor_table[method]; + + return BITSWAP08(e,tbl[0],tbl[1],tbl[2],tbl[3],tbl[4],tbl[5],tbl[6],tbl[7]) ^ tbl[8]; +} + + +void pacplus_decode() +{ + for (int i = 0; i < 0x4000; i++) + { + Rom[i] = pacplus_decrypt(i,Rom[i]); + } +} + +static int pacplusInit() +{ + pPacInitCallback = pacplus_decode; + + return DrvInit(); +} + +struct BurnDriver BurnDrvpacplus = { + "pacplus", NULL, NULL, "1982", + "Pac-Man Plus\0", NULL, "[Namco] (Midway license)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, pacplusRomInfo, pacplusRomName, DrvInputInfo, DrvDIPInfo, + pacplusInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + + +// Newpuc2 + +static struct BurnRomInfo newpuc2RomDesc[] = { + { "6e.cpu", 0x0800, 0x69496a98, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "6k.cpu", 0x0800, 0x158fc01c, 1 | BRF_ESS | BRF_PRG }, // 1 + { "6f.cpu", 0x0800, 0x7d177853, 1 | BRF_ESS | BRF_PRG }, // 2 + { "6m.cpu", 0x0800, 0x70810ccf, 1 | BRF_ESS | BRF_PRG }, // 3 + { "6h.cpu", 0x0800, 0x81719de8, 1 | BRF_ESS | BRF_PRG }, // 4 + { "6n.cpu", 0x0800, 0x3f250c58, 1 | BRF_ESS | BRF_PRG }, // 5 + { "6j.cpu", 0x0800, 0xe6675736, 1 | BRF_ESS | BRF_PRG }, // 6 + { "6p.cpu", 0x0800, 0x1f81e765, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "5e.cpu", 0x0800, 0x2066a0b7, 2 | BRF_GRA }, // 8 Graphics + { "5h.cpu", 0x0800, 0x777c70d3, 2 | BRF_GRA }, // 9 + { "5f.cpu", 0x0800, 0xca8c184c, 2 | BRF_GRA }, // 10 + { "5j.cpu", 0x0800, 0x7dc75a81, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(newpuc2); +STD_ROM_FN(newpuc2); + +struct BurnDriver BurnDrvnewpuc2 = { + "newpuc2", "puckman", NULL, "1980", + "Newpuc2\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, newpuc2RomInfo, newpuc2RomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Newpuc2b + +static struct BurnRomInfo newpuc2bRomDesc[] = { + { "np2b1.bin", 0x0800, 0x9d027c4a, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "6k.cpu", 0x0800, 0x158fc01c, 1 | BRF_ESS | BRF_PRG }, // 1 + { "6f.cpu", 0x0800, 0x7d177853, 1 | BRF_ESS | BRF_PRG }, // 2 + { "6m.cpu", 0x0800, 0x70810ccf, 1 | BRF_ESS | BRF_PRG }, // 3 + { "np2b3.bin", 0x0800, 0xf5e4b2b1, 1 | BRF_ESS | BRF_PRG }, // 4 + { "6n.cpu", 0x0800, 0x3f250c58, 1 | BRF_ESS | BRF_PRG }, // 5 + { "np2b4.bin", 0x0800, 0xf068e009, 1 | BRF_ESS | BRF_PRG }, // 6 + { "np2b8.bin", 0x0800, 0x1fadcc2f, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "5e.cpu", 0x0800, 0x2066a0b7, 2 | BRF_GRA }, // 8 Graphics + { "5h.cpu", 0x0800, 0x777c70d3, 2 | BRF_GRA }, // 9 + { "5f.cpu", 0x0800, 0xca8c184c, 2 | BRF_GRA }, // 10 + { "5j.cpu", 0x0800, 0x7dc75a81, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Prom + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(newpuc2b); +STD_ROM_FN(newpuc2b); + +struct BurnDriver BurnDrvnewpuc2b = { + "newpuc2b", "puckman", NULL, "1980", + "Newpuc2b\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, newpuc2bRomInfo, newpuc2bRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// MS Pacman + +static struct BurnRomInfo mspacmanRomDesc[] = { + { "pacman.6e", 0x1000, 0xc1e6ab10, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacman.6f", 0x1000, 0x1a6fb2d4, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pacman.6h", 0x1000, 0xbcdd1beb, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pacman.6j", 0x1000, 0x817d94e3, 1 | BRF_ESS | BRF_PRG }, // 3 + { "u5", 0x0800, 0xf45fbbcd, 1 | BRF_ESS | BRF_PRG }, // 4 + { "u6", 0x1000, 0xa90e7000, 1 | BRF_ESS | BRF_PRG }, // 5 + { "u7", 0x1000, 0xc82cd714, 1 | BRF_ESS | BRF_PRG }, // 6 + + { "5e", 0x1000, 0x5c281d01, 2 | BRF_GRA }, // 7 Graphics + { "5f", 0x1000, 0x615af909, 2 | BRF_GRA }, // 8 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 9 Color Prom + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 10 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 11 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 12 Timing Prom (not used) +}; + +STD_ROM_PICK(mspacman); +STD_ROM_FN(mspacman); + +static void mspacman_set_bank(int nBank) +{ + nBank &= 1; + + nPacBank = nBank; + ZetMapArea(0x0000, 0x3fff, 0, Rom + 0x0000 + (nBank * 0x10000)); + ZetMapArea(0x0000, 0x3fff, 2, Rom + 0x0000 + (nBank * 0x10000)); + ZetMapArea(0x8000, 0xbfff, 0, Rom + 0x8000 + (nBank * 0x10000)); + ZetMapArea(0x8000, 0xbfff, 2, Rom + 0x8000 + (nBank * 0x10000)); +} + +static void mspacman_decode() +{ +#define decryptd(e) BITSWAP08(e, 0, 4, 5, 7, 6, 3, 2, 1) +#define decrypta1(e) BITSWAP16(e, 15, 14, 13, 12, 11, 7, 8, 6, 9, 5, 4, 3, 10, 2, 1, 0) +#define decrypta2(e) BITSWAP16(e, 15, 14, 13, 12, 11, 6, 7, 10, 9, 5, 8, 3, 4, 2, 1, 0) + + int i; + static const int tab[10 * 8] = { // even is dst, odd is src + 0x0410, 0x8008, 0x08E0, 0x81D8, 0x0A30, 0x8118, 0x0BD0, 0x80D8, + 0x0C20, 0x8120, 0x0E58, 0x8168, 0x0EA8, 0x8198, 0x1000, 0x8020, + 0x1008, 0x8010, 0x1288, 0x8098, 0x1348, 0x8048, 0x1688, 0x8088, + 0x16B0, 0x8188, 0x16D8, 0x80C8, 0x16F8, 0x81C8, 0x19A8, 0x80A8, + 0x19B8, 0x81A8, 0x2060, 0x8148, 0x2108, 0x8018, 0x21A0, 0x81A0, + 0x2298, 0x80A0, 0x23E0, 0x80E8, 0x2418, 0x8000, 0x2448, 0x8058, + 0x2470, 0x8140, 0x2488, 0x8080, 0x24B0, 0x8180, 0x24D8, 0x80C0, + 0x24F8, 0x81C0, 0x2748, 0x8050, 0x2780, 0x8090, 0x27B8, 0x8190, + 0x2800, 0x8028, 0x2B20, 0x8100, 0x2B30, 0x8110, 0x2BF0, 0x81D0, + 0x2CC0, 0x80D0, 0x2CD8, 0x80E0, 0x2CF0, 0x81E0, 0x2D60, 0x8160, + }; + + memcpy (Rom + 0x10000, Rom + 0x00000, 0x03000); + + for (i = 0; i < 0x1000; i++) { + Rom[decrypta1(i)+0x13000] = decryptd(Rom[0xb000+i]); // u7 + Rom[decrypta1(i)+0x19000] = decryptd(Rom[0x9000+i]); // u6 + } + + for (i = 0; i < 0x0800; i++) { + Rom[decrypta2(i)+0x18000] = decryptd(Rom[0x8000+i]); // u5 + Rom[0x18800+i] = Rom[0x19800+i]; + } + + for (i = 0; i < 80; i+=2) { + memcpy (Rom + 0x10000 + tab[i], Rom + 0x10000 + tab[i+1], 8); + } +} + +static void mspacmanCallback() +{ + // Fix the loading + memcpy (Rom + 0xb000, Rom + 0x9800, 0x1000); + memcpy (Rom + 0x9000, Rom + 0x8800, 0x1000); + + memset (Rom + 0x8800, 0, 0x0800); + memset (Rom + 0xa000, 0, 0x0800); + + mspacman_decode(); +} + +static int mspacmanInit() +{ + mspacman = 1; + + pPacInitCallback = mspacmanCallback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvmspacman = { + "mspacman", NULL, NULL, "1980", + "MS Pacman\0", NULL, "Namco", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, mspacmanRomInfo, mspacmanRomName, DrvInputInfo, mspacmanDIPInfo, + mspacmanInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Ms. Pac-Man (with speedup hack) + +static struct BurnRomInfo mspacmnfRomDesc[] = { + { "pacman.6e", 0x1000, 0xc1e6ab10, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacfast.6f", 0x1000, 0x720dc3ee, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pacman.6h", 0x1000, 0xbcdd1beb, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pacman.6j", 0x1000, 0x817d94e3, 1 | BRF_ESS | BRF_PRG }, // 3 + { "u5", 0x0800, 0xf45fbbcd, 1 | BRF_ESS | BRF_PRG }, // 4 + { "u6", 0x1000, 0xa90e7000, 1 | BRF_ESS | BRF_PRG }, // 5 + { "u7", 0x1000, 0xc82cd714, 1 | BRF_ESS | BRF_PRG }, // 6 + + { "5e", 0x1000, 0x5c281d01, 2 | BRF_GRA }, // 7 Graphics + { "5f", 0x1000, 0x615af909, 2 | BRF_GRA }, // 8 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 9 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 10 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 11 Timing Prom (not used) +}; + +STD_ROM_PICK(mspacmnf); +STD_ROM_FN(mspacmnf); + +struct BurnDriver BurnDrvmspacmnf = { + "mspacmnf", "mspacman", NULL, "1980", + "Ms. Pac-Man (with speedup hack)\0", NULL, "Midway", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, mspacmnfRomInfo, mspacmnfRomName, DrvInputInfo, mspacmanDIPInfo, + mspacmanInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Ms. Pac Attack + +static struct BurnRomInfo mspacmatRomDesc[] = { + { "pacman.6e", 0x1000, 0xc1e6ab10, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacman.6f", 0x1000, 0x1a6fb2d4, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pacman.6h", 0x1000, 0xbcdd1beb, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pacman.6j", 0x1000, 0x817d94e3, 1 | BRF_ESS | BRF_PRG }, // 3 + { "u5", 0x0800, 0xf45fbbcd, 1 | BRF_ESS | BRF_PRG }, // 4 + { "u6pacatk", 0x1000, 0xf6d83f4d, 1 | BRF_ESS | BRF_PRG }, // 5 + { "u7", 0x1000, 0xc82cd714, 1 | BRF_ESS | BRF_PRG }, // 6 + + { "5e", 0x1000, 0x5c281d01, 2 | BRF_GRA }, // 7 Graphics + { "5f", 0x1000, 0x615af909, 2 | BRF_GRA }, // 8 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 9 Color Prom + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 10 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 11 + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 12 Sound Prom (not used) +}; + +STD_ROM_PICK(mspacmat); +STD_ROM_FN(mspacmat); + +struct BurnDriver BurnDrvmspacmat = { + "mspacmat", "mspacman", NULL, "1980", + "Ms. Pac Attack\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, mspacmatRomInfo, mspacmatRomName, DrvInputInfo, mspacmanDIPInfo, + mspacmanInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// MS Pacman (bootleg) + +static struct BurnRomInfo mspacmabRomDesc[] = { + { "boot1", 0x1000, 0xd16b31b7, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "boot2", 0x1000, 0x0d32de5e, 1 | BRF_ESS | BRF_PRG }, // 1 + { "boot3", 0x1000, 0x1821ee0b, 1 | BRF_ESS | BRF_PRG }, // 2 + { "boot4", 0x1000, 0x165a9dd8, 1 | BRF_ESS | BRF_PRG }, // 3 + { "boot5", 0x1000, 0x8c3e6de6, 1 | BRF_ESS | BRF_PRG }, // 4 + { "boot6", 0x1000, 0x368cb165, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "5e", 0x1000, 0x5c281d01, 2 | BRF_GRA }, // 6 Graphics + { "5f", 0x1000, 0x615af909, 2 | BRF_GRA }, // 7 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 8 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 9 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 10 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 11 Timing Prom (not used) +}; + +STD_ROM_PICK(mspacmab); +STD_ROM_FN(mspacmab); + +struct BurnDriver BurnDrvmspacmab = { + "mspacmab", "mspacman", NULL, "1981", + "MS Pacman (bootleg)\0", NULL, "Namco", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, mspacmabRomInfo, mspacmabRomName, DrvInputInfo, mspacmanDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + + +// Ms. Pac-Man (bootleg, (encrypted)) + +static struct BurnRomInfo mspacmbeRomDesc[] = { + { "boot1", 0x1000, 0xd16b31b7, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "2.bin", 0x1000, 0x04e6c486, 1 | BRF_ESS | BRF_PRG }, // 1 + { "boot3", 0x1000, 0x1821ee0b, 1 | BRF_ESS | BRF_PRG }, // 2 + { "boot4", 0x1000, 0x165a9dd8, 1 | BRF_ESS | BRF_PRG }, // 3 + { "boot5", 0x1000, 0x8c3e6de6, 1 | BRF_ESS | BRF_PRG }, // 4 + { "6.bin", 0x1000, 0x206a9623, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "5e", 0x1000, 0x5c281d01, 2 | BRF_GRA }, // 6 Graphics + { "5f", 0x1000, 0x615af909, 2 | BRF_GRA }, // 7 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 8 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 9 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 10 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 11 Timing Prom (not used) +}; + +STD_ROM_PICK(mspacmbe); +STD_ROM_FN(mspacmbe); + +static void mspacmbe_decode() +{ + // Address lines A1 and A0 swapped if A2=0 + for(int i = 0x1000; i < 0x2000; i+=4) + { + if (!(i & 8)) + { + int t = Rom[i+1]; + Rom[i+1] = Rom[i+2]; + Rom[i+2] = t; + }; + } +} + +static int mspacmbeInit() +{ + pPacInitCallback = mspacmbe_decode; + + return DrvInit(); +} + +struct BurnDriver BurnDrvmspacmbe = { + "mspacmbe", "mspacman", NULL, "1981", + "Ms. Pac-Man (bootleg, (encrypted))\0", NULL, "bootleg", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, mspacmbeRomInfo, mspacmbeRomName, DrvInputInfo, mspacmanDIPInfo, + mspacmbeInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Pac-Gal + +static struct BurnRomInfo pacgalRomDesc[] = { + { "boot1", 0x1000, 0xd16b31b7, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "boot2", 0x1000, 0x0d32de5e, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pacman.7fh", 0x1000, 0x513f4d5c, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pacman.7hj", 0x1000, 0x70694c8e, 1 | BRF_ESS | BRF_PRG }, // 3 + { "boot5", 0x1000, 0x8c3e6de6, 1 | BRF_ESS | BRF_PRG }, // 4 + { "boot6", 0x1000, 0x368cb165, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "5e", 0x1000, 0x5c281d01, 2 | BRF_GRA }, // 6 Graphics + { "pacman.5ef", 0x0800, 0x65a3ee71, 2 | BRF_GRA }, // 7 + { "pacman.5hj", 0x0800, 0x50c7477d, 2 | BRF_GRA }, // 8 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 9 Color Proms + { "82s129.4a", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 10 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 11 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 12 Timing Prom (not used) +}; + +STD_ROM_PICK(pacgal); +STD_ROM_FN(pacgal); + +struct BurnDriver BurnDrvpacgal = { + "pacgal", "mspacman", NULL, "1981", + "Pac-Gal\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, pacgalRomInfo, pacgalRomName, DrvInputInfo, mspacmanDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Ms. Pac-Man Plus + +static struct BurnRomInfo mspacplsRomDesc[] = { + { "boot1", 0x1000, 0xd16b31b7, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "mspacatk.2", 0x1000, 0x0af09d31, 1 | BRF_ESS | BRF_PRG }, // 1 + { "boot3", 0x1000, 0x1821ee0b, 1 | BRF_ESS | BRF_PRG }, // 2 + { "boot4", 0x1000, 0x165a9dd8, 1 | BRF_ESS | BRF_PRG }, // 3 + { "mspacatk.5", 0x1000, 0xe6e06954, 1 | BRF_ESS | BRF_PRG }, // 4 + { "mspacatk.6", 0x1000, 0x3b5db308, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "5e", 0x1000, 0x5c281d01, 2 | BRF_GRA }, // 6 Graphics + { "5f", 0x1000, 0x615af909, 2 | BRF_GRA }, // 7 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 8 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 9 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 10 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 11 Timing Prom (not used) +}; + +STD_ROM_PICK(mspacpls); +STD_ROM_FN(mspacpls); + +struct BurnDriver BurnDrvmspacpls = { + "mspacpls", "mspacman", NULL, "1981", + "Ms. Pac-Man Plus\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, mspacplsRomInfo, mspacplsRomName, DrvInputInfo, mspacmanDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + + +// Ms. Pacman Champion Edition / Super Zola Pac Gal + + +static struct BurnRomInfo mschampRomDesc[] = { + { "pm4.bin", 0x10000, 0x7d6b6303, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + + { "pm5.bin", 0x2000, 0x7fe6b9e2, 2 | BRF_GRA }, // 1 Graphics + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 2 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 3 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 4 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 5 Timing Prom (not used)) ) +}; + +STD_ROM_PICK(mschamp); +STD_ROM_FN(mschamp); + +static void mschamp_set_bank() +{ + int nBank = DrvDips[3] & 1; + + nPacBank = nBank; + ZetMapArea(0x0000, 0x3fff, 0, Rom + 0x10000 + (nBank * 0x08000)); + ZetMapArea(0x0000, 0x3fff, 2, Rom + 0x10000 + (nBank * 0x08000)); + ZetMapArea(0x8000, 0xbfff, 0, Rom + 0x14000 + (nBank * 0x08000)); + ZetMapArea(0x8000, 0xbfff, 2, Rom + 0x14000 + (nBank * 0x08000)); +} + +static void mschampCallback() +{ + memcpy (Rom + 0x10000, Gfx, 0x2000); + + memcpy (Gfx + 0x0000, Rom + 0x10000, 0x0800); + memcpy (Gfx + 0x1000, Rom + 0x10800, 0x0800); + memcpy (Gfx + 0x0800, Rom + 0x11000, 0x0800); + memcpy (Gfx + 0x1800, Rom + 0x11800, 0x0800); + + memcpy (Rom + 0x10000, Rom, 0x10000); +} + +static int mschampInit() +{ + mschamp = 1; + + pPacInitCallback = mschampCallback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvmschamp = { + "mschamp", "mspacman", NULL, "1995", + "Ms. Pacman Champion Edition / Super Zola Pac Gal\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, mschampRomInfo, mschampRomName, mschampInputInfo, mschampDIPInfo, + mschampInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Crush Roller (Kural Samno) + +static struct BurnRomInfo crushRomDesc[] = { + { "crushkrl.6e", 0x1000, 0xa8dd8f54, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "crushkrl.6f", 0x1000, 0x91387299, 1 | BRF_ESS | BRF_PRG }, // 1 + { "crushkrl.6h", 0x1000, 0xd4455f27, 1 | BRF_ESS | BRF_PRG }, // 2 + { "crushkrl.6j", 0x1000, 0xd59fc251, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "maketrax.5e", 0x1000, 0x91bad2da, 2 | BRF_GRA }, // 4 Graphics + { "maketrax.5f", 0x1000, 0xaea79f55, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Prom + { "2s140.4a", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(crush); +STD_ROM_FN(crush); + +static void maketraxCallback() +{ + // From the bootleg + // Patch protection & rom test + Rom[0x0224] = 0x00; + Rom[0x0225] = 0x00; + Rom[0x0226] = 0x00; + Rom[0x022D] = 0x00; + Rom[0x022F] = 0x00; + Rom[0x023C] = 0x00; + Rom[0x023D] = 0x00; + Rom[0x023E] = 0x00; + Rom[0x0415] = 0xc9; + Rom[0x0428] = 0xC6; + Rom[0x0429] = 0x12; + Rom[0x115E] = 0xC9; + Rom[0x1481] = 0x28; + Rom[0x1492] = 0x20; + Rom[0x14A5] = 0xC8; + Rom[0x1978] = 0x18; + Rom[0x1C9F] = 0xA7; + Rom[0x1CA0] = 0xC9; + Rom[0x238e] = 0xc9; + Rom[0x3AE5] = 0x3E; + Rom[0x3AE7] = 0xFE; + Rom[0x3AE8] = 0x3F; + Rom[0x3AE9] = 0xC9; +} + +static int crushInit() +{ + pPacInitCallback = maketraxCallback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvcrush = { + "crush", NULL, NULL, "1981", + "Crush Roller (Kural Samno)\0", NULL, "Kural Samno Electric", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, crushRomInfo, crushRomName, DrvInputInfo, maketraxDIPInfo, + crushInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + + +// Crush Roller (bootleg) + +static struct BurnRomInfo crushblRomDesc[] = { + { "cr1.bin", 0x1000, 0xe2e84cd1, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "cr2.bin", 0x1000, 0xec020e6f, 1 | BRF_ESS | BRF_PRG }, // 1 + { "cr3.bin", 0x1000, 0xd4455f27, 1 | BRF_ESS | BRF_PRG }, // 2 + { "cr4.bin", 0x1000, 0x9936ae06, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "maketrax.5e", 0x1000, 0x91bad2da, 2 | BRF_GRA }, // 4 Graphics + { "maketrax.5f", 0x1000, 0xaea79f55, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Prom + { "2s140.4a", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(crushbl); +STD_ROM_FN(crushbl); + +struct BurnDriver BurnDrvcrushbl = { + "crushbl", "crush", NULL, "1981", + "Crush Roller (bootleg)\0", NULL, "Kural Samno Electric", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, crushblRomInfo, crushblRomName, DrvInputInfo, maketraxDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Crush Roller (Kural Esco - bootleg?) + +static struct BurnRomInfo crush2RomDesc[] = { + { "tp1", 0x0800, 0xf276592e, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "tp5a", 0x0800, 0x3d302abe, 1 | BRF_ESS | BRF_PRG }, // 1 + { "tp2", 0x0800, 0x25f42e70, 1 | BRF_ESS | BRF_PRG }, // 2 + { "tp6", 0x0800, 0x98279cbe, 1 | BRF_ESS | BRF_PRG }, // 3 + { "tp3", 0x0800, 0x8377b4cb, 1 | BRF_ESS | BRF_PRG }, // 4 + { "tp7", 0x0800, 0xd8e76c8c, 1 | BRF_ESS | BRF_PRG }, // 5 + { "tp4", 0x0800, 0x90b28fa3, 1 | BRF_ESS | BRF_PRG }, // 6 + { "tp8", 0x0800, 0x10854e1b, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "tpa", 0x0800, 0xc7617198, 2 | BRF_GRA }, // 8 Graphics + { "tpc", 0x0800, 0xe129d76a, 2 | BRF_GRA }, // 9 + { "tpb", 0x0800, 0xd1899f05, 2 | BRF_GRA }, // 10 + { "tpd", 0x0800, 0xd35d1caf, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "2s140.4a", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(crush2); +STD_ROM_FN(crush2); + +struct BurnDriver BurnDrvcrush2 = { + "crush2", "crush", NULL, "1981", + "Crush Roller (Kural Esco - bootleg?)\0", NULL, "Kural Esco Electric", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, crush2RomInfo, crush2RomName, DrvInputInfo, maketraxDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Crush Roller (Kural - bootleg?) + +static struct BurnRomInfo crush3RomDesc[] = { + { "unkmol.4e", 0x0800, 0x49150ddf, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "unkmol.6e", 0x0800, 0x21f47e17, 1 | BRF_ESS | BRF_PRG }, // 1 + { "unkmol.4f", 0x0800, 0x9b6dd592, 1 | BRF_ESS | BRF_PRG }, // 2 + { "unkmol.6f", 0x0800, 0x755c1452, 1 | BRF_ESS | BRF_PRG }, // 3 + { "unkmol.4h", 0x0800, 0xed30a312, 1 | BRF_ESS | BRF_PRG }, // 4 + { "unkmol.6h", 0x0800, 0xfe4bb0eb, 1 | BRF_ESS | BRF_PRG }, // 5 + { "unkmol.4j", 0x0800, 0x072b91c9, 1 | BRF_ESS | BRF_PRG }, // 6 + { "unkmol.6j", 0x0800, 0x66fba07d, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "unkmol.5e", 0x0800, 0x338880a0, 2 | BRF_GRA }, // 8 Graphics + { "unkmol.5h", 0x0800, 0x4ce9c81f, 2 | BRF_GRA }, // 9 + { "unkmol.5f", 0x0800, 0x752e3780, 2 | BRF_GRA }, // 10 + { "unkmol.5j", 0x0800, 0x6e00d2ac, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "2s140.4a", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(crush3); +STD_ROM_FN(crush3); + +static void eyes_gfx_decode(unsigned char *src) +{ + unsigned char buf[8]; + + for (int j = 0; j < 8; j++) + { + buf[j] = BITSWAP08(src[(j & 0xff00) | BITSWAP08(j,7,6,5,4,3,0,1,2)],7,4,5,6,3,2,1,0); + } + + memcpy (src, buf, 8); +} + +static void eyes_decode() +{ + // Data lines D3 and D5 swapped + for (int i = 0; i < 0x4000; i++) + { + Rom[i] = BITSWAP08(Rom[i],7,6,3,4,5,2,1,0); + } + + + // Graphics ROMs + // Data lines D4 and D6 and address lines A0 and A2 are swapped + for (int i = 0;i < 0x2000; i += 8) + eyes_gfx_decode(Gfx + i); +} + +static int crush3Init() +{ + pPacInitCallback = eyes_decode; + + return DrvInit(); +} + +struct BurnDriver BurnDrvcrush3 = { + "crush3", "crush", NULL, "1981", + "Crush Roller (Kural - bootleg?)\0", NULL, "Kural Electric", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, crush3RomInfo, crush3RomName, DrvInputInfo, maketraxDIPInfo, + crush3Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Crush Roller (Kural TWT) + +static struct BurnRomInfo crush4RomDesc[] = { + { "crtwt.2", 0x10000, 0xadbd21f7, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code (banked) + + { "crtwt.1", 0x4000, 0x4250a9ea, 2 | BRF_GRA }, // 1 Graphics + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 2 Color Proms + { "82s129.bin", 0x0100, 0x2bc5d339, 3 | BRF_GRA }, // 3 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 4 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 5 Timing Prom (not used) +}; + +STD_ROM_PICK(crush4); +STD_ROM_FN(crush4); + +static void crush4Callback() +{ + // Fix graphics order + memcpy (Rom + 0x10000, Gfx + 0x00000, 0x04000); + memcpy (Gfx + 0x01000, Rom + 0x10800, 0x00800); + memcpy (Gfx + 0x00800, Rom + 0x11000, 0x00800); + memcpy (Gfx + 0x03000, Rom + 0x12800, 0x00800); + memcpy (Gfx + 0x02800, Rom + 0x13000, 0x00800); + + // always select second part of the code + memcpy (Rom + 0x00000, Rom + 0x08000, 0x04000); + memcpy (Rom + 0x08000, Rom + 0x0c000, 0x04000); + memset (Rom + 0x0c000, 0, 0x4000); +} + + +static int crush4Init() +{ + pPacInitCallback = crush4Callback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvcrush4 = { + "crush4", "crush", NULL, "1981", + "Crush Roller (Kural TWT)\0", NULL, "Kural TWT", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, crush4RomInfo, crush4RomName, DrvInputInfo, maketraxDIPInfo, + crush4Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Paint Roller + +static struct BurnRomInfo paintrlrRomDesc[] = { + { "paintrlr.1", 0x0800, 0x556d20b5, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "paintrlr.5", 0x0800, 0x4598a965, 1 | BRF_ESS | BRF_PRG }, // 1 + { "paintrlr.2", 0x0800, 0x2da29c81, 1 | BRF_ESS | BRF_PRG }, // 2 + { "paintrlr.6", 0x0800, 0x1f561c54, 1 | BRF_ESS | BRF_PRG }, // 3 + { "paintrlr.3", 0x0800, 0xe695b785, 1 | BRF_ESS | BRF_PRG }, // 4 + { "paintrlr.7", 0x0800, 0x00e6eec0, 1 | BRF_ESS | BRF_PRG }, // 5 + { "paintrlr.4", 0x0800, 0x0fd5884b, 1 | BRF_ESS | BRF_PRG }, // 6 + { "paintrlr.8", 0x0800, 0x4900114a, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "tpa", 0x0800, 0xc7617198, 2 | BRF_GRA }, // 8 Graphics + { "mbrush.5h", 0x0800, 0xc15b6967, 2 | BRF_GRA }, // 9 + { "mbrush.5f", 0x0800, 0xd5bc5cb8, 2 | BRF_GRA }, // 10 + { "tpd", 0x0800, 0xd35d1caf, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "2s140.4a", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (unused) +}; + +STD_ROM_PICK(paintrlr); +STD_ROM_FN(paintrlr); + +struct BurnDriverD BurnDrvpaintrlr = { + "paintrlr", "crush", NULL, "1981", + "Paint Roller\0", NULL, "bootleg", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, paintrlrRomInfo, paintrlrRomName, DrvInputInfo, mbrushDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + + +// Crush Roller (Sidam bootleg) + +static struct BurnRomInfo crushsRomDesc[] = { + { "11105-0.0j", 0x1000, 0xdd425429, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "11105-1.1j", 0x1000, 0xf9d89eef, 1 | BRF_ESS | BRF_PRG }, // 1 + { "11105-2.2j", 0x1000, 0x40c23a27, 1 | BRF_ESS | BRF_PRG }, // 2 + { "11105-3.3j", 0x1000, 0x5802644f, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "11105-4.4j", 0x1000, 0x91bad2da, 2 | BRF_GRA }, // 4 Graphics + { "11105-5.5j", 0x1000, 0xb5c14376, 2 | BRF_GRA }, // 5 + + { "74s288.8a", 0x0020, 0xff344446, 3 | BRF_GRA }, // 6 Color Proms + { "24s10.6b", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 7 + + // uses AY8910 +}; + +STD_ROM_PICK(crushs); +STD_ROM_FN(crushs); + +static int crushsInit() +{ + crushs = 1; + + return DrvInit(); +} + +struct BurnDriver BurnDrvcrushs = { + "crushs", "crush", NULL, "19??", + "Crush Roller (Sidam bootleg)\0", NULL, "[Kural] (Sidam bootleg)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, crushsRomInfo, crushsRomName, DrvInputInfo, crushsDIPInfo, + crushsInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Make Trax (set 1) + +static struct BurnRomInfo maketraxRomDesc[] = { + { "maketrax.6e", 0x1000, 0x0150fb4a, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "maketrax.6f", 0x1000, 0x77531691, 1 | BRF_ESS | BRF_PRG }, // 1 + { "maketrax.6h", 0x1000, 0xa2cdc51e, 1 | BRF_ESS | BRF_PRG }, // 2 + { "maketrax.6j", 0x1000, 0x0b4b5e0a, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "maketrax.5e", 0x1000, 0x91bad2da, 2 | BRF_GRA }, // 4 Graphics + { "maketrax.5f", 0x1000, 0xaea79f55, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "2s140.4a", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(maketrax); +STD_ROM_FN(maketrax); + +static unsigned char maketrax_special_port2_r(unsigned short offset) +{ + int data = DrvDips[2]; + int pc = ZetPc(-1); + + if ((pc == 0x1973) || (pc == 0x2389)) return data | 0x40; + + switch (offset) + { + case 0x01: + case 0x04: + data |= 0x40; break; + case 0x05: + data |= 0xc0; break; + default: + data &= 0x3f; break; + } + + return data; +} + +static unsigned char maketrax_special_port3_r(unsigned short offset) +{ + int pc = ZetPc(-1); + + if (pc == 0x040e) return 0x20; + + if ((pc == 0x115e) || (pc == 0x3ae2)) return 0x00; + + switch (offset) + { + case 0x00: + return 0x1f; + case 0x09: + return 0x30; + case 0x0c: + return 0x00; + default: + return 0x20; + } +} + +static int maketraxInit() +{ + maketrax = 1; + screen_flip = 1; + + pPacInitCallback = maketraxCallback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvmaketrax = { + "maketrax", "crush", NULL, "1981", + "Make Trax (set 1)\0", NULL, "[Kural] (Williams license)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, maketraxRomInfo, maketraxRomName, DrvInputInfo, maketraxDIPInfo, + maketraxInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Make Trax (set 2) + +static struct BurnRomInfo maketrxbRomDesc[] = { + { "maketrax.6e", 0x1000, 0x0150fb4a, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "maketrax.6f", 0x1000, 0x77531691, 1 | BRF_ESS | BRF_PRG }, // 1 + { "maketrxb.6h", 0x1000, 0x6ad342c9, 1 | BRF_ESS | BRF_PRG }, // 2 + { "maketrxb.6j", 0x1000, 0xbe27f729, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "maketrax.5e", 0x1000, 0x91bad2da, 2 | BRF_GRA }, // 4 Graphics + { "maketrax.5f", 0x1000, 0xaea79f55, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "2s140.4a", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(maketrxb); +STD_ROM_FN(maketrxb); + +struct BurnDriver BurnDrvmaketrxb = { + "maketrxb", "crush", NULL, "1981", + "Make Trax (set 2)\0", NULL, "[Kural] (Williams license)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, maketrxbRomInfo, maketrxbRomName, DrvInputInfo, maketraxDIPInfo, + maketraxInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Magic Brush + +static struct BurnRomInfo mbrushRomDesc[] = { + { "mbrush.6e", 0x1000, 0x750fbff7, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "mbrush.6f", 0x1000, 0x27eb4299, 1 | BRF_ESS | BRF_PRG }, // 1 + { "mbrush.6h", 0x1000, 0xd297108e, 1 | BRF_ESS | BRF_PRG }, // 2 + { "mbrush.6j", 0x1000, 0x6fd719d0, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "tpa", 0x0800, 0xc7617198, 2 | BRF_GRA }, // 4 Graphics + { "mbrush.5h", 0x0800, 0xc15b6967, 2 | BRF_GRA }, // 5 + { "mbrush.5f", 0x0800, 0xd5bc5cb8, 2 | BRF_GRA }, // 6 + { "tpd", 0x0800, 0xd35d1caf, 2 | BRF_GRA }, // 7 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 8 Color Proms + { "2s140.4a", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 9 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 10 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 11 Timing Prom (not used) +}; + +STD_ROM_PICK(mbrush); +STD_ROM_FN(mbrush); + +static void mbrushCallback() +{ + // patches from crush bootleg (incomplete?) + Rom[0x3AE2] = 0x3E; + Rom[0x3AE3] = 0x00; + Rom[0x3AE4] = 0x00; +} + +static int mbrushInit() +{ + pPacInitCallback = mbrushCallback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvmbrush = { + "mbrush", "crush", NULL, "1981", + "Magic Brush\0", NULL, "bootleg", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, mbrushRomInfo, mbrushRomName, DrvInputInfo, mbrushDIPInfo, + mbrushInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Korosuke Roller + +static struct BurnRomInfo korosukeRomDesc[] = { + { "kr.6e", 0x1000, 0x69f6e2da, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "kr.6f", 0x1000, 0xabf34d23, 1 | BRF_ESS | BRF_PRG }, // 1 + { "kr.6h", 0x1000, 0x76a2e2e2, 1 | BRF_ESS | BRF_PRG }, // 2 + { "kr.6j", 0x1000, 0x33e0e3bb, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "kr.5e", 0x1000, 0xe0380be8, 2 | BRF_GRA }, // 4 Graphics + { "kr.5f", 0x1000, 0x63fec9ee, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "2s140.4a", 0x0100, 0x63efb927, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(korosuke); +STD_ROM_FN(korosuke); + +static unsigned char korosuke_special_port2_r(unsigned short offset) +{ + int data = DrvDips[2]; + int pc = ZetPc(-1); + + if ((pc == 0x196e) || (pc == 0x2387)) return data | 0x40; + + switch (offset) + { + case 0x01: + case 0x04: + data |= 0x40; break; + + case 0x05: + data |= 0xc0; break; + + default: + data &= 0x3f; break; + } + + return data; +} + +static unsigned char korosuke_special_port3_r(unsigned short offset) +{ + int pc = ZetPc(-1); + + if (pc == 0x0445) return 0x20; + + if ((pc == 0x115b) || (pc == 0x3ae6)) return 0x00; + + switch (offset) + { + case 0x00: + return 0x1f; + case 0x09: + return 0x30; + case 0x0c: + return 0x00; + default: + return 0x20; + } +} + +static void korosukeCallback() +{ + // From the bootleg + // Patch protection & rom test + Rom[0x0233] = 0x00; + Rom[0x0234] = 0x00; + Rom[0x0235] = 0x00; + Rom[0x023c] = 0x00; + Rom[0x023e] = 0x00; + Rom[0x024b] = 0x00; + Rom[0x024c] = 0x00; + Rom[0x024d] = 0x00; + Rom[0x044c] = 0xc9; + Rom[0x115B] = 0xC9; + Rom[0x1AE9] = 0x18; + Rom[0x1CA7] = 0xA7; + Rom[0x1CA8] = 0xC9; + Rom[0x238c] = 0xc9; + Rom[0x3AE9] = 0x3E; + Rom[0x3AEB] = 0xFE; + Rom[0x3AEC] = 0x3F; + Rom[0x3AEE] = 0xC9; + Rom[0x045d] = 0xC6; + Rom[0x045e] = 0x12; + Rom[0x1481] = 0x28; + Rom[0x1492] = 0x20; + Rom[0x14A5] = 0xC8; +} + + +static int korosukeInit() +{ + korosuke = 1; + + pPacInitCallback = korosukeCallback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvkorosuke = { + "korosuke", "crush", NULL, "1981", + "Korosuke Roller\0", NULL, "Kural Electric", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, korosukeRomInfo, korosukeRomName, korosukeInputInfo, korosukeDIPInfo, + korosukeInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Eyes (Digitrex Techstar) + +static struct BurnRomInfo eyesRomDesc[] = { + { "d7", 0x1000, 0x3b09ac89, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "e7", 0x1000, 0x97096855, 1 | BRF_ESS | BRF_PRG }, // 1 + { "f7", 0x1000, 0x731e294e, 1 | BRF_ESS | BRF_PRG }, // 2 + { "h7", 0x1000, 0x22f7a719, 1 | BRF_ESS | BRF_PRG }, // 4 + + { "d5", 0x1000, 0xd6af0030, 2 | BRF_GRA }, // 5 Graphics + { "e5", 0x1000, 0xa42b5201, 2 | BRF_GRA }, // 6 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 7 Color Proms + { "82s129.4a", 0x0100, 0xd8d78829, 3 | BRF_GRA }, // 8 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 9 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 10 Timing Prom (not used) +}; + +STD_ROM_PICK(eyes); +STD_ROM_FN(eyes); + +static int eyesInit() +{ + pPacInitCallback = eyes_decode; + + return DrvInit(); +} + +struct BurnDriver BurnDrveyes = { + "eyes", NULL, NULL, "1982", + "Eyes (Digitrex Techstar)\0", NULL, "Digitrex Techstar (Rock-ola license)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, eyesRomInfo, eyesRomName, eyesInputInfo, eyesDIPInfo, + eyesInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Eyes (Techstar) + +static struct BurnRomInfo eyes2RomDesc[] = { + { "g38201.7d", 0x1000, 0x2cda7185, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "g38202.7e", 0x1000, 0xb9fe4f59, 1 | BRF_ESS | BRF_PRG }, // 1 + { "g38203.7f", 0x1000, 0xd618ba66, 1 | BRF_ESS | BRF_PRG }, // 2 + { "g38204.7h", 0x1000, 0xcf038276, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "g38205.5d", 0x1000, 0x03b1b4c7, 2 | BRF_GRA }, // 4 Graphics + { "e5", 0x1000, 0xa42b5201, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "82s129.4a", 0x0100, 0xd8d78829, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(eyes2); +STD_ROM_FN(eyes2); + +struct BurnDriver BurnDrveyes2 = { + "eyes2", "eyes", NULL, "1982", + "Eyes (Techstar)\0", NULL, "Techstar (Rock-ola license)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, eyes2RomInfo, eyes2RomName, eyesInputInfo, eyesDIPInfo, + eyesInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Eyes (Zaccaria) + +static struct BurnRomInfo eyeszacRomDesc[] = { + { "1.bin", 0x0800, 0xa4a9d7a0, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "5.bin", 0x0800, 0xc32b3f73, 1 | BRF_ESS | BRF_PRG }, // 1 + { "2.bin", 0x0800, 0x195b9473, 1 | BRF_ESS | BRF_PRG }, // 2 + { "6.bin", 0x0800, 0x292886cb, 1 | BRF_ESS | BRF_PRG }, // 3 + { "3.bin", 0x0800, 0xff94b015, 1 | BRF_ESS | BRF_PRG }, // 4 + { "7.bin", 0x0800, 0x9271c58c, 1 | BRF_ESS | BRF_PRG }, // 5 + { "4.bin", 0x0800, 0x965cf32b, 1 | BRF_ESS | BRF_PRG }, // 6 + { "8.bin", 0x0800, 0xc254e92e, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "x.bin", 0x0800, 0x59dce22e, 2 | BRF_GRA }, // 8 Graphics + { "c.bin", 0x0800, 0xaaa7a537, 2 | BRF_GRA }, // 9 + { "b.bin", 0x0800, 0x1969792b, 2 | BRF_GRA }, // 10 + { "p.bin", 0x0800, 0x99af4b30, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "82s129.4a", 0x0100, 0xd8d78829, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) + + { "11.bin", 0x0800, 0x69c1602a, 0 | BRF_PRG }, // 16 (Not used) +}; + +STD_ROM_PICK(eyeszac); +STD_ROM_FN(eyeszac); + +struct BurnDriver BurnDrveyeszac = { + "eyeszac", "eyes", NULL, "1982", + "Eyes (Zaccaria)\0", NULL, "Zaccaria / bootleg", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, eyeszacRomInfo, eyeszacRomName, eyesInputInfo, eyesDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Mr. TNT + +static struct BurnRomInfo mrtntRomDesc[] = { + { "tnt.1", 0x1000, 0x0e836586, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "tnt.2", 0x1000, 0x779c4c5b, 1 | BRF_ESS | BRF_PRG }, // 1 + { "tnt.3", 0x1000, 0xad6fc688, 1 | BRF_ESS | BRF_PRG }, // 2 + { "tnt.4", 0x1000, 0xd77557b3, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "tnt.5", 0x1000, 0x3038cc0e, 2 | BRF_GRA }, // 4 Graphics + { "tnt.6", 0x1000, 0x97634d8b, 2 | BRF_GRA }, // 5 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 6 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 7 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 8 Timing Prom (not used) +}; + +STD_ROM_PICK(mrtnt); +STD_ROM_FN(mrtnt); + +struct BurnDriver BurnDrvmrtnt = { + "mrtnt", NULL, NULL, "1982", + "Mr. TNT\0", NULL, "Telko", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, mrtntRomInfo, mrtntRomName, eyesInputInfo, mrtntDIPInfo, + eyesInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Gorkans + +static struct BurnRomInfo gorkansRomDesc[] = { + { "gorkans8.rom", 0x0800, 0x55100b18, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "gorkans4.rom", 0x0800, 0xb5c604bf, 1 | BRF_ESS | BRF_PRG }, // 1 + { "gorkans7.rom", 0x0800, 0xb8c6def4, 1 | BRF_ESS | BRF_PRG }, // 2 + { "gorkans3.rom", 0x0800, 0x4602c840, 1 | BRF_ESS | BRF_PRG }, // 3 + { "gorkans6.rom", 0x0800, 0x21412a62, 1 | BRF_ESS | BRF_PRG }, // 4 + { "gorkans2.rom", 0x0800, 0xa013310b, 1 | BRF_ESS | BRF_PRG }, // 5 + { "gorkans5.rom", 0x0800, 0x122969b2, 1 | BRF_ESS | BRF_PRG }, // 6 + { "gorkans1.rom", 0x0800, 0xf2524b11, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "gorkgfx4.rom", 0x0800, 0x39cd0dbc, 2 | BRF_GRA }, // 8 Graphics + { "gorkgfx2.rom", 0x0800, 0x33d52535, 2 | BRF_GRA }, // 9 + { "gorkgfx3.rom", 0x0800, 0x4b6b7970, 2 | BRF_GRA }, // 10 + { "gorkgfx1.rom", 0x0800, 0xed70bb3c, 2 | BRF_GRA }, // 11 + + { "gorkprom.4", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "gorkprom.1", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 13 + + { "gorkprom.3", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "gorkprom.2", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(gorkans); +STD_ROM_FN(gorkans); + +struct BurnDriver BurnDrvgorkans = { + "gorkans", "mrtnt", NULL, "1983", + "Gorkans\0", NULL, "Techstar", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, gorkansRomInfo, gorkansRomName, eyesInputInfo, mrtntDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Eggor + +static struct BurnRomInfo eggorRomDesc[] = { + { "1.bin", 0x0800, 0x818ed154, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "5.bin", 0x0800, 0xa4b21d93, 1 | BRF_ESS | BRF_PRG }, // 1 + { "2.bin", 0x0800, 0x5d7a23ed, 1 | BRF_ESS | BRF_PRG }, // 2 + { "6.bin", 0x0800, 0xe9dbca8d, 1 | BRF_ESS | BRF_PRG }, // 3 + { "3.bin", 0x0800, 0x4318ab85, 1 | BRF_ESS | BRF_PRG }, // 4 + { "7.bin", 0x0800, 0x03214d7f, 1 | BRF_ESS | BRF_PRG }, // 5 + { "4.bin", 0x0800, 0xdc805be4, 1 | BRF_ESS | BRF_PRG }, // 6 + { "8.bin", 0x0800, 0xf9ae204b, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "9.bin", 0x0800, 0x96ad8626, 2 | BRF_GRA }, // 8 Graphics + { "11.bin", 0x0800, 0xcc324017, 2 | BRF_GRA }, // 9 + { "10.bin", 0x0800, 0x7c97f513, 2 | BRF_GRA }, // 10 + { "12.bin", 0x0800, 0x2e930602, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(eggor); +STD_ROM_FN(eggor); + +struct BurnDriver BurnDrveggor = { + "eggor", NULL, NULL, "1982", + "Eggor\0", NULL, "Telko", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, eggorRomInfo, eggorRomName, eyesInputInfo, mrtntDIPInfo, + eyesInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + + +// Piranha + +static struct BurnRomInfo piranhaRomDesc[] = { + { "pir1.bin", 0x0800, 0x69a3e6ea, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pir5.bin", 0x0800, 0x245e753f, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pir2.bin", 0x0800, 0x62cb6954, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pir6.bin", 0x0800, 0xcb0700bc, 1 | BRF_ESS | BRF_PRG }, // 3 + { "pir3.bin", 0x0800, 0x843fbfe5, 1 | BRF_ESS | BRF_PRG }, // 4 + { "pir7.bin", 0x0800, 0x73084d5e, 1 | BRF_ESS | BRF_PRG }, // 5 + { "pir4.bin", 0x0800, 0x4cdf6704, 1 | BRF_ESS | BRF_PRG }, // 6 + { "pir8.bin", 0x0800, 0xb86fedb3, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "pir9.bin", 0x0800, 0x0f19eb28, 2 | BRF_GRA }, // 8 Graphics + { "pir11.bin", 0x0800, 0x5f8bdabe, 2 | BRF_GRA }, // 9 + { "pir10.bin", 0x0800, 0xd19399fb, 2 | BRF_GRA }, // 10 + { "pir12.bin", 0x0800, 0xcfb4403d, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Prom + { "piranha.4a", 0x0100, 0x08c9447b, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(piranha); +STD_ROM_FN(piranha); + +static int piranhaInit() +{ + piranha = 1; + + return eyesInit(); +} + +struct BurnDriver BurnDrvpiranha = { + "piranha", "puckman", NULL, "1981", + "Piranha\0", NULL, "GL (US Billiards License)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, piranhaRomInfo, piranhaRomName, DrvInputInfo, mspacmanDIPInfo, + piranhaInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Piranha (older) + +static struct BurnRomInfo piranhaoRomDesc[] = { + { "p1.bin", 0x0800, 0xc6ce1bfc, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "p5.bin", 0x0800, 0xa2655a33, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pir2.bin", 0x0800, 0x62cb6954, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pir6.bin", 0x0800, 0xcb0700bc, 1 | BRF_ESS | BRF_PRG }, // 3 + { "pir3.bin", 0x0800, 0x843fbfe5, 1 | BRF_ESS | BRF_PRG }, // 4 + { "pir7.bin", 0x0800, 0x73084d5e, 1 | BRF_ESS | BRF_PRG }, // 5 + { "p4.bin", 0x0800, 0x9363a4d1, 1 | BRF_ESS | BRF_PRG }, // 6 + { "p8.bin", 0x0800, 0x2769979c, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "p9.bin", 0x0800, 0x94eb7563, 2 | BRF_GRA }, // 8 Graphics + { "p11.bin", 0x0800, 0xa3606973, 2 | BRF_GRA }, // 9 + { "p10.bin", 0x0800, 0x84165a2c, 2 | BRF_GRA }, // 10 + { "p12.bin", 0x0800, 0x2699ba9e, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "piranha.4a", 0x0100, 0x08c9447b, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(piranhao); +STD_ROM_FN(piranhao); + +struct BurnDriver BurnDrvpiranhao = { + "piranhao", "puckman", NULL, "1981", + "Piranha (older)\0", NULL, "GL (US Billiards License)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, piranhaoRomInfo, piranhaoRomName, DrvInputInfo, mspacmanDIPInfo, + piranhaInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Piranha (hack) + +static struct BurnRomInfo piranhahRomDesc[] = { + { "pr1.cpu", 0x1000, 0xbc5ad024, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "pacman.6f", 0x1000, 0x1a6fb2d4, 1 | BRF_ESS | BRF_PRG }, // 1 + { "pr3.cpu", 0x1000, 0x473c379d, 1 | BRF_ESS | BRF_PRG }, // 2 + { "pr4.cpu", 0x1000, 0x63fbf895, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "pr5.cpu", 0x0800, 0x3fc4030c, 2 | BRF_GRA }, // 4 Graphics + { "pr7.cpu", 0x0800, 0x30b9a010, 2 | BRF_GRA }, // 5 + { "pr6.cpu", 0x0800, 0xf3e9c9d5, 2 | BRF_GRA }, // 6 + { "pr8.cpu", 0x0800, 0x133d720d, 2 | BRF_GRA }, // 7 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 8 Color Prom + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 9 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 10 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 11 Timing Prom (not used) +}; + +STD_ROM_PICK(piranhah); +STD_ROM_FN(piranhah); + +struct BurnDriver BurnDrvpiranhah = { + "piranhah", "puckman", NULL, "1981", + "Piranha (hack)\0", NULL, "hack", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, piranhahRomInfo, piranhahRomName, DrvInputInfo, mspacmanDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Abscam + +static struct BurnRomInfo abscamRomDesc[] = { + { "as0.bin", 0x0800, 0x0b102302, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "as4.bin", 0x0800, 0x3116a8ec, 1 | BRF_ESS | BRF_PRG }, // 1 + { "as1.bin", 0x0800, 0xbc0281e0, 1 | BRF_ESS | BRF_PRG }, // 2 + { "as5.bin", 0x0800, 0x428ee2e8, 1 | BRF_ESS | BRF_PRG }, // 3 + { "as2.bin", 0x0800, 0xe05d46ad, 1 | BRF_ESS | BRF_PRG }, // 4 + { "as6.bin", 0x0800, 0x3ae9a8cb, 1 | BRF_ESS | BRF_PRG }, // 5 + { "as3.bin", 0x0800, 0xb39eb940, 1 | BRF_ESS | BRF_PRG }, // 6 + { "as7.bin", 0x0800, 0x16cf1c67, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "as8.bin", 0x0800, 0x61daabe5, 2 | BRF_GRA }, // 8 Graphics + { "as10.bin", 0x0800, 0x81d50c98, 2 | BRF_GRA }, // 9 + { "as9.bin", 0x0800, 0xa3bd1613, 2 | BRF_GRA }, // 10 + { "as11.bin", 0x0800, 0x9d802b68, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "as4a.bin", 0x0100, 0x1605b324, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(abscam); +STD_ROM_FN(abscam); + +struct BurnDriver BurnDrvabscam = { + "abscam", "puckman", NULL, "1981", + "Abscam\0", NULL, "GL (US Billiards License)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, abscamRomInfo, abscamRomName, DrvInputInfo, mspacmanDIPInfo, + piranhaInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Jump Shot + +static struct BurnRomInfo jumpshotRomDesc[] = { + { "6e", 0x1000, 0xf00def9a, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "6f", 0x1000, 0xf70deae2, 1 | BRF_ESS | BRF_PRG }, // 1 + { "6h", 0x1000, 0x894d6f68, 1 | BRF_ESS | BRF_PRG }, // 2 + { "6j", 0x1000, 0xf15a108a, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "5e", 0x1000, 0xd9fa90f5, 2 | BRF_GRA }, // 4 Graphics + { "5f", 0x1000, 0x2ec711c1, 2 | BRF_GRA }, // 5 + + { "prom.7f", 0x0020, 0x872b42f3, 3 | BRF_GRA }, // 6 Color Prom + { "prom.4a", 0x0100, 0x0399f39f, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(jumpshot); +STD_ROM_FN(jumpshot); + +static unsigned char jumpshot_decrypt(int addr, unsigned char e) +{ + static const unsigned char swap_xor_table[6][9] = + { + { 7,6,5,4,3,2,1,0, 0x00 }, + { 7,6,3,4,5,2,1,0, 0x20 }, + { 5,0,4,3,7,1,2,6, 0xa4 }, + { 5,0,4,3,7,1,2,6, 0x8c }, + { 2,3,1,7,4,6,0,5, 0x6e }, + { 2,3,4,7,1,6,0,5, 0x4e } + }; + static const int picktable[32] = + { + 0,2,4,4,4,2,0,2,2,0,2,4,4,2,0,2, + 5,3,5,1,5,3,5,3,1,5,1,5,5,3,5,3 + }; + int method = 0; + const unsigned char *tbl; + + // pick method from bits 0 2 5 7 9 of the address + method = picktable[ + (addr & 0x001) | + ((addr & 0x004) >> 1) | + ((addr & 0x020) >> 3) | + ((addr & 0x080) >> 4) | + ((addr & 0x200) >> 5)]; + + // switch method if bit 11 of the address is set + if ((addr & 0x800) == 0x800) + method ^= 1; + + tbl = swap_xor_table[method]; + return BITSWAP08(e,tbl[0],tbl[1],tbl[2],tbl[3],tbl[4],tbl[5],tbl[6],tbl[7]) ^ tbl[8]; +} + + +void jumpshot_decode() +{ + for (int i = 0; i < 0x4000; i++) + { + Rom[i] = jumpshot_decrypt(i, Rom[i]); + } +} + +static int jumpshotInit() +{ + pPacInitCallback = jumpshot_decode; + + return DrvInit(); +} + +struct BurnDriver BurnDrvjumpshot = { + "jumpshot", NULL, NULL, "1985", + "Jump Shot\0", NULL, "Bally Midway", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, jumpshotRomInfo, jumpshotRomName, jumpshotInputInfo, jumpshotDIPInfo, + jumpshotInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Jump Shot Engineering Sample + +static struct BurnRomInfo jumpshtpRomDesc[] = { + { "js6e.bin", 0x1000, 0xacc5e15e, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "js6f.bin", 0x1000, 0x62b48ba4, 1 | BRF_ESS | BRF_PRG }, // 1 + { "js6h.bin", 0x1000, 0x7c9b5e30, 1 | BRF_ESS | BRF_PRG }, // 2 + { "js6j.bin", 0x1000, 0x9f0c39f6, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "5e", 0x1000, 0xd9fa90f5, 2 | BRF_GRA }, // 4 Graphics + { "5f", 0x1000, 0x2ec711c1, 2 | BRF_GRA }, // 5 + + { "prom.7f", 0x0020, 0x872b42f3, 3 | BRF_GRA }, // 6 Color Proms + { "prom.4a", 0x0100, 0x0399f39f, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(jumpshtp); +STD_ROM_FN(jumpshtp); + +struct BurnDriver BurnDrvjumpshtp = { + "jumpshtp", "jumpshot", NULL, "1985", + "Jump Shot Engineering Sample\0", NULL, "Bally Midway", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, jumpshtpRomInfo, jumpshtpRomName, jumpshotInputInfo, jumpshtpDIPInfo, + jumpshotInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Shoot the Bull + +static struct BurnRomInfo shootbulRomDesc[] = { + { "sb6e.cpu", 0x1000, 0x25daa5e9, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "sb6f.cpu", 0x1000, 0x92144044, 1 | BRF_ESS | BRF_PRG }, // 1 + { "sb6h.cpu", 0x1000, 0x43b7f99d, 1 | BRF_ESS | BRF_PRG }, // 2 + { "sb6j.cpu", 0x1000, 0xbc4d3bbf, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "sb5e.cpu", 0x1000, 0x07c6c5aa, 2 | BRF_GRA }, // 4 Graphics + { "sb5f.cpu", 0x1000, 0xeaec6837, 2 | BRF_GRA }, // 5 + + { "7f.rom", 0x0020, 0xec578b98, 3 | BRF_GRA }, // 6 Color Proms + { "4a.rom", 0x0100, 0x81a6b30f, 3 | BRF_GRA }, // 7 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 8 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 9 Timing Prom (not used) +}; + +STD_ROM_PICK(shootbul); +STD_ROM_FN(shootbul); + +static int shootbulInit() +{ + shootbul = 1; + + return jumpshotInit(); +} + +struct BurnDriver BurnDrvshootbul = { + "shootbul", NULL, NULL, "1985", + "Shoot the Bull\0", NULL, "Bally Midway", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, shootbulRomInfo, shootbulRomName, shootbulInputInfo, shootbulDIPInfo, + shootbulInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Cannon Ball (Pacman Hardware) + +static struct BurnRomInfo cannonbpRomDesc[] = { + { "n1-6e", 0x0800, 0xc68878c7, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "n2-6k", 0x0800, 0xff3951a5, 1 | BRF_ESS | BRF_PRG }, // 1 + { "n3-6f", 0x0800, 0x2329079d, 1 | BRF_ESS | BRF_PRG }, // 2 + { "n4-6m", 0x0800, 0xfcc57ecb, 1 | BRF_ESS | BRF_PRG }, // 3 + { "n5-6h", 0x0800, 0x52846c9d, 1 | BRF_ESS | BRF_PRG }, // 4 + { "n6-6n", 0x0800, 0x59e890dd, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "z1-5e", 0x0800, 0x125779e0, 2 | BRF_GRA }, // 6 Graphics + { "z3-5h", 0x0800, 0x78f866c0, 2 | BRF_GRA }, // 7 + { "z2-5f", 0x0800, 0xfbd2c99d, 2 | BRF_GRA }, // 8 + { "z4-5j", 0x0800, 0x8734c904, 2 | BRF_GRA }, // 9 + + { "colorprom_1", 0x0020, 0x08f8ae7e, 3 | BRF_GRA }, // 10 Color Proms + { "colorprom_2", 0x0100, 0x359a15dc, 3 | BRF_GRA }, // 11 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 12 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 13 Timing Prom (not used) +}; + +STD_ROM_PICK(cannonbp); +STD_ROM_FN(cannonbp); + +static unsigned char cannonbp_protection_r(unsigned short offset) +{ + switch (offset) + { + case 0x0000: // unknown + case 0x0003: // unknown + case 0x0012: // unknown + return 0x00; + + case 0x0004: + cannonb_bit_to_read = 7; + return 0x00; + + case 0x0001: // affects the ball hitting the blocks as well as jump address after bonus round + if (ZetPc(-1) == 0x2b97) + return ((0x46 >> (cannonb_bit_to_read--)) & 1) << 7; + else + return 0xff; + + case 0x0105: // player start x position -> register L + return 0x00; + + case 0x0107: // player start y position -> register H + return 0x40; + } + + return 0; +} + +static int cannonbpInit() +{ + cannonbp = 1; + + return DrvInit(); +} + +struct BurnDriver BurnDrvcannonbp = { + "cannonbp", NULL, NULL, "198?", + "Cannon Ball (Pacman Hardware)\0", "wrong colors", "Novomatic", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, cannonbpRomInfo, cannonbpRomName, cannonbpInputInfo, cannonbpDIPInfo, + cannonbpInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Woodpecker (set 1) + +static struct BurnRomInfo woodpekRomDesc[] = { + { "f.bin", 0x1000, 0x37ea66ca, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "i.bin", 0x1000, 0xcd115dba, 1 | BRF_ESS | BRF_PRG }, // 1 + { "e.bin", 0x1000, 0xd40b2321, 1 | BRF_ESS | BRF_PRG }, // 2 + { "g.bin", 0x1000, 0x024092f4, 1 | BRF_ESS | BRF_PRG }, // 3 + { "h.bin", 0x1000, 0x18ef0fc8, 1 | BRF_ESS | BRF_PRG }, // 4 + + { "a.5e", 0x0800, 0x15a87f62, 2 | BRF_GRA }, // 5 Graphics + { "c.5h", 0x0800, 0xab4abd88, 2 | BRF_GRA }, // 6 + { "b.5f", 0x0800, 0x5b9ba95b, 2 | BRF_GRA }, // 7 + { "d.5j", 0x0800, 0xd7b80a45, 2 | BRF_GRA }, // 8 + + { "pr.8h", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 9 Color Prom + { "pr.4a", 0x0100, 0xd8772167, 3 | BRF_GRA }, // 10 + + { "pr.1k", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 11 Sound Prom + { "pr.3k", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 12 Timing Prom (not used) +}; + +STD_ROM_PICK(woodpek); +STD_ROM_FN(woodpek); + +static void woodpekCallback() +{ + memcpy (Rom + 0xb000, Rom + 0x8000, 0x1000); + memcpy (Rom + 0x8000, Rom + 0x1000, 0x3000); + + memset (Rom + 0x1000, 0, 0x3000); + + for (int i = 0; i < 0x2000; i += 8) + eyes_gfx_decode(Gfx + i); +} + +static int woodpekInit() +{ + pPacInitCallback = woodpekCallback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvwoodpek = { + "woodpek", NULL, NULL, "1981", + "Woodpecker (set 1)\0", NULL, "Amenip (Palcom Queen River)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, woodpekRomInfo, woodpekRomName, woodpekInputInfo, woodpekDIPInfo, + woodpekInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Woodpecker (set 2) + +static struct BurnRomInfo woodpekaRomDesc[] = { + { "0", 0x1000, 0xb5ee8bca, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "1", 0x1000, 0, 1 | BRF_PRG | BRF_ESS | BRF_NODUMP }, // 1 + { "2", 0x1000, 0x07ea534e, 1 | BRF_PRG | BRF_ESS }, // 2 + { "3", 0x1000, 0xa3a3253a, 1 | BRF_PRG | BRF_ESS }, // 3 + { "4", 0x1000, 0x6c50546b, 1 | BRF_PRG | BRF_ESS }, // 4 + + { "10.5f", 0x1000, 0x0bf52102, 2 | BRF_GRA }, // 5 Graphics + { "11.5h", 0x1000, 0x0ed8def8, 2 | BRF_GRA }, // 6 + + { "pr.8h", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 7 Color Proms + { "pr.4a", 0x0100, 0xd8772167, 3 | BRF_GRA }, // 8 + + { "pr.1k", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 9 + { "pr.3k", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 10 Timing Prom (not used) +}; + +STD_ROM_PICK(woodpeka); +STD_ROM_FN(woodpeka); + +struct BurnDriverD BurnDrvwoodpeka = { + "woodpeka", "woodpek", NULL, "1981", + "Woodpecker (set 2)\0", NULL, "Amenip (Palcom Queen River)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, woodpekaRomInfo, woodpekaRomName, woodpekInputInfo, woodpekDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Lizard Wizard + +static struct BurnRomInfo lizwizRomDesc[] = { + { "6e.cpu", 0x1000, 0x32bc1990, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "6f.cpu", 0x1000, 0xef24b414, 1 | BRF_ESS | BRF_PRG }, // 1 + { "6h.cpu", 0x1000, 0x30bed83d, 1 | BRF_ESS | BRF_PRG }, // 2 + { "6j.cpu", 0x1000, 0xdd09baeb, 1 | BRF_ESS | BRF_PRG }, // 3 + { "wiza", 0x1000, 0xf6dea3a6, 1 | BRF_ESS | BRF_PRG }, // 4 + { "wizb", 0x1000, 0xf27fb5a8, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "5e.cpu", 0x1000, 0x45059e73, 2 | BRF_GRA }, // 6 Graphics + { "5f.cpu", 0x1000, 0xd2469717, 2 | BRF_GRA }, // 7 + + { "7f.cpu", 0x0020, 0x7549a947, 3 | BRF_GRA }, // 8 Color Proms + { "4a.cpu", 0x0100, 0x5fdca536, 3 | BRF_GRA }, // 9 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 10 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 11 Timing Prom (not used) +}; + +STD_ROM_PICK(lizwiz); +STD_ROM_FN(lizwiz); + +struct BurnDriver BurnDrvlizwiz = { + "lizwiz", NULL, NULL, "1985", + "Lizard Wizard\0", NULL, "Techstar (Sunn license)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, lizwizRomInfo, lizwizRomName, DrvInputInfo, lizwizDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Ponpoko + +static struct BurnRomInfo ponpokoRomDesc[] = { + { "ppokoj1.bin", 0x1000, 0xffa3c004, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "ppokoj2.bin", 0x1000, 0x4a496866, 1 | BRF_ESS | BRF_PRG }, // 1 + { "ppokoj3.bin", 0x1000, 0x17da6ca3, 1 | BRF_ESS | BRF_PRG }, // 2 + { "ppokoj4.bin", 0x1000, 0x9d39a565, 1 | BRF_ESS | BRF_PRG }, // 3 + { "ppoko5.bin", 0x1000, 0x54ca3d7d, 1 | BRF_ESS | BRF_PRG }, // 4 + { "ppoko6.bin", 0x1000, 0x3055c7e0, 1 | BRF_ESS | BRF_PRG }, // 5 + { "ppoko7.bin", 0x1000, 0x3cbe47ca, 1 | BRF_ESS | BRF_PRG }, // 6 + { "ppokoj8.bin", 0x1000, 0x04b63fc6, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "ppoko9.bin", 0x1000, 0xb73e1a06, 2 | BRF_GRA }, // 8 Graphics + { "ppoko10.bin", 0x1000, 0x62069b5d, 2 | BRF_GRA }, // 9 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 10 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 11 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 12 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 13 Timing Prom (not used) +}; + +STD_ROM_PICK(ponpoko); +STD_ROM_FN(ponpoko); + +static void ponpoko_decode() +{ + // The gfx data is swapped wrt the other Pac-Man hardware games. + // Here we revert it to the usual format. + + // Characters + for (int i = 0;i < 0x1000;i += 0x10) + { + for (int j = 0; j < 8; j++) + { + int t = Gfx[i+j+0x08]; + Gfx[i+j+0x08] = Gfx[i+j+0x00]; + Gfx[i+j+0x00] = t; + } + } + + // Sprites + for (int i = 0x1000;i < 0x2000;i += 0x20) + { + for (int j = 0; j < 8; j++) + { + int t = Gfx[i+j+0x18]; + Gfx[i+j+0x18] = Gfx[i+j+0x10]; + Gfx[i+j+0x10] = Gfx[i+j+0x08]; + Gfx[i+j+0x08] = Gfx[i+j+0x00]; + Gfx[i+j+0x00] = t; + } + } +} + +static int ponpokoInit() +{ + pPacInitCallback = ponpoko_decode; + + return DrvInit(); +} + +struct BurnDriver BurnDrvponpoko = { + "ponpoko", NULL, NULL, "1982", + "Ponpoko\0", NULL, "Sigma Enterprises Inc.", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, ponpokoRomInfo, ponpokoRomName, ponpokoInputInfo, ponpokoDIPInfo, + ponpokoInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 288, 224, 4, 3 +}; + + +// Ponpoko (Venture Line) + +static struct BurnRomInfo ponpokovRomDesc[] = { + { "ppoko1.bin", 0x1000, 0x49077667, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "ppoko2.bin", 0x1000, 0x5101781a, 1 | BRF_ESS | BRF_PRG }, // 1 + { "ppoko3.bin", 0x1000, 0xd790ed22, 1 | BRF_ESS | BRF_PRG }, // 2 + { "ppoko4.bin", 0x1000, 0x4e449069, 1 | BRF_ESS | BRF_PRG }, // 3 + { "ppoko5.bin", 0x1000, 0x54ca3d7d, 1 | BRF_ESS | BRF_PRG }, // 4 + { "ppoko6.bin", 0x1000, 0x3055c7e0, 1 | BRF_ESS | BRF_PRG }, // 5 + { "ppoko7.bin", 0x1000, 0x3cbe47ca, 1 | BRF_ESS | BRF_PRG }, // 6 + { "ppoko8.bin", 0x1000, 0xb39be27d, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "ppoko9.bin", 0x1000, 0xb73e1a06, 2 | BRF_GRA }, // 8 Graphics + { "ppoko10.bin", 0x1000, 0x62069b5d, 2 | BRF_GRA }, // 9 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 10 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 11 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 12 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 13 Timing Prom (not used) +}; + +STD_ROM_PICK(ponpokov); +STD_ROM_FN(ponpokov); + +struct BurnDriver BurnDrvponpokov = { + "ponpokov", "ponpoko", NULL, "1982", + "Ponpoko (Venture Line)\0", NULL, "Sigma Enterprises Inc. (Venture Line license)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, ponpokovRomInfo, ponpokovRomName, ponpokoInputInfo, ponpokoDIPInfo, + ponpokoInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 288, 224, 4, 3 +}; + + +// The Glob (Pac-Man hardware) + +static struct BurnRomInfo theglobpRomDesc[] = { + { "glob.u2", 0x2000, 0x829d0bea, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "glob.u3", 0x2000, 0x31de6628, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "glob.5e", 0x1000, 0x53688260, 2 | BRF_GRA }, // 2 Graphics + { "glob.5f", 0x1000, 0x051f59c7, 2 | BRF_GRA }, // 3 + + { "glob.7f", 0x0020, 0x1f617527, 3 | BRF_GRA }, // 4 Color Proms + { "glob.4a", 0x0100, 0x28faa769, 3 | BRF_GRA }, // 5 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 6 Sound Prom + { "82s126.3m" , 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 7 Timing Prom (not used) +}; + +STD_ROM_PICK(theglobp); +STD_ROM_FN(theglobp); + +static void epos_hardware_set_bank(int nBank) +{ + nBank &= 3; + + nPacBank = nBank; + ZetMapArea(0x0000, 0x3fff, 0, Rom + 0x10000 + (nBank * 0x04000)); + ZetMapArea(0x0000, 0x3fff, 2, Rom + 0x10000 + (nBank * 0x04000)); +} + +static unsigned char epos_hardware_decrypt_rom(unsigned short offset) +{ + if (offset & 0x01) + { + epos_hardware_counter = epos_hardware_counter - 1; + if (epos_hardware_counter < 0) + epos_hardware_counter = 0x0f; + } + else + { + epos_hardware_counter = (epos_hardware_counter + 1) & 0x0f; + } + + if (epos_hardware_counter >= 0x08 && epos_hardware_counter <= 0x0b) { + epos_hardware_set_bank(epos_hardware_counter); + } + + return 0; +} + +static void theglobp_decrypt() +{ + for (int i = 0; i < 0x4000; i++) { + Rom[0x10000 + i] = BITSWAP08(Rom[i] ^ 0xfc, 3, 7, 0, 6, 4, 1, 2, 5); + Rom[0x14000 + i] = BITSWAP08(Rom[i] ^ 0xf6, 1, 7, 0, 3, 4, 6, 2, 5); + Rom[0x18000 + i] = BITSWAP08(Rom[i] ^ 0x7d, 3, 0, 4, 6, 7, 1, 2, 5); + Rom[0x1c000 + i] = BITSWAP08(Rom[i] ^ 0x77, 1, 0, 4, 3, 7, 6, 2, 5); + } +} + +static int theglobpInit() +{ + epos_hardware = 1; + + pPacInitCallback = theglobp_decrypt; + + return DrvInit(); +} + +struct BurnDriver BurnDrvtheglobp = { + "theglobp", "suprglob", NULL, "1983", + "The Glob (Pac-Man hardware)\0", NULL, "Epos Corporation", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, theglobpRomInfo, theglobpRomName, theglobpInputInfo, theglobpDIPInfo, + theglobpInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Super Glob (Pac-Man hardware) + +static struct BurnRomInfo sprglobpRomDesc[] = { + { "glob.u2", 0x2000, 0x829d0bea, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "glob.u3", 0x2000, 0x31de6628, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "5e_2532.dat", 0x1000, 0x1aa16109, 2 | BRF_GRA }, // 2 Graphics + { "5f_2532.dat", 0x1000, 0xafe72a89, 2 | BRF_GRA }, // 3 + + { "glob.7f", 0x0020, 0x1f617527, 3 | BRF_GRA }, // 4 Color Prom + { "glob.4a", 0x0100, 0x28faa769, 3 | BRF_GRA }, // 5 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 6 Sound Prom + { "82s126.3m" , 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 7 Timing Prom (not used) +}; + +STD_ROM_PICK(sprglobp); +STD_ROM_FN(sprglobp); + +struct BurnDriver BurnDrvsprglobp = { + "sprglobp", "suprglob", NULL, "1983", + "Super Glob (Pac-Man hardware)\0", NULL, "Epos Corporation", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, sprglobpRomInfo, sprglobpRomName, theglobpInputInfo, theglobpDIPInfo, + theglobpInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Super Glob (Pac-Man hardware) German + +static struct BurnRomInfo sprglbpgRomDesc[] = { + { "ic8.1", 0x1000, 0xa2df2073, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "ic7.2", 0x1000, 0x3d2c22d9, 1 | BRF_ESS | BRF_PRG }, // 1 + { "ic15.3", 0x1000, 0xa252047f, 1 | BRF_ESS | BRF_PRG }, // 2 + { "ic14.4", 0x1000, 0x7efa81f1, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "ic92.5", 0x2000, 0xE54F484D, 2 | BRF_GRA }, // 4 Graphics + + { "ic78.prm", 0x0020, 0x1f617527, 3 | BRF_GRA }, // 5 Color Prom + { "ic88.prm", 0x0100, 0x28faa769, 3 | BRF_GRA }, // 6 + + { "ic51.prm", 0x0100, 0xc29dea27, 4 | BRF_SND }, // 7 Sound Prom + { "ic70.prm" , 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 8 Timing Prom (not used) +}; + +STD_ROM_PICK(sprglbpg); +STD_ROM_FN(sprglbpg); + +struct BurnDriver BurnDrvsprglbpg = { + "sprglbpg", "suprglob", NULL, "1983", + "Super Glob (Pac-Man hardware) German\0", NULL, "bootleg", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, sprglbpgRomInfo, sprglbpgRomName, theglobpInputInfo, theglobpDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Beastie Feastie + +static struct BurnRomInfo beastfRomDesc[] = { + { "bf-u2.bin", 0x2000, 0x3afc517b, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "bf-u3.bin", 0x2000, 0x8dbd76d0, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "beastf.5e", 0x1000, 0x5654dc34, 2 | BRF_GRA }, // 2 Graphics + { "beastf.5f", 0x1000, 0x1b30ca61, 2 | BRF_GRA }, // 3 + + { "glob.7f", 0x0020, 0x1f617527, 3 | BRF_GRA }, // 4 Color Proms + { "glob.4a", 0x0100, 0x28faa769, 3 | BRF_GRA }, // 5 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 6 Sound Prom + { "82s126.3m" , 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 7 Timing Prom (not used) +}; + +STD_ROM_PICK(beastf); +STD_ROM_FN(beastf); + +struct BurnDriver BurnDrvbeastf = { + "beastf", "suprglob", NULL, "1984", + "Beastie Feastie\0", NULL, "Epos Corporation", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, beastfRomInfo, beastfRomName, theglobpInputInfo, theglobpDIPInfo, + theglobpInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Van-Van Car + +static struct BurnRomInfo vanvanRomDesc[] = { + { "van-1.50", 0x1000, 0xcf1b2df0, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "van-2.51", 0x1000, 0xdf58e1cb, 1 | BRF_ESS | BRF_PRG }, // 1 + { "van-3.52", 0x1000, 0x15571e24, 1 | BRF_ESS | BRF_PRG }, // 2 + { "van-4.53", 0x1000, 0xb724cbe0, 1 | BRF_ESS | BRF_PRG }, // 3 + { "van-5.39", 0x1000, 0xdb67414c, 1 | BRF_ESS | BRF_PRG }, // 4 + + { "van-20.18", 0x1000, 0x60efbe66, 2 | BRF_GRA }, // 5 Graphics + { "van-21.19", 0x1000, 0x5dd53723, 2 | BRF_GRA }, // 6 + + { "6331-1.6", 0x0020, 0xce1d9503, 3 | BRF_GRA }, // 7 Color Proms + { "6301-1.37", 0x0100, 0x4b803d9f, 3 | BRF_GRA }, // 8 + + // uses 2x SN76496 for sound +}; + +STD_ROM_PICK(vanvan); +STD_ROM_FN(vanvan); + +static void vanvanCallback() +{ + memcpy (Rom + 0x9000, Rom + 0x8000, 0x1000); + memcpy (Rom + 0xa000, Rom + 0x8000, 0x1000); + memcpy (Rom + 0xb000, Rom + 0x8000, 0x1000); +} + +static int vanvanInit() +{ + vanvan = 1; + screen_flip = 1; + + pPacInitCallback = vanvanCallback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvvanvan = { + "vanvan", NULL, NULL, "1983", + "Van-Van Car\0", NULL, "Sanritsu", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, vanvanRomInfo, vanvanRomName, vanvanInputInfo, vanvanDIPInfo, + vanvanInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Van-Van Car (Karateco) + +static struct BurnRomInfo vanvankRomDesc[] = { + { "van1.bin", 0x1000, 0x00f48295, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "van-2.51", 0x1000, 0xdf58e1cb, 1 | BRF_ESS | BRF_PRG }, // 1 + { "van-3.52", 0x1000, 0x15571e24, 1 | BRF_ESS | BRF_PRG }, // 2 + { "van4.bin", 0x1000, 0xf8b37ed5, 1 | BRF_ESS | BRF_PRG }, // 3 + { "van5.bin", 0x1000, 0xb8c1e089, 1 | BRF_ESS | BRF_PRG }, // 4 + + { "van-20.18", 0x1000, 0x60efbe66, 2 | BRF_GRA }, // 5 Graphics + { "van-21.19", 0x1000, 0x5dd53723, 2 | BRF_GRA }, // 6 + + { "6331-1.6", 0x0020, 0xce1d9503, 3 | BRF_GRA }, // 7 Color Proms + { "6301-1.37", 0x0100, 0x4b803d9f, 3 | BRF_GRA }, // 8 + + // uses 2x SN76496 for sound +}; + +STD_ROM_PICK(vanvank); +STD_ROM_FN(vanvank); + +struct BurnDriver BurnDrvvanvank = { + "vanvank", "vanvan", NULL, "1983", + "Van-Van Car (Karateco)\0", NULL, "Karateco", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, vanvankRomInfo, vanvankRomName, vanvankInputInfo, vanvanDIPInfo, + vanvanInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Van-Van Car (set 3) + +static struct BurnRomInfo vanvanbRomDesc[] = { + { "vv1.bin", 0x1000, 0xcf1b2df0, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "vv2.bin", 0x1000, 0x80eca6a5, 1 | BRF_ESS | BRF_PRG }, // 1 + { "vv3.bin", 0x1000, 0x15571e24, 1 | BRF_ESS | BRF_PRG }, // 2 + { "vv4.bin", 0x1000, 0xb1f04006, 1 | BRF_ESS | BRF_PRG }, // 3 + { "vv5.bin", 0x1000, 0xdb67414c, 1 | BRF_ESS | BRF_PRG }, // 4 + + { "vv20.bin", 0x1000, 0xeb56cb51, 2 | BRF_GRA }, // 5 Graphics + { "vv21.bin", 0x1000, 0x5dd53723, 2 | BRF_GRA }, // 6 + + { "6331-1.6", 0x0020, 0xce1d9503, 3 | BRF_GRA }, // 7 Color Proms + { "6301-1.37", 0x0100, 0x4b803d9f, 3 | BRF_GRA }, // 8 + + // uses 2x SN76496 for sound +}; + +STD_ROM_PICK(vanvanb); +STD_ROM_FN(vanvanb); + +struct BurnDriver BurnDrvvanvanb = { + "vanvanb", "vanvan", NULL, "1983", + "Van-Van Car (set 3)\0", NULL, "Karateco", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, vanvanbRomInfo, vanvanbRomName, vanvankInputInfo, vanvanDIPInfo, + vanvanInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Naughty Mouse (set 1) + +static struct BurnRomInfo nmouseRomDesc[] = { + { "naumouse.d7", 0x0800, 0xe447ecfa, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "naumouse.d6", 0x0800, 0x2e6f13d9, 1 | BRF_ESS | BRF_PRG }, // 1 + { "naumouse.e7", 0x0800, 0x44a80f97, 1 | BRF_ESS | BRF_PRG }, // 2 + { "naumouse.e6", 0x0800, 0x9c7a46bd, 1 | BRF_ESS | BRF_PRG }, // 3 + { "naumouse.h7", 0x0800, 0x5bc94c5d, 1 | BRF_ESS | BRF_PRG }, // 4 + { "naumouse.h6", 0x0800, 0x1af29e22, 1 | BRF_ESS | BRF_PRG }, // 5 + { "naumouse.j7", 0x0800, 0xcc3be185, 1 | BRF_ESS | BRF_PRG }, // 6 + { "naumouse.j6", 0x0800, 0x66b3e5dc, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "naumouse.d5", 0x0800, 0x2ea7cc3f, 2 | BRF_GRA }, // 8 Graphics + { "naumouse.h5", 0x0800, 0x0511fcea, 2 | BRF_GRA }, // 9 + { "naumouse.e5", 0x0800, 0xf5a627cd, 2 | BRF_GRA }, // 10 + { "naumouse.j5", 0x0800, 0x65f2580e, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "naumouse.a4", 0x0100, 0xd8772167, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(nmouse); +STD_ROM_FN(nmouse); + +static int nmouseInit() +{ + nmouse = 1; + + return eyesInit(); +} + +struct BurnDriver BurnDrvnmouse = { + "nmouse", NULL, NULL, "1981", + "Naughty Mouse (set 1)\0", NULL, "Amenip (Palcom Queen River)", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, nmouseRomInfo, nmouseRomName, DrvInputInfo, nmouseDIPInfo, + nmouseInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Naughty Mouse (set 2) + +static struct BurnRomInfo nmousebRomDesc[] = { + { "naumouse.d7", 0x0800, 0xe447ecfa, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "naumouse.d6", 0x0800, 0x2e6f13d9, 1 | BRF_ESS | BRF_PRG }, // 1 + { "naumouse.e7", 0x0800, 0x44a80f97, 1 | BRF_ESS | BRF_PRG }, // 2 + { "naumouse.e6", 0x0800, 0x9c7a46bd, 1 | BRF_ESS | BRF_PRG }, // 3 + { "snatch2.bin", 0x0800, 0x405aa389, 1 | BRF_ESS | BRF_PRG }, // 4 + { "snatch6.bin", 0x0800, 0xf58e7df4, 1 | BRF_ESS | BRF_PRG }, // 5 + { "snatch3.bin", 0x0800, 0x06fb18ec, 1 | BRF_ESS | BRF_PRG }, // 6 + { "snatch7.bin", 0x0800, 0xd187b82b, 1 | BRF_ESS | BRF_PRG }, // 7 + + { "naumouse.d5", 0x0800, 0x2ea7cc3f, 2 | BRF_GRA }, // 8 Graphics + { "naumouse.h5", 0x0800, 0x0511fcea, 2 | BRF_GRA }, // 9 + { "naumouse.e5", 0x0800, 0xf5a627cd, 2 | BRF_GRA }, // 10 + { "snatch11.bin", 0x0800, 0x330230a5, 2 | BRF_GRA }, // 11 + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 12 Color Proms + { "naumouse.a4", 0x0100, 0xd8772167, 3 | BRF_GRA }, // 13 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 14 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 15 Timing Prom (not used) +}; + +STD_ROM_PICK(nmouseb); +STD_ROM_FN(nmouseb); + +struct BurnDriver BurnDrvnmouseb = { + "nmouseb", "nmouse", NULL, "1981", + "Naughty Mouse (set 2)\0", NULL, "Amenip Nova Games Ltd.", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, nmousebRomInfo, nmousebRomName, DrvInputInfo, nmouseDIPInfo, + nmouseInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Dream Shopper + +static struct BurnRomInfo dremshprRomDesc[] = { + { "red_1.50", 0x1000, 0x830c6361, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "red_2.51", 0x1000, 0xd22551cc, 1 | BRF_ESS | BRF_PRG }, // 1 + { "red_3.52", 0x1000, 0x0713a34a, 1 | BRF_ESS | BRF_PRG }, // 2 + { "red_4.53", 0x1000, 0xf38bcaaa, 1 | BRF_ESS | BRF_PRG }, // 3 + { "red_5.39", 0x1000, 0x6a382267, 1 | BRF_ESS | BRF_PRG }, // 4 + { "red_6.40", 0x1000, 0x4cf8b121, 1 | BRF_ESS | BRF_PRG }, // 5 + { "red_7.41", 0x1000, 0xbd4fc4ba, 1 | BRF_ESS | BRF_PRG }, // 6 + + { "red-20.18", 0x1000, 0x2d6698dc, 2 | BRF_GRA }, // 7 Graphics + { "red-21.19", 0x1000, 0x38c9ce9b, 2 | BRF_GRA }, // 8 + + { "6331-1.6", 0x0020, 0xce1d9503, 3 | BRF_GRA }, // 9 Color Proms + { "6301-1.37", 0x0100, 0x39d6fb5c, 3 | BRF_GRA }, // 10 + + // Uses AY8910 +}; + +STD_ROM_PICK(dremshpr); +STD_ROM_FN(dremshpr); + +static int dremshprInit() +{ + screen_flip = 1; + dremshpr = 1; + + return DrvInit(); +} + +struct BurnDriver BurnDrvdremshpr = { + "dremshpr", NULL, NULL, "1982", + "Dream Shopper\0", NULL, "Sanritsu", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, dremshprRomInfo, dremshprRomName, dremshprInputInfo, dremshprDIPInfo, + dremshprInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Boardwalk Casino + +static struct BurnRomInfo bwcasinoRomDesc[] = { + { "bwc_u2.bin", 0x2000, 0xe2eea868, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "bwc_u3.bin", 0x2000, 0xa935571e, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "bwc_5e.bin", 0x1000, 0xe334c01e, 2 | BRF_GRA }, // 2 Graphics + + { "aca_7f.bin", 0x0020, 0x133bb744, 3 | BRF_GRA }, // 3 Color Proms + { "aca_4a.bin", 0x0100, 0x8e29208f, 3 | BRF_GRA }, // 4 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 5 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 6 Timing Prom (not used) +}; + +STD_ROM_PICK(bwcasino); +STD_ROM_FN(bwcasino); + +static void acitya_decode() +{ + for (int i = 0; i < 0x4000; i++) { + Rom[i + 0x10000] = BITSWAP08(Rom[i] ^ 0xb5, 1, 6, 7, 3, 4, 0, 2, 5); // type 8 + Rom[i + 0x14000] = BITSWAP08(Rom[i] ^ 0xa7, 7, 6, 1, 3, 4, 0, 2, 5); // type 9 + Rom[i + 0x18000] = BITSWAP08(Rom[i] ^ 0xfc, 1, 0, 7, 6, 4, 3, 2, 5); // type a + Rom[i + 0x1c000] = BITSWAP08(Rom[i] ^ 0xee, 7, 0, 1, 6, 4, 3, 2, 5); // type b + } +} + +static int acityaInit() +{ + acitya = 1; + epos_hardware = 1; + + pPacInitCallback = acitya_decode; + + return DrvInit(); +} + +struct BurnDriver BurnDrvbwcasino = { + "bwcasino", NULL, NULL, "1983", + "Boardwalk Casino\0", NULL, "EPOS Corporation", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, bwcasinoRomInfo, bwcasinoRomName, bwcasinoInputInfo, bwcasinoDIPInfo, + acityaInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Atlantic City Action + +static struct BurnRomInfo acityaRomDesc[] = { + { "aca_u2.bin", 0x2000, 0x261c2fdc, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "aca_u3.bin", 0x2000, 0x05fab4ca, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "aca_5e.bin", 0x1000, 0x7f2dd2c9, 2 | BRF_GRA }, // 2 Graphics + + { "aca_7f.bin", 0x0020, 0x133bb744, 3 | BRF_GRA }, // 3 Color Proms + { "aca_4a.bin", 0x0100, 0x8e29208f, 3 | BRF_GRA }, // 4 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 5 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 6 Timing Prom (not used) +}; + +STD_ROM_PICK(acitya); +STD_ROM_FN(acitya); + +struct BurnDriver BurnDrvacitya = { + "acitya", "bwcasino", NULL, "1983", + "Atlantic City Action\0", NULL, "EPOS Corporation", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, acityaRomInfo, acityaRomName, acityaInputInfo, acityaDIPInfo, + acityaInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Big Bucks + +static struct BurnRomInfo bigbucksRomDesc[] = { + { "p.rom", 0x4000, 0xeea6c1c9, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "m.rom", 0x2000, 0xbb8f7363, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "5e.cpu", 0x1000, 0x18442c37, 2 | BRF_GRA }, // 2 Graphics + + { "82s123.7f", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 3 Color Proms + { "82s126.4a", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 4 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 5 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 6 Timing Prom + + { "rom1.rom", 0x8000, 0x90b7785f, 0 | BRF_PRG | BRF_ESS }, // 7 Question Roms + { "rom2.rom", 0x8000, 0x60172d77, 0 | BRF_PRG | BRF_ESS }, // 8 + { "rom3.rom", 0x8000, 0xa2207320, 0 | BRF_PRG | BRF_ESS }, // 9 + { "rom4.rom", 0x8000, 0x5a74c1f9, 0 | BRF_PRG | BRF_ESS }, // 10 + { "rom5.rom", 0x8000, 0x93bc1080, 0 | BRF_PRG | BRF_ESS }, // 11 + { "rom6.rom", 0x8000, 0xeea2423f, 0 | BRF_PRG | BRF_ESS }, // 12 + { "rom7.rom", 0x8000, 0x96694055, 0 | BRF_PRG | BRF_ESS }, // 13 + { "rom8.rom", 0x8000, 0xe68ebf8e, 0 | BRF_PRG | BRF_ESS }, // 14 + { "rom9.rom", 0x8000, 0xfd20921d, 0 | BRF_PRG | BRF_ESS }, // 15 + { "rom10.rom", 0x8000, 0x5091b951, 0 | BRF_PRG | BRF_ESS }, // 16 + { "rom11.rom", 0x8000, 0x705128db, 0 | BRF_PRG | BRF_ESS }, // 17 + { "rom12.rom", 0x8000, 0x74c776e7, 0 | BRF_PRG | BRF_ESS }, // 18 +}; + +STD_ROM_PICK(bigbucks); +STD_ROM_FN(bigbucks); + +static void bigbucksCallback() +{ + QRom = (unsigned char*)malloc(0x60000); + if (QRom == NULL) { + return; + } + + for (int i = 0; i < 12; i++) { + BurnLoadRom(QRom + i * 0x08000, i + 7, 1); + } +} + +static int bigbucksInit() +{ + bigbucks = 1; + nPacBank = 0; + + pPacInitCallback = bigbucksCallback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvbigbucks = { + "bigbucks", NULL, NULL, "1986", + "Big Bucks\0", NULL, "Dynasoft Inc.", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, bigbucksRomInfo, bigbucksRomName, bigbucksInputInfo, bigbucksDIPInfo, + bigbucksInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + + +// MTV Rock-N-Roll Trivia (Part 2) + +static struct BurnRomInfo rocktrv2RomDesc[] = { + { "1.aux", 0x4000, 0xd182947b, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "2.aux", 0x2000, 0x27a7461d, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "5e.cpu", 0x1000, 0x0a6cc43b, 2 | BRF_GRA }, // 2 Graphics + + { "7f.cpu", 0x0020, 0x7549a947, 3 | BRF_GRA }, // 3 Color Proms + { "4a.cpu", 0x0100, 0xddd5d88e, 3 | BRF_GRA }, // 4 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 5 Sound Prom + { "82s126.3m" , 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 6 Timing Prom (not used) + + { "3.aux", 0x4000, 0x5b117ca6, 0 | BRF_PRG | BRF_ESS }, // 7 Question Roms + { "4.aux", 0x4000, 0x81bfd4c3, 0 | BRF_PRG | BRF_ESS }, // 8 + { "5.aux", 0x4000, 0xe976423c, 0 | BRF_PRG | BRF_ESS }, // 9 + { "6.aux", 0x4000, 0x425946bf, 0 | BRF_PRG | BRF_ESS }, // 10 + { "7.aux", 0x4000, 0x7056fc8f, 0 | BRF_PRG | BRF_ESS }, // 11 + { "8.aux", 0x4000, 0x8b86464f, 0 | BRF_PRG | BRF_ESS }, // 12 + { "9.aux", 0x4000, 0x17d8eba4, 0 | BRF_PRG | BRF_ESS }, // 13 + { "10.aux", 0x4000, 0x398c8eb4, 0 | BRF_PRG | BRF_ESS }, // 14 + { "11.aux", 0x4000, 0x7f376424, 0 | BRF_PRG | BRF_ESS }, // 15 + { "12.aux", 0x4000, 0x8d5bbf81, 0 | BRF_PRG | BRF_ESS }, // 16 + { "13.aux", 0x4000, 0x99fe2c21, 0 | BRF_PRG | BRF_ESS }, // 17 + { "14.aux", 0x4000, 0xdf4cf5e7, 0 | BRF_PRG | BRF_ESS }, // 18 + { "15.aux", 0x4000, 0x2a32de26, 0 | BRF_PRG | BRF_ESS }, // 19 + { "16.aux", 0x4000, 0xfcd42187, 0 | BRF_PRG | BRF_ESS }, // 20 + { "17.aux", 0x4000, 0x24d5c388, 0 | BRF_PRG | BRF_ESS }, // 21 + { "18.aux", 0x4000, 0xfeb195fd, 0 | BRF_PRG | BRF_ESS }, // 22 +}; + +STD_ROM_PICK(rocktrv2); +STD_ROM_FN(rocktrv2); + +static void rocktrv2Callback() +{ + QRom = (unsigned char*)malloc(0x40000); + if (QRom == NULL) { + return; + } + + for (int i = 0; i < 16; i++) { + BurnLoadRom(QRom + i * 0x04000, i + 7, 1); + } + + Rom[0x9ffe] = 0xa7; + Rom[0x9fee] = 0x6d; +} + +static int rocktrv2Init() +{ + nPacBank = 0; + rocktrv2 = 1; + + pPacInitCallback = rocktrv2Callback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvrocktrv2 = { + "rocktrv2", NULL, NULL, "1986", + "MTV Rock-N-Roll Trivia (Part 2)\0", NULL, "Triumph Software Inc.", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, rocktrv2RomInfo, rocktrv2RomName, rocktrv2InputInfo, rocktrv2DIPInfo, + rocktrv2Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Ali Baba and 40 Thieves + +static struct BurnRomInfo alibabaRomDesc[] = { + { "6e", 0x1000, 0x38d701aa, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "6f", 0x1000, 0x3d0e35f3, 1 | BRF_ESS | BRF_PRG }, // 1 + { "6h", 0x1000, 0x823bee89, 1 | BRF_ESS | BRF_PRG }, // 2 + { "6k", 0x1000, 0x474d032f, 1 | BRF_ESS | BRF_PRG }, // 3 + { "6l", 0x1000, 0x5ab315c1, 1 | BRF_ESS | BRF_PRG }, // 4 + { "6m", 0x0800, 0x438d0357, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "5e", 0x0800, 0x85bcb8f8, 2 | BRF_GRA }, // 6 Graphics + { "5h", 0x0800, 0x38e50862, 2 | BRF_GRA }, // 7 + { "5f", 0x0800, 0xb5715c86, 2 | BRF_GRA }, // 8 + { "5k", 0x0800, 0x713086b3, 2 | BRF_GRA }, // 9 + + { "82s123.e7", 0x0020, 0x2fc650bd, 3 | BRF_GRA }, // 10 Color Proms + { "82s129.a4", 0x0100, 0x3eb3a8e4, 3 | BRF_GRA }, // 11 + + { "82s126.1m", 0x0100, 0xa9cc86bf, 4 | BRF_SND }, // 12 Sound Prom + { "82s126.3m", 0x0100, 0x77245b66, 0 | BRF_SND | BRF_OPT }, // 13 Timing Prom + + { "7.p6", 0x1000, 0xd8eb7cbd, 0 | BRF_OPT }, // 14 Mystery Rom? (1st & 2nd halves identical) +}; + +STD_ROM_PICK(alibaba); +STD_ROM_FN(alibaba); + +static void alibabaCallback() +{ + memcpy (Rom + 0xa000, Rom + 0x9000, 0x0800); + memset (Rom + 0x9000, 0, 0x800); +} + +static int alibabaInit() +{ + alibaba = 1; + + pPacInitCallback = alibabaCallback; + + return DrvInit(); +} + +struct BurnDriver BurnDrvalibaba = { + "alibaba", NULL, NULL, "1982", + "Ali Baba and 40 Thieves\0", NULL, "Sega", "Pac-man", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, alibabaRomInfo, alibabaRomName, alibabaInputInfo, alibabaDIPInfo, + alibabaInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +//------------------------------------------------------------------------------------------------------ +// S2650-based games (not working) + + +// Driving Force (Pac-Man conversion) + +static struct BurnRomInfo drivfrcpRomDesc[] = { + { "drivforc.1", 0x4000, 0x10b59d27, 1 | BRF_ESS | BRF_PRG }, // 0 S2650 Code + + { "drivforc.2", 0x4000, 0x56331cb5, 2 | BRF_GRA }, // 1 Graphics + + { "drivforc.pr1", 0x0020, 0x045aa47f, 3 | BRF_GRA }, // 2 Color Proms + { "drivforc.pr2", 0x0100, 0x9e6d2f1d, 3 | BRF_GRA }, // 3 + + // Uses SN76496 for audio +}; + +STD_ROM_PICK(drivfrcp); +STD_ROM_FN(drivfrcp); + +static int s2650Init() +{ + return 1; +} + +struct BurnDriverD BurnDrvdrivfrcp = { + "drivfrcp", NULL, NULL, "1984", + "Driving Force (Pac-Man conversion)\0", NULL, "Shinkai Inc. (Magic Eletronics Inc. licence)", "Pac-man", + NULL, NULL, NULL, NULL, + 0, 2, HARDWARE_MISC_PRE90S, + NULL, drivfrcpRomInfo, drivfrcpRomName, DrvInputInfo, NULL, + s2650Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Porky + +static struct BurnRomInfo porkyRomDesc[] = { + { "pp", 0x4000, 0x00592624, 1 | BRF_ESS | BRF_PRG }, // 0 S2650 Code + { "ps", 0x4000, 0x2efb9861, 1 | BRF_ESS | BRF_PRG }, // 1 + + { "pc", 0x4000, 0xa20e3d39, 2 | BRF_GRA }, // 2 Graphics + + { "7f", 0x0020, 0x98bce7cc, 3 | BRF_GRA }, // 3 Color Proms + { "4a", 0x0100, 0x30fe0266, 3 | BRF_GRA }, // 4 + + // Uses SN76496 for audio +}; + +STD_ROM_PICK(porky); +STD_ROM_FN(porky); + +struct BurnDriverD BurnDrvporky = { + "porky", NULL, NULL, "1985", + "Porky\0", NULL, "Shinkai Inc. (Magic Eletronics Inc. licence)", "Pac-man", + NULL, NULL, NULL, NULL, + 0, 2, HARDWARE_MISC_PRE90S, + NULL, porkyRomInfo, porkyRomName, DrvInputInfo, NULL, + s2650Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; + + +// Eight Ball Action (Pac-Man conversion) + +static struct BurnRomInfo bpm8RomDesc[] = { + { "8bpmp.bin", 0x4000, 0xb4f7eba7, 1 | BRF_ESS | BRF_PRG }, // 0 S2650 Code + + { "8bpmc.bin", 0x4000, 0x1c894a6d, 2 | BRF_GRA }, // 1 Graphics + + { "8bpm.7f", 0x0020, 0x4cf54241, 3 | BRF_GRA }, // 2 Color Proms + { "8bpm.4a", 0x0100, 0x618505a0, 3 | BRF_GRA }, // 3 + + // Uses SN76496 for audio +}; + +STD_ROM_PICK(bpm8); +STD_ROM_FN(bpm8); + +struct BurnDriverD BurnDrvbpm8 = { + "8bpm", "8ballact", NULL, "1985", + "Eight Ball Action (Pac-Man conversion)\0", NULL, "Seatongrove Ltd (Magic Eletronics USA licence)", "Pac-man", + NULL, NULL, NULL, NULL, + 0 | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, bpm8RomInfo, bpm8RomName, DrvInputInfo, NULL, + s2650Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 224, 288, 3, 4 +}; diff --git a/src/burn/misc/pre90s/d_pkunwar.cpp b/src/burn/misc/pre90s/d_pkunwar.cpp new file mode 100644 index 0000000..171b920 --- /dev/null +++ b/src/burn/misc/pre90s/d_pkunwar.cpp @@ -0,0 +1,630 @@ +// FB Alpha Penguin-Kun Wars Driver Module +// Based on MAME Driver by David Haywood and Phil Stroffolino + +#include "tiles_generic.h" +#include "driver.h" +extern "C" { + #include "ay8910.h" +} + + +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvDips, DrvReset; +static short *pAY8910Buffer[6], *pFMBuffer = NULL; +static unsigned char *Mem, *Rom, *Gfx0, *Gfx1; +static int *Palette; + +static int flipscreen, vblank; + + +//------------------------------------------------------------------------------------------------- +// Input Handlers + + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy2 + 7, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy1 + 5, "p1 start" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 0, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 1, "p1 right" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 2, "p1 fire 1"}, + + {"P2 start" , BIT_DIGITAL , DrvJoy2 + 5, "p2 start" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 0, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 1, "p2 right" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 2, "p2 fire 1"}, + + {"Service Mode", BIT_DIGITAL, DrvJoy2 + 6, "diag" }, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, &DrvDips , "dip" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x0b, 0xff, 0xff, 0xfb, NULL }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x0b, 0x01, 0x03, 0x00, "3C 1C" }, + {0x0b, 0x01, 0x03, 0x02, "2C 1C" }, + {0x0b, 0x01, 0x03, 0x03, "1C 1C" }, + {0x0b, 0x01, 0x03, 0x01, "1C 2C" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0b, 0x01, 0x04, 0x00, "Upright" }, + {0x0b, 0x01, 0x04, 0x04, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x0b, 0x01, 0x08, 0x00, "Off" }, + {0x0b, 0x01, 0x08, 0x08, "On" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x0b, 0x01, 0x30, 0x10, "Easy" }, + {0x0b, 0x01, 0x30, 0x30, "Medium" }, + {0x0b, 0x01, 0x30, 0x20, "Hard" }, + {0x0b, 0x01, 0x30, 0x00, "Hardest" }, + + {0 , 0xfe, 0 , 2 , "Flip screen" }, + {0x0b, 0x01, 0x40, 0x40, "Off" }, + {0x0b, 0x01, 0x40, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Free Play" }, + {0x0b, 0x01, 0x80, 0x80, "Off" }, + {0x0b, 0x01, 0x80, 0x00, "On" }, +}; + +STDDIPINFO(Drv); + + +//------------------------------------------------------------------------------------------------- +// Memory Handlers + + +unsigned char __fastcall pkunwar_read(unsigned short address) +{ + switch (address) + { + case 0xa001: + return AY8910Read(0); + break; + + case 0xa003: + return AY8910Read(1); + break; + } + + return 0; +} + +void __fastcall pkunwar_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0xa000: + AY8910Write(0, 0, data); + break; + + case 0xa001: + AY8910Write(0, 1, data); + break; + + case 0xa002: + AY8910Write(1, 0, data); + break; + + case 0xa003: + AY8910Write(1, 1, data); + break; + } +} + +void __fastcall pkunwar_out(unsigned short address, unsigned char data) +{ + address &= 0xff; + + if (address == 0) flipscreen = data & 1; +} + + +//------------------------------------------------------------------------------------------------- +// AY8910 Ports + + +static unsigned char pkunwar_port_0(unsigned int) +{ + unsigned char ret = 0x7f | (vblank ^= 0x80); + + for (int i = 0; i < 8; i++) { + ret ^= DrvJoy1[i] << i; + } + + return ret; +} + +static unsigned char pkunwar_port_1(unsigned int) +{ + unsigned char ret = 0xff; + + for (int i = 0; i < 8; i++) { + ret ^= DrvJoy2[i] << i; + } + + return ret; +} + +static unsigned char pkunwar_port_2(unsigned int) +{ + return 0xff; +} + +static unsigned char pkunwar_port_3(unsigned int) +{ + return DrvDips; +} + + +//------------------------------------------------------------------------------------------------- +// Initialization Routines + + +static int DrvDoReset() +{ + DrvReset = 0; + + memset (Rom + 0x8000, 0, 0x1000); + memset (Rom + 0xc000, 0, 0x0800); + + flipscreen = 0; + + ZetOpen(0); + ZetReset(); + ZetClose(); + + AY8910Reset(0); + AY8910Reset(1); + + return 0; +} + +static void pkunwar_palette_init(unsigned char *Prom) +{ + for (int i = 0; i < 0x200; i++) + { + int entry; + int intensity,r,g,b; + + if ((i & 0xf) == 1) + { + entry = ((i & 0xf0) >> 4) | ((i & 0x100) >> 4); + } + else + { + entry = ((i & 0x0f) >> 0) | ((i & 0x100) >> 4); + } + + intensity = Prom[entry] & 0x03; + + r = (((Prom[entry] >> 0) & 0x0c) | intensity) * 0x11; + g = (((Prom[entry] >> 2) & 0x0c) | intensity) * 0x11; + b = (((Prom[entry] >> 4) & 0x0c) | intensity) * 0x11; + + Palette[i] = (r << 16) | (g << 8) | b; + } +} + +static void pkunwar_gfx_decode(unsigned char *Gfx) +{ + static int PlaneOffsets[4] = { 0, 1, 2, 3 }; + + static int XOffsets[16] = { + 0x00000, 0x00004, 0x40000, 0x40004, 0x00008, 0x0000c, 0x40008, 0x4000c, + 0x00080, 0x00084, 0x40080, 0x40084, 0x00088, 0x0008c, 0x40088, 0x4008c + }; + + static int YOffsets[16] = { + 0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, + 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160, 0x170 + }; + + GfxDecode(0x800, 4, 8, 8, PlaneOffsets, XOffsets, YOffsets, 0x080, Gfx, Gfx0); + GfxDecode(0x200, 4, 16, 16, PlaneOffsets, XOffsets, YOffsets, 0x200, Gfx, Gfx1); +} + +static int LoadRoms() +{ + unsigned char *tmp = (unsigned char*)malloc(0x10000); + if (tmp == NULL) { + return 1; + } + + if (BurnLoadRom(Rom + 0x0000, 0, 1)) return 1; + if (BurnLoadRom(Rom + 0x4000, 1, 1)) return 1; + if (BurnLoadRom(Rom + 0xe000, 2, 1)) return 1; + + if (BurnLoadRom(Gfx0 + 0x0000, 3, 1)) return 1; + if (BurnLoadRom(Gfx0 + 0x4000, 4, 1)) return 1; + if (BurnLoadRom(Gfx0 + 0x8000, 5, 1)) return 1; + if (BurnLoadRom(Gfx0 + 0xc000, 6, 1)) return 1; + + for (int i = 0; i < 8; i++) { + int j = ((i & 1) << 2) | ((i >> 1) & 3); + memcpy (tmp + j * 0x2000, Gfx0 + i * 0x2000, 0x2000); + } + + pkunwar_gfx_decode(tmp); + + if (BurnLoadRom(tmp + 0x0000, 7, 1)) return 1; + + pkunwar_palette_init(tmp); + + free (tmp); + + return 0; +} + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x10000 + 0x20000 * 2 + 0x200 * sizeof(int)); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short *)malloc (nBurnSoundLen * 6 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + Rom = Mem + 0x00000; + Gfx0 = Mem + 0x10000; + Gfx1 = Mem + 0x30000; + Palette = (int*)(Mem + 0x40000); + + if (LoadRoms()) return 1; + + ZetInit(1); + ZetOpen(0); + ZetSetOutHandler(pkunwar_out); + ZetSetReadHandler(pkunwar_read); + ZetSetWriteHandler(pkunwar_write); + ZetMapArea(0x0000, 0x7fff, 0, Rom + 0x00000); + ZetMapArea(0x0000, 0x7fff, 2, Rom + 0x00000); + ZetMapArea(0x8000, 0x8fff, 0, Rom + 0x08000); + ZetMapArea(0x8000, 0x8fff, 1, Rom + 0x08000); + ZetMapArea(0xc000, 0xc7ff, 0, Rom + 0x0c000); + ZetMapArea(0xc000, 0xc7ff, 1, Rom + 0x0c000); + ZetMapArea(0xc000, 0xc7ff, 2, Rom + 0x0c000); + ZetMapArea(0xe000, 0xffff, 0, Rom + 0x0e000); + ZetMapArea(0xe000, 0xffff, 2, Rom + 0x0e000); + ZetMemEnd(); + ZetClose(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + pAY8910Buffer[3] = pFMBuffer + nBurnSoundLen * 3; + pAY8910Buffer[4] = pFMBuffer + nBurnSoundLen * 4; + pAY8910Buffer[5] = pFMBuffer + nBurnSoundLen * 5; + + AY8910Init(0, 1500000, nBurnSoundRate, &pkunwar_port_0, &pkunwar_port_1, NULL, NULL); + AY8910Init(1, 1500000, nBurnSoundRate, &pkunwar_port_2, &pkunwar_port_3, NULL, NULL); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + AY8910Exit(0); + AY8910Exit(1); + + free (pFMBuffer); + free (Mem); + + Rom = Gfx0 = Gfx1 = Mem = NULL; + Palette = NULL; + + vblank = flipscreen = 0; + + return 0; +} + + +//------------------------------------------------------------------------------------------------- +// Drawing Routines + + +static int DrawChars(int priority) +{ + int offs; + + for (offs = 0x3c0 - 1;offs >= 0x40;offs--) + { + if (Rom[0x8c00 + offs] & 0x08 || !priority) + { + int sx,sy,num,color,pxl,pos; + + sx = (offs & 0x1f) << 3; + sy = (offs >> 2) & 0xf8; + + if (sy < 32 || sy > 223) continue; + sy -= 32; + + num = Rom[0x8800 + offs] | ((Rom[0x8c00 + offs] & 7) << 8); + color = 0x100 | (Rom[0x8c00 + offs] & 0xf0); + + unsigned char *src = Gfx0 + (num << 6); + + for (int y = sy; y < sy + 8; y++) + { + for (int x = sx; x < sx + 8; x++, src++) + { + if (!*src && priority) continue; + + pxl = Palette[color | *src]; + + if (flipscreen) + pos = ((191 - y) << 8) | (~x & 0xff); + else + pos = (y << 8) | (x & 0xff); + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } + } + + return 0; +} + +static int DrvDraw() +{ + int offs; + + DrawChars(0); + + for (offs = 0;offs < 0x800;offs += 32) + { + int sx,sy,flipx,flipy,num,color,pxl,pos; + + sx = Rom[0x8001 + offs]; + sy = Rom[0x8002 + offs]; + + if (sy < 16 || sy > 223) continue; + sy -= 32; + + flipx = Rom[0x8000 + offs] & 0x01; + flipy = Rom[0x8000 + offs] & 0x02; + + num = ((Rom[0x8000 + offs] & 0xfc) >> 2) + ((Rom[0x8003 + offs] & 7) << 6); + color = Rom[0x8003 + offs] & 0xf0; + + unsigned char *src = Gfx1 + (num << 8); + + if (flipy) + { + for (int y = sy + 15; y >= sy; y--) + { + if (flipx) + { + for (int x = sx + 15; x >= sx; x--, src++) + { + if (y > 191 || y < 0 || !*src) continue; + + pxl = Palette[color | *src]; + + if (flipscreen) + pos = ((191 - y) << 8) | (~x & 0xff); + else + pos = (y << 8) | (x & 0xff); + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } else { + for (int x = sx; x < sx + 16; x++, src++) + { + if (y > 191 || y < 0 || !*src) continue; + + pxl = Palette[color | *src]; + + if (flipscreen) + pos = ((191 - y) << 8) | (~x & 0xff); + else + pos = (y << 8) | (x & 0xff); + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } + } else { + for (int y = sy; y < sy + 16; y++) + { + if (flipx) + { + for (int x = sx + 15; x >= sx; x--, src++) + { + if (y > 191 || y < 0 || !*src) continue; + + pxl = Palette[color | *src]; + + if (flipscreen) + pos = ((191 - y) << 8) | (~x & 0xff); + else + pos = (y << 8) | (x & 0xff); + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } else { + for (int x = sx; x < sx + 16; x++, src++) + { + if (y > 191 || y < 0 || !*src) continue; + + pxl = Palette[color | *src]; + + if (flipscreen) + pos = ((191 - y) << 8) | (~x & 0xff); + else + pos = (y << 8) | (x & 0xff); + + PutPix(pBurnDraw + pos * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } + } + } + + DrawChars(1); + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + vblank = 0; + + ZetOpen(0); + ZetRun(3000000 / 60); + ZetRaiseIrq(0); + ZetClose(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +//------------------------------------------------------------------------------------------------- +// Save State + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0x8000; + ba.nLen = 0x1000; + ba.szName = "Video Ram"; + BurnAcb(&ba); + + ba.Data = Rom + 0xc000; + ba.nLen = 0x0800; + ba.szName = "Work Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + + AY8910Scan(nAction, pnMin); + + SCAN_VAR(flipscreen); + } + + return 0; +} + + +//------------------------------------------------------------------------------------------------- +// Game drivers + + +// Penguin-Kun Wars (US) + +static struct BurnRomInfo pkunwarRomDesc[] = { + { "pkwar.01r", 0x4000, 0xce2d2c7b, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "pkwar.02r", 0x4000, 0xabc1f661, 1 | BRF_PRG | BRF_ESS }, // 1 + { "pkwar.03r", 0x2000, 0x56faebea, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "pkwar.01y", 0x4000, 0x428d3b92, 2 | BRF_GRA }, // 3 Graphics + { "pkwar.02y", 0x4000, 0xce1da7bc, 2 | BRF_GRA }, // 4 + { "pkwar.03y", 0x4000, 0x63204400, 2 | BRF_GRA }, // 5 + { "pkwar.04y", 0x4000, 0x061dfca8, 2 | BRF_GRA }, // 6 + + { "pkwar.col", 0x0020, 0xaf0fc5e2, 3 | BRF_GRA }, // 7 Color Prom +}; + +STD_ROM_PICK(pkunwar); +STD_ROM_FN(pkunwar); + +struct BurnDriver BurnDrvpkunwar = { + "pkunwar", NULL, NULL, "1985", + "Penguin-Kun Wars (US)\0", NULL, "UPL", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, pkunwarRomInfo, pkunwarRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 192, 4, 3 +}; + + +// Penguin-Kun Wars (Japan) + +static struct BurnRomInfo pkunwarjRomDesc[] = { + { "pgunwar.6", 0x4000, 0x357f3ef3, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code + { "pgunwar.5", 0x4000, 0x0092e49e, 1 | BRF_PRG | BRF_ESS }, // 1 + { "pkwar.03r", 0x2000, 0x56faebea, 1 | BRF_PRG | BRF_ESS }, // 2 + + { "pkwar.01y", 0x4000, 0x428d3b92, 2 | BRF_GRA }, // 3 Graphics + { "pkwar.02y", 0x4000, 0xce1da7bc, 2 | BRF_GRA }, // 4 + { "pgunwar.2", 0x4000, 0xa2a43443, 2 | BRF_GRA }, // 5 + { "pkwar.04y", 0x4000, 0x061dfca8, 2 | BRF_GRA }, // 6 + + { "pkwar.col", 0x0020, 0xaf0fc5e2, 3 | BRF_GRA }, // 7 Color Prom +}; + +STD_ROM_PICK(pkunwarj); +STD_ROM_FN(pkunwarj); + +struct BurnDriver BurnDrvpkunwarj = { + "pkunwarj", "pkunwar", NULL, "1985", + "Penguin-Kun Wars (Japan)\0", NULL, "UPL", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, pkunwarjRomInfo, pkunwarjRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 192, 4, 3 +}; + diff --git a/src/burn/misc/pre90s/d_pooyan.cpp b/src/burn/misc/pre90s/d_pooyan.cpp new file mode 100644 index 0000000..67eb733 --- /dev/null +++ b/src/burn/misc/pre90s/d_pooyan.cpp @@ -0,0 +1,778 @@ +// FB Alpha Pooyan Driver Module +// Based on MAME driver by Allard van der Bas, Mike Cuddy, Nicola Salmoria, Martin Binder, and Marco Cassili + +#include "tiles_generic.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +static unsigned char *Mem, *MemEnd; +static unsigned char *Rom0, *Rom1, *Gfx0, *Gfx1, *Prom; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvJoy3[8], DrvDips[2], DrvReset; +static unsigned int *Palette, *DrvPalette; +static unsigned char DrvRecalcPalette; + +static short *pFMBuffer; +static short *pAY8910Buffer[6]; + +static unsigned char irqtrigger; +static unsigned char irq_enable; +static unsigned char flipscreen; +static unsigned char soundlatch; + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 0, "p1 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 3, "p1 start" }, + {"P1 Up" , BIT_DIGITAL , DrvJoy2 + 2, "p1 up" }, + {"P1 Down" , BIT_DIGITAL , DrvJoy2 + 3, "p1 down" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p1 fire 1"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy1 + 1, "p2 coin" }, + {"P2 Start" , BIT_DIGITAL , DrvJoy1 + 4, "p2 start" }, + {"P2 Up" , BIT_DIGITAL , DrvJoy3 + 2, "p2 up" }, + {"P2 Down" , BIT_DIGITAL , DrvJoy3 + 3, "p2 down" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy3 + 4, "p2 fire 1"}, + + {"Service" , BIT_DIGITAL , DrvJoy1 + 2, "service" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDips + 1, "dip" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x0c, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 16 , "Coin A" }, + {0x0c, 0x01, 0x0f, 0x02, "4 Coins 1 Credit" }, + {0x0c, 0x01, 0x0f, 0x05, "3 Coins 1 Credit" }, + {0x0c, 0x01, 0x0f, 0x08, "2 Coins 1 Credit" }, + {0x0c, 0x01, 0x0f, 0x04, "3 Coins 2 Credits" }, + {0x0c, 0x01, 0x0f, 0x01, "4 Coins 3 Credits" }, + {0x0c, 0x01, 0x0f, 0x0f, "1 Coin 1 Credit" }, + {0x0c, 0x01, 0x0f, 0x03, "3 Coins 4 Credits" }, + {0x0c, 0x01, 0x0f, 0x07, "2 Coins 3 Credits" }, + {0x0c, 0x01, 0x0f, 0x0e, "1 Coin 2 Credits" }, + {0x0c, 0x01, 0x0f, 0x06, "2 Coins 5 Credits" }, + {0x0c, 0x01, 0x0f, 0x0d, "1 Coin 3 Credits" }, + {0x0c, 0x01, 0x0f, 0x0c, "1 Coin 4 Credits" }, + {0x0c, 0x01, 0x0f, 0x0b, "1 Coin 5 Credits" }, + {0x0c, 0x01, 0x0f, 0x0a, "1 Coin 6 Credits" }, + {0x0c, 0x01, 0x0f, 0x09, "1 Coin 7 Credits" }, + {0x0c, 0x01, 0x0f, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 15 , "Coin B" }, + {0x0c, 0x82, 0xf0, 0x20, "4 Coins 1 Credit" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0x50, "3 Coins 1 Credit" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0x80, "2 Coins 1 Credit" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0x40, "3 Coins 2 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0x10, "4 Coins 3 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0xf0, "1 Coin 1 Credit" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0x30, "3 Coins 4 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0x70, "2 Coins 3 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0xe0, "1 Coin 2 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0x60, "2 Coins 5 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0xd0, "1 Coin 3 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0xc0, "1 Coin 4 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0xb0, "1 Coin 5 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0xa0, "1 Coin 6 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + {0x0c, 0x82, 0xf0, 0x90, "1 Coin 7 Credits" }, + {0x0c, 0x00, 0x0f, 0x00, NULL }, + + // Default Values + {0x0d, 0xff, 0xff, 0x7b, NULL }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0d, 0x01, 0x03, 0x03, "3" }, + {0x0d, 0x01, 0x03, 0x02, "4" }, + {0x0d, 0x01, 0x03, 0x01, "5" }, + {0x0d, 0x01, 0x03, 0x00, "256" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0d, 0x01, 0x04, 0x00, "Upright" }, + {0x0d, 0x01, 0x04, 0x04, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Bonus Life" }, + {0x0d, 0x01, 0x08, 0x08, "50K 80K+" }, + {0x0d, 0x01, 0x08, 0x00, "30K 70K+" }, + + {0 , 0xfe, 0 , 8 , "Difficulty" }, + {0x0d, 0x01, 0x70, 0x70, "1 (Easy)" }, + {0x0d, 0x01, 0x70, 0x60, "2" }, + {0x0d, 0x01, 0x70, 0x50, "3" }, + {0x0d, 0x01, 0x70, 0x40, "4" }, + {0x0d, 0x01, 0x70, 0x30, "5" }, + {0x0d, 0x01, 0x70, 0x20, "6" }, + {0x0d, 0x01, 0x70, 0x10, "7" }, + {0x0d, 0x01, 0x70, 0x00, "8 (Hard)" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x0d, 0x01, 0x80, 0x80, "Off" }, + {0x0d, 0x01, 0x80, 0x00, "On" }, +}; + +STDDIPINFO(Drv); + +unsigned char __fastcall pooyan_cpu0_read(unsigned short address) +{ + unsigned char ret = 0xff; + + switch (address) + { + case 0xa000: + return DrvDips[1]; + + case 0xa080: + { + for (int i = 0; i < 8; i++) { + ret ^= DrvJoy1[i] << i; + } + + return ret; + } + + case 0xa0a0: + { + for (int i = 0; i < 8; i++) { + ret ^= DrvJoy2[i] << i; + } + + return ret; + } + + case 0xa0c0: + { + for (int i = 0; i < 8; i++) { + ret ^= DrvJoy3[i] << i; + } + + return ret; + } + + case 0xa0e0: + return DrvDips[0]; + + } + + return 0; +} + +void __fastcall pooyan_cpu0_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0xa000: + // watchdog + break; + + case 0xa100: + soundlatch = data; + break; + + case 0xa180: + irq_enable = data & 1; + + if (!irq_enable) + ZetSetIRQLine(0, ZET_IRQSTATUS_NONE); + break; + + case 0xa181: + { + if (irqtrigger == 0 && data) { + ZetClose(); + ZetOpen(1); + ZetSetIRQLine(0, ZET_IRQSTATUS_AUTO); + ZetClose(); + ZetOpen(0); + } + + irqtrigger = data; + } + break; + + case 0xa183: + break; + + case 0xa187: + flipscreen = ~data & 1; + break; + } +} + +unsigned char __fastcall pooyan_cpu1_read(unsigned short address) +{ + switch (address & 0xf000) + { + case 0x4000: + return AY8910Read(0); + + case 0x6000: + return AY8910Read(1); + } + + return 0; +} + +void __fastcall pooyan_cpu1_write(unsigned short address, unsigned char data) +{ + switch (address & 0xf000) + { + case 0x4000: + AY8910Write(0, 1, data); + break; + + case 0x5000: + AY8910Write(0, 0, data); + break; + + case 0x6000: + AY8910Write(1, 1, data); + break; + + case 0x7000: + AY8910Write(1, 0, data); + break; + + case 0x8000: + case 0x9000: + case 0xa000: + case 0xb000: + case 0xc000: + case 0xd000: + case 0xe000: + case 0xf000: + // timeplt_filter_w + break; + } +} + +static unsigned char AY8910_0_port0(unsigned int) +{ + return soundlatch; +} + +static unsigned char AY8910_0_port1(unsigned int) +{ + static int timeplt_timer[10] = + { + 0x00, 0x10, 0x20, 0x30, 0x40, 0x90, 0xa0, 0xb0, 0xa0, 0xd0 + }; + + return timeplt_timer[(ZetTotalCycles() >> 9) % 10]; +} + +static int DrvDoReset() +{ + DrvReset = 0; + + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + } + + AY8910Reset(0); + AY8910Reset(1); + + memset (Rom0 + 0x8000, 0, 0x1800); + memset (Rom1 + 0x3000, 0, 0x0400); + + irqtrigger = 0; + flipscreen = 0; + soundlatch = 0; + irq_enable = 0; + + return 0; +} + +static void DrvPaletteInit() +{ + int i; + unsigned int c_pal[0x20]; + + for (i = 0; i < 0x20; i++) + { + int r, g, b; + int bit0, bit1, bit2; + + bit0 = (Prom[i] >> 0) & 0x01; + bit1 = (Prom[i] >> 1) & 0x01; + bit2 = (Prom[i] >> 2) & 0x01; + r = 33 * bit0 + 71 * bit1 + 151 * bit2; + + bit0 = (Prom[i] >> 3) & 0x01; + bit1 = (Prom[i] >> 4) & 0x01; + bit2 = (Prom[i] >> 5) & 0x01; + g = 33 * bit0 + 71 * bit1 + 151 * bit2; + + bit0 = (Prom[i] >> 6) & 0x01; + bit1 = (Prom[i] >> 7) & 0x01; + b = 80 * bit0 + 171 * bit1; + + c_pal[i] = (r << 16) | (g << 8) | b; + } + + for (i = 0; i < 0x100; i++) + { + Palette[i + 0x000] = c_pal[(Prom[i + 0x020] & 0x0f) | 0x10]; + Palette[i + 0x100] = c_pal[(Prom[i + 0x120] & 0x0f) | 0x00]; + } +} + +static int DrvGfxDecode() +{ + unsigned char *tmp = (unsigned char*)malloc(0x2000); + if (!tmp) return 1; + + static int Planes[4] = { 0x8004, 0x8000, 4, 0 }; + static int XOffs[16] = { 0, 1, 2, 3, 0x40, 0x41, 0x42, 0x43, 0x80, 0x81, 0x82, 0x83, 0xc0, 0xc1, 0xc2, 0xc3 }; + static int YOffs[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 256, 264, 272, 280, 288, 296, 304, 312 }; + + memcpy (tmp, Gfx0, 0x2000); + + GfxDecode(0x100, 4, 8, 8, Planes, XOffs, YOffs, 0x080, tmp, Gfx0); + + memcpy (tmp, Gfx1, 0x2000); + + GfxDecode(0x40, 4, 16, 16, Planes, XOffs, YOffs, 0x200, tmp, Gfx1); + + free (tmp); + + return 0; +} + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + Rom0 = Next; Next += 0x10000; + Rom1 = Next; Next += 0x04000; + Gfx0 = Next; Next += 0x04000; + Gfx1 = Next; Next += 0x04000; + Prom = Next; Next += 0x00220; + + Palette = (unsigned int*)Next; Next += 0x00200 * sizeof(unsigned int); + DrvPalette = (unsigned int*)Next; Next += 0x00200 * sizeof(unsigned int); + + pFMBuffer = (short *)Next; Next += nBurnSoundLen * 6 * sizeof(short); + + MemEnd = Next; + + return 0; +} + +static int DrvInit() +{ + int nLen; + + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + pAY8910Buffer[3] = pFMBuffer + nBurnSoundLen * 3; + pAY8910Buffer[4] = pFMBuffer + nBurnSoundLen * 4; + pAY8910Buffer[5] = pFMBuffer + nBurnSoundLen * 5; + + { + for (int i = 0; i < 4; i++) { + if (BurnLoadRom(Rom0 + i * 0x2000, 0 + i, 1)) return 1; + } + + for (int i = 0; i < 2; i++) { + if (BurnLoadRom(Rom1 + i * 0x1000, 4 + i, 1)) return 1; + if (BurnLoadRom(Gfx0 + i * 0x1000, 6 + i, 1)) return 1; + if (BurnLoadRom(Gfx1 + i * 0x1000, 8 + i, 1)) return 1; + } + + if (BurnLoadRom(Prom + 0x000, 10, 1)) return 1; + if (BurnLoadRom(Prom + 0x020, 11, 1)) return 1; + if (BurnLoadRom(Prom + 0x120, 12, 1)) return 1; + + if (DrvGfxDecode()) return 1; + DrvPaletteInit(); + } + + ZetInit(2); + ZetOpen(0); + ZetMapArea(0x0000, 0x7fff, 0, Rom0 + 0x0000); + ZetMapArea(0x0000, 0x7fff, 2, Rom0 + 0x0000); + ZetMapArea(0x8000, 0x8fff, 0, Rom0 + 0x8000); + ZetMapArea(0x8000, 0x8fff, 1, Rom0 + 0x8000); + ZetMapArea(0x8000, 0x8fff, 2, Rom0 + 0x8000); + ZetMapArea(0x9000, 0x90ff, 0, Rom0 + 0x9000); + ZetMapArea(0x9000, 0x90ff, 1, Rom0 + 0x9000); + ZetMapArea(0x9000, 0x90ff, 2, Rom0 + 0x9000); + ZetMapArea(0x9400, 0x94ff, 0, Rom0 + 0x9400); + ZetMapArea(0x9400, 0x94ff, 1, Rom0 + 0x9400); + ZetMapArea(0x9400, 0x94ff, 2, Rom0 + 0x9400); + ZetSetWriteHandler(pooyan_cpu0_write); + ZetSetReadHandler(pooyan_cpu0_read); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetMemEnd(); + ZetMapArea(0x0000, 0x1fff, 0, Rom1 + 0x0000); + ZetMapArea(0x0000, 0x1fff, 2, Rom1 + 0x0000); + ZetMapArea(0x3000, 0x33ff, 0, Rom1 + 0x3000); + ZetMapArea(0x3000, 0x33ff, 1, Rom1 + 0x3000); + ZetMapArea(0x3000, 0x33ff, 2, Rom1 + 0x3000); + ZetSetWriteHandler(pooyan_cpu1_write); + ZetSetReadHandler(pooyan_cpu1_read); + ZetClose(); + + GenericTilesInit(); + + AY8910Init(0, 1789773, nBurnSoundRate, &AY8910_0_port0, &AY8910_0_port1, NULL, NULL); + AY8910Init(1, 1789773, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + AY8910Exit(0); + AY8910Exit(1); + + GenericTilesExit(); + + free (Mem); + + Mem = MemEnd = NULL; + Rom0 = Rom1 = Gfx0 = Gfx1 = Prom = NULL; + + Palette = DrvPalette = NULL; + pFMBuffer = NULL; + + for (int i = 0; i < 6; i++) { + pAY8910Buffer[i] = NULL; + } + + irqtrigger = 0; + irq_enable = 0; + flipscreen = 0; + soundlatch = 0; + + return 0; +} + +static int DrvDraw() +{ + if (DrvRecalcPalette) { + for (int i = 0; i < 0x200; i++) { + unsigned int col = Palette[i]; + DrvPalette[i] = BurnHighCol(col >> 16, col >> 8, col, 0); + } + } + + for (int i = 0; i < 0x0400; i++) + { + int attr = Rom0[0x8000 + i]; + int code = Rom0[0x8400 + i]; + int color = attr & 0x0f; + int flipx = (attr >> 6) & 1; + int flipy = (attr >> 7) & 1; + + int sx = (i << 3) & 0xf8; + int sy = (i >> 2) & 0xf8; + + if (flipscreen) { + sx ^= 0xf8; + sy ^= 0xf8; + flipx ^= 1; + flipy ^= 1; + } + + if (sy > 239 || sy < 16) continue; + sy -= 16; + + if (flipy) { + if (flipx) { + Render8x8Tile_FlipXY(pTransDraw, code, sx, sy, color, 4, 0, Gfx0); + } else { + Render8x8Tile_FlipY(pTransDraw, code, sx, sy, color, 4, 0, Gfx0); + } + } else { + if (flipx) { + Render8x8Tile_FlipX(pTransDraw, code, sx, sy, color, 4, 0, Gfx0); + } else { + Render8x8Tile(pTransDraw, code, sx, sy, color, 4, 0, Gfx0); + } + } + } + + for (int i = 0x10; i < 0x40; i += 2) + { + int sx = Rom0[0x9000 + i]; + int sy = 240 - Rom0[0x9401 + i]; + + int code = Rom0[0x9001 + i] & 0x3f; + int color = (Rom0[0x9400 + i] & 0x0f) | 0x10; + int flipx = ~Rom0[0x9400 + i] & 0x40; + int flipy = Rom0[0x9400 + i] & 0x80; + + if (sy == 0 || sy >= 240) continue; + + sy -= 16; + + if (flipy) { + if (flipx) { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, Gfx1); + } else { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, Gfx1); + } + } else { + if (flipx) { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, Gfx1); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, color, 4, 0, 0, Gfx1); + } + } + } + + BurnTransferCopy(DrvPalette); + + return 0; +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + int nInterleave = 10; + + int nCyclesSegment; + int nCyclesTotal[2], nCyclesDone[2]; + + nCyclesTotal[0] = 3072000 / 60; + nCyclesTotal[1] = 1789773 / 60; + + nCyclesDone[0] = nCyclesDone[1] = 0; + + for (int i = 0; i < nInterleave; i++) + { + int nCurrentCPU, nNext; + + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if (irq_enable && i == (nInterleave - 1)) ZetNmi(); + ZetClose(); + + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + ZetClose(); + } + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom0 + 0x8000; + ba.nLen = 0x1800; + ba.szName = "Cpu #0 Ram"; + BurnAcb(&ba); + + ba.Data = Rom1 + 0x3000; + ba.nLen = 0x0400; + ba.szName = "Cpu #1 Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + AY8910Scan(nAction, pnMin); + + SCAN_VAR(soundlatch); + SCAN_VAR(irqtrigger); + SCAN_VAR(irq_enable); + SCAN_VAR(flipscreen); + } + + return 0; +} + + +// Pooyan + +static struct BurnRomInfo pooyanRomDesc[] = { + { "1.4a", 0x2000, 0xbb319c63, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "2.5a", 0x2000, 0xa1463d98, 1 | BRF_PRG | BRF_ESS }, // 1 + { "3.6a", 0x2000, 0xfe1a9e08, 1 | BRF_PRG | BRF_ESS }, // 2 + { "4.7a", 0x2000, 0x9e0f9bcc, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "xx.7a", 0x1000, 0xfbe2b368, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 #1 Code + { "xx.8a", 0x1000, 0xe1795b3d, 2 | BRF_PRG | BRF_ESS }, // 5 + + { "8.10g", 0x1000, 0x931b29eb, 3 | BRF_GRA }, // 6 Characters + { "7.9g", 0x1000, 0xbbe6d6e4, 3 | BRF_GRA }, // 7 + + { "6.9a", 0x1000, 0xb2d8c121, 4 | BRF_GRA }, // 8 Sprites + { "5.8a", 0x1000, 0x1097c2b6, 4 | BRF_GRA }, // 9 + + { "pooyan.pr1", 0x0020, 0xa06a6d0e, 5 | BRF_GRA }, // 10 Color Proms + { "pooyan.pr3", 0x0100, 0x8cd4cd60, 5 | BRF_GRA }, // 11 + { "pooyan.pr2", 0x0100, 0x82748c0b, 5 | BRF_GRA }, // 12 +}; + +STD_ROM_PICK(pooyan); +STD_ROM_FN(pooyan); + +struct BurnDriver BurnDrvPooyan = { + "pooyan", NULL, NULL, "1982", + "Pooyan\0", NULL, "Konami", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, pooyanRomInfo, pooyanRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPalette, + 224, 256, 3, 4 +}; + + +// Pooyan (Stern) + +static struct BurnRomInfo pooyansRomDesc[] = { + { "ic22_a4.cpu", 0x2000, 0x916ae7d7, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "ic23_a5.cpu", 0x2000, 0x8fe38c61, 1 | BRF_PRG | BRF_ESS }, // 1 + { "ic24_a6.cpu", 0x2000, 0x2660218a, 1 | BRF_PRG | BRF_ESS }, // 2 + { "ic25_a7.cpu", 0x2000, 0x3d2a10ad, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "xx.7a", 0x1000, 0xfbe2b368, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 #1 Code + { "xx.8a", 0x1000, 0xe1795b3d, 2 | BRF_PRG | BRF_ESS }, // 5 + + { "ic13_g10.cpu", 0x1000, 0x7433aea9, 3 | BRF_GRA }, // 6 Characters + { "ic14_g9.cpu", 0x1000, 0x87c1789e, 3 | BRF_GRA }, // 7 + + { "6.9a", 0x1000, 0xb2d8c121, 4 | BRF_GRA }, // 8 Sprites + { "5.8a", 0x1000, 0x1097c2b6, 4 | BRF_GRA }, // 9 + + { "pooyan.pr1", 0x0020, 0xa06a6d0e, 5 | BRF_GRA }, // 10 Color Proms + { "pooyan.pr3", 0x0100, 0x8cd4cd60, 5 | BRF_GRA }, // 11 + { "pooyan.pr2", 0x0100, 0x82748c0b, 5 | BRF_GRA }, // 12 +}; + +STD_ROM_PICK(pooyans); +STD_ROM_FN(pooyans); + +struct BurnDriver BurnDrvPooyans = { + "pooyans", "pooyan", NULL, "1982", + "Pooyan (Stern)\0", NULL, "[Konami] (Stern license)", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, pooyansRomInfo, pooyansRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPalette, + 224, 256, 3, 4 +}; + + +// Pootan + +static struct BurnRomInfo pootanRomDesc[] = { + { "poo_ic22.bin", 0x2000, 0x41b23a24, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "poo_ic23.bin", 0x2000, 0xc9d94661, 1 | BRF_PRG | BRF_ESS }, // 1 + { "3.6a", 0x2000, 0xfe1a9e08, 1 | BRF_PRG | BRF_ESS }, // 2 + { "poo_ic25.bin", 0x2000, 0x8ae459ef, 1 | BRF_PRG | BRF_ESS }, // 3 + + { "xx.7a", 0x1000, 0xfbe2b368, 2 | BRF_PRG | BRF_ESS }, // 4 Z80 #1 Code + { "xx.8a", 0x1000, 0xe1795b3d, 2 | BRF_PRG | BRF_ESS }, // 5 + + { "poo_ic13.bin", 0x1000, 0x0be802e4, 3 | BRF_GRA }, // 6 Characters + { "poo_ic14.bin", 0x1000, 0xcba29096, 3 | BRF_GRA }, // 7 + + { "6.9a", 0x1000, 0xb2d8c121, 4 | BRF_GRA }, // 8 Sprites + { "5.8a", 0x1000, 0x1097c2b6, 4 | BRF_GRA }, // 9 + + { "pooyan.pr1", 0x0020, 0xa06a6d0e, 5 | BRF_GRA }, // 10 Color Proms + { "pooyan.pr3", 0x0100, 0x8cd4cd60, 5 | BRF_GRA }, // 11 + { "pooyan.pr2", 0x0100, 0x82748c0b, 5 | BRF_GRA }, // 12 +}; + +STD_ROM_PICK(pootan); +STD_ROM_FN(pootan); + +struct BurnDriver BurnDrvPootan = { + "pootan", "pooyan", NULL, "1982", + "Pootan\0", NULL, "bootleg", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, pootanRomInfo, pootanRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPalette, + 224, 256, 3, 4 +}; + diff --git a/src/burn/misc/pre90s/d_prehisle.cpp b/src/burn/misc/pre90s/d_prehisle.cpp new file mode 100644 index 0000000..c543d33 --- /dev/null +++ b/src/burn/misc/pre90s/d_prehisle.cpp @@ -0,0 +1,855 @@ +#include "tiles_generic.h" +#include "burn_ym3812.h" +#include "upd7759.h" + +// Input Related Variables +static unsigned char PrehisleInputPort0[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char PrehisleInputPort1[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char PrehisleInputPort2[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char PrehisleDip[2] = {0, 0}; +static unsigned char PrehisleInput[3] = {0x00, 0x00, 0x00}; +static unsigned char PrehisleReset = 0; + +// Memory Holders +static unsigned char *Mem = NULL; +static unsigned char *MemEnd = NULL; +static unsigned char *RamStart = NULL; +static unsigned char *RamEnd = NULL; +static unsigned char *PrehisleRom = NULL; +static unsigned char *PrehisleZ80Rom = NULL; +static unsigned char *PrehisleTileMapRom = NULL; +static unsigned char *PrehisleADPCMSamples = NULL; +static unsigned char *PrehisleRam = NULL; +static unsigned char *PrehisleVideoRam = NULL; +static unsigned char *PrehisleSpriteRam = NULL; +static unsigned char *PrehisleVideo2Ram = NULL; +static unsigned char *PrehislePaletteRam = NULL; +static unsigned char *PrehisleZ80Ram = NULL; +static unsigned int *PrehislePalette = NULL; +static unsigned char *PrehisleTextTiles = NULL; +static unsigned char *PrehisleSprites = NULL; +static unsigned char *PrehisleBack1Tiles = NULL; +static unsigned char *PrehisleBack2Tiles = NULL; +static unsigned char *PrehisleTempGfx = NULL; + +// Misc Variables, system control values, etc. +static int ControlsInvert; +static unsigned short VidControl[7]; +static int SoundLatch; + +// CPU Interleave Variables +static int nCyclesDone[2], nCyclesTotal[2]; +static int nCyclesSegment; + +// Dip Switch and Input Definitions +static struct BurnInputInfo PrehisleInputList[] = { + {"Coin 1" , BIT_DIGITAL , PrehisleInputPort2 + 0, "p1 coin" }, + {"Start 1" , BIT_DIGITAL , PrehisleInputPort0 + 7, "p1 start" }, + {"Coin 2" , BIT_DIGITAL , PrehisleInputPort2 + 1, "p2 coin" }, + {"Start 2" , BIT_DIGITAL , PrehisleInputPort1 + 7, "p2 start" }, + + {"P1 Up" , BIT_DIGITAL , PrehisleInputPort0 + 0, "p1 up" }, + {"P1 Down" , BIT_DIGITAL , PrehisleInputPort0 + 1, "p1 down" }, + {"P1 Left" , BIT_DIGITAL , PrehisleInputPort0 + 2, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , PrehisleInputPort0 + 3, "p1 right" }, + {"P1 Fire 1" , BIT_DIGITAL , PrehisleInputPort0 + 4, "p1 fire 1" }, + {"P1 Fire 2" , BIT_DIGITAL , PrehisleInputPort0 + 5, "p1 fire 2" }, + {"P1 Fire 3" , BIT_DIGITAL , PrehisleInputPort0 + 6, "p1 fire 3" }, + + {"P2 Up" , BIT_DIGITAL , PrehisleInputPort1 + 0, "p2 up" }, + {"P2 Down" , BIT_DIGITAL , PrehisleInputPort1 + 1, "p2 down" }, + {"P2 Left" , BIT_DIGITAL , PrehisleInputPort1 + 2, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , PrehisleInputPort1 + 3, "p2 right" }, + {"P2 Fire 1" , BIT_DIGITAL , PrehisleInputPort1 + 4, "p2 fire 1" }, + {"P2 Fire 2" , BIT_DIGITAL , PrehisleInputPort1 + 5, "p2 fire 2" }, + {"P2 Fire 3" , BIT_DIGITAL , PrehisleInputPort1 + 6, "p2 fire 3" }, + + {"Reset" , BIT_DIGITAL , &PrehisleReset , "reset" }, + {"Service" , BIT_DIGITAL , PrehisleInputPort2 + 2, "service" }, + {"Diagnostics" , BIT_DIGITAL , PrehisleInputPort2 + 3, "diag" }, + {"Tilt" , BIT_DIGITAL , PrehisleInputPort2 + 4, "tilt" }, + {"Dip 1" , BIT_DIPSWITCH, PrehisleDip + 0 , "dip" }, + {"Dip 2" , BIT_DIPSWITCH, PrehisleDip + 1 , "dip" }, +}; + +STDINPUTINFO(Prehisle); + +inline void PrehisleClearOpposites(unsigned char* nJoystickInputs) +{ + if ((*nJoystickInputs & 0x03) == 0x03) { + *nJoystickInputs &= ~0x03; + } + if ((*nJoystickInputs & 0x0c) == 0x0c) { + *nJoystickInputs &= ~0x0c; + } +} + +inline void PrehisleMakeInputs() +{ + // Reset Inputs + PrehisleInput[0] = PrehisleInput[1] = PrehisleInput[2] = 0x00; + + // Compile Digital Inputs + for (int i = 0; i < 8; i++) { + PrehisleInput[0] |= (PrehisleInputPort0[i] & 1) << i; + PrehisleInput[1] |= (PrehisleInputPort1[i] & 1) << i; + PrehisleInput[2] |= (PrehisleInputPort2[i] & 1) << i; + } + + // Clear Opposites + PrehisleClearOpposites(&PrehisleInput[0]); + PrehisleClearOpposites(&PrehisleInput[1]); +} + +static struct BurnDIPInfo PrehisleDIPList[]= +{ + // Default Values + {0x16, 0xff, 0xff, 0xff, NULL }, + {0x17, 0xff, 0xff, 0x7f, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 2 , "Display" }, + {0x16, 0x01, 0x01, 0x01, "Normal" }, + {0x16, 0x01, 0x01, 0x00, "Inverse" }, + + {0 , 0xfe, 0 , 2 , "Level Select" }, + {0x16, 0x01, 0x02, 0x02, "Off" }, + {0x16, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Bonus" }, + {0x16, 0x01, 0x04, 0x04, "2nd" }, + {0x16, 0x01, 0x04, 0x00, "Every" }, + +// {0 , 0xfe, 0 , 2 , "Unknown" }, +// {0x16, 0x01, 0x08, 0x08, "Off" }, +// {0x16, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 4 , "Coinage" }, + {0x16, 0x01, 0x30, 0x30, "A 1-1 B 1-1" }, + {0x16, 0x01, 0x30, 0x20, "A 2-1 B 1-2" }, + {0x16, 0x01, 0x30, 0x10, "A 3-1 B 1-3" }, + {0x16, 0x01, 0x30, 0x00, "A 4-1 B 1-4" }, + + {0 , 0xfe, 0 , 4 , "Hero" }, + {0x16, 0x01, 0xc0, 0x80, "2" }, + {0x16, 0x01, 0xc0, 0xc0, "3" }, + {0x16, 0x01, 0xc0, 0x40, "4" }, + {0x16, 0x01, 0xc0, 0x00, "5" }, + + // Dip 2 + {0 , 0xfe, 0 , 4 , "Level" }, + {0x17, 0x01, 0x03, 0x02, "1 (Easy)" }, + {0x17, 0x01, 0x03, 0x03, "2 (Standard)" }, + {0x17, 0x01, 0x03, 0x01, "3 (Middle)" }, + {0x17, 0x01, 0x03, 0x00, "4 (Difficult)" }, + + {0 , 0xfe, 0 , 4 , "Game Mode" }, + {0x17, 0x01, 0x0c, 0x08, "Demo Sound Off" }, + {0x17, 0x01, 0x0c, 0x0c, "Demo Sound On" }, + {0x17, 0x01, 0x0c, 0x00, "Stop Video" }, + {0x17, 0x01, 0x0c, 0x04, "Never Finish" }, + + {0 , 0xfe, 0 , 4 , "Bonus 1st/2nd" }, + {0x17, 0x01, 0x30, 0x30, "100000/200000" }, + {0x17, 0x01, 0x30, 0x20, "150000/300000" }, + {0x17, 0x01, 0x30, 0x10, "300000/500000" }, + {0x17, 0x01, 0x30, 0x00, "No Bonus" }, + + {0 , 0xfe, 0 , 2 , "Continue" }, + {0x17, 0x01, 0x40, 0x00, "Off" }, + {0x17, 0x01, 0x40, 0x40, "On" }, +}; + +STDDIPINFO(Prehisle); + +// Rom Definitions +static struct BurnRomInfo PrehisleRomDesc[] = { + { "gt.2", 0x20000, 0x7083245a, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "gt.3", 0x20000, 0x6d8cdf58, BRF_ESS | BRF_PRG }, // 1 68000 Program Code + + { "gt15.b15", 0x08000, 0xac652412, BRF_GRA }, // 2 Text Layer Tiles + { "pi8914.b14", 0x40000, 0x207d6187, BRF_GRA }, // 3 Background2 Layer Tiles + { "pi8916.h16", 0x40000, 0x7cffe0f6, BRF_GRA }, // 4 Background1 Layer Tiles + { "pi8910.k14", 0x80000, 0x5a101b0b, BRF_GRA }, // 5 Sprite Layer Tiles + { "gt.5", 0x20000, 0x3d3ab273, BRF_GRA }, // 6 Sprite Layer Tiles + { "gt.11", 0x10000, 0xb4f0fcf0, BRF_GRA }, // 7 Background 2 TileMap + + { "gt.1", 0x10000, 0x80a4c093, BRF_SND }, // 8 Z80 Program Code + + { "gt.4", 0x20000, 0x85dfb9ec, BRF_SND }, // 9 ADPCM Samples +}; + + +STD_ROM_PICK(Prehisle); +STD_ROM_FN(Prehisle); + +static struct BurnRomInfo PrehisluRomDesc[] = { + { "gt-u2.2h", 0x20000, 0xa14f49bb, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "gt-u3.3h", 0x20000, 0xf165757e, BRF_ESS | BRF_PRG }, // 1 68000 Program Code + + { "gt15.b15", 0x08000, 0xac652412, BRF_GRA }, // 2 Text Layer Tiles + { "pi8914.b14", 0x40000, 0x207d6187, BRF_GRA }, // 3 Background2 Layer Tiles + { "pi8916.h16", 0x40000, 0x7cffe0f6, BRF_GRA }, // 4 Background1 Layer Tiles + { "pi8910.k14", 0x80000, 0x5a101b0b, BRF_GRA }, // 5 Sprite Layer Tiles + { "gt.5", 0x20000, 0x3d3ab273, BRF_GRA }, // 6 Sprite Layer Tiles + { "gt.11", 0x10000, 0xb4f0fcf0, BRF_GRA }, // 7 Background 2 TileMap + + { "gt.1", 0x10000, 0x80a4c093, BRF_SND }, // 8 Z80 Program Code + + { "gt.4", 0x20000, 0x85dfb9ec, BRF_SND }, // 9 ADPCM Samples +}; + + +STD_ROM_PICK(Prehislu); +STD_ROM_FN(Prehislu); + +static struct BurnRomInfo GensitouRomDesc[] = { + { "gt2j.bin", 0x20000, 0xa2da0b6b, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "gt3j.bin", 0x20000, 0xc1a0ae8e, BRF_ESS | BRF_PRG }, // 1 68000 Program Code + + { "gt15.b15", 0x08000, 0xac652412, BRF_GRA }, // 2 Text Layer Tiles + { "pi8914.b14", 0x40000, 0x207d6187, BRF_GRA }, // 3 Background2 Layer Tiles + { "pi8916.h16", 0x40000, 0x7cffe0f6, BRF_GRA }, // 4 Background1 Layer Tiles + { "pi8910.k14", 0x80000, 0x5a101b0b, BRF_GRA }, // 5 Sprite Layer Tiles + { "gt.5", 0x20000, 0x3d3ab273, BRF_GRA }, // 6 Sprite Layer Tiles + { "gt.11", 0x10000, 0xb4f0fcf0, BRF_GRA }, // 7 Background 2 TileMap + + { "gt.1", 0x10000, 0x80a4c093, BRF_SND }, // 8 Z80 Program Code + + { "gt.4", 0x20000, 0x85dfb9ec, BRF_SND }, // 9 ADPCM Samples +}; + + +STD_ROM_PICK(Gensitou); +STD_ROM_FN(Gensitou); + +// Misc Driver Functions and Memory Handlers +int PrehisleDoReset() +{ + ControlsInvert = 0; + SoundLatch = 0; + VidControl[0] = VidControl[1] = VidControl[2] = VidControl[3] = VidControl[4] = VidControl[5] = VidControl[6] = 0; + + SekOpen(0); + SekReset(); + SekClose(); + ZetOpen(0); + ZetReset(); + ZetClose(); + + BurnYM3812Reset(); + UPD7759Reset(); + + return 0; +} + +// ---------------------------------------------------------------------------- +// Callbacks for the FM chip + +static void prehisleFMIRQHandler(int, int nStatus) +{ + if (nStatus) { + ZetSetIRQLine(0xFF, ZET_IRQSTATUS_ACK); + } else { + ZetSetIRQLine(0, ZET_IRQSTATUS_NONE); + } +} + +static int prehisleSynchroniseStream(int nSoundRate) +{ + return (long long)ZetTotalCycles() * nSoundRate / 4000000; +} + +// VBlank + +inline unsigned short PrehisleVBlankRegister() +{ + int nCycles = SekTotalCycles(); + + // 262 == approximate number of scanlines on an arcade monitor + if (nCycles >= (262 - 16) * ((12000000 / 60) / 262)) { + return 0x80; + } else { + if (nCycles < (262 - 210 - 16) * ((12000000 / 60) / 262)) { + return 0x80; + } + } + + return 0x00; +} + +unsigned short __fastcall PrehisleReadWord(unsigned int a) +{ + switch (a) { + case 0x0e0010: { + return 0xff - PrehisleInput[1]; + } + + case 0x0e0020: { + return 0xff - PrehisleInput[2]; + } + + case 0x0e0040: { + return 0xff - (PrehisleInput[0] ^ ControlsInvert); + } + + case 0x0e0042: { + return PrehisleDip[0]; + } + + case 0x0e0044: { + return PrehisleDip[1] + PrehisleVBlankRegister(); + } + } + + return 0; +} + +void __fastcall PrehisleWriteWord(unsigned int a, unsigned short d) +{ + switch (a) { + case 0x0f0000: { + VidControl[0] = d; + return; + } + + case 0x0f0010: { + VidControl[1] = d; + return; + } + + case 0x0f0020: { + VidControl[2] = d; + return; + } + + case 0x0f0030: { + VidControl[3] = d; + return; + } + + case 0x0f0046: { + ControlsInvert = d ? 0xff : 0x00; + return; + } + + case 0x0f0050: { + VidControl[4] = d; + return; + } + + case 0x0f0052: { + VidControl[5] = d; + return; + } + + case 0x0f0060: { + VidControl[6] = d; + return; + } + + case 0x0f0070: { + SoundLatch = d & 0xff; + ZetNmi(); + return; + } + } +} + +unsigned char __fastcall PrehisleZ80PortRead(unsigned short a) +{ + a &= 0xff; + switch (a) { + case 0x00: { + return BurnYM3812Read(0); + } + } + + return 0; +} + +void __fastcall PrehisleZ80PortWrite(unsigned short a, unsigned char d) +{ + a &= 0xff; + switch (a) { + case 0x00: { + BurnYM3812Write(0, d); + return; + } + + case 0x20: { + BurnYM3812Write(1, d); + return; + } + + case 0x40: { + UPD7759PortWrite(d); + UPD7759StartWrite(0); + UPD7759StartWrite(1); + return; + } + + case 0x80: { + UPD7759ResetWrite(d); + return; + } + } +} + +unsigned char __fastcall PrehisleZ80Read(unsigned short a) +{ + switch (a) { + case 0xf800: { + return SoundLatch; + } + } + + return 0; +} + +// Function to Allocate and Index required memory +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + PrehisleRom = Next; Next += 0x40000; + PrehisleZ80Rom = Next; Next += 0x10000; + PrehisleTileMapRom = Next; Next += 0x10000; + PrehisleADPCMSamples = Next; Next += 0x20000; + + RamStart = Next; + + PrehisleRam = Next; Next += 0x04000; + PrehisleVideoRam = Next; Next += 0x00800; + PrehisleSpriteRam = Next; Next += 0x00800; + PrehisleVideo2Ram = Next; Next += 0x04000; + PrehislePaletteRam = Next; Next += 0x00800; + PrehisleZ80Ram = Next; Next += 0x00800; + + RamEnd = Next; + + PrehisleTextTiles = Next; Next += (1024 * 8 * 8); + PrehisleSprites = Next; Next += (5120 * 16 * 16); + PrehisleBack1Tiles = Next; Next += (2048 * 16 * 16); + PrehisleBack2Tiles = Next; Next += (2048 * 16 * 16); + PrehislePalette = (unsigned int*)Next; Next += 0x00800 * sizeof(unsigned int); + MemEnd = Next; + + return 0; +} + +static int CharPlaneOffsets[4] = { 0, 1, 2, 3 }; +static int CharXOffsets[8] = { 0, 4, 8, 12, 16, 20, 24, 28 }; +static int CharYOffsets[8] = { 0, 32, 64, 96, 128, 160, 192, 224 }; +static int TilePlaneOffsets[4] = { 0, 1, 2, 3 }; +static int TileXOffsets[16] = { 0, 4, 8, 12, 16, 20, 24, 28, 512, 516, 520, 524, 528, 532, 536, 540 }; +static int TileYOffsets[16] = { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480 }; + +// Driver Init and Exit Functions +int PrehisleInit() +{ + int nRet = 0, nLen; + + // Allocate and Blank all required memory + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + PrehisleTempGfx = (unsigned char*)malloc(0xa0000); + + // Load and byte-swap 68000 Program roms + nRet = BurnLoadRom(PrehisleRom + 0x00001, 0, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(PrehisleRom + 0x00000, 1, 2); if (nRet != 0) return 1; + + // Load and decode Text Tiles rom + memset(PrehisleTempGfx, 0, 0xa0000); + nRet = BurnLoadRom(PrehisleTempGfx, 2, 1); if (nRet != 0) return 1; + GfxDecode(1024, 4, 8, 8, CharPlaneOffsets, CharXOffsets, CharYOffsets, 0x100, PrehisleTempGfx, PrehisleTextTiles); + + // Load and decode Background2 Tile rom + memset(PrehisleTempGfx, 0, 0xa0000); + nRet = BurnLoadRom(PrehisleTempGfx, 3, 1); if (nRet != 0) return 1; + GfxDecode(2048, 4, 16, 16, TilePlaneOffsets, TileXOffsets, TileYOffsets, 0x400, PrehisleTempGfx, PrehisleBack2Tiles); + + // Load and decode Background1 Tile rom + memset(PrehisleTempGfx, 0, 0xa0000); + nRet = BurnLoadRom(PrehisleTempGfx, 4, 1); if (nRet != 0) return 1; + GfxDecode(2048, 4, 16, 16, TilePlaneOffsets, TileXOffsets, TileYOffsets, 0x400, PrehisleTempGfx, PrehisleBack1Tiles); + + // Load and decode Sprite roms + memset(PrehisleTempGfx, 0, 0xa0000); + nRet = BurnLoadRom(PrehisleTempGfx + 0x00000, 5, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(PrehisleTempGfx + 0x80000, 6, 1); if (nRet != 0) return 1; + GfxDecode(5120, 4, 16, 16, TilePlaneOffsets, TileXOffsets, TileYOffsets, 0x400, PrehisleTempGfx, PrehisleSprites); + + free(PrehisleTempGfx); + + // Load Background2 Tilemap rom + nRet = BurnLoadRom(PrehisleTileMapRom, 7, 1); if (nRet != 0) return 1; + + // Load Z80 Program rom + nRet = BurnLoadRom(PrehisleZ80Rom, 8, 1); if (nRet != 0) return 1; + + // Load ADPCM Samples + nRet = BurnLoadRom(PrehisleADPCMSamples, 9, 1); if (nRet != 0) return 1; + + // Setup the 68000 emulation + SekInit(0, 0x68000); + SekOpen(0); + SekMapMemory(PrehisleRom , 0x000000, 0x03ffff, SM_ROM); + SekMapMemory(PrehisleRam , 0x070000, 0x073fff, SM_RAM); + SekMapMemory(PrehisleVideoRam , 0x090000, 0x0907ff, SM_RAM); + SekMapMemory(PrehisleSpriteRam , 0x0a0000, 0x0a07ff, SM_RAM); + SekMapMemory(PrehisleVideo2Ram , 0x0b0000, 0x0b3fff, SM_RAM); + SekMapMemory(PrehislePaletteRam, 0x0d0000, 0x0d07ff, SM_RAM); + SekSetReadWordHandler(0, PrehisleReadWord); + SekSetWriteWordHandler(0, PrehisleWriteWord); + SekClose(); + + // Setup the Z80 emulation + ZetInit(1); + ZetOpen(0); + ZetMapArea(0x0000, 0xefff, 0, PrehisleZ80Rom); + ZetMapArea(0x0000, 0xefff, 2, PrehisleZ80Rom); + ZetMapArea(0xf000, 0xf7ff, 0, PrehisleZ80Ram); + ZetMapArea(0xf000, 0xf7ff, 1, PrehisleZ80Ram); + ZetMapArea(0xf000, 0xf7ff, 2, PrehisleZ80Ram); + ZetMemEnd(); + ZetSetReadHandler(PrehisleZ80Read); + ZetSetInHandler(PrehisleZ80PortRead); + ZetSetOutHandler(PrehisleZ80PortWrite); + ZetClose(); + + BurnYM3812Init(4000000, &prehisleFMIRQHandler, &prehisleSynchroniseStream, 0); + BurnTimerAttachZet(4000000); + + UPD7759Init(UPD7759_STANDARD_CLOCK, PrehisleADPCMSamples); + + GenericTilesInit(); + + // Reset the driver + PrehisleDoReset(); + + return 0; +} + +int PrehisleExit() +{ + BurnYM3812Exit(); + UPD7759Exit(); + + SekExit(); + ZetExit(); + + GenericTilesExit(); + + free(Mem); + Mem = NULL; + + return 0; +} + +// Graphics Emulation +void PrehisleRenderBack2TileLayer() +{ + int TileBase, mx, my, Tile, Colour, Scrollx, Scrolly, x, y, Flipx; + + TileBase = ((VidControl[3] >> 4) & 0x3ff) * 32; + TileBase &= 0x7fff; + Scrollx = -(VidControl[3] & 0x0f); + Scrolly = -VidControl[2]; + + for (mx = 0; mx < 17; mx++) { + for (my = 0; my < 32; my++) { + Tile = (PrehisleTileMapRom[2 * TileBase + 0] << 8) + PrehisleTileMapRom[2 * TileBase + 1]; + Colour = Tile >> 12; + Flipx = Tile & 0x800; + x = 16 * mx + Scrollx; + y = (16 * my + Scrolly) & 0x1ff; + y -= 16; + + if (x > 15 && x < 240 && y > 15 && y < 208) { + if (!Flipx) { + Render16x16Tile(pTransDraw, Tile & 0x7ff, x, y, Colour, 4, 768, PrehisleBack2Tiles); + } else { + Render16x16Tile_FlipX(pTransDraw, Tile & 0x7ff, x, y, Colour, 4, 768, PrehisleBack2Tiles); + } + } else { + if (!Flipx) { + Render16x16Tile_Clip(pTransDraw, Tile & 0x7ff, x, y, Colour, 4, 768, PrehisleBack2Tiles); + } else { + Render16x16Tile_FlipX_Clip(pTransDraw, Tile & 0x7ff, x, y, Colour, 4, 768, PrehisleBack2Tiles); + } + } + + TileBase ++; + if (TileBase == 0x8000) TileBase = 0; + } + } +} + +void PrehisleRenderBack1TileLayer() +{ + int TileBase, mx, my, Tile, Colour, Scrollx, Scrolly, x, y, Flipy; + + TileBase = ((VidControl[1] >> 4) & 0xff) * 32; + TileBase &= 0x1fff; + Scrollx = -(VidControl[1] & 0x0f); + Scrolly = -VidControl[0]; + + for (mx = 0; mx < 17; mx++) { + for (my = 0; my < 32; my++) { + Tile = (PrehisleVideo2Ram[2 * TileBase + 1] << 8) + PrehisleVideo2Ram[2 * TileBase + 0]; + Colour = Tile >> 12; + Flipy = Tile & 0x800; + x = 16 * mx + Scrollx; + y = (16 * my + Scrolly) & 0x1ff; + y -= 16; + + if (x > 15 && x < 240 && y > 15 && y < 208) { + if (!Flipy) { + Render16x16Tile_Mask(pTransDraw, Tile & 0x7ff, x, y, Colour, 4, 0x0f, 512, PrehisleBack1Tiles); + } else { + Render16x16Tile_Mask_FlipY(pTransDraw, Tile & 0x7ff, x, y, Colour, 4, 0x0f, 512, PrehisleBack1Tiles); + } + } else { + if (!Flipy) { + Render16x16Tile_Mask_Clip(pTransDraw, Tile & 0x7ff, x, y, Colour, 4, 0x0f, 512, PrehisleBack1Tiles); + } else { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, Tile & 0x7ff, x, y, Colour, 4, 0x0f, 512, PrehisleBack1Tiles); + } + } + + TileBase ++; + if (TileBase == 0x2000) TileBase = 0; + } + } +} + +void PrehisleRenderSpriteLayer() +{ + int offs; + + for (offs = 0; offs < 0x800; offs += 8) { + int x, y, Sprite, Colour, Flipx, Flipy; + + y = (PrehisleSpriteRam[offs + 1] << 8) + PrehisleSpriteRam[offs + 0]; + if (y > 254) continue; + y -= 16; + x = (PrehisleSpriteRam[offs + 3] << 8) + PrehisleSpriteRam[offs + 2]; + if (x & 0x200) x = -(0xff - (x & 0xff)); + if (x > 256) continue; + + Sprite = (PrehisleSpriteRam[offs + 5] << 8) + PrehisleSpriteRam[offs + 4]; + Colour = ((PrehisleSpriteRam[offs + 7] << 8) + PrehisleSpriteRam[offs + 6]) >> 12; + Flipy = Sprite & 0x8000; + Flipx = Sprite & 0x4000; + Sprite &= 0x1fff; + if (Sprite > 0x13ff) Sprite = 0x13ff; + + if (x > 15 && x < 240 && y > 15 && y < 208) { + if (!Flipy) { + if (!Flipx) { + Render16x16Tile_Mask(pTransDraw, Sprite, x, y, Colour, 4, 0x0f, 256, PrehisleSprites); + } else { + Render16x16Tile_Mask_FlipX(pTransDraw, Sprite, x, y, Colour, 4, 0x0f, 256, PrehisleSprites); + } + } else { + if (!Flipx) { + Render16x16Tile_Mask_FlipY(pTransDraw, Sprite, x, y, Colour, 4, 0x0f, 256, PrehisleSprites); + } else { + Render16x16Tile_Mask_FlipXY(pTransDraw, Sprite, x, y, Colour, 4, 0x0f, 256, PrehisleSprites); + } + } + } else { + if (!Flipy) { + if (!Flipx) { + Render16x16Tile_Mask_Clip(pTransDraw, Sprite, x, y, Colour, 4, 0x0f, 256, PrehisleSprites); + } else { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, Sprite, x, y, Colour, 4, 0x0f, 256, PrehisleSprites); + } + } else { + if (!Flipx) { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, Sprite, x, y, Colour, 4, 0x0f, 256, PrehisleSprites); + } else { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, Sprite, x, y, Colour, 4, 0x0f, 256, PrehisleSprites); + } + } + } + } +} + +void PrehisleRenderTextLayer() +{ + int offs, mx, my, Colour, Tile, x, y; + + mx = -1; + my = 0; + for (offs = 0x000; offs < 0x800; offs+=2) { + mx++; + if (mx == 32) { + mx = 0; + my++; + } + Tile = (PrehisleVideoRam[offs + 1] << 8) + PrehisleVideoRam[offs + 0]; + Colour = Tile >> 12; + x = 8 * mx; + y = 8 * my; + y -= 16; + + if (x > 7 && x < 248 && y > 7 && y < 216) { + Render8x8Tile_Mask(pTransDraw, Tile & 0xfff, x, y, Colour, 4, 0x0f, 0, PrehisleTextTiles); + } else { + Render8x8Tile_Mask_Clip(pTransDraw, Tile & 0xfff, x, y, Colour, 4, 0x0f, 0, PrehisleTextTiles); + } + } +} + +inline static unsigned int CalcCol(unsigned short nColour) +{ + int r, g, b; + + r = (nColour >> 12) & 0x0f; + g = (nColour >> 8) & 0x0f; + b = (nColour >> 4) & 0x0f; + + r = (r << 4) | r; + g = (g << 4) | g; + b = (b << 4) | b; + + return BurnHighCol(r, g, b, 0); +} + +int PrehisleCalcPalette() +{ + int i; + unsigned short* ps; + unsigned int* pd; + + for (i = 0, ps = (unsigned short*)PrehislePaletteRam, pd = PrehislePalette; i < 0x800; i++, ps++, pd++) { + *pd = CalcCol(*ps); + } + + return 0; +} + +void PrehisleDraw() +{ + PrehisleCalcPalette(); + PrehisleRenderBack2TileLayer(); + PrehisleRenderBack1TileLayer(); + PrehisleRenderSpriteLayer(); + PrehisleRenderTextLayer(); + BurnTransferCopy(PrehislePalette); +} + +// Frame Function +int PrehisleFrame() +{ + int nInterleave = 1; + + if (PrehisleReset) PrehisleDoReset(); + + PrehisleMakeInputs(); + + nCyclesTotal[0] = 12000000 / 60; + nCyclesTotal[1] = 4000000 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + SekOpen(0); + ZetOpen(0); + + SekNewFrame(); + ZetNewFrame(); + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run 68000 + nCurrentCPU = 0; + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += SekRun(nCyclesSegment); + if (i == (nInterleave - 1)) SekSetIRQLine(4, SEK_IRQSTATUS_AUTO); + } + + BurnTimerEndFrame(nCyclesTotal[1]); + BurnYM3812Update(pBurnSoundOut, nBurnSoundLen); + UPD7759Update(pBurnSoundOut, nBurnSoundLen); + + ZetClose(); + SekClose(); + + if (pBurnDraw) PrehisleDraw(); + + return 0; +} + +// Scan RAM +static int PrehisleScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin != NULL) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_MEMORY_RAM) { // Scan all memory, devices & variables + memset(&ba, 0, sizeof(ba)); + ba.Data = RamStart; + ba.nLen = RamEnd-RamStart; + ba.szName = "All Ram"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + SekScan(nAction); // Scan 68000 + ZetScan(nAction); // Scan Z80 + + BurnYM3812Scan(nAction, pnMin); + UPD7759Scan(nAction, pnMin); + + // Scan critical driver variables + SCAN_VAR(PrehisleInput); + SCAN_VAR(PrehisleDip); + SCAN_VAR(ControlsInvert); + SCAN_VAR(VidControl); + SCAN_VAR(nCyclesDone); + } + + return 0; +} + +// Driver Declarations +struct BurnDriver BurnDrvPrehisle = { + "prehisle", NULL, NULL, "1989", + "Prehistoric Isle in 1930 (World)\0", NULL, "SNK", "Prehistoric Isle (SNK)", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, PrehisleRomInfo, PrehisleRomName, PrehisleInputInfo, PrehisleDIPInfo, + PrehisleInit, PrehisleExit, PrehisleFrame, NULL, PrehisleScan, + 0, NULL, NULL, NULL, NULL, 256, 224, 4, 3 +}; + +struct BurnDriver BurnDrvPrehislu = { + "prehislu", "prehisle", NULL, "1989", + "Prehistoric Isle in 1930 (US)\0", NULL, "SNK of America", "Prehistoric Isle (SNK)", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, PrehisluRomInfo, PrehisluRomName, PrehisleInputInfo, PrehisleDIPInfo, + PrehisleInit, PrehisleExit, PrehisleFrame, NULL, PrehisleScan, + 0, NULL, NULL, NULL, NULL, 256, 224, 4, 3 +}; + +struct BurnDriver BurnDrvGensitou = { + "gensitou", "prehisle", NULL, "1989", + "Genshi-Tou 1930's (Japan)\0", NULL, "SNK", "Prehistoric Isle (SNK)", + L"Genshi-Tou 1930's (Japan)\0\u539F\u59CB\u5CF6 1930's (Japan)\0", NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, GensitouRomInfo, GensitouRomName, PrehisleInputInfo, PrehisleDIPInfo, + PrehisleInit, PrehisleExit, PrehisleFrame, NULL, PrehisleScan, + 0, NULL, NULL, NULL, NULL, 256, 224, 4, 3 +}; diff --git a/src/burn/misc/pre90s/d_quizo.cpp b/src/burn/misc/pre90s/d_quizo.cpp new file mode 100644 index 0000000..ba95512 --- /dev/null +++ b/src/burn/misc/pre90s/d_quizo.cpp @@ -0,0 +1,386 @@ +// FB Alpha Quiz Olympic driver module +// Based on MAME driver by Tomasz Slanina + +#include "burnint.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} +#include "bitswap.h" + +static unsigned char *Mem, *Rom, *Prom, *RomBank, *VideoRam, *framebuffer; +static unsigned char DrvJoy[8], DrvDips, DrvReset; +static unsigned int *Palette; +static unsigned char port60 = 0, port70 = 0, dirty = 0; + +static short* pAY8910Buffer[3]; +static short *pFMBuffer = NULL; + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1", BIT_DIGITAL, DrvJoy + 0, "p1 coin" }, + {"Coin 2", BIT_DIGITAL, DrvJoy + 1, "p1 coin2" }, + {"Start 1", BIT_DIGITAL, DrvJoy + 2, "p1 start" }, + + {"P1 Button 1", BIT_DIGITAL, DrvJoy + 3, "p1 fire 1" }, + {"P1 Button 2", BIT_DIGITAL, DrvJoy + 4, "p1 fire 2" }, + {"P1 Button 3", BIT_DIGITAL, DrvJoy + 5, "p1 fire 3" }, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset" }, + {"Tilt", BIT_DIGITAL, DrvJoy + 6, "tilt" }, + {"Dip Switches", BIT_DIPSWITCH, &DrvDips, "dip" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[] = +{ + // Defaults + {0x08, 0xFF, 0xFF, 0x40, NULL}, + + {0, 0xFE, 0, 2, "Test mode"}, + {0x08, 0x01, 0x08, 0x00, "Off"}, + {0x08, 0x01, 0x08, 0x08, "On"}, + {0, 0xFE, 0, 2, "Show the answer"}, // look the star + {0x08, 0x01, 0x10, 0x00, "Off"}, + {0x08, 0x01, 0x10, 0x10, "On"}, + {0, 0xFE, 0, 2, "Coin A"}, + {0x08, 0x01, 0x40, 0x00, "2 coins 1 credit"}, + {0x08, 0x01, 0x40, 0x40, "1 coin 1 credit"}, +}; + +STDDIPINFO(Drv); + + +static void quizo_palette_init() +{ + int i; unsigned char *color_prom = Prom; + + for (i = 0;i < 16;i++) + { + int bit0,bit1,bit2,r,g,b; + + bit0 = 0; + bit1 = (*color_prom >> 0) & 0x01; + bit2 = (*color_prom >> 1) & 0x01; + b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = (*color_prom >> 2) & 0x01; + bit1 = (*color_prom >> 3) & 0x01; + bit2 = (*color_prom >> 4) & 0x01; + g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = (*color_prom >> 5) & 0x01; + bit1 = (*color_prom >> 6) & 0x01; + bit2 = (*color_prom >> 7) & 0x01; + r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + Palette[i] = (r << 16) | (g << 8) | b; + color_prom++; + } +} + + +static int DrvDraw() +{ + int x,y; + unsigned int *src = (unsigned int *)framebuffer; + + if(dirty) + { + for(y=0;y<200;y++) + { + for(x=0;x<80;x++) + { + int data=VideoRam[y*80+x]; + int data1=VideoRam[y*80+x+0x4000]; + int pix; + + pix=(data&1)|(((data>>4)&1)<<1)|((data1&1)<<2)|(((data1>>4)&1)<<3); + src[((x*4+3) + (y * 320))] = Palette[pix&15]; + data>>=1; + data1>>=1; + pix=(data&1)|(((data>>4)&1)<<1)|((data1&1)<<2)|(((data1>>4)&1)<<3); + src[((x*4+2) + (y * 320))] = Palette[pix&15]; + data>>=1; + data1>>=1; + pix=(data&1)|(((data>>4)&1)<<1)|((data1&1)<<2)|(((data1>>4)&1)<<3); + src[((x*4+1) + (y * 320))] = Palette[pix&15]; + data>>=1; + data1>>=1; + pix=(data&1)|(((data>>4)&1)<<1)|((data1&1)<<2)|(((data1>>4)&1)<<3); + src[((x*4+0) + (y * 320))] = Palette[pix&15]; + } + } + } + dirty = 0; + + for (x = 0; x < 320 * 200; x++) { + PutPix(pBurnDraw + x * nBurnBpp, BurnHighCol(src[x]>>16, src[x]>>8, src[x], 0)); + } + + return 0; +} + + +void port60_w(unsigned short, unsigned char data) +{ + static const unsigned char rombankLookup[]={ 2, 3, 4, 4, 4, 4, 4, 5, 0, 1}; + + if (data > 9) + { + data=0; + } + + port60 = data; + + ZetMapArea(0x8000, 0xbfff, 0, RomBank + rombankLookup[data] * 0x4000); + ZetMapArea(0x8000, 0xbfff, 2, RomBank + rombankLookup[data] * 0x4000); +} + +void __fastcall quizo_write(unsigned short a, unsigned char data) +{ + if (a >= 0xc000) { + int bank = (port70 & 8) ? 1 : 0; + VideoRam[(a & 0x3fff) + bank * 0x4000] = data; + dirty=1; + return; + } +} + +void __fastcall quizo_out_port(unsigned short a, unsigned char d) +{ + switch (a & 0xff) + { + case 0x50: + AY8910Write(0, 0, d); + break; + + case 0x51: + AY8910Write(0, 1, d); + break; + + case 0x60: + port60_w(0, d); + break; + + case 0x70: + port70 = d; + break; + } +} + +unsigned char __fastcall quizo_in_port(unsigned short a) +{ + switch (a & 0xff) + { + case 0x00: // input port 0 + return (DrvJoy[0] | (DrvJoy[1] << 2) | (DrvJoy[6] << 3) | (DrvJoy[2] << 4)) ^ 0x18; + + case 0x10: // input port 1 + return (DrvJoy[3] | (DrvJoy[4] << 1) | (DrvJoy[5] << 2)) ^ 0xff; + + case 0x40: // input port 2 + return DrvDips; + } + + return 0; +} + +static int DrvDoReset() +{ + dirty = 1; + port70 = port60 = 0; + + DrvReset = 0; + + ZetOpen(0); + ZetReset(); + ZetClose(); + + AY8910Reset(0); + + memset (Rom + 0x4000, 0, 0x0400); + memset (VideoRam, 0, 0x8000); + memset (framebuffer, 0, 320 * 200 * 4); + + return 0; +} + + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x30000 + 0x20 + 0x40 + 0x3e800); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short *)malloc (nBurnSoundLen * 3 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + Rom = Mem + 0x00000; + RomBank = Mem + 0x10000; + VideoRam = Mem + 0x28000; + Prom = Mem + 0x30000; + Palette = (unsigned int*)(Mem + 0x30020); + framebuffer = Mem + 0x30060; + + if (BurnLoadRom(Rom, 0, 1)) return 1; + memcpy (Rom, Rom + 0x4000, 0x4000); + + if (BurnLoadRom(RomBank + 0x00000, 1, 1)) return 1; + if (BurnLoadRom(RomBank + 0x08000, 2, 1)) return 1; + if (BurnLoadRom(RomBank + 0x10000, 3, 1)) return 1; + + if (BurnLoadRom(Prom, 4, 1)) return 1; + + quizo_palette_init(); + + ZetInit(1); + ZetOpen(0); + ZetSetWriteHandler(quizo_write); + ZetSetInHandler(quizo_in_port); + ZetSetOutHandler(quizo_out_port); + ZetMapArea(0x0000, 0x3fff, 0, Rom + 0x0000); + ZetMapArea(0x0000, 0x3fff, 2, Rom + 0x0000); + ZetMapArea(0x4000, 0x47ff, 0, Rom + 0x4000); + ZetMapArea(0x4000, 0x47ff, 1, Rom + 0x4000); + ZetMemEnd(); + ZetClose(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + AY8910Init(0, 1342329, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) DrvDoReset(); + + int nSoundBufferPos = 0; + + ZetOpen(0); + ZetRun(4000000 / 60); + ZetRaiseIrq(1); + ZetClose(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) DrvDraw(); + + return 0; +} + + +static int DrvExit() +{ + Mem = Rom = Prom = RomBank = VideoRam = framebuffer = NULL; + Palette = NULL; + pFMBuffer = NULL; + AY8910Exit(0); + ZetExit(); + free (Mem); + free (pFMBuffer); + + return 0; +} + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + ba.Data = VideoRam; + ba.nLen = 0x08000; + ba.szName = "Video Ram"; + BurnAcb(&ba); + + ba.Data = Rom + 0x4000; + ba.nLen = 0x00400; + ba.szName = "Main Ram"; + BurnAcb(&ba); + + ba.Data = framebuffer; + ba.nLen = 320 * 200 * 4; + ba.szName = "Main Ram"; + BurnAcb(&ba); + + ZetScan(nAction); // Scan Z80 + AY8910Scan(nAction, pnMin); // Scan AY8910 + + // Scan critical driver variables + SCAN_VAR(port60); + SCAN_VAR(port70); + SCAN_VAR(dirty); + + port60_w(0, port60); + } + + return 0; +} + + +// Quiz Olympic + +static struct BurnRomInfo quizoRomDesc[] = { + { "rom1", 0x8000, 0x6731735f, BRF_ESS | BRF_PRG }, // 0 Z80 code + + { "rom2", 0x8000, 0xa700eb30, BRF_ESS | BRF_PRG }, // 1 Z80 code banks + { "rom3", 0x8000, 0xd344f97e, BRF_ESS | BRF_PRG }, // 2 + { "rom4", 0x8000, 0xab1eb174, BRF_ESS | BRF_PRG }, // 3 + + { "82s123", 0x0020, 0xc3f15914, BRF_GRA }, // 4 Color Prom +}; + +STD_ROM_PICK(quizo); +STD_ROM_FN(quizo); + +struct BurnDriver BurnDrvQuizo = { + "quizo", NULL, NULL, "1985", + "Quiz Olympic\0", NULL, "Seoul Coin Corp.", "Miscellaneous", + L"\uD034\uC988\uC62C\uB9BC\uD53D\0Quiz Olympic\0", NULL, NULL, NULL, + BDF_GAME_WORKING, 1, HARDWARE_MISC_PRE90S, + NULL, quizoRomInfo, quizoRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, NULL, NULL, 0, NULL, NULL, NULL, NULL, + 320, 200, 4, 3 +}; + diff --git a/src/burn/misc/pre90s/d_route16.cpp b/src/burn/misc/pre90s/d_route16.cpp new file mode 100644 index 0000000..24edf69 --- /dev/null +++ b/src/burn/misc/pre90s/d_route16.cpp @@ -0,0 +1,1074 @@ +// FB Alpha Route 16 driver module +// Based on code by Zsolt Vasvari + +#include "burnint.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +//------------------------------------------------------------------------------------------------ + +static int draw_type; +static unsigned char *Mem = NULL; +static unsigned char *Rom0, *Rom1, *Prom; + +static unsigned char flipscreen, palette_1, palette_2, ttmahjng_port_select; +static int speakres_vrx; + +static short *pAY8910Buffer[3]; +static short *pFMBuffer = NULL; + +static unsigned char DrvJoy1[24], DrvJoy2[8], Dips, DrvReset; + +//------------------------------------------------------------------------------------------------ + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 0, "p1 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 1, "p1 start" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 2, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 3, "p1 left" }, + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 4, "p1 up" }, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 5, "p1 down", }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 6, "p1 fire 1"}, + + {"P2 Start" , BIT_DIGITAL , DrvJoy2 + 0, "p2 start" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 1, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 2, "p2 left" }, + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 3, "p2 up" }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 4, "p2 down", }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 5, "p2 fire 1"}, + + {"Service Mode", BIT_DIGITAL, DrvJoy1 + 7, "diag" }, + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, &Dips , "dip" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnInputInfo mahjongInputList[] = { + {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin"}, + {"P1 Start", BIT_DIGITAL, DrvJoy1 + 1, "p1 start"}, + {"P2 Start", BIT_DIGITAL, DrvJoy1 + 2, "p2 start"}, + {"A", BIT_DIGITAL, DrvJoy1 + 3, "mah a"}, + {"E", BIT_DIGITAL, DrvJoy1 + 4, "mah e"}, + {"I", BIT_DIGITAL, DrvJoy1 + 5, "mah i"}, + {"M", BIT_DIGITAL, DrvJoy1 + 6, "mah m"}, + {"Kan", BIT_DIGITAL, DrvJoy1 + 7, "mah kan"}, + {"B", BIT_DIGITAL, DrvJoy1 + 8, "mah b"}, + {"F", BIT_DIGITAL, DrvJoy1 + 9, "mah f"}, + {"J", BIT_DIGITAL, DrvJoy1 + 10, "mah j"}, + {"N", BIT_DIGITAL, DrvJoy1 + 11, "mah n"}, + {"Reach", BIT_DIGITAL, DrvJoy1 + 12, "mah reach"}, + {"C", BIT_DIGITAL, DrvJoy1 + 13, "mah c"}, + {"G", BIT_DIGITAL, DrvJoy1 + 14, "mah g"}, + {"K", BIT_DIGITAL, DrvJoy1 + 15, "mah k"}, + {"Chi", BIT_DIGITAL, DrvJoy1 + 16, "mah chi"}, + {"Ron", BIT_DIGITAL, DrvJoy1 + 17, "mah ron"}, + {"D", BIT_DIGITAL, DrvJoy1 + 18, "mah d"}, + {"H", BIT_DIGITAL, DrvJoy1 + 19, "mah h"}, + {"L", BIT_DIGITAL, DrvJoy1 + 20, "mah l"}, + {"Pon", BIT_DIGITAL, DrvJoy1 + 21, "mah pon"}, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset"}, +}; + +STDINPUTINFO(mahjong); + + + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x20, NULL }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x0f, 0x01, 0x01, 0x00, "3" }, + {0x0f, 0x01, 0x01, 0x01, "5" }, + + {0 , 0xfe, 0 , 3 , "Coinage" }, + {0x0f, 0x01, 0x18, 0x08, "2C_1C" }, + {0x0f, 0x01, 0x18, 0x00, "1C_1C" }, + {0x0f, 0x01, 0x18, 0x18, "1C_2C" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x20, 0x20, "Upright" }, + {0x0f, 0x01, 0x20, 0x00, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0f, 0x01, 0x40, 0x00, "Off" }, + {0x0f, 0x01, 0x40, 0x40, "On" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x0f, 0x01, 0x80, 0x00, "Off" }, + {0x0f, 0x01, 0x80, 0x80, "On" }, +}; + +STDDIPINFO(Drv); + +static struct BurnDIPInfo stratvoxDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x20, NULL }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x0f, 0x01, 0x01, 0x00, "3" }, + {0x0f, 0x01, 0x01, 0x01, "5" }, + + {0 , 0xfe, 0 , 2 , "Replenish Astronauts" }, + {0x0f, 0x01, 0x02, 0x00, "No" }, + {0x0f, 0x01, 0x02, 0x02, "Yes" }, + + {0 , 0xfe, 0 , 4 , "2 Attackers At Wave" }, + {0x0f, 0x01, 0x0c, 0x00, "2" }, + {0x0f, 0x01, 0x0c, 0x04, "3" }, + {0x0f, 0x01, 0x0c, 0x08, "4" }, + {0x0f, 0x01, 0x0c, 0x0c, "5" }, + + {0 , 0xfe, 0 , 3 , "Astronauts Kidnapped" }, + {0x0f, 0x01, 0x10, 0x00, "Less Often" }, + {0x0f, 0x01, 0x10, 0x10, "More Often" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x20, 0x20, "Upright" }, + {0x0f, 0x01, 0x20, 0x00, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0f, 0x01, 0x40, 0x00, "Off" }, + {0x0f, 0x01, 0x40, 0x40, "On" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x0f, 0x01, 0x80, 0x00, "Off" }, + {0x0f, 0x01, 0x80, 0x80, "On" }, +}; + +STDDIPINFO(stratvox); + +static struct BurnDIPInfo speakresDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x20, NULL }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x0f, 0x01, 0x03, 0x00, "3" }, + {0x0f, 0x01, 0x03, 0x01, "4" }, + {0x0f, 0x01, 0x03, 0x02, "5" }, + {0x0f, 0x01, 0x03, 0x03, "6" }, + + {0 , 0xfe, 0 , 4 , "2 Attackers At Wave" }, + {0x0f, 0x01, 0x0c, 0x00, "2" }, + {0x0f, 0x01, 0x0c, 0x04, "3" }, + {0x0f, 0x01, 0x0c, 0x08, "4" }, + {0x0f, 0x01, 0x0c, 0x0c, "5" }, + + {0 , 0xfe, 0 , 3 , "Bonus Life" }, + {0x0f, 0x01, 0x10, 0x00, "5000" }, + {0x0f, 0x01, 0x10, 0x10, "8000" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x20, 0x20, "Upright" }, + {0x0f, 0x01, 0x20, 0x00, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x0f, 0x01, 0x40, 0x00, "Off" }, + {0x0f, 0x01, 0x40, 0x40, "On" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x0f, 0x01, 0x80, 0x00, "Off" }, + {0x0f, 0x01, 0x80, 0x80, "On" }, +}; + +STDDIPINFO(speakres); + + +//------------------------------------------------------------------------------------------------ + +static unsigned char ttmahjng_input_port_matrix_r() +{ + unsigned char ret = 0; + + switch (ttmahjng_port_select) + { + case 1: { + for (int i = 0; i < 5; i++) ret |= DrvJoy1[ 3 + i] << i; + ret |= DrvJoy1[1] << 5; + } + break; + case 2: { + for (int i = 0; i < 5; i++) ret |= DrvJoy1[ 8 + i] << i; + ret |= DrvJoy1[2] << 5; + } + break; + case 4: { + for (int i = 0; i < 5; i++) ret |= DrvJoy1[13 + i] << i; + } + break; + case 8: { + for (int i = 0; i < 4; i++) ret |= DrvJoy1[18 + i] << i; + } + break; + default: break; + } + + return ~ret; +} + + +unsigned char __fastcall route16_cpu0_read(unsigned short offset) +{ + unsigned char nRet = 0; + + switch (offset) + { + case 0x4800: + return Dips; + + case 0x5000: + { + if (draw_type == 1) { // ttmahjng + nRet = (DrvJoy1[0] << 7) ^ 0xff; + } else { + if (DrvJoy1[2]) nRet |= 0x01; + if (DrvJoy1[3]) nRet |= 0x02; + if (DrvJoy1[4]) nRet |= 0x04; + if (DrvJoy1[5]) nRet |= 0x08; + if (DrvJoy1[6]) nRet |= 0x10; + if (DrvJoy1[7]) nRet |= 0x40; // service mode + if (DrvJoy1[0]) nRet |= 0x80; // coin + } + return nRet; + } + + + case 0x5800: + { + if (draw_type == 1) { // ttmahjng + nRet = ttmahjng_input_port_matrix_r(); + } else { + if (DrvJoy2[1]) nRet |= 0x01; + if (DrvJoy2[2]) nRet |= 0x02; + if (DrvJoy2[3]) nRet |= 0x04; + if (DrvJoy2[4]) nRet |= 0x08; + if (DrvJoy2[5]) nRet |= 0x10; + if (DrvJoy2[0]) nRet |= 0x40; // start 2 + if (DrvJoy1[1]) nRet |= 0x80; // start 1 + } + + return nRet; + } + + case 0x6000: // speakres + { + int bit2=4, bit1=2, bit0=1; + + // just using a counter, the constants are the number of reads + // before going low, each read is 40 cycles apart. the constants + // were chosen based on the startup tests and for vr0=vr2 + speakres_vrx++; + if(speakres_vrx>0x300) bit0=0; /* VR0 100k ohm - speech */ + if(speakres_vrx>0x200) bit1=0; /* VR1 50k ohm - main volume */ + if(speakres_vrx>0x300) bit2=0; /* VR2 100k ohm - explosion */ + + return 0xf8|bit2|bit1|bit0; + } + + case 0x6400: // routex + { + if (ZetPc(-1) == 0x2f) + return 0xfb; + else + return 0; + } + } + + return 0; +} + + +void __fastcall route16_cpu0_write(unsigned short offset, unsigned char data) +{ + if (offset >= 0x4000 && offset < 0x4400) { + Rom0[offset] = data; + + // 4313-4319 are used in Route 16 as triggers to wake the other CPU + if (offset >= 0x4313 && offset <= 0x4319 && data == 0xff) + { + // Let the other CPU run + // cpu_yield(); + ZetRunEnd(); // Correct? + } + + return; + } + + switch (offset) + { + case 0x2800: // stratvox + // DAC_0_data_w + break; + + case 0x4800: + palette_1 = data & 0x1f; + break; + + case 0x5000: + palette_2 = data & 0x1f; + flipscreen = (data >> 5) & 0x01; + break; + + case 0x5800: // speakres, ttmahjng + ttmahjng_port_select = data; + speakres_vrx = 0; + break; + + case 0x6800: // ttmahjng + AY8910Write(0, 1, data); + break; + + case 0x6900: // ttmahjng + AY8910Write(0, 0, data); + break; + } +} + +void __fastcall route16_cpu0_out(unsigned short offset, unsigned char data) +{ + switch (offset & 0x1ff) + { + case 0x000: + AY8910Write(0, 1, data); + break; + + case 0x100: + AY8910Write(0, 0, data); + break; + } +} + + +static int GetRoms() +{ + char* pRomName; + struct BurnRomInfo ri; + unsigned char *Rom0Load = Rom0; + unsigned char *Rom1Load = Rom1; + unsigned char *PromLoad = Prom; + + for (int i = 0; !BurnDrvGetRomName(&pRomName, i, 0); i++) { + + BurnDrvGetRomInfo(&ri, i); + + if ((ri.nType & 7) == 1) { + if (BurnLoadRom(Rom0Load, i, 1)) return 1; + Rom0Load += ri.nLen; + continue; + } + + if ((ri.nType & 7) == 2) { + if (BurnLoadRom(Rom1Load, i, 1)) return 1; + Rom1Load += ri.nLen; + continue; + } + + if ((ri.nType & 7) == 3) { + if (BurnLoadRom(PromLoad, i, 1)) return 1; + PromLoad += ri.nLen; + continue; + } + } + + return 0; +} + + +static int DrvDoReset() +{ + flipscreen = palette_1 = palette_2 = ttmahjng_port_select = 0; + speakres_vrx = 0; + + DrvReset = 0; + + memset (Rom0 + 0x4000, 0, 0xc000); // Shared & video ram + memset (Rom1 + 0x8000, 0, 0x4000); + + ZetOpen(0); + ZetReset(); + ZetClose(); + ZetOpen(1); + ZetReset(); + ZetClose(); + + AY8910Reset(0); + + return 0; +} + + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x10000 + 0x10000 + 0x200); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short *)malloc (nBurnSoundLen * 3 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + Rom0 = Mem + 0x00000; + Rom1 = Mem + 0x10000; + Prom = Mem + 0x20000; + + // Load Roms + if (GetRoms()) return 1; + + ZetInit(2); + ZetOpen(0); + ZetSetOutHandler(route16_cpu0_out); + ZetSetReadHandler(route16_cpu0_read); + ZetSetWriteHandler(route16_cpu0_write); + ZetMapArea (0x0000, 0x3fff, 0, Rom0 + 0x0000); // ROM + ZetMapArea (0x0000, 0x3fff, 2, Rom0 + 0x0000); + ZetMapArea (0x4000, 0x43ff, 0, Rom0 + 0x4000); // Read Shared RAM + ZetMapArea (0x8000, 0xbfff, 0, Rom0 + 0x8000); // Video RAM + ZetMapArea (0x8000, 0xbfff, 1, Rom0 + 0x8000); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetSetWriteHandler(route16_cpu0_write); + ZetMapArea (0x0000, 0x1fff, 0, Rom1 + 0x0000); // ROM + ZetMapArea (0x0000, 0x1fff, 2, Rom1 + 0x0000); + ZetMapArea (0x4000, 0x43ff, 0, Rom0 + 0x4000); // Read Shared RAM + ZetMapArea (0x8000, 0xbfff, 0, Rom1 + 0x8000); // Video RAM + ZetMapArea (0x8000, 0xbfff, 1, Rom1 + 0x8000); + ZetMemEnd(); + ZetClose(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + AY8910Init(0, 1250000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + return 0; +} + + +static int DrvExit() +{ + ZetExit(); + AY8910Exit(0); + + free (Mem); + free (pFMBuffer); + + draw_type = 0; + + pFMBuffer = NULL; + Mem = NULL; + Rom0 = Rom1 = Prom = NULL; + pAY8910Buffer[0] = pAY8910Buffer[0] = pAY8910Buffer[0] = NULL; + + return 0; +} + + +//------------------------------------------------------------------------------------------------ +// Drawing functions + +static inline unsigned int route16_make_pen(unsigned char color) +{ + unsigned int ret = 0; + if (color & 1) ret |= 0x00ff0000; + if (color & 2) ret |= 0x0000ff00; + if (color & 4) ret |= 0x000000ff; + return ret; +} + + +static inline unsigned int ttmajng_make_pen(unsigned char color) +{ + unsigned int ret = 0; + if (color & 4) ret |= 0x00ff0000; + if (color & 2) ret |= 0x0000ff00; + if (color & 1) ret |= 0x000000ff; + return ret; +} + + +static int DrvDraw() +{ + unsigned char *prom1 = Prom + 0x0000; + unsigned char *prom2 = Prom + 0x0100; + + for (int offs = 0; offs < 0x4000; offs++) + { + unsigned char y = offs >> 6; + unsigned char x = offs << 2; + + unsigned char d1 = Rom0[0x8000 + offs]; + unsigned char d2 = Rom1[0x8000 + offs]; + + for (int i = 0; i < 4; i++) + { + unsigned char color1, color2; + + // stratvox & ttmahjng + if (draw_type) { + color1 = prom1[(palette_1 << 2) | ((d1 >> 3) & 2) | (d1 & 1)]; + color2 = prom2[(((d1 << 3) & 0x80) | ((d1 << 7) & 0x80)) | (palette_2 << 2) | ((d2 >> 3) & 2) | (d2 & 1)]; + } else { + color1 = prom1[((palette_1 << 6) & 0x80) | (palette_1 << 2) | ((d1 >> 3) & 0x02) | ((d1 >> 0) & 0x01)]; + color2 = prom2[((palette_2 << 6) & 0x80) | (((color1 << 6) & 0x80) | ((color1 << 7) & 0x80)) | (palette_2 << 2) | ((d2 >> 3) & 2) | (d2 & 1)]; + } + + unsigned char final_color = color1 | color2; + + unsigned int pen; + if (draw_type == 1) { + pen = ttmajng_make_pen(final_color); + } else { + pen = route16_make_pen(final_color); + } + + if (flipscreen) + PutPix(pBurnDraw + ((x << 8) | (y ^ 0xff)) * nBurnBpp, BurnHighCol(pen>>16, pen>>8, pen, 0)); + else + PutPix(pBurnDraw + (((x ^ 0xff) << 8) | y) * nBurnBpp, BurnHighCol(pen>>16, pen>>8, pen, 0)); + + x += 1; + d1 >>= 1; + d2 >>= 1; + } + } + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + int nSoundBufferPos = 0; + int nInterleave = 10; + + int nCyclesSegment; + int nCyclesDone[2], nCyclesTotal[2]; + + nCyclesTotal[0] = 2500000 / 60; + nCyclesTotal[1] = 2500000 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run Z80 #0 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if (i+1 == nInterleave) ZetRaiseIrq(1); + ZetClose(); + + // Run Z80 #1 + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesSegment = ZetRun(nCyclesSegment); + nCyclesDone[nCurrentCPU] += nCyclesSegment; + if (i == 9 && draw_type == 3) ZetSetIRQLine(0, ZET_IRQSTATUS_AUTO); // space echo + ZetClose(); + + // Render Sound Segment + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + nSoundBufferPos += nSegmentLength; + } + } + + // Make sure the buffer is entirely filled. + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +//------------------------------------------------------------------------------------------------ +// Savestates + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + ba.Data = Rom0 + 0x4000; + ba.nLen = 0x0400; + ba.szName = "Shared RAM"; + BurnAcb(&ba); + + memset(&ba, 0, sizeof(ba)); + ba.Data = Rom0 + 0x8000; + ba.nLen = 0x4000; + ba.szName = "Cpu0 Video RAM"; + BurnAcb(&ba); + + memset(&ba, 0, sizeof(ba)); + ba.Data = Rom1 + 0x8000; + ba.nLen = 0x4000; + ba.szName = "Cpu1 Video RAM"; + BurnAcb(&ba); + + ZetScan(nAction); // Scan Z80 + AY8910Scan(nAction, pnMin); // Scan AY8910 + + // Scan critical driver variables + SCAN_VAR(flipscreen); + SCAN_VAR(palette_1); + SCAN_VAR(palette_2); + SCAN_VAR(ttmahjng_port_select); + SCAN_VAR(speakres_vrx); + } + + return 0; +} + + +//------------------------------------------------------------------------------------------------ +// Drivers + + +// Route 16 + +static struct BurnRomInfo route16RomDesc[] = { + { "route16.a0", 0x0800, 0x8f9101bd, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 #0 Code + { "route16.a1", 0x0800, 0x389bc077, 1 | BRF_ESS | BRF_PRG }, // 1 + { "route16.a2", 0x0800, 0x1065a468, 1 | BRF_ESS | BRF_PRG }, // 2 + { "route16.a3", 0x0800, 0x0b1987f3, 1 | BRF_ESS | BRF_PRG }, // 3 + { "route16.a4", 0x0800, 0xf67d853a, 1 | BRF_ESS | BRF_PRG }, // 4 + { "route16.a5", 0x0800, 0xd85cf758, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "route16.b0", 0x0800, 0x0f9588a7, 2 | BRF_ESS | BRF_PRG }, // 6 Z80 #1 Code + { "route16.b1", 0x0800, 0x2b326cf9, 2 | BRF_ESS | BRF_PRG }, // 7 + { "route16.b2", 0x0800, 0x529cad13, 2 | BRF_ESS | BRF_PRG }, // 8 + { "route16.b3", 0x0800, 0x3bd8b899, 2 | BRF_ESS | BRF_PRG }, // 9 + + { "im5623.f10", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 10 Graphics + { "im5623.f12", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 11 +}; + +STD_ROM_PICK(route16); +STD_ROM_FN(route16); + +static int route16Init() +{ + int nRet; + + draw_type = 0; + + nRet = DrvInit(); + + if (nRet == 0) + { + // Patch protection + Rom0[0x00e9] = 0x3a; + Rom0[0x0754] = 0xc3; + Rom0[0x0755] = 0x63; + Rom0[0x0756] = 0x07; + } + + return nRet; +} + +struct BurnDriver BurnDrvroute16 = { + "route16", NULL, NULL, "1981", + "Route 16\0", NULL, "Tehkan/Sun (Centuri license)", "Route 16", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, route16RomInfo, route16RomName, DrvInputInfo, DrvDIPInfo, + route16Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 3, 4 +}; + + +// Route 16 (set 2) + +static struct BurnRomInfo route16aRomDesc[] = { + { "vg-54", 0x0800, 0x0c966319, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 #0 Code + { "vg-55", 0x0800, 0xa6a8c212, 1 | BRF_ESS | BRF_PRG }, // 1 + { "vg-56", 0x0800, 0x5c74406a, 1 | BRF_ESS | BRF_PRG }, // 2 + { "vg-57", 0x0800, 0x313e68ab, 1 | BRF_ESS | BRF_PRG }, // 3 + { "vg-58", 0x0800, 0x40824e3c, 1 | BRF_ESS | BRF_PRG }, // 4 + { "vg-59", 0x0800, 0x9313d2c2, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "route16.b0", 0x0800, 0x0f9588a7, 2 | BRF_ESS | BRF_PRG }, // 6 Z80 #1 Code + { "vg-61", 0x0800, 0xb216c88c, 2 | BRF_ESS | BRF_PRG }, // 7 + { "route16.b2", 0x0800, 0x529cad13, 2 | BRF_ESS | BRF_PRG }, // 8 + { "route16.b3", 0x0800, 0x3bd8b899, 2 | BRF_ESS | BRF_PRG }, // 9 + + { "im5623.f10", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 10 Graphics + { "im5623.f12", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 11 +}; + +STD_ROM_PICK(route16a); +STD_ROM_FN(route16a); + +static int route16aInit() +{ + int nRet; + + draw_type = 0; + + nRet = DrvInit(); + + if (nRet == 0) + { + // Patch protection + Rom0[0x00e9] = 0x3a; + + Rom0[0x0105] = 0x00; // jp nz,$4109 (nirvana) - NOP's in route16 + Rom0[0x0106] = 0x00; + Rom0[0x0107] = 0x00; + + Rom0[0x0731] = 0x00; // jp nz,$4238 (nirvana) + Rom0[0x0732] = 0x00; + Rom0[0x0733] = 0x00; + + Rom0[0x0747] = 0xc3; + Rom0[0x0748] = 0x56; + Rom0[0x0749] = 0x07; + } + + return nRet; +} + +struct BurnDriver BurnDrvroute16a = { + "route16a", "route16", NULL, "1981", + "Route 16 (set 2)\0", NULL, "Tehkan/Sun (Centuri license)", "Route 16", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, route16aRomInfo, route16aRomName, DrvInputInfo, DrvDIPInfo, + route16aInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 3, 4 +}; + + +// Route 16 (bootleg) + +static struct BurnRomInfo route16bRomDesc[] = { + { "rt16.0", 0x0800, 0xb1f0f636, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 #0 Code + { "rt16.1", 0x0800, 0x3ec52fe5, 1 | BRF_ESS | BRF_PRG }, // 1 + { "rt16.2", 0x0800, 0xa8e92871, 1 | BRF_ESS | BRF_PRG }, // 2 + { "rt16.3", 0x0800, 0xa0fc9fc5, 1 | BRF_ESS | BRF_PRG }, // 3 + { "rt16.4", 0x0800, 0x6dcaf8c4, 1 | BRF_ESS | BRF_PRG }, // 4 + { "rt16.5", 0x0800, 0x63d7b05b, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "rt16.6", 0x0800, 0xfef605f3, 2 | BRF_ESS | BRF_PRG }, // 6 Z80 #1 Code + { "rt16.7", 0x0800, 0xd0d6c189, 2 | BRF_ESS | BRF_PRG }, // 7 + { "rt16.8", 0x0800, 0xdefc5797, 2 | BRF_ESS | BRF_PRG }, // 8 + { "rt16.9", 0x0800, 0x88d94a66, 2 | BRF_ESS | BRF_PRG }, // 9 + + { "im5623.f10", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 10 Graphics + { "im5623.f12", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 11 +}; + +STD_ROM_PICK(route16b); +STD_ROM_FN(route16b); + +static int route16bInit() +{ + draw_type = 0; + + return DrvInit(); +} + +struct BurnDriver BurnDrvroute16b = { + "route16b", "route16", NULL, "1981", + "Route 16 (bootleg)\0", NULL, "bootleg", "Route 16", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, route16bRomInfo, route16bRomName, DrvInputInfo, DrvDIPInfo, + route16Init, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 3, 4 +}; + + +// Route X (bootleg) + +static struct BurnRomInfo routexRomDesc[] = { + { "routex01.a0", 0x0800, 0x99b500e7, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 #0 Code + { "rt16.1", 0x0800, 0x3ec52fe5, 1 | BRF_ESS | BRF_PRG }, // 1 + { "rt16.2", 0x0800, 0xa8e92871, 1 | BRF_ESS | BRF_PRG }, // 2 + { "rt16.3", 0x0800, 0xa0fc9fc5, 1 | BRF_ESS | BRF_PRG }, // 3 + { "routex05.a4", 0x0800, 0x2fef7653, 1 | BRF_ESS | BRF_PRG }, // 4 + { "routex06.a5", 0x0800, 0xa39ef648, 1 | BRF_ESS | BRF_PRG }, // 5 + { "routex07.a6", 0x0800, 0x89f80c1c, 1 | BRF_ESS | BRF_PRG }, // 6 + + { "routex11.b0", 0x0800, 0xb51edd1d, 2 | BRF_ESS | BRF_PRG }, // 7 Z80 #1 Code + { "rt16.7", 0x0800, 0xd0d6c189, 2 | BRF_ESS | BRF_PRG }, // 8 + { "rt16.8", 0x0800, 0xdefc5797, 2 | BRF_ESS | BRF_PRG }, // 9 + { "rt16.9", 0x0800, 0x88d94a66, 2 | BRF_ESS | BRF_PRG }, // 10 + + { "im5623.f10", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 11 Graphics + { "im5623.f12", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 12 +}; + +STD_ROM_PICK(routex); +STD_ROM_FN(routex); + +struct BurnDriver BurnDrvroutex = { + "routex", "route16", NULL, "1981", + "Route X (bootleg)\0", NULL, "bootleg", "Route 16", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, routexRomInfo, routexRomName, DrvInputInfo, DrvDIPInfo, + route16bInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 3, 4 +}; + + +// Speak & Rescue + +static struct BurnRomInfo speakresRomDesc[] = { + { "speakres.1", 0x0800, 0x6026e4ea, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 #0 Code + { "speakres.2", 0x0800, 0x93f0d4da, 1 | BRF_ESS | BRF_PRG }, // 1 + { "speakres.3", 0x0800, 0xa3874304, 1 | BRF_ESS | BRF_PRG }, // 2 + { "speakres.4", 0x0800, 0xf484be3a, 1 | BRF_ESS | BRF_PRG }, // 3 + { "speakres.5", 0x0800, 0x61b12a67, 1 | BRF_ESS | BRF_PRG }, // 4 + { "speakres.6", 0x0800, 0x220e0ab2, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "speakres.7", 0x0800, 0xd417be13, 2 | BRF_ESS | BRF_PRG }, // 6 Z80 #1 Code + { "speakres.8", 0x0800, 0x52485d60, 2 | BRF_ESS | BRF_PRG }, // 7 + + { "im5623.f10", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 8 Graphics + { "im5623.f12", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 9 +}; + +STD_ROM_PICK(speakres); +STD_ROM_FN(speakres); + +static int speakresInit() +{ + draw_type = 2; + + return DrvInit(); +} + +struct BurnDriver BurnDrvspeakres = { + "speakres", NULL, NULL, "1980", + "Speak & Rescue\0", NULL, "Sun Electronics", "Route 16", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, speakresRomInfo, speakresRomName, DrvInputInfo, speakresDIPInfo, + speakresInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 3, 4 +}; + + +// Stratovox + +static struct BurnRomInfo stratvoxRomDesc[] = { + { "ls01.bin", 0x0800, 0xbf4d582e, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 #0 Code + { "ls02.bin", 0x0800, 0x16739dd4, 1 | BRF_ESS | BRF_PRG }, // 1 + { "ls03.bin", 0x0800, 0x083c28de, 1 | BRF_ESS | BRF_PRG }, // 2 + { "ls04.bin", 0x0800, 0xb0927e3b, 1 | BRF_ESS | BRF_PRG }, // 3 + { "ls05.bin", 0x0800, 0xccd25c4e, 1 | BRF_ESS | BRF_PRG }, // 4 + { "ls06.bin", 0x0800, 0x07a907a7, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "ls07.bin", 0x0800, 0x4d333985, 2 | BRF_ESS | BRF_PRG }, // 6 Z80 #1 Code + { "ls08.bin", 0x0800, 0x35b753fc, 2 | BRF_ESS | BRF_PRG }, // 7 + + { "im5623.f10", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 8 Graphics + { "im5623.f12", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 9 +}; + +STD_ROM_PICK(stratvox); +STD_ROM_FN(stratvox); + +struct BurnDriver BurnDrvstratvox = { + "stratvox", "speakres", NULL, "1980", + "Stratovox\0", NULL, "[Sun Electronics] (Taito license)", "Route 16", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, stratvoxRomInfo, stratvoxRomName, DrvInputInfo, stratvoxDIPInfo, + speakresInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 3, 4 +}; + + +// Stratovox (bootleg) + +static struct BurnRomInfo stratvobRomDesc[] = { + { "j0-1", 0x0800, 0x93c78274, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 #0 Code + { "j0-2", 0x0800, 0x93b2b02d, 1 | BRF_ESS | BRF_PRG }, // 1 + { "j0-3", 0x0800, 0x655facb5, 1 | BRF_ESS | BRF_PRG }, // 2 + { "j0-4", 0x0800, 0xb0927e3b, 1 | BRF_ESS | BRF_PRG }, // 3 + { "j0-5", 0x0800, 0x9d2178d9, 1 | BRF_ESS | BRF_PRG }, // 4 + { "j0-6", 0x0800, 0x79118ffc, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "b0-a", 0x0800, 0x4d333985, 2 | BRF_ESS | BRF_PRG }, // 6 Z80 #1 Code + { "j0-a", 0x0800, 0x3416a830, 2 | BRF_ESS | BRF_PRG }, // 7 + + { "im5623.f10", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 8 Graphics + { "im5623.f12", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 9 +}; + +STD_ROM_PICK(stratvob); +STD_ROM_FN(stratvob); + +struct BurnDriver BurnDrvstratvob = { + "stratvob", "speakres", NULL, "1980", + "Stratovox (bootleg)\0", NULL, "bootleg", "Route 16", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, stratvobRomInfo, stratvobRomName, DrvInputInfo, stratvoxDIPInfo, + speakresInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 3, 4 +}; + + +// Space Echo (bootleg) + +static struct BurnRomInfo spacechoRomDesc[] = { + { "rom.a0", 0x0800, 0x40d74dce, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 #0 Code + { "rom.a1", 0x0800, 0xa5f0a34f, 1 | BRF_ESS | BRF_PRG }, // 1 + { "rom.a2", 0x0800, 0xcbbb3acb, 1 | BRF_ESS | BRF_PRG }, // 2 + { "rom.a3", 0x0800, 0x311050ca, 1 | BRF_ESS | BRF_PRG }, // 3 + { "rom.a4", 0x0800, 0x28943803, 1 | BRF_ESS | BRF_PRG }, // 4 + { "rom.a5", 0x0800, 0x851c9f28, 1 | BRF_ESS | BRF_PRG }, // 5 + + { "rom.b0", 0x0800, 0xdb45689d, 2 | BRF_ESS | BRF_PRG }, // 6 Z80 #1 Code + { "rom.b2", 0x0800, 0x1e074157, 2 | BRF_ESS | BRF_PRG }, // 7 + { "rom.b3", 0x0800, 0xd50a8b20, 2 | BRF_ESS | BRF_PRG }, // 8 + + { "im5623.f10", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 9 Graphics + { "im5623.f12", 0x0100, 0x08793ef7, 3 | BRF_GRA }, // 10 +}; + +STD_ROM_PICK(spacecho); +STD_ROM_FN(spacecho); + +static int spacechoInit() +{ + int nRet; + + draw_type = 3; + + nRet = DrvInit(); + + memcpy (Rom1 + 0x1000, Rom1 + 0x800, 0x1000); + + return nRet; +} + +struct BurnDriver BurnDrvspacecho = { + "spacecho", "speakres", NULL, "1980", + "Space Echo (bootleg)\0", NULL, "bootleg", "Route 16", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, spacechoRomInfo, spacechoRomName, DrvInputInfo, stratvoxDIPInfo, + spacechoInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 3, 4 +}; + + +// Mahjong + +static struct BurnRomInfo ttmahjngRomDesc[] = { + { "ju04", 0x1000, 0xfe7c693a, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 #0 Code + { "ju05", 0x1000, 0x985723d3, 1 | BRF_ESS | BRF_PRG }, // 1 + { "ju06", 0x1000, 0x2cd69bc8, 1 | BRF_ESS | BRF_PRG }, // 2 + { "ju07", 0x1000, 0x30e8ec63, 1 | BRF_ESS | BRF_PRG }, // 3 + + { "ju01", 0x0800, 0x0f05ca3c, 2 | BRF_ESS | BRF_PRG }, // 4 Z80 #1 Code + { "ju02", 0x0800, 0xc1ffeceb, 2 | BRF_ESS | BRF_PRG }, // 5 + { "ju08", 0x0800, 0x2dcc76b5, 2 | BRF_ESS | BRF_PRG }, // 6 + + { "ju03", 0x0100, 0x27d47624, 3 | BRF_GRA }, // 7 Graphics + { "ju09", 0x0100, 0x27d47624, 3 | BRF_GRA }, // 8 +}; + +STD_ROM_PICK(ttmahjng); +STD_ROM_FN(ttmahjng); + +static int ttmahjngInit() +{ + draw_type = 1; + + return DrvInit(); +} + +struct BurnDriver BurnDrvttmahjng = { + "ttmahjng", NULL, NULL, "1980", + "Mahjong\0", NULL, "Taito", "Route 16", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, ttmahjngRomInfo, ttmahjngRomName, mahjongInputInfo, NULL, + ttmahjngInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + diff --git a/src/burn/misc/pre90s/d_scregg.cpp b/src/burn/misc/pre90s/d_scregg.cpp new file mode 100644 index 0000000..60364de --- /dev/null +++ b/src/burn/misc/pre90s/d_scregg.cpp @@ -0,0 +1,721 @@ +#include "tiles_generic.h" +#include "m6502.h" +#include "bitswap.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +static unsigned char *Mem, *Rom, *Gfx0, *Gfx1, *Prom; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvDips[2], DrvReset; +static unsigned int *Palette, *DrvPalette; +static unsigned char DrvRecalcPal = 0; +static short *pFMBuffer, *pAY8910Buffer[6]; + +static int flipscreen = 0; +static int VBLK = 0; + +static int scregg = 0, rockduck = 0; + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy1 + 6, "p1 coin" }, + {"P1 start" , BIT_DIGITAL , DrvJoy2 + 6, "p1 start" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 0, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 1, "p1 left" }, + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 2, "p1 up", }, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down", }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 1"}, + + {"P2 Coin" , BIT_DIGITAL , DrvJoy1 + 7, "p2 coin" }, + {"P2 start" , BIT_DIGITAL , DrvJoy2 + 7, "p2 start" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 0, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 1, "p2 left" }, + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 2, "p2 up", }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down", }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 1"}, + + {"Reset", BIT_DIGITAL , &DrvReset, "reset" }, + {"Dip 1", BIT_DIPSWITCH, DrvDips + 0, "dip 1" }, + {"Dip 2", BIT_DIPSWITCH, DrvDips + 1, "dip 2" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x7f, NULL }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x0f, 0x01, 0x03, 0x00, "2C 1C" }, + {0x0f, 0x01, 0x03, 0x03, "1C 1C" }, + {0x0f, 0x01, 0x03, 0x01, "1C 2C" }, + {0x0f, 0x01, 0x03, 0x02, "1C 3C" }, + + {0 , 0xfe, 0 , 4 , "Coin B" }, + {0x0f, 0x01, 0x0c, 0x00, "2C 1C" }, + {0x0f, 0x01, 0x0c, 0x0c, "1C 3C" }, + {0x0f, 0x01, 0x0c, 0x04, "1C 2C" }, + {0x0f, 0x01, 0x0c, 0x08, "1C 3C" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x0f, 0x01, 0x40, 0x40, "Cocktail" }, + {0x0f, 0x01, 0x40, 0x00, "Upright" }, + + // Default Values + {0x10, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 2 , "Lives" }, + {0x10, 0x01, 0x01, 0x01, "3" }, + {0x10, 0x01, 0x01, 0x00, "5" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x10, 0x01, 0x06, 0x04, "30000" }, + {0x10, 0x01, 0x06, 0x02, "50000" }, + {0x10, 0x01, 0x06, 0x06, "70000" }, + {0x10, 0x01, 0x06, 0x00, "Never" }, + + {0 , 0xfe, 0 , 2 , "Difficulty" }, + {0x10, 0x01, 0x80, 0x80, "Easy" }, + {0x10, 0x01, 0x80, 0x00, "Hard" }, +}; + +STDDIPINFO(Drv); + +static inline int calc_mirror_offset(unsigned short address) +{ + int x, y, offset; + offset = address & 0x3ff; + + x = offset >> 5; + y = offset & 0x1f; + + return ((y << 5) | x); +} + +unsigned char eggs_readmem(unsigned short address) +{ + unsigned char ret = 0xff; + + if ((address & 0xf800) == 0x1800) { + return Rom[0x2000 + (address & 0x400) + calc_mirror_offset(address)]; + } + + switch (address) + { + case 0x2000: + return VBLK | DrvDips[0]; + + case 0x2001: + return DrvDips[1]; + + case 0x2002: + { + for (int i = 0; i < 8; i++) ret ^= DrvJoy1[i] << i; + + return ret; + } + + case 0x2003: + { + for (int i = 0; i < 8; i++) ret ^= DrvJoy2[i] << i; + + return ret; + } + } + + return 0; +} + +void eggs_writemem(unsigned short address, unsigned char data) +{ + if ((address & 0xf800) == 0x1800) { + Rom[0x2000 + (address & 0x400) + calc_mirror_offset(address)] = data; + return; + } + + switch (address) + { + case 0x2000: + flipscreen = data & 1; + break; + + case 0x2001: + break; + + case 0x2004: + case 0x2005: + case 0x2006: + case 0x2007: + AY8910Write((address >> 1) & 1, address & 1, data); + break; + } +} + +unsigned char dommy_readmem(unsigned short address) +{ + unsigned char ret = 0xff; + + if (address >= 0x2800 && address <= 0x2bff) { + return Rom[0x2000 + calc_mirror_offset(address)]; + } + + switch (address) + { + case 0x4000: + return DrvDips[0] | VBLK; + + case 0x4001: + return DrvDips[1]; + + case 0x4002: + { + for (int i = 0; i < 8; i++) ret ^= DrvJoy1[i] << i; + + return ret; + } + + case 0x4003: + { + for (int i = 0; i < 8; i++) ret ^= DrvJoy2[i] << i; + + return ret; + } + } + + return 0; +} + +void dommy_writemem(unsigned short address, unsigned char data) +{ + if (address >= 0x2800 && address <= 0x2bff) { + Rom[0x2000 + calc_mirror_offset(address)] = data; + return; + } + + switch (address) + { + case 0x4000: + break; + + case 0x4001: + flipscreen = data & 1; + break; + + case 0x4004: + case 0x4005: + case 0x4006: + case 0x4007: + AY8910Write((address >> 1) & 1, address & 1, data); + break; + } +} + + +static int DrvDoReset() +{ + memset (Rom, 0, 0x3000); + + flipscreen = 0; + + m6502Open(0); + m6502Reset(); + m6502Close(); + + AY8910Reset(0); + AY8910Reset(1); + + return 0; +} + + +static int scregg_gfx_convert() +{ + static int PlaneOffsets[3] = { 0x20000, 0x10000, 0 }; + static int XOffsets[16] = { 128, 129, 130, 131, 132, 133, 134, 135, 0, 1, 2, 3, 4, 5, 6, 7 }; + static int YOffsets[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }; + + unsigned char *tmp = (unsigned char*)malloc(0x6000); + if (tmp == NULL) { + return 1; + } + + memcpy (tmp, Gfx0, 0x6000); + + GfxDecode(0x400, 3, 8, 8, PlaneOffsets, XOffsets + 8, YOffsets, 0x040, tmp, Gfx0); + GfxDecode(0x100, 3, 16, 16, PlaneOffsets, XOffsets + 0, YOffsets, 0x100, tmp, Gfx1); + + free (tmp); + + return 0; +} + +static int scregg_palette_init() +{ + for (int i = 0;i < 8;i++) + { + int bit0,bit1,bit2,r,g,b; + + bit0 = (Prom[i] >> 0) & 0x01; + bit1 = (Prom[i] >> 1) & 0x01; + bit2 = (Prom[i] >> 2) & 0x01; + r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = (Prom[i] >> 3) & 0x01; + bit1 = (Prom[i] >> 4) & 0x01; + bit2 = (Prom[i] >> 5) & 0x01; + g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + bit0 = 0; + bit1 = (Prom[i] >> 6) & 0x01; + bit2 = (Prom[i] >> 7) & 0x01; + b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + Palette[i] = (r << 16) | (g << 8) | b; + } + + return 0; +} + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x10000 + 0x10000 + 0x10000 + 0x20 + 0x40); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short *)malloc (nBurnSoundLen * 6 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + Rom = Mem + 0x00000; + Gfx0 = Mem + 0x10000; + Gfx1 = Mem + 0x20000; + Prom = Mem + 0x30000; + Palette = (unsigned int*)(Mem + 0x30020); + DrvPalette = (unsigned int*)(Mem + 0x30040); + + if (scregg) + { + if (rockduck) { + if (BurnLoadRom(Rom + 0x4000, 0, 1)) return 1; + if (BurnLoadRom(Rom + 0x6000, 1, 1)) return 1; + if (BurnLoadRom(Rom + 0x8000, 2, 1)) return 1; + memcpy (Rom + 0x3000, Rom + 0x5000, 0x1000); + memcpy (Rom + 0x5000, Rom + 0x7000, 0x1000); + memcpy (Rom + 0xe000, Rom + 0x8000, 0x2000); + memcpy (Rom + 0x7000, Rom + 0x9000, 0x1000); + + if (BurnLoadRom(Gfx0 + 0x0000, 3, 1)) return 1; + if (BurnLoadRom(Gfx0 + 0x2000, 4, 1)) return 1; + if (BurnLoadRom(Gfx0 + 0x4000, 5, 1)) return 1; + + if (BurnLoadRom(Prom + 0x0000, 6, 1)) return 1; + + for (int i = 0x2000; i < 0x6000; i++) + Gfx0[i] = BITSWAP08(Gfx0[i],2,0,3,6,1,4,7,5); + + } else { + for (int i = 0; i < 5; i++) + if (BurnLoadRom(Rom + 0x3000 + i * 0x1000, i, 1)) return 1; + + memcpy (Rom + 0xf000, Rom + 0x7000, 0x1000); + + for (int i = 0; i < 6; i++) + if (BurnLoadRom(Gfx0 + i * 0x1000, i + 5, 1)) return 1; + + if (BurnLoadRom(Prom, 11, 1)) return 1; + } + + m6502Init(1); + m6502Open(0); + m6502SetReadHandler(eggs_readmem); + m6502SetWriteHandler(eggs_writemem); + m6502MapMemory(Rom + 0x0000, 0x0000, 0x07ff, M6502_RAM); + m6502MapMemory(Rom + 0x2000, 0x1000, 0x17ff, M6502_RAM); + m6502MapMemory(Rom + 0x3000, 0x3000, 0x7fff, M6502_ROM); + m6502MapMemory(Rom + 0xf000, 0xf000, 0xffff, M6502_ROM); + m6502Close(); + } else { + for (int i = 0; i < 3; i++) { + if (BurnLoadRom(Rom + 0xa000 + i * 0x2000, i, 1)) return 1; + if (BurnLoadRom(Gfx0 + 0x0000 + i * 0x2000, 3 + i, 1)) return 1; + } + + if (BurnLoadRom(Prom, 6, 1)) return 1; + memcpy (Prom, Prom + 0x18, 8); + + m6502Init(1); + m6502Open(0); + m6502SetReadHandler(dommy_readmem); + m6502SetWriteHandler(dommy_writemem); + m6502MapMemory(Rom + 0x0000, 0x0000, 0x07ff, M6502_RAM); + m6502MapMemory(Rom + 0x2000, 0x2000, 0x27ff, M6502_RAM); + m6502MapMemory(Rom + 0xa000, 0xa000, 0xffff, M6502_ROM); + m6502Close(); + } + + scregg_gfx_convert(); + scregg_palette_init(); + +// BurnSetRefreshRate(57); // Proper rate, but the AY8910 can't handle it + + GenericTilesInit(); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + pAY8910Buffer[3] = pFMBuffer + nBurnSoundLen * 3; + pAY8910Buffer[4] = pFMBuffer + nBurnSoundLen * 4; + pAY8910Buffer[5] = pFMBuffer + nBurnSoundLen * 5; + + AY8910Init(0, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(1, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + m6502Exit(); + AY8910Exit(0); + AY8910Exit(1); + GenericTilesExit(); + + free (Mem); + DrvRecalcPal = 0; + flipscreen = 0; + + scregg = rockduck = 0; + VBLK = 0; + + return 0; +} + +static void draw_chars() +{ + for (int offs = 0; offs < 0x400; offs++) + { + int sx = (~offs >> 2) & 0xf8; + int sy = ( offs & 0x1f) << 3; + + unsigned short code = Rom[0x2000 | offs] | ((Rom[0x2400 | offs] & 3) << 8); + + if (flipscreen) + { + sx ^= 0xf8; + sy ^= 0xf8; + } + + sy -= 8; + if (scregg) sx -= 8; + + if (flipscreen) { + Render8x8Tile_FlipXY_Clip(pTransDraw, code, sx, sy, 0, 3, 0, Gfx0); + } else { + Render8x8Tile_Clip(pTransDraw, code, sx, sy, 0, 3, 0, Gfx0); + } + } +} + +static void draw_sprites() +{ + for (int i = 0, offs = 0; i < 8; i++, offs += 4*0x20) + { + int sx, sy, code; + unsigned char flipx,flipy; + + if (!(Rom[0x2000 + offs] & 0x01)) continue; + + sx = 240 - Rom[0x2000 + offs + 0x60]; + sy = 240 - Rom[0x2000 + offs + 0x40]; + + flipx = Rom[0x2000 + offs] & 0x04; + flipy = Rom[0x2000 + offs] & 0x02; + + code = Rom[0x2000 + offs + 0x20]; + + if (flipscreen) + { + sx = 240 - sx; + sy = 240 - sy; + + flipx = !flipx; + flipy = !flipy; + } + + sy -= 8; + if (scregg) sx -= 8; + + if (flipy) { + if (flipx) { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, code, sx, sy, 0, 3, 0, 0, Gfx1); + } else { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, code, sx, sy, 0, 3, 0, 0, Gfx1); + } + } else { + if (flipx) { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, code, sx, sy, 0, 3, 0, 0, Gfx1); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, 0, 3, 0, 0, Gfx1); + } + } + } +} + +static int DrvDraw() +{ + // check to see if we need to recalculate the palette + if (DrvRecalcPal) { + for (int i = 0; i < 8; i++) { + int col = Palette[i]; + DrvPalette[i] = BurnHighCol(col >> 16, col >> 8, col, 0); + } + } + + draw_chars(); + draw_sprites(); + + BurnTransferCopy(DrvPalette); + + return 0; +} + +static inline void scregg_interrupt_handler(int scanline) +{ + if (scanline == 0) + VBLK = 0; + + if (scanline == 14) + VBLK = 0x80; + + m6502SetIRQ(M6502_IRQ); +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + int nTotalCycles = (int)((double)(1500000 / 57)); + int nCyclesRun = 0; + + m6502Open(0); + + for (int i = 0; i < 16; i++) { + nCyclesRun += m6502Run((nTotalCycles - nCyclesRun) / (16 - i)); + scregg_interrupt_handler(i); + } + + m6502Close(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0x0000; + ba.nLen = 0x3000; + ba.szName = "All Ram"; + BurnAcb(&ba); + + m6502Scan(nAction); + AY8910Scan(nAction, pnMin); + + // Scan critical driver variables + SCAN_VAR(flipscreen); + } + + return 0; +} + + +// Dommy + +static struct BurnRomInfo dommyRomDesc[] = { + { "dommy.e01", 0x2000, 0x9ae064ed, 1 | BRF_ESS | BRF_PRG }, // 0 M6502 Code + { "dommy.e11", 0x2000, 0x7c4fad5c, 1 | BRF_ESS | BRF_PRG }, // 1 + { "dommy.e21", 0x2000, 0xcd1a4d55, 1 | BRF_ESS | BRF_PRG }, // 2 + + { "dommy.e50", 0x2000, 0x5e9db0a4, 2 | BRF_GRA }, // 3 Graphics + { "dommy.e40", 0x2000, 0x4d1c36fb, 2 | BRF_GRA }, // 4 + { "dommy.e30", 0x2000, 0x4e68bb12, 2 | BRF_GRA }, // 5 + + { "dommy.e70", 0x0020, 0x50c1d86e, 3 | BRF_GRA }, // 6 Palette + + { "dommy.e60", 0x0020, 0x24da2b63, 4 | BRF_OPT }, // 7 +}; + +STD_ROM_PICK(dommy); +STD_ROM_FN(dommy); + +struct BurnDriver BurnDrvdommy = { + "dommy", NULL, NULL, "198?", + "Dommy\0", NULL, "Technos", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, dommyRomInfo, dommyRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 240, 248, 3, 4 +}; + + +// Scrambled Egg + +static struct BurnRomInfo screggRomDesc[] = { + { "scregg.e14", 0x1000, 0x29226d77, 1 | BRF_ESS | BRF_PRG }, // 0 M6502 Code + { "scregg.d14", 0x1000, 0xeb143880, 1 | BRF_ESS | BRF_PRG }, // 1 + { "scregg.c14", 0x1000, 0x4455f262, 1 | BRF_ESS | BRF_PRG }, // 2 + { "scregg.b14", 0x1000, 0x044ac5d2, 1 | BRF_ESS | BRF_PRG }, // 3 + { "scregg.a14", 0x1000, 0xb5a0814a, 1 | BRF_ESS | BRF_PRG }, // 4 + + { "scregg.j12", 0x1000, 0xa485c10c, 2 | BRF_GRA }, // 5 Graphics + { "scregg.j10", 0x1000, 0x1fd4e539, 2 | BRF_GRA }, // 6 + { "scregg.h12", 0x1000, 0x8454f4b2, 2 | BRF_GRA }, // 7 + { "scregg.h10", 0x1000, 0x72bd89ee, 2 | BRF_GRA }, // 8 + { "scregg.g12", 0x1000, 0xff3c2894, 2 | BRF_GRA }, // 9 + { "scregg.g10", 0x1000, 0x9c20214a, 2 | BRF_GRA }, // 10 + + { "screggco.c6", 0x0020, 0xff23bdd6, 3 | BRF_GRA }, // 11 Palette + + { "screggco.b4", 0x0020, 0x7cc4824b, 0 | BRF_OPT }, // 12 +}; + +STD_ROM_PICK(scregg); +STD_ROM_FN(scregg); + +static int screggInit() +{ + scregg = 1; + + return DrvInit(); +} + +struct BurnDriver BurnDrvscregg = { + "scregg", NULL, NULL, "1983", + "Scrambled Egg\0", NULL, "Technos", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, screggRomInfo, screggRomName, DrvInputInfo, DrvDIPInfo, + screggInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 240, 240, 3, 4 +}; + + +// Eggs + +static struct BurnRomInfo eggsRomDesc[] = { + { "e14.bin", 0x1000, 0x4e216f9d, 1 | BRF_ESS | BRF_PRG }, // 0 M6502 Code + { "d14.bin", 0x1000, 0x4edb267f, 1 | BRF_ESS | BRF_PRG }, // 1 + { "c14.bin", 0x1000, 0x15a5c48c, 1 | BRF_ESS | BRF_PRG }, // 2 + { "b14.bin", 0x1000, 0x5c11c00e, 1 | BRF_ESS | BRF_PRG }, // 3 + { "a14.bin", 0x1000, 0x953faf07, 1 | BRF_ESS | BRF_PRG }, // 4 + + { "j12.bin", 0x1000, 0xce4a2e46, 2 | BRF_GRA }, // 5 Graphics + { "j10.bin", 0x1000, 0xa1bcaffc, 2 | BRF_GRA }, // 6 + { "h12.bin", 0x1000, 0x9562836d, 2 | BRF_GRA }, // 7 + { "h10.bin", 0x1000, 0x3cfb3a8e, 2 | BRF_GRA }, // 8 + { "g12.bin", 0x1000, 0x679f8af7, 2 | BRF_GRA }, // 9 + { "g10.bin", 0x1000, 0x5b58d3b5, 2 | BRF_GRA }, // 10 + + { "eggs.c6", 0x0020, 0xe8408c81, 3 | BRF_GRA }, // 11 Palette + + { "screggco.b4", 0x0020, 0x7cc4824b, 0 | BRF_OPT }, // 12 +}; + +STD_ROM_PICK(eggs); +STD_ROM_FN(eggs); + +struct BurnDriver BurnDrveggs = { + "eggs", "scregg", NULL, "1983", + "Eggs\0", NULL, "[Technos] Universal USA", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, eggsRomInfo, eggsRomName, DrvInputInfo, DrvDIPInfo, + screggInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 240, 240, 3, 4 +}; + + +// Rock Duck (prototype?) + +static struct BurnRomInfo rockduckRomDesc[] = { + { "rde.bin", 0x2000, 0x56e2a030, 1 | BRF_ESS | BRF_PRG }, // 0 M6502 Code + { "rdc.bin", 0x2000, 0x482d9a0c, 1 | BRF_ESS | BRF_PRG }, // 1 + { "rdb.bin", 0x2000, 0x974626f2, 1 | BRF_ESS | BRF_PRG }, // 2 + + + { "rd3.rdg", 0x2000, 0x8a3f1e53, 2 | BRF_GRA }, // 3 Graphics + { "rd2.rdh", 0x2000, 0xe94e673e, 2 | BRF_GRA }, // 4 + { "rd1.rdj", 0x2000, 0x654afff2, 2 | BRF_GRA }, // 5 + + { "eggs.c6", 0x0020, 0xe8408c81, 3 | BRF_GRA }, // 6 Palette +}; + +STD_ROM_PICK(rockduck); +STD_ROM_FN(rockduck); + +static int rockduckInit() +{ + scregg = 1; + rockduck = 1; + + return DrvInit(); +} + +struct BurnDriver BurnDrvrockduck = { + "rockduck", NULL, NULL, "1983", + "Rock Duck (prototype?)\0", "incorrect colors", "Datel SAS", "misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, rockduckRomInfo, rockduckRomName, DrvInputInfo, DrvDIPInfo, + rockduckInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalcPal, + 240, 240, 3, 4 +}; diff --git a/src/burn/misc/pre90s/d_solomon.cpp b/src/burn/misc/pre90s/d_solomon.cpp new file mode 100644 index 0000000..7cf5703 --- /dev/null +++ b/src/burn/misc/pre90s/d_solomon.cpp @@ -0,0 +1,829 @@ +#include "tiles_generic.h" + +#include "driver.h" +extern "C" { + #include "ay8910.h" +} + +static unsigned char SolomonInputPort0[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char SolomonInputPort1[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char SolomonInputPort2[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char SolomonDip[2] = {0, 0}; +static unsigned char SolomonInput[3] = {0x00, 0x00, 0x00}; +static unsigned char SolomonReset = 0; + +static unsigned char *Mem = NULL; +static unsigned char *MemEnd = NULL; +static unsigned char *RamStart = NULL; +static unsigned char *RamEnd = NULL; +static unsigned char *SolomonZ80Rom1 = NULL; +static unsigned char *SolomonZ80Rom2 = NULL; +static unsigned char *SolomonZ80Ram1 = NULL; +static unsigned char *SolomonZ80Ram2 = NULL; +static unsigned char *SolomonColourRam = NULL; +static unsigned char *SolomonVideoRam = NULL; +static unsigned char *SolomonBgColourRam = NULL; +static unsigned char *SolomonBgVideoRam = NULL; +static unsigned char *SolomonSpriteRam = NULL; +static unsigned char *SolomonPaletteRam = NULL; +static unsigned int *SolomonPalette = NULL; +static unsigned char *SolomonBgTiles = NULL; +static unsigned char *SolomonFgTiles = NULL; +static unsigned char *SolomonSprites = NULL; +static unsigned char *SolomonTempRom = NULL; + +static int SolomonIrqFire = 0; + +static int SolomonFlipScreen = 0; + +static int SolomonSoundLatch = 0; +static short* pFMBuffer; +static short* pAY8910Buffer[9]; + +static int nCyclesDone[2], nCyclesTotal[2]; +static int nCyclesSegment; + +static struct BurnInputInfo SolomonInputList[] = +{ + {"Coin 1" , BIT_DIGITAL , SolomonInputPort2 + 2, "p1 coin" }, + {"Start 1" , BIT_DIGITAL , SolomonInputPort2 + 0, "p1 start" }, + {"Coin 2" , BIT_DIGITAL , SolomonInputPort2 + 3, "p2 coin" }, + {"Start 2" , BIT_DIGITAL , SolomonInputPort2 + 1, "p2 start" }, + + {"Up" , BIT_DIGITAL , SolomonInputPort0 + 2, "p1 up" }, + {"Down" , BIT_DIGITAL , SolomonInputPort0 + 3, "p1 down" }, + {"Left" , BIT_DIGITAL , SolomonInputPort0 + 1, "p1 left" }, + {"Right" , BIT_DIGITAL , SolomonInputPort0 + 0, "p1 right" }, + {"Fire 1" , BIT_DIGITAL , SolomonInputPort0 + 5, "p1 fire 1" }, + {"Fire 2" , BIT_DIGITAL , SolomonInputPort0 + 4, "p1 fire 2" }, + + {"Up (Cocktail)" , BIT_DIGITAL , SolomonInputPort1 + 2, "p2 up" }, + {"Down (Cocktail)" , BIT_DIGITAL , SolomonInputPort1 + 3, "p2 down" }, + {"Left (Cocktail)" , BIT_DIGITAL , SolomonInputPort1 + 1, "p2 left" }, + {"Right (Cocktail)" , BIT_DIGITAL , SolomonInputPort1 + 0, "p2 right" }, + {"Fire 1 (Cocktail)" , BIT_DIGITAL , SolomonInputPort1 + 5, "p2 fire 1" }, + {"Fire 2 (Cocktail)" , BIT_DIGITAL , SolomonInputPort1 + 4, "p2 fire 2" }, + + {"Reset" , BIT_DIGITAL , &SolomonReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, SolomonDip + 0 , "dip" }, + {"Dip 2" , BIT_DIPSWITCH, SolomonDip + 1 , "dip" }, +}; + +STDINPUTINFO(Solomon); + +inline void SolomonClearOpposites(unsigned char* nJoystickInputs) +{ + if ((*nJoystickInputs & 0x03) == 0x03) { + *nJoystickInputs &= ~0x03; + } + if ((*nJoystickInputs & 0x0c) == 0x0c) { + *nJoystickInputs &= ~0x0c; + } +} + +inline void SolomonMakeInputs() +{ + // Reset Inputs + SolomonInput[0] = SolomonInput[1] = SolomonInput[2] = 0x00; + + // Compile Digital Inputs + for (int i = 0; i < 8; i++) { + SolomonInput[0] |= (SolomonInputPort0[i] & 1) << i; + SolomonInput[1] |= (SolomonInputPort1[i] & 1) << i; + SolomonInput[2] |= (SolomonInputPort2[i] & 1) << i; + } + + // Clear Opposites + SolomonClearOpposites(&SolomonInput[0]); + SolomonClearOpposites(&SolomonInput[1]); +} + +static struct BurnDIPInfo SolomonDIPList[]= +{ + // Default Values + {0x11, 0xff, 0xff, 0x02, NULL }, + {0x12, 0xff, 0xff, 0x00, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x11, 0x01, 0x01, 0x01, "Off" }, + {0x11, 0x01, 0x01, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x11, 0x01, 0x02, 0x02, "Upright" }, + {0x11, 0x01, 0x02, 0x00, "Cocktail" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x11, 0x01, 0x0c, 0x0c, "2" }, + {0x11, 0x01, 0x0c, 0x00, "3" }, + {0x11, 0x01, 0x0c, 0x08, "4" }, + {0x11, 0x01, 0x0c, 0x04, "5" }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x11, 0x01, 0xc0, 0x80, "2 Coins 1 Play" }, + {0x11, 0x01, 0xc0, 0x00, "1 Coin 1 Play" }, + {0x11, 0x01, 0xc0, 0x40, "1 Coin 2 Play" }, + {0x11, 0x01, 0xc0, 0xc0, "1 Coin 3 Play" }, + + {0 , 0xfe, 0 , 4 , "Coin B" }, + {0x11, 0x01, 0x30, 0x20, "2 Coins 1 Play" }, + {0x11, 0x01, 0x30, 0x00, "1 Coin 1 Play" }, + {0x11, 0x01, 0x30, 0x10, "1 Coin 2 Play" }, + {0x11, 0x01, 0x30, 0x30, "1 Coin 3 Play" }, + + // Dip 2 + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x12, 0x01, 0x03, 0x02, "Easy" }, + {0x12, 0x01, 0x03, 0x00, "Normal" }, + {0x12, 0x01, 0x03, 0x01, "Harder" }, + {0x12, 0x01, 0x03, 0x03, "Difficult" }, + + {0 , 0xfe, 0 , 4 , "Timer Speed" }, + {0x12, 0x01, 0x0c, 0x08, "Slow" }, + {0x12, 0x01, 0x0c, 0x00, "Normal" }, + {0x12, 0x01, 0x0c, 0x04, "Faster" }, + {0x12, 0x01, 0x0c, 0x0c, "Fastest" }, + + {0 , 0xfe, 0 , 2 , "Extra" }, + {0x12, 0x01, 0x10, 0x00, "Normal" }, + {0x12, 0x01, 0x10, 0x10, "Difficult" }, + + {0 , 0xfe, 0 , 8 , "Bonus Life" }, + {0x12, 0x01, 0xe0, 0x00, "30k 200k 500k" }, + {0x12, 0x01, 0xe0, 0x80, "100k 300k 800k" }, + {0x12, 0x01, 0xe0, 0x40, "30k 200k" }, + {0x12, 0x01, 0xe0, 0xc0, "100k 300k" }, + {0x12, 0x01, 0xe0, 0x20, "30k" }, + {0x12, 0x01, 0xe0, 0xa0, "100k" }, + {0x12, 0x01, 0xe0, 0x60, "200k" }, + {0x12, 0x01, 0xe0, 0xe0, "None" }, +}; + +STDDIPINFO(Solomon); + +static struct BurnRomInfo SolomonRomDesc[] = { + { "6.3f", 0x04000, 0x645eb0f3, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "7.3h", 0x08000, 0x1bf5c482, BRF_ESS | BRF_PRG }, // 1 Z80 #1 Program Code + { "8.3jk", 0x08000, 0x0a6cdefc, BRF_ESS | BRF_PRG }, // 2 Z80 #1 Program Code + + { "1.3jk", 0x04000, 0xfa6e562e, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program Code + + { "12.3t", 0x08000, 0xb371291c, BRF_GRA }, // 4 Characters + { "11.3r", 0x08000, 0x6f94d2af, BRF_GRA }, // 5 Characters + { "10.3p", 0x08000, 0x8310c2a1, BRF_GRA }, // 6 Characters + { "9.3m", 0x08000, 0xab7e6c42, BRF_GRA }, // 7 Characters + { "2.5lm", 0x04000, 0x80fa2be3, BRF_GRA }, // 8 Sprites + { "3.6lm", 0x04000, 0x236106b4, BRF_GRA }, // 9 Sprites + { "4.7lm", 0x04000, 0x088fe5d9, BRF_GRA }, // 10 Sprites + { "5.8lm", 0x04000, 0x8366232a, BRF_GRA }, // 11 Sprites +}; + + +STD_ROM_PICK(Solomon); +STD_ROM_FN(Solomon); + +static struct BurnRomInfo SolomonjRomDesc[] = { + { "slmn_06.bin", 0x04000, 0xe4d421ff, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "slmn_07.bin", 0x08000, 0xd52d7e38, BRF_ESS | BRF_PRG }, // 1 Z80 #1 Program Code + { "slmn_08.bin", 0x01000, 0xb924d162, BRF_ESS | BRF_PRG }, // 2 Z80 #1 Program Code + + { "slmn_01.bin", 0x04000, 0xfa6e562e, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program Code + + { "slmn_12.bin", 0x08000, 0xaa26dfcb, BRF_GRA }, // 4 Characters + { "slmn_11.bin", 0x08000, 0x6f94d2af, BRF_GRA }, // 5 Characters + { "slmn_10.bin", 0x08000, 0x8310c2a1, BRF_GRA }, // 6 Characters + { "slmn_09.bin", 0x08000, 0xab7e6c42, BRF_GRA }, // 7 Characters + { "slmn_02.bin", 0x04000, 0x80fa2be3, BRF_GRA }, // 8 Sprites + { "slmn_03.bin", 0x04000, 0x236106b4, BRF_GRA }, // 9 Sprites + { "slmn_04.bin", 0x04000, 0x088fe5d9, BRF_GRA }, // 10 Sprites + { "slmn_05.bin", 0x04000, 0x8366232a, BRF_GRA }, // 11 Sprites +}; + + +STD_ROM_PICK(Solomonj); +STD_ROM_FN(Solomonj); + +int SolomonDoReset() +{ + SolomonIrqFire = 0; + SolomonFlipScreen = 0; + SolomonSoundLatch = 0; + + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + } + + for (int i = 0; i < 3; i++) { + AY8910Reset(i); + } + + return 0; +} + +unsigned char __fastcall SolomonRead1(unsigned short a) +{ + switch (a) { + case 0xe600: { + return SolomonInput[0]; + } + + case 0xe601: { + return SolomonInput[1]; + } + + case 0xe602: { + return SolomonInput[2]; + } + + case 0xe604: { + return SolomonDip[0]; + } + + case 0xe605: { + return SolomonDip[1]; + } + } + + return 0; +} + +void __fastcall SolomonWrite1(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xe600: { + SolomonIrqFire = d; + return; + } + + case 0xe604: { + SolomonFlipScreen = d & 1; + return; + } + + case 0xe800: { + SolomonSoundLatch = d; + ZetClose(); + ZetOpen(1); + ZetNmi(); + ZetClose(); + ZetOpen(0); + return; + } + } +} + +unsigned char __fastcall SolomonRead2(unsigned short a) +{ + switch (a) { + case 0x8000: { + return SolomonSoundLatch; + } + } + + return 0; +} + +void __fastcall SolomonPortWrite2(unsigned short a, unsigned char d) +{ + a &= 0xff; + + switch (a) { + case 0x10: { + AY8910Write(0, 0, d); + return; + } + + case 0x11: { + AY8910Write(0, 1, d); + return; + } + + case 0x20: { + AY8910Write(1, 0, d); + return; + } + + case 0x21: { + AY8910Write(1, 1, d); + return; + } + + case 0x30: { + AY8910Write(2, 0, d); + return; + } + + case 0x31: { + AY8910Write(2, 1, d); + return; + } + } +} + +static int SolomonMemIndex() +{ + unsigned char *Next; Next = Mem; + + SolomonZ80Rom1 = Next; Next += 0x10000; + SolomonZ80Rom2 = Next; Next += 0x04000; + + RamStart = Next; + + SolomonZ80Ram1 = Next; Next += 0x01000; + SolomonZ80Ram2 = Next; Next += 0x00800; + SolomonColourRam = Next; Next += 0x00400; + SolomonVideoRam = Next; Next += 0x00400; + SolomonBgColourRam = Next; Next += 0x00400; + SolomonBgVideoRam = Next; Next += 0x00400; + SolomonSpriteRam = Next; Next += 0x00080; + SolomonPaletteRam = Next; Next += 0x00200; + + RamEnd = Next; + + SolomonBgTiles = Next; Next += 2048 * 8 * 8; + SolomonFgTiles = Next; Next += 2048 * 8 * 8; + SolomonSprites = Next; Next += 2048 * 8 * 8; + pFMBuffer = (short*)Next; Next += nBurnSoundLen * 9 * sizeof(short); + SolomonPalette = (unsigned int*)Next; Next += 0x00200 * sizeof(unsigned int); + + MemEnd = Next; + + return 0; +} + +static int TilePlaneOffsets[4] = { 0, 1, 2, 3 }; +static int TileXOffsets[8] = { 0, 4, 8, 12, 16, 20, 24, 28 }; +static int TileYOffsets[8] = { 0, 32, 64, 96, 128, 160, 192, 224 }; +static int SpritePlaneOffsets[4] = { 0, 131072, 262144, 393216 }; +static int SpriteXOffsets[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 64, 65, 66, 67, 68, 69, 70, 71 }; +static int SpriteYOffsets[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 128, 136, 144, 152, 160, 168, 176, 184 }; + +int SolomonInit() +{ + int nRet = 0, nLen; + + // Allocate and Blank all required memory + Mem = NULL; + SolomonMemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + SolomonMemIndex(); + + SolomonTempRom = (unsigned char *)malloc(0x10000); + + // Load Z80 #1 Program Roms + nRet = BurnLoadRom(SolomonZ80Rom1, 0, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(SolomonTempRom, 1, 1); if (nRet != 0) return 1; + memcpy(SolomonZ80Rom1 + 0x4000, SolomonTempRom + 0x4000, 0x4000); + memcpy(SolomonZ80Rom1 + 0x8000, SolomonTempRom + 0x0000, 0x4000); + memset(SolomonTempRom, 0, 0x10000); + nRet = BurnLoadRom(SolomonTempRom, 2, 1); if (nRet != 0) return 1; + memcpy(SolomonZ80Rom1 + 0xf000, SolomonTempRom, 0x1000); + + // Load Z80 #2 Program Rom + nRet = BurnLoadRom(SolomonZ80Rom2, 3, 1); if (nRet != 0) return 1; + + // Load and decode Bg Tiles + memset(SolomonTempRom, 0, 0x10000); + nRet = BurnLoadRom(SolomonTempRom + 0x0000, 6, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(SolomonTempRom + 0x8000, 7, 1); if (nRet != 0) return 1; + GfxDecode(2048, 4, 8, 8, TilePlaneOffsets, TileXOffsets, TileYOffsets, 0x100, SolomonTempRom, SolomonBgTiles); + + // Load and decode Fg Tiles + memset(SolomonTempRom, 0, 0x10000); + nRet = BurnLoadRom(SolomonTempRom + 0x0000, 4, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(SolomonTempRom + 0x8000, 5, 1); if (nRet != 0) return 1; + GfxDecode(2048, 4, 8, 8, TilePlaneOffsets, TileXOffsets, TileYOffsets, 0x100, SolomonTempRom, SolomonFgTiles); + + // Load and decode Sprite Tiles + memset(SolomonTempRom, 0, 0x10000); + nRet = BurnLoadRom(SolomonTempRom + 0x0000, 8, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(SolomonTempRom + 0x4000, 9, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(SolomonTempRom + 0x8000, 10, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(SolomonTempRom + 0xc000, 11, 1); if (nRet != 0) return 1; +// SolomonDecodeSprites(SolomonSprites, 2048, 0x0000, 0x4000, 0x8000, 0xc000); + GfxDecode(512, 4, 16, 16, SpritePlaneOffsets, SpriteXOffsets, SpriteYOffsets, 0x100, SolomonTempRom, SolomonSprites); + + // Setup the Z80 emulation + ZetInit(2); + ZetOpen(0); + ZetSetReadHandler(SolomonRead1); + ZetSetWriteHandler(SolomonWrite1); + ZetMapArea(0x0000, 0xbfff, 0, SolomonZ80Rom1 ); + ZetMapArea(0x0000, 0xbfff, 2, SolomonZ80Rom1 ); + ZetMapArea(0xc000, 0xcfff, 0, SolomonZ80Ram1 ); + ZetMapArea(0xc000, 0xcfff, 1, SolomonZ80Ram1 ); + ZetMapArea(0xc000, 0xcfff, 2, SolomonZ80Ram1 ); + ZetMapArea(0xd000, 0xd3ff, 0, SolomonColourRam ); + ZetMapArea(0xd000, 0xd3ff, 1, SolomonColourRam ); + ZetMapArea(0xd000, 0xd3ff, 2, SolomonColourRam ); + ZetMapArea(0xd400, 0xd7ff, 0, SolomonVideoRam ); + ZetMapArea(0xd400, 0xd7ff, 1, SolomonVideoRam ); + ZetMapArea(0xd400, 0xd7ff, 2, SolomonVideoRam ); + ZetMapArea(0xd800, 0xdbff, 0, SolomonBgColourRam ); + ZetMapArea(0xd800, 0xdbff, 1, SolomonBgColourRam ); + ZetMapArea(0xd800, 0xdbff, 2, SolomonBgColourRam ); + ZetMapArea(0xdc00, 0xdfff, 0, SolomonBgVideoRam ); + ZetMapArea(0xdc00, 0xdfff, 1, SolomonBgVideoRam ); + ZetMapArea(0xdc00, 0xdfff, 2, SolomonBgVideoRam ); + ZetMapArea(0xe000, 0xe07f, 0, SolomonSpriteRam ); + ZetMapArea(0xe000, 0xe07f, 1, SolomonSpriteRam ); + ZetMapArea(0xe000, 0xe07f, 2, SolomonSpriteRam ); + ZetMapArea(0xe400, 0xe5ff, 0, SolomonPaletteRam ); + ZetMapArea(0xe400, 0xe5ff, 1, SolomonPaletteRam ); + ZetMapArea(0xe400, 0xe5ff, 2, SolomonPaletteRam ); + ZetMapArea(0xf000, 0xffff, 0, SolomonZ80Rom1 + 0xf000); + ZetMapArea(0xf000, 0xffff, 2, SolomonZ80Rom1 + 0xf000); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetSetReadHandler(SolomonRead2); + ZetSetOutHandler(SolomonPortWrite2); + ZetMapArea(0x0000, 0x3fff, 0, SolomonZ80Rom2 ); + ZetMapArea(0x0000, 0x3fff, 2, SolomonZ80Rom2 ); + ZetMapArea(0x4000, 0x47ff, 0, SolomonZ80Ram2 ); + ZetMapArea(0x4000, 0x47ff, 1, SolomonZ80Ram2 ); + ZetMapArea(0x4000, 0x47ff, 2, SolomonZ80Ram2 ); + ZetMemEnd(); + ZetClose(); + + free(SolomonTempRom); + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + pAY8910Buffer[3] = pFMBuffer + nBurnSoundLen * 3; + pAY8910Buffer[4] = pFMBuffer + nBurnSoundLen * 4; + pAY8910Buffer[5] = pFMBuffer + nBurnSoundLen * 5; + pAY8910Buffer[6] = pFMBuffer + nBurnSoundLen * 6; + pAY8910Buffer[7] = pFMBuffer + nBurnSoundLen * 7; + pAY8910Buffer[8] = pFMBuffer + nBurnSoundLen * 8; + + AY8910Init(0, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(1, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(2, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + GenericTilesInit(); + + // Reset the driver + SolomonDoReset(); + + return 0; +} + +int SolomonExit() +{ + ZetExit(); + + for (int i = 0; i < 3; i++) { + AY8910Exit(i); + } + + GenericTilesExit(); + + free(Mem); + Mem = NULL; + + return 0; +} + +void SolomonRenderBgLayer() +{ + for (int Offs = 0; Offs < 0x400; Offs++) { + int sx, sy, Attr, Code, Colour, FlipX, FlipY; + + sx = (Offs % 32); + sy = (Offs / 32); + Attr = SolomonBgColourRam[Offs]; + Code = SolomonBgVideoRam[Offs] + 256 * (Attr & 0x07); + Colour = (Attr & 0x70) >> 4; + FlipX = Attr & 0x80; + FlipY = Attr & 0x08; + + if (SolomonFlipScreen) { + sx = 31 - sx; + sy = 31 - sy; + FlipX = !FlipX; + FlipY = !FlipY; + } + + sx *= 8; + sy *= 8; + sy -= 16; + + if (sx >= 0 && sx < 247 && sy >= 0 && sy < 215) { + if (!FlipY) { + if (!FlipX) { + Render8x8Tile_Mask(pTransDraw, Code, sx, sy, Colour, 4, 0, 128, SolomonBgTiles); + } else { + Render8x8Tile_Mask_FlipX(pTransDraw, Code, sx, sy, Colour, 4, 0, 128, SolomonBgTiles); + } + } else { + if (!FlipX) { + Render8x8Tile_Mask_FlipY(pTransDraw, Code, sx, sy, Colour, 4, 0, 128, SolomonBgTiles); + } else { + Render8x8Tile_Mask_FlipXY(pTransDraw, Code, sx, sy, Colour, 4, 0, 128, SolomonBgTiles); + } + } + } else { + if (!FlipY) { + if (!FlipX) { + Render8x8Tile_Mask_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 128, SolomonBgTiles); + } else { + Render8x8Tile_Mask_FlipX_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 128, SolomonBgTiles); + } + } else { + if (!FlipX) { + Render8x8Tile_Mask_FlipY_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 128, SolomonBgTiles); + } else { + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 128, SolomonBgTiles); + } + } + } + } +} + +void SolomonRenderFgLayer() +{ + for (int Offs = 0x400 - 1; Offs >= 0; Offs--) { + int sx, sy, Code, Colour; + + sx = (Offs % 32); + sy = (Offs / 32); + Code = SolomonVideoRam[Offs] + 256 * (SolomonColourRam[Offs] & 0x07); + Colour = (SolomonColourRam[Offs] & 0x70) >> 4; + + if (SolomonFlipScreen) { + sx = 31 - sx; + sy = 31 - sy; + } + + sx *= 8; + sy *= 8; + sy -= 16; + + if (sx >= 0 && sx < 247 && sy >= 0 && sy < 215) { + if (!SolomonFlipScreen) { + Render8x8Tile_Mask(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonFgTiles); + } else { + Render8x8Tile_Mask_FlipXY(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonFgTiles); + } + } else { + if (!SolomonFlipScreen) { + Render8x8Tile_Mask_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonFgTiles); + } else { + Render8x8Tile_Mask_FlipXY_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonFgTiles); + } + } + } +} + +void SolomonRenderSpriteLayer() +{ + for (int Offs = 0x80 - 4; Offs >= 0; Offs -= 4) { + int sx, sy, Attr, Code, Colour, FlipX, FlipY; + + sx = SolomonSpriteRam[Offs + 3]; + sy = 241 - SolomonSpriteRam[Offs + 2]; + Attr = SolomonSpriteRam[Offs + 1]; + Code = SolomonSpriteRam[Offs] + 16 * (Attr & 0x10); + Colour = (Attr & 0x0e) >> 1; + FlipX = Attr & 0x40; + FlipY = Attr & 0x80; + + if (SolomonFlipScreen & 1) { + sx = 240 - sx; + sy = 240 - sy; + FlipX = !FlipX; + FlipY = !FlipY; + } + + sy -= 16; + + if (sx >= 0 && sx < 239 && sy >= 0 && sy < 207) { + if (!FlipY) { + if (!FlipX) { + Render16x16Tile_Mask(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonSprites); + } else { + Render16x16Tile_Mask_FlipX(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonSprites); + } + } else { + if (!FlipX) { + Render16x16Tile_Mask_FlipY(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonSprites); + } else { + Render16x16Tile_Mask_FlipXY(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonSprites); + } + } + } else { + if (!FlipY) { + if (!FlipX) { + Render16x16Tile_Mask_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonSprites); + } else { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonSprites); + } + } else { + if (!FlipX) { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonSprites); + } else { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 0, SolomonSprites); + } + } + } + } +} + +inline static unsigned int CalcCol(unsigned short nColour) +{ + int r, g, b; + + r = (nColour >> 0) & 0x0f; + g = (nColour >> 4) & 0x0f; + b = (nColour >> 8) & 0x0f; + + r = (r << 4) | r; + g = (g << 4) | g; + b = (b << 4) | b; + + return BurnHighCol(r, g, b, 0); +} + +int SolomonCalcPalette() +{ + for (int i = 0; i < 0x200; i++) { + SolomonPalette[i / 2] = CalcCol(SolomonPaletteRam[i & ~1] | (SolomonPaletteRam[i | 1] << 8)); + } + + return 0; +} + +void SolomonDraw() +{ + BurnTransferClear(); + SolomonCalcPalette(); + SolomonRenderBgLayer(); + SolomonRenderFgLayer(); + SolomonRenderSpriteLayer(); + BurnTransferCopy(SolomonPalette); +} + +int SolomonFrame() +{ + int nInterleave = 2; + int nSoundBufferPos = 0; + + if (SolomonReset) SolomonDoReset(); + + SolomonMakeInputs(); + + nCyclesTotal[0] = 4000000 / 60; + nCyclesTotal[1] = 3072000 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run Z80 #1 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if (i == 1) if(SolomonIrqFire) ZetNmi(); + ZetClose(); + + // Run Z80 #2 + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesSegment = ZetRun(nCyclesSegment); + nCyclesDone[nCurrentCPU] += nCyclesSegment; + ZetRaiseIrq(0); + ZetClose(); + + // Render Sound Segment + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + AY8910Update(2, &pAY8910Buffer[6], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + nSample += pAY8910Buffer[6][n] >> 2; + nSample += pAY8910Buffer[7][n] >> 2; + nSample += pAY8910Buffer[8][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + nSoundBufferPos += nSegmentLength; + } + } + + // Make sure the buffer is entirely filled. + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + AY8910Update(2, &pAY8910Buffer[6], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + nSample += pAY8910Buffer[6][n] >> 2; + nSample += pAY8910Buffer[7][n] >> 2; + nSample += pAY8910Buffer[8][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) SolomonDraw(); + + return 0; +} + +static int SolomonScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin != NULL) { // Return minimum compatible version + *pnMin = 0x02945; + } + + if (nAction & ACB_MEMORY_RAM) { + memset(&ba, 0, sizeof(ba)); + ba.Data = RamStart; + ba.nLen = RamEnd-RamStart; + ba.szName = "All Ram"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + ZetScan(nAction); // Scan Z80 + + // Scan critical driver variables + SCAN_VAR(SolomonIrqFire); + SCAN_VAR(SolomonFlipScreen); + SCAN_VAR(SolomonSoundLatch); + SCAN_VAR(SolomonInput); + SCAN_VAR(SolomonDip); + } + + return 0; +} + +struct BurnDriver BurnDrvSolomon = { + "solomon", NULL, NULL, "1986", + "Solomon's Key (US)\0", NULL, "Tecmo", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, SolomonRomInfo, SolomonRomName, SolomonInputInfo, SolomonDIPInfo, + SolomonInit, SolomonExit, SolomonFrame, NULL, SolomonScan, + 0, NULL, NULL, NULL, NULL, 256, 224, 4, 3 +}; + +struct BurnDriver BurnDrvSolomonj = { + "solomonj", "solomon", NULL, "1986", + "Solomon's Key (Japan)\0", NULL, "Tecmo", "Miscellaneous", + L"Solomon's Key (Japan)\0Solomon's Key \u30BD\u30ED\u30E2\u30F3\u306E\u9375\0", NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, SolomonjRomInfo, SolomonjRomName, SolomonInputInfo, SolomonDIPInfo, + SolomonInit, SolomonExit, SolomonFrame, NULL, SolomonScan, + 0, NULL, NULL, NULL, NULL, 256, 224, 4, 3 +}; diff --git a/src/burn/misc/pre90s/d_tigerheli.cpp b/src/burn/misc/pre90s/d_tigerheli.cpp new file mode 100644 index 0000000..87bc372 --- /dev/null +++ b/src/burn/misc/pre90s/d_tigerheli.cpp @@ -0,0 +1,2028 @@ +// Tiger Heli, Get Star / Guardian, & Slap Fight + +#include "burnint.h" + +#include "driver.h" +extern "C" { + #include "ay8910.h" +} + +static int nWhichGame; + +static bool bInterruptEnable; +static bool bSoundCPUEnable; +static bool bSoundNMIEnable; + +static int nStatusIndex; +static int nProtectIndex; + +// --------------------------------------------------------------------------- +// Inputs + +static unsigned char tigerhInput[4] = {0,0,0,0}; +static unsigned char tigerhInpJoy1[8]; +static unsigned char tigerhInpMisc[8]; +static unsigned char tigerhReset = 0; + +// Dip Switch and Input Definitions +static struct BurnInputInfo tigerhInputList[] = { + {"P1 Coin", BIT_DIGITAL, tigerhInpMisc + 6, "p1 coin"}, + {"P1 Start", BIT_DIGITAL, tigerhInpMisc + 4, "p1 start"}, + {"P1 Up", BIT_DIGITAL, tigerhInpJoy1 + 0, "p1 up"}, + {"P1 Down", BIT_DIGITAL, tigerhInpJoy1 + 1, "p1 down"}, + {"P1 Left", BIT_DIGITAL, tigerhInpJoy1 + 3, "p1 left"}, + {"P1 Right", BIT_DIGITAL, tigerhInpJoy1 + 2, "p1 right"}, + {"P1 Button 1", BIT_DIGITAL, tigerhInpMisc + 1, "p1 fire 1"}, + {"P1 Button 2", BIT_DIGITAL, tigerhInpMisc + 0, "p1 fire 2"}, + + {"P2 Coin", BIT_DIGITAL, tigerhInpMisc + 7, "p2 coin"}, + {"P2 Start", BIT_DIGITAL, tigerhInpMisc + 5, "p2 start"}, + {"P2 Up", BIT_DIGITAL, tigerhInpJoy1 + 4, "p2 up"}, + {"P2 Down", BIT_DIGITAL, tigerhInpJoy1 + 5, "p2 down"}, + {"P2 Left", BIT_DIGITAL, tigerhInpJoy1 + 7, "p2 left"}, + {"P2 Right", BIT_DIGITAL, tigerhInpJoy1 + 6, "p2 right"}, + {"P2 Button 1", BIT_DIGITAL, tigerhInpMisc + 3, "p2 fire 1"}, + {"P2 Button 2", BIT_DIGITAL, tigerhInpMisc + 2, "p2 fire 2"}, + + {"Reset", BIT_DIGITAL, &tigerhReset, "reset"}, + + {"Dip A", BIT_DIPSWITCH, tigerhInput + 2, "dip"}, + {"Dip B", BIT_DIPSWITCH, tigerhInput + 3, "dip"}, +}; + +STDINPUTINFO(tigerh); + +static struct BurnInputInfo gtstarbaInputList[] = { + {"P1 Coin", BIT_DIGITAL, tigerhInpMisc + 6, "p1 coin"}, + {"P1 Start", BIT_DIGITAL, tigerhInpMisc + 4, "p1 start"}, + {"P1 Up", BIT_DIGITAL, tigerhInpJoy1 + 0, "p1 up"}, + {"P1 Down", BIT_DIGITAL, tigerhInpJoy1 + 2, "p1 down"}, + {"P1 Left", BIT_DIGITAL, tigerhInpJoy1 + 3, "p1 left"}, + {"P1 Right", BIT_DIGITAL, tigerhInpJoy1 + 1, "p1 right"}, + {"P1 Button 1", BIT_DIGITAL, tigerhInpMisc + 1, "p1 fire 1"}, + {"P1 Button 2", BIT_DIGITAL, tigerhInpMisc + 0, "p1 fire 2"}, + + {"P2 Coin", BIT_DIGITAL, tigerhInpMisc + 7, "p2 coin"}, + {"P2 Start", BIT_DIGITAL, tigerhInpMisc + 5, "p2 start"}, + {"P2 Up", BIT_DIGITAL, tigerhInpJoy1 + 4, "p2 up"}, + {"P2 Down", BIT_DIGITAL, tigerhInpJoy1 + 6, "p2 down"}, + {"P2 Left", BIT_DIGITAL, tigerhInpJoy1 + 7, "p2 left"}, + {"P2 Right", BIT_DIGITAL, tigerhInpJoy1 + 5, "p2 right"}, + {"P2 Button 1", BIT_DIGITAL, tigerhInpMisc + 3, "p2 fire 1"}, + {"P2 Button 2", BIT_DIGITAL, tigerhInpMisc + 2, "p2 fire 2"}, + + {"Reset", BIT_DIGITAL, &tigerhReset, "reset"}, + + {"Dip A", BIT_DIPSWITCH, tigerhInput + 2, "dip"}, + {"Dip B", BIT_DIPSWITCH, tigerhInput + 3, "dip"}, +}; + +STDINPUTINFO(gtstarba); + +static struct BurnDIPInfo tigerhDIPList[] = { + // Defaults + {0x11, 0xFF, 0xFF, 0x10, NULL}, + {0x12, 0xFF, 0xFF, 0x00, NULL}, + + // DIP A + {0, 0xFE, 0, 2, "Hero speed"}, + {0x11, 0x01, 0x80, 0x00, "Normal"}, + {0x11, 0x01, 0x80, 0x80, "Fast"}, + {0, 0xFE, 0, 2, NULL}, + {0x11, 0x01, 0x40, 0x00, "Normal game"}, + {0x11, 0x01, 0x40, 0x40, "DIP switch test"}, + {0, 0xFE, 0, 2, NULL}, + {0x11, 0x01, 0x20, 0x00, "Normal screen"}, + {0x11, 0x01, 0x20, 0x20, "Invert screen"}, + {0, 0xFE, 0, 2, "Cabinet"}, + {0x11, 0x01, 0x10, 0x10, "Upright"}, + {0x11, 0x01, 0x10, 0x00, "Table"}, + {0, 0xFE, 0, 2, "Advertise sound"}, + {0x11, 0x01, 0x08, 0x00, "On"}, + {0x11, 0x01, 0x08, 0x08, "Off"}, + {0, 0xFE, 0, 7, "Coinage"}, + {0x11, 0x01, 0x07, 0x00, "1 coin 1 credit"}, + {0x11, 0x01, 0x07, 0x01, "1 coin 2 credits"}, + {0x11, 0x01, 0x07, 0x02, "1 coin 3 credits"}, + {0x11, 0x01, 0x07, 0x03, "2 coins 1 credit"}, + {0x11, 0x01, 0x07, 0x04, "2 coins 3 credits"}, + {0x11, 0x01, 0x07, 0x05, "3 coins 1 credit"}, + {0x11, 0x01, 0x07, 0x07, "Free play"}, + {0x11, 0x01, 0x07, 0x06, "3 coins 1 credit"}, + + // DIP B + {0, 0xFE, 0, 2, "Extend"}, + {0x12, 0x01, 0x10, 0x00, "20000 & 80000"}, + {0x12, 0x01, 0x10, 0x10, "50000 & 120000"}, + {0, 0xFE, 0, 4, "Game difficulty"}, + {0x12, 0x01, 0x0C, 0x00, "0"}, + {0x12, 0x01, 0x0C, 0x04, "1"}, + {0x12, 0x01, 0x0C, 0x08, "2"}, + {0x12, 0x01, 0x0C, 0x0C, "3"}, + {0, 0xFE, 0, 4, "Number of heroes"}, + {0x12, 0x01, 0x03, 0x00, "3"}, + {0x12, 0x01, 0x03, 0x01, "5"}, + {0x12, 0x01, 0x03, 0x02, "1"}, + {0x12, 0x01, 0x03, 0x03, "2"}, +}; + +STDDIPINFO(tigerh); + +static struct BurnDIPInfo getstarDIPList[] = { + // Defaults + {0x11, 0xFF, 0xFF, 0x10, NULL}, + + // DIP A + {0, 0xFE, 0, 2, "Hero speed"}, // really work? + {0x11, 0x01, 0x80, 0x00, "Normal"}, + {0x11, 0x01, 0x80, 0x80, "Fast"}, + {0, 0xFE, 0, 2, NULL}, + {0x11, 0x01, 0x40, 0x00, "Normal game"}, + {0x11, 0x01, 0x40, 0x40, "DIP switch test"}, + {0, 0xFE, 0, 2, NULL}, + {0x11, 0x01, 0x20, 0x00, "Normal screen"}, + {0x11, 0x01, 0x20, 0x20, "Invert screen"}, + {0, 0xFE, 0, 2, "Cabinet"}, + {0x11, 0x01, 0x10, 0x10, "Upright"}, + {0x11, 0x01, 0x10, 0x00, "Table"}, + {0, 0xFE, 0, 2, "Advertise sound"}, + {0x11, 0x01, 0x08, 0x00, "On"}, + {0x11, 0x01, 0x08, 0x08, "Off"}, + {0, 0xFE, 0, 7, "Coinage"}, + {0x11, 0x01, 0x07, 0x00, "1 coin 1 credit"}, + {0x11, 0x01, 0x07, 0x01, "1 coin 2 credits"}, + {0x11, 0x01, 0x07, 0x02, "1 coin 3 credits"}, + {0x11, 0x01, 0x07, 0x03, "2 coins 1 credit"}, + {0x11, 0x01, 0x07, 0x04, "2 coins 3 credits"}, + {0x11, 0x01, 0x07, 0x05, "3 coins 1 credit"}, + {0x11, 0x01, 0x07, 0x07, "Free play"}, + {0x11, 0x01, 0x07, 0x06, "3 coins 1 credit"}, + + // DIP B + {0, 0xFE, 0, 2, "Extend"}, + {0x12, 0x01, 0x10, 0x00, "30000 & 100000"}, + {0x12, 0x01, 0x10, 0x10, "50000 & 150000"}, + {0, 0xFE, 0, 4, "Game difficulty"}, + {0x12, 0x01, 0x0C, 0x00, "0"}, + {0x12, 0x01, 0x0C, 0x04, "1"}, + {0x12, 0x01, 0x0C, 0x08, "2"}, + {0x12, 0x01, 0x0C, 0x0C, "3"}, +}; + +static struct BurnDIPInfo getstarHeroesDIPList[] = +{ + // Defaults + {0x12, 0xFF, 0xFF, 0x01, NULL}, + + // DIP B + {0, 0xFE, 0, 4, "Number of heroes"}, + {0x12, 0x01, 0x03, 0x01, "3"}, + {0x12, 0x01, 0x03, 0x02, "4"}, + {0x12, 0x01, 0x03, 0x03, "5"}, + {0x12, 0x01, 0x03, 0x00, "240 (cheat)"}, +}; + +static struct BurnDIPInfo gtstarbaHeroesDIPList[] = +{ + // Defaults + {0x12, 0xFF, 0xFF, 0x00, NULL}, + + // DIP B + {0, 0xFE, 0, 4, "Number of heroes"}, + {0x12, 0x01, 0x03, 0x02, "1"}, + {0x12, 0x01, 0x03, 0x03, "2"}, + {0x12, 0x01, 0x03, 0x00, "3"}, + {0x12, 0x01, 0x03, 0x01, "5"}, +}; + +STDDIPINFOEXT(getstar, getstar, getstarHeroes); +STDDIPINFOEXT(gtstarba, getstar, gtstarbaHeroes); + +static struct BurnDIPInfo slapfighDIPList[] = { + // Defaults + {0x11, 0xFF, 0xFF, 0x80, NULL}, + {0x12, 0xFF, 0xFF, 0x00, NULL}, + + // DIP A + {0, 0xFE, 0, 2, NULL}, + {0x11, 0x01, 0x80, 0x80, "Up-right type"}, + {0x11, 0x01, 0x80, 0x00, "Table type"}, + {0, 0xFE, 0, 2, NULL}, + {0x11, 0x01, 0x40, 0x00, "Normal screen"}, + {0x11, 0x01, 0x40, 0x40, "Invert screen"}, + {0, 0xFE, 0, 2, NULL}, + {0x11, 0x01, 0x20, 0x00, "Normal game"}, + {0x11, 0x01, 0x20, 0x20, "Screen test mode"}, + {0, 0xFE, 0, 2, "Advertise sound"}, + {0x11, 0x01, 0x10, 0x00, "On"}, + {0x11, 0x01, 0x10, 0x10, "Off"}, + {0, 0xFE, 0, 4, "Coin A"}, + {0x11, 0x01, 0x0C, 0x00, "1 coin 1 play"}, + {0x11, 0x01, 0x0C, 0x08, "1 coin 2 plays"}, + {0x11, 0x01, 0x0C, 0x04, "2 coins 1 play"}, + {0x11, 0x01, 0x0C, 0x0C, "2 coins 3 plays"}, + {0, 0xFE, 0, 4, "Coin B"}, + {0x11, 0x01, 0x03, 0x00, "1 coin 1 play"}, + {0x11, 0x01, 0x03, 0x02, "1 coin 2 plays"}, + {0x11, 0x01, 0x03, 0x01, "2 coins 1 play"}, + {0x11, 0x01, 0x03, 0x03, "2 coins 3 plays"}, + + // DIP B + {0, 0xFE, 0, 4, "Game difficulty"}, + {0x12, 0x01, 0xC0, 0x00, "B"}, + {0x12, 0x01, 0xC0, 0x80, "A"}, + {0x12, 0x01, 0xC0, 0x40, "C"}, + {0x12, 0x01, 0xC0, 0xC0, "D"}, + {0, 0xFE, 0, 4, "Extend"}, + {0x12, 0x01, 0x30, 0x00, "30000, 100000"}, + {0x12, 0x01, 0x30, 0x20, "50000, 200000"}, + {0x12, 0x01, 0x30, 0x10, "50000 only"}, + {0x12, 0x01, 0x30, 0x30, "100000 only"}, + {0, 0xFE, 0, 4, "Fighter counts"}, + {0x12, 0x01, 0x0C, 0x00, "3"}, + {0x12, 0x01, 0x0C, 0x08, "5"}, + {0x12, 0x01, 0x0C, 0x04, "1"}, + {0x12, 0x01, 0x0C, 0x0C, "2"}, + {0, 0xFE, 0, 2, NULL}, + {0x12, 0x01, 0x02, 0x00, "Normal game"}, + {0x12, 0x01, 0x02, 0x02, "DIP-switch display"}, +}; + +STDDIPINFO(slapfigh); + +// --------------------------------------------------------------------------- + +static unsigned char *Mem, *MemEnd, *RamStart, *RamEnd; + +static unsigned char *Rom01, *Rom02; +static unsigned char *TigerHeliTileROM, *TigerHeliSpriteROM, *TigerHeliTextROM; + +static unsigned char *Ram01, *RamShared; +static unsigned char *TigerHeliTileRAM, *TigerHeliSpriteRAM, *TigerHeliSpriteBuf, *TigerHeliTextRAM; + +static unsigned char* TigerHeliPaletteROM; +static unsigned int* TigerHeliPalette; + +static short* pFMBuffer; +static short* pAY8910Buffer[6]; + +static int MemIndex() +{ + unsigned char* Next; Next = Mem; + Rom01 = Next; Next += 0x012000; // Z80 main program + Rom02 = Next; Next += 0x002000; // Z80 sound program + TigerHeliTextROM = Next; Next += 0x010000; + TigerHeliSpriteROM = Next; Next += 0x040000; + TigerHeliTileROM = Next; Next += 0x040000; + RamStart = Next; + Ram01 = Next; Next += 0x000800; // Z80 main work RAM + RamShared = Next; Next += 0x000800; // Shared RAM + TigerHeliTextRAM = Next; Next += 0x001000; + TigerHeliSpriteRAM = Next; Next += 0x000800; + TigerHeliSpriteBuf = Next; Next += 0x000800; + TigerHeliTileRAM = Next; Next += 0x001000; + RamEnd = Next; + pFMBuffer = (short*)Next; Next += nBurnSoundLen * 6 * sizeof(short); + TigerHeliPaletteROM = Next; Next += 0x000300; + TigerHeliPalette = (unsigned int*)Next; Next += 0x000100 * sizeof(int); + MemEnd = Next; + + return 0; +} + +// --------------------------------------------------------------------------- +// Graphics + +static int nTigerHeliTileXPosLo, nTigerHeliTileXPosHi, nTigerHeliTileYPosLo; +static int nTigerHeliTileMask; + +static unsigned char* pTileData; + +static int nTileNumber; +static int nTilePalette; + +static unsigned short* pTileRow; +static unsigned short* pTile; + +static int nTileXPos, nTileYPos; + +// --------------------------------------------------------------------------- +// Palette + +static unsigned char tigerhRecalcPalette = 0; + +static void TigerHeliPaletteInit() +{ + for (int i = 0; i < 0x0100; i++) { + int r, g, b; + + r = TigerHeliPaletteROM[i + 0x0000]; // Red + r |= r << 4; + g = TigerHeliPaletteROM[i + 0x0100]; // Green + g |= g << 4; + b = TigerHeliPaletteROM[i + 0x0200]; // Blue + b |= b << 4; + + TigerHeliPalette[i] = BurnHighCol(r, g, b, 0); + } + + return; +} + +static void TigerHeliPaletteUpdate() +{ + if (tigerhRecalcPalette) { + tigerhRecalcPalette = 0; + + TigerHeliPaletteInit(); + } +} + +// --------------------------------------------------------------------------- +// Text layer + +static unsigned char* TigerHeliTextAttrib = NULL; + +static void TigerHeliTextExit() +{ + free(TigerHeliTextAttrib); + TigerHeliTextAttrib = NULL; +} + +static int TigerHeliTextInit() +{ + if ((TigerHeliTextAttrib = (unsigned char*)malloc(0x0400)) == NULL) { + return 1; + } + + for (int i = 0; i < 0x0400; i++) { + bool bEmpty = true; + + for (int j = 0; j < 64; j++) { + if (TigerHeliTextROM[(i << 6) + j]) { + bEmpty = false; + break; + } + } + + if (bEmpty) { + TigerHeliTextAttrib[i] = 0; + } else { + TigerHeliTextAttrib[i] = 1; + } + } + + return 0; +} + +#define PLOTPIXEL(x) if (pTileData[x]) { pPixel[x] = nPalette + pTileData[x]; } + +static void TigerHeliRenderTextTile() +{ + unsigned short nPalette = nTilePalette << 2; + pTileData = TigerHeliTextROM + (nTileNumber << 6); + + unsigned short* pPixel = pTile; + + for (int y = 0; y < 8; y++, pPixel += 280, pTileData += 8) { + + if ((nTileYPos + y) >= 240) { + break; + } + if ((nTileYPos + y) < 0) { + continue; + } + + PLOTPIXEL(0); + PLOTPIXEL(1); + PLOTPIXEL(2); + PLOTPIXEL(3); + PLOTPIXEL(4); + PLOTPIXEL(5); + PLOTPIXEL(6); + PLOTPIXEL(7); + } +} + +#undef PLOTPIXEL + +static void TigerHeliTextRender() +{ + unsigned char* pTextRAM; + + if ((nBurnLayer & 2) == 0) { + return; + } + + switch (nWhichGame) { + case 0: // Tiger Heli + nTileYPos = -15; + break; + case 1: // Get Star + nTileYPos = -15; + break; + case 2: // Slap Fight + nTileYPos = -16; + break; + } + pTileRow = pTransDraw + nTileYPos * 280; + + for (int y = 0; y < 32; y++, nTileYPos += 8, pTileRow += (280 << 3)) { + if (nTileYPos <= -8 || nTileYPos >= 240 ) { + continue; + } + pTextRAM = TigerHeliTextRAM + (y << 6); + pTile = pTileRow; + for (int x = 1; x < 36; x++, pTile += 8) { + nTileNumber = pTextRAM[x] | (pTextRAM[0x0800 + x] << 8); + nTilePalette = nTileNumber >> 10; + nTileNumber &= 0x03FF; + + if (TigerHeliTextAttrib[nTileNumber]) { + TigerHeliRenderTextTile(); + } + } + } + + return; +} + +// --------------------------------------------------------------------------- +// Tile layer + +static void TigerHeliTileExit() +{ + return; +} + +static int TigerHeliTileInit() +{ + return 0; +} + +#define PLOTPIXEL(x) pPixel[x] = nPalette + pTileData[x]; +#define CLIPPIXEL(a,b) if ((nTileXPos + a) >= 0 && (nTileXPos + a) < 280) { b; } + +static void TigerHeliRenderTileNoClip() +{ + unsigned char nPalette = nTilePalette << 4; + pTileData = TigerHeliTileROM + (nTileNumber << 6); + + unsigned short* pPixel = pTile; + + for (int y = 0; y < 8; y++, pPixel += 280, pTileData += 8) { + PLOTPIXEL(0); + PLOTPIXEL(1); + PLOTPIXEL(2); + PLOTPIXEL(3); + PLOTPIXEL(4); + PLOTPIXEL(5); + PLOTPIXEL(6); + PLOTPIXEL(7); + } +} + +static void TigerHeliRenderTileClip() +{ + unsigned char nPalette = nTilePalette << 4; + pTileData = TigerHeliTileROM + (nTileNumber << 6); + + unsigned short* pPixel = pTile; + + for (int y = 0; y < 8; y++, pPixel += 280, pTileData += 8) { + + if ((nTileYPos + y) >= 240) { + break; + } + if ((nTileYPos + y) < 0) { + continue; + } + + CLIPPIXEL(0, PLOTPIXEL(0)); + CLIPPIXEL(1, PLOTPIXEL(1)); + CLIPPIXEL(2, PLOTPIXEL(2)); + CLIPPIXEL(3, PLOTPIXEL(3)); + CLIPPIXEL(4, PLOTPIXEL(4)); + CLIPPIXEL(5, PLOTPIXEL(5)); + CLIPPIXEL(6, PLOTPIXEL(6)); + CLIPPIXEL(7, PLOTPIXEL(7)); + } +} + +#undef CLIPPIXEL +#undef PLOTPIXEL + +static void TigerHeliTileRender() +{ + unsigned char* pTileRAM; + + if ((nBurnLayer & 3) == 0) { + BurnTransferClear(); + return; + } + + int nTigerHeliTileXPos = nTigerHeliTileXPosLo + (nTigerHeliTileXPosHi << 8); + int nTigerHeliTileYPos = nTigerHeliTileYPosLo; + + switch (nWhichGame) { + case 0: // Tiger Heli + nTigerHeliTileYPos -= 1; + break; + case 1: // Get Star + nTigerHeliTileYPos -= 1; + break; + case 2: // Slap Fight + nTigerHeliTileYPos += 1; + break; + } + + int nXPos = -nTigerHeliTileXPos & 7; + nTileYPos = -nTigerHeliTileYPos & 7; + + if (nTigerHeliTileXPos & 7) { + nXPos -= 8; + } + if (nTigerHeliTileYPos & 7) { + nTileYPos -= 8; + } + + pTileRow = pTransDraw; + pTileRow -= (nTigerHeliTileXPos & 7); + pTileRow -= (nTigerHeliTileYPos & 7) * 280; + + for (int y = 2; y < 33; y++, nTileYPos += 8, pTileRow += (280 << 3)) { + pTileRAM = TigerHeliTileRAM + ((y + (nTigerHeliTileYPos >> 3) << 6) & 0x07C0); + pTile = pTileRow; + nTileXPos = nXPos; + for (int x = 1; x < 37; x++, nTileXPos += 8, pTile += 8) { + int x2 = (x + (nTigerHeliTileXPos >> 3) & 0x3F); + nTileNumber = pTileRAM[x2] | (pTileRAM[0x0800 + x2] << 8); + nTilePalette = nTileNumber >> 12; + nTileNumber &= nTigerHeliTileMask; + + if (nTileXPos < 0 || nTileXPos > 272 || nTileYPos < 0 || nTileYPos > 232) { + TigerHeliRenderTileClip(); + } else { + TigerHeliRenderTileNoClip(); + } + } + } + + return; +} + +// --------------------------------------------------------------------------- +// Sprites + +static int nSpriteXPos, nSpriteYPos, nSpriteNumber, nSpritePalette; + +static int nTigerHeliSpriteMask; + +static void TigerHeliSpriteExit() +{ + return; +} + +static int TigerHeliSpriteInit() +{ + return 0; +} + +#define PLOTPIXEL(a) if (pSpriteData[a]) { pPixel[a] = nPalette + pSpriteData[a]; } +#define CLIPPIXEL(a,b) if ((nSpriteXPos + a) >= 0 && (nSpriteXPos + a) < 280) { b; } + +static void TigerHeliRenderSpriteNoClip() +{ + unsigned char nPalette = nSpritePalette << 4; + unsigned char* pSpriteData = TigerHeliSpriteROM + (nSpriteNumber << 8); + + unsigned short* pPixel = pTransDraw + nSpriteXPos + nSpriteYPos * 280; + + for (int y = 0; y < 16; y++, pPixel += 280, pSpriteData += 16) { + PLOTPIXEL( 0); + PLOTPIXEL( 1); + PLOTPIXEL( 2); + PLOTPIXEL( 3); + PLOTPIXEL( 4); + PLOTPIXEL( 5); + PLOTPIXEL( 6); + PLOTPIXEL( 7); + PLOTPIXEL( 8); + PLOTPIXEL( 9); + PLOTPIXEL(10); + PLOTPIXEL(11); + PLOTPIXEL(12); + PLOTPIXEL(13); + PLOTPIXEL(14); + PLOTPIXEL(15); + } +} + +static void TigerHeliRenderSpriteClip() +{ + unsigned char nPalette = nSpritePalette << 4; + unsigned char* pSpriteData = TigerHeliSpriteROM + (nSpriteNumber << 8); + + unsigned short* pPixel = pTransDraw + nSpriteXPos + nSpriteYPos * 280; + + for (int y = 0; y < 16; y++, pPixel += 280, pSpriteData += 16) { + + if ((nSpriteYPos + y) < 0 || (nSpriteYPos + y) >= 240) { + continue; + } + + CLIPPIXEL( 0, PLOTPIXEL( 0)); + CLIPPIXEL( 1, PLOTPIXEL( 1)); + CLIPPIXEL( 2, PLOTPIXEL( 2)); + CLIPPIXEL( 3, PLOTPIXEL( 3)); + CLIPPIXEL( 4, PLOTPIXEL( 4)); + CLIPPIXEL( 5, PLOTPIXEL( 5)); + CLIPPIXEL( 6, PLOTPIXEL( 6)); + CLIPPIXEL( 7, PLOTPIXEL( 7)); + CLIPPIXEL( 8, PLOTPIXEL( 8)); + CLIPPIXEL( 9, PLOTPIXEL( 9)); + CLIPPIXEL(10, PLOTPIXEL(10)); + CLIPPIXEL(11, PLOTPIXEL(11)); + CLIPPIXEL(12, PLOTPIXEL(12)); + CLIPPIXEL(13, PLOTPIXEL(13)); + CLIPPIXEL(14, PLOTPIXEL(14)); + CLIPPIXEL(15, PLOTPIXEL(15)); + } +} + +#undef CLIPPIXEL +#undef PLOTPIXEL + +static void TigerHeliSpriteRender() +{ + unsigned char* pSpriteRAM = TigerHeliSpriteBuf; + int nSpriteYOffset = 0; + + if ((nBurnLayer & 1) == 0) { + return; + } + + switch (nWhichGame) { + case 0: // Tiger Heli + nSpriteYOffset = -16; + break; + case 1: // Get Star + nSpriteYOffset = -16; + break; + case 2: // Slap Fight + nSpriteYOffset = -17; + break; + } + + for (int i = 0; i < 0x0800; i += 4) { + nSpriteNumber = pSpriteRAM[i + 0x00] | ((pSpriteRAM[i + 0x02] & 0xC0) << 2); + nSpriteNumber &= nTigerHeliSpriteMask; + nSpritePalette = (pSpriteRAM[i + 0x02] >> 1) & 0x0F; + nSpriteXPos = (pSpriteRAM[i + 0x01] | ((pSpriteRAM[i + 0x02] & 0x01) << 8)) - 21; + nSpriteYPos = pSpriteRAM[i + 0x03] + nSpriteYOffset; + + if (nSpriteXPos > -16 && nSpriteXPos < 280 && nSpriteYPos > -16 && nSpriteYPos < 240) { + if (nSpriteXPos >= 0 && nSpriteXPos <= 264 && nSpriteYPos >= 0 && nSpriteYPos <= 224) { + TigerHeliRenderSpriteNoClip(); + } else { + TigerHeliRenderSpriteClip(); + } + } + } + + return; +} + +static void TigerHeliBufferSprites() +{ + memcpy(TigerHeliSpriteBuf, TigerHeliSpriteRAM, 0x0800); +} + +// --------------------------------------------------------------------------- + +unsigned char __fastcall tigerhReadCPU0(unsigned short a) +{ + if (a >= 0xc800 && a <= 0xcfff) { + if (ZetPc(0) == 0x6d34) return 0xff; + return RamShared[a - 0xc800]; + } + + switch (a) { + case 0xE803: { + unsigned char nProtectSequence[3] = { 0, 1, (0 + 5) ^ 0x56 }; + + //if (nProtectIndex == 3) { + // nProtectIndex = 0; + //} + +// bprintf(PRINT_NORMAL, "Protection read (%02X) PC: %04X.\n", nProtectSequence[nProtectIndex], ZetPc(-1)); + //return nProtectSequence[nProtectIndex++]; + + unsigned char val = nProtectSequence[nProtectIndex]; + nProtectIndex = (nProtectIndex + 1) % 3; + return val; + } + +// default: +// bprintf(PRINT_NORMAL, _T("Attempt by CPU0 to read address %04X.\n"), a); + } + + return 0; +} + +void __fastcall tigerhWriteCPU0(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xE800: + nTigerHeliTileXPosLo = d; + break; + case 0xE801: + nTigerHeliTileXPosHi = d; + break; + case 0xE802: + nTigerHeliTileYPosLo = d; + break; +// default: +// bprintf(PRINT_NORMAL, "Attempt by CPU0 to write address %04X -> %02X.\n", a, d); + } +} + +void __fastcall tigerhWriteCPU0_slapbtuk(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xE800: + nTigerHeliTileXPosHi = d; + break; + case 0xE802: + nTigerHeliTileYPosLo = d; + break; + case 0xE803: + nTigerHeliTileXPosLo = d; + break; +// default: +// bprintf(PRINT_NORMAL, "Attempt by CPU0 to write address %04X -> %02X.\n", a, d); + } +} + +unsigned char __fastcall tigerhInCPU0(unsigned short a) +{ + a &= 0xFF; + + switch (a) { + case 0x00: { + unsigned char nStatusSequence[3] = { 0xC7, 0x55, 0x00 }; + + //if (nStatusIndex == 3) { + // nStatusIndex = 0; + //} + +// bprintf(PRINT_NORMAL, "Status read (%02X) PC: %04X.\n", nStatusSequence[nStatusIndex], ZetPc(-1)); + //return nStatusSequence[nStatusIndex++]; + + unsigned char nStatus = nStatusSequence[nStatusIndex]; + nStatusIndex++; + if (nStatusIndex > 2) nStatusIndex = 0; + return nStatus; + + } + +// default: +// bprintf(PRINT_NORMAL, "Attempt by CPU0 to read port %02X.\n", a); + } + + return 0; +} + +unsigned char __fastcall tigerhInCPU0_gtstarba(unsigned short a) +{ + a &= 0xFF; + + switch (a) { + case 0x00: { + if (ZetPc(0) == 0x6d1e) return 0; + if (ZetPc(0) == 0x6d24) return 6; + if (ZetPc(0) == 0x6d2c) return 2; + if (ZetPc(0) == 0x6d34) return 4; + return 0; + } + +// default: +// bprintf(PRINT_NORMAL, "Attempt by CPU0 to read port %02X.\n", a); + } + + return 0; +} + +void __fastcall tigerhOutCPU0(unsigned short a, unsigned char /* d */) +{ + a &= 0xFF; + + switch (a) { + case 0x00: // Assert reset line on sound CPU +// bprintf(PRINT_NORMAL, "Sound CPU disabled.\n"); + + if (bSoundCPUEnable) { + ZetClose(); + ZetOpen(1); + ZetReset(); + ZetClose(); + ZetOpen(0); + + bSoundCPUEnable = false; + } + + break; + case 0x01: // Release reset line on sound CPU +// bprintf(PRINT_NORMAL, "Sound CPU enabled.\n"); + + bSoundCPUEnable = true; + break; + +// case 0x03: +// break; + +// case 0x05: +// bprintf(PRINT_NORMAL, "Sound NMI triggered.\n"); +/* + if (bSoundNMIEnable) { + ZetClose(); + ZetOpen(1); + ZetNmi(); + ZetClose(); + ZetOpen(0); + } +*/ +// break; + + case 0x06: // Disable interrupts +// bprintf(PRINT_NORMAL, "Interrupts disabled.\n"); + + bInterruptEnable = false; + ZetLowerIrq(); + break; + case 0x07: // Enable interrupts +// bprintf(PRINT_NORMAL, "Interrupts enabled.\n"); + + bInterruptEnable = true; + break; + + case 0x08: +// bprintf(PRINT_NORMAL, "ROM bank 0 selected.\n"); + + // ROM bank 0 selected + ZetMapArea(0x8000, 0xBFFF, 0, Rom01 + 0x8000); + ZetMapArea(0x8000, 0xBFFF, 2, Rom01 + 0x8000); + break; + case 0x09: +// bprintf(PRINT_NORMAL, "ROM bank 1 selected.\n"); + + // ROM bank 1 selected + ZetMapArea(0x8000, 0xBFFF, 0, Rom01 + 0xC000); + ZetMapArea(0x8000, 0xBFFF, 2, Rom01 + 0xC000); + break; + +// default: +// bprintf(PRINT_NORMAL, "Attempt by CPU0 to write port %02X -> %02X.\n", a, d); + } +} + +unsigned char __fastcall tigerhReadCPU1(unsigned short a) +{ + switch (a) { + case 0xA081: +// bprintf(PRINT_NORMAL, "AY8910 0 read (%02X).\n", AY8910Read(0)); + return AY8910Read(0); + case 0xA091: +// bprintf(PRINT_NORMAL, "AY8910 1 read (%02X).\n", AY8910Read(1)); + return AY8910Read(1); + +// default: +// bprintf(PRINT_NORMAL, "Attempt by CPU1 to read address %04X.\n", a); + } + + return 0; +} + +void __fastcall tigerhWriteCPU1(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xA080: +// bprintf(PRINT_NORMAL, "AY8910 0 Register select (%02X).\n", d); + AY8910Write(0, 0, d); + break; + case 0xA082: +// bprintf(PRINT_NORMAL, "AY8910 0 Register Write (%02X).\n", d); + AY8910Write(0, 1, d); + break; + case 0xA090: +// bprintf(PRINT_NORMAL, "AY8910 1 Register select (%02X).\n", d); + AY8910Write(1, 0, d); + break; + case 0xA092: +// bprintf(PRINT_NORMAL, "AY8910 1 Register Write (%02X).\n", d); + AY8910Write(1, 1, d); + break; + + case 0xA0E0: +// bprintf(PRINT_NORMAL, "Sound NMI enabled.\n"); + bSoundNMIEnable = true; + break; + +// default: +// bprintf(PRINT_NORMAL, "Attempt by CPU1 to write address %04X -> %02X.\n", a, d); + } +} + +unsigned char __fastcall tigerhInCPU1(unsigned short /* a */) +{ +// bprintf(PRINT_NORMAL, "Attempt by CPU1 to read port %02X.\n", a); + + return 0; +} + +void __fastcall tigerhOutCPU1(unsigned short /* a */, unsigned char /* d */) +{ +// bprintf(PRINT_NORMAL, "Attempt by CPU1 to write port %02X -> %02X.\n", a, d); +} + +static unsigned char tigerhReadPort0(unsigned int) +{ + return ~tigerhInput[0]; +} +static unsigned char tigerhReadPort1(unsigned int) +{ + return ~tigerhInput[1]; +} +static unsigned char tigerhReadPort2(unsigned int) +{ + return ~tigerhInput[2]; +} +static unsigned char tigerhReadPort3(unsigned int) +{ + return ~tigerhInput[3]; +} + +// --------------------------------------------------------------------------- + +static int tigerhLoadROMs() +{ + int nRomOffset = 0; + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "slapbtuk")) nRomOffset = 1; + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "slapfgtr")) nRomOffset = 2; + + // Z80 main program + switch (nWhichGame) { + case 0: // Tiger Heli + if (BurnLoadRom(Rom01 + 0x0000, 0, 1)) { + return 1; + } + if (BurnLoadRom(Rom01 + 0x4000, 1, 1)) { + return 1; + } + if (BurnLoadRom(Rom01 + 0x8000, 2, 1)) { + return 1; + } + break; + case 1: // Get Star + if (BurnLoadRom(Rom01 + 0x0000, 0, 1)) { + return 1; + } + if (BurnLoadRom(Rom01 + 0x4000, 1, 1)) { + return 1; + } + if (BurnLoadRom(Rom01 + 0x8000, 2, 1)) { + return 1; + } + break; + case 2: { // Slap Fight + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "slapbtuk")) { + if (BurnLoadRom(Rom01 + 0x0000, 0, 1)) { + return 1; + } + if (BurnLoadRom(Rom01 + 0x4000, 1, 1)) { + return 1; + } + if (BurnLoadRom(Rom01 + 0x8000, 2, 1)) { + return 1; + } + break; + } else { + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "slapfgtr")) { + if (BurnLoadRom(Rom01 + 0x0000, 0, 1)) { + return 1; + } + if (BurnLoadRom(Rom01 + 0x4000, 1, 1)) { + return 1; + } + if (BurnLoadRom(Rom01 + 0x10000, 2, 1)) { + return 1; + } + if (BurnLoadRom(Rom01 + 0x8000, 3, 1)) { + return 1; + } + break; + } else { + if (BurnLoadRom(Rom01 + 0x0000, 0, 1)) { + return 1; + } + if (BurnLoadRom(Rom01 + 0x8000, 1, 1)) { + return 1; + } + break; + } + } + } + } + + // Sprites + { + int nRet = 0, nBaseROM = 0; + switch (nWhichGame) { + case 0: // Tiger Heli + nBaseROM = 3; + break; + case 1: // Get Star + nBaseROM = 3; + break; + case 2: // Slap Fight + nBaseROM = 2 + nRomOffset; + break; + } + + int nSize; + + { + struct BurnRomInfo ri; + + ri.nType = 0; + ri.nLen = 0; + + BurnDrvGetRomInfo(&ri, nBaseROM); + + nSize = ri.nLen; + } + + unsigned char* pTemp = (unsigned char*)malloc(nSize * 4); + + for (int i = 0; i < 4; i++) { + nRet |= BurnLoadRom(pTemp + nSize * i, nBaseROM + i, 1); + } + + for (int i = 0; i < nSize; i++) { + for (int j = 0; j < 8; j++) { + TigerHeliSpriteROM[(i << 3) + j] = ((pTemp[i + nSize * 0] >> (7 - j)) & 1) << 3; + TigerHeliSpriteROM[(i << 3) + j] |= ((pTemp[i + nSize * 1] >> (7 - j)) & 1) << 2; + TigerHeliSpriteROM[(i << 3) + j] |= ((pTemp[i + nSize * 2] >> (7 - j)) & 1) << 1; + TigerHeliSpriteROM[(i << 3) + j] |= ((pTemp[i + nSize * 3] >> (7 - j)) & 1) << 0; + } + } + + free(pTemp); + + nTigerHeliSpriteMask = (nSize >> 5) - 1; + + if (nRet) { + return 1; + } + } + + // Text layer + { + int nBaseROM = 0; + switch (nWhichGame) { + case 0: // Tiger Heli + nBaseROM = 7; + break; + case 1: // Get Star + nBaseROM = 7; + break; + case 2: // Slap Fight + nBaseROM = 6 + nRomOffset; + break; + } + + unsigned char* pTemp = (unsigned char*)malloc(0x4000); + + if (BurnLoadRom(pTemp + 0x0000, nBaseROM + 0, 1)) { + return 1; + } + if (BurnLoadRom(pTemp + 0x2000, nBaseROM + 1, 1)) { + return 1; + } + + for (int i = 0; i < 0x02000; i++) { + for (int j = 0; j < 8; j++) { + TigerHeliTextROM[(i << 3) + j] = ((pTemp[i + 0x0000] >> (7 - j)) & 1) << 1; + TigerHeliTextROM[(i << 3) + j] |= ((pTemp[i + 0x2000] >> (7 - j)) & 1) << 0; + } + } + + free(pTemp); + } + + // Tile layer + { + int nRet = 0, nBaseROM = 0; + switch (nWhichGame) { + case 0: // Tiger Heli + nBaseROM = 9; + break; + case 1: // Get Star + nBaseROM = 9; + break; + case 2: // Slap Fight + nBaseROM = 8 + nRomOffset; + break; + } + + int nSize; + + { + struct BurnRomInfo ri; + + ri.nType = 0; + ri.nLen = 0; + + BurnDrvGetRomInfo(&ri, nBaseROM); + + nSize = ri.nLen; + } + + unsigned char* pTemp = (unsigned char*)malloc(nSize * 4); + + for (int i = 0; i < 4; i++) { + nRet |= BurnLoadRom(pTemp + nSize * i, nBaseROM + i, 1); + } + + for (int i = 0; i < nSize; i++) { + for (int j = 0; j < 8; j++) { + TigerHeliTileROM[(i << 3) + j] = ((pTemp[i + nSize * 0] >> (7 - j)) & 1) << 3; + TigerHeliTileROM[(i << 3) + j] |= ((pTemp[i + nSize * 1] >> (7 - j)) & 1) << 2; + TigerHeliTileROM[(i << 3) + j] |= ((pTemp[i + nSize * 2] >> (7 - j)) & 1) << 1; + TigerHeliTileROM[(i << 3) + j] |= ((pTemp[i + nSize * 3] >> (7 - j)) & 1) << 0; + } + } + + free(pTemp); + + nTigerHeliTileMask = (nSize >> 3) - 1; + + if (nRet) { + return 1; + } + } + + // Colour PROMs + { + int nBaseROM = 0; + switch (nWhichGame) { + case 0: // Tiger Heli + nBaseROM = 13; + break; + case 1: // Get Star + nBaseROM = 13; + break; + case 2: // Slap Fight + nBaseROM = 12 + nRomOffset; + break; + } + + if (BurnLoadRom(TigerHeliPaletteROM + 0x0000, nBaseROM + 0, 1)) { + return 1; + } + if (BurnLoadRom(TigerHeliPaletteROM + 0x0100, nBaseROM + 1, 1)) { + return 1; + } + if (BurnLoadRom(TigerHeliPaletteROM + 0x0200, nBaseROM + 2, 1)) { + return 1; + } + } + + // Z80 program + { + int nBaseROM = 0; + switch (nWhichGame) { + case 0: // Tiger Heli + nBaseROM = 16; + break; + case 1: // Get Star + nBaseROM = 16; + break; + case 2: // Slap Fight + nBaseROM = 15 + nRomOffset; + break; + } + + if (BurnLoadRom(Rom02, nBaseROM, 1)) { + return 1; + } + } + + return 0; +} + +static int tigerhExit() +{ + BurnTransferExit(); + + TigerHeliSpriteExit(); + TigerHeliTextExit(); + TigerHeliTileExit(); + + ZetExit(); + + // Deallocate all used memory + free(Mem); + Mem = NULL; + + return 0; +} + +static void tigerhDoReset() +{ + bInterruptEnable = false; + bSoundNMIEnable = false; + bSoundCPUEnable = true; + + nStatusIndex = 0; + nProtectIndex = 0; + + ZetOpen(0); + ZetReset(); + ZetClose(); + + ZetOpen(1); + ZetReset(); + ZetClose(); + + return; +} + +static int tigerhInit() +{ + int nLen; + + nWhichGame = -1; + + if (strcmp(BurnDrvGetTextA(DRV_NAME), "tigerh") == 0 || strcmp(BurnDrvGetTextA(DRV_NAME), "tigerhb1") == 0 || strcmp(BurnDrvGetTextA(DRV_NAME), "tigerhb2") == 0) { + nWhichGame = 0; + } + if (strcmp(BurnDrvGetTextA(DRV_NAME), "getstar") == 0 || strcmp(BurnDrvGetTextA(DRV_NAME), "getstarb") == 0 || strcmp(BurnDrvGetTextA(DRV_NAME), "gtstarba") == 0) { + nWhichGame = 1; + } + if (strcmp(BurnDrvGetTextA(DRV_NAME), "slapfigh") == 0 || strcmp(BurnDrvGetTextA(DRV_NAME), "slapbtjp") == 0 || strcmp(BurnDrvGetTextA(DRV_NAME), "slapbtuk") == 0 || strcmp(BurnDrvGetTextA(DRV_NAME), "slapfgtr") == 0) { + nWhichGame = 2; + } + + // Find out how much memory is needed + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char*)0; + if ((Mem = (unsigned char*)malloc(nLen)) == NULL) { + return 1; + } + memset(Mem, 0, nLen); // blank all memory + MemIndex(); // Index the allocated memory + + // Load the roms into memory + if (tigerhLoadROMs()) { + return 1; + } + + { + ZetInit(2); + + // Main CPU setup + ZetOpen(0); + + // Program ROM + ZetMapArea(0x0000, 0x7FFF, 0, Rom01); + ZetMapArea(0x0000, 0x7FFF, 2, Rom01); + // Banked ROM + ZetMapArea(0x8000, 0xBFFF, 0, Rom01 + 0x8000); + ZetMapArea(0x8000, 0xBFFF, 2, Rom01 + 0x8000); + + // Work RAM + ZetMapArea(0xC000, 0xC7FF, 0, Ram01); + ZetMapArea(0xC000, 0xC7FF, 1, Ram01); + ZetMapArea(0xC000, 0xC7FF, 2, Ram01); + + // Shared RAM + if (strcmp(BurnDrvGetTextA(DRV_NAME), "gtstarba")) { + ZetMapArea(0xC800, 0xCFFF, 0, RamShared); + } + ZetMapArea(0xC800, 0xCFFF, 1, RamShared); + ZetMapArea(0xC800, 0xCFFF, 2, RamShared); + + // Tile RAM + ZetMapArea(0xD000, 0xDFFF, 0, TigerHeliTileRAM); + ZetMapArea(0xD000, 0xDFFF, 1, TigerHeliTileRAM); + ZetMapArea(0xD000, 0xDFFF, 2, TigerHeliTileRAM); + // Sprite RAM + ZetMapArea(0xE000, 0xE7FF, 0, TigerHeliSpriteRAM); + ZetMapArea(0xE000, 0xE7FF, 1, TigerHeliSpriteRAM); + ZetMapArea(0xE000, 0xE7FF, 2, TigerHeliSpriteRAM); + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "slapbtuk") || !strcmp(BurnDrvGetTextA(DRV_NAME), "slapfgtr")) { + ZetMapArea(0xec00, 0xeFFF, 0, Rom01 + 0x10c00); + ZetMapArea(0xec00, 0xeFFF, 2, Rom01 + 0x10c00); + } + + // Text RAM + ZetMapArea(0xF000, 0xFFFF, 0, TigerHeliTextRAM); + ZetMapArea(0xF000, 0xFFFF, 1, TigerHeliTextRAM); + ZetMapArea(0xF000, 0xFFFF, 2, TigerHeliTextRAM); + + ZetMemEnd(); + + ZetSetReadHandler(tigerhReadCPU0); + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "slapbtuk") || !strcmp(BurnDrvGetTextA(DRV_NAME), "slapfgtr")) { + ZetSetWriteHandler(tigerhWriteCPU0_slapbtuk); + } else { + ZetSetWriteHandler(tigerhWriteCPU0); + } + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "gtstarba")) { + ZetSetInHandler(tigerhInCPU0_gtstarba); + } else { + ZetSetInHandler(tigerhInCPU0); + } + ZetSetOutHandler(tigerhOutCPU0); + + ZetClose(); + + // Sound CPU setup + ZetOpen(1); + + // Program ROM + ZetMapArea(0x0000, 0x1FFF, 0, Rom02); + ZetMapArea(0x0000, 0x1FFF, 2, Rom02); + + // Work RAM + ZetMapArea(0xC800, 0xCFFF, 0, RamShared); + ZetMapArea(0xC800, 0xCFFF, 1, RamShared); + ZetMapArea(0xC800, 0xCFFF, 2, RamShared); + + ZetMemEnd(); + + ZetSetReadHandler(tigerhReadCPU1); + ZetSetWriteHandler(tigerhWriteCPU1); + ZetSetInHandler(tigerhInCPU1); + ZetSetOutHandler(tigerhOutCPU1); + + ZetClose(); + } + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + pAY8910Buffer[3] = pFMBuffer + nBurnSoundLen * 3; + pAY8910Buffer[4] = pFMBuffer + nBurnSoundLen * 4; + pAY8910Buffer[5] = pFMBuffer + nBurnSoundLen * 5; + + AY8910Init(0, 1500000, nBurnSoundRate, &tigerhReadPort0, &tigerhReadPort1, NULL, NULL); + AY8910Init(1, 1500000, nBurnSoundRate, &tigerhReadPort2, &tigerhReadPort3, NULL, NULL); + + TigerHeliTileInit(); + TigerHeliTextInit(); + TigerHeliSpriteInit(); + TigerHeliPaletteInit(); + + BurnTransferInit(); + + tigerhDoReset(); + + return 0; +} + +static int tigerhScan(int nAction, int* pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + ba.Data = RamStart; + ba.nLen = RamEnd-RamStart; + ba.szName = "All Ram"; + BurnAcb(&ba); + + ZetScan(nAction); // Scan Z80 + + // Scan critical driver variables + SCAN_VAR(bInterruptEnable); + SCAN_VAR(bSoundCPUEnable); + SCAN_VAR(bSoundNMIEnable); + SCAN_VAR(nStatusIndex); + SCAN_VAR(nProtectIndex); + SCAN_VAR(tigerhInput); + } + + return 0; +} + +static void tigerhDraw() +{ + TigerHeliPaletteUpdate(); + + TigerHeliTileRender(); + TigerHeliSpriteRender(); + TigerHeliTextRender(); + + BurnTransferCopy(TigerHeliPalette); + + return; +} + +static inline int CheckSleep(int) +{ + return 0; +} + +static int tigerhFrame() +{ + int nCyclesTotal[2], nCyclesDone[2]; + + if (tigerhReset) { // Reset machine + tigerhDoReset(); + } + + // Compile digital inputs + tigerhInput[0] = 0x00; + tigerhInput[1] = 0x00; + for (int i = 0; i < 8; i++) { + tigerhInput[0] |= (tigerhInpJoy1[i] & 1) << i; + if (nWhichGame == 0 && i < 4) { + tigerhInput[1] |= (tigerhInpMisc[i] & 1) << (i ^ 1); + } else { + tigerhInput[1] |= (tigerhInpMisc[i] & 1) << i; + } + } + + if ((tigerhInput[0] & 0x03) == 0x03) { + tigerhInput[0] &= ~0x03; + } + if ((tigerhInput[0] & 0x0C) == 0x0C) { + tigerhInput[0] &= ~0x0C; + } + if ((tigerhInput[0] & 0x30) == 0x30) { + tigerhInput[0] &= ~0x30; + } + if ((tigerhInput[0] & 0xC0) == 0xC0) { + tigerhInput[0] &= ~0xC0; + } + + if (nWhichGame == 1) { + tigerhInput[0] = (tigerhInput[0] & 0x99) | ((tigerhInput[0] << 1) & 0x44) | ((tigerhInput[0] >> 1) & 0x22); + } + + nCyclesTotal[0] = nCyclesTotal[1] = 6000000 / 60; + nCyclesDone[0] = nCyclesDone[1] = 0; + + const int nVBlankCycles = 248 * 6000000 / 60 / 262; + const int nInterleave = 12; + + int nSoundBufferPos = 0; + int nSoundNMIMask = 0; + switch (nWhichGame) { + case 0: + nSoundNMIMask = 1; + break; + case 1: + nSoundNMIMask = 3; + break; + case 2: + nSoundNMIMask = 3; + break; + } + + bool bVBlank = false; + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU; + int nNext, nCyclesSegment; + + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + + if (nNext > nVBlankCycles && !bVBlank) { + nCyclesDone[nCurrentCPU] += ZetRun(nNext - nVBlankCycles); + + if (pBurnDraw != NULL) { + tigerhDraw(); // Draw screen if needed + } + + TigerHeliBufferSprites(); + + bVBlank = true; + + if (bInterruptEnable) { + ZetRaiseIrq(0xFF); +#if 0 + ZetClose(); + ZetOpen(1); + ZetRaiseIrq(0xFF); + ZetClose(); + ZetOpen(0); +#endif + } + } + + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + if (bVBlank || (!CheckSleep(nCurrentCPU))) { // See if this CPU is busywaiting + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + } else { + nCyclesDone[nCurrentCPU] += nCyclesSegment; + } + + ZetClose(); + + nCurrentCPU = 1; + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + + if (bSoundCPUEnable) { + ZetOpen(nCurrentCPU); + + if ((i & nSoundNMIMask) == 0) { + if (bSoundNMIEnable) { + ZetNmi(); + } + } + + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + ZetClose(); + } else { + nCyclesDone[nCurrentCPU] += nCyclesSegment; + } + + { + // Render sound segment + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen / nInterleave; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + nSoundBufferPos += nSegmentLength; + } + } + } + + { + // Make sure the buffer is entirely filled. + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + } + + return 0; +} + +// --------------------------------------------------------------------------- +// Rom information + +static struct BurnRomInfo tigerhRomDesc[] = { + { "0.4", 0x004000, 0x4BE73246, BRF_ESS | BRF_PRG }, // 0 CPU #0 code + { "1.4", 0x004000, 0xAAD04867, BRF_ESS | BRF_PRG }, // 1 + { "2.4", 0x004000, 0x4843F15C, BRF_ESS | BRF_PRG }, // 2 + + { "a47_13.bin", 0x004000, 0x739A7E7E, BRF_GRA }, // 3 Sprite data + { "a47_12.bin", 0x004000, 0xC064ECDB, BRF_GRA }, // 4 + { "a47_11.bin", 0x004000, 0x744FAE9B, BRF_GRA }, // 5 + { "a47_10.bin", 0x004000, 0xE1CF844E, BRF_GRA }, // 6 + + { "a47_05.bin", 0x002000, 0xC5325B49, BRF_GRA }, // 7 Text layer + { "a47_04.bin", 0x002000, 0xCD59628E, BRF_GRA }, // 8 + + { "a47_09.bin", 0x004000, 0x31FAE8A8, BRF_GRA }, // 9 Background layer + { "a47_08.bin", 0x004000, 0xE539AF2B, BRF_GRA }, // 10 + { "a47_07.bin", 0x004000, 0x02FDD429, BRF_GRA }, // 11 + { "a47_06.bin", 0x004000, 0x11FBCC8C, BRF_GRA }, // 12 + + { "82s129.12q", 0x000100, 0x2C69350D, BRF_GRA }, // 13 + { "82s129.12m", 0x000100, 0x7142E972, BRF_GRA }, // 14 + { "82s129.12n", 0x000100, 0x25F273F2, BRF_GRA }, // 15 + + { "a47_03.bin", 0x002000, 0xD105260F, BRF_ESS | BRF_PRG }, // 16 + + { "a47_14.6a", 0x000800, 0x4042489F, BRF_GRA }, + + { "pal16r4a.2e", 260, 0x00000000, BRF_NODUMP }, +}; + + +STD_ROM_PICK(tigerh); +STD_ROM_FN(tigerh); + +static struct BurnRomInfo tigerhb1RomDesc[] = { + { "14", 0x004000, 0xCA59DD73, BRF_ESS | BRF_PRG }, // 0 CPU #0 code + { "13", 0x004000, 0x38BD54DB, BRF_ESS | BRF_PRG }, // 1 + { "a47_02.bin", 0x004000, 0x633D324B, BRF_ESS | BRF_PRG }, // 2 + + { "a47_13.bin", 0x004000, 0x739A7E7E, BRF_GRA }, // 3 Sprite data + { "a47_12.bin", 0x004000, 0xC064ECDB, BRF_GRA }, // 4 + { "a47_11.bin", 0x004000, 0x744FAE9B, BRF_GRA }, // 5 + { "a47_10.bin", 0x004000, 0xE1CF844E, BRF_GRA }, // 6 + + { "a47_05.bin", 0x002000, 0xC5325B49, BRF_GRA }, // 7 Text layer + { "a47_04.bin", 0x002000, 0xCD59628E, BRF_GRA }, // 8 + + { "a47_09.bin", 0x004000, 0x31FAE8A8, BRF_GRA }, // 9 Background layer + { "a47_08.bin", 0x004000, 0xE539AF2B, BRF_GRA }, // 10 + { "a47_07.bin", 0x004000, 0x02FDD429, BRF_GRA }, // 11 + { "a47_06.bin", 0x004000, 0x11FBCC8C, BRF_GRA }, // 12 + + { "82s129.12q", 0x000100, 0x2C69350D, BRF_GRA }, // 13 + { "82s129.12m", 0x000100, 0x7142E972, BRF_GRA }, // 14 + { "82s129.12n", 0x000100, 0x25F273F2, BRF_GRA }, // 15 + + { "a47_03.bin", 0x002000, 0xD105260F, BRF_ESS | BRF_PRG }, // 16 +}; + + +STD_ROM_PICK(tigerhb1); +STD_ROM_FN(tigerhb1); + +static struct BurnRomInfo tigerhb2RomDesc[] = { + { "rom00_09.bin", 0x004000, 0xef738c68, BRF_ESS | BRF_PRG }, // 0 CPU #0 code + { "a47_01.bin", 0x004000, 0x65df2152, BRF_ESS | BRF_PRG }, // 1 + { "rom02_07.bin", 0x004000, 0x36e250b9, BRF_ESS | BRF_PRG }, // 2 + + { "a47_13.bin", 0x004000, 0x739A7E7E, BRF_GRA }, // 3 Sprite data + { "a47_12.bin", 0x004000, 0xC064ECDB, BRF_GRA }, // 4 + { "a47_11.bin", 0x004000, 0x744FAE9B, BRF_GRA }, // 5 + { "a47_10.bin", 0x004000, 0xE1CF844E, BRF_GRA }, // 6 + + { "a47_05.bin", 0x002000, 0xC5325B49, BRF_GRA }, // 7 Text layer + { "a47_04.bin", 0x002000, 0xCD59628E, BRF_GRA }, // 8 + + { "a47_09.bin", 0x004000, 0x31FAE8A8, BRF_GRA }, // 9 Background layer + { "a47_08.bin", 0x004000, 0xE539AF2B, BRF_GRA }, // 10 + { "a47_07.bin", 0x004000, 0x02FDD429, BRF_GRA }, // 11 + { "a47_06.bin", 0x004000, 0x11FBCC8C, BRF_GRA }, // 12 + + { "82s129.12q", 0x000100, 0x2C69350D, BRF_GRA }, // 13 + { "82s129.12m", 0x000100, 0x7142E972, BRF_GRA }, // 14 + { "82s129.12n", 0x000100, 0x25F273F2, BRF_GRA }, // 15 + + { "a47_03.bin", 0x002000, 0xD105260F, BRF_ESS | BRF_PRG }, // 16 +}; + + +STD_ROM_PICK(tigerhb2); +STD_ROM_FN(tigerhb2); + +static struct BurnRomInfo getstarRomDesc[] = { + { "rom0", 0x004000, 0x6A8BDC6C, BRF_ESS | BRF_PRG }, // 0 CPU #0 code + { "rom1", 0x004000, 0xEBE8DB3C, BRF_ESS | BRF_PRG }, // 1 + { "rom2", 0x008000, 0x343E8415, BRF_ESS | BRF_PRG }, // 2 + + { "a68-13", 0x008000, 0x643FB282, BRF_GRA }, // 3 Sprite data + { "a68-12", 0x008000, 0x11F74E32, BRF_GRA }, // 4 + { "a68-11", 0x008000, 0xF24158CF, BRF_GRA }, // 5 + { "a68-10", 0x008000, 0x83161Ed0, BRF_GRA }, // 6 + + { "a68_05-1", 0x002000, 0x06F60107, BRF_GRA }, // 7 Text layer + { "a68_04-1", 0x002000, 0x1FC8F277, BRF_GRA }, // 8 + + { "a68_09", 0x008000, 0xA293CC2E, BRF_GRA }, // 9 Background layer + { "a68_08", 0x008000, 0x37662375, BRF_GRA }, // 10 + { "a68_07", 0x008000, 0xCF1A964C, BRF_GRA }, // 11 + { "a68_06", 0x008000, 0x05F9EB9A, BRF_GRA }, // 12 + + { "rom21", 0x000100, 0xD6360B4D, BRF_GRA }, // 13 + { "rom20", 0x000100, 0x4CA01887, BRF_GRA }, // 14 + { "rom19", 0x000100, 0x513224F0, BRF_GRA }, // 15 + + { "a68-03", 0x002000, 0x18DAA44C, BRF_ESS | BRF_PRG }, // 16 + + { "68705.bin", 0x000800, 0x00000000, BRF_NODUMP | BRF_ESS | BRF_PRG }, // 17 MCU ROM +}; + + +STD_ROM_PICK(getstar); +STD_ROM_FN(getstar); + +static struct BurnRomInfo getstarbRomDesc[] = { + { "gs_14.rom", 0x004000, 0x1A57A920, BRF_ESS | BRF_PRG }, // 0 CPU #0 code + { "gs_13.rom", 0x004000, 0x805F8E77, BRF_ESS | BRF_PRG }, // 1 + { "a68_02.bin", 0x008000, 0x3567DA17, BRF_ESS | BRF_PRG }, // 2 + + { "a68-13", 0x008000, 0x643FB282, BRF_GRA }, // 3 Sprite data + { "a68-12", 0x008000, 0x11F74E32, BRF_GRA }, // 4 + { "a68-11", 0x008000, 0xF24158CF, BRF_GRA }, // 5 + { "a68-10", 0x008000, 0x83161Ed0, BRF_GRA }, // 6 + + { "a68_05.bin", 0x002000, 0xE3D409E7, BRF_GRA }, // 7 Text layer + { "a68_04.bin", 0x002000, 0x6E5AC9D4, BRF_GRA }, // 8 + + { "a68_09", 0x008000, 0xA293CC2E, BRF_GRA }, // 9 Background layer + { "a68_08", 0x008000, 0x37662375, BRF_GRA }, // 10 + { "a68_07", 0x008000, 0xCF1A964C, BRF_GRA }, // 11 + { "a68_06", 0x008000, 0x05F9EB9A, BRF_GRA }, // 12 + + { "rom21", 0x000100, 0xD6360B4D, BRF_GRA }, // 13 + { "rom20", 0x000100, 0x4CA01887, BRF_GRA }, // 14 + { "rom19", 0x000100, 0x513224F0, BRF_GRA }, // 15 + + { "a68-03", 0x002000, 0x18DAA44C, BRF_ESS | BRF_PRG }, // 16 +}; + + +STD_ROM_PICK(getstarb); +STD_ROM_FN(getstarb); + +static struct BurnRomInfo gtstarbaRomDesc[] = { + { "gs_rb_1.bin", 0x004000, 0x9afad7e0, BRF_ESS | BRF_PRG }, // 0 CPU #0 code + { "gs_rb_2.bin", 0x004000, 0x5feb0a60, BRF_ESS | BRF_PRG }, // 1 + { "gs_rb_3.bin", 0x008000, 0xe3cfb1ba, BRF_ESS | BRF_PRG }, // 2 + + { "a68-13", 0x008000, 0x643FB282, BRF_GRA }, // 3 Sprite data + { "a68-12", 0x008000, 0x11F74E32, BRF_GRA }, // 4 + { "a68-11", 0x008000, 0xF24158CF, BRF_GRA }, // 5 + { "a68-10", 0x008000, 0x83161Ed0, BRF_GRA }, // 6 + + { "a68_05.bin", 0x002000, 0xE3D409E7, BRF_GRA }, // 7 Text layer + { "a68_04.bin", 0x002000, 0x6E5AC9D4, BRF_GRA }, // 8 + + { "a68_09", 0x008000, 0xA293CC2E, BRF_GRA }, // 9 Background layer + { "a68_08", 0x008000, 0x37662375, BRF_GRA }, // 10 + { "a68_07", 0x008000, 0xCF1A964C, BRF_GRA }, // 11 + { "a68_06", 0x008000, 0x05F9EB9A, BRF_GRA }, // 12 + + { "rom21", 0x000100, 0xD6360B4D, BRF_GRA }, // 13 + { "rom20", 0x000100, 0x4CA01887, BRF_GRA }, // 14 + { "rom19", 0x000100, 0x513224F0, BRF_GRA }, // 15 + + { "a68-03", 0x002000, 0x18DAA44C, BRF_ESS | BRF_PRG }, // 16 +}; + + +STD_ROM_PICK(gtstarba); +STD_ROM_FN(gtstarba); + +static struct BurnRomInfo slapfighRomDesc[] = { + { "sf_r19.bin", 0x008000, 0x674C0E0F, BRF_ESS | BRF_PRG }, // 0 CPU #0 code + { "sf_rh.bin", 0x008000, 0x3C42E4A7, BRF_ESS | BRF_PRG }, // 1 + + { "sf_r03.bin", 0x008000, 0x8545D397, BRF_GRA }, // 2 Sprite data + { "sf_r01.bin", 0x008000, 0xB1B7B925, BRF_GRA }, // 3 + { "sf_r04.bin", 0x008000, 0x422D946B, BRF_GRA }, // 4 + { "sf_r02.bin", 0x008000, 0x587113AE, BRF_GRA }, // 5 + + { "sf_r11.bin", 0x002000, 0x2AC7B943, BRF_GRA }, // 6 Text layer + { "sf_r10.bin", 0x002000, 0x33CADC93, BRF_GRA }, // 7 + + { "sf_r06.bin", 0x008000, 0xB6358305, BRF_GRA }, // 8 Background layer + { "sf_r09.bin", 0x008000, 0xE92D9D60, BRF_GRA }, // 9 + { "sf_r08.bin", 0x008000, 0x5FAEEEA3, BRF_GRA }, // 10 + { "sf_r07.bin", 0x008000, 0x974E2EA9, BRF_GRA }, // 11 + + { "sf_col21.bin", 0x000100, 0xA0EFAF99, BRF_GRA }, // 12 + { "sf_col20.bin", 0x000100, 0xA56D57E5, BRF_GRA }, // 13 + { "sf_col19.bin", 0x000100, 0x5CBF9FBF, BRF_GRA }, // 14 + + { "sf_r05.bin", 0x002000, 0x87F4705A, BRF_ESS | BRF_PRG }, // 15 + + { "68705.bin", 0x000800, 0x00000000, BRF_NODUMP | BRF_ESS | BRF_PRG }, // 16 MCU ROM +}; + + +STD_ROM_PICK(slapfigh); +STD_ROM_FN(slapfigh); + +static struct BurnRomInfo slapbtjpRomDesc[] = { + { "sf_r19jb.bin", 0x008000, 0x9A7AC8B3, BRF_ESS | BRF_PRG }, // 0 CPU #0 code + { "sf_rh.bin", 0x008000, 0x3C42E4A7, BRF_ESS | BRF_PRG }, // 1 + + { "sf_r03.bin", 0x008000, 0x8545D397, BRF_GRA }, // 2 Sprite data + { "sf_r01.bin", 0x008000, 0xB1B7B925, BRF_GRA }, // 3 + { "sf_r04.bin", 0x008000, 0x422D946B, BRF_GRA }, // 4 + { "sf_r02.bin", 0x008000, 0x587113AE, BRF_GRA }, // 5 + + { "sf_r11.bin", 0x002000, 0x2AC7B943, BRF_GRA }, // 6 Text layer + { "sf_r10.bin", 0x002000, 0x33CADC93, BRF_GRA }, // 7 + + { "sf_r06.bin", 0x008000, 0xB6358305, BRF_GRA }, // 8 Background layer + { "sf_r09.bin", 0x008000, 0xE92D9D60, BRF_GRA }, // 9 + { "sf_r08.bin", 0x008000, 0x5FAEEEA3, BRF_GRA }, // 10 + { "sf_r07.bin", 0x008000, 0x974E2EA9, BRF_GRA }, // 11 + + { "sf_col21.bin", 0x000100, 0xA0EFAF99, BRF_GRA }, // 12 + { "sf_col20.bin", 0x000100, 0xA56D57E5, BRF_GRA }, // 13 + { "sf_col19.bin", 0x000100, 0x5CBF9FBF, BRF_GRA }, // 14 + + { "sf_r05.bin", 0x002000, 0x87F4705A, BRF_ESS | BRF_PRG }, // 15 +}; + + +STD_ROM_PICK(slapbtjp); +STD_ROM_FN(slapbtjp); + +static struct BurnRomInfo slapbtukRomDesc[] = { + { "sf_r19eb.bin", 0x004000, 0x2efe47af, BRF_ESS | BRF_PRG }, // 0 CPU #0 code + { "sf_r20eb.bin", 0x004000, 0xf42c7951, BRF_ESS | BRF_PRG }, // 1 + { "sf_rh.bin", 0x008000, 0x3C42E4A7, BRF_ESS | BRF_PRG }, // 1 + + { "sf_r03.bin", 0x008000, 0x8545D397, BRF_GRA }, // 2 Sprite data + { "sf_r01.bin", 0x008000, 0xB1B7B925, BRF_GRA }, // 3 + { "sf_r04.bin", 0x008000, 0x422D946B, BRF_GRA }, // 4 + { "sf_r02.bin", 0x008000, 0x587113AE, BRF_GRA }, // 5 + + { "sf_r11.bin", 0x002000, 0x2AC7B943, BRF_GRA }, // 6 Text layer + { "sf_r10.bin", 0x002000, 0x33CADC93, BRF_GRA }, // 7 + + { "sf_r06.bin", 0x008000, 0xB6358305, BRF_GRA }, // 8 Background layer + { "sf_r09.bin", 0x008000, 0xE92D9D60, BRF_GRA }, // 9 + { "sf_r08.bin", 0x008000, 0x5FAEEEA3, BRF_GRA }, // 10 + { "sf_r07.bin", 0x008000, 0x974E2EA9, BRF_GRA }, // 11 + + { "sf_col21.bin", 0x000100, 0xA0EFAF99, BRF_GRA }, // 12 + { "sf_col20.bin", 0x000100, 0xA56D57E5, BRF_GRA }, // 13 + { "sf_col19.bin", 0x000100, 0x5CBF9FBF, BRF_GRA }, // 14 + + { "sf_r05.bin", 0x002000, 0x87F4705A, BRF_ESS | BRF_PRG }, // 15 +}; + + +STD_ROM_PICK(slapbtuk); +STD_ROM_FN(slapbtuk); + +static struct BurnRomInfo slapfgtrRomDesc[] = { + { "k1-10.u90", 0x004000, 0x2efe47af, BRF_ESS | BRF_PRG }, // 0 CPU #0 code + { "k1-09.u89", 0x004000, 0x17c187c5, BRF_ESS | BRF_PRG }, // 1 + { "k1-08.u88", 0x002000, 0x945af97f, BRF_ESS | BRF_PRG }, // 1 + { "k1-07.u87", 0x008000, 0x3C42E4A7, BRF_ESS | BRF_PRG }, // 1 + + { "k1-15.u60", 0x008000, 0x8545D397, BRF_GRA }, // 2 Sprite data + { "k1-13.u50", 0x008000, 0xB1B7B925, BRF_GRA }, // 3 + { "k1-14.u59", 0x008000, 0x422D946B, BRF_GRA }, // 4 + { "k1-12.u49", 0x008000, 0x587113AE, BRF_GRA }, // 5 + + { "k1-02.u57" , 0x002000, 0x2AC7B943, BRF_GRA }, // 6 Text layer + { "k1-03.u58", 0x002000, 0x33CADC93, BRF_GRA }, // 7 + + { "k1-01.u49" , 0x008000, 0xB6358305, BRF_GRA }, // 8 Background layer + { "k1-04.u62", 0x008000, 0xE92D9D60, BRF_GRA }, // 9 + { "k1-05.u63", 0x008000, 0x5FAEEEA3, BRF_GRA }, // 10 + { "k1-06.u64", 0x008000, 0x974E2EA9, BRF_GRA }, // 11 + + { "sf_col21.bin", 0x000100, 0xA0EFAF99, BRF_GRA }, // 12 + { "sf_col20.bin", 0x000100, 0xA56D57E5, BRF_GRA }, // 13 + { "sf_col19.bin", 0x000100, 0x5CBF9FBF, BRF_GRA }, // 14 + + { "k1-11.u89", 0x002000, 0x87F4705A, BRF_ESS | BRF_PRG }, // 15 +}; + + +STD_ROM_PICK(slapfgtr); +STD_ROM_FN(slapfgtr); + +struct BurnDriver BurnDrvTigerH = { + "tigerh", NULL, NULL, "1985", + "Tiger Heli (US)\0", "Protection MCU not emulated", "Taito", "Early Toaplan", + NULL, NULL, NULL, NULL, + BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, tigerhRomInfo, tigerhRomName, tigerhInputInfo, tigerhDIPInfo, + tigerhInit, tigerhExit, tigerhFrame, NULL, tigerhScan, 0, NULL, NULL, NULL, &tigerhRecalcPalette, + 240, 280, 3, 4 +}; + +struct BurnDriver BurnDrvTigerHB1 = { + "tigerhb1", "tigerh", NULL, "1985", + "Tiger Heli (bootleg, set 1)\0", NULL, "Taito", "Early Toaplan", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, tigerhb1RomInfo, tigerhb1RomName, tigerhInputInfo, tigerhDIPInfo, + tigerhInit, tigerhExit, tigerhFrame, NULL, tigerhScan, 0, NULL, NULL, NULL, &tigerhRecalcPalette, + 240, 280, 3, 4 +}; + +struct BurnDriver BurnDrvTigerHB2 = { + "tigerhb2", "tigerh", NULL, "1985", + "Tiger Heli (bootleg, set 2)\0", NULL, "Taito", "Early Toaplan", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, tigerhb2RomInfo, tigerhb2RomName, tigerhInputInfo, tigerhDIPInfo, + tigerhInit, tigerhExit, tigerhFrame, NULL, tigerhScan, 0, NULL, NULL, NULL, &tigerhRecalcPalette, + 240, 280, 3, 4 +}; + +struct BurnDriver BurnDrvGetStar = { + "getstar", NULL, NULL, "1986", + "Guardian\0", "Protection MCU not emulated", "Taito", "Early Toaplan", + NULL, NULL, NULL, NULL, + 0, 2, HARDWARE_MISC_PRE90S, + NULL, getstarRomInfo, getstarRomName, tigerhInputInfo, getstarDIPInfo, + tigerhInit, tigerhExit, tigerhFrame, NULL, tigerhScan, 0, NULL, NULL, NULL, &tigerhRecalcPalette, + 280, 240, 4, 3 +}; + +struct BurnDriver BurnDrvGetStarB = { + "getstarb", "getstar", NULL, "1986", + "Get Star (bootleg, set 1)\0", NULL, "Taito", "Early Toaplan", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_MISC_PRE90S, + NULL, getstarbRomInfo, getstarbRomName, tigerhInputInfo, getstarDIPInfo, + tigerhInit, tigerhExit, tigerhFrame, NULL, tigerhScan, 0, NULL, NULL, NULL, &tigerhRecalcPalette, + 280, 240, 4, 3 +}; + +struct BurnDriver BurnDrvGetStarBa = { + "gtstarba", "getstar", NULL, "1986", + "Get Star (bootleg, set 2)\0", NULL, "Taito", "Early Toaplan", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_MISC_PRE90S, + NULL, gtstarbaRomInfo, gtstarbaRomName, gtstarbaInputInfo, gtstarbaDIPInfo, + tigerhInit, tigerhExit, tigerhFrame, NULL, tigerhScan, 0, NULL, NULL, NULL, &tigerhRecalcPalette, + 280, 240, 4, 3 +}; + +struct BurnDriver BurnDrvSlapFigh = { + "slapfigh", NULL, NULL, "1986", + "Slap Fight (set 1)\0", "Protection MCU not emulated", "Taito", "Early Toaplan", + NULL, NULL, NULL, NULL, + BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, slapfighRomInfo, slapfighRomName, tigerhInputInfo, slapfighDIPInfo, + tigerhInit, tigerhExit, tigerhFrame, NULL, tigerhScan, 0, NULL, NULL, NULL, &tigerhRecalcPalette, + 240, 280, 3, 4 +}; + +struct BurnDriver BurnDrvSlapBtJP = { + "slapbtjp", "slapfigh", NULL, "1986", + "Slap Fight (Japan bootleg)\0", NULL, "Taito", "Early Toaplan", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, slapbtjpRomInfo, slapbtjpRomName, tigerhInputInfo, slapfighDIPInfo, + tigerhInit, tigerhExit, tigerhFrame, NULL, tigerhScan, 0, NULL, NULL, NULL, &tigerhRecalcPalette, + 240, 280, 3, 4 +}; + +struct BurnDriver BurnDrvSlapBtUK = { + "slapbtuk", "slapfigh", NULL, "1986", + "Slap Fight (English bootleg)\0", NULL, "Taito", "Early Toaplan", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, slapbtukRomInfo, slapbtukRomName, tigerhInputInfo, slapfighDIPInfo, + tigerhInit, tigerhExit, tigerhFrame, NULL, tigerhScan, 0, NULL, NULL, NULL, &tigerhRecalcPalette, + 240, 280, 3, 4 +}; + +struct BurnDriver BurnDrvSlapFghtr = { + "slapfgtr", "slapfigh", NULL, "1986", + "Slap Fight (bootleg)\0", NULL, "Taito", "Early Toaplan", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, slapfgtrRomInfo, slapfgtrRomName, tigerhInputInfo, slapfighDIPInfo, + tigerhInit, tigerhExit, tigerhFrame, NULL, tigerhScan, 0, NULL, NULL, NULL, &tigerhRecalcPalette, + 240, 280, 3, 4 +}; diff --git a/src/burn/misc/pre90s/d_tnzs.cpp b/src/burn/misc/pre90s/d_tnzs.cpp new file mode 100644 index 0000000..0e951aa --- /dev/null +++ b/src/burn/misc/pre90s/d_tnzs.cpp @@ -0,0 +1,774 @@ +// FB Alpha The NewZealand Story driver module +// Based on MAME driver by Chris Moore, Brad Oliver, Nicola Salmoria, and many others + +#include "tiles_generic.h" +#include "burn_ym2203.h" + +static unsigned char *Mem, *Rom0, *Rom1, *Rom2, *Gfx; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvJoy3[8], DrvDips[2], DrvReset; +static unsigned int *Palette; + +static int tnzs_bg_flag, tnzs_screenflip; +static int tnzs_cpu1_reset; +static int tnzs_bank0, tnzs_bank1; +static int soundlatch; + +static struct BurnInputInfo DrvInputList[] = { + {"P1 Coin" , BIT_DIGITAL , DrvJoy3 + 4, "p1 coin" }, + {"P2 Coin" , BIT_DIGITAL , DrvJoy3 + 5, "p2 coin" }, + + {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 7, "p1 start" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy1 + 0, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvJoy1 + 1, "p1 right" }, + {"P1 Up", BIT_DIGITAL, DrvJoy1 + 2, "p1 up" }, + {"P1 Down", BIT_DIGITAL, DrvJoy1 + 3, "p1 down", }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy1 + 4, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy1 + 5, "p1 fire 2"}, + + {"P2 Start" , BIT_DIGITAL , DrvJoy2 + 7, "p2 start" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy2 + 0, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvJoy2 + 1, "p2 right" }, + {"P2 Up", BIT_DIGITAL, DrvJoy2 + 2, "p2 up" }, + {"P2 Down", BIT_DIGITAL, DrvJoy2 + 3, "p2 down", }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy2 + 5, "p2 fire 2"}, + + {"Service Mode", BIT_DIGITAL, DrvJoy3 + 0, "diag" }, + {"Tilt", BIT_DIGITAL, DrvJoy3 + 1, "tilt" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDips + 0 , "dip 1" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDips + 1 , "dip 2" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x13, 0xff, 0xff, 0xfe, NULL }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x13, 0x01, 0x01, 0x00, "Upright" }, + {0x13, 0x01, 0x01, 0x01, "Cocktail" }, + + {0 , 0xfe, 0 , 2 , "Flip Screen" }, + {0x13, 0x01, 0x02, 0x02, "Off" }, + {0x13, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Invulnerability (Debug)"}, + {0x13, 0x01, 0x08, 0x08, "Off" }, + {0x13, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x13, 0x01, 0x30, 0x00, "4C 1C" }, + {0x13, 0x01, 0x30, 0x10, "3C 1C" }, + {0x13, 0x01, 0x30, 0x20, "2C 1C" }, + {0x13, 0x01, 0x30, 0x30, "1C 1C" }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x13, 0x01, 0xc0, 0xc0, "1C 2C" }, + {0x13, 0x01, 0xc0, 0x80, "1C 3C" }, + {0x13, 0x01, 0xc0, 0x40, "1C 4C" }, + {0x13, 0x01, 0xc0, 0x00, "1C 5C" }, + + // Default Values + {0x14, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x14, 0x01, 0x03, 0x02, "Easy" }, + {0x14, 0x01, 0x03, 0x03, "Medium" }, + {0x14, 0x01, 0x03, 0x01, "Hard" }, + {0x14, 0x01, 0x03, 0x00, "Hardest" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x14, 0x01, 0x0c, 0x00, "50000 150000" }, + {0x14, 0x01, 0x0c, 0x0c, "70000 200000" }, + {0x14, 0x01, 0x0c, 0x04, "100000 250000" }, + {0x14, 0x01, 0x0c, 0x08, "200000 300000" }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x14, 0x01, 0x30, 0x20, "2" }, + {0x14, 0x01, 0x30, 0x30, "3" }, + {0x14, 0x01, 0x30, 0x00, "4" }, + {0x14, 0x01, 0x30, 0x10, "5" }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x14, 0x01, 0x40, 0x00, "No" }, + {0x14, 0x01, 0x40, 0x40, "Yes" }, +}; + +STDDIPINFO(Drv); + +void __fastcall tnzs_bankswitch_w(unsigned char data) +{ + if (~data & 0x10) { + tnzs_cpu1_reset = 1; + } + + tnzs_bank0 = (data & 7) | 0x10; + + ZetMapArea(0x8000, 0xbfff, 0, Rom0 + 0x10000 + 0x4000 * (data & 7)); + ZetMapArea(0x8000, 0xbfff, 1, Rom0 + 0x10000 + 0x4000 * (data & 7)); + ZetMapArea(0x8000, 0xbfff, 2, Rom0 + 0x10000 + 0x4000 * (data & 7)); +} + +void __fastcall tnzs_bankswitch1_w(unsigned char data) +{ + tnzs_bank1 = data & 3; + + ZetMapArea(0x8000, 0x9fff, 0, Rom1 + 0x10000 + 0x2000 * (data & 3)); + ZetMapArea(0x8000, 0x9fff, 2, Rom1 + 0x10000 + 0x2000 * (data & 3)); +} + +void __fastcall tnzs_cpu0_write(unsigned short address, unsigned char data) +{ + if (address > 0xf7ff) return; + + switch (address) + { + case 0xf400: + tnzs_bg_flag = data; + break; + + case 0xf600: + tnzs_bankswitch_w(data); + break; + } + + if (address >= 0xe000 && address <= 0xefff) + { + if (address == 0xef10 && data == 0xff) { + data = 0; // probably not right... + } + + Rom0[address] = data; + return; + } + + if (address >= 0xf300 && address <= 0xf3ff) + { + Rom0[address & 0xff03] = data; + return; + } +} + +inline static unsigned char pal5bit(unsigned char bits) +{ + bits &= 0x1f; + return (bits << 3) | (bits >> 2); +} + +void __fastcall tnzs_cpu1_write(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0xa000: + tnzs_bankswitch1_w(data); + break; + + case 0xb004: + soundlatch = data; + ZetClose(); + ZetOpen(2); + ZetRaiseIrq(0); + ZetClose(); + ZetOpen(0); + break; + } + + if (address >= 0xf000 && address <= 0xf3ff) + { + Rom1[address & 0xf3ff] = data; + + unsigned short pal = (Rom1[address | 1] << 8) | (Rom1[address & ~1]); + + Palette[(address >> 1) & 0x3ff] = (pal5bit(pal >> 10) << 16) | (pal5bit(pal >> 5) << 8) | pal5bit(pal); + return; + } +} + +unsigned char __fastcall tnzs_cpu1_read(unsigned short address) +{ + switch (address) + { + case 0xb002: + return DrvDips[0]; + + case 0xb003: + return DrvDips[1]; + + // lhld can't use handlers, so use a MapArea instead + case 0xc000: // inp2 + case 0xc001: // inp3 + case 0xc002: // inp4 + return 0; + } + + if (address >= 0xf000 && address <= 0xf003) { + return Rom1[address]; + } + + return 0; +} + +void __fastcall tnzs_cpu2_out(unsigned short port, unsigned char data) +{ + switch (port & 0xff) + { + case 0x00: + BurnYM2203Write(0, 0, data); + break; + + case 0x01: + BurnYM2203Write(0, 1, data); + break; + } +} + +unsigned char __fastcall tnzs_cpu2_in(unsigned short port) +{ + switch (port & 0xff) + { + case 0x00: + return BurnYM2203Read(0, 0); + + case 0x02: + return soundlatch; + } + + return 0; +} + +inline static void DrvYM2203IRQHandler(int, int nStatus) +{ + if (nStatus & 1) { + ZetNmi(); + } else { + ZetSetIRQLine(0, ZET_IRQSTATUS_NONE); + } +} + +inline static int DrvSynchroniseStream(int nSoundRate) +{ + return (long long)ZetTotalCycles() * nSoundRate / 6000000; +} + +inline static double DrvGetTime() +{ + return (double)ZetTotalCycles() / 6000000; +} + +static int DrvDoReset() +{ + memset (Palette, 0, 0x200 * sizeof(int)); + memset (Rom0 + 0x0c000, 0, 0x2000); + memset (Rom0 + 0x0e000, 0, 0x1000); + memset (Rom0 + 0x0f000, 0, 0x0400); + memset (Rom0 + 0x10000, 0, 0x8000); + memset (Rom1 + 0x0d000, 0, 0x1000); + memset (Rom1 + 0x0f000, 0, 0x0400); + memset (Rom2 + 0x0c000, 0, 0x2000); + + tnzs_bg_flag = tnzs_screenflip = 0; + tnzs_cpu1_reset = 0; + soundlatch = 0; + + for (int i = 0; i < 3; i++) { + ZetOpen(i); + ZetReset(); + if (i == 0) tnzs_bankswitch_w(0x17); + if (i == 1) tnzs_bankswitch1_w(0x00); + ZetClose(); + } + + BurnYM2203Reset(); + + return 0; +} + +static int tnzs_gfx_convert() +{ + unsigned char *tmp = (unsigned char*)malloc(0x100000); + if (tmp == NULL) { + return 1; + } + + memcpy (tmp, Gfx, 0x100000); + + static int Plane[4] = { 0x600000, 0x400000, 0x200000, 0x000000 }; + static int XOffs[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 64, 65, 66, 67, 68, 69, 70, 71 }; + static int YOffs[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 128, 136, 144, 152, 160, 168, 176, 184 }; + + GfxDecode(0x2000, 4, 16, 16, Plane, XOffs, YOffs, 0x100, tmp, Gfx); + + free (tmp); + + return 0; +} + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x30000 + 0x20000 + 0x10000 + 0x200000 + 0x804); + if (Mem == NULL) { + return 1; + } + + Rom0 = Mem + 0x000000; + Rom1 = Mem + 0x030000; + Rom2 = Mem + 0x050000; + Gfx = Mem + 0x060000; + Palette = (unsigned int*)(Mem + 0x260000); + + { + if (BurnLoadRom(Rom0 + 0x10000, 0, 1)) return 1; + memcpy (Rom0, Rom0 + 0x10000, 0x8000); + + if (BurnLoadRom(Rom1 + 0x00000, 1, 1)) return 1; + memcpy (Rom1 + 0x10000, Rom1 + 0x08000, 0x8000); + memset (Rom1 + 0x08000, 0, 0x08000); + + if (BurnLoadRom(Rom2 + 0x00000, 2, 1)) return 1; + + for (int i = 0; i < 8; i++) + if (BurnLoadRom(Gfx + i * 0x20000, i + 3, 1)) return 1; + + if (tnzs_gfx_convert()) return 1; + } + + ZetInit(3); + ZetOpen(0); + ZetSetWriteHandler(tnzs_cpu0_write); + ZetMapArea(0x0000, 0x7fff, 0, Rom0 + 0x00000); + ZetMapArea(0x0000, 0x7fff, 2, Rom0 + 0x00000); + ZetMapArea(0x8000, 0xbfff, 0, Rom0 + 0x2c000); + ZetMapArea(0x8000, 0xbfff, 2, Rom0 + 0x2c000); + ZetMapArea(0xc000, 0xdfff, 0, Rom0 + 0x0c000); + ZetMapArea(0xc000, 0xdfff, 1, Rom0 + 0x0c000); + ZetMapArea(0xe000, 0xefff, 0, Rom0 + 0x0e000); + ZetMapArea(0xe000, 0xefff, 1, Rom0 + 0x0e000); + ZetMapArea(0xe000, 0xefff, 2, Rom0 + 0x0e000); + ZetMapArea(0xf000, 0xf1ff, 0, Rom0 + 0x0f000); + ZetMapArea(0xf000, 0xf1ff, 1, Rom0 + 0x0f000); + ZetMapArea(0xf000, 0xf1ff, 2, Rom0 + 0x0f000); + ZetMapArea(0xf200, 0xf2ff, 0, Rom0 + 0x0f200); + ZetMapArea(0xf200, 0xf2ff, 1, Rom0 + 0x0f200); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetSetWriteHandler(tnzs_cpu1_write); + ZetSetReadHandler(tnzs_cpu1_read); + ZetMapArea(0x0000, 0x7fff, 0, Rom1 + 0x00000); + ZetMapArea(0x0000, 0x7fff, 2, Rom1 + 0x00000); + ZetMapArea(0x8000, 0x9fff, 0, Rom1 + 0x10000); + ZetMapArea(0x8000, 0x9fff, 2, Rom1 + 0x10000); + ZetMapArea(0xc000, 0xc0ff, 0, Rom1 + 0x0c000); // read inputs + ZetMapArea(0xd000, 0xdfff, 0, Rom1 + 0x0d000); + ZetMapArea(0xd000, 0xdfff, 1, Rom1 + 0x0d000); + ZetMapArea(0xd000, 0xdfff, 2, Rom1 + 0x0d000); + ZetMapArea(0xe000, 0xefff, 0, Rom0 + 0x0e000); + ZetMapArea(0xe000, 0xefff, 1, Rom0 + 0x0e000); + ZetMapArea(0xe000, 0xefff, 2, Rom0 + 0x0e000); + ZetMemEnd(); + ZetClose(); + + ZetOpen(2); + ZetSetInHandler(tnzs_cpu2_in); + ZetSetOutHandler(tnzs_cpu2_out); + ZetMapArea(0x0000, 0x7fff, 0, Rom2 + 0x0000); + ZetMapArea(0x0000, 0x7fff, 2, Rom2 + 0x0000); + ZetMapArea(0xc000, 0xdfff, 0, Rom2 + 0xc000); + ZetMapArea(0xc000, 0xdfff, 1, Rom2 + 0xc000); + ZetMapArea(0xc000, 0xdfff, 2, Rom2 + 0xc000); + ZetMemEnd(); + ZetClose(); + + BurnYM2203Init(1, 3000000, &DrvYM2203IRQHandler, DrvSynchroniseStream, DrvGetTime, 0); + BurnTimerAttachZet(6000000); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + BurnYM2203Exit(); + + free (Mem); + + Mem = Rom0 = Rom1 = Rom2 = Gfx = NULL; + Palette = NULL; + + tnzs_bg_flag = tnzs_screenflip = 0; + tnzs_cpu1_reset = 0; + tnzs_bank0 = tnzs_bank1 = 0; + soundlatch = 0; + + return 0; +} + +static inline void tnzs_plotpix(int x, unsigned char y, int color, unsigned char src, int transp) +{ + if (x < 0 || x > 255 || y > 223) return; + if (transp && !src) return; + + int pxl = Palette[color | src]; + + PutPix(pBurnDraw + ((y << 8) | x) * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); +} + +static void draw_16x16(int sx, int sy, int code, int color, int flipx, int flipy, int transp) +{ + unsigned char *src = Gfx + (code << 8); + + if (flipy) { + for (int y = sy + 15; y >= sy; y--) { + if (flipx) { + for (int x = sx + 15; x >= sx; x--, src++) { + tnzs_plotpix(x, y, color, *src, transp); + } + } else { + for (int x = sx; x < sx + 16; x++, src++) { + tnzs_plotpix(x, y, color, *src, transp); + } + } + } + } else { + for (int y = sy; y < sy + 16; y++) { + if (flipx) { + for (int x = sx + 15; x >= sx; x--, src++) { + tnzs_plotpix(x, y, color, *src, transp); + } + } else { + for (int x = sx; x < sx + 16; x++, src++) { + tnzs_plotpix(x, y, color, *src, transp); + } + } + } + } +} + +static void draw_background() +{ + unsigned char *m = Rom0 + 0xc400; + unsigned char *tnzs_objctrl = Rom0 + 0xf300; + unsigned char *tnzs_scrollram = Rom0 + 0xf200; + + int x,y,column,tot,flag; + int scrollx, scrolly; + unsigned int upperbits; + int ctrl2 = tnzs_objctrl[1]; + + if ((ctrl2 ^ (~ctrl2<<1)) & 0x40) { + m += 0x800; + } + + if (tnzs_bg_flag & 0x80) + flag = 0; + else + flag = 1; + + tot = tnzs_objctrl[1] & 0x1f; + if (tot == 1) tot = 16; + + upperbits = tnzs_objctrl[2] | (tnzs_objctrl[3] << 8); + + for (column = 0;column < tot;column++) + { + scrollx = tnzs_scrollram[column*16+4] - ((upperbits & 0x01) << 8); + if (tnzs_screenflip) + scrolly = tnzs_scrollram[column*16] + 1 - 256; + else + scrolly = -tnzs_scrollram[column*16] + 1; + + for (y = 0; y < 16; y++) + { + for (x = 0; x < 2; x++) + { + int code,color,flipx,flipy,sx,sy; + int i = 32 * (column ^ 8) + 2 * y + x; + + code = m[i] + ((m[i + 0x1000] & 0x1f) << 8); + color = (m[i + 0x1200] & 0xf8) << 1; + sx = x << 4; + sy = y << 4; + flipx = m[i + 0x1000] & 0x80; + flipy = m[i + 0x1000] & 0x40; + if (tnzs_screenflip) + { + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } + + sy = ((sy + 16 + scrolly) & 0xff) - 32; + sx += scrollx; + + draw_16x16(sx, sy, code, color, flipx, flipy, flag); + } + } + + upperbits >>= 1; + } +} + +static void draw_foreground() +{ + int i; + unsigned char *tnzs_objctrl = Rom0 + 0xf300; + unsigned char *char_pointer = Rom0 + 0xc000; + unsigned char *x_pointer = Rom0 + 0xc200; + unsigned char *y_pointer = Rom0 + 0xf000; + unsigned char *ctrl_pointer = Rom0 + 0xd000; + unsigned char *color_pointer = Rom0 + 0xd200; + int ctrl2 = tnzs_objctrl[1]; + + if ((ctrl2 ^ (~ctrl2<<1)) & 0x40) + { + char_pointer += 0x800; + x_pointer += 0x800; + ctrl_pointer += 0x800; + color_pointer += 0x800; + } + + for (i=0x1ff;i >= 0;i--) + { + int code,color,sx,sy,flipx,flipy; + + code = char_pointer[i] + ((ctrl_pointer[i] & 0x1f) << 8); + color = (color_pointer[i] & 0xf8) << 1; + sx = x_pointer[i] - ((color_pointer[i] & 1) << 8); + sy = y_pointer[i] ^ 0xff; + flipx = ctrl_pointer[i] & 0x80; + flipy = ctrl_pointer[i] & 0x40; + if (tnzs_screenflip) + { + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } else { + sy -= 32; + } + + sy += 2; + + draw_16x16(sx, sy, code, color, flipx, flipy, 1); + } +} + +static void clear_background(int col) +{ + for (int i = 0; i < 256 * 256; i++) { + tnzs_plotpix(i & 0xff, i >> 8, col, 0, 0); + } +} + +static int DrvDraw() +{ + int ctrl2 = Rom0[0xf301]; + + tnzs_screenflip = (Rom0[0xf300] & 0x40) >> 6; + + if (nBurnLayer & 2) { + clear_background(0x1f0); + draw_background(); + } else { + Palette[0x200] = 0xff00ff; + clear_background(0x200); + } + + if (nBurnLayer & 1) draw_foreground(); + + if (~ctrl2 & 0x20) + { + if (ctrl2 & 0x40) + { + memcpy(Rom0 + 0xc000, Rom0 + 0xc800, 0x0400); + memcpy(Rom0 + 0xd000, Rom0 + 0xd800, 0x0400); + } + else + { + memcpy(Rom0 + 0xc800, Rom0 + 0xc000, 0x0400); + memcpy(Rom0 + 0xd800, Rom0 + 0xd000, 0x0400); + } + + memcpy(Rom0 + 0xc400, Rom0 + 0xcc00, 0x0400); + memcpy(Rom0 + 0xd400, Rom0 + 0xdc00, 0x0400); + } + + return 0; +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetNewFrame(); + + // Assemble inputs (work-around for lhld bug in Doze) + { + Rom1[0xc000] = Rom1[0xc001] = Rom1[0xc002] = 0xff; + for (int i = 0; i < 8; i++) { + Rom1[0xc000] ^= DrvJoy1[i] << i; + Rom1[0xc001] ^= DrvJoy2[i] << i; + Rom1[0xc002] ^= DrvJoy3[i] << i; + } + } + + int nInterleave = 10; + + int nCyclesSegment; + int nCyclesDone[3], nCyclesTotal[3]; + + nCyclesTotal[0] = 6000000 / 60; + nCyclesTotal[1] = 6000000 / 60; + nCyclesTotal[2] = 6000000 / 60; + + nCyclesDone[0] = nCyclesDone[1] = nCyclesDone[2] = 0; + + for (int i = 0; i < nInterleave; i++) { + int nCurrentCPU, nNext; + + // Run Z80 #0 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment); + if (i+1 == nInterleave) ZetSetIRQLine(0, ZET_IRQSTATUS_AUTO); + ZetClose(); + + // Run Z80 #1 + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + if (tnzs_cpu1_reset) { + ZetReset(); + tnzs_cpu1_reset = 0; + } + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesSegment = ZetRun(nCyclesSegment); + nCyclesDone[nCurrentCPU] += nCyclesSegment; + if (i+1 == nInterleave) ZetSetIRQLine(0, ZET_IRQSTATUS_AUTO); + ZetClose(); + } + + ZetOpen(2); + BurnTimerEndFrame(nCyclesTotal[2] - nCyclesDone[2]); + BurnYM2203Update(pBurnSoundOut, nBurnSoundLen); + ZetClose(); + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029672; + } + + if (nAction & ACB_VOLATILE) { + ba.Data = Rom0 + 0xc000; + ba.nLen = 0x2000; + ba.szName = "CPU0 Video RAM"; + BurnAcb(&ba); + + ba.Data = Rom0 + 0xe000; + ba.nLen = 0x1000; + ba.szName = "Shared RAM"; + BurnAcb(&ba); + + ba.Data = Rom0 + 0xf000; + ba.nLen = 0x0400; + ba.szName = "CPU0 Misc Ram"; + BurnAcb(&ba); + + ba.Data = Rom0 + 0x10000; + ba.nLen = 0x8000; + ba.szName = "CPU0 Banked Ram"; + BurnAcb(&ba); + + ba.Data = Rom1 + 0xd000; + ba.nLen = 0x1000; + ba.szName = "CPU1 Main RAM"; + BurnAcb(&ba); + + ba.Data = Rom1 + 0xf000; + ba.nLen = 0x0400; + ba.szName = "Palette RAM"; + BurnAcb(&ba); + + ba.Data = Rom2 + 0xc000; + ba.nLen = 0x2000; + ba.szName = "CPU2 Main RAM"; + BurnAcb(&ba); + + ba.Data = (unsigned char*)Palette; + ba.nLen = 0x0200 * sizeof(int); + ba.szName = "Palette"; + BurnAcb(&ba); + + ZetScan(nAction); + BurnYM2203Scan(nAction, pnMin); + + SCAN_VAR(soundlatch); + SCAN_VAR(tnzs_bg_flag); + SCAN_VAR(tnzs_screenflip); + SCAN_VAR(tnzs_bank0); + SCAN_VAR(tnzs_bank1); + SCAN_VAR(tnzs_cpu1_reset); + + ZetOpen(0); + tnzs_bankswitch_w(tnzs_bank0); + ZetClose(); + ZetOpen(1); + tnzs_bankswitch1_w(tnzs_bank1); + ZetClose(); + } + + return 0; +} + +// The NewZealand Story (World, newer) + +static struct BurnRomInfo tnzsRomDesc[] = { + { "b53-24.1", 0x20000, 0xd66824c6, 1 | BRF_ESS | BRF_PRG }, // 0 Z80 #0 Code + + { "b53-25.3", 0x10000, 0xd6ac4e71, 2 | BRF_ESS | BRF_PRG }, // 1 Z80 #1 Code + + { "b53-26.34", 0x10000, 0xcfd5649c, 3 | BRF_ESS | BRF_PRG }, // 2 Z80 #2 Code + + { "b53-08.8", 0x20000, 0xc3519c2a, 4 | BRF_GRA }, // 3 Graphics + { "b53-07.7", 0x20000, 0x2bf199e8, 4 | BRF_GRA }, // 4 + { "b53-06.6", 0x20000, 0x92f35ed9, 4 | BRF_GRA }, // 5 + { "b53-05.5", 0x20000, 0xedbb9581, 4 | BRF_GRA }, // 6 + { "b53-04.4", 0x20000, 0x59d2aef6, 4 | BRF_GRA }, // 7 + { "b53-03.3", 0x20000, 0x74acfb9b, 4 | BRF_GRA }, // 8 + { "b53-02.2", 0x20000, 0x095d0dc0, 4 | BRF_GRA }, // 9 + { "b53-01.1", 0x20000, 0x9800c54d, 4 | BRF_GRA }, // 10 +}; + +STD_ROM_PICK(tnzs); +STD_ROM_FN(tnzs); + +struct BurnDriver BurnDrvtnzs = { + "tnzs", NULL, NULL, "1988", + "The NewZealand Story (World, newer)\0", NULL, "Taito Corporation Japan", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, tnzsRomInfo, tnzsRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 224, 4, 3 +}; + diff --git a/src/burn/misc/pre90s/d_vulgus.cpp b/src/burn/misc/pre90s/d_vulgus.cpp new file mode 100644 index 0000000..97ea1a8 --- /dev/null +++ b/src/burn/misc/pre90s/d_vulgus.cpp @@ -0,0 +1,832 @@ +// FB Alpha Vulgus drive module +// Based on MAME driver by Mirko Buffoni + +// To do: flip screen + +#include "tiles_generic.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + +static unsigned char *Mem, *MemEnd, *Rom0, *Rom1, *Gfx0, *Gfx1, *Gfx2, *Prom; +static unsigned char DrvJoy1[8], DrvJoy2[8], DrvJoy3[8], DrvDips[2], DrvReset; +static short *pAY8910Buffer[6], *pFMBuffer = NULL; +static unsigned int *DrvPalette, *Palette; +static unsigned char DrvRecalc; + +static int vulgus_soundlatch; +static int vulgus_scroll[2]; +static int vulgus_palette_bank; +static int vulgus_flipscreen; + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1" , BIT_DIGITAL , DrvJoy1 + 7, "p1 coin" }, + {"Coin 2" , BIT_DIGITAL , DrvJoy1 + 6, "p2 coin" }, + {"P1 Start" , BIT_DIGITAL , DrvJoy1 + 0, "p1 start" }, + {"P2 Start" , BIT_DIGITAL , DrvJoy1 + 1, "p2 start" }, + + {"P1 Right" , BIT_DIGITAL , DrvJoy2 + 0, "p1 right" }, + {"P1 Left" , BIT_DIGITAL , DrvJoy2 + 1, "p1 left" }, + {"P1 Down" , BIT_DIGITAL , DrvJoy2 + 2, "p1 down" }, + {"P1 Up" , BIT_DIGITAL , DrvJoy2 + 3, "p1 up" }, + {"P1 Button 1" , BIT_DIGITAL , DrvJoy2 + 4, "p1 fire 1"}, + {"P1 Button 2" , BIT_DIGITAL , DrvJoy2 + 5, "p1 fire 2"}, + + {"P2 Right" , BIT_DIGITAL , DrvJoy3 + 0, "p2 right" }, + {"P2 Left" , BIT_DIGITAL , DrvJoy3 + 1, "p2 left" }, + {"P2 Down" , BIT_DIGITAL , DrvJoy3 + 2, "p2 down" }, + {"P2 Up" , BIT_DIGITAL , DrvJoy3 + 3, "p2 up" }, + {"P2 Button 1" , BIT_DIGITAL , DrvJoy3 + 4, "p2 fire 1"}, + {"P2 Button 2" , BIT_DIGITAL , DrvJoy3 + 5, "p2 fire 2"}, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDips + 0, "dip 1" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDips + 1, "dip 2" }, +}; + +STDINPUTINFO(Drv); + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, + {0x12, 0xff, 0xff, 0x7f, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x11, 0x01, 0x03, 0x01, "1" }, + {0x11, 0x01, 0x03, 0x02, "2" }, + {0x11, 0x01, 0x03, 0x03, "3" }, + {0x11, 0x01, 0x03, 0x00, "5" }, + + {0 , 0xfe, 0 , 7 , "Coin B" }, + {0x11, 0x01, 0x1c, 0x10, "5 Coins 1 Play" }, + {0x11, 0x01, 0x1c, 0x08, "4 Coins 1 Play" }, + {0x11, 0x01, 0x1c, 0x18, "3 Coins 1 Play" }, + {0x11, 0x01, 0x1c, 0x04, "2 Coins 1 Play" }, + {0x11, 0x01, 0x1c, 0x1c, "1 Coin 1 Play" }, + {0x11, 0x01, 0x1c, 0x0c, "1 Coin 2 Plays" }, + {0x11, 0x01, 0x1c, 0x14, "1 Coin 3 Plays" }, +// {0x11, 0x01, 0x1c, 0x00, "Invalid" }, + + {0 , 0xfe, 0 , 8 , "Coin A" }, + {0x11, 0x01, 0xe0, 0x80, "5 Coins 1 Play" }, + {0x11, 0x01, 0xe0, 0x40, "4 Coins 1 Play" }, + {0x11, 0x01, 0xe0, 0xc0, "3 Coins 1 Play" }, + {0x11, 0x01, 0xe0, 0x20, "2 Coins 1 Play" }, + {0x11, 0x01, 0xe0, 0xe0, "1 Coin 1 Play" }, + {0x11, 0x01, 0xe0, 0x60, "1 Coin 2 Plays" }, + {0x11, 0x01, 0xe0, 0xa0, "1 Coin 3 Plays" }, + {0x11, 0x01, 0xe0, 0x00, "Freeplay" }, + + // Dip 2 + {0 , 0xfe, 0 , 4 , "Difficulty?" }, + {0x12, 0x01, 0x03, 0x02, "Easy?" }, + {0x12, 0x01, 0x03, 0x03, "Normal?" }, + {0x12, 0x01, 0x03, 0x01, "Hard?" }, + {0x12, 0x01, 0x03, 0x00, "Hardest?" }, + + {0 , 0xfe, 0 , 2 , "Demo Music" }, + {0x12, 0x01, 0x04, 0x00, "Off" }, + {0x12, 0x01, 0x04, 0x04, "On" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x12, 0x01, 0x08, 0x00, "Off" }, + {0x12, 0x01, 0x08, 0x08, "On" }, + + {0 , 0xfe, 0 , 8 , "Bonus Life" }, + {0x12, 0x01, 0x70, 0x30, "10000 50000" }, + {0x12, 0x01, 0x70, 0x50, "10000 60000" }, + {0x12, 0x01, 0x70, 0x10, "10000 70000" }, + {0x12, 0x01, 0x70, 0x70, "20000 60000" }, + {0x12, 0x01, 0x70, 0x60, "20000 70000" }, + {0x12, 0x01, 0x70, 0x20, "20000 80000" }, + {0x12, 0x01, 0x70, 0x40, "30000 70000" }, + {0x12, 0x01, 0x70, 0x00, "None" }, + + {0 , 0xfe, 0 , 2 , "Cabinet" }, + {0x12, 0x01, 0x80, 0x00, "Upright" }, + {0x12, 0x01, 0x80, 0x80, "Cocktail" }, +}; + +STDDIPINFO(Drv); + +void __fastcall vulgus_write_main(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0xc800: + vulgus_soundlatch = data; + break; + + case 0xc802: + case 0xc803: + vulgus_scroll[address & 1] = (vulgus_scroll[address & 1] & 0xff00) | data; + break; + + case 0xc804: + vulgus_flipscreen = data >> 7; + break; + + case 0xc805: + vulgus_palette_bank = data & 3; + break; + + case 0xc902: + case 0xc903: + vulgus_scroll[address & 1] = (vulgus_scroll[address & 1] & 0x00ff) | (data << 8); + break; + } +} + +unsigned char __fastcall vulgus_read_main(unsigned short address) +{ + unsigned char ret; + + switch (address) + { + case 0xc000: + { + ret = 0xff; + + for (int i = 0; i < 8; i++) ret ^= DrvJoy1[i] << i; + + return ret; + } + + case 0xc001: + { + ret = 0xff; + + for (int i = 0; i < 5; i++) ret ^= DrvJoy2[i] << i; + + return ret; + } + + case 0xc002: + { + ret = 0xff; + + for (int i = 0; i < 5; i++) ret ^= DrvJoy3[i] << i; + + return ret; + } + + case 0xc003: + return DrvDips[0]; + + case 0xc004: + return DrvDips[1]; + } + + return 0; +} + +void __fastcall vulgus_write_sound(unsigned short address, unsigned char data) +{ + switch (address) + { + case 0x8000: + case 0x8001: + case 0xc000: + case 0xc001: + AY8910Write((address >> 14) & 1, address & 1, data); + break; + } +} + +unsigned char __fastcall vulgus_read_sound(unsigned short address) +{ + switch (address) + { + case 0x6000: + return vulgus_soundlatch; + } + + return 0; +} + +static int DrvDoReset() +{ + DrvReset = 0; + + vulgus_flipscreen = 0; + vulgus_soundlatch = 0; + vulgus_palette_bank = 0; + + vulgus_scroll[0] = 0; + vulgus_scroll[1] = 0; + + memset (Rom0 + 0xcc00, 0, 0x2400); + memset (Rom1 + 0x4000, 0, 0x0800); + + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + + AY8910Reset(i); + } + + return 0; +} + +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + Rom0 = Next; Next += 0x10000; + Rom1 = Next; Next += 0x05000; + Gfx0 = Next; Next += 0x08000; + Gfx1 = Next; Next += 0x20000; + Gfx2 = Next; Next += 0x10000; + Prom = Next; Next += 0x00600; + + Palette = (unsigned int*)Next; Next += 0x00800 * sizeof(unsigned int); + DrvPalette = (unsigned int*)Next; Next += 0x00800 * sizeof(unsigned int); + + pFMBuffer = (short*)Next; Next += (nBurnSoundLen * 6 * sizeof(short)); + + MemEnd = Next; + + return 0; +} + +static int DrvPaletteInit() +{ + unsigned int *tmp = (unsigned int*)malloc(0x100 * sizeof(int)); + if (tmp == NULL) { + return 1; + } + + for (int i = 0; i < 256; i++) + { + int bit0,bit1,bit2,bit3,r,g,b; + + bit0 = (Prom[ 0 + i] >> 0) & 0x01; + bit1 = (Prom[ 0 + i] >> 1) & 0x01; + bit2 = (Prom[ 0 + i] >> 2) & 0x01; + bit3 = (Prom[ 0 + i] >> 3) & 0x01; + r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (Prom[256 + i] >> 0) & 0x01; + bit1 = (Prom[256 + i] >> 1) & 0x01; + bit2 = (Prom[256 + i] >> 2) & 0x01; + bit3 = (Prom[256 + i] >> 3) & 0x01; + g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (Prom[512 + i] >> 0) & 0x01; + bit1 = (Prom[512 + i] >> 1) & 0x01; + bit2 = (Prom[512 + i] >> 2) & 0x01; + bit3 = (Prom[512 + i] >> 3) & 0x01; + b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + tmp[i] = (r << 16) | (g << 8) | b; + } + + for (int i = 0; i < 0x100; i++) { + Palette[i] = tmp[32 + Prom[0x300 + i]]; + } + + for (int i = 0; i < 0x100; i++) { + Palette[0x100 + i] = tmp[16 + Prom[0x400 + i]]; + } + + for (int i = 0; i < 0x100; i++) { + Palette[0x400 + i] = tmp[Prom[0x500 + i] + 0x00]; + Palette[0x500 + i] = tmp[Prom[0x500 + i] + 0x40]; + Palette[0x600 + i] = tmp[Prom[0x500 + i] + 0x80]; + Palette[0x700 + i] = tmp[Prom[0x500 + i] + 0xc0]; + } + + free (tmp); + + return 0; +} + +static int DrvGfxDecode() +{ + unsigned char *tmp = (unsigned char*)malloc(0xc000); + if (tmp == NULL) { + return 1; + } + + static int SpriPlanes[4] = { 0x20004, 0x20000, 0x00004, 0x00000 }; + static int SpriXOffs[16] = { 0x000, 0x001, 0x002, 0x003, 0x008, 0x009, 0x00a, 0x00b, + 0x100, 0x101, 0x102, 0x103, 0x108, 0x109, 0x10a, 0x10b }; + static int SpriYOffs[16] = { 0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, + 0x080, 0x090, 0x0a0, 0x0b0, 0x0c0, 0x0d0, 0x0e0, 0x0f0 }; + + static int TilePlanes[3] = { 0x00000, 0x20000, 0x40000 }; + static int TileXOffs[16] = { 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, + 0x080, 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087 }; + static int TileYOffs[16] = { 0x000, 0x008, 0x010, 0x018, 0x020, 0x028, 0x030, 0x038, + 0x040, 0x048, 0x050, 0x058, 0x060, 0x068, 0x070, 0x078 }; + + memcpy (tmp, Gfx0, 0x2000); + + GfxDecode(0x200, 2, 8, 8, SpriPlanes + 2, SpriXOffs, SpriYOffs, 0x080, tmp, Gfx0); + + memcpy (tmp, Gfx1, 0xc000); + + GfxDecode(0x200, 3, 16, 16, TilePlanes + 0, TileXOffs, TileYOffs, 0x100, tmp, Gfx1); + + memcpy (tmp, Gfx2, 0x8000); + + GfxDecode(0x100, 4, 16, 16, SpriPlanes + 0, SpriXOffs, SpriYOffs, 0x200, tmp, Gfx2); + + free (tmp); + + return 0; +} + +static int DrvInit() +{ + int nLen; + + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + for (int i = 0; i < 6; i++) { + pAY8910Buffer[i] = pFMBuffer + nBurnSoundLen * i; + } + + { + for (int i = 0; i < 5; i++) { + if (BurnLoadRom(Rom0 + i * 0x2000, i + 0, 1)) return 1; + } + + if (BurnLoadRom(Rom1 + 0x0000, 5, 1)) return 1; + if (BurnLoadRom(Gfx0 + 0x0000, 6, 1)) return 1; + + for (int i = 0; i < 6; i++) { + if (BurnLoadRom(Gfx1 + i * 0x2000, i + 7, 1)) return 1; + } + + for (int i = 0; i < 4; i++) { + if (BurnLoadRom(Gfx2 + i * 0x2000, i + 13, 1)) return 1; + } + + for (int i = 0; i < 6; i++) { + if (BurnLoadRom(Prom + i * 0x0100, i + 17, 1)) return 1; + } + + if (DrvPaletteInit()) return 1; + if (DrvGfxDecode()) return 1; + } + + ZetInit(2); + ZetOpen(0); + ZetMapArea(0x0000, 0x9fff, 0, Rom0 + 0x0000); + ZetMapArea(0x0000, 0x9fff, 2, Rom0 + 0x0000); + ZetMapArea(0xcc00, 0xccff, 0, Rom0 + 0xcc00); + ZetMapArea(0xcc00, 0xccff, 1, Rom0 + 0xcc00); + ZetMapArea(0xd000, 0xdfff, 0, Rom0 + 0xd000); + ZetMapArea(0xd000, 0xdfff, 1, Rom0 + 0xd000); + ZetMapArea(0xe000, 0xefff, 0, Rom0 + 0xe000); + ZetMapArea(0xe000, 0xefff, 1, Rom0 + 0xe000); + ZetMapArea(0xe000, 0xefff, 2, Rom0 + 0xe000); + ZetSetWriteHandler(vulgus_write_main); + ZetSetReadHandler(vulgus_read_main); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetMapArea(0x0000, 0x1fff, 0, Rom1 + 0x0000); + ZetMapArea(0x0000, 0x1fff, 2, Rom1 + 0x0000); + ZetMapArea(0x4000, 0x47ff, 0, Rom1 + 0x4000); + ZetMapArea(0x4000, 0x47ff, 1, Rom1 + 0x4000); + ZetMapArea(0x4000, 0x47ff, 2, Rom1 + 0x4000); + ZetSetWriteHandler(vulgus_write_sound); + ZetSetReadHandler(vulgus_read_sound); + ZetMemEnd(); + ZetClose(); + + AY8910Init(0, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + AY8910Init(1, 1500000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + GenericTilesInit(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + AY8910Exit(0); + AY8910Exit(1); + GenericTilesExit(); + + free (Mem); + + Mem = MemEnd = Rom0 = Rom1 = NULL; + Gfx0 = Gfx1 = Gfx2 = Prom = NULL; + pFMBuffer = NULL; + + for (int i = 0; i < 6; i++) { + pAY8910Buffer[i] = NULL; + } + + DrvPalette = Palette = NULL; + + DrvRecalc = 0; + + vulgus_soundlatch = 0; + vulgus_scroll[0] = vulgus_scroll[1] = 0; + vulgus_palette_bank = 0; + vulgus_flipscreen = 0; + + return 0; +} + +static int DrvDraw() +{ + if (DrvRecalc) { + for (int i = 0; i < 0x800; i++) { + int color = Palette[i]; + DrvPalette[i] = BurnHighCol(color >> 16, color >> 8, color, 0); + } + } + + for (int offs = 0; offs < 0x400; offs++) + { + int sx, sy, color, code, flipx, flipy; + + sx = (offs >> 1) & 0x1f0; + sy = (offs << 4) & 0x1f0; + + sx -= vulgus_scroll[1]; + sy -= vulgus_scroll[0]; + + if (sx < -15) sx += 0x200; // wrap + if (sy < -15) sy += 0x200; + + color = Rom0[0xdc00 + offs]; + code = Rom0[0xd800 + offs] | ((color & 0x80) << 1); + + flipx = color & 0x20; + flipy = color & 0x40; + + color = (color & 0x1f) | (vulgus_palette_bank << 5); + + sy -= 0x10; + + if (flipy) { + if (flipx) { + Render16x16Tile_FlipXY_Clip(pTransDraw, code, sx, sy, color, 3, 0x400, Gfx1); + } else { + Render16x16Tile_FlipY_Clip(pTransDraw, code, sx, sy, color, 3, 0x400, Gfx1); + } + } else { + if (flipx) { + Render16x16Tile_FlipX_Clip(pTransDraw, code, sx, sy, color, 3, 0x400, Gfx1); + } else { + Render16x16Tile_Clip(pTransDraw, code, sx, sy, color, 3, 0x400, Gfx1); + } + } + } + + for (int offs = 0x7c; offs >= 0; offs -= 4) + { + int code, i, color, sx, sy; + + code = Rom0[0xcc00 + offs]; + color = Rom0[0xcc01 + offs] & 0x0f; + sx = Rom0[0xcc03 + offs]; + sy = Rom0[0xcc02 + offs]; + + sy -= 0x10; + + i = Rom0[0xcc01 + offs] >> 6; + if (i == 2) i = 3; + + for (; i >= 0; i--) { + int ssy = sy + (i << 4); + Render16x16Tile_Mask_Clip(pTransDraw, code + i, sx, ssy, color, 4, 0x0f, 0x100, Gfx2); + if (ssy > 240) { // wrap + Render16x16Tile_Mask_Clip(pTransDraw, code + i, sx, ssy - 256, color, 4, 0x0f, 0x100, Gfx2); + } + } + } + + for (int offs = 0x40; offs < 0x3c0; offs++) + { + int sx, sy, color, code; + + color = Rom0[0xd400 + offs]; + code = Rom0[0xd000 + offs] | ((color & 0x80) << 1); + + if (code == 0x20) continue; + + unsigned char *src = Gfx0 + (code << 6); + + color = (color & 0x3f) << 2; + + sx = (offs << 3) & 0xf8; + sy = (offs >> 2) & 0xf8; + + sy -= 0x10; + + for (int y = sy; y < sy + 8; y++) { + for (int x = sx; x < sx + 8; x++, src++) { + int pxl = color | *src; + if (Prom[0x300 | pxl] == 0x0f) continue; + pTransDraw[(y << 8) | x] = pxl; + } + } + } + + if (vulgus_flipscreen) { + int nSize = (nScreenWidth * nScreenHeight) - 1; + for (int i = 0; i < nSize >> 1; i++) { + int n = pTransDraw[i]; + pTransDraw[i] = pTransDraw[nSize - i]; + pTransDraw[nSize - i] = n; + } + } + + BurnTransferCopy(DrvPalette); + + return 0; +} + + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + int nInterleave = 8; + int nSoundBufferPos = 0; + int nCycles[2] = { 4000000 / 60, 3000000 / 60 }; + + for (int i = 0; i < nInterleave; i++) + { + ZetOpen(0); + nCycles[0] -= ZetRun(nCycles[0] / (nInterleave - i)); + if (i == ((nInterleave / 2) - 1)) ZetRaiseIrq(0xd7); + if (i == ( nInterleave - 1)) ZetRaiseIrq(0xcf); + ZetClose(); + + ZetOpen(1); + nCycles[1] -= ZetRun(nCycles[1] / (nInterleave - i)); + ZetRaiseIrq(0); + ZetClose(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) | 0] = nSample; + pSoundBuf[(n << 1) | 1] = nSample; + } + nSoundBufferPos += nSegmentLength; + } + } + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen - nSoundBufferPos; + short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1); + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + AY8910Update(1, &pAY8910Buffer[3], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n] >> 2; + nSample += pAY8910Buffer[1][n] >> 2; + nSample += pAY8910Buffer[2][n] >> 2; + nSample += pAY8910Buffer[3][n] >> 2; + nSample += pAY8910Buffer[4][n] >> 2; + nSample += pAY8910Buffer[5][n] >> 2; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) | 0] = nSample; + pSoundBuf[(n << 1) | 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom0 + 0xcc00; + ba.nLen = 0x2400; + ba.szName = "All CPU #0 Ram"; + BurnAcb(&ba); + + ba.Data = Rom1 + 0x4000; + ba.nLen = 0x0800; + ba.szName = "All CPU #1 Ram"; + BurnAcb(&ba); + + ZetScan(nAction); + AY8910Scan(nAction, pnMin); + + SCAN_VAR(vulgus_flipscreen); + SCAN_VAR(vulgus_soundlatch); + SCAN_VAR(vulgus_palette_bank); + SCAN_VAR(vulgus_scroll[0]); + SCAN_VAR(vulgus_scroll[1]); + } + + return 0; +} + + +// Vulgus (set 1) + +static struct BurnRomInfo vulgusRomDesc[] = { + { "v2", 0x2000, 0x3e18ff62, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "v3", 0x2000, 0xb4650d82, 1 | BRF_PRG | BRF_ESS }, // 1 + { "v4", 0x2000, 0x5b26355c, 1 | BRF_PRG | BRF_ESS }, // 2 + { "v5", 0x2000, 0x4ca7f10e, 1 | BRF_PRG | BRF_ESS }, // 3 + { "1-8n.bin", 0x2000, 0x6ca5ca41, 1 | BRF_PRG | BRF_ESS }, // 4 + + { "1-11c.bin", 0x2000, 0x3bd2acf4, 2 | BRF_PRG | BRF_ESS }, // 5 Z80 #1 Code + + { "1-3d.bin", 0x2000, 0x8bc5d7a5, 3 | BRF_GRA }, // 6 Foreground Tiles + + { "2-2a.bin", 0x2000, 0xe10aaca1, 4 | BRF_GRA }, // 7 Background Tiles + { "2-3a.bin", 0x2000, 0x8da520da, 4 | BRF_GRA }, // 8 + { "2-4a.bin", 0x2000, 0x206a13f1, 4 | BRF_GRA }, // 9 + { "2-5a.bin", 0x2000, 0xb6d81984, 4 | BRF_GRA }, // 10 + { "2-6a.bin", 0x2000, 0x5a26b38f, 4 | BRF_GRA }, // 11 + { "2-7a.bin", 0x2000, 0x1e1ca773, 4 | BRF_GRA }, // 12 + + { "2-2n.bin", 0x2000, 0x6db1b10d, 5 | BRF_GRA }, // 13 Sprites + { "2-3n.bin", 0x2000, 0x5d8c34ec, 5 | BRF_GRA }, // 14 + { "2-4n.bin", 0x2000, 0x0071a2e3, 5 | BRF_GRA }, // 15 + { "2-5n.bin", 0x2000, 0x4023a1ec, 5 | BRF_GRA }, // 16 + + { "e8.bin", 0x0100, 0x06a83606, 6 | BRF_GRA }, // 17 Color Proms + { "e9.bin", 0x0100, 0xbeacf13c, 6 | BRF_GRA }, // 18 + { "e10.bin", 0x0100, 0xde1fb621, 6 | BRF_GRA }, // 19 + { "d1.bin", 0x0100, 0x7179080d, 6 | BRF_GRA }, // 20 + { "j2.bin", 0x0100, 0xd0842029, 6 | BRF_GRA }, // 21 + { "c9.bin", 0x0100, 0x7a1f0bd6, 6 | BRF_GRA }, // 22 + + { "82s126.9k", 0x0100, 0x32b10521, 0 | BRF_OPT }, // 23 Misc. Proms + { "82s129.8n", 0x0100, 0x4921635c, 0 | BRF_OPT }, // 24 +}; + +STD_ROM_PICK(vulgus); +STD_ROM_FN(vulgus); + +struct BurnDriver BurnDrvvulgus = { + "vulgus", NULL, NULL, "1984", + "Vulgus (set 1)\0", NULL, "Capcom", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_MISC_PRE90S, + NULL, vulgusRomInfo, vulgusRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalc, + 224, 256, 3, 4 +}; + + +// Vulgus (set 2) + +static struct BurnRomInfo vulgus2RomDesc[] = { + { "vulgus.002", 0x2000, 0xe49d6c5d, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "vulgus.003", 0x2000, 0x51acef76, 1 | BRF_PRG | BRF_ESS }, // 1 + { "vulgus.004", 0x2000, 0x489e7f60, 1 | BRF_PRG | BRF_ESS }, // 2 + { "vulgus.005", 0x2000, 0xde3a24a8, 1 | BRF_PRG | BRF_ESS }, // 3 + { "1-8n.bin", 0x2000, 0x6ca5ca41, 1 | BRF_PRG | BRF_ESS }, // 4 + + { "1-11c.bin", 0x2000, 0x3bd2acf4, 2 | BRF_PRG | BRF_ESS }, // 5 Z80 #1 Code + + { "1-3d.bin", 0x2000, 0x8bc5d7a5, 3 | BRF_GRA }, // 6 Foreground Tiles + + { "2-2a.bin", 0x2000, 0xe10aaca1, 4 | BRF_GRA }, // 7 Background Tiles + { "2-3a.bin", 0x2000, 0x8da520da, 4 | BRF_GRA }, // 8 + { "2-4a.bin", 0x2000, 0x206a13f1, 4 | BRF_GRA }, // 9 + { "2-5a.bin", 0x2000, 0xb6d81984, 4 | BRF_GRA }, // 10 + { "2-6a.bin", 0x2000, 0x5a26b38f, 4 | BRF_GRA }, // 11 + { "2-7a.bin", 0x2000, 0x1e1ca773, 4 | BRF_GRA }, // 12 + + { "2-2n.bin", 0x2000, 0x6db1b10d, 5 | BRF_GRA }, // 13 Sprites + { "2-3n.bin", 0x2000, 0x5d8c34ec, 5 | BRF_GRA }, // 14 + { "2-4n.bin", 0x2000, 0x0071a2e3, 5 | BRF_GRA }, // 15 + { "2-5n.bin", 0x2000, 0x4023a1ec, 5 | BRF_GRA }, // 16 + + { "e8.bin", 0x0100, 0x06a83606, 6 | BRF_GRA }, // 17 Color Proms + { "e9.bin", 0x0100, 0xbeacf13c, 6 | BRF_GRA }, // 18 + { "e10.bin", 0x0100, 0xde1fb621, 6 | BRF_GRA }, // 19 + { "d1.bin", 0x0100, 0x7179080d, 6 | BRF_GRA }, // 20 + { "j2.bin", 0x0100, 0xd0842029, 6 | BRF_GRA }, // 21 + { "c9.bin", 0x0100, 0x7a1f0bd6, 6 | BRF_GRA }, // 22 + + { "82s126.9k", 0x0100, 0x32b10521, 0 | BRF_OPT }, // 23 Misc. Proms + { "82s129.8n", 0x0100, 0x4921635c, 0 | BRF_OPT }, // 24 +}; + +STD_ROM_PICK(vulgus2); +STD_ROM_FN(vulgus2); + +struct BurnDriver BurnDrvvulgus2 = { + "vulgus2", "vulgus", NULL, "1984", + "Vulgus (set 2)\0", NULL, "Capcom", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, vulgus2RomInfo, vulgus2RomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalc, + 224, 256, 3, 4 +}; + + +// Vulgus (Japan) + +static struct BurnRomInfo vulgusjRomDesc[] = { + { "1-4n.bin", 0x2000, 0xfe5a5ca5, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "1-5n.bin", 0x2000, 0x847e437f, 1 | BRF_PRG | BRF_ESS }, // 1 + { "1-6n.bin", 0x2000, 0x4666c436, 1 | BRF_PRG | BRF_ESS }, // 2 + { "1-7n.bin", 0x2000, 0xff2097f9, 1 | BRF_PRG | BRF_ESS }, // 3 + { "1-8n.bin", 0x2000, 0x6ca5ca41, 1 | BRF_PRG | BRF_ESS }, // 4 + + { "1-11c.bin", 0x2000, 0x3bd2acf4, 2 | BRF_PRG | BRF_ESS }, // 5 Z80 #1 Code + + { "1-3d.bin", 0x2000, 0x8bc5d7a5, 3 | BRF_GRA }, // 6 Foreground Tiles + + { "2-2a.bin", 0x2000, 0xe10aaca1, 4 | BRF_GRA }, // 7 Background Tiles + { "2-3a.bin", 0x2000, 0x8da520da, 4 | BRF_GRA }, // 8 + { "2-4a.bin", 0x2000, 0x206a13f1, 4 | BRF_GRA }, // 9 + { "2-5a.bin", 0x2000, 0xb6d81984, 4 | BRF_GRA }, // 10 + { "2-6a.bin", 0x2000, 0x5a26b38f, 4 | BRF_GRA }, // 11 + { "2-7a.bin", 0x2000, 0x1e1ca773, 4 | BRF_GRA }, // 12 + + { "2-2n.bin", 0x2000, 0x6db1b10d, 5 | BRF_GRA }, // 13 Sprites + { "2-3n.bin", 0x2000, 0x5d8c34ec, 5 | BRF_GRA }, // 14 + { "2-4n.bin", 0x2000, 0x0071a2e3, 5 | BRF_GRA }, // 15 + { "2-5n.bin", 0x2000, 0x4023a1ec, 5 | BRF_GRA }, // 16 + + { "e8.bin", 0x0100, 0x06a83606, 6 | BRF_GRA }, // 17 Color Proms + { "e9.bin", 0x0100, 0xbeacf13c, 6 | BRF_GRA }, // 18 + { "e10.bin", 0x0100, 0xde1fb621, 6 | BRF_GRA }, // 19 + { "d1.bin", 0x0100, 0x7179080d, 6 | BRF_GRA }, // 20 + { "j2.bin", 0x0100, 0xd0842029, 6 | BRF_GRA }, // 21 + { "c9.bin", 0x0100, 0x7a1f0bd6, 6 | BRF_GRA }, // 22 + + { "82s126.9k", 0x0100, 0x32b10521, 0 | BRF_OPT }, // 23 Misc. Proms + { "82s129.8n", 0x0100, 0x4921635c, 0 | BRF_OPT }, // 24 +}; + +STD_ROM_PICK(vulgusj); +STD_ROM_FN(vulgusj); + +struct BurnDriver BurnDrvvulgusj = { + "vulgusj", "vulgus", NULL, "1984", + "Vulgus (Japan?)\0", NULL, "Capcom", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, + NULL, vulgusjRomInfo, vulgusjRomName, DrvInputInfo, DrvDIPInfo, + DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, &DrvRecalc, + 224, 256, 3, 4 +}; + diff --git a/src/burn/misc/pre90s/d_wallc.cpp b/src/burn/misc/pre90s/d_wallc.cpp new file mode 100644 index 0000000..a87ab69 --- /dev/null +++ b/src/burn/misc/pre90s/d_wallc.cpp @@ -0,0 +1,484 @@ +// Wall Crash FBA Driver Module +// Based on MAME driver (wallc.c) by Jarek Burczynski + +#include "burnint.h" +#include "bitswap.h" +#include "driver.h" +extern "C" { +#include "ay8910.h" +} + + +static unsigned char *Mem, *Rom, *Gfx, *Prom; +static int Palette[8]; + +static unsigned char DrvJoy1[8], DrvDips[2], DrvReset; +static unsigned short DrvAxis[1]; +static unsigned int nAnalogAxis; + +static short *pFMBuffer = NULL, *pAY8910Buffer[3]; + +static int wallca; + + +#define A(a, b, c, d) { a, b, (unsigned char*)(c), d } + +static struct BurnInputInfo DrvInputList[] = { + {"Coin 1" , BIT_DIGITAL , DrvJoy1 + 0, "p1 coin" }, + {"Coin 2" , BIT_DIGITAL , DrvJoy1 + 1, "p2 coin" }, + {"Coin 3" , BIT_DIGITAL , DrvJoy1 + 2, "p3 coin" }, + {"Start" , BIT_DIGITAL , DrvJoy1 + 3, "p1 start" }, + {"P1 Button 1", BIT_DIGITAL, DrvJoy1 + 4, "p1 fire 1" }, + {"P1 Button 2", BIT_DIGITAL, DrvJoy1 + 5, "p1 fire 2" }, + + A("P1 Right / left", BIT_ANALOG_REL, DrvAxis + 0, "mouse x-axis"), + + {"Service" , BIT_DIGITAL , DrvJoy1 + 6, "diag" }, + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDips + 0 , "dip" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDips + 1 , "dip" }, +}; + +STDINPUTINFO(Drv); + + +static struct BurnDIPInfo DrvDIPList[]= +{ + // Default Values + {0x09, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 4 , "Lives" }, + {0x09, 0x01, 0x03, 0x03, "5" }, + {0x09, 0x01, 0x03, 0x02, "4" }, + {0x09, 0x01, 0x03, 0x01, "3" }, + {0x09, 0x01, 0x03, 0x00, "2" }, + + {0 , 0xfe, 0 , 4 , "Bonus Life" }, + {0x09, 0x01, 0x0c, 0x0c, "100K/200K/400K/800K" }, + {0x09, 0x01, 0x0c, 0x08, "80K/160K/320K/640K" }, + {0x09, 0x01, 0x0c, 0x04, "60K/120K/240K/480K" }, + {0x09, 0x01, 0x0c, 0x00, "Off" }, + + {0 , 0xfe, 0 , 2 , "Curve Effect" }, + {0x09, 0x01, 0x10, 0x10, "Normal" }, + {0x09, 0x01, 0x10, 0x00, "More" }, + + {0 , 0xfe, 0 , 4 , "Timer Speed" }, + {0x09, 0x01, 0x60, 0x60, "Slow" }, + {0x09, 0x01, 0x60, 0x40, "Normal" }, + {0x09, 0x01, 0x60, 0x20, "Fast" }, + {0x09, 0x01, 0x60, 0x00, "Super Fast" }, + + {0 , 0xfe, 0 , 2 , "Service" }, + {0x09, 0x01, 0x80, 0x80, "Free Play and Level Select" }, + {0x09, 0x01, 0x80, 0x00, "Normal" }, + + // Default Values + {0x0a, 0xff, 0xff, 0xff, NULL }, + + {0 , 0xfe, 0 , 4 , "Coin A" }, + {0x0a, 0x01, 0x03, 0x03, "2C 1C" }, + {0x0a, 0x01, 0x03, 0x00, "1C 1C" }, + {0x0a, 0x01, 0x03, 0x01, "1C 2C" }, + {0x0a, 0x01, 0x03, 0x02, "1C 5C" }, + + {0 , 0xfe, 0 , 4 , "Coin B" }, + {0x0a, 0x01, 0x0c, 0x0c, "2C 1C" }, + {0x0a, 0x01, 0x0c, 0x00, "1C 1C" }, + {0x0a, 0x01, 0x0c, 0x04, "1C 2C" }, + {0x0a, 0x01, 0x0c, 0x08, "1C 5C" }, + + {0 , 0xfe, 0 , 4 , "Coin C" }, + {0x0a, 0x01, 0x30, 0x30, "2C 1C" }, + {0x0a, 0x01, 0x30, 0x00, "1C 1C" }, + {0x0a, 0x01, 0x30, 0x10, "1C 2C" }, + {0x0a, 0x01, 0x30, 0x20, "1C 5C" }, +}; + +STDDIPINFO(Drv); + + +void __fastcall wallc_write_handler(unsigned short a, unsigned char d) +{ + switch (a) + { + case 0xb000: // ? + case 0xb100: // coin counter + case 0xb200: // ? + break; + + case 0xb500: + AY8910Write(0, 0, d); + break; + + case 0xb600: + AY8910Write(0, 1, d); + break; + } +} + +unsigned char __fastcall wallc_read_handler(unsigned short a) +{ + unsigned char ret = 0; + + switch (a) + { + case 0xb000: // input port 0 + ret = DrvDips[0]; + break; + + case 0xb200: // input port 1 + ret |= DrvJoy1[5]; + ret |= DrvJoy1[6] << 2; + ret |= DrvJoy1[4] << 3; + ret |= DrvJoy1[0] << 4; + ret |= DrvJoy1[1] << 5; + ret |= DrvJoy1[2] << 6; + ret |= DrvJoy1[3] << 7; + ret ^= 0xff; + break; + + case 0xb400: // input port 2 + nAnalogAxis -= DrvAxis[0]; + ret = (nAnalogAxis >> 8) & 0xFF; + break; + + case 0xb600: // input port 3 + ret = DrvDips[1]; + break; + } + + return ret; +} + + +static int DrvDoReset() +{ + DrvReset = 0; + nAnalogAxis = 0; + + memset(Rom + 0x8000, 0, 0x0400); + memset(Rom + 0xa000, 0, 0x0400); + + ZetOpen(0); + ZetReset(); + ZetClose(); + + AY8910Reset(0); + + return 0; +} + +static void wallc_palette_init() +{ + int i; + for (i = 8; i < 16; i++) + { + int bit0,bit1,bit7,r,g,b; + + // red component + bit0 = (Prom[i] >> 5) & 0x01; + bit1 = (Prom[i] >> 6) & 0x01; + r = ((77 * bit1) + (115 * bit0)) + 1; + + // green component + bit0 = (Prom[i] >> 2) & 0x01; + bit1 = (Prom[i] >> 3) & 0x01; + g = ((77 * bit1) + (115 * bit0)) + 1; + + // blue component + bit0 = (Prom[i] >> 0) & 0x01; + bit1 = (Prom[i] >> 1) & 0x01; + bit7 = (Prom[i] >> 7) & 0x01; + b = ((54 * bit7) + (84 * bit1) + (115 * bit0)); + + Palette[i-8] = (r << 16) | (g << 8) | b; + } +} + +static int DrvInit() +{ + Mem = (unsigned char*)malloc(0x10000 + 0x04000 + 0x00020); + if (Mem == NULL) { + return 1; + } + + pFMBuffer = (short *)malloc (nBurnSoundLen * 3 * sizeof(short)); + if (pFMBuffer == NULL) { + return 1; + } + + Rom = Mem + 0x00000; + Gfx = Mem + 0x10000; + Prom = Mem + 0x14000; + + pAY8910Buffer[0] = pFMBuffer + nBurnSoundLen * 0; + pAY8910Buffer[1] = pFMBuffer + nBurnSoundLen * 1; + pAY8910Buffer[2] = pFMBuffer + nBurnSoundLen * 2; + + { + if (BurnLoadRom(Rom + 0x0000, 0, 1)) return 1; + if (BurnLoadRom(Rom + 0x2000, 1, 1)) return 1; + + if (BurnLoadRom(Gfx + 0x0000 + 0x800 * wallca, 2, 1)) return 1; + if (BurnLoadRom(Gfx + 0x1000 + 0x800 * wallca, 3, 1)) return 1; + if (BurnLoadRom(Gfx + 0x2000 + 0x800 * wallca, 4, 1)) return 1; + + if (BurnLoadRom(Prom, 5, 1)) return 1; + } + + // Convert gfx + { + int i; + unsigned char a, b, c; + unsigned char *tmp = (unsigned char*)malloc(0x8000); + for (i = 0; i < 0x1000 * 8; i++) + { + a = (Gfx[(i >> 3) + 0x0000] >> (i & 7)) & 1; + b = (Gfx[(i >> 3) + 0x1000] >> (i & 7)) & 1; + c = (Gfx[(i >> 3) + 0x2000] >> (i & 7)) & 1; + + tmp[i] = (a << 2) | (b << 1) | c; + } + memcpy (Gfx, tmp + 0x4000, 0x4000); + free (tmp); + + wallc_palette_init(); + } + + ZetInit(1); + ZetOpen(0); + ZetSetReadHandler(wallc_read_handler); + ZetSetWriteHandler(wallc_write_handler); + ZetMapArea(0x0000, 0x7fff, 0, Rom + 0x0000); + ZetMapArea(0x0000, 0x7fff, 2, Rom + 0x0000); + + ZetMapArea(0x8000, 0x83ff, 0, Rom + 0x8000); + ZetMapArea(0x8000, 0x83ff, 1, Rom + 0x8000); + ZetMapArea(0x8000, 0x83ff, 2, Rom + 0x8000); + + ZetMapArea(0x8c00, 0x8fff, 0, Rom + 0x8000); // Mirror + ZetMapArea(0x8c00, 0x8fff, 1, Rom + 0x8000); + ZetMapArea(0x8c00, 0x8fff, 2, Rom + 0x8000); + + ZetMapArea(0xa000, 0xa3ff, 0, Rom + 0xa000); + ZetMapArea(0xa000, 0xa3ff, 1, Rom + 0xa000); + ZetMapArea(0xa000, 0xa3ff, 2, Rom + 0xa000); + ZetMemEnd(); + ZetClose(); + + AY8910Init(0, 1536000, nBurnSoundRate, NULL, NULL, NULL, NULL); + + DrvDoReset(); + + return 0; +} + +static int DrvExit() +{ + ZetExit(); + AY8910Exit(0); + + free (Mem); + free (pFMBuffer); + + Mem = Rom = Gfx = Prom = NULL; + pAY8910Buffer[0] = pAY8910Buffer[1] = pAY8910Buffer[2] = NULL; + + return 0; +} + + +static int DrvDraw() +{ + unsigned char *vram = Rom + 0x8000; + + int offs; + for (offs = 0; offs < 0x400; offs ++) + { + int sy = (~offs & 0x1f) << 3; + int sx = (offs >> 2) & 0xf8; + unsigned char *src = Gfx + (vram[offs] << 6); + + for (int y = sy; y < sy + 8; y++) + { + for (int x = sx; x < sx + 8; x++, src++) + { + int pxl = Palette[src[0]]; + + PutPix(pBurnDraw + ((y << 8) | x) * nBurnBpp, BurnHighCol(pxl >> 16, pxl >> 8, pxl, 0)); + } + } + } + + return 0; +} + +static int DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetOpen(0); + ZetRun(3072000 / 60); + ZetSetIRQLine(0, ZET_IRQSTATUS_AUTO); + ZetClose(); + + if (pBurnSoundOut) { + int nSample; + int nSegmentLength = nBurnSoundLen; + short* pSoundBuf = pBurnSoundOut; + if (nSegmentLength) { + AY8910Update(0, &pAY8910Buffer[0], nSegmentLength); + for (int n = 0; n < nSegmentLength; n++) { + nSample = pAY8910Buffer[0][n]; + nSample += pAY8910Buffer[1][n]; + nSample += pAY8910Buffer[2][n]; + + nSample /= 4; + + if (nSample < -32768) { + nSample = -32768; + } else { + if (nSample > 32767) { + nSample = 32767; + } + } + + pSoundBuf[(n << 1) + 0] = nSample; + pSoundBuf[(n << 1) + 1] = nSample; + } + } + } + + if (pBurnDraw) { + DrvDraw(); + } + + return 0; +} + + +static int DrvScan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_VOLATILE) { // Scan volatile ram + memset(&ba, 0, sizeof(ba)); + + ba.Data = Rom + 0x8000; + ba.nLen = 0x0400; + ba.szName = "Video Ram"; + BurnAcb(&ba); + + ba.Data = Rom + 0xa000; + ba.nLen = 0x0400; + ba.szName = "Main Ram"; + BurnAcb(&ba); + + ZetScan(nAction); // Scan Z80 + + AY8910Scan(nAction, pnMin); // Scan AY8910 + + // Scan critical driver variables + SCAN_VAR(nAnalogAxis); + } + + return 0; +} + + + +// Wall Crash (set 1) + +static struct BurnRomInfo wallcRomDesc[] = { + { "wac05.h7", 0x2000, 0xab6e472e, 0 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "wac1-52.h6", 0x2000, 0x988eaa6d, 0 | BRF_ESS | BRF_PRG }, // 1 + + { "wc1.e3", 0x1000, 0xca5c4b53, 1 | BRF_GRA }, // 2 Graphics + { "wc2.e2", 0x1000, 0xb7f52a59, 1 | BRF_GRA }, // 3 + { "wc3.e1", 0x1000, 0xf6854b3a, 1 | BRF_GRA }, // 4 + + { "74s288.c2", 0x0020, 0x83e3e293, 2 | BRF_GRA }, // 5 Color Prom +}; + +STD_ROM_PICK(wallc); +STD_ROM_FN(wallc); + +static int wallcInit() +{ + wallca = 0; + + int nRet = DrvInit(); + + if (nRet == 0) { + for (int i = 0; i < 0x4000; i++) { + Rom[i] = BITSWAP08(Rom[i] ^ 0xAA, 4,2,6,0,7,1,3,5); + } + } + + return nRet; +} + +struct BurnDriver BurnDrvwallc = { + "wallc", NULL, NULL, "1984", + "Wall Crash (set 1)\0", NULL, "Midcoin", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 1, HARDWARE_MISC_PRE90S, + NULL, wallcRomInfo, wallcRomName, DrvInputInfo, DrvDIPInfo, + wallcInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + +// Wall Crash (set 2) + +static struct BurnRomInfo wallcaRomDesc[] = { + { "rom4.rom", 0x2000, 0xce43af1b, 0 | BRF_ESS | BRF_PRG }, // 0 Z80 Code + { "rom5.rom", 0x2000, 0xb789a705, 0 | BRF_ESS | BRF_PRG }, // 1 + + { "rom3.rom", 0x0800, 0x6634db73, 1 | BRF_GRA }, // 2 Graphics + { "rom2.rom", 0x0800, 0x79f49c2c, 1 | BRF_GRA }, // 3 + { "rom1.rom", 0x0800, 0x3884fd4f, 1 | BRF_GRA }, // 4 + + { "74s288.c2", 0x0020, 0x83e3e293, 2 | BRF_GRA }, // 5 Color Prom +}; + +STD_ROM_PICK(wallca); +STD_ROM_FN(wallca); + +static int wallcaInit() +{ + wallca = 1; + + int nRet = DrvInit(); + + if (nRet == 0) { + for (int i = 0; i < 0x4000; i++) { + if(i & 0x100) { + Rom[i] = BITSWAP08(Rom[i] ^ 0x4a, 4,7,1,3,2,0,5,6); + } else { + Rom[i] = BITSWAP08(Rom[i] ^ 0xa5, 0,2,3,6,1,5,7,4); + } + } + } + + return nRet; +} + +struct BurnDriver BurnDrvwallca = { + "wallca", "wallc", NULL, "1984", + "Wall Crash (set 2)\0", NULL, "Midcoin", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 1, HARDWARE_MISC_PRE90S, + NULL, wallcaRomInfo, wallcaRomName, DrvInputInfo, DrvDIPInfo, + wallcaInit, DrvExit, DrvFrame, DrvDraw, DrvScan, 0, NULL, NULL, NULL, NULL, + 256, 256, 4, 3 +}; + + diff --git a/src/burn/misc/pre90s/d_wc90.cpp b/src/burn/misc/pre90s/d_wc90.cpp new file mode 100644 index 0000000..d2ae52d --- /dev/null +++ b/src/burn/misc/pre90s/d_wc90.cpp @@ -0,0 +1,1301 @@ +// FB Alpha - World Cup '90 driver + +#include "tiles_generic.h" +#include "burn_ym2608.h" + +static unsigned char Wc90InputPort0[6] = {0, 0, 0, 0, 0, 0}; +static unsigned char Wc90InputPort1[6] = {0, 0, 0, 0, 0, 0}; +static unsigned char Wc90InputPort2[6] = {0, 0, 0, 0, 0, 0}; +static unsigned char Wc90Dip[2] = {0, 0}; +static unsigned char Wc90Input[3] = {0x00, 0x00, 0x00}; +static unsigned char Wc90Reset = 0; + +static unsigned char *Mem = NULL; +static unsigned char *MemEnd = NULL; +static unsigned char *RamStart = NULL; +static unsigned char *RamEnd = NULL; +static unsigned char *Wc90Z80Rom1 = NULL; +static unsigned char *Wc90Z80Rom2 = NULL; +static unsigned char *Wc90Z80Rom3 = NULL; +static unsigned char *Wc90Z80Ram1 = NULL; +static unsigned char *Wc90Z80Ram2 = NULL; +static unsigned char *Wc90Z80Ram3 = NULL; +static unsigned char *Wc90FgVideoRam = NULL; +static unsigned char *Wc90BgVideoRam = NULL; +static unsigned char *Wc90TextVideoRam = NULL; +static unsigned char *Wc90SpriteRam = NULL; +static unsigned char *Wc90PaletteRam = NULL; +static unsigned char *Wc90SharedRam = NULL; +static unsigned int *Wc90Palette = NULL; +static unsigned char *Wc90CharTiles = NULL; +static unsigned char *Wc90BgTiles = NULL; +static unsigned char *Wc90FgTiles = NULL; +static unsigned char *Wc90Sprites = NULL; +static unsigned char *Wc90TempGfx = NULL; +static unsigned char *Wc90YM2608Rom = NULL; + +static int Wc90Scroll0YLo; +static int Wc90Scroll0YHi; +static int Wc90Scroll0XLo; +static int Wc90Scroll0XHi; +static int Wc90Scroll1YLo; +static int Wc90Scroll1YHi; +static int Wc90Scroll1XLo; +static int Wc90Scroll1XHi; +static int Wc90Scroll2YLo; +static int Wc90Scroll2YHi; +static int Wc90Scroll2XLo; +static int Wc90Scroll2XHi; + +static int Wc90SoundLatch = 0; + +static int nCyclesDone[3], nCyclesTotal[3]; +static int nCyclesSegment; + +static int nTileType; + +// Input definitions and functions +static struct BurnInputInfo Wc90InputList[] = +{ + {"Coin 1" , BIT_DIGITAL , Wc90InputPort2 + 0, "p1 coin" }, + {"Start 1" , BIT_DIGITAL , Wc90InputPort2 + 2, "p1 start" }, + {"Coin 2" , BIT_DIGITAL , Wc90InputPort2 + 1, "p2 coin" }, + {"Start 2" , BIT_DIGITAL , Wc90InputPort2 + 3, "p2 start" }, + + {"P1 Up" , BIT_DIGITAL , Wc90InputPort0 + 0, "p1 up" }, + {"P1 Down" , BIT_DIGITAL , Wc90InputPort0 + 1, "p1 down" }, + {"P1 Left" , BIT_DIGITAL , Wc90InputPort0 + 2, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , Wc90InputPort0 + 3, "p1 right" }, + {"P1 Fire 1" , BIT_DIGITAL , Wc90InputPort0 + 4, "p1 fire 1" }, + {"P1 Fire 2" , BIT_DIGITAL , Wc90InputPort0 + 5, "p1 fire 2" }, + + {"P2 Up" , BIT_DIGITAL , Wc90InputPort1 + 0, "p2 up" }, + {"P2 Down" , BIT_DIGITAL , Wc90InputPort1 + 1, "p2 down" }, + {"P2 Left" , BIT_DIGITAL , Wc90InputPort1 + 2, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , Wc90InputPort1 + 3, "p2 right" }, + {"P2 Fire 1" , BIT_DIGITAL , Wc90InputPort1 + 4, "p2 fire 1" }, + {"P2 Fire 2" , BIT_DIGITAL , Wc90InputPort1 + 5, "p2 fire 2" }, + + {"Reset" , BIT_DIGITAL , &Wc90Reset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, Wc90Dip + 0 , "dip" }, + {"Dip 2" , BIT_DIPSWITCH, Wc90Dip + 1 , "dip" }, +}; + +STDINPUTINFO(Wc90); + +inline void Wc90ClearOpposites(unsigned char* nJoystickInputs) +{ + if ((*nJoystickInputs & 0x03) == 0x03) { + *nJoystickInputs &= ~0x03; + } + if ((*nJoystickInputs & 0x0c) == 0x0c) { + *nJoystickInputs &= ~0x0c; + } +} + +inline void Wc90MakeInputs() +{ + // Reset Inputs + Wc90Input[0] = Wc90Input[1] = 0x00; + Wc90Input[2] = 0x03; + + // Compile Digital Inputs + for (int i = 0; i < 6; i++) { + Wc90Input[0] |= (Wc90InputPort0[i] & 1) << i; + Wc90Input[1] |= (Wc90InputPort1[i] & 1) << i; + } + + if (Wc90InputPort2[0]) Wc90Input[2] -= 0x01; + if (Wc90InputPort2[1]) Wc90Input[2] -= 0x02; + if (Wc90InputPort2[2]) Wc90Input[2] |= 0x04; + if (Wc90InputPort2[3]) Wc90Input[2] |= 0x08; + + // Clear Opposites + Wc90ClearOpposites(&Wc90Input[0]); + Wc90ClearOpposites(&Wc90Input[1]); +} + +// Dip Switch definitions +static struct BurnDIPInfo Wc90DIPList[]= +{ + // Default Values + {0x11, 0xff, 0xff, 0xff, NULL }, + {0x12, 0xff, 0xff, 0x7f, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 16 , "Coinage" }, + {0x11, 0x01, 0x0f, 0x00, "10 Coins 1 Credit" }, + {0x11, 0x01, 0x0f, 0x08, " 9 Coins 1 Credit" }, + {0x11, 0x01, 0x0f, 0x04, " 8 Coins 1 Credit" }, + {0x11, 0x01, 0x0f, 0x0c, " 7 Coins 1 Credit" }, + {0x11, 0x01, 0x0f, 0x02, " 6 Coins 1 Credit" }, + {0x11, 0x01, 0x0f, 0x0a, " 5 Coins 1 Credit" }, + {0x11, 0x01, 0x0f, 0x06, " 4 Coins 1 Credit" }, + {0x11, 0x01, 0x0f, 0x0e, " 3 Coins 1 Credit" }, + {0x11, 0x01, 0x0f, 0x01, " 2 Coins 3 Credits" }, + {0x11, 0x01, 0x0f, 0x09, " 2 Coins 1 Credit" }, + {0x11, 0x01, 0x0f, 0x0f, " 1 Coin 1 Credit" }, + {0x11, 0x01, 0x0f, 0x07, " 1 Coin 2 Credits" }, + {0x11, 0x01, 0x0f, 0x0b, " 1 Coin 3 Credits" }, + {0x11, 0x01, 0x0f, 0x03, " 1 Coin 4 Credits" }, + {0x11, 0x01, 0x0f, 0x0d, " 1 Coin 5 Credits" }, + {0x11, 0x01, 0x0f, 0x05, " 1 Coin 6 Credits" }, + + {0 , 0xfe, 0 , 4 , "Difficulty" }, + {0x11, 0x01, 0x30, 0x30, "Easy" }, + {0x11, 0x01, 0x30, 0x10, "Normal" }, + {0x11, 0x01, 0x30, 0x20, "Hard" }, + {0x11, 0x01, 0x30, 0x00, "Hardest" }, + + {0 , 0xfe, 0 , 2 , "Countdown Speed" }, + {0x11, 0x01, 0x40, 0x40, "Normal" }, + {0x11, 0x01, 0x40, 0x00, "Fast" }, + + {0 , 0xfe, 0 , 2 , "Demo Sounds" }, + {0x11, 0x01, 0x80, 0x00, "Off" }, + {0x11, 0x01, 0x80, 0x80, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 4 , "1 Player Game Time" }, + {0x12, 0x01, 0x03, 0x01, "1:00" }, + {0x12, 0x01, 0x03, 0x02, "1:30" }, + {0x12, 0x01, 0x03, 0x03, "2:00" }, + {0x12, 0x01, 0x03, 0x00, "2:30" }, + + {0 , 0xfe, 0 , 8 , "2 Players Game Time" }, + {0x12, 0x01, 0x1c, 0x0c, "1:00" }, + {0x12, 0x01, 0x1c, 0x14, "1:30" }, + {0x12, 0x01, 0x1c, 0x04, "2:00" }, + {0x12, 0x01, 0x1c, 0x18, "2:30" }, + {0x12, 0x01, 0x1c, 0x1c, "3:00" }, + {0x12, 0x01, 0x1c, 0x08, "3:30" }, + {0x12, 0x01, 0x1c, 0x10, "4:00" }, + {0x12, 0x01, 0x1c, 0x00, "5:00" }, + +// {0 , 0xfe, 0 , 2 , "Unknown" }, +// {0x12, 0x01, 0x20, 0x20, "Off" }, +// {0x12, 0x01, 0x20, 0x00, "On" }, + +// {0 , 0xfe, 0 , 2 , "Unknown" }, +// {0x12, 0x01, 0x40, 0x40, "Off" }, +// {0x12, 0x01, 0x40, 0x00, "On" }, + + {0 , 0xfe, 0 , 2 , "Language" }, + {0x12, 0x01, 0x80, 0x00, "English" }, + {0x12, 0x01, 0x80, 0x80, "Japanese" }, +}; + +STDDIPINFO(Wc90); + +// Rom definitions +static struct BurnRomInfo Wc90RomDesc[] = { + { "ic87_01.bin", 0x08000, 0x4a1affbc, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "ic95_02.bin", 0x10000, 0x847d439c, BRF_ESS | BRF_PRG }, // 1 Z80 #1 Program Code + + { "ic67_04.bin", 0x10000, 0xdc6eaf00, BRF_ESS | BRF_PRG }, // 2 Z80 #2 Program Code + { "ic56_03.bin", 0x10000, 0x1ac02b3b, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program Code + + { "ic54_05.bin", 0x10000, 0x27c348b3, BRF_ESS | BRF_PRG }, // 4 Z80 #3 Program Code + + { "ic85_07v.bin", 0x10000, 0xc5219426, BRF_GRA }, // 5 Characters + { "ic86_08v.bin", 0x20000, 0x8fa1a1ff, BRF_GRA }, // 6 Fg Tiles + { "ic90_09v.bin", 0x20000, 0x99f8841c, BRF_GRA }, // 7 Fg Tiles + { "ic87_10v.bin", 0x20000, 0x8232093d, BRF_GRA }, // 8 Bg Tiles + { "ic91_11v.bin", 0x20000, 0x188d3789, BRF_GRA }, // 9 Bg Tiles + { "ic50_12v.bin", 0x20000, 0xda1fe922, BRF_GRA }, // 10 Sprites + { "ic54_13v.bin", 0x20000, 0x9ad03c2c, BRF_GRA }, // 11 Sprites + { "ic60_14v.bin", 0x20000, 0x499dfb1b, BRF_GRA }, // 12 Sprites + { "ic65_15v.bin", 0x20000, 0xd8ea5c81, BRF_GRA }, // 13 Sprites + + { "ic82_06.bin", 0x20000, 0x2fd692ed, BRF_SND }, // 14 ADPCM Samples +}; + + +STD_ROM_PICK(Wc90); +STD_ROM_FN(Wc90); + +static struct BurnRomInfo Wc90aRomDesc[] = { + { "wc90-1.bin", 0x08000, 0xd1804e1a, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "ic95_02.bin", 0x10000, 0x847d439c, BRF_ESS | BRF_PRG }, // 1 Z80 #1 Program Code + + { "ic67_04.bin", 0x10000, 0xdc6eaf00, BRF_ESS | BRF_PRG }, // 2 Z80 #2 Program Code + { "ic56_03.bin", 0x10000, 0x1ac02b3b, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program Code + + { "ic54_05.bin", 0x10000, 0x27c348b3, BRF_ESS | BRF_PRG }, // 4 Z80 #3 Program Code + + { "ic85_07v.bin", 0x10000, 0xc5219426, BRF_GRA }, // 5 Characters + { "ic86_08v.bin", 0x20000, 0x8fa1a1ff, BRF_GRA }, // 6 Fg Tiles + { "ic90_09v.bin", 0x20000, 0x99f8841c, BRF_GRA }, // 7 Fg Tiles + { "ic87_10v.bin", 0x20000, 0x8232093d, BRF_GRA }, // 8 Bg Tiles + { "ic91_11v.bin", 0x20000, 0x188d3789, BRF_GRA }, // 9 Bg Tiles + { "ic50_12v.bin", 0x20000, 0xda1fe922, BRF_GRA }, // 10 Sprites + { "ic54_13v.bin", 0x20000, 0x9ad03c2c, BRF_GRA }, // 11 Sprites + { "ic60_14v.bin", 0x20000, 0x499dfb1b, BRF_GRA }, // 12 Sprites + { "ic65_15v.bin", 0x20000, 0xd8ea5c81, BRF_GRA }, // 13 Sprites + + { "ic82_06.bin", 0x20000, 0x2fd692ed, BRF_SND }, // 14 ADPCM Samples +}; + + +STD_ROM_PICK(Wc90a); +STD_ROM_FN(Wc90a); + +static struct BurnRomInfo Wc90tRomDesc[] = { + { "wc90a-1.bin", 0x08000, 0xb6f51a68, BRF_ESS | BRF_PRG }, // 0 Z80 #1 Program Code + { "wc90a-2.bin", 0x10000, 0xc50f2a98, BRF_ESS | BRF_PRG }, // 1 Z80 #1 Program Code + + { "ic67_04.bin", 0x10000, 0xdc6eaf00, BRF_ESS | BRF_PRG }, // 2 Z80 #2 Program Code + { "wc90a-3.bin", 0x10000, 0x8c7a9542, BRF_ESS | BRF_PRG }, // 3 Z80 #2 Program Code + + { "ic54_05.bin", 0x10000, 0x27c348b3, BRF_ESS | BRF_PRG }, // 4 Z80 #3 Program Code + + { "ic85_07v.bin", 0x10000, 0xc5219426, BRF_GRA }, // 5 Characters + { "ic86_08v.bin", 0x20000, 0x8fa1a1ff, BRF_GRA }, // 6 Fg Tiles + { "ic90_09v.bin", 0x20000, 0x99f8841c, BRF_GRA }, // 7 Fg Tiles + { "ic87_10v.bin", 0x20000, 0x8232093d, BRF_GRA }, // 8 Bg Tiles + { "ic91_11v.bin", 0x20000, 0x188d3789, BRF_GRA }, // 9 Bg Tiles + { "ic50_12v.bin", 0x20000, 0xda1fe922, BRF_GRA }, // 10 Sprites + { "ic54_13v.bin", 0x20000, 0x9ad03c2c, BRF_GRA }, // 11 Sprites + { "ic60_14v.bin", 0x20000, 0x499dfb1b, BRF_GRA }, // 12 Sprites + { "ic65_15v.bin", 0x20000, 0xd8ea5c81, BRF_GRA }, // 13 Sprites + + { "ic82_06.bin", 0x20000, 0x2fd692ed, BRF_SND }, // 14 ADPCM Samples +}; + + +STD_ROM_PICK(Wc90t); +STD_ROM_FN(Wc90t); + +// Driver reset +int Wc90DoReset() +{ + Wc90Scroll0XLo = Wc90Scroll0XHi = Wc90Scroll0YLo = Wc90Scroll0YHi = 0; + Wc90Scroll1XLo = Wc90Scroll1XHi = Wc90Scroll1YLo = Wc90Scroll1YHi = 0; + Wc90Scroll2XLo = Wc90Scroll2XHi = Wc90Scroll2YLo = Wc90Scroll2YHi = 0; + + Wc90SoundLatch = 0; + + for (int i = 0; i < 3; i++) { + ZetOpen(i); + ZetReset(); + ZetClose(); + } + + BurnYM2608Reset(); + + return 0; +} + +// YM2608 IRQ Handler +static void wc90FMIRQHandler(int, int nStatus) +{ +// bprintf(PRINT_NORMAL, _T(" YM2608 IRQ status: 0x%02X (%6i cycles)\n"), nStatus, ZetTotalCycles()); + + if (nStatus & 1) { + ZetSetIRQLine(0xFF, ZET_IRQSTATUS_ACK); + } else { + ZetSetIRQLine(0, ZET_IRQSTATUS_NONE); + } +} + +// CPU synchronisation +static inline void wc90SendSoundCommand(int nCommand) +{ + int nCycles = ZetTotalCycles() * 2 / 3; + +// bprintf(PRINT_NORMAL, _T(" Sync Sound CPU %i -> %i\n"), ZetTotalCycles(), nCycles); + + Wc90SoundLatch = nCommand; + + ZetClose(); + ZetOpen(2); + + if (nCycles > ZetTotalCycles()) { + BurnTimerUpdate(nCycles); + } + + ZetNmi(); + + ZetClose(); + ZetOpen(0); +} + +static int wc90SynchroniseStream(int nSoundRate) +{ + return (long long)ZetTotalCycles() * nSoundRate / 4000000; +} + +static double wc90GetTime() +{ + return (double)ZetTotalCycles() / 4000000; +} + +// Unmapped Memory reads and writes +unsigned char __fastcall Wc90Read1(unsigned short a) +{ + switch (a) { + case 0xfc00: { + return 0xff - Wc90Input[0]; + } + + case 0xfc02: { + return 0xff - Wc90Input[1]; + } + + case 0xfc05: { + return 0xff - Wc90Input[2]; + } + + case 0xfc06: { + return Wc90Dip[0]; + } + + case 0xfc07: { + return Wc90Dip[1]; + } + } + + return 0; +} + +void __fastcall Wc90Write1(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xfc02: { + Wc90Scroll0YLo = d; + return; + } + + case 0xfc03: { + Wc90Scroll0YHi = d; + return; + } + + case 0xfc06: { + Wc90Scroll0XLo = d; + return; + } + + case 0xfc07: { + Wc90Scroll0XHi = d; + return; + } + + case 0xfc22: { + Wc90Scroll1YLo = d; + return; + } + + case 0xfc23: { + Wc90Scroll1YHi = d; + return; + } + + case 0xfc26: { + Wc90Scroll1XLo = d; + return; + } + + case 0xfc27: { + Wc90Scroll1XHi = d; + return; + } + + case 0xfc42: { + Wc90Scroll2YLo = d; + return; + } + + case 0xfc43: { + Wc90Scroll2YHi = d; + return; + } + + case 0xfc46: { + Wc90Scroll2XLo = d; + return; + } + + case 0xfc47: { + Wc90Scroll2XHi = d; + return; + } + + case 0xfcc0: { + wc90SendSoundCommand(d); + return; + } + + case 0xfce0: { + int BankAddress; + + BankAddress = 0x10000 + ((d & 0xf8) << 8); + ZetMapArea(0xf000, 0xf7ff, 0, Wc90Z80Rom1 + BankAddress); + ZetMapArea(0xf000, 0xf7ff, 2, Wc90Z80Rom1 + BankAddress); + return; + } + } +} + +void __fastcall Wc90Write2(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xfc00: { + int BankAddress; + + BankAddress = 0x10000 + ((d & 0xf8) << 8); + ZetMapArea(0xf000, 0xf7ff, 0, Wc90Z80Rom2 + BankAddress); + ZetMapArea(0xf000, 0xf7ff, 2, Wc90Z80Rom2 + BankAddress); + return; + } + } +} + +unsigned char __fastcall Wc90Read3(unsigned short a) +{ + switch (a) { + case 0xf800: { + return BurnYM2608Read(0); + } + + case 0xf802: { + return BurnYM2608Read(2); + } + + case 0xfc10: { + return Wc90SoundLatch; + } + } + + return 0; +} + +void __fastcall Wc90Write3(unsigned short a, unsigned char d) +{ + switch (a) { + case 0xf800: { + BurnYM2608Write(0, d); + return; + } + + case 0xf801: { + BurnYM2608Write(1, d); + return; + } + + case 0xf802: { + BurnYM2608Write(2, d); + return; + } + + case 0xf803: { + BurnYM2608Write(3, d); + return; + } + } +} + +// Function to allocate memory and set up pointers +static int MemIndex() +{ + unsigned char *Next; Next = Mem; + + Wc90Z80Rom1 = Next; Next += 0x20000; + Wc90Z80Rom2 = Next; Next += 0x20000; + Wc90Z80Rom3 = Next; Next += 0x10000; + Wc90YM2608Rom = Next; Next += 0x20000; + + RamStart = Next; + + Wc90Z80Ram1 = Next; Next += 0x04000; + Wc90Z80Ram2 = Next; Next += 0x01800; + Wc90Z80Ram3 = Next; Next += 0x00800; + Wc90FgVideoRam = Next; Next += 0x01000; + Wc90BgVideoRam = Next; Next += 0x01000; + Wc90TextVideoRam = Next; Next += 0x01000; + Wc90SpriteRam = Next; Next += 0x00800; + Wc90PaletteRam = Next; Next += 0x00800; + Wc90SharedRam = Next; Next += 0x00400; + + RamEnd = Next; + + Wc90CharTiles = Next; Next += (2048 * 8 * 8); + Wc90BgTiles = Next; Next += (2048 * 16 * 16); + Wc90FgTiles = Next; Next += (2048 * 16 * 16); + Wc90Sprites = Next; Next += (4096 * 16 * 16); + Wc90Palette = (unsigned int*)Next; Next += 0x00800 * sizeof(unsigned int); + + MemEnd = Next; + + return 0; +} + +// Background Layer emulation +void Wc90RenderBgLayer() +{ + int mx, my, Attr, Code, Colour, x, y, TileIndex = 0; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 64; mx++) { + Attr = Wc90BgVideoRam[TileIndex]; + Code = Wc90BgVideoRam[TileIndex + 0x800] + 256 * ((Attr & 3) + ((Attr >> 1) & 4)); + Colour = Attr >> 4; + + x = 16 * mx; + y = 16 * my; + + x -= Wc90Scroll2XLo + 256 * Wc90Scroll2XHi; + y -= Wc90Scroll2YLo + 256 * Wc90Scroll2YHi; + + x &= 0x3ff; + y &= 0x1ff; + + y -= 16; + if (x > 968) x -= 1024; + + if (x > 15 && x < 240 && y > 15 && y < 208) { + Render16x16Tile(pTransDraw, Code, x, y, Colour, 4, 768, Wc90BgTiles); + } else { + Render16x16Tile_Clip(pTransDraw, Code, x, y, Colour, 4, 768, Wc90BgTiles); + } + + TileIndex++; + } + } +} + +void Wc90tRenderBgLayer() +{ + int mx, my, Attr, Code, Colour, x, y, TileIndex = 0; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 64; mx++) { + Attr = Wc90BgVideoRam[TileIndex]; + Code = Wc90BgVideoRam[TileIndex + 0x800] + 256 * (Attr & 7); + Colour = Attr >> 4; + + x = 16 * mx; + y = 16 * my; + + x -= Wc90Scroll2XLo + 256 * Wc90Scroll2XHi; + y -= Wc90Scroll2YLo + 256 * Wc90Scroll2YHi; + + x &= 0x3ff; + y &= 0x1ff; + + y -= 16; + if (x > 968) x -= 1024; + + if (x > 15 && x < 240 && y > 15 && y < 208) { + Render16x16Tile(pTransDraw, Code, x, y, Colour, 4, 768, Wc90BgTiles); + } else { + Render16x16Tile_Clip(pTransDraw, Code, x, y, Colour, 4, 768, Wc90BgTiles); + } + + TileIndex++; + } + } +} + +// Foreground Layer emulation +void Wc90RenderFgLayer() +{ + int mx, my, Attr, Code, Colour, x, y, TileIndex = 0; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 64; mx++) { + Attr = Wc90FgVideoRam[TileIndex]; + Code = Wc90FgVideoRam[TileIndex + 0x800] + 256 * ((Attr & 3) + ((Attr >> 1) & 4)); + Colour = Attr >> 4; + + x = 16 * mx; + y = 16 * my; + + x -= Wc90Scroll1XLo + 256 * Wc90Scroll1XHi; + y -= Wc90Scroll1YLo + 256 * Wc90Scroll1YHi; + + x &= 0x3ff; + y &= 0x1ff; + + y -= 16; + if (x > 968) x -= 1024; + + if (x > 15 && x < 240 && y > 15 && y < 208) { + Render16x16Tile_Mask(pTransDraw, Code, x, y, Colour, 4, 0, 512, Wc90FgTiles); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 512, Wc90FgTiles); + } + + TileIndex++; + } + } +} + +void Wc90tRenderFgLayer() +{ + int mx, my, Attr, Code, Colour, x, y, TileIndex = 0; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 64; mx++) { + Attr = Wc90FgVideoRam[TileIndex]; + Code = Wc90FgVideoRam[TileIndex + 0x800] + 256 * (Attr & 7); + Colour = Attr >> 4; + + x = 16 * mx; + y = 16 * my; + + x -= Wc90Scroll1XLo + 256 * Wc90Scroll1XHi; + y -= Wc90Scroll1YLo + 256 * Wc90Scroll1YHi; + + x &= 0x3ff; + y &= 0x1ff; + + y -= 16; + if (x > 968) x -= 1024; + + if (x > 15 && x < 240 && y > 15 && y < 208) { + Render16x16Tile_Mask(pTransDraw, Code, x, y, Colour, 4, 0, 512, Wc90FgTiles); + } else { + Render16x16Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 512, Wc90FgTiles); + } + + TileIndex++; + } + } +} + +// Character Layer emulation +void Wc90RenderCharLayer() +{ + int mx, my, Code, Colour, x, y, TileIndex = 0; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 64; mx++) { + Code = Wc90TextVideoRam[TileIndex + 0x800] + ((Wc90TextVideoRam[TileIndex] & 0x07) << 8); + Colour = Wc90TextVideoRam[TileIndex] >> 4; + + x = 8 * mx; + y = 8 * my; + + x -= Wc90Scroll0XLo + 256 * Wc90Scroll0XHi; + y -= Wc90Scroll0YLo + 256 * Wc90Scroll0YHi; + + x &= 0x1ff; + y &= 0x0ff; + + y -= 16; + + if (x > 7 && x < 248 && y > 7 && y < 216) { + Render8x8Tile_Mask(pTransDraw, Code, x, y, Colour, 4, 0, 256, Wc90CharTiles); + } else { + Render8x8Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 256, Wc90CharTiles); + } + + TileIndex++; + } + } +} + +// Sprite Layers emulation +void Wc90RenderSprite(int Code, int Colour, int FlipX, int FlipY, int x, int y) +{ + if (x > 15 && x < 240 && y > 15 && y < 208) { + if (!FlipY) { + if (!FlipX) { + Render16x16Tile_Mask(pTransDraw, Code, x, y, Colour, 4, 0, 0, Wc90Sprites); + } else { + Render16x16Tile_Mask_FlipX(pTransDraw, Code, x, y, Colour, 4, 0, 0, Wc90Sprites); + } + } else { + if (!FlipX) { + Render16x16Tile_Mask_FlipY(pTransDraw, Code, x, y, Colour, 4, 0, 0, Wc90Sprites); + } else { + Render16x16Tile_Mask_FlipXY(pTransDraw, Code, x, y, Colour, 4, 0, 0, Wc90Sprites); + } + } + } else { + if (!FlipY) { + if (!FlipX) { + Render16x16Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 0, Wc90Sprites); + } else { + Render16x16Tile_Mask_FlipX_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 0, Wc90Sprites); + } + } else { + if (!FlipX) { + Render16x16Tile_Mask_FlipY_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 0, Wc90Sprites); + } else { + Render16x16Tile_Mask_FlipXY_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 0, Wc90Sprites); + } + } + } +} + +static char pos32x32[] = { 0, 1, 2, 3 }; +static char pos32x32x[] = { 1, 0, 3, 2 }; +static char pos32x32y[] = { 2, 3, 0, 1 }; +static char pos32x32xy[] = { 3, 2, 1, 0 }; + +static char pos32x64[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +static char pos32x64x[] = { 5, 4, 7, 6, 1, 0, 3, 2 }; +static char pos32x64y[] = { 2, 3, 0, 1, 6, 7, 4, 5 }; +static char pos32x64xy[] = { 7, 6, 5, 4, 3, 2, 1, 0 }; + +static char pos64x32[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +static char pos64x32x[] = { 1, 0, 3, 2, 5, 4, 7, 6 }; +static char pos64x32y[] = { 6, 7, 4, 5, 2, 3, 0, 1 }; +static char pos64x32xy[] = { 7, 6, 5, 4, 3, 2, 1, 0 }; + +static char pos64x64[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; +static char pos64x64x[] = { 5, 4, 7, 6, 1, 0, 3, 2, 13, 12, 15, 14, 9, 8, 11, 10 }; +static char pos64x64y[] = { 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5 }; +static char pos64x64xy[] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + +static char* p32x32[4] = { + pos32x32, + pos32x32x, + pos32x32y, + pos32x32xy +}; + +static char* p32x64[4] = { + pos32x64, + pos32x64x, + pos32x64y, + pos32x64xy +}; + +static char* p64x32[4] = { + pos64x32, + pos64x32x, + pos64x32y, + pos64x32xy +}; + +static char* p64x64[4] = { + pos64x64, + pos64x64x, + pos64x64y, + pos64x64xy +}; + +static void drawsprite_16x16(int Code, int x, int y, int Bank, int Attr) { + Wc90RenderSprite(Code, Attr >> 4, Bank & 1, Bank & 2, x, y); +} + +static void drawsprite_16x32(int Code, int x, int y, int Bank, int Attr) { + if (Bank & 2) { + Wc90RenderSprite(Code + 1, Attr >> 4, Bank & 1, Bank & 2, x, y + 16); + Wc90RenderSprite(Code + 0, Attr >> 4, Bank & 1, Bank & 2, x, y + 0); + } else { + Wc90RenderSprite(Code + 0, Attr >> 4, Bank & 1, Bank & 2, x, y + 0); + Wc90RenderSprite(Code + 1, Attr >> 4, Bank & 1, Bank & 2, x, y + 16); + } +} + +static void drawsprite_16x64(int Code, int x, int y, int Bank, int Attr) { + if (Bank & 2) { + Wc90RenderSprite(Code + 3, Attr >> 4, Bank & 1, Bank & 2, x, y + 48); + Wc90RenderSprite(Code + 2, Attr >> 4, Bank & 1, Bank & 2, x, y + 32); + Wc90RenderSprite(Code + 1, Attr >> 4, Bank & 1, Bank & 2, x, y + 16); + Wc90RenderSprite(Code + 0, Attr >> 4, Bank & 1, Bank & 2, x, y + 0); + } else { + Wc90RenderSprite(Code + 0, Attr >> 4, Bank & 1, Bank & 2, x, y + 0); + Wc90RenderSprite(Code + 1, Attr >> 4, Bank & 1, Bank & 2, x, y + 16); + Wc90RenderSprite(Code + 2, Attr >> 4, Bank & 1, Bank & 2, x, y + 32); + Wc90RenderSprite(Code + 3, Attr >> 4, Bank & 1, Bank & 2, x, y + 48); + } +} + +static void drawsprite_32x16(int Code, int x, int y, int Bank, int Attr) { + if (Bank & 1) { + Wc90RenderSprite(Code + 1, Attr >> 4, Bank & 1, Bank & 2, x + 16, y); + Wc90RenderSprite(Code + 0, Attr >> 4, Bank & 1, Bank & 2, x + 0, y); + } else { + Wc90RenderSprite(Code + 0, Attr >> 4, Bank & 1, Bank & 2, x + 0, y); + Wc90RenderSprite(Code + 1, Attr >> 4, Bank & 1, Bank & 2, x + 16, y); + } +} + +static void drawsprite_32x32(int Code, int x, int y, int Bank, int Attr) { + char *p = p32x32[Bank & 3]; + + Wc90RenderSprite(Code + p[0], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 0); + Wc90RenderSprite(Code + p[1], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 0); + Wc90RenderSprite(Code + p[2], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 16); + Wc90RenderSprite(Code + p[3], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 16); +} + +static void drawsprite_32x64(int Code, int x, int y, int Bank, int Attr) { + char *p = p32x64[Bank & 3]; + + Wc90RenderSprite(Code + p[0], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 0); + Wc90RenderSprite(Code + p[1], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 0); + Wc90RenderSprite(Code + p[2], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 16); + Wc90RenderSprite(Code + p[3], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 16); + Wc90RenderSprite(Code + p[4], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 32); + Wc90RenderSprite(Code + p[5], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 32); + Wc90RenderSprite(Code + p[6], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 48); + Wc90RenderSprite(Code + p[7], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 48); +} + +static void drawsprite_64x16(int Code, int x, int y, int Bank, int Attr) { + if (Bank & 1) { + Wc90RenderSprite(Code + 3, Attr >> 4, Bank & 1, Bank & 2, x + 48, y); + Wc90RenderSprite(Code + 2, Attr >> 4, Bank & 1, Bank & 2, x + 32, y); + Wc90RenderSprite(Code + 1, Attr >> 4, Bank & 1, Bank & 2, x + 16, y); + Wc90RenderSprite(Code + 0, Attr >> 4, Bank & 1, Bank & 2, x + 0, y); + } else { + Wc90RenderSprite(Code + 0, Attr >> 4, Bank & 1, Bank & 2, x + 0, y); + Wc90RenderSprite(Code + 1, Attr >> 4, Bank & 1, Bank & 2, x + 16, y); + Wc90RenderSprite(Code + 2, Attr >> 4, Bank & 1, Bank & 2, x + 32, y); + Wc90RenderSprite(Code + 3, Attr >> 4, Bank & 1, Bank & 2, x + 48, y); + } +} + +static void drawsprite_64x32(int Code, int x, int y, int Bank, int Attr) { + char *p = p64x32[Bank & 3]; + + Wc90RenderSprite(Code + p[0], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 0); + Wc90RenderSprite(Code + p[1], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 0); + Wc90RenderSprite(Code + p[2], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 16); + Wc90RenderSprite(Code + p[3], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 16); + Wc90RenderSprite(Code + p[4], Attr >> 4, Bank & 1, Bank & 2, x + 32 ,y + 0); + Wc90RenderSprite(Code + p[5], Attr >> 4, Bank & 1, Bank & 2, x + 48, y + 0); + Wc90RenderSprite(Code + p[6], Attr >> 4, Bank & 1, Bank & 2, x + 32, y + 16); + Wc90RenderSprite(Code + p[7], Attr >> 4, Bank & 1, Bank & 2, x + 48, y + 16); +} + +static void drawsprite_64x64(int Code, int x, int y, int Bank, int Attr) { + char *p = p64x64[Bank & 3]; + + Wc90RenderSprite(Code + p[ 0], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 0); + Wc90RenderSprite(Code + p[ 1], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 0); + Wc90RenderSprite(Code + p[ 2], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 16); + Wc90RenderSprite(Code + p[ 3], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 16); + Wc90RenderSprite(Code + p[ 4], Attr >> 4, Bank & 1, Bank & 2, x + 32 ,y + 0); + Wc90RenderSprite(Code + p[ 5], Attr >> 4, Bank & 1, Bank & 2, x + 48, y + 0); + Wc90RenderSprite(Code + p[ 6], Attr >> 4, Bank & 1, Bank & 2, x + 32, y + 16); + Wc90RenderSprite(Code + p[ 7], Attr >> 4, Bank & 1, Bank & 2, x + 48, y + 16); + Wc90RenderSprite(Code + p[ 8], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 32); + Wc90RenderSprite(Code + p[ 9], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 32); + Wc90RenderSprite(Code + p[10], Attr >> 4, Bank & 1, Bank & 2, x + 0, y + 48); + Wc90RenderSprite(Code + p[11], Attr >> 4, Bank & 1, Bank & 2, x + 16, y + 48); + Wc90RenderSprite(Code + p[12], Attr >> 4, Bank & 1, Bank & 2, x + 32, y + 32); + Wc90RenderSprite(Code + p[13], Attr >> 4, Bank & 1, Bank & 2, x + 48, y + 32); + Wc90RenderSprite(Code + p[14], Attr >> 4, Bank & 1, Bank & 2, x + 32, y + 48); + Wc90RenderSprite(Code + p[15], Attr >> 4, Bank & 1, Bank & 2, x + 48, y + 48); +} + +static void drawsprite_invalid(int Code, int x, int y, int Bank, int Attr) { +#ifdef FBA_DEBUG + bprintf(PRINT_NORMAL, _T("8 Pixel Size not Supported! %X, %d, %d, %X, %X\n"), Code, x, y, Bank, Attr); +#else + (void)Code; (void)x; (void)y; (void)Bank; (void)Attr; +#endif +} + +typedef void (*drawsprites_procdef)(int, int, int, int, int); + +static drawsprites_procdef drawsprites_proc[16] = { + drawsprite_invalid, /* 0000 = 08x08 */ + drawsprite_invalid, /* 0001 = 16x08 */ + drawsprite_invalid, /* 0010 = 32x08 */ + drawsprite_invalid, /* 0011 = 64x08 */ + drawsprite_invalid, /* 0100 = 08x16 */ + drawsprite_16x16, /* 0101 = 16x16 */ + drawsprite_32x16, /* 0110 = 32x16 */ + drawsprite_64x16, /* 0111 = 64x16 */ + drawsprite_invalid, /* 1000 = 08x32 */ + drawsprite_16x32, /* 1001 = 16x32 */ + drawsprite_32x32, /* 1010 = 32x32 */ + drawsprite_64x32, /* 1011 = 64x32 */ + drawsprite_invalid, /* 1100 = 08x64 */ + drawsprite_16x64, /* 1101 = 16x64 */ + drawsprite_32x64, /* 1110 = 32x64 */ + drawsprite_64x64 /* 1111 = 64x64 */ +}; + +void Wc90RenderSprites(int Priority) +{ + int Code, Attr, x, y; + + for (int Offs = 0; Offs < 0x800; Offs += 16) { + int Bank = Wc90SpriteRam[Offs + 0]; + + if ((Bank >> 4) == Priority) { + if (Bank & 4) { + Code = (Wc90SpriteRam[Offs + 2] >> 2) + (Wc90SpriteRam[Offs + 3] << 6); + + x = Wc90SpriteRam[Offs + 8] + ((Wc90SpriteRam[Offs + 9] & 1) << 8); + y = Wc90SpriteRam[Offs + 6] + ((Wc90SpriteRam[Offs + 7] & 1) << 8); + + y -= 16; + + Attr = Wc90SpriteRam[Offs + 4]; + (*(drawsprites_proc[Attr & 0x0f]))(Code, x, y, Bank, Attr); + } + } + } +} + +// Palette handling functions +inline static unsigned int CalcCol(unsigned short nColour) +{ + int r, g, b; + + r = (nColour >> 4) & 0x0f; + g = (nColour >> 0) & 0x0f; + b = (nColour >> 8) & 0x0f; + + r = (r << 4) | r; + g = (g << 4) | g; + b = (b << 4) | b; + + return BurnHighCol(r, g, b, 0); +} + +int Wc90CalcPalette() +{ + int i; + + for (i = 0; i < 0x800; i++) { + Wc90Palette[i / 2] = CalcCol(Wc90PaletteRam[i | 1] | (Wc90PaletteRam[i & ~1] << 8)); + } + + return 0; +} + +// Draw Screen functions +void Wc90Draw() +{ + Wc90CalcPalette(); + Wc90RenderBgLayer(); + Wc90RenderSprites(2); + Wc90RenderFgLayer(); + Wc90RenderSprites(1); + Wc90RenderCharLayer(); + Wc90RenderSprites(0); + BurnTransferCopy(Wc90Palette); +} + +void Wc90tDraw() +{ + Wc90CalcPalette(); + Wc90tRenderBgLayer(); + Wc90RenderSprites(2); + Wc90tRenderFgLayer(); + Wc90RenderSprites(1); + Wc90RenderCharLayer(); + Wc90RenderSprites(0); + BurnTransferCopy(Wc90Palette); +} + +typedef void (*drawscreen_procdef)(void); + +static drawscreen_procdef drawscreen_proc[2] = { + Wc90Draw, + Wc90tDraw, +}; + +// Frame function +int Wc90Frame() +{ + int nInterleave = 16; + int nCurrentCPU; + + if (Wc90Reset) Wc90DoReset(); + + Wc90MakeInputs(); + + ZetNewFrame(); + + // Compensate for extra cycles executed + for (int i = 0; i < 3; i++) { + ZetOpen(i); + ZetIdle(nCyclesDone[i]); + ZetClose(); + } + + nCyclesTotal[0] = 6000000 / 60; + nCyclesTotal[1] = 6000000 / 60; + nCyclesTotal[2] = 4000000 / 60; + + for (int i = 0; i < nInterleave; i++) { + int nNext; + + // Run Z80 #1 + nCurrentCPU = 0; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - ZetTotalCycles(); + ZetRun(nCyclesSegment); + ZetClose(); + + // Run Z80 #2 + nCurrentCPU = 1; + ZetOpen(nCurrentCPU); + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - ZetTotalCycles(); + ZetRun(nCyclesSegment); + ZetClose(); + } + + for (int i = 0; i < 2; i++) { + ZetOpen(i); + ZetRaiseIrq(0); + nCyclesDone[i] = ZetTotalCycles() - nCyclesTotal[i]; + ZetClose(); + } + + ZetOpen(2); + BurnTimerEndFrame(nCyclesTotal[2]); + BurnYM2608Update(pBurnSoundOut, nBurnSoundLen); + nCyclesDone[2] = ZetTotalCycles() - nCyclesTotal[2]; + ZetClose(); + +// bprintf(PRINT_NORMAL, _T(" %i %i %i\n"), nCyclesDone[0], nCyclesDone[1], nCyclesDone[2]); + + if (pBurnDraw) (*(drawscreen_proc[nTileType]))(); + + return 0; +} + +static int CharPlaneOffsets[4] = { 0, 1, 2, 3 }; +static int CharXOffsets[8] = { 0, 4, 8, 12, 16, 20, 24, 28 }; +static int CharYOffsets[8] = { 0, 32, 64, 96, 128, 160, 192, 224 }; +static int TilePlaneOffsets[4] = { 0, 1, 2, 3 }; +static int TileXOffsets[16] = { 0, 4, 8, 12, 16, 20, 24, 28, 256, 260, 264, 268, 272, 276, 280, 284 }; +static int TileYOffsets[16] = { 0, 32, 64, 96, 128, 160, 192, 224, 512, 544, 576, 608, 640, 672, 704, 736 }; +static int SpritePlaneOffsets[4] = { 0, 1, 2, 3 }; +static int SpriteXOffsets[16] = { 0, 4, 0x200000, 0x200004, 8, 12, 0x200008, 0x20000c, 128, 132, 0x200080, 0x200084, 136, 140, 0x200088, 0x20008c }; +static int SpriteYOffsets[16] = { 0, 16, 32, 48, 64, 80, 96, 112, 256, 272, 288, 304, 320, 336, 352, 368 }; + +// Driver Init function +int Wc90Init() +{ + int nRet = 0, nLen; + + // Allocate and Blank all required memory + Mem = NULL; + MemIndex(); + nLen = MemEnd - (unsigned char *)0; + if ((Mem = (unsigned char *)malloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + Wc90TempGfx = (unsigned char*)malloc(0x80000); + if (Wc90TempGfx == NULL) return 1; + + // Load Z80 #1 Program Roms + nRet = BurnLoadRom(Wc90Z80Rom1 + 0x00000, 0, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(Wc90Z80Rom1 + 0x10000, 1, 1); if (nRet != 0) return 1; + + // Load Z80 #2 Program Roms + nRet = BurnLoadRom(Wc90Z80Rom2 + 0x00000, 2, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(Wc90Z80Rom2 + 0x10000, 3, 1); if (nRet != 0) return 1; + + // Load Z80 #3 Program Rom + nRet = BurnLoadRom(Wc90Z80Rom3 + 0x00000, 4, 1); if (nRet != 0) return 1; + + // Load and Decode Char Tile Rom + memset(Wc90TempGfx, 0, 0x80000); + nRet = BurnLoadRom(Wc90TempGfx + 0x00000, 5, 1); if (nRet != 0) return 1; + GfxDecode(2048, 4, 8, 8, CharPlaneOffsets, CharXOffsets, CharYOffsets, 0x100, Wc90TempGfx, Wc90CharTiles); + + // Load and Decode Fg Tile Roms + memset(Wc90TempGfx, 0, 0x80000); + nRet = BurnLoadRom(Wc90TempGfx + 0x00000, 6, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(Wc90TempGfx + 0x20000, 7, 1); if (nRet != 0) return 1; + GfxDecode(2048, 4, 16, 16, TilePlaneOffsets, TileXOffsets, TileYOffsets, 0x400, Wc90TempGfx, Wc90FgTiles); + + // Load and Decode Bg Tile Roms + memset(Wc90TempGfx, 0, 0x80000); + nRet = BurnLoadRom(Wc90TempGfx + 0x00000, 8, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(Wc90TempGfx + 0x20000, 9, 1); if (nRet != 0) return 1; + GfxDecode(2048, 4, 16, 16, TilePlaneOffsets, TileXOffsets, TileYOffsets, 0x400, Wc90TempGfx, Wc90BgTiles); + + // Load and Decode Sprite Roms + memset(Wc90TempGfx, 0, 0x80000); + nRet = BurnLoadRom(Wc90TempGfx + 0x00000, 10, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(Wc90TempGfx + 0x20000, 11, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(Wc90TempGfx + 0x40000, 12, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(Wc90TempGfx + 0x60000, 13, 1); if (nRet != 0) return 1; + GfxDecode(4096, 4, 16, 16, SpritePlaneOffsets, SpriteXOffsets, SpriteYOffsets, 0x200, Wc90TempGfx, Wc90Sprites); + + free(Wc90TempGfx); + + // Load ADPCM Rom + nRet = BurnLoadRom(Wc90YM2608Rom, 14, 1); if (nRet !=0) return 1; + + // Setup the Z80 emulation + ZetInit(3); + ZetOpen(0); + ZetSetReadHandler(Wc90Read1); + ZetSetWriteHandler(Wc90Write1); + ZetMapArea(0x0000, 0x7fff, 0, Wc90Z80Rom1 ); + ZetMapArea(0x0000, 0x7fff, 2, Wc90Z80Rom1 ); + ZetMapArea(0x8000, 0x9fff, 0, Wc90Z80Ram1 + 0x00000); + ZetMapArea(0x8000, 0x9fff, 1, Wc90Z80Ram1 + 0x00000); + ZetMapArea(0x8000, 0x9fff, 2, Wc90Z80Ram1 + 0x00000); + ZetMapArea(0xa000, 0xafff, 0, Wc90FgVideoRam ); + ZetMapArea(0xa000, 0xafff, 1, Wc90FgVideoRam ); + ZetMapArea(0xa000, 0xafff, 2, Wc90FgVideoRam ); + ZetMapArea(0xb000, 0xbfff, 0, Wc90Z80Ram1 + 0x02000); + ZetMapArea(0xb000, 0xbfff, 1, Wc90Z80Ram1 + 0x02000); + ZetMapArea(0xb000, 0xbfff, 2, Wc90Z80Ram1 + 0x02000); + ZetMapArea(0xc000, 0xcfff, 0, Wc90BgVideoRam ); + ZetMapArea(0xc000, 0xcfff, 1, Wc90BgVideoRam ); + ZetMapArea(0xc000, 0xcfff, 2, Wc90BgVideoRam ); + ZetMapArea(0xd000, 0xdfff, 0, Wc90Z80Ram1 + 0x03000); + ZetMapArea(0xd000, 0xdfff, 1, Wc90Z80Ram1 + 0x03000); + ZetMapArea(0xd000, 0xdfff, 2, Wc90Z80Ram1 + 0x03000); + ZetMapArea(0xe000, 0xefff, 0, Wc90TextVideoRam ); + ZetMapArea(0xe000, 0xefff, 1, Wc90TextVideoRam ); + ZetMapArea(0xe000, 0xefff, 2, Wc90TextVideoRam ); + ZetMapArea(0xf000, 0xf7ff, 0, Wc90Z80Rom1 + 0x10000); + ZetMapArea(0xf000, 0xf7ff, 2, Wc90Z80Rom1 + 0x10000); + ZetMapArea(0xf800, 0xfbff, 0, Wc90SharedRam ); + ZetMapArea(0xf800, 0xfbff, 1, Wc90SharedRam ); + ZetMapArea(0xf800, 0xfbff, 2, Wc90SharedRam ); + ZetMemEnd(); + ZetClose(); + + ZetOpen(1); + ZetSetWriteHandler(Wc90Write2); + ZetMapArea(0x0000, 0xbfff, 0, Wc90Z80Rom2 ); + ZetMapArea(0x0000, 0xbfff, 2, Wc90Z80Rom2 ); + ZetMapArea(0xc000, 0xcfff, 0, Wc90Z80Ram2 + 0x00000); + ZetMapArea(0xc000, 0xcfff, 1, Wc90Z80Ram2 + 0x00000); + ZetMapArea(0xc000, 0xcfff, 2, Wc90Z80Ram2 + 0x00000); + ZetMapArea(0xd000, 0xd7ff, 0, Wc90SpriteRam ); + ZetMapArea(0xd000, 0xd7ff, 1, Wc90SpriteRam ); + ZetMapArea(0xd000, 0xd7ff, 2, Wc90SpriteRam ); + ZetMapArea(0xd800, 0xdfff, 0, Wc90Z80Ram2 + 0x01000); + ZetMapArea(0xd800, 0xdfff, 1, Wc90Z80Ram2 + 0x01000); + ZetMapArea(0xd800, 0xdfff, 2, Wc90Z80Ram2 + 0x01000); + ZetMapArea(0xe000, 0xe7ff, 0, Wc90PaletteRam ); + ZetMapArea(0xe000, 0xe7ff, 1, Wc90PaletteRam ); + ZetMapArea(0xe000, 0xe7ff, 2, Wc90PaletteRam ); + ZetMapArea(0xf000, 0xf7ff, 0, Wc90Z80Rom2 + 0x10000); + ZetMapArea(0xf000, 0xf7ff, 2, Wc90Z80Rom2 + 0x10000); + ZetMapArea(0xf800, 0xfbff, 0, Wc90SharedRam ); + ZetMapArea(0xf800, 0xfbff, 1, Wc90SharedRam ); + ZetMapArea(0xf800, 0xfbff, 2, Wc90SharedRam ); + ZetMemEnd(); + ZetClose(); + + ZetOpen(2); + ZetSetReadHandler(Wc90Read3); + ZetSetWriteHandler(Wc90Write3); + ZetMapArea(0x0000, 0xbfff, 0, Wc90Z80Rom3 ); + ZetMapArea(0x0000, 0xbfff, 2, Wc90Z80Rom3 ); + ZetMapArea(0xf000, 0xf7ff, 0, Wc90Z80Ram3 ); + ZetMapArea(0xf000, 0xf7ff, 1, Wc90Z80Ram3 ); + ZetMapArea(0xf000, 0xf7ff, 2, Wc90Z80Ram3 ); + ZetMemEnd(); + ZetClose(); + + GenericTilesInit(); + + if (!strcmp(BurnDrvGetTextA(DRV_NAME), "wc90t")) { + nTileType = 1; + } else { + nTileType = 0; + } + + int Wc90YM2608RomSize = 0x20000; + BurnYM2608Init(8000000, Wc90YM2608Rom, &Wc90YM2608RomSize, &wc90FMIRQHandler, wc90SynchroniseStream, wc90GetTime, 0); + BurnTimerAttachZet(4000000); + + // Reset the driver + Wc90DoReset(); + + return 0; +} + +// Driver Exit function +int Wc90Exit() +{ + ZetExit(); + GenericTilesExit(); + BurnYM2608Exit(); + + free(Mem); + Mem = NULL; + + return 0; +} + +// Scan Ram function +static int Wc90Scan(int nAction,int *pnMin) +{ + struct BurnArea ba; + + if (pnMin != NULL) { // Return minimum compatible version + *pnMin = 0x029521; + } + + if (nAction & ACB_MEMORY_RAM) { + memset(&ba, 0, sizeof(ba)); + ba.Data = RamStart; + ba.nLen = RamEnd-RamStart; + ba.szName = "All Ram"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + ZetScan(nAction); // Scan Z80 + + BurnYM2608Scan(nAction, pnMin); // Scan YM2608 + + // Scan critical driver variables + SCAN_VAR(Wc90SoundLatch); + SCAN_VAR(Wc90Input); + SCAN_VAR(Wc90Dip); + SCAN_VAR(Wc90Scroll0YLo); + SCAN_VAR(Wc90Scroll0YHi); + SCAN_VAR(Wc90Scroll0XLo); + SCAN_VAR(Wc90Scroll0XHi); + SCAN_VAR(Wc90Scroll1YLo); + SCAN_VAR(Wc90Scroll1YHi); + SCAN_VAR(Wc90Scroll1XLo); + SCAN_VAR(Wc90Scroll1XHi); + SCAN_VAR(Wc90Scroll2YLo); + SCAN_VAR(Wc90Scroll2YHi); + SCAN_VAR(Wc90Scroll2XLo); + SCAN_VAR(Wc90Scroll2XHi); + } + + return 0; +} + +// Driver definitions +struct BurnDriver BurnDrvWc90 = { + "wc90", NULL, NULL, "1989", + "World Cup '90 (set 1)\0", NULL, "Tecmo", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, + NULL, Wc90RomInfo, Wc90RomName, Wc90InputInfo, Wc90DIPInfo, + Wc90Init, Wc90Exit, Wc90Frame, NULL, Wc90Scan, + 0, NULL, NULL, NULL, NULL, 256, 224, 4, 3 +}; + +struct BurnDriver BurnDrvWc90a = { + "wc90a", "wc90", NULL, "1989", + "World Cup '90 (set 2)\0", NULL, "Tecmo", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, Wc90aRomInfo, Wc90aRomName, Wc90InputInfo, Wc90DIPInfo, + Wc90Init, Wc90Exit, Wc90Frame, NULL, Wc90Scan, + 0, NULL, NULL, NULL, NULL, 256, 224, 4, 3 +}; + +struct BurnDriver BurnDrvWc90t = { + "wc90t", "wc90", NULL, "1989", + "World Cup '90 (trackball)\0", NULL, "Tecmo", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_MISC_PRE90S, + NULL, Wc90tRomInfo, Wc90tRomName, Wc90InputInfo, Wc90DIPInfo, + Wc90Init, Wc90Exit, Wc90Frame, NULL, Wc90Scan, + 0, NULL, NULL, NULL, NULL, 256, 224, 4, 3 +};