diff --git a/makefile.burn_rules b/makefile.burn_rules index fcdeee554..3328cec7a 100644 --- a/makefile.burn_rules +++ b/makefile.burn_rules @@ -54,9 +54,10 @@ drvobj = d_dodonpachi.o d_donpachi.o d_esprade.o d_feversos.o d_gaia.o d_guwang d_1945kiii.o d_aerofgt.o d_airbustr.o d_aquarium.o d_blmbycar.o d_bloodbro.o d_crospang.o d_crshrace.o d_dcon.o \ d_deniam.o d_ddragon3.o d_diverboy.o d_drtomy.o d_egghunt.o d_esd16.o d_f1gp.o d_fstarfrc.o d_funybubl.o d_fuukifg3.o \ d_gaelco.o d_gaiden.o d_galpanic.o d_galspnbl.o d_gotcha.o d_gumbo.o d_hyperpac.o d_jchan.o d_kaneko16.o d_lordgun.o \ - d_mcatadv.o d_midas.o d_mugsmash.o d_news.o d_nmg5.o d_nmk16.o d_ohmygod.o d_pass.o d_pirates.o d_powerins.o \ - d_pushman.o d_raiden.o d_seta.o d_seta2.o d_shadfrce.o d_silkroad.o d_silvmil.o d_speedspn.o d_suna16.o d_taotaido.o \ - d_tecmosys.o d_tumbleb.o d_unico.o d_vmetal.o d_welltris.o d_wwfwfest.o d_xorworld.o d_yunsun16.o d_zerozone.o \ + d_mcatadv.o d_midas.o d_mugsmash.o d_news.o d_nmg5.o d_nmk16.o d_ohmygod.o d_pass.o d_pirates.o d_playmark.o \ + d_powerins.o d_pushman.o d_raiden.o d_seta.o d_seta2.o d_shadfrce.o d_silkroad.o d_silvmil.o d_speedspn.o d_suna16.o \ + d_taotaido.o d_tecmosys.o d_tumbleb.o d_unico.o d_vmetal.o d_welltris.o d_wwfwfest.o d_xorworld.o d_yunsun16.o \ + d_zerozone.o \ \ d_parent.o \ \ diff --git a/src/burn/drv/pst90s/d_playmark.cpp b/src/burn/drv/pst90s/d_playmark.cpp new file mode 100644 index 000000000..807dc0137 --- /dev/null +++ b/src/burn/drv/pst90s/d_playmark.cpp @@ -0,0 +1,784 @@ +#include "tiles_generic.h" +#include "m68000_intf.h" +#include "msm6295.h" + +static UINT8 DrvInputPort0[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static UINT8 DrvInputPort1[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static UINT8 DrvInputPort2[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static UINT8 DrvDip[2] = {0, 0}; +static UINT8 DrvInput[3] = {0x00, 0x00, 0x00}; +static UINT8 DrvReset = 0; + +static UINT8 *Mem = NULL; +static UINT8 *MemEnd = NULL; +static UINT8 *RamStart = NULL; +static UINT8 *RamEnd = NULL; +static UINT8 *Drv68kRom = NULL; +static UINT8 *Drv68kRam = NULL; +static UINT8 *DrvPicRom = NULL; +static UINT8 *DrvSpriteRam = NULL; +static UINT8 *DrvVideo1Ram = NULL; +static UINT8 *DrvVideo2Ram = NULL; +static UINT8 *DrvBgVideoRam = NULL; +static UINT8 *DrvPaletteRam = NULL; +static UINT32 *DrvPalette = NULL; +static UINT8 *DrvSprites = NULL; +static UINT8 *DrvTiles = NULL; +static UINT8 *DrvChars = NULL; +static UINT8 *DrvTempGfx = NULL; + +static UINT16 DrvFgScrollX = 0; +static UINT16 DrvFgScrollY = 0; +static UINT16 DrvCharScrollX = 0; +static UINT16 DrvCharScrollY = 0; +static UINT16 DrvBgEnable = 0; +static UINT16 DrvBgFullSize = 0; +static UINT16 DrvBgScrollX = 0; +static UINT16 DrvBgScrollY = 0; + +static UINT8 DrvSoundCommand = 0; +static UINT8 DrvSoundFlag = 0; +static UINT8 DrvOkiControl = 0; +static UINT8 DrvOldOkiBank = 0; +static UINT8 DrvOkiBank = 0; + +static INT32 nCyclesDone[2], nCyclesTotal[2]; +static INT32 nCyclesSegment; + +static struct BurnInputInfo BigtwinInputList[] = { + {"Coin 1" , BIT_DIGITAL , DrvInputPort0 + 4, "p1 coin" }, + {"Start 1" , BIT_DIGITAL , DrvInputPort1 + 7, "p1 start" }, + {"Coin 2" , BIT_DIGITAL , DrvInputPort0 + 5, "p2 coin" }, + {"Start 2" , BIT_DIGITAL , DrvInputPort2 + 7, "p2 start" }, + + {"P1 Up" , BIT_DIGITAL , DrvInputPort1 + 0, "p1 up" }, + {"P1 Down" , BIT_DIGITAL , DrvInputPort1 + 1, "p1 down" }, + {"P1 Left" , BIT_DIGITAL , DrvInputPort1 + 2, "p1 left" }, + {"P1 Right" , BIT_DIGITAL , DrvInputPort1 + 3, "p1 right" }, + {"P1 Fire 1" , BIT_DIGITAL , DrvInputPort1 + 4, "p1 fire 1" }, + + {"P2 Up" , BIT_DIGITAL , DrvInputPort2 + 0, "p2 up" }, + {"P2 Down" , BIT_DIGITAL , DrvInputPort2 + 1, "p2 down" }, + {"P2 Left" , BIT_DIGITAL , DrvInputPort2 + 2, "p2 left" }, + {"P2 Right" , BIT_DIGITAL , DrvInputPort2 + 3, "p2 right" }, + {"P2 Fire 1" , BIT_DIGITAL , DrvInputPort2 + 4, "p2 fire 1" }, + + {"Reset" , BIT_DIGITAL , &DrvReset , "reset" }, + {"Dip 1" , BIT_DIPSWITCH, DrvDip + 0 , "dip" }, + {"Dip 2" , BIT_DIPSWITCH, DrvDip + 1 , "dip" }, +}; + +STDINPUTINFO(Bigtwin) + +static inline void DrvClearOpposites(UINT8* nJoystickInputs) +{ + if ((*nJoystickInputs & 0x03) == 0x03) { + *nJoystickInputs &= ~0x03; + } + if ((*nJoystickInputs & 0x0c) == 0x0c) { + *nJoystickInputs &= ~0x0c; + } +} + +static inline void DrvMakeInputs() +{ + DrvInput[0] = DrvInput[1] = DrvInput[2] = 0x00; + + for (INT32 i = 0; i < 8; i++) { + DrvInput[0] |= (DrvInputPort0[i] & 1) << i; + DrvInput[1] |= (DrvInputPort1[i] & 1) << i; + DrvInput[2] |= (DrvInputPort2[i] & 1) << i; + } + + DrvClearOpposites(&DrvInput[1]); + DrvClearOpposites(&DrvInput[2]); +} + +static struct BurnDIPInfo BigtwinDIPList[]= +{ + // Default Values + {0x0f, 0xff, 0xff, 0x4a, NULL }, + {0x10, 0xff, 0xff, 0xff, NULL }, + + // Dip 1 + {0 , 0xfe, 0 , 2 , "Language" }, + {0x0f, 0x01, 0x01, 0x01, "English" }, + {0x0f, 0x01, 0x01, 0x00, "Italian" }, + + {0 , 0xfe, 0 , 2 , "Censor Pictures" }, + {0x0f, 0x01, 0x04, 0x00, "No" }, + {0x0f, 0x01, 0x04, 0x04, "Yes" }, + + {0 , 0xfe, 0 , 3 , "Difficulty" }, + {0x0f, 0x01, 0x30, 0x30, "Normal" }, + {0x0f, 0x01, 0x30, 0x10, "Hard" }, + {0x0f, 0x01, 0x30, 0x00, "Very Hard" }, + + {0 , 0xfe, 0 , 2 , "Allow Continue" }, + {0x0f, 0x01, 0x40, 0x00, "No" }, + {0x0f, 0x01, 0x40, 0x40, "Yes" }, + + {0 , 0xfe, 0 , 2 , "Demo Sound" }, + {0x0f, 0x01, 0x80, 0x80, "Off" }, + {0x0f, 0x01, 0x80, 0x00, "On" }, + + // Dip 2 + {0 , 0xfe, 0 , 2 , "Coin Mode" }, + {0x10, 0x01, 0x01, 0x01, "Mode 1" }, + {0x10, 0x01, 0x01, 0x00, "Mode 2" }, + + {0 , 0xfe, 0 , 16 , "Coinage Mode 1" }, + {0x10, 0x01, 0x1e, 0x14, "6 Coins 1 Credit" }, + {0x10, 0x01, 0x1e, 0x16, "5 Coins 1 Credit" }, + {0x10, 0x01, 0x1e, 0x14, "4 Coins 1 Credit" }, + {0x10, 0x01, 0x1e, 0x18, "3 Coins 1 Credit" }, + {0x10, 0x01, 0x1e, 0x1a, "8 Coins 3 Credits" }, + {0x10, 0x01, 0x1e, 0x02, "2 Coins 1 Credit" }, + {0x10, 0x01, 0x1e, 0x04, "5 Coins 1 Credits" }, + {0x10, 0x01, 0x1e, 0x06, "3 Coins 2 Credits" }, + {0x10, 0x01, 0x1e, 0x1e, "1 Coin 1 Credit" }, + {0x10, 0x01, 0x1e, 0x08, "2 Coins 3 Credits" }, + {0x10, 0x01, 0x1e, 0x12, "1 Coin 2 Credits" }, + {0x10, 0x01, 0x1e, 0x10, "1 Coin 3 Credits" }, + {0x10, 0x01, 0x1e, 0x0e, "1 Coin 4 Credits" }, + {0x10, 0x01, 0x1e, 0x0c, "1 Coin 5 Credits" }, + {0x10, 0x01, 0x1e, 0x0a, "1 Coin 6 Credits" }, + {0x10, 0x01, 0x1e, 0x00, "Free Play" }, + + {0 , 0xfe, 0 , 2 , "Minimum Credits to Start" }, + {0x10, 0x01, 0x20, 0x20, "1" }, + {0x10, 0x01, 0x20, 0x00, "2" }, +}; + +STDDIPINFO(Bigtwin) + +static struct BurnRomInfo BigtwinRomDesc[] = { + { "2.302", 0x80000, 0xe6767f60, BRF_ESS | BRF_PRG }, // 0 68000 Program Code + { "3.301", 0x80000, 0x5aba6990, BRF_ESS | BRF_PRG }, // 1 68000 Program Code + + { "16c57hs.015", 0x02d4c, 0xc07e9375, BRF_ESS | BRF_PRG }, // 2 PIC16C57 HEX + + { "4.311", 0x40000, 0x6f628fbc, BRF_GRA }, // 3 Tiles + { "5.312", 0x40000, 0x6a9b1752, BRF_GRA }, // 4 Tiles + { "6.313", 0x40000, 0x411cf852, BRF_GRA }, // 5 Tiles + { "7.314", 0x40000, 0x635c81fd, BRF_GRA }, // 6 Tiles + + { "8.321", 0x20000, 0x2749644d, BRF_GRA }, // 7 Sprites + { "9.322", 0x20000, 0x1d1897af, BRF_GRA }, // 8 Sprites + { "10.323", 0x20000, 0x2a03432e, BRF_GRA }, // 9 Sprites + { "11.324", 0x20000, 0x2c980c4c, BRF_GRA }, // 10 Sprites + + { "1.013", 0x40000, 0xff6671dc, BRF_SND }, // 11 Samples +}; + +STD_ROM_PICK(Bigtwin) +STD_ROM_FN(Bigtwin) + +static INT32 DrvDoReset() +{ + SekOpen(0); + SekReset(); + SekClose(); + + DrvFgScrollX = 0; + DrvFgScrollY = 0; + DrvCharScrollX = 0; + DrvCharScrollY = 0; + DrvBgEnable = 0; + DrvBgFullSize = 0; + DrvBgScrollX = 0; + DrvBgScrollY = 0; + + DrvSoundCommand = 0; + DrvSoundFlag = 0; + DrvOkiControl = 0; + DrvOldOkiBank = 0; + DrvOkiBank = 0; + + return 0; +} + +static INT32 MemIndex() +{ + UINT8 *Next; Next = Mem; + + Drv68kRom = Next; Next += 0x100000; + MSM6295ROM = Next; Next += 0x040000; + DrvPicRom = Next; Next += 0x001000; + + RamStart = Next; + + Drv68kRam = Next; Next += 0x010000; + DrvSpriteRam = Next; Next += 0x004000; + DrvVideo1Ram = Next; Next += 0x002000; + DrvVideo2Ram = Next; Next += 0x001000; + DrvBgVideoRam = Next; Next += 0x080000; + DrvPaletteRam = Next; Next += 0x000800; + + RamEnd = Next; + + DrvSprites = Next; Next += (0x0400 * 32 * 32); + DrvTiles = Next; Next += (0x2000 * 16 * 16); + DrvChars = Next; Next += (0x2000 * 8 * 8); + DrvPalette = (UINT32*)Next; Next += 0x00400 * sizeof(UINT32); + + MemEnd = Next; + + return 0; +} + +UINT8 __fastcall DrvReadByte(UINT32 a) +{ + switch (a) { + case 0x700013: { + return 0xff - DrvInput[1]; + } + + case 0x700015: { + return 0xff - DrvInput[2]; + } + + default: { + bprintf(PRINT_NORMAL, _T("Read byte -> %06X\n"), a); + } + } + + return 0; +} + +void __fastcall DrvWriteByte(UINT32 a, UINT8 d) +{ + switch (a) { + case 0x70001f: { + DrvSoundCommand = d; + DrvSoundFlag = 1; + // space.device().execute().yield(); + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Write byte -> %06X, %02X\n"), a, d); + } + } +} + +UINT16 __fastcall DrvReadWord(UINT32 a) +{ + switch (a) { + case 0x700010: { + return 0xffff - DrvInput[0]; + } + + case 0x70001a: { + return 0xff00 | DrvDip[0]; + } + + case 0x70001c: { + return 0xff00 | DrvDip[1]; + } + + default: { + bprintf(PRINT_NORMAL, _T("Read Word -> %06X\n"), a); + } + } + + return 0; +} + +void __fastcall DrvWriteWord(UINT32 a, UINT16 d) +{ + if (a >= 0x501000 && a <= 0x501fff) { + // unused ram??? + return; + } + + if (a >= 0x504000 && a <= 0x50ffff) { + // unused ram??? + return; + } + + switch (a) { + case 0x304000: { + // irq ack??? + return; + } + + case 0x510000: { + DrvCharScrollX = (d + 2) & 0x1ff; + return; + } + + case 0x510002: { + DrvCharScrollY = d & 0xff; + return; + } + + case 0x510004: { + DrvBgScrollX = -(d + 4); + return; + } + + case 0x510006: { + DrvBgScrollY = -d & 0x1ff; + DrvBgEnable = d & 0x200; + DrvBgFullSize = d & 0x400; + return; + } + + case 0x510008: { + DrvFgScrollX = (d + 6) & 0x1ff; + return; + } + + case 0x51000a: { + DrvFgScrollY = d & 0x1ff; + return; + } + + case 0x51000c: { + // nop??? + return; + } + + case 0xe00000: { + // ??? + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Write word -> %06X, %04X\n"), a, d); + } + } +} + +static UINT8 playmark_asciitohex(UINT8 data) +{ + // Convert ASCII data to HEX + + if ((data >= 0x30) && (data < 0x3a)) data -= 0x30; + data &= 0xdf; // remove case sensitivity */ + if ((data >= 0x41) && (data < 0x5b)) data -= 0x37; + + return data; +} + +static void DrvPICHexConvert() +{ + UINT8 *playmark_PICROM_HEX = (UINT8*)BurnMalloc(0x2d4c); + UINT16 *playmark_PICROM = (UINT16*)DrvPicRom; + INT32 Data; + UINT16 SrcPos = 0; + UINT16 DstPos = 0; + UINT8 DataHi, DataLo; + + BurnLoadRom(playmark_PICROM_HEX, 2, 1); + + DrvSoundFlag = 0; + + // Convert the PIC16C57 ASCII HEX dumps to pure HEX + do { + if ((playmark_PICROM_HEX[SrcPos + 0] == ':') && (playmark_PICROM_HEX[SrcPos + 1] == '1') && (playmark_PICROM_HEX[SrcPos + 2] == '0')) { + SrcPos += 9; + + for (INT32 Offs = 0; Offs < 32; Offs += 4) { + DataHi = playmark_asciitohex((playmark_PICROM_HEX[SrcPos + Offs + 0])); + DataLo = playmark_asciitohex((playmark_PICROM_HEX[SrcPos + Offs + 1])); + if ((DataHi <= 0x0f) && (DataLo <= 0x0f)) { + Data = (DataHi << 4) | (DataLo << 0); + DataHi = playmark_asciitohex((playmark_PICROM_HEX[SrcPos + Offs + 2])); + DataLo = playmark_asciitohex((playmark_PICROM_HEX[SrcPos + Offs + 3])); + + if ((DataHi <= 0x0f) && (DataLo <= 0x0f)) { + Data |= (DataHi << 12) | (DataLo << 8); + playmark_PICROM[DstPos] = Data; + DstPos += 1; + } + } + } + SrcPos += 32; + } + + // Get the PIC16C57 Config register data + + if ((playmark_PICROM_HEX[SrcPos + 0] == ':') && (playmark_PICROM_HEX[SrcPos + 1] == '0') && (playmark_PICROM_HEX[SrcPos + 2] == '2') && (playmark_PICROM_HEX[SrcPos + 3] == '1')) { + SrcPos += 9; + + DataHi = playmark_asciitohex((playmark_PICROM_HEX[SrcPos + 0])); + DataLo = playmark_asciitohex((playmark_PICROM_HEX[SrcPos + 1])); + Data = (DataHi << 4) | (DataLo << 0); + DataHi = playmark_asciitohex((playmark_PICROM_HEX[SrcPos + 2])); + DataLo = playmark_asciitohex((playmark_PICROM_HEX[SrcPos + 3])); + Data |= (DataHi << 12) | (DataLo << 8); + +// pic16c5x_set_config(machine().device("audiocpu"), data); + + SrcPos = 0x7fff; // Force Exit + } + SrcPos += 1; + } while (SrcPos < 0x2d4c); +} + +static INT32 DrvCharPlaneOffsets[4] = { 0x600000, 0x400000, 0x200000, 0 }; +static INT32 DrvCharXOffsets[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +static INT32 DrvCharYOffsets[8] = { 0, 8, 16, 24, 32, 40, 48, 56 }; +static INT32 DrvTilePlaneOffsets[4] = { 0x600000, 0x400000, 0x200000, 0 }; +static INT32 DrvTileXOffsets[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 128, 129, 130, 131, 132, 133, 134, 135 }; +static INT32 DrvTileYOffsets[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }; +static INT32 DrvSpritePlaneOffsets[4] = { 0x300000, 0x200000, 0x100000, 0 }; +static INT32 DrvSpriteXOffsets[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 128, 129, 130, 131, 132, 133, 134, 135, 256, 257, 258, 259, 260, 261, 262, 263, 384, 385, 386, 387, 388, 389, 390, 391 }; +static INT32 DrvSpriteYOffsets[32] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 512, 520, 528, 536, 544, 552, 560, 568, 576, 584, 592, 600, 608, 616, 624, 632 }; + +static INT32 DrvInit() +{ + INT32 nRet = 0, nLen; + + Mem = NULL; + MemIndex(); + nLen = MemEnd - (UINT8 *)0; + if ((Mem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1; + memset(Mem, 0, nLen); + MemIndex(); + + DrvTempGfx = (UINT8*)BurnMalloc(0x100000); + + nRet = BurnLoadRom(Drv68kRom + 0x00001, 0, 2); if (nRet != 0) return 1; + nRet = BurnLoadRom(Drv68kRom + 0x00000, 1, 2); if (nRet != 0) return 1; + + nRet = BurnLoadRom(DrvTempGfx + 0x00000, 3, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempGfx + 0x40000, 4, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempGfx + 0x80000, 5, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempGfx + 0xc0000, 6, 1); if (nRet != 0) return 1; + GfxDecode(0x2000, 4, 16, 16, DrvTilePlaneOffsets, DrvTileXOffsets, DrvTileYOffsets, 0x100, DrvTempGfx, DrvTiles); + GfxDecode(0x2000, 4, 8, 8, DrvCharPlaneOffsets, DrvCharXOffsets, DrvCharYOffsets, 0x100, DrvTempGfx, DrvChars); + + memset(DrvTempGfx, 0, 0x100000); + nRet = BurnLoadRom(DrvTempGfx + 0x00000, 7, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempGfx + 0x20000, 8, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempGfx + 0x40000, 9, 1); if (nRet != 0) return 1; + nRet = BurnLoadRom(DrvTempGfx + 0x60000, 10, 1); if (nRet != 0) return 1; + GfxDecode(0x400, 4, 32, 32, DrvSpritePlaneOffsets, DrvSpriteXOffsets, DrvSpriteYOffsets, 0x400, DrvTempGfx, DrvSprites); + BurnFree(DrvTempGfx); + + nRet = BurnLoadRom(MSM6295ROM, 11, 1); if (nRet != 0) return 1; + + BurnSetRefreshRate(58.0); + + SekInit(0, 0x68000); + SekOpen(0); + SekMapMemory(Drv68kRom , 0x000000, 0x0fffff, SM_ROM); + SekMapMemory(DrvSpriteRam , 0x440000, 0x4403ff, SM_RAM); + SekMapMemory(DrvVideo2Ram , 0x500000, 0x500fff, SM_RAM); + SekMapMemory(DrvVideo1Ram , 0x502000, 0x503fff, SM_RAM); + SekMapMemory(DrvBgVideoRam , 0x600000, 0x67ffff, SM_RAM); + SekMapMemory(DrvPaletteRam , 0x780000, 0x7807ff, SM_RAM); + SekMapMemory(Drv68kRam , 0xff0000, 0xffffff, SM_RAM); + SekSetReadByteHandler(0, DrvReadByte); + SekSetReadWordHandler(0, DrvReadWord); + SekSetWriteByteHandler(0, DrvWriteByte); + SekSetWriteWordHandler(0, DrvWriteWord); + SekClose(); + + DrvPICHexConvert(); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static INT32 DrvExit() +{ + SekExit(); + + GenericTilesExit(); + + BurnFree(Mem); + + DrvFgScrollX = 0; + DrvFgScrollY = 0; + DrvCharScrollX = 0; + DrvCharScrollY = 0; + DrvBgEnable = 0; + DrvBgFullSize = 0; + DrvBgScrollX = 0; + DrvBgScrollY = 0; + + DrvSoundCommand = 0; + DrvSoundFlag = 0; + DrvOkiControl = 0; + DrvOldOkiBank = 0; + DrvOkiBank = 0; + + return 0; +} + +static inline UINT8 pal5bit(UINT8 bits) +{ + bits &= 0x1f; + return (bits << 3) | (bits >> 2); +} + +static inline UINT32 CalcCol(UINT16 nColour) +{ + INT32 r, g, b; + + r = (nColour >> 11) & 0x1e; + g = (nColour >> 7) & 0x1e; + b = (nColour >> 3) & 0x1e; + + r |= ((nColour & 0x08) >> 3); + g |= ((nColour & 0x04) >> 2); + b |= ((nColour & 0x02) >> 1); + + return BurnHighCol(pal5bit(r), pal5bit(g), pal5bit(b), 0); +} + +static void DrvCalcPalette() +{ + INT32 i; + UINT16* ps; + UINT32* pd; + + for (i = 0, ps = (UINT16*)DrvPaletteRam, pd = DrvPalette; i < 0x400; i++, ps++, pd++) { + *pd = CalcCol(*ps); + } +} + +static void DrvRenderFgLayer() +{ + INT32 mx, my, Code, Colour, x, y, TileIndex = 0; + + UINT16 *VideoRam = (UINT16*)DrvVideo2Ram; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 32; mx++) { + Code = BURN_ENDIAN_SWAP_INT16(VideoRam[(TileIndex * 2)+ 0]); + Colour = BURN_ENDIAN_SWAP_INT16(VideoRam[(TileIndex * 2)+ 1]); + + x = 16 * mx; + y = 16 * my; + + x -= DrvFgScrollX; + y -= DrvFgScrollY; + if (x < -16) x += 512; + if (y < -16) y += 512; + + y -= 16; + + if (x > 16 && x < 304 && y > 16 && y < 224) { + Render16x16Tile(pTransDraw, Code, x, y, Colour, 4, 0, DrvTiles); + } else { + Render16x16Tile_Clip(pTransDraw, Code, x, y, Colour, 4, 0, DrvTiles); + } + + TileIndex++; + } + } +} + +static void DrvRenderCharLayer() +{ + INT32 mx, my, Code, Colour, x, y, TileIndex = 0; + + UINT16 *VideoRam = (UINT16*)DrvVideo1Ram; + + for (my = 0; my < 32; my++) { + for (mx = 0; mx < 64; mx++) { + Code = BURN_ENDIAN_SWAP_INT16(VideoRam[(TileIndex * 2)+ 0]); + Colour = BURN_ENDIAN_SWAP_INT16(VideoRam[(TileIndex * 2)+ 1]); + + x = 8 * mx; + y = 8 * my; + + x -= DrvCharScrollX; + y -= DrvCharScrollY; + if (x < -8) x += 512; + if (y < -8) y += 256; + + y -= 16; + + if (x > 8 && x < 312 && y > 8 && y < 232) { + Render8x8Tile_Mask(pTransDraw, Code, x, y, Colour, 4, 0, 0x80, DrvChars); + } else { + Render8x8Tile_Mask_Clip(pTransDraw, Code, x, y, Colour, 4, 0, 0x80, DrvChars); + } + + TileIndex++; + } + } +} + +static void DrvRenderSprites(INT32 CodeShift) +{ + INT32 Offs, StartOffset = 0x4000 / 2 - 4; + INT32 Height = 32; + INT32 ColourDiv = 0x10 / 16; + UINT16 *SpriteRam = (UINT16*)DrvSpriteRam; + + for (Offs = 4; Offs < 0x4000 / 2; Offs += 4) { + if (SpriteRam[Offs + 3 - 4] == 0x2000) { + StartOffset = Offs - 4; + break; + } + } + + for (Offs = StartOffset; Offs >= 4; Offs -= 4) { + INT32 sx, sy, Code, Colour, xFlip, Pri; + + sy = SpriteRam[Offs + 3 - 4]; + + xFlip = sy & 0x4000; + sx = (SpriteRam[Offs + 1] & 0x01ff) - 16 - 7; + sy = (256 - 8 - Height - sy) & 0xff; + Code = SpriteRam[Offs + 2] >> CodeShift; + Colour = ((SpriteRam[Offs + 1] & 0x3e00) >> 9) / ColourDiv; + Pri = (SpriteRam[Offs + 1] & 0x8000) >> 15; + + if(!Pri && (Colour & 0x0c) == 0x0c) Pri = 2; + + sy -= 16; + + /*pdrawgfx_transpen(bitmap,cliprect,machine().gfx[0], + code, + color, + flipx,0, + sx + m_xoffset,sy + m_yoffset, + machine().priority_bitmap,m_pri_masks[pri],0);*/ + + // other games need priority support adding + + if (sx > 16 && sx < 304 && sy > 16 && sy < 224) { + if (xFlip) { + Render32x32Tile_Mask_FlipX(pTransDraw, Code, sx, sy, Colour, 4, 0, 0x200, DrvSprites); + } else { + Render32x32Tile_Mask(pTransDraw, Code, sx, sy, Colour, 4, 0, 0x200, DrvSprites); + } + } else { + if (xFlip) { + Render32x32Tile_Mask_FlipX_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 0x200, DrvSprites); + } else { + Render32x32Tile_Mask_Clip(pTransDraw, Code, sx, sy, Colour, 4, 0, 0x200, DrvSprites); + } + } + } +} + +static void DrvRenderBitmap() +{ + INT32 Colour; +// UINT8 *Pri; + UINT16 *VideoRam = (UINT16*)DrvBgVideoRam; + INT32 Count = 0; + + for (INT32 y = 0; y < 512; y++) { + for (INT32 x = 0; x < 512; x++) { + Colour = VideoRam[Count] & 0xff; + + if (Colour) { + if (DrvBgFullSize) { + INT32 yPlot = (y - 16 + DrvBgScrollY) & 0x1ff; + INT32 xPlot = (x + DrvBgScrollX) & 0x1ff; + + if (xPlot >= 0 && xPlot < 320 && yPlot >= 0 && yPlot < 240) { + pTransDraw[(yPlot * nScreenWidth) + xPlot] = 0x100 + Colour; + } + +// pri = &machine().priority_bitmap.pix8((y + m_bgscrolly) & 0x1ff); +// pri[(x + m_bgscrollx) & 0x1ff] |= 2; + } else { + // 50% size + if(!(x % 2) && !(y % 2)) { + // untested for now + INT32 yPlot = ((y / 2) - 16 + DrvBgScrollY) & 0x1ff; + INT32 xPlot = ((x / 2) + DrvBgScrollX) & 0x1ff; + + if (xPlot >= 0 && xPlot < 320 && yPlot >= 0 && yPlot < 240) { + pTransDraw[(yPlot * nScreenWidth) + xPlot] = 0x100 + Colour; + } + +// bitmap.pix16((y / 2 + m_bgscrolly) & 0x1ff, (x / 2 + m_bgscrollx) & 0x1ff) = 0x100 + color; + +// pri = &machine().priority_bitmap.pix8((y / 2 + m_bgscrolly) & 0x1ff); +// pri[(x / 2 + m_bgscrollx) & 0x1ff] |= 2; + } + } + } + + Count++; + } + } +} + +static void DrvRender() +{ + BurnTransferClear(); + DrvCalcPalette(); + DrvRenderFgLayer(); + if (DrvBgEnable) DrvRenderBitmap(); + DrvRenderSprites(4); + DrvRenderCharLayer(); + BurnTransferCopy(DrvPalette); +} + +static INT32 DrvFrame() +{ + INT32 nInterleave = 10; + + if (DrvReset) DrvDoReset(); + + DrvMakeInputs(); + + nCyclesTotal[0] = (INT32)((double)12000000 / 58.0); + nCyclesTotal[1] = (INT32)((double)12000000 / 58.0); + nCyclesDone[0] = nCyclesDone[1] = 0; + + SekNewFrame(); + + SekOpen(0); + for (INT32 i = 0; i < nInterleave; i++) { + INT32 nCurrentCPU, nNext; + + // Run 68000 + nCurrentCPU = 0; + nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave; + nCyclesSegment = nNext - nCyclesDone[nCurrentCPU]; + nCyclesDone[nCurrentCPU] += SekRun(nCyclesSegment); + + if (i == 9) SekSetIRQLine(2, SEK_IRQSTATUS_AUTO); + } + SekClose(); + + if (pBurnDraw) DrvRender(); + + return 0; +} + +static INT32 DrvScan(INT32 nAction, INT32 *pnMin) +{ + struct BurnArea ba; + + if (pnMin != NULL) { + *pnMin = 0x02729; + } + + 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); + } + + return 0; +} + +struct BurnDriver BurnDrvBigtwin = { + "bigtwin", NULL, NULL, NULL, "1995", + "Big Twin\0", "No Sound", "SemiCom", "Misc", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_MISC_POST90S, GBF_PUZZLE, 0, + NULL, BigtwinRomInfo, BigtwinRomName, NULL, NULL, BigtwinInputInfo, BigtwinDIPInfo, + DrvInit, DrvExit, DrvFrame, NULL, DrvScan, + NULL, 0x400, 320, 240, 4, 3 +};