diff options
Diffstat (limited to 'src/mame/drivers/koikoi.c')
-rw-r--r-- | src/mame/drivers/koikoi.c | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/src/mame/drivers/koikoi.c b/src/mame/drivers/koikoi.c new file mode 100644 index 00000000000..6fe21fd3900 --- /dev/null +++ b/src/mame/drivers/koikoi.c @@ -0,0 +1,312 @@ +/*************************************************************************** + +Koi Koi Part 2 +--------------- +driver by + Tomasz Slanina + David Haywood + +TODO: +- map inputs (temp mapped to keys a-l and z-x) +- is there (still..) some kind of protection ? timers looks weird (2nd player timer is frozen) +- colors (afaik color(?) prom outputs are connected to one of pals) + + +Basic hw is... +z80 (possibly xtal/4) +ay3-8910 (possibly xtal/8) +15.468xtal +1 dsw (8) +2kx8 SRAM (x2) + + +Few words about inputs (code @ $21bd): +-------------------------------------- + +There's four reads in a row of input port 3 - 32 possibilities. +But only 14 are valid - two lookup tables are used to decode the inputs. + +For example, for one of input keys game expects data: 0,0,8,0 +It's encoded (in internal lookup table, as well as in inputTab[]) as 0x68 : + - bits 0-4 = data to return (valid values are 1,2,4,8,$10 - only one bit set) + - bits 5-7 = read cycle (1-4) to return above data +All other reads should return 0. + +Also, every other call, code at $21bd must return 0 (2 in 2nd read cycle) +to prevent disabling inputs. + +***************************************************************************/ + +#include "driver.h" +#include "sound/ay8910.h" + +static int inputcnt=0; +static int inputval=0; +static int inputlen=0; +static tilemap *koikoi_tilemap; +static int ioram[8]; + +static const int inputTab[]= { 0x22, 0x64, 0x44, 0x68, 0x30, 0x50, 0x70, 0x48, 0x28, 0x21, 0x41, 0x82, 0x81, 0x42 }; + +static TILE_GET_INFO( get_tile_info ) +{ + int code = videoram[tile_index]|((videoram[tile_index+0x400]<<2)&0x100); + int color = videoram[tile_index+0x400]&0x1f; + int flip =(videoram[tile_index+0x400]&0x80)?(TILEMAP_FLIPX|TILEMAP_FLIPY):0; + + SET_TILE_INFO( 0, code, color, flip); +} + +static WRITE8_HANDLER(vram_w) +{ + videoram[offset]=data; + tilemap_mark_tile_dirty(koikoi_tilemap,offset&0x3ff); +} + +static READ8_HANDLER(vram_r) +{ + return videoram[offset]; +} + +static READ8_HANDLER(input_r) +{ + if(inputcnt<0){ return 0; } + if(!inputcnt) + { + int key=input_port_2_word_r(0,0); + int keyval=0; //we must return 0 (0x2 in 2nd read) to clear 4 bit at $6600 and allow next read + + if(key) + { + while(!(key&1)) { key>>=1; keyval++; } + } + + inputval=inputTab[keyval]&0x1f; + inputlen=inputTab[keyval]>>5; + } + if(inputlen==++inputcnt) //return expected value + { + return inputval^0xff; + } + if(inputcnt>4) //end of cycle + { + inputcnt=-1; + } + return 0xff; //return 0^0xff +} + +static WRITE8_HANDLER(unknown_w) +{ + //unknown... could be input select (player 1 or 2 = fd/fe or ef/df(??) ) +} + +static READ8_HANDLER(io_r) +{ + if(!offset) + { + return input_port_1_r(0)^ioram[4]; //coin + } + return 0; +} + +static WRITE8_HANDLER(io_w) +{ + if(offset==7 && data==0) + { + inputcnt=0; //reset read cycle counter + } + ioram[offset]=data; +} + +static ADDRESS_MAP_START( readmem, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x2fff) AM_ROM + AM_RANGE(0x6000, 0x67ff) AM_RAM + AM_RANGE(0x8000, 0x8000) AM_READ( input_port_0_r ) + AM_RANGE(0x7000, 0x77ff) AM_READWRITE(vram_r, vram_w) AM_BASE(&videoram) + AM_RANGE(0x9000, 0x9007) AM_READWRITE(io_r, io_w) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( readport, ADDRESS_SPACE_IO, 8 ) + ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) + AM_RANGE(0x02, 0x02) AM_WRITENOP //unknown , many writes + AM_RANGE(0x03, 0x03) AM_READ( AY8910_read_port_0_r ) + AM_RANGE(0x07, 0x07) AM_WRITE(AY8910_control_port_0_w) + AM_RANGE(0x06, 0x06) AM_WRITE(AY8910_write_port_0_w) + +ADDRESS_MAP_END + +static INPUT_PORTS_START( koikoi ) + PORT_START /* DSW */ + PORT_DIPNAME( 0x03, 0x01, "Timer C" ) + PORT_DIPSETTING( 0x00, "50" ) + PORT_DIPSETTING( 0x01, "70" ) + PORT_DIPSETTING( 0x02, "90" ) + PORT_DIPSETTING( 0x03, "110" ) + + PORT_DIPNAME( 0x0c, 0x04, "Timer M" ) + PORT_DIPSETTING( 0x00, "120" ) + PORT_DIPSETTING( 0x04, "150" ) + PORT_DIPSETTING( 0x08, "180" ) + PORT_DIPSETTING( 0x0c, "210" ) + + PORT_DIPNAME( 0x10, 0x00, DEF_STR( Coin_A ) ) + PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x10, DEF_STR( 1C_2C ) ) + + PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x20, DEF_STR( On ) ) + + PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x40, DEF_STR( On ) ) + + PORT_DIPNAME( 0x80, 0x00, "Test Mode" ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x80, DEF_STR( On ) ) + + PORT_START /* IN0 */ + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_COIN1 ) + PORT_BIT( 0xbf, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START /* IN1 */ + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_A) //1 + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_S) //2 + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_D) //3 + PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_F) //4 + PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_G) //5 + PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_H) //6 + PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_J) //7 + PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_K) //8 + + PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_Z) + PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_X) + PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_C) + + PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_START1 ) + PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_START2 ) + +INPUT_PORTS_END + +static PALETTE_INIT( koikoi ) //wrong +{ + int i; + + for (i = 0;i < 256;i++) + { + int bit0,bit1,bit2,bit3,r,g,b; + + bit0 = (color_prom[i] >> 0) & 0x01; + bit1 = (color_prom[i] >> 1) & 0x01; + bit2 = (color_prom[i] >> 2) & 0x01; + bit3 = (color_prom[i] >> 3) & 0x01; + + r=bit0*255; + g=bit1*255; + b=bit2*255; + + palette_set_color(machine,i,MAKE_RGB(r,g,b)); + } +} + +static VIDEO_START(koikoi) +{ + koikoi_tilemap = tilemap_create(get_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32); +} + +static VIDEO_UPDATE(koikoi) +{ + tilemap_draw(bitmap,cliprect,koikoi_tilemap,0,0); + return 0; +} + + +static const gfx_layout tilelayout = +{ + 8, 8, + RGN_FRAC(1,3), + 3, + { RGN_FRAC(0,3), RGN_FRAC(1,3), RGN_FRAC(2,3) }, + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, + 8*8 +}; + + +static GFXDECODE_START( koikoi ) + GFXDECODE_ENTRY( REGION_GFX1, 0x0000, tilelayout, 0, 32 ) +GFXDECODE_END + + +static struct AY8910interface ay8910_interface = +{ + 0, input_r, + unknown_w, 0 +}; + +#define KOIKOI_CRYSTAL 15468000 + +static MACHINE_DRIVER_START( koikoi ) + + /* basic machine hardware */ + MDRV_CPU_ADD(Z80,KOIKOI_CRYSTAL/4) /* ?? */ + MDRV_CPU_PROGRAM_MAP(readmem, 0) + MDRV_CPU_IO_MAP(readport, 0) + MDRV_CPU_VBLANK_INT(nmi_line_pulse,1) + + MDRV_SCREEN_REFRESH_RATE(60) + MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) + + /* video hardware */ + MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MDRV_SCREEN_SIZE(32*8, 32*8) + MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1) + MDRV_GFXDECODE(koikoi) + MDRV_PALETTE_LENGTH(8*32) + MDRV_PALETTE_INIT(koikoi) + + MDRV_VIDEO_START(koikoi) + MDRV_VIDEO_UPDATE(koikoi) + + /* sound hardware */ + MDRV_SPEAKER_STANDARD_MONO("mono") + + MDRV_SOUND_ADD(AY8910, KOIKOI_CRYSTAL/8) + MDRV_SOUND_CONFIG(ay8910_interface) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.10) + +MACHINE_DRIVER_END + + +/*************************************************************************** + + Game driver(s) + +***************************************************************************/ + + +ROM_START( koikoi ) + ROM_REGION( 0x10000, REGION_CPU1, 0 ) /* code */ + ROM_LOAD( "ic56", 0x0000, 0x1000, CRC(bdc68f9d) SHA1(c45fbc95abb37f750acc1d9f3b35ad0f41af097d) ) + ROM_LOAD( "ic55", 0x1000, 0x1000, CRC(fe09248a) SHA1(c192795678068e387bd406f5cd1c5aba5f5ef66a) ) + ROM_LOAD( "ic54", 0x2000, 0x1000, CRC(925fc57c) SHA1(4c79df92b6617fe84e61359c8e6e3b907b138777) ) + + ROM_REGION( 0x3000, REGION_GFX1, 0 ) /* gfx */ + ROM_LOAD( "ic33", 0x0000, 0x1000, CRC(9e4d563b) SHA1(63664dcffc2eb198a161c73131b95a66b2067424) ) + ROM_LOAD( "ic26", 0x1000, 0x1000, CRC(79cb1e93) SHA1(4d08b3d88727b437673f7a51d47396f19bbc3caa) ) + ROM_LOAD( "ic18", 0x2000, 0x1000, CRC(c209362d) SHA1(0620c19fe72e8407db0f487b6413c5d45ac8046c) ) + + ROM_REGION( 0x0100, REGION_PROMS, 0 ) + ROM_LOAD( "prom.ic23", 0x000, 0x100, CRC(f1d169a6) SHA1(5ee4b1dfe61e8b97a90cc113ba234298189f1a73) ) + + ROM_REGION( 0x0a00, REGION_PLDS, ROMREGION_DISPOSE ) + ROM_LOAD( "pal16r8-10_pink.ic9", 0x0000, 0x0104, CRC(9f8fdb95) SHA1(cdcdb1a6baef18961cf6c75fba0c3aba47f3edbb) ) + ROM_LOAD( "pal16r8-10_green.ic15", 0x0200, 0x0104, CRC(da7b8b95) SHA1(a4eb12f2365ff2b6057e4a2e225e8f879a961d45) ) + ROM_LOAD( "pal16r8a_yellow.ic8", 0x0400, 0x0104, CRC(7d8da540) SHA1(28925d1fb4ef670e9c9d24860b67fdff8791c6a9) ) + ROM_LOAD( "pal16r8a_brown.ic11", 0x0600, 0x0104, CRC(fff46363) SHA1(97f673c862e9d5b12cac283000a779c465c76828) ) + ROM_LOAD( "pal16r8a_red.ic10", 0x0800, 0x0104, CRC(027ad661) SHA1(fa5aafe6deb3a9865498152b92dd3776ea10a51d) ) + +ROM_END + +GAME( 1982, koikoi, 0, koikoi, koikoi, 0, ROT270, "Kiwako", "Koi Koi Part 2", GAME_WRONG_COLORS ) |