diff --git a/makefile.burn_rules b/makefile.burn_rules index 15c6ac421..806d8f560 100644 --- a/makefile.burn_rules +++ b/makefile.burn_rules @@ -44,7 +44,7 @@ drvsrc = d_arcadecl.cpp d_atarig1.cpp d_badlands.cpp d_batman.cpp d_blstroid.cp d_turbo.o d_xbrd.o d_ybrd.o d_zaxxon.o \ \ d_arkanoid.o d_ashnojoe.o d_asuka.o d_bublbobl.o d_chaknpop.o d_crbaloon.o d_darius2.o d_darkmist.o d_exzisus.o d_flstory.o d_groundfx.o d_gunbuster.o d_jollyjgr.o \ - d_ksayakyu.o d_lkage.o d_minivdr.o d_msisaac.o d_othunder.o d_qix.o d_retofinv.o d_rollrace.o d_slapshot.o d_ssrj.o d_superchs.o d_supridr.o d_taitob.o \ + d_ksayakyu.o d_lkage.o d_mexico86.o d_minivdr.o d_msisaac.o d_othunder.o d_qix.o d_retofinv.o d_rollrace.o d_slapshot.o d_ssrj.o d_superchs.o d_supridr.o d_taitob.o \ d_taitoh.o d_taitof2.o d_taitof3.o d_taitol.o d_taitomisc.o d_taitosj.o d_taitox.o d_taitoz.o d_tnzs.o d_undrfire.o d_wyvernf0.o \ \ d_batrider.o d_batsugun.o d_battleg.o d_bbakraid.o d_dogyuun.o d_enmadaio.o d_fixeight.o d_ghox.o d_kbash.o d_kbash2.o d_mahoudai.o d_pipibibs.o \ diff --git a/src/burn/drv/taito/d_mexico86.cpp b/src/burn/drv/taito/d_mexico86.cpp new file mode 100644 index 000000000..8c40e729c --- /dev/null +++ b/src/burn/drv/taito/d_mexico86.cpp @@ -0,0 +1,1357 @@ +// FB Alpha Kick & Run driver module +// Based on MAME driver by Ernesto Corvi + +#include "tiles_generic.h" +#include "z80_intf.h" +#include "burn_ym2203.h" +#include "bitswap.h" +#include "taito_m68705.h" + +static UINT8 *AllMem; +static UINT8 *AllRam; +static UINT8 *RamEnd; +static UINT8 *MemEnd; +static UINT8 *DrvZ80ROM0; +static UINT8 *DrvZ80ROM1; +static UINT8 *DrvZ80ROM2; +static UINT8 *DrvMCUROM; +static UINT8 *DrvGfxROM; +static UINT8 *DrvColPROM; +static UINT8 *DrvShareRAM0; +static UINT8 *DrvShareRAM1; +static UINT8 *DrvZ80RAM1; +static UINT8 *DrvZ80RAM2; +static UINT8 *DrvMCURAM; +static UINT8 *DrvPrtRAM; + +static UINT32 *DrvPalette; +static UINT8 DrvRecalc; + +static INT32 nExtraCycles; +static INT32 nBankData; +static INT32 nCharBank; +static INT32 nSoundCPUHalted; +static INT32 nMCUHalted; +static INT32 nSubCPUHalted; +static INT32 mcu_running; +static INT32 mcu_initialised; +static bool coin_last[2]; +static INT32 coin_fract; +static INT32 mcu_address; +static INT32 mcu_latch; + +static INT32 has_mcu = 0; +static INT32 has_sub = 0; + +static INT32 is_mexico86 = 0; + +static UINT8 DrvJoy1[8]; +static UINT8 DrvJoy2[8]; +static UINT8 DrvJoy3[8]; +static UINT8 DrvJoy4[8]; +static UINT8 DrvJoy5[8]; +static UINT8 DrvJoy6[8]; +static UINT8 DrvJoy7[8]; +static UINT8 DrvJoy8[8]; +static UINT8 DrvDips[2]; +static UINT8 DrvInputs[8]; +static UINT8 DrvReset; + +static struct BurnInputInfo KikikaiInputList[] = { + {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" }, + {"P1 Start", BIT_DIGITAL, DrvJoy4 + 3, "p1 start" }, + {"P1 Up", BIT_DIGITAL, DrvJoy2 + 0, "p1 up" }, + {"P1 Down", BIT_DIGITAL, DrvJoy2 + 1, "p1 down" }, + {"P1 Left", BIT_DIGITAL, DrvJoy2 + 2, "p1 left" }, + {"P1 Right", BIT_DIGITAL, DrvJoy2 + 3, "p1 right" }, + {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire 1" }, + {"P1 Button 2", BIT_DIGITAL, DrvJoy2 + 5, "p1 fire 2" }, + + {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 1, "p2 coin" }, + {"P2 Start", BIT_DIGITAL, DrvJoy4 + 4, "p2 start" }, + {"P2 Up", BIT_DIGITAL, DrvJoy3 + 0, "p2 up" }, + {"P2 Down", BIT_DIGITAL, DrvJoy3 + 1, "p2 down" }, + {"P2 Left", BIT_DIGITAL, DrvJoy3 + 2, "p2 left" }, + {"P2 Right", BIT_DIGITAL, DrvJoy3 + 3, "p2 right" }, + {"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" }, + {"Service", BIT_DIGITAL, DrvJoy4 + 0, "service" }, + {"Tilt", BIT_DIGITAL, DrvJoy4 + 2, "tilt" }, + {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" }, +}; + +STDINPUTINFO(Kikikai) + +static struct BurnInputInfo Mexico86InputList[] = { + {"P1 Coin", BIT_DIGITAL, DrvJoy1 + 0, "p1 coin" }, + {"P1 Start", BIT_DIGITAL, DrvJoy4 + 3, "p1 start" }, + {"P1 Up", BIT_DIGITAL, DrvJoy2 + 0, "p1 up" }, + {"P1 Down", BIT_DIGITAL, DrvJoy2 + 1, "p1 down" }, + {"P1 Left", BIT_DIGITAL, DrvJoy2 + 2, "p1 left" }, + {"P1 Right", BIT_DIGITAL, DrvJoy2 + 3, "p1 right" }, + {"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 5, "p1 fire 1" }, + {"P1 Button 2", BIT_DIGITAL, DrvJoy2 + 4, "p1 fire 2" }, + + {"P2 Coin", BIT_DIGITAL, DrvJoy1 + 1, "p2 coin" }, + {"P2 Start", BIT_DIGITAL, DrvJoy4 + 4, "p2 start" }, + {"P2 Up", BIT_DIGITAL, DrvJoy3 + 0, "p2 up" }, + {"P2 Down", BIT_DIGITAL, DrvJoy3 + 1, "p2 down" }, + {"P2 Left", BIT_DIGITAL, DrvJoy3 + 2, "p2 left" }, + {"P2 Right", BIT_DIGITAL, DrvJoy3 + 3, "p2 right" }, + {"P2 Button 1", BIT_DIGITAL, DrvJoy3 + 5, "p2 fire 1" }, + {"P2 Button 2", BIT_DIGITAL, DrvJoy3 + 4, "p2 fire 2" }, + + {"P3 Coin", BIT_DIGITAL, DrvJoy7 + 0, "p3 coin" }, + {"P3 Start", BIT_DIGITAL, DrvJoy7 + 2, "p3 start" }, + {"P3 Up", BIT_DIGITAL, DrvJoy5 + 0, "p3 up" }, + {"P3 Down", BIT_DIGITAL, DrvJoy5 + 1, "p3 down" }, + {"P3 Left", BIT_DIGITAL, DrvJoy5 + 2, "p3 left" }, + {"P3 Right", BIT_DIGITAL, DrvJoy5 + 3, "p3 right" }, + {"P3 Button 1", BIT_DIGITAL, DrvJoy5 + 5, "p3 fire 1" }, + {"P3 Button 2", BIT_DIGITAL, DrvJoy5 + 4, "p3 fire 2" }, + + {"P4 Coin", BIT_DIGITAL, DrvJoy8 + 0, "p4 coin" }, + {"P4 Start", BIT_DIGITAL, DrvJoy8 + 2, "p4 start" }, + {"P4 Up", BIT_DIGITAL, DrvJoy6 + 0, "p4 up" }, + {"P4 Down", BIT_DIGITAL, DrvJoy6 + 1, "p4 down" }, + {"P4 Left", BIT_DIGITAL, DrvJoy6 + 2, "p4 left" }, + {"P4 Right", BIT_DIGITAL, DrvJoy6 + 3, "p4 right" }, + {"P4 Button 1", BIT_DIGITAL, DrvJoy6 + 5, "p4 fire 1" }, + {"P4 Button 2", BIT_DIGITAL, DrvJoy6 + 4, "p4 fire 2" }, + + {"Reset", BIT_DIGITAL, &DrvReset, "reset" }, + {"Service", BIT_DIGITAL, DrvJoy4 + 0, "service" }, + {"Tilt", BIT_DIGITAL, DrvJoy4 + 2, "tilt" }, + {"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" }, + {"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" }, +}; + +STDINPUTINFO(Mexico86) + +static struct BurnDIPInfo KikikaiDIPList[]= +{ + {0x13, 0xff, 0xff, 0xfe, NULL }, + {0x14, 0xff, 0xff, 0x7f, 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, "Service Mode" }, + {0x13, 0x01, 0x04, 0x04, "Off" }, + {0x13, 0x01, 0x04, 0x00, "On" }, + + {0 , 0xfe, 0 , 2, "Unused" }, + {0x13, 0x01, 0x08, 0x08, "Off" }, + {0x13, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 4, "Coin A" }, + {0x13, 0x01, 0x30, 0x10, "2 Coins 1 Credits" }, + {0x13, 0x01, 0x30, 0x30, "1 Coin 1 Credits" }, + {0x13, 0x01, 0x30, 0x00, "2 Coins 3 Credits" }, + {0x13, 0x01, 0x30, 0x20, "1 Coin 2 Credits" }, + + {0 , 0xfe, 0 , 4, "Coin B" }, + {0x13, 0x01, 0xc0, 0x40, "2 Coins 1 Credits" }, + {0x13, 0x01, 0xc0, 0xc0, "1 Coin 1 Credits" }, + {0x13, 0x01, 0xc0, 0x00, "2 Coins 3 Credits" }, + {0x13, 0x01, 0xc0, 0x80, "1 Coin 2 Credits" }, + + {0 , 0xfe, 0 , 4, "Difficulty" }, + {0x14, 0x01, 0x03, 0x02, "Easy" }, + {0x14, 0x01, 0x03, 0x03, "Normal" }, + {0x14, 0x01, 0x03, 0x01, "Hard" }, + {0x14, 0x01, 0x03, 0x00, "Hardest" }, + + {0 , 0xfe, 0 , 4, "Bonus Life" }, + {0x14, 0x01, 0x0c, 0x00, "50000 100000" }, + {0x14, 0x01, 0x0c, 0x0c, "70000 150000" }, + {0x14, 0x01, 0x0c, 0x08, "70000 200000" }, + {0x14, 0x01, 0x0c, 0x04, "100000 300000" }, + + {0 , 0xfe, 0 , 4, "Lives" }, + {0x14, 0x01, 0x30, 0x00, "2" }, + {0x14, 0x01, 0x30, 0x30, "3" }, + {0x14, 0x01, 0x30, 0x20, "4" }, + {0x14, 0x01, 0x30, 0x10, "5" }, + + {0 , 0xfe, 0 , 2, "Coinage" }, + {0x14, 0x01, 0x40, 0x40, "A" }, + {0x14, 0x01, 0x40, 0x00, "B" }, + + {0 , 0xfe, 0 , 2, "Number Match" }, + {0x14, 0x01, 0x80, 0x80, "Off" }, + {0x14, 0x01, 0x80, 0x00, "On" }, +}; + +STDDIPINFO(Kikikai) + +static struct BurnDIPInfo Mexico86DIPList[]= +{ + {0x23, 0xff, 0xff, 0xff, NULL }, + {0x24, 0xff, 0xff, 0xfb, NULL }, + + {0 , 0xfe, 0 , 2, "Master/Slave Mode" }, + {0x23, 0x01, 0x01, 0x01, "Off" }, + {0x23, 0x01, 0x01, 0x00, "On" }, + + {0 , 0xfe, 0 , 2, "Unknown" }, + {0x23, 0x01, 0x02, 0x02, "Off" }, + {0x23, 0x01, 0x02, 0x00, "On" }, + + {0 , 0xfe, 0 , 2, "Service Mode" }, + {0x23, 0x01, 0x04, 0x04, "Off" }, + {0x23, 0x01, 0x04, 0x00, "On" }, + + {0 , 0xfe, 0 , 2, "Unknown" }, + {0x23, 0x01, 0x08, 0x08, "Off" }, + {0x23, 0x01, 0x08, 0x00, "On" }, + + {0 , 0xfe, 0 , 4, "Coin A" }, + {0x23, 0x01, 0x30, 0x10, "2 Coins 1 Credits" }, + {0x23, 0x01, 0x30, 0x30, "1 Coin 1 Credits" }, + {0x23, 0x01, 0x30, 0x00, "2 Coins 3 Credits" }, + {0x23, 0x01, 0x30, 0x20, "1 Coin 2 Credits" }, + + {0 , 0xfe, 0 , 4, "Coin B" }, + {0x23, 0x01, 0xc0, 0x40, "2 Coins 1 Credits" }, + {0x23, 0x01, 0xc0, 0xc0, "1 Coin 1 Credits" }, + {0x23, 0x01, 0xc0, 0x00, "2 Coins 3 Credits" }, + {0x23, 0x01, 0xc0, 0x80, "1 Coin 2 Credits" }, + + {0 , 0xfe, 0 , 4, "Difficulty" }, + {0x24, 0x01, 0x03, 0x03, "Easy" }, + {0x24, 0x01, 0x03, 0x02, "Normal" }, + {0x24, 0x01, 0x03, 0x01, "Hard" }, + {0x24, 0x01, 0x03, 0x00, "Hardest" }, + + {0 , 0xfe, 0 , 4, "Playing Time" }, + {0x24, 0x01, 0x0c, 0x00, "40 Seconds" }, + {0x24, 0x01, 0x0c, 0x0c, "One Minute" }, + {0x24, 0x01, 0x0c, 0x08, "One Minute and 20 Sec." }, + {0x24, 0x01, 0x0c, 0x04, "One Minute and 40 Sec." }, + + {0 , 0xfe, 0 , 2, "Unknown" }, + {0x24, 0x01, 0x10, 0x10, "Off" }, + {0x24, 0x01, 0x10, 0x00, "On" }, + + {0 , 0xfe, 0 , 2, "Board ID" }, + {0x24, 0x01, 0x20, 0x20, "Master" }, + {0x24, 0x01, 0x20, 0x00, "Slave" }, + + {0 , 0xfe, 0 , 2, "Number of Matches" }, + {0x24, 0x01, 0x40, 0x00, "2" }, + {0x24, 0x01, 0x40, 0x40, "6" }, + + {0 , 0xfe, 0 , 2, "Single board 4 Players Mode" }, + {0x24, 0x01, 0x80, 0x80, "Off" }, + {0x24, 0x01, 0x80, 0x00, "On" }, +}; + +STDDIPINFO(Mexico86) + +static void bankswitch(INT32 data) +{ + nBankData = data; + nCharBank = (data & 0x20) >> 5; + + INT32 bank = 0x8000 + (data & 7) * 0x4000; + + ZetMapMemory(DrvZ80ROM0 + bank, 0x8000, 0xbfff, MAP_ROM); +} + +static void __fastcall mexico86_main_write(UINT16 address, UINT8 data) +{ + switch (address) + { + case 0xf000: + bankswitch(data); + return; + + case 0xf008: + { + nMCUHalted = ~data & 0x02; + if (nMCUHalted && has_mcu) { + m6805Open(0); + m6805Reset(); + m6805Close(); + } + + nSoundCPUHalted = ~data & 0x04; + if (nSoundCPUHalted) { + ZetClose(); + ZetOpen(1); + ZetReset(); + ZetClose(); + ZetOpen(0); + } + + mcu_running = data & 2; + + if (!mcu_running) + mcu_initialised = 0; + } + return; + + case 0xf018: + return; // nop + } +} + +static UINT8 __fastcall mexico86_main_read(UINT16 address) +{ + switch (address) + { + case 0xf010: + return DrvInputs[3]; + } + + return 0; +} + +static void __fastcall mexico86_sound_write(UINT16 address, UINT8 data) +{ + switch (address) + { + case 0xc000: + case 0xc001: + BurnYM2203Write(0, address & 1, data); + return; + } +} + +static UINT8 __fastcall mexico86_sound_read(UINT16 address) +{ + switch (address) + { + case 0xc000: + return BurnYM2203Read(0,0) & 0x7f; // ignore busy status + + case 0xc001: + return BurnYM2203Read(0,1); + } + + return 0; +} + +static void __fastcall mexico86_sub_write(UINT16 address, UINT8 data) +{ + switch (address) + { + case 0xc004: + // coin lockout & counters + return; + } +} + +static UINT8 __fastcall mexico86_sub_read(UINT16 address) +{ + switch (address) + { + case 0xc000: + return DrvInputs[4]; + + case 0xc001: + return DrvInputs[5]; + + case 0xc002: + return DrvInputs[6]; + + case 0xc003: + return DrvInputs[7]; + } + + return 0; +} + +static void mexico86_m68705_portB_out(UINT8 *data) +{ + if ((ddrB & 0x01) && (~*data & 0x01) && (portB_out & 0x01)) + { + portA_in = mcu_latch; + } + + if ((ddrB & 0x02) && (*data & 0x02) && (~portB_out & 0x02)) + { + mcu_address = portA_out; + } + + if ((ddrB & 0x08) && (~*data & 0x08) && (portB_out & 0x08)) + { + if (*data & 0x10) /* read */ + { + if (*data & 0x04) + { + mcu_latch = DrvPrtRAM[mcu_address]; + } + else + { + mcu_latch = DrvInputs[(mcu_address & 1) + 1]; + } + } + else + { + DrvPrtRAM[mcu_address] = portA_out; + } + } + if ((ddrB & 0x20) && (*data & 0x20) && (~portB_out & 0x20)) + { + ZetOpen(0); + ZetSetVector(DrvPrtRAM[0]); + ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD); + ZetClose(); + m68705SetIrqLine(M68705_IRQ_LINE, CPU_IRQSTATUS_NONE); + } + + portB_out = *data; +} + +static void mexico86_m68705_portC_in() +{ + portC_in = DrvInputs[0]; +} + +static m68705_interface mexico86_m68705_interface = { + NULL /* portA */, mexico86_m68705_portB_out /* portB */, NULL /* portC */, + NULL /* ddrA */, NULL /* ddrB */, NULL /* ddrC */, + NULL /* portA */, NULL /* portB */, mexico86_m68705_portC_in /* portC */ +}; + +static UINT8 YM2203_read_portA(UINT32) +{ + return DrvDips[0]; +} + +static UINT8 YM2203_read_portB(UINT32) +{ + return DrvDips[1]; +} + +static INT32 DrvDoReset() +{ + memset (AllRam, 0, RamEnd - AllRam); + + ZetOpen(0); + bankswitch(0); + ZetReset(); + ZetClose(); + + ZetOpen(1); + ZetReset(); + BurnYM2203Reset(); + ZetClose(); + + ZetOpen(2); + ZetReset(); + ZetClose(); + + m67805_taito_reset(); + + nExtraCycles = 0; + nBankData = 0; + nCharBank = 0; + nSoundCPUHalted = 0; + nMCUHalted = 0; + nSubCPUHalted = (has_sub && (DrvDips[1] & 0x80)); // 4-player board + + mcu_running = 0; + mcu_initialised = 0; + coin_last[0] = false; + coin_last[1] = false; + coin_fract = 0; + + mcu_address = 0; + mcu_latch = 0; + + return 0; +} + +static INT32 MemIndex() +{ + UINT8 *Next; Next = AllMem; + + DrvZ80ROM0 = Next; Next += 0x020000; + DrvZ80ROM1 = Next; Next += 0x008000; + DrvZ80ROM2 = Next; Next += 0x004000; + DrvMCUROM = Next; Next += 0x000800; + + DrvGfxROM = Next; Next += 0x080000; + + DrvColPROM = Next; Next += 0x000300; + + DrvPalette = (UINT32*)Next; Next += 0x0101 * sizeof(UINT32); + + AllRam = Next; + + DrvShareRAM0 = Next; Next += 0x003000; + DrvShareRAM1 = Next; Next += 0x000800; + DrvZ80RAM1 = Next; Next += 0x001800; + DrvZ80RAM2 = Next; Next += 0x000800; + DrvMCURAM = Next; Next += 0x000080; + + RamEnd = Next; + + MemEnd = Next; + + return 0; +} + +static INT32 DrvGfxDecode(INT32 swap) +{ + INT32 Plane[4] = { 0x20000*8, 0x20000*8+4, 0, 4 }; + INT32 XOffs[8] = { STEP4(3,-1), STEP4(11, -1) }; + INT32 YOffs[8] = { STEP8(0,16) }; + + UINT8 *tmp = (UINT8*)BurnMalloc(0x40000); + if (tmp == NULL) { + return 1; + } + + if (swap) swap = 0x8000; + + for (INT32 i = 0; i < 0x40000; i++) tmp[i] = DrvGfxROM[i^swap] ^ 0xff; // invert + + GfxDecode(0x2000, 4, 8, 8, Plane, XOffs, YOffs, 0x80, tmp, DrvGfxROM); + + BurnFree(tmp); + + return 0; +} + +static INT32 DrvInit(INT32 game) +{ + AllMem = NULL; + MemIndex(); + INT32 nLen = MemEnd - (UINT8 *)0; + if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1; + memset(AllMem, 0, nLen); + MemIndex(); + + if (game == 0) // kiki + { + INT32 k = 0; + if (BurnLoadRom(DrvGfxROM + 0x00000, k++, 1)) return 1; + memcpy(DrvZ80ROM0 + 0x00000, DrvGfxROM + 0x00000, 0x8000); + memcpy(DrvZ80ROM0 + 0x18000, DrvGfxROM + 0x08000, 0x8000); + if (BurnLoadRom(DrvZ80ROM0 + 0x08000, k++, 1)) return 1; + + if (BurnLoadRom(DrvZ80ROM1 + 0x00000, k++, 1)) return 1; + +// if (BurnLoadRom(DrvMCUROM + 0x00000, k++, 1)) return 1; // un-comment and remove next line when dump available! + k++; + + if (BurnLoadRom(DrvGfxROM + 0x00000, k++, 1)) return 1; + if (BurnLoadRom(DrvGfxROM + 0x10000, k++, 1)) return 1; + if (BurnLoadRom(DrvGfxROM + 0x20000, k++, 1)) return 1; + if (BurnLoadRom(DrvGfxROM + 0x30000, k++, 1)) return 1; + + if (BurnLoadRom(DrvColPROM + 0x00000, k++, 1)) return 1; + if (BurnLoadRom(DrvColPROM + 0x00100, k++, 1)) return 1; + if (BurnLoadRom(DrvColPROM + 0x00200, k++, 1)) return 1; + + DrvGfxDecode(0); + + has_mcu = 0; + has_sub = 0; + } + else if (game == 1) // knightb + { + INT32 k = 0; + if (BurnLoadRom(DrvGfxROM + 0x00000, k++, 1)) return 1; // temp space to load segmented rom + memcpy(DrvZ80ROM0 + 0x00000, DrvGfxROM + 0x00000, 0x8000); + memcpy(DrvZ80ROM0 + 0x18000, DrvGfxROM + 0x08000, 0x8000); + if (BurnLoadRom(DrvZ80ROM0 + 0x08000, k++, 1)) return 1; + + if (BurnLoadRom(DrvZ80ROM1 + 0x00000, k++, 1)) return 1; + + if (BurnLoadRom(DrvMCUROM + 0x00000, k++, 1)) return 1; + + if (BurnLoadRom(DrvGfxROM + 0x00000, k++, 1)) return 1; + if (BurnLoadRom(DrvGfxROM + 0x10000, k++, 1)) return 1; + if (BurnLoadRom(DrvGfxROM + 0x20000, k++, 1)) return 1; + if (BurnLoadRom(DrvGfxROM + 0x30000, k++, 1)) return 1; + + if (BurnLoadRom(DrvColPROM + 0x00000, k++, 1)) return 1; + if (BurnLoadRom(DrvColPROM + 0x00100, k++, 1)) return 1; + if (BurnLoadRom(DrvColPROM + 0x00200, k++, 1)) return 1; + + DrvGfxDecode(0); + + has_mcu = 1; + has_sub = 0; + } + else if (game == 2) // mexico86 & kicknrun + { + INT32 k = 0; + if (BurnLoadRom(DrvGfxROM + 0x00000, k++, 1)) return 1; + memcpy(DrvZ80ROM0 + 0x00000, DrvGfxROM + 0x00000, 0x8000); + memcpy(DrvZ80ROM0 + 0x18000, DrvGfxROM + 0x08000, 0x8000); + if (BurnLoadRom(DrvZ80ROM0 + 0x08000, k++, 1)) return 1; + + if (BurnLoadRom(DrvZ80ROM1 + 0x00000, k++, 1)) return 1; + + if (BurnLoadRom(DrvMCUROM + 0x00000, k++, 1)) return 1; + + if (BurnLoadRom(DrvZ80ROM2 + 0x00000, k++, 1)) return 1; + + if (BurnLoadRom(DrvGfxROM + 0x10000, k++, 1)) return 1; // temp space. + memcpy(DrvGfxROM + 0x08000, DrvGfxROM + 0x10000, 0x8000); + memcpy(DrvGfxROM + 0x00000, DrvGfxROM + 0x18000, 0x8000); + + if (BurnLoadRom(DrvGfxROM + 0x10000, k , 1)) return 1; + if (BurnLoadRom(DrvGfxROM + 0x18000, k++, 1)) return 1; // reload + + if (BurnLoadRom(DrvGfxROM + 0x28000, k++, 1)) return 1; // half @ 0x28000 + memcpy(DrvGfxROM + 0x20000, DrvGfxROM + 0x30000, 0x8000); // other half at 0x20000 + + if (BurnLoadRom(DrvGfxROM + 0x30000, k, 1)) return 1; + if (BurnLoadRom(DrvGfxROM + 0x38000, k++, 1)) return 1; // reload + + if (BurnLoadRom(DrvColPROM + 0x00000, k++, 1)) return 1; + if (BurnLoadRom(DrvColPROM + 0x00100, k++, 1)) return 1; + if (BurnLoadRom(DrvColPROM + 0x00200, k++, 1)) return 1; + + DrvGfxDecode(0); + + has_mcu = 1; + has_sub = 1; // cpu for 4player mode + } + + ZetInit(0); + ZetOpen(0); + ZetMapMemory(DrvZ80ROM0, 0x0000, 0x7fff, MAP_ROM); + ZetMapMemory(DrvShareRAM0, 0xc000, 0xefff, MAP_RAM); + +// DrvVidRAM = DrvShareRAM0 + 0x0000; // 0xc000-0xd4ff +// DrvSprRAM = DrvShareRAM0 + 0x1500; // 0xd500-0xd7ff + DrvPrtRAM = DrvShareRAM0 + 0x2800; // 0xe800-0xe8ff + + ZetMapMemory(DrvShareRAM1, 0xf800, 0xffff, MAP_RAM); + ZetSetWriteHandler(mexico86_main_write); + ZetSetReadHandler(mexico86_main_read); + ZetClose(); + + ZetInit(1); + ZetOpen(1); + ZetMapMemory(DrvZ80ROM1, 0x0000, 0x7fff, MAP_ROM); + ZetMapMemory(DrvShareRAM0, 0x8000, 0xa7ff, MAP_RAM); + ZetMapMemory(DrvZ80RAM1, 0xa800, 0xbfff, MAP_RAM); + ZetSetWriteHandler(mexico86_sound_write); + ZetSetReadHandler(mexico86_sound_read); + ZetClose(); + + ZetInit(2); // not on kiki / knightb + ZetOpen(2); + ZetMapMemory(DrvZ80ROM2, 0x0000, 0x3fff, MAP_ROM); + ZetMapMemory(DrvZ80RAM2, 0x4000, 0x47ff, MAP_RAM); + ZetMapMemory(DrvShareRAM1, 0x8000, 0x87ff, MAP_RAM); + ZetSetWriteHandler(mexico86_sub_write); + ZetSetReadHandler(mexico86_sub_read); + ZetClose(); + + m67805_taito_init(DrvMCUROM, DrvMCURAM, &mexico86_m68705_interface); // not on kiki + + BurnYM2203Init(1, 3000000, NULL, 0); + BurnYM2203SetPorts(0, &YM2203_read_portA, &YM2203_read_portB, NULL, NULL); + BurnTimerAttachZet(6000000); + BurnYM2203SetRoute(0, BURN_SND_YM2203_YM2203_ROUTE, 1.00, BURN_SND_ROUTE_BOTH); + BurnYM2203SetRoute(0, BURN_SND_YM2203_AY8910_ROUTE_1, 0.30, BURN_SND_ROUTE_BOTH); + BurnYM2203SetRoute(0, BURN_SND_YM2203_AY8910_ROUTE_2, 0.30, BURN_SND_ROUTE_BOTH); + BurnYM2203SetRoute(0, BURN_SND_YM2203_AY8910_ROUTE_3, 0.30, BURN_SND_ROUTE_BOTH); + + GenericTilesInit(); + + DrvDoReset(); + + return 0; +} + +static INT32 DrvExit() +{ + has_mcu = 0; + has_sub = 0; + + GenericTilesExit(); + + ZetExit(); + m67805_taito_exit(); + + BurnYM2203Exit(); + + BurnFree(AllMem); + + is_mexico86 = 0; + + return 0; +} + +static void DrvPaletteInit() +{ + for (INT32 i = 0; i < 0x100; i++) + { + INT32 bit0 = (DrvColPROM[i + 0x000] >> 0) & 0x01; + INT32 bit1 = (DrvColPROM[i + 0x000] >> 1) & 0x01; + INT32 bit2 = (DrvColPROM[i + 0x000] >> 2) & 0x01; + INT32 bit3 = (DrvColPROM[i + 0x000] >> 3) & 0x01; + INT32 r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (DrvColPROM[i + 0x100] >> 0) & 0x01; + bit1 = (DrvColPROM[i + 0x100] >> 1) & 0x01; + bit2 = (DrvColPROM[i + 0x100] >> 2) & 0x01; + bit3 = (DrvColPROM[i + 0x100] >> 3) & 0x01; + INT32 g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + bit0 = (DrvColPROM[i + 0x200] >> 0) & 0x01; + bit1 = (DrvColPROM[i + 0x200] >> 1) & 0x01; + bit2 = (DrvColPROM[i + 0x200] >> 2) & 0x01; + bit3 = (DrvColPROM[i + 0x200] >> 3) & 0x01; + INT32 b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + DrvPalette[i] = BurnHighCol(r,g,b,0); + } + +// DrvPalette[0x100] = 0x100; // ?????? +} + +static void screen_update_mexico86() +{ + INT32 sx = 0; + + for (INT32 offs = 0x1500; offs < 0x2000; offs += 4) + { + INT32 height; + + if (offs >= 0x1800 && offs < 0x1980) + continue; + + if (offs >= 0x19c0) + continue; + + if (*(UINT32 *)(&DrvShareRAM0[offs]) == 0) + continue; + + INT32 gfx_num = DrvShareRAM0[offs + 1]; + INT32 gfx_attr = DrvShareRAM0[offs + 3]; + INT32 gfx_offs = 0; + + if (~gfx_num & 0x80) + { + gfx_offs = ((gfx_num & 0x1f) * 0x80) + ((gfx_num & 0x60) >> 1) + 12; + height = 2; + } + else + { + gfx_offs = ((gfx_num & 0x3f) * 0x80); + height = 32; + } + + if ((gfx_num & 0xc0) == 0xc0) + sx += 16; + else + sx = DrvShareRAM0[offs + 2]; + + INT32 sy = 256 - height * 8 - (DrvShareRAM0[offs + 0]); + + for (INT32 xc = 0; xc < 2; xc++) + { + for (INT32 yc = 0; yc < height; yc++) + { + INT32 goffs = gfx_offs + xc * 0x40 + yc * 0x02; + INT32 code = DrvShareRAM0[goffs] + ((DrvShareRAM0[goffs + 1] & 0x07) << 8) + + ((DrvShareRAM0[goffs + 1] & 0x80) << 4) + (nCharBank << 12); + INT32 color = ((DrvShareRAM0[goffs + 1] & 0x38) >> 3) + ((gfx_attr & 0x02) << 2); + INT32 flipx = DrvShareRAM0[goffs + 1] & 0x40; + INT32 flipy = 0; + + INT32 x = (sx + xc * 8) & 0xff; + INT32 y = (sy + yc * 8) & 0xff; + + Draw8x8MaskTile(pTransDraw, code, x, y - 16, flipx, flipy, color, 4, 0xf, 0, DrvGfxROM); + } + } + } +} + +static void screen_update_kikikai() +{ + INT32 sx = 0, sy, gfx_offs, height; + + for (INT32 offs = 0x1500; offs < 0x1800; offs += 4) + { + if (*(UINT32*)(DrvShareRAM0 + offs) == 0) + continue; + + INT32 ty = DrvShareRAM0[offs]; + INT32 gfx_num = DrvShareRAM0[offs + 1]; + INT32 tx = DrvShareRAM0[offs + 2]; + + if (gfx_num & 0x80) + { + gfx_offs = ((gfx_num & 0x3f) << 7); + height = 32; + if (gfx_num & 0x40) sx += 16; + else sx = tx; + } + else + { + if (!(ty && tx)) continue; + gfx_offs = ((gfx_num & 0x1f) << 7) + ((gfx_num & 0x60) >> 1) + 12; + height = 2; + sx = tx; + } + + sy = 256 - (height << 3) - ty; + + height <<= 1; + + for (INT32 yc = 0; yc < height; yc += 2) + { + INT32 y = (sy + (yc << 2)) & 0xff; + INT32 goffs = gfx_offs + yc; + INT32 code = DrvShareRAM0[goffs] + ((DrvShareRAM0[goffs + 1] & 0x1f) << 8); + INT32 color = (DrvShareRAM0[goffs + 1] & 0xe0) >> 5; + goffs += 0x40; + + Draw8x8MaskTile(pTransDraw, code, (sx + 0) & 0xff, y - 16, 0, 0, color, 4, 0xf, 0, DrvGfxROM); + + code = DrvShareRAM0[goffs] + ((DrvShareRAM0[goffs + 1] & 0x1f) << 8); + color = (DrvShareRAM0[goffs + 1] & 0xe0) >> 5; + + Draw8x8MaskTile(pTransDraw, code, (sx + 8) & 0xff, y - 16, 0, 0, color, 4, 0xf, 0, DrvGfxROM); + } + } +} + +static INT32 DrvDraw() +{ + if (DrvRecalc) { + DrvPaletteInit(); + DrvRecalc = 0; + } + + BurnTransferClear(0x100); + + if (is_mexico86) + screen_update_mexico86(); + else + screen_update_kikikai(); + + BurnTransferCopy(DrvPalette); + + return 0; +} + +static void mcu_simulate() +{ + UINT8 *protection_ram = DrvPrtRAM; + + if (!mcu_initialised) + { + if (protection_ram[0x01] == 0x00) + { + protection_ram[0x04] = 0xfc; // coin inputs + protection_ram[0x02] = 0xff; // player 1 + protection_ram[0x03] = 0xff; // player 2 + protection_ram[0x1b] = 0xff; // active player + protection_ram[0x06] = 0xff; // must be FF otherwise PS4 ERROR + protection_ram[0x07] = 0x03; // must be 03 otherwise PS4 ERROR + protection_ram[0x00] = 0x00; + mcu_initialised = 1; + } + } + + if (mcu_initialised) + { + int i; + bool coin_curr; + UINT8 coin_in_read = DrvInputs[0] & 3; + + for (INT32 coin_idx = 0; coin_idx < 2; coin_idx++) + { + coin_curr = (coin_in_read & (1 << coin_idx)) == 0; + if (coin_curr && coin_last[coin_idx] == false) + { + UINT8 coinage_setting = (DrvDips[0] >> (coin_idx*2 + 4)) & 3; + + // increase credits counter + switch(coinage_setting) + { + case 0: // 2c / 3c + case 1: // 2c / 1c + if(coin_fract == 1) + { + protection_ram[0x01]+= (coinage_setting == 0) ? 3 : 1; + coin_fract = 0; + } + else + coin_fract ++; + + break; + case 2: // 1c / 2c + case 3: // 1c / 1c + protection_ram[0x01]+= (coinage_setting == 2) ? 2 : 1; + break; + + } + + protection_ram[0x0a] = 0x01; // set flag (coin inserted sound is not played otherwise) + } + coin_last[coin_idx] = coin_curr; + } + // Purge any coin counter higher than 9 TODO: is this limit correct? + if(protection_ram[0x01] > 9) + protection_ram[0x01] = 9; + + protection_ram[0x04] = 0x3c | (coin_in_read ^ 3); // coin inputs + + protection_ram[0x02] = BITSWAP08(DrvInputs[1], 7,6,5,4,2,3,1,0); // player 1 + protection_ram[0x03] = BITSWAP08(DrvInputs[2], 7,6,5,4,2,3,1,0); // player 2 + + if (protection_ram[0x19] == 0xaa) // player 2 active + protection_ram[0x1b] = protection_ram[0x03]; + else + protection_ram[0x1b] = protection_ram[0x02]; + + for (i = 0; i < 0x10; i += 2) + protection_ram[i + 0xb1] = protection_ram[i + 0xb0]; + + for (i = 0; i < 0x0a; i++) + protection_ram[i + 0xc0] = protection_ram[i + 0x90] + 1; + + if (protection_ram[0xd1] == 0xff) + { + if (protection_ram[0xd0] > 0 && protection_ram[0xd0] < 4) + { + protection_ram[0xd2] = 0x81; + protection_ram[0xd0] = 0xff; + } + } + + if (protection_ram[0xe0] > 0 && protection_ram[0xe0] < 4) + { + static const UINT8 answers[3][16] = + { + { 0x00,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x80,0x88,0x00,0x00,0x00,0x00,0x00 }, + { 0x00,0x04,0x08,0x0C,0x10,0x14,0x18,0x1C,0x20,0x31,0x2B,0x35,0x00,0x00,0x00,0x00 }, + { 0x00,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x03,0x0A,0x0B,0x14,0x00,0x00,0x00,0x00 }, + }; + int table = protection_ram[0xe0] - 1; + + for (i = 1; i < 0x10; i++) + protection_ram[0xe0 + i] = answers[table][i]; + protection_ram[0xe0] = 0xff; + } + + if (protection_ram[0xf0] > 0 && protection_ram[0xf0] < 4) + { + protection_ram[0xf1] = 0xb3; + protection_ram[0xf0] = 0xff; + } + + // The following is missing from Knight Boy + // this should be equivalent to the obfuscated kiki_clogic() below + { + static const UINT8 db[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x18,0x00,0x00,0x00,0x00}; + UINT16 sy = protection_ram[0xa0] + ((0x18) >> 1); + UINT16 sx = protection_ram[0xa1] + ((0x18) >> 1); + + for (i = 0; i < 0x38; i += 8) + { + UINT8 hw = db[protection_ram[0x20 + i] & 0xf]; + + if (hw) + { + UINT16 xdiff = sx - ((UINT16)(protection_ram[0x20 + i + 6]) << 8 | protection_ram[0x20 + i + 7]); + if (xdiff < hw) + { + UINT16 ydiff = sy - ((UINT16)(protection_ram[0x20 + i + 4]) << 8 | protection_ram[0x20 + i + 5]); + if (ydiff < hw) + protection_ram[0xa2] = 1; // we have a collision + } + } + } + } + } +} + +static INT32 DrvFrame() +{ + if (DrvReset) { + DrvDoReset(); + } + + ZetNewFrame(); + + { + DrvInputs[0] = 0xff; + DrvInputs[1] = 0xff; + DrvInputs[2] = 0xff; + DrvInputs[3] = 0xff; + DrvInputs[4] = 0xff; + DrvInputs[5] = 0xff; + DrvInputs[6] = 0xfe; + DrvInputs[7] = 0xfe; + + for (INT32 i = 0; i < 8; i++) { + DrvInputs[0] ^= (DrvJoy1[i] & 1) << i; + DrvInputs[1] ^= (DrvJoy2[i] & 1) << i; + DrvInputs[2] ^= (DrvJoy3[i] & 1) << i; + DrvInputs[3] ^= (DrvJoy4[i] & 1) << i; + DrvInputs[4] ^= (DrvJoy5[i] & 1) << i; + DrvInputs[5] ^= (DrvJoy6[i] & 1) << i; + DrvInputs[6] ^= (DrvJoy7[i] & 1) << i; + DrvInputs[7] ^= (DrvJoy8[i] & 1) << i; + } + } + + INT32 nInterleave = 256; + INT32 nCyclesTotal[4] = { 6000000 / 60, 6000000 / 60, 4000000 / 60, 1000000 / 60 }; + INT32 nCyclesDone[4] = { nExtraCycles, 0, 0, 0 }; + + for (INT32 i = 0; i < nInterleave; i++) + { + ZetOpen(0); + nCyclesDone[0] += ZetRun(((i + 1) * nCyclesTotal[0] / nInterleave) - nCyclesDone[0]); + if (i == 255 && !has_mcu) { + UINT8 *protection_ram = DrvPrtRAM; + if (mcu_running) mcu_simulate(); + ZetSetVector(protection_ram[0]); + ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD); + } + ZetClose(); + + ZetOpen(1); + if (nSoundCPUHalted) { + ZetIdle(((nCyclesTotal[0] / nInterleave) * (i + 1)) - ZetTotalCycles()); + } else { + BurnTimerUpdate((nCyclesTotal[0] / nInterleave) * (i + 1)); + } + if (i == 255) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD); + ZetClose(); + + if (has_sub && !nSubCPUHalted) + { + ZetOpen(2); + nCyclesDone[2] += ZetRun(((i + 1) * nCyclesTotal[2] / nInterleave) - nCyclesDone[2]); + if (i == 255) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD); + ZetClose(); + } + + if (nMCUHalted || !has_mcu) { + nCyclesDone[3] += ((i + 1) * nCyclesTotal[3] / nInterleave) - nCyclesDone[3]; + } else { + m6805Open(0); + nCyclesDone[3] += m6805Run(((i + 1) * nCyclesTotal[3] / nInterleave) - nCyclesDone[3]); + if (i == 255) m68705SetIrqLine(M68705_IRQ_LINE, CPU_IRQSTATUS_ACK); + m6805Close(); + } + } + + ZetOpen(1); + + BurnTimerEndFrame(nCyclesTotal[1]); + + if (pBurnSoundOut) { + BurnYM2203Update(pBurnSoundOut, nBurnSoundLen); + } + + ZetClose(); + + nExtraCycles = nCyclesDone[0] - nCyclesTotal[0]; + + if (pBurnDraw) + DrvDraw(); + + return 0; +} + +static INT32 DrvScan(INT32 nAction, INT32 *pnMin) +{ + struct BurnArea ba; + + if (pnMin != NULL) { + *pnMin = 0x029672; + } + + if (nAction & ACB_MEMORY_RAM) { + memset(&ba, 0, sizeof(ba)); + ba.Data = AllRam; + ba.nLen = RamEnd-AllRam; + ba.szName = "All Ram"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + ZetScan(nAction); + m68705_taito_scan(nAction); + + BurnYM2203Scan(nAction, pnMin); + + SCAN_VAR(mcu_address); + SCAN_VAR(mcu_latch); + + SCAN_VAR(nExtraCycles); + SCAN_VAR(nBankData); + SCAN_VAR(nCharBank); + SCAN_VAR(nSoundCPUHalted); + SCAN_VAR(nSubCPUHalted); + SCAN_VAR(mcu_running); + SCAN_VAR(mcu_initialised); + SCAN_VAR(coin_last); + SCAN_VAR(coin_fract); + } + + if (nAction & ACB_WRITE) { + ZetOpen(0); + bankswitch(nBankData); + ZetClose(); + } + + return 0; +} + + +// KiKi KaiKai + +static struct BurnRomInfo kikikaiRomDesc[] = { + { "a85-17.h16", 0x10000, 0xc141d5ab, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "a85-16.h18", 0x10000, 0x4094d750, 1 | BRF_PRG | BRF_ESS }, // 1 + + { "a85-11.f6", 0x08000, 0xcc3539db, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 #1 Code + + { "a85-01.g8", 0x00800, 0x00000000, 3 | BRF_NODUMP | BRF_PRG }, // 3 MCU Code (undumped) + + { "a85-15.a1", 0x10000, 0xaebc8c32, 4 | BRF_GRA }, // 4 Graphics + { "a85-14.a3", 0x10000, 0xa9df0453, 4 | BRF_GRA }, // 5 + { "a85-13.a4", 0x10000, 0x3eeaf878, 4 | BRF_GRA }, // 6 + { "a85-12.a6", 0x10000, 0x91e58067, 4 | BRF_GRA }, // 7 + + { "a85-08.g15", 0x00100, 0xd15f61a8, 5 | BRF_GRA }, // 8 Color Data + { "a85-10.g12", 0x00100, 0x8fc3fa86, 5 | BRF_GRA }, // 9 + { "a85-09.g14", 0x00100, 0xb931c94d, 5 | BRF_GRA }, // 10 +}; + +STD_ROM_PICK(kikikai) +STD_ROM_FN(kikikai) + +static INT32 KikikaiInit() +{ + return DrvInit(0); +} + +struct BurnDriver BurnDrvKikikai = { + "kikikai", NULL, NULL, NULL, "1986", + "KiKi KaiKai\0", NULL, "Taito Corporation", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_TAITO_MISC, GBF_MISC, 0, + NULL, kikikaiRomInfo, kikikaiRomName, NULL, NULL, NULL, NULL, KikikaiInputInfo, KikikaiDIPInfo, + KikikaiInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x101, + 224, 256, 3, 4 +}; + + +// Knight Boy + +static struct BurnRomInfo knightbRomDesc[] = { + { "a85-17.h16", 0x10000, 0xc141d5ab, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "a85-16.h18", 0x10000, 0x4094d750, 1 | BRF_PRG | BRF_ESS }, // 1 + + { "a85-11.f6", 0x08000, 0xcc3539db, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 #1 Code + + { "knightb.uc", 0x00800, 0x3cc2bbe4, 3 | BRF_PRG | BRF_ESS }, // 3 M68705 Code + + { "knightb.d", 0x10000, 0x53ecdb3f, 4 | BRF_GRA }, // 4 Graphics + { "a85-14.a3", 0x10000, 0xa9df0453, 4 | BRF_GRA }, // 5 + { "knightb.b", 0x10000, 0x63ad7df3, 4 | BRF_GRA }, // 6 + { "a85-12.a6", 0x10000, 0x91e58067, 4 | BRF_GRA }, // 7 + + { "a85-08.g15", 0x00100, 0xd15f61a8, 5 | BRF_GRA }, // 8 Color Data + { "a85-10.g12", 0x00100, 0x8fc3fa86, 5 | BRF_GRA }, // 9 + { "a85-09.g14", 0x00100, 0xb931c94d, 5 | BRF_GRA }, // 10 +}; + +STD_ROM_PICK(knightb) +STD_ROM_FN(knightb) + +static INT32 KnightbInit() +{ + return DrvInit(1); +} + +struct BurnDriver BurnDrvKnightb = { + "knightb", "kikikai", NULL, NULL, "1986", + "Knight Boy\0", NULL, "bootleg", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED, 2, HARDWARE_TAITO_MISC, GBF_MISC, 0, + NULL, knightbRomInfo, knightbRomName, NULL, NULL, NULL, NULL, KikikaiInputInfo, KikikaiDIPInfo, + KnightbInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x101, + 224, 256, 3, 4 +}; + + +// Kick and Run (World) + +static struct BurnRomInfo kicknrunRomDesc[] = { + { "a87-08.h16", 0x10000, 0x715e1b04, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "a87-07.h18", 0x10000, 0x6cb6ebfe, 1 | BRF_PRG | BRF_ESS }, // 1 + + { "a87-06.f6", 0x08000, 0x1625b587, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 #1 Code + + { "a87-01.g8", 0x00800, 0x8e821fa0, 3 | BRF_PRG | BRF_ESS }, // 3 M68705 Code + + { "a87-09-1", 0x04000, 0x6a2ad32f, 4 | BRF_PRG | BRF_ESS }, // 4 Z80 #2 Code + + { "a87-05.a1", 0x10000, 0x4eee3a8a, 5 | BRF_GRA }, // 5 Graphics + { "a87-04.a3", 0x08000, 0x8b438d20, 5 | BRF_GRA }, // 6 + { "a87-03.a4", 0x10000, 0xf42e8a88, 5 | BRF_GRA }, // 7 + { "a87-02.a6", 0x08000, 0x64f1a85f, 5 | BRF_GRA }, // 8 + + { "a87-10.g15", 0x00100, 0xbe6eb1f0, 6 | BRF_GRA }, // 9 Color Data + { "a87-12.g12", 0x00100, 0x3e953444, 6 | BRF_GRA }, // 10 + { "a87-11.g14", 0x00100, 0x14f6c28d, 6 | BRF_GRA }, // 11 +}; + +STD_ROM_PICK(kicknrun) +STD_ROM_FN(kicknrun) + +static INT32 KicknrunInit() +{ + is_mexico86 = 1; + + return DrvInit(2); +} + +struct BurnDriver BurnDrvKicknrun = { + "kicknrun", NULL, NULL, NULL, "1986", + "Kick and Run (World)\0", NULL, "Taito Corporation", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING, 2, HARDWARE_TAITO_MISC, GBF_MISC, 0, + NULL, kicknrunRomInfo, kicknrunRomName, NULL, NULL, NULL, NULL, Mexico86InputInfo, Mexico86DIPInfo, + KicknrunInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x101, + 256, 224, 4, 3 +}; + + +// Kick and Run (US) + +static struct BurnRomInfo kicknrunuRomDesc[] = { + { "a87-23.h16", 0x10000, 0x37182560, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "a87-22.h18", 0x10000, 0x3b5a8354, 1 | BRF_PRG | BRF_ESS }, // 1 + + { "a87-06.f6", 0x08000, 0x1625b587, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 #1 Code + + { "a87-01.g8", 0x00800, 0x8e821fa0, 3 | BRF_PRG | BRF_ESS }, // 3 M68705 Code + + { "a87-09-1", 0x04000, 0x6a2ad32f, 4 | BRF_PRG | BRF_ESS }, // 4 Z80 #2 Code + + { "a87-05.a1", 0x10000, 0x4eee3a8a, 5 | BRF_GRA }, // 5 Graphics + { "a87-04.a3", 0x08000, 0x8b438d20, 5 | BRF_GRA }, // 6 + { "a87-03.a4", 0x10000, 0xf42e8a88, 5 | BRF_GRA }, // 7 + { "a87-02.a6", 0x08000, 0x64f1a85f, 5 | BRF_GRA }, // 8 + + { "a87-10.g15", 0x00100, 0xbe6eb1f0, 6 | BRF_GRA }, // 9 Color Data + { "a87-12.g12", 0x00100, 0x3e953444, 6 | BRF_GRA }, // 10 + { "a87-11.g14", 0x00100, 0x14f6c28d, 6 | BRF_GRA }, // 11 +}; + +STD_ROM_PICK(kicknrunu) +STD_ROM_FN(kicknrunu) + +struct BurnDriver BurnDrvKicknrunu = { + "kicknrunu", "kicknrun", NULL, NULL, "1986", + "Kick and Run (US)\0", NULL, "Taito America Corp", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_TAITO_MISC, GBF_MISC, 0, + NULL, kicknrunuRomInfo, kicknrunuRomName, NULL, NULL, NULL, NULL, Mexico86InputInfo, Mexico86DIPInfo, + KicknrunInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x101, + 256, 224, 4, 3 +}; + + +// Mexico 86 (bootleg of Kick and Run) (set 1) + +static struct BurnRomInfo mexico86RomDesc[] = { + { "2_g.bin", 0x10000, 0x2bbfe0fb, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "1_f.bin", 0x10000, 0x0b93e68e, 1 | BRF_PRG | BRF_ESS }, // 1 + + { "a87-06.f6", 0x08000, 0x1625b587, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 #1 Code + + { "68_h.bin", 0x00800, 0xff92f816, 3 | BRF_PRG | BRF_ESS }, // 3 M68705 Code + + { "a87-09-1", 0x04000, 0x6a2ad32f, 4 | BRF_PRG | BRF_ESS }, // 4 Z80 #2 Code + + { "4_d.bin", 0x10000, 0x57cfdbca, 5 | BRF_GRA }, // 5 Graphics + { "5_c.bin", 0x08000, 0xe42fa143, 5 | BRF_GRA }, // 6 + { "6_b.bin", 0x10000, 0xa4607989, 5 | BRF_GRA }, // 7 + { "7_a.bin", 0x08000, 0x245036b1, 5 | BRF_GRA }, // 8 + + { "a87-10.g15", 0x00100, 0xbe6eb1f0, 6 | BRF_GRA }, // 9 Color Data + { "a87-12.g12", 0x00100, 0x3e953444, 6 | BRF_GRA }, // 10 + { "a87-11.g14", 0x00100, 0x14f6c28d, 6 | BRF_GRA }, // 11 +}; + +STD_ROM_PICK(mexico86) +STD_ROM_FN(mexico86) + +struct BurnDriver BurnDrvMexico86 = { + "mexico86", "kicknrun", NULL, NULL, "1986", + "Mexico 86 (bootleg of Kick and Run) (set 1)\0", NULL, "bootleg", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_TAITO_MISC, GBF_MISC, 0, + NULL, mexico86RomInfo, mexico86RomName, NULL, NULL, NULL, NULL, Mexico86InputInfo, Mexico86DIPInfo, + KicknrunInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x101, + 256, 224, 4, 3 +}; + + +// Mexico 86 (bootleg of Kick and Run) (set 2) + +static struct BurnRomInfo mexico86aRomDesc[] = { + { "2.bin", 0x10000, 0x397c93ad, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 #0 Code + { "1.bin", 0x10000, 0x0b93e68e, 1 | BRF_PRG | BRF_ESS }, // 1 + + { "3x.bin", 0x08000, 0xabbbf6c4, 2 | BRF_PRG | BRF_ESS }, // 2 Z80 #1 Code + { "3.bin", 0x08000, 0x1625b587, 2 | BRF_PRG | BRF_ESS }, // 3 + + { "68_h.bin", 0x00800, 0xff92f816, 3 | BRF_PRG | BRF_ESS }, // 4 M68705 Code + + { "8.bin", 0x04000, 0x6a2ad32f, 4 | BRF_PRG | BRF_ESS }, // 5 Z80 #2 Code + + { "4.bin", 0x10000, 0x57cfdbca, 5 | BRF_GRA }, // 6 Graphics + { "5.bin", 0x08000, 0xe42fa143, 5 | BRF_GRA }, // 7 + { "6.bin", 0x10000, 0xa4607989, 5 | BRF_GRA }, // 8 + { "7.bin", 0x08000, 0x245036b1, 5 | BRF_GRA }, // 9 + + { "n82s129n.1.bin", 0x00100, 0xbe6eb1f0, 6 | BRF_GRA }, // 10 Color Data + { "n82s129n.3.bin", 0x00100, 0x3e953444, 6 | BRF_GRA }, // 11 + { "n82s129n.2.bin", 0x00100, 0x14f6c28d, 6 | BRF_GRA }, // 12 + + { "ampal16l8pc.1.bin", 0x00104, 0x634f3a5b, 7 | BRF_OPT }, // 13 PLDs + { "ampal16l8pc.3.bin", 0x00104, 0xf9ce900a, 7 | BRF_OPT }, // 14 + { "ampal16l8pc.4.bin", 0x00104, 0x39120b6f, 7 | BRF_OPT }, // 15 + { "ampal16l8pc.5.bin", 0x00104, 0x1d27f7b9, 7 | BRF_OPT }, // 16 + { "ampal16l8pc.6.bin", 0x00104, 0x9f941c8e, 7 | BRF_OPT }, // 17 + { "ampal16l8pc.7.bin", 0x00104, 0x9f941c8e, 7 | BRF_OPT }, // 18 + { "ampal16r4pc.2.bin", 0x00104, 0x213a71d1, 7 | BRF_OPT }, // 19 +}; + +STD_ROM_PICK(mexico86a) +STD_ROM_FN(mexico86a) + +struct BurnDriverD BurnDrvMexico86a = { + "mexico86a", "kicknrun", NULL, NULL, "1986", + "Mexico 86 (bootleg of Kick and Run) (set 2)\0", NULL, "bootleg", "Miscellaneous", + NULL, NULL, NULL, NULL, + BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_TAITO_MISC, GBF_MISC, 0, + NULL, mexico86aRomInfo, mexico86aRomName, NULL, NULL, NULL, NULL, Mexico86InputInfo, Mexico86DIPInfo, + KicknrunInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x101, + 256, 224, 4, 3 +}; + diff --git a/whatsnew.html b/whatsnew.html index a16006a53..558425858 100644 --- a/whatsnew.html +++ b/whatsnew.html @@ -315,6 +315,10 @@
  • Fix crash issue with Tecmo Bowl when playing via Keyboard [dink]
  • Add RESET Line to Z80 cpu interface [dink]
  • Fix graphics issues in Superior Soldiers (background gfx) and Gun Force (titlescreen) on Irem m92 [dink]
  • +
  • Fix Localisation Template [Barry]
  • +
  • Sync romsets with MAME 0.207 [Barry]
  • +
  • Fix 2p controller on Colecovision [dink]
  • +
  • Fix sound in Baseball Stars and NAM-1975 when using alternate MVS bioses [dink]
  • []
  • @@ -395,6 +399,8 @@
  • Added driver for Taito's Ground Effects / Super Ground Effects [iq_132, dink]
  • Added driver for Liberation, Boomer Rang'r and Kamikaze Cabbie by DataEast [iq_132]
  • Added driver for Taito's Under Fire and Chase Bombers [iq_132, dink]
  • +
  • Added driver for Taito's Qix, Zookeeper, Slither, Space Dungeon, Complex X, Kram and The Electric Yo-Yo [iq_132, dink]
  • +
  • Added driver for Taito's Kiki KaiKai/Knight Boy and Kick and Run/Mexico '86 [iq_132, dink]
  • New additions / updates to existing drivers