summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/viper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/viper.c')
-rw-r--r--src/mame/drivers/viper.c1047
1 files changed, 1047 insertions, 0 deletions
diff --git a/src/mame/drivers/viper.c b/src/mame/drivers/viper.c
new file mode 100644
index 00000000000..c7e1c8f41f2
--- /dev/null
+++ b/src/mame/drivers/viper.c
@@ -0,0 +1,1047 @@
+/*
+ Konami Viper System
+
+ Driver by Ville Linde
+
+
+
+ Games on this hardware:
+
+ Game ID Year Game
+ ------------------------------------------------------------------------------------------------------
+ GK922 2000 Code One Dispatch
+ G???? 2001 ParaParaParadise 2nd Mix
+ GM941 2001 GTI Club 2
+ G?A00 2001 Police 911 (USA) / Police 24/7 (World) / Keisatsukan Shinjuku 24ji (Japan)
+ GKA13 2001 Silent Scope EX (USA/World) / Sogeki (Japan)
+ G?A29 2001 Mocap Boxing
+ G?A30 2001 Tsurugi
+ GMA41 2001 Thrill Drive 2
+ G?A45 2001 Boxing Mania
+ G?B11 2001 Police 911 2 (USA) / Police 24/7 2 (World) / Keisatsukan Shinjuku 24ji 2 (Japan)
+ G?B33 2001 Mocap Golf
+ G?B41 2001 Jurassic Park 3
+ G?B4x 2002 Xtrial Racing
+ G?C00 2003 Pop'n Music 9
+ G?C09 2002 Mahjong Fight Club
+ G?C22 2002 World Combat (USA/Japan/Korea) / Warzaid (Europe)
+*/
+
+#include "driver.h"
+#include "cpu/powerpc/ppc.h"
+#include "machine/pci.h"
+#include "memconv.h"
+#include "machine/idectrl.h"
+#include "machine/timekpr.h"
+#include "video/voodoo.h"
+
+
+
+static UINT8 backup_ram[0x2000];
+
+
+static VIDEO_START(viper)
+{
+ voodoo_start(0, 0, VOODOO_3, 16, 16, 16);
+}
+
+static VIDEO_UPDATE(viper)
+{
+ return voodoo_update(0, bitmap, cliprect) ? 0 : UPDATE_HAS_NOT_CHANGED;
+}
+
+
+
+/*****************************************************************************/
+
+static UINT32 mpc8240_regs[256/4];
+static UINT32 mpc8240_pci_r(int function, int reg, UINT32 mem_mask)
+{
+// printf("MPC8240: PCI read %d, %02X, %08X\n", function, reg, mem_mask);
+
+ switch (reg)
+ {
+ }
+
+ return mpc8240_regs[reg/4];
+}
+
+static void mpc8240_pci_w(int function, int reg, UINT32 data, UINT32 mem_mask)
+{
+// printf("MPC8240: PCI write %d, %02X, %08X, %08X\n", function, reg, data, mem_mask);
+ COMBINE_DATA(mpc8240_regs + (reg/4));
+}
+
+
+static READ64_HANDLER( pci_config_addr_r )
+{
+ return pci_64be_r(0, U64(0x00000000ffffffff));
+}
+
+static WRITE64_HANDLER( pci_config_addr_w )
+{
+ pci_64be_w(0, data, U64(0x00000000ffffffff));
+}
+
+static READ64_HANDLER( pci_config_data_r )
+{
+ return pci_64be_r(1, U64(0xffffffff00000000)) << 32;
+}
+
+static WRITE64_HANDLER( pci_config_data_w )
+{
+ pci_64be_w(1, data >> 32, U64(0xffffffff00000000));
+}
+
+
+
+static UINT32 epic_iack;
+
+static READ32_HANDLER( epic_r )
+{
+ int reg;
+ reg = offset * 4;
+
+ //printf("EPIC: read %08X, %08X at %08X\n", reg, mem_mask, activecpu_get_pc());
+
+ switch (reg >> 16)
+ {
+ // 0x60000 - 0x6FFFF
+ case 0x6:
+ {
+ switch (reg & 0xffff)
+ {
+ case 0x00a0: // IACK
+ return epic_iack;
+
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static WRITE32_HANDLER( epic_w )
+{
+ int reg;
+ reg = offset * 4;
+
+ //printf("EPIC: write %08X, %08X, %08X at %08X\n", data, reg, mem_mask, activecpu_get_pc());
+
+ switch (reg >> 16)
+ {
+ // 0x60000 - 0x6FFFF
+ case 0x6:
+ {
+ switch (reg & 0xffff)
+ {
+ case 0x00b0: // EOI
+ epic_iack = 0xff;
+ break;
+ }
+ break;
+ }
+ }
+}
+
+static READ64_HANDLER(epic_64be_r)
+{
+ return read64be_with_32le_handler(epic_r, offset, mem_mask);
+}
+static WRITE64_HANDLER(epic_64be_w)
+{
+ write64be_with_32le_handler(epic_w, offset, data, mem_mask);
+}
+
+
+static int cf_card_ide = 0;
+
+static UINT8 cf_card_tuples[] =
+{
+ 0x01, // Device Tuple
+ 0x01, // Tuple size
+ 0xd0, // Device Type Func Spec
+
+ 0x1a, // Config Tuple
+ 0xff, // Tuple size (last?)
+ 0x03, // CCR base size
+ 0x00, // last config index?
+ 0x00, 0x01, 0x00, 0x00, // CCR base (0x00000100)
+};
+
+static READ64_HANDLER(cf_card_data_r)
+{
+ UINT64 r = 0;
+
+ if (!(mem_mask & U64(0x00000000ffff0000)))
+ {
+ switch (offset & 0xf)
+ {
+ case 0x8: // Duplicate Even RD Data
+ {
+ r |= ide_bus_0_r(0, 0) << 16;
+ break;
+ }
+
+ default:
+ {
+ fatalerror("cf_card_data_r: IDE reg %02X at %08X\n", offset & 0xf, activecpu_get_pc());
+ }
+ }
+ }
+ return r;
+}
+
+static WRITE64_HANDLER(cf_card_data_w)
+{
+ if (!(mem_mask & U64(0x00000000ffff0000)))
+ {
+ switch (offset & 0xf)
+ {
+ case 0x8: // Duplicate Even RD Data
+ {
+ ide_bus_0_w(0, 0, (data >> 16) & 0xffff);
+ break;
+ }
+
+ default:
+ {
+ fatalerror("cf_card_data_w: IDE reg %02X, %04X at %08X\n", offset & 0xf, (UINT16)(data >> 16), activecpu_get_pc());
+ }
+ }
+ }
+}
+
+static READ64_HANDLER(cf_card_r)
+{
+ UINT64 r = 0;
+
+ if (!(mem_mask & U64(0x00000000ffff0000)))
+ {
+ if (cf_card_ide)
+ {
+ switch (offset & 0xf)
+ {
+ case 0x0: // Even RD Data
+ case 0x1: // Error
+ case 0x2: // Sector Count
+ case 0x3: // Sector No.
+ case 0x4: // Cylinder Low
+ case 0x5: // Cylinder High
+ case 0x6: // Select Card/Head
+ case 0x7: // Status
+ {
+ r |= ide_bus_0_r(0, offset & 7) << 16;
+ break;
+ }
+
+ //case 0x8: // Duplicate Even RD Data
+ //case 0x9: // Duplicate Odd RD Data
+
+ case 0xd: // Duplicate Error
+ {
+ r |= ide_bus_0_r(0, 1) << 16;
+ break;
+ }
+ case 0xe: // Alt Status
+ case 0xf: // Drive Address
+ {
+ r |= ide_bus_0_r(1, offset & 7) << 16;
+ break;
+ }
+
+ default:
+ {
+ printf("compact_flash_r: IDE reg %02X at %08X\n", offset & 0xf, activecpu_get_pc());
+ }
+ }
+ }
+ else
+ {
+ int reg = offset;
+
+ //printf("cf_r: %04X\n", reg);
+
+ if ((reg >> 1) < sizeof(cf_card_tuples))
+ {
+ r |= cf_card_tuples[reg >> 1] << 16;
+ }
+ else
+ {
+ fatalerror("compact_flash_r: reg %02X at %08X\n", reg, activecpu_get_pc());
+ }
+ }
+ }
+ return r;
+}
+
+static WRITE64_HANDLER(cf_card_w)
+{
+ //printf("compact_flash_w: %08X%08X, %08X, %08X%08X at %08X\n", (UINT32)(data>>32), (UINT32)(data), offset, (UINT32)(mem_mask >> 32), (UINT32)(mem_mask), activecpu_get_pc());
+
+ if (!(mem_mask & U64(0x00000000ffff0000)))
+ {
+ if (offset < 0x10)
+ {
+ switch (offset & 0xf)
+ {
+ case 0x0: // Even WR Data
+ case 0x1: // Features
+ case 0x2: // Sector Count
+ case 0x3: // Sector No.
+ case 0x4: // Cylinder Low
+ case 0x5: // Cylinder High
+ case 0x6: // Select Card/Head
+ case 0x7: // Command
+ {
+ ide_bus_0_w(0, offset & 7, (data >> 16) & 0xffff);
+ break;
+ }
+
+ //case 0x8: // Duplicate Even WR Data
+ //case 0x9: // Duplicate Odd WR Data
+
+ case 0xd: // Duplicate Features
+ {
+ ide_bus_0_w(0, 1, (data >> 16) & 0xffff);
+ break;
+ }
+ case 0xe: // Device Ctl
+ case 0xf: // Reserved
+ {
+ ide_bus_0_w(1, offset & 7, (data >> 16) & 0xffff);
+ break;
+ }
+
+ default:
+ {
+ fatalerror("compact_flash_w: IDE reg %02X, data %04X at %08X\n", offset & 0xf, (UINT16)((data >> 16) & 0xffff), activecpu_get_pc());
+ }
+ }
+ }
+ else if (offset >= 0x100)
+ {
+ switch (offset)
+ {
+ case 0x100:
+ {
+ if ((data >> 16) & 0x80)
+ {
+ cf_card_ide = 1;
+
+ // soft reset
+ // sector count register is set to 0x01
+ // sector number register is set to 0x01
+ // cylinder low register is set to 0x00
+ // cylinder high register is set to 0x00
+
+ ide_bus_0_w(1, 6, 0x04);
+ }
+ break;
+ }
+ default:
+ {
+ fatalerror("compact_flash_w: reg %02X, data %04X at %08X\n", offset, (UINT16)((data >> 16) & 0xffff), activecpu_get_pc());
+ }
+ }
+ }
+ }
+}
+
+static WRITE64_HANDLER(unk2_w)
+{
+ if (!(mem_mask & U64(0xff00000000000000)))
+ {
+ cf_card_ide = 0;
+ }
+}
+
+
+
+
+static READ64_HANDLER(ata_r)
+{
+ UINT64 r = 0;
+
+ if (!(mem_mask & U64(0x00000000ffff0000)))
+ {
+ int reg = (offset >> 4) & 0x7;
+
+ r |= ide_bus_0_r((offset & 0x80) ? 1 : 0, reg) << 16;
+ }
+
+ return r;
+}
+
+static WRITE64_HANDLER(ata_w)
+{
+ if (!(mem_mask & U64(0x00000000ffff0000)))
+ {
+ int reg = (offset >> 4) & 0x7;
+
+ ide_bus_0_w((offset & 0x80) ? 1 : 0, reg, (UINT16)(data >> 16));
+ }
+}
+
+static int unk1_bit = 0;
+static READ64_HANDLER(unk1_r)
+{
+ UINT64 r = 0;
+ //return 0;//U64(0x0000400000000000);
+
+ if (!(mem_mask & U64(0x0000ff0000000000)))
+ {
+ r |= (UINT64)(unk1_bit << 5) << 40;
+ }
+
+ return r;
+}
+
+static WRITE64_HANDLER(unk1a_w)
+{
+ if (!(mem_mask & U64(0xff00000000000000)))
+ {
+ unk1_bit = 1;
+ }
+}
+
+static WRITE64_HANDLER(unk1b_w)
+{
+ if (!(mem_mask & U64(0xff00000000000000)))
+ {
+ unk1_bit = 0;
+ }
+}
+
+static UINT32 voodoo3_pci_reg[0x100];
+static UINT32 voodoo3_pci_r(int function, int reg, UINT32 mem_mask)
+{
+ switch (reg)
+ {
+ case 0x00: // PCI Vendor ID (0x121a = 3dfx), Device ID (0x0005 = Voodoo 3)
+ {
+ return 0x0005121a;
+ }
+ case 0x08: // Device class code
+ {
+ return 0x03000000;
+ }
+ case 0x10: // memBaseAddr0
+ {
+ return voodoo3_pci_reg[0x10/4];
+ }
+ case 0x14: // memBaseAddr1
+ {
+ return voodoo3_pci_reg[0x14/4];
+ }
+ case 0x18: // memBaseAddr1
+ {
+ return voodoo3_pci_reg[0x18/4];
+ }
+ case 0x40: // fabId
+ {
+ return voodoo3_pci_reg[0x40/4];
+ }
+ case 0x50: // cfgScratch
+ {
+ return voodoo3_pci_reg[0x50/4];
+ }
+
+ default:
+ fatalerror("voodoo3_pci_r: %08X at %08X", reg, activecpu_get_pc());
+ }
+ return 0;
+}
+
+static void voodoo3_pci_w(int function, int reg, UINT32 data, UINT32 mem_mask)
+{
+// printf("voodoo3_pci_w: %08X, %08X\n", reg, data);
+
+ switch (reg)
+ {
+ case 0x04: // Command register
+ {
+ voodoo3_pci_reg[0x04/4] = data;
+ break;
+ }
+ case 0x10: // memBaseAddr0
+ {
+ if (data == 0xffffffff)
+ {
+ voodoo3_pci_reg[0x10/4] = 0xfe000000;
+ }
+ else
+ {
+ voodoo3_pci_reg[0x10/4] = data;
+ }
+ break;
+ }
+ case 0x14: // memBaseAddr1
+ {
+ if (data == 0xffffffff)
+ {
+ voodoo3_pci_reg[0x14/4] = 0xfe000008;
+ }
+ else
+ {
+ voodoo3_pci_reg[0x14/4] = data;
+ }
+ break;
+ }
+ case 0x18: // ioBaseAddr
+ {
+ if (data == 0xffffffff)
+ {
+ voodoo3_pci_reg[0x18/4] = 0xffffff01;
+ }
+ else
+ {
+ voodoo3_pci_reg[0x18/4] = data;
+ }
+ break;
+ }
+ case 0x3c: // InterruptLine
+ {
+ break;
+ }
+ case 0x40: // fabId
+ {
+ voodoo3_pci_reg[0x40/4] = data;
+ break;
+ }
+ case 0x50: // cfgScratch
+ {
+ voodoo3_pci_reg[0x50/4] = data;
+ break;
+ }
+
+ default:
+ fatalerror("voodoo3_pci_w: %08X, %08X at %08X", data, reg, activecpu_get_pc());
+ }
+}
+
+static READ64_HANDLER(voodoo3_io_r)
+{
+ return read64be_with_32le_handler(banshee_io_0_r, offset, mem_mask);
+}
+static WRITE64_HANDLER(voodoo3_io_w)
+{
+// printf("voodoo3_io_w: %08X%08X, %08X at %08X\n", (UINT32)(data >> 32), (UINT32)(data), offset, activecpu_get_pc());
+ write64be_with_32le_handler(banshee_io_0_w, offset, data, mem_mask);
+}
+
+static READ64_HANDLER(voodoo3_r)
+{
+ return read64be_with_32le_handler(banshee_0_r, offset, mem_mask);
+}
+static WRITE64_HANDLER(voodoo3_w)
+{
+// printf("voodoo3_w: %08X%08X, %08X at %08X\n", (UINT32)(data >> 32), (UINT32)(data), offset, activecpu_get_pc());
+ write64be_with_32le_handler(banshee_0_w, offset, data, mem_mask);
+}
+
+static READ64_HANDLER(voodoo3_lfb_r)
+{
+ return read64be_with_32le_handler(banshee_fb_0_r, offset, mem_mask);
+}
+static WRITE64_HANDLER(voodoo3_lfb_w)
+{
+// printf("voodoo3_lfb_w: %08X%08X, %08X at %08X\n", (UINT32)(data >> 32), (UINT32)(data), offset, activecpu_get_pc());
+ write64be_with_32le_handler(banshee_fb_0_w, offset, data, mem_mask);
+}
+
+
+
+static READ64_HANDLER(m48t58_r)
+{
+ UINT64 r = 0;
+
+ if ((mem_mask & U64(0xffffffff00000000)) != U64(0xffffffff00000000))
+ {
+ r |= (UINT64)timekeeper_0_32be_r((offset * 2) + 0, (UINT32)(mem_mask >> 32)) << 32;
+ }
+ if ((mem_mask & U64(0x00000000ffffffff)) != U64(0x00000000ffffffff))
+ {
+ r |= timekeeper_0_32be_r((offset * 2) + 1, (UINT32)(mem_mask));
+ }
+
+ return r;
+}
+
+static WRITE64_HANDLER(m48t58_w)
+{
+ if (!(mem_mask & U64(0xffffffff00000000)))
+ {
+ timekeeper_0_32be_w((offset * 2) + 0, (UINT32)(data >> 32), (UINT32)(mem_mask >> 32));
+ }
+ if (!(mem_mask & U64(0x00000000ffffffff)))
+ {
+ timekeeper_0_32be_w((offset * 2) + 1, (UINT32)(data), (UINT32)(mem_mask));
+ }
+}
+
+/*****************************************************************************/
+
+static ADDRESS_MAP_START(viper_map, ADDRESS_SPACE_PROGRAM, 64)
+ AM_RANGE(0x00000000, 0x00ffffff) AM_MIRROR(0x1000000) AM_RAM
+ AM_RANGE(0x80000000, 0x800fffff) AM_READWRITE(epic_64be_r, epic_64be_w)
+ AM_RANGE(0x82000000, 0x83ffffff) AM_READWRITE(voodoo3_r, voodoo3_w)
+ AM_RANGE(0x84000000, 0x85ffffff) AM_READWRITE(voodoo3_lfb_r, voodoo3_lfb_w)
+ AM_RANGE(0xfe800000, 0xfe8000ff) AM_READWRITE(voodoo3_io_r, voodoo3_io_w)
+ AM_RANGE(0xfec00000, 0xfedfffff) AM_READWRITE(pci_config_addr_r, pci_config_addr_w)
+ AM_RANGE(0xfee00000, 0xfeefffff) AM_READWRITE(pci_config_data_r, pci_config_data_w)
+ AM_RANGE(0xff300000, 0xff300fff) AM_READWRITE(ata_r, ata_w)
+ AM_RANGE(0xffe10000, 0xffe10007) AM_READ(unk1_r)
+ AM_RANGE(0xffe30000, 0xffe31fff) AM_READWRITE(m48t58_r, m48t58_w)
+ AM_RANGE(0xffe40000, 0xffe4000f) AM_NOP
+ AM_RANGE(0xffe50000, 0xffe50007) AM_WRITE(unk2_w)
+ AM_RANGE(0xffe80000, 0xffe80007) AM_WRITE(unk1a_w)
+ AM_RANGE(0xffe88000, 0xffe88007) AM_WRITE(unk1b_w)
+ AM_RANGE(0xfff00000, 0xfff3ffff) AM_ROM AM_REGION(REGION_USER1, 0) // Boot ROM
+ADDRESS_MAP_END
+
+/*****************************************************************************/
+
+
+static INPUT_PORTS_START(viper)
+
+INPUT_PORTS_END
+
+static ppc_config viper_ppc_cfg =
+{
+ PPC_MODEL_MPC8240,
+ 0x30,
+ BUS_FREQUENCY_66MHZ
+};
+
+static INTERRUPT_GEN(viper_vblank)
+{
+
+}
+static MACHINE_RESET(viper)
+{
+ ide_controller_reset(0);
+}
+
+static MACHINE_DRIVER_START(viper)
+
+ /* basic machine hardware */
+ MDRV_CPU_ADD(MPC8240, 200000000)
+ MDRV_CPU_CONFIG(viper_ppc_cfg)
+ MDRV_CPU_PROGRAM_MAP(viper_map, 0)
+ MDRV_CPU_VBLANK_INT(viper_vblank, 1)
+
+ MDRV_SCREEN_REFRESH_RATE(60)
+
+ MDRV_MACHINE_RESET(viper)
+
+ MDRV_NVRAM_HANDLER(timekeeper_0)
+
+ /* video hardware */
+ MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
+ MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
+ MDRV_SCREEN_SIZE(800, 600)
+ MDRV_SCREEN_VISIBLE_AREA(0, 799, 0, 599)
+ MDRV_PALETTE_LENGTH(65536)
+
+ MDRV_VIDEO_START(viper)
+ MDRV_VIDEO_UPDATE(viper)
+
+ /* sound hardware */
+ MDRV_SPEAKER_STANDARD_STEREO("left", "right")
+
+MACHINE_DRIVER_END
+
+/*****************************************************************************/
+
+static void ide_interrupt(int state)
+{
+}
+
+static struct pci_device_info mpc8240 =
+{
+ mpc8240_pci_r,
+ mpc8240_pci_w
+};
+
+static struct pci_device_info voodoo3 =
+{
+ voodoo3_pci_r,
+ voodoo3_pci_w
+};
+
+static struct ide_interface ide_intf =
+{
+ ide_interrupt
+};
+
+static DRIVER_INIT(viper)
+{
+ UINT8 *nvram;
+
+ pci_init();
+ pci_add_device(0, 0, &mpc8240);
+ pci_add_device(0, 12, &voodoo3);
+
+ ide_controller_init(0, &ide_intf);
+
+ timekeeper_init(0, TIMEKEEPER_M48T58, backup_ram);
+
+ nvram = memory_region(REGION_USER2);
+ memcpy(backup_ram, nvram, 0x2000);
+}
+
+static DRIVER_INIT(vipercf)
+{
+ driver_init_viper(machine);
+
+ memory_install_read64_handler( 0, ADDRESS_SPACE_PROGRAM, 0xff000000, 0xff000fff, 0, 0, cf_card_data_r );
+ memory_install_write64_handler(0, ADDRESS_SPACE_PROGRAM, 0xff000000, 0xff000fff, 0, 0, cf_card_data_w );
+ memory_install_read64_handler( 0, ADDRESS_SPACE_PROGRAM, 0xff200000, 0xff200fff, 0, 0, cf_card_r );
+ memory_install_write64_handler(0, ADDRESS_SPACE_PROGRAM, 0xff200000, 0xff200fff, 0, 0, cf_card_w );
+}
+
+static DRIVER_INIT(ppp2nd)
+{
+ driver_init_viper(machine);
+
+ /*
+ backup_ram[0x0000] = 0x50; // P
+ backup_ram[0x0001] = 0x33; // 3
+ backup_ram[0x0002] = 0x5f; // _
+ backup_ram[0x0003] = 0x32; // 2
+ backup_ram[0x0004] = 0x6e; // n
+ backup_ram[0x0005] = 0x64; // d
+ backup_ram[0x0006] = 0x4d; // M
+ backup_ram[0x0007] = 0x49; // I
+ backup_ram[0x0008] = 0x58; // X
+ backup_ram[0x0009] = 0x00; //
+ backup_ram[0x000a] = 0x00; //
+ backup_ram[0x000b] = 0x00; //
+ backup_ram[0x000c] = 0x00; //
+ backup_ram[0x000d] = 0x00; //
+ backup_ram[0x000e] = 0x00; //
+ backup_ram[0x000f] = 0x00; //
+
+ backup_ram[0x0100] = 0x39;
+ backup_ram[0x0101] = 0x89;
+ backup_ram[0x0102] = 0x3a;
+ backup_ram[0x0103] = 0xaa;
+ */
+}
+
+
+/*****************************************************************************/
+
+#define ROM_LOAD_BIOS(bios,name,offset,length,hash) \
+ ROMX_LOAD(name, offset, length, hash, ROM_BIOS(bios+1)) /* Note '+1' */
+
+#define VIPER_BIOS \
+ ROM_REGION64_BE(0x40000, REGION_USER1, 0) /* Boot ROM */ \
+ ROM_SYSTEM_BIOS(0, "Viper BIOS", "GM941B01") \
+ ROM_LOAD_BIOS(0, "941b01.u25", 0x00000, 0x40000, CRC(233e5159) SHA1(66ff268d5bf78fbfa48cdc3e1b08f8956cfd6cfb))
+
+
+ROM_START(kviper)
+ VIPER_BIOS
+ROM_END
+
+
+/* Viper games with hard disk */
+ROM_START(ppp2nd)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "ppp2nd", 0, MD5(06012243d4b64ebd9b81e9781fb5624d) SHA1(54b45e2df3f4239191000900181a94227a351c67))
+ROM_END
+
+/* Viper games with Compact Flash card */
+ROM_START(boxingm)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(c24e29fc) SHA1(efb6ecaf25cbdf9d8dfcafa85e38a195fa5ff6c4))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "a45jaa02", 0, MD5(db0e9de39e2b4e6bd9f6f768472ab24a) SHA1(046c766fdb1b6607e794c598d5d603215b8e81a3) )
+ROM_END
+
+ROM_START(code1d)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "gk922d02", 0, MD5(c2713080273300a963fbf96dc22f70d7) SHA1(fcf451e8d49a93ca25a2177f2eb014da6ca6bcb3) )
+ROM_END
+
+ROM_START(code1db)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "gk922b02", 0, MD5(c1a9b406300c2e258be1cca00746ad6c) SHA1(ce949cdbe16ff8539e7fa46ccc58a06a90c7edde) )
+ROM_END
+
+ROM_START(gticlub2)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(d0604e84) SHA1(18d1183f1331af3e655a56692eb7ab877b4bc239))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "gm941b02", 0, MD5(8403c7f5fa5c254a30d87b59f8d1fedc) SHA1(217ef1628e8a377d22f537507dbe18fa9fe01fa2) )
+ROM_END
+
+ROM_START(jpark3)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(55d1681d) SHA1(26868cf0d14f23f06b81f2df0b4186924439bb43))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "b41c02", 0, MD5(4909b6c4007cc24f8cc514aa0ea26170) SHA1(386059033832c70063ff38363d473050162835e9) )
+ROM_END
+
+ROM_START(mocapglf)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "b33a02", 0, MD5(5e7d62ab51dae4e9ace35d7e52b08b5d) SHA1(a56df1917fb476cbacfe24f1a2f2cacc770eb80a) )
+ROM_END
+
+ROM_START(mocapb)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x000000, 0x2000, CRC(14b9fe68) SHA1(3c59e6df1bb46bc1835c13fd182b1bb092c08759))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "a29b02", 0, MD5(18f7070bbde3c3ca38d71425bdc074ab) SHA1(167b4b9f0960503db37c22e81ce4149925c5ec71) )
+ROM_END
+
+ROM_START(mocapbj)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x000000, 0x2000, CRC(2f7cdf27) SHA1(0b69d8728be12909e235268268a312982f81d46a))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "a29a02", 0, MD5(ba06338534dbad61071d39907a3aed85) SHA1(8ab0b63f6e4d1401380a286736964f0cd668a70e) )
+ROM_END
+
+ROM_START(p911)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x000000, 0x2000, CRC(cca056ca) SHA1(de1a00d84c1311d48bbe6d24f5b36e22ecf5e85a))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "a00aad02", 0, MD5(894ec7584841d7e1775e76edc53e739e) SHA1(2fc73fdaf9bc9ab6942672458206517bf8d851e1) )
+ROM_END
+
+ROM_START(p911uc)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "a00aac02", 0, MD5(c1d1a18932490c9d6185d0c3b55b50cf) SHA1(5cbdfce13ce2cb5c45ea66e20e092d5a5fe69c5d) )
+ROM_END
+
+ROM_START(p911e)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "a00eaa02", 0, MD5(5c870c38a408591e080516ae6a5f28e5) SHA1(8ff93666c33c7ee3ac2e4eeca9077c8296036187) )
+ROM_END
+
+ROM_START(p911j)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x000000, 0x2000, CRC(9ecf70dc) SHA1(4769a99b0cc28563e219860b8d480f32d1e21f60))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "a00jac02", 0, MD5(6c4b7c934159a54c93d5aa386e44969a) SHA1(80217103ad96b06855a57763c702140cbe4a2494) )
+ROM_END
+
+ROM_START(p9112)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "b11a02", 0, MD5(7ddf6139577bce2062b2f9a9ac99e56a) SHA1(56d9c47f3c7fceb2d8c36a8fa205c90595923c6f) )
+ROM_END
+
+ROM_START(popn9)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "c00jab", 0, MD5(f16cfaae05d29fdeeb7289265bf45712) SHA1(fd5b374731975e956b6e4e7102bc8350bfd8b5f4) )
+ROM_END
+
+ROM_START(sscopex)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x000000, 0x2000, CRC(7b0e1ac8) SHA1(1ea549964539e27f87370e9986bfa44eeed037cd))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "gka13c02", 0, MD5(994ced1f61dfe5ea10eac4b407359392) SHA1(179145b0e98c2ab5a7fc5c93cbc0c5398f961f65) )
+ROM_END
+
+ROM_START(sogeki)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x000000, 0x2000, CRC(2f325c55) SHA1(0bc44f40f981a815c8ce64eae95ae55db510c565))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "a13b02", 0, MD5(b476764d13ebf3fc3ec52e1fc2b36f96) SHA1(16965f5f164f4f8191e93274f8c99d84def15c70) )
+ROM_END
+
+ROM_START(thrild2)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(d5de9b8e) SHA1(768bcd46a6ad20948f60f5e0ecd2f7b9c2901061))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "gma41b02", 0, MD5(a3c39be28464fa737390e2e1e2aeb683) SHA1(0a451e33f5a6b708a54b70cc247e4d49ada0025a) )
+ROM_END
+
+ROM_START(thrild2a)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(3b7b0969) SHA1(3f11b6420ad3e3ee6f807e1ae14908bdc6e86d8f))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "gma41a02", 0, MD5(e73843d28afaef6c6af2513b6cf064e6) SHA1(abdaba1f539cf5d723fa51e939c0ffcbf5cdf28f) )
+ROM_END
+
+ROM_START(tsurugi)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(c123342c) SHA1(55416767608fe0311a362854a16b214b04435a31))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "a30eab02", 0, MD5(81593f4d5a10f7dea124bef0b02d15e6) SHA1(2202d8f8fa7cc752d4ebae16eac6818a5de06b98) )
+ROM_END
+
+ROM_START(tsurugij)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "a30jac02", 0, MD5(c7400ccdb4b045bbf2de4fa9d63a9e87) SHA1(64cc19941c2f3b39cbbe158042f3b312a678752d) )
+ROM_END
+
+ROM_START(wcombat)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(4f8b5858) SHA1(68066241c6f9db7f45e55b3c5da101987f4ce53c))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "c22d02", 0, MD5(f3b63ac0b2f613c9183356e7cf966ba6) SHA1(f7a6e8eba877f213075bd4836a62a898f17a27dc) )
+ROM_END
+
+ROM_START(wcombak)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(ebd4d645) SHA1(2fa7e2c6b113214f3eb1900c8ceef4d5fcf0bb76))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "c22c02", 0, MD5(e108a01a0a3ada065f42b0b4b16a4480) SHA1(6caff33b9b22fc56a619d58cfb8fb5aca2ecd289) )
+ROM_END
+
+ROM_START(wcombaj)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(bd8a6640) SHA1(2d409197ef3fb07d984d27fa943f29c7a711d715))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "c22a02", 0, MD5(0df54ceaa46c00e9b849af4bea6df1eb) SHA1(63ba75403ff714b2169f3c2e8ae3246a035da2d3) )
+ROM_END
+
+ROM_START(xtrial)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(33708a93) SHA1(715968e3c9c15edf628fa6ac655dc0864e336c6c))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "b4xb02", 0, MD5(c915e4946231fee8d3df00d5be08c177) SHA1(8631efafc19cc34ab8fbee2ed912d35de1f8b161) )
+ROM_END
+
+/* Viper Satellite Terminal games */
+ROM_START(mfightc)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+ ROM_LOAD("nvram.u39", 0x00000, 0x2000, CRC(9fb551a5) SHA1(a33d185e186d404c3bf62277d7e34e5ad0000b09))
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "c09jad04", 0, MD5(a858ca8f04838e8b5b603ea12526016c) SHA1(97e9b57c72787737c976cf9d7e997aee50befd53) )
+ROM_END
+
+ROM_START(mfightcc)
+ VIPER_BIOS
+
+ ROM_REGION(0x2000, REGION_USER2, ROMREGION_ERASE00) /* M48T58 Timekeeper NVRAM */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE( "c09jac04", 0, MD5(3d502e1f9c8dbd7a9179ffd754a3de1b) SHA1(d27f04cc25df9955c014b7b97f768324f8e47c5c) )
+ROM_END
+
+/*****************************************************************************/
+
+/* Viper BIOS */
+GAME(1999, kviper, 0, viper, viper, viper, ROT0, "Konami", "Konami Viper BIOS", GAME_IS_BIOS_ROOT)
+
+GAME(2001, ppp2nd, kviper, viper, viper, ppp2nd, ROT0, "Konami", "ParaParaParadise 2nd Mix", GAME_NOT_WORKING|GAME_NO_SOUND)
+
+GAME(2001, boxingm, kviper, viper, viper, vipercf, ROT0, "Konami", "Boxing Mania", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2000, code1d, kviper, viper, viper, vipercf, ROT0, "Konami", "Code One Dispatch", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2000, code1db, code1d, viper, viper, vipercf, ROT0, "Konami", "Code One Dispatch (ver B)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, gticlub2, kviper, viper, viper, vipercf, ROT0, "Konami", "GTI Club 2", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, jpark3, kviper, viper, viper, vipercf, ROT0, "Konami", "Jurassic Park 3", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, mocapglf, kviper, viper, viper, vipercf, ROT0, "Konami", "Mocap Golf", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, mocapb, kviper, viper, viper, vipercf, ROT0, "Konami", "Mocap Boxing (ver AAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, mocapbj, mocapb, viper, viper, vipercf, ROT0, "Konami", "Mocap Boxing (ver JAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, p911, kviper, viper, viper, vipercf, ROT0, "Konami", "Police 911", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, p911uc, p911, viper, viper, vipercf, ROT0, "Konami", "Police 911 (ver UAC)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, p911e, p911, viper, viper, vipercf, ROT0, "Konami", "Police 24/7 (ver EAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, p911j, p911, viper, viper, vipercf, ROT0, "Konami", "Keisatsukan Shinjuku 24ji (ver JAC)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, p9112, kviper, viper, viper, vipercf, ROT0, "Konami", "Police 911 2", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2003, popn9, kviper, viper, viper, vipercf, ROT0, "Konami", "Pop'n Music 9", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, sscopex, kviper, viper, viper, vipercf, ROT0, "Konami", "Silent Scope EX (ver UAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, sogeki, sscopex, viper, viper, vipercf, ROT0, "Konami", "Sogeki (ver JAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, thrild2, kviper, viper, viper, vipercf, ROT0, "Konami", "Thrill Drive 2", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, thrild2a, thrild2, viper, viper, vipercf, ROT0, "Konami", "Thrill Drive 2 (ver A)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, tsurugi, kviper, viper, viper, vipercf, ROT0, "Konami", "Tsurugi (ver EAB)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2001, tsurugij, tsurugi, viper, viper, vipercf, ROT0, "Konami", "Tsurugi (ver JAC)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2002, wcombat, kviper, viper, viper, vipercf, ROT0, "Konami", "World Combat", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2002, wcombak, wcombat, viper, viper, vipercf, ROT0, "Konami", "World Combat (ver KBC)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2002, wcombaj, wcombat, viper, viper, vipercf, ROT0, "Konami", "World Combat (ver JAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2002, xtrial, kviper, viper, viper, vipercf, ROT0, "Konami", "Xtrial Racing", GAME_NOT_WORKING|GAME_NO_SOUND)
+
+GAME(2002, mfightc, kviper, viper, viper, vipercf, ROT0, "Konami", "Mahjong Fight Club (ver D)", GAME_NOT_WORKING|GAME_NO_SOUND)
+GAME(2002, mfightcc, mfightc, viper, viper, vipercf, ROT0, "Konami", "Mahjong Fight Club (ver C)", GAME_NOT_WORKING|GAME_NO_SOUND)