/* Sliver - Hollow Corp.1996 driver by Tomasz Slanina Custom blitter + background framebuffer + oki for sound. The background images on this hardware are in JPEG format, the Zoran chips are hardware JPEG decompression chips. Driver (temporary) uses fake rom with decompressed images (gfx.bin) TODO: - verify OKI rom banking (bank num inverted or not) - DIPS - add jpeg decompression - fix transparency problems in some stages PCB Layout ---------- WS16-AJ-940820 |---------|-----------|------------------------------------| | TL084 | i8031 | KA-1 | | |-----------||--------| | | AD-65 KA-2 |ACTEL | KA-6 KA-7 KA-8 KA-9 | | |A1020B | | | KA-3 |PL84C | | | PAL | | | | |--------| | | AT76C176 62256 62256 | | | |J KM75C02 62256 62256 | |A | |M PAL 62256 62256 | |M | |A 62256 62256 | | HY534256| | DSW1 PAL |-------| HY534256| | PAL PAL |ZORAN | HY534256| | |-------| |ZR36011| HY534256| | DSW2 62256 62256 |ZORAN | |-------| | | KA-4 KA-5 |ZR36050| | | |-------| |-------| | | |------------------|16MHz |FUJI | | | | | |MD0204 | | | | MC68000P10 | |-------| | | | | KA-12 KA-11 KA-10| |24MHz |------------------| | |----------------------------------------------------------| Notes: i8031 - Intel 8031 CPU, clock 8.000MHz (DIP40) 68000 - Motorola MC68000 CPU, clock 12.000MHz (DIP64) AT76C176 - Atmel AT76C176 1-Channel 6-Bit AD/DA Convertor with Clamp Circuit (DIP28). When removed, text and _some_ graphics turn black (palette related use) This chip is compatible to Fujitsu MB40176 A1020B - Actel A1020B FPGA (PLCC84) ZR36050 - Zoran ZR36050PQC-21 DF4B9423G (QFP100) ZR36011 - Zoran ZR36011PQC JAPAN 079414 (QFP100) MD0204 - Fuji MD0204 JAPAN F39D110 (QFP128) - Memory controller 62256 - 32K x8 SRAM (DIP28) HY534256 - Hyundai 256K x4 (1MBit) DRAM (DIP20) KM75C02 - Samsung KM75C02 FIFO RAM (DIP28) AD-65 - Clone OKI M6295 (QFP44), clock 1.000MHz, sample rate = 1000000Hz / 132 VSync - 60Hz */ #include "driver.h" #include "deprecat.h" #include "sound/okim6295.h" #include "cpu/i8051/i8051.h" #define FIFO_SIZE 1024 #define IO_SIZE 0x100 #define COMMAND_SIZE 8 #define x_offset 0x45 #define y_offset 0x0d static UINT16 io_offset; static UINT16 io_reg[IO_SIZE]; static UINT16 fifo[FIFO_SIZE]; static UINT16 fptr; static int jpeg_addr=-1; static UINT16 jpeg1,jpeg2; static int jpeg_h=0; static int jpeg_w=0; static int jpeg_x=0; static int jpeg_y=0; static int tmp_counter; static int clr_offset=0; static bitmap_t *sliver_bitmap_fg; static bitmap_t *sliver_bitmap_bg; static UINT16 tempbuf[8]; static const int gfxlookup[][4]= { { 0x0000000, 0x0000000, 512, 256 }, { 0x0060000, 0x0007fa5, 512, 256 }, { 0x00c0000, 0x0008c04, 512, 512 }, { 0x0180000, 0x001642b, 512, 512 }, { 0x0240000, 0x00240fb, 512, 512 }, { 0x0300000, 0x0033494, 512, 256 }, { 0x0360000, 0x003ad9a, 512, 256 }, { 0x03c0000, 0x003cab3, 512, 256 }, { 0x0420000, 0x003e50c, 512, 256 }, { 0x0480000, 0x003fd94, 512, 256 }, { 0x04e0000, 0x004166e, 512, 256 }, { 0x0540000, 0x004306a, 512, 256 }, { 0x05a0000, 0x0044c65, 512, 256 }, { 0x0600000, 0x0046aeb, 512, 256 }, { 0x0660000, 0x0048a86, 512, 512 }, { 0x0720000, 0x00527c7, 512, 512 }, { 0x07e0000, 0x005a789, 512, 256 }, { 0x0840000, 0x005f9b0, 512, 256 }, { 0x08a0000, 0x0065621, 512, 512 }, { 0x0960000, 0x006fbd6, 512, 512 }, { 0x0a20000, 0x0077b98, 512, 512 }, { 0x0ae0000, 0x007fa6e, 512, 512 }, { 0x0ba0000, 0x0087a42, 512, 512 }, { 0x0c60000, 0x008f996, 512, 256 }, { 0x0cc0000, 0x0094b82, 512, 512 }, { 0x0d80000, 0x009e27a, 512, 512 }, { 0x0e40000, 0x00a6157, 512, 256 }, { 0x0ea0000, 0x00ab417, 512, 512 }, { 0x0f60000, 0x00b33c1, 512, 512 }, { 0x1020000, 0x00bd7f1, 512, 256 }, { 0x1080000, 0x00c1679, 512, 512 }, { 0x1140000, 0x00cbc8a, 512, 256 }, { 0x11a0000, 0x00d0ee2, 512, 256 }, { 0x1200000, 0x00d4d76, 512, 256 }, { 0x1260000, 0x00d8a4f, 512, 256 }, { 0x12c0000, 0x00dc980, 512, 256 }, { 0x1320000, 0x00e07ba, 512, 256 }, { 0x1380000, 0x00e45a2, 512, 256 }, { 0x13e0000, 0x00e842e, 512, 256 }, { 0x1440000, 0x00ec0db, 512, 256 }, { 0x14a0000, 0x00efdae, 512, 256 }, { 0x1500000, 0x00f3c99, 512, 256 }, { 0x1560000, 0x00f794f, 512, 256 }, { 0x15c0000, 0x00fb5db, 512, 256 }, { 0x1620000, 0x00ff2e6, 512, 256 }, { 0x1680000, 0x0103156, 512, 256 }, { 0x16e0000, 0x0106fcf, 512, 256 }, { 0x1740000, 0x010ae0c, 512, 256 }, { 0x17a0000, 0x010edaf, 512, 256 }, { 0x1800000, 0x0112bac, 512, 256 }, { 0x1860000, 0x01169c1, 128, 128 }, { 0x186c000, 0x0119b95, 128, 128 }, { 0x1878000, 0x011d0dc, 128, 128 }, { 0x1884000, 0x01205ca, 128, 128 }, { 0x1890000, 0x01236b2, 128, 128 }, { 0x189c000, 0x01268ff, 128, 128 }, { 0x18a8000, 0x0129bef, 128, 128 }, { 0x18b4000, 0x012cf51, 128, 128 }, { 0x18c0000, 0x0130331, 128, 128 }, { 0x18cc000, 0x013370d, 128, 128 }, { 0x18d8000, 0x0136a80, 128, 128 }, { 0x18e4000, 0x0139d2a, 128, 128 }, { 0x18f0000, 0x013ce39, 128, 128 }, { 0x18fc000, 0x0140236, 128, 128 }, { 0x1908000, 0x0143701, 128, 128 }, { 0x1914000, 0x0146cb3, 128, 128 }, { 0x1920000, 0x014a40d, 128, 128 }, { 0x192c000, 0x014da18, 128, 128 }, { 0x1938000, 0x0150ea4, 512, 256 }, { 0x1998000, 0x0154e17, 512, 256 }, { 0x19f8000, 0x0158ddf, 512, 256 }, { 0x1a58000, 0x015cd80, 512, 256 }, { 0x1ab8000, 0x0160d5b, 512, 256 }, { 0x1b18000, 0x0164d2f, 512, 256 }, { 0x1b78000, 0x017b5db, 512, 256 }, { 0x1bd8000, 0x017f2e6, 512, 256 }, { -1,-1,-1,-1} }; static WRITE16_HANDLER( sliver_RAMDAC_offset_w ) { clr_offset=data*3; } static WRITE16_HANDLER( sliver_RAMDAC_color_w ) { colorram[clr_offset]=data; clr_offset=(clr_offset+1)%768; } static void plot_pixel_rgb(int x, int y, UINT32 r, UINT32 g, UINT32 b) { UINT16 color; if(y<0 ||x<0 || x>383 || y> 255) return; if (sliver_bitmap_bg->bpp == 32) { *BITMAP_ADDR32(sliver_bitmap_bg, y, x) = r | (g<<8) | (b<<16); } else { r>>=3; g>>=3; b>>=3; color = r|(g<<5)|(b<<10); *BITMAP_ADDR16(sliver_bitmap_bg, y, x) = color; } } static void plot_pixel_pal(int x, int y, int addr) { UINT32 r,g,b; UINT16 color; if(y<0 ||x<0 || x>383 || y> 255) return; addr*=3; b=colorram[addr]<<2; g=colorram[addr+1]<<2; r=colorram[addr+2]<<2; if (sliver_bitmap_fg->bpp == 32) { *BITMAP_ADDR32(sliver_bitmap_fg, y, x) = r | (g<<8) | (b<<16); } else { r>>=3; g>>=3; b>>=3; color = r|(g<<5)|(b<<10); *BITMAP_ADDR16(sliver_bitmap_fg, y, x) = color; } } static WRITE16_HANDLER( fifo_data_w ) { if(tmp_counter<8) { COMBINE_DATA(&tempbuf[tmp_counter]); tmp_counter++; if(tmp_counter==8) // copy 8 bytes to fifo, every byte should be copied directly, but it's easier to copy whole commands { do { fifo[fptr++]=tempbuf[8-tmp_counter]; if(fptr>(FIFO_SIZE-1)) { fptr=FIFO_SIZE-1; } } while(--tmp_counter>0); } } } static void blit_gfx(running_machine *machine) { int tmpptr=0; const UINT8 *rom = memory_region(machine, "user1"); while(tmpptr=0) { if(offset==gfxlookup[idx][1]) { return idx; } ++idx; } return -1; } static WRITE16_HANDLER( jpeg2_w ) { COMBINE_DATA(&jpeg2); { int idx=find_data((int)jpeg2+(((int)jpeg1)<<16)); if(idx>=0) { jpeg_addr=gfxlookup[idx][0]; jpeg_w=gfxlookup[idx][2]; jpeg_h=gfxlookup[idx][3]; render_jpeg(machine); } else { jpeg_addr=-1; } } } static WRITE16_HANDLER(io_offset_w) { COMBINE_DATA(&io_offset); } static WRITE16_HANDLER(io_data_w) { if(io_offsetprimary_screen); sliver_bitmap_fg = video_screen_auto_bitmap_alloc(machine->primary_screen); } static VIDEO_UPDATE(sliver) { copybitmap (bitmap, sliver_bitmap_bg, 0, 0, 0, 0, cliprect); copybitmap_trans(bitmap, sliver_bitmap_fg, 0, 0, 0, 0, cliprect, 0); return 0; } static INPUT_PORTS_START( sliver ) PORT_START("P1_P2") PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("SYSTEM") PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_START2 ) PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_UNKNOWN ) //jpeg ready flag PORT_BIT( 0xffa4, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("DSW") PORT_DIPNAME( 0x000f, 0x000f, DEF_STR( Coin_A ) ) PORT_DIPSETTING( 0x000f, DEF_STR( 1C_1C ) ) PORT_DIPSETTING( 0x000e, DEF_STR( 1C_2C ) ) PORT_DIPSETTING( 0x000d, DEF_STR( 1C_3C ) ) PORT_DIPSETTING( 0x000c, DEF_STR( 1C_4C ) ) PORT_DIPSETTING( 0x000b, DEF_STR( 1C_5C ) ) PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) ) PORT_DIPNAME( 0x0030, 0x0020, DEF_STR( Lives ) ) PORT_DIPSETTING( 0x0030, "2" ) PORT_DIPSETTING( 0x0020, "3" ) PORT_DIPSETTING( 0x0010, "4" ) PORT_DIPSETTING( 0x0000, "5" ) PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0040, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0080, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0200, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0400, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0800, 0x0800, "Demo_Sounds" ) PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0800, DEF_STR( On ) ) PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN ) // unknown PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) INPUT_PORTS_END static INTERRUPT_GEN( sliver_int ) { //valid interrupts are 2,3,4 cpunum_set_input_line(machine, 0, 2+cpu_getiloops(), HOLD_LINE); } static MACHINE_DRIVER_START( sliver ) MDRV_CPU_ADD("main", M68000, 12000000) MDRV_CPU_PROGRAM_MAP(sliver_map,0) MDRV_CPU_VBLANK_INT_HACK(sliver_int,3) MDRV_CPU_ADD("audio", I8051, 8000000) MDRV_CPU_PROGRAM_MAP(soundmem_prg,0) MDRV_CPU_DATA_MAP(soundmem_data,0) MDRV_CPU_IO_MAP(soundmem_io,0) MDRV_SCREEN_ADD("main", RASTER) MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) MDRV_SCREEN_SIZE(64*8, 32*8) MDRV_SCREEN_VISIBLE_AREA(0*8, 384-1-16, 0*8, 240-1) MDRV_VIDEO_START(sliver) MDRV_VIDEO_UPDATE(sliver) MDRV_SPEAKER_STANDARD_STEREO("left", "right") MDRV_SOUND_ADD("oki", OKIM6295, 1000000) MDRV_SOUND_CONFIG(okim6295_interface_pin7high) MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.6) MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.6) MACHINE_DRIVER_END ROM_START( sliver ) ROM_REGION( 0x100000, "main", 0 ) /* 68000 Code */ ROM_LOAD16_BYTE( "ka-4.bin", 0x00001, 0x20000, CRC(4906367f) SHA1(cc030930ffe7018ba6c362cab136798d027db7d8) ) ROM_LOAD16_BYTE( "ka-5.bin", 0x00000, 0x20000, CRC(f260dabc) SHA1(3727cb8aa652809386075b39a1d85d5b20973702) ) ROM_REGION( 0x10000, "audio", 0 ) /* 8031 */ ROM_LOAD( "ka-1.bin", 0x000000, 0x10000, CRC(56e616a2) SHA1(f8952aba62ae0410e300d99e95dc8b752543af1e) ) ROM_REGION( 0x180000, "oki", 0 ) /* Samples */ ROM_LOAD( "ka-2.bin", 0x000000, 0x20000, CRC(3df96eb0) SHA1(ec3dfc29da08f6525a1c708839f83094a6784f72) ) ROM_LOAD( "ka-3.bin", 0x100000, 0x80000, CRC(33ee929c) SHA1(a652ad68c547248ef5fa1ed8006b7ac7aef76383) ) ROM_REGION( 0x200000, "user1", 0 ) /* Graphics (not tiles) */ ROM_LOAD16_BYTE( "ka-8.bin", 0x000000, 0x80000, CRC(dbfd7489) SHA1(4a7b07d041dce04a8d8d6688698164f988baefc9) ) ROM_LOAD16_BYTE( "ka-6.bin", 0x000001, 0x80000, CRC(bd182316) SHA1(a22db9f73a2865f59630183c14201aeede821642) ) ROM_LOAD16_BYTE( "ka-9.bin", 0x100000, 0x40000, CRC(71f044ba) SHA1(bd88bfaa0249de9fd8eb8bd25eae0126744a9046) ) ROM_LOAD16_BYTE( "ka-7.bin", 0x100001, 0x40000, CRC(1c5d6fb9) SHA1(372533264eb41a5f57b2a59eb039adb6334f36c5) ) ROM_REGION( 0x180000, "user2", 0 ) /* JPEG(!) compressed GFX */ ROM_LOAD( "ka-10.bin", 0x000000, 0x80000, CRC(a6824271) SHA1(2eefa4e61491f7b72ccde744fa6f88a1a3c60c92) ) ROM_LOAD( "ka-11.bin", 0x080000, 0x80000, CRC(4ae121ff) SHA1(ece7cc07483801a0d436def977d72dc7b1a07c8f) ) ROM_LOAD( "ka-12.bin", 0x100000, 0x80000, CRC(0901e142) SHA1(68ebd38beeedf53414a831c01813881feee33446) ) ROM_REGION( 0x2000000, "user3", 0 ) /* decompressed GFX - temporary!*/ ROM_LOAD( "gfx.bin", 0x000000, 0x2000000, BAD_DUMP CRC(706f264e) SHA1(dbcc8dbf30bd65d86bcde7d6db1b08af4242a253) ) ROM_END static DRIVER_INIT(sliver) { colorram=auto_malloc(256*3); } GAME( 1996, sliver, 0, sliver, sliver, sliver, ROT0, "Hollow Corp", "Sliver", GAME_IMPERFECT_GRAPHICS )