diff options
Diffstat (limited to 'src/mame/drivers/littlerb.c')
-rw-r--r-- | src/mame/drivers/littlerb.c | 392 |
1 files changed, 392 insertions, 0 deletions
diff --git a/src/mame/drivers/littlerb.c b/src/mame/drivers/littlerb.c new file mode 100644 index 00000000000..2a803108b77 --- /dev/null +++ b/src/mame/drivers/littlerb.c @@ -0,0 +1,392 @@ +/* Little Robin */ + +/* driver by +Pierpaolo Prazzoli +David Haywood +*/ + +/* + +strange vdp/memory access chip.. +at the moment gfx / palettes etc. get drawn then erased + +maybe it needs read commands working so it knows how many sprites are in +the list? + +maybe the vdp 'commands' can be used to store and get back +write addresses? + +Dip sw.1 +-------- + | Coin 1 | Coin 2 | + 1 2 3 4 5 6 7 8 Coin Play +--------------------------------------------------- + Coins - - - - - - 1 4 + + - - + - - 1 3 + - + - - + - 1 2 + + + - + + - 1 1 + - - + - - + 2 1 + + - + + - + 3 1 + - + + - + + 4 1 + + + + + + + 5 1 + Player - - 2 + + - 3 + - + 4 + + + 5 + + +Dip sw.2 +-------- 1 2 3 4 5 6 7 8 +----------------------------------------------------------- + Demo Sound - Yes + + No + Mode - Test Mode + + Game Mode + Difficulty - - - 0 (Easy) + + - - 1 + - + - 2 (Normal) + + + - 3 + - - + 4 + + - + 5 + - + + 6 + + + + 7 (Hardest) + Bonus - - Every 150000 + + - Every 200000 + - + Every 300000 + + + No Bonus + + +*/ + +#include "driver.h" + +static UINT16 littlerb_vdp_address_low; +static UINT16 littlerb_vdp_address_high; +static UINT16 littlerb_vdp_writemode; +static UINT32 littlerb_write_address; + +static void littlerb_recalc_regs(void) +{ + littlerb_vdp_address_low = littlerb_write_address&0xffff; + littlerb_vdp_address_high = (littlerb_write_address>>16)&0xffff; +} + +static UINT16* littlerb_region1; +static UINT16* littlerb_region2; +static UINT16* littlerb_region3; +static UINT16* littlerb_region4; + + +static void littlerb_data_write(UINT16 data) +{ + UINT32 addr = littlerb_write_address>>4; // is this right? should we shift? + + if (addr>=0x00000000 && addr<=0x0003ffff) + { + addr &= 0x0003ffff; + + // littlerb_region1[addr] = data; + littlerb_region4[addr] = data; // it writes the 'slime' gfx you cover the enemy in with here + // it might be a mirror, or just another area of ram it can + // access but isn't because of the sprite drawing.. + } + else if (addr>=0x00400000 && addr<=0x004007ff) + { + int x; + addr &= 0x7ff; + littlerb_region2[addr] = data; + + for (x=0;x<0x100;x+=3) + { + int r,g,b; + + b = littlerb_region2[x]; + r = littlerb_region2[x+1]; + g = littlerb_region2[x+2]; + + palette_set_color(Machine,x/3,MAKE_RGB(r,g,b)); + } + + + } + else if (addr>=0x0c000000 && addr<=0x0c00001f) + { + addr &= 0x1f; + littlerb_region3[addr] = data; + } + else if (addr>=0x0ffc0000 && addr<=0x0fffffff) + { + addr &=0x3ffff; + littlerb_region4[addr] = data; + + } + else + { + mame_printf_debug("write data %04x to %08x\n",data,addr); + } + + littlerb_write_address+=0x10; + littlerb_recalc_regs(); + +} + + + + +static void littlerb_recalc_address(void) +{ + littlerb_write_address = littlerb_vdp_address_low | littlerb_vdp_address_high<<16; +} + +static READ16_HANDLER( littlerb_vdp_r ) +{ + switch (offset) + { + case 0: + return littlerb_vdp_address_low; + + case 1: + return littlerb_vdp_address_high; + + case 2: + return 0; // data read? -- startup check expects 0 for something.. + + case 3: + return littlerb_vdp_writemode; + } + + return -1; +} + +static WRITE16_HANDLER( littlerb_vdp_w ) +{ + switch (offset) + { + case 0: + littlerb_vdp_address_low = data; + littlerb_recalc_address(); + break; + + case 1: + littlerb_vdp_address_high = data; + littlerb_recalc_address(); + break; + + + case 2: + littlerb_data_write(data); + break; + + case 3: + littlerb_vdp_writemode = data; + break; + + } + +} + +static ADDRESS_MAP_START( littlerb_main, ADDRESS_SPACE_PROGRAM, 16 ) + AM_RANGE(0x000008, 0x000017) AM_WRITENOP + AM_RANGE(0x000020, 0x00002f) AM_WRITENOP + AM_RANGE(0x000070, 0x000073) AM_WRITENOP + AM_RANGE(0x060004, 0x060007) AM_WRITENOP + AM_RANGE(0x000000, 0x0fffff) AM_ROM + AM_RANGE(0x200000, 0x203fff) AM_RAM // main ram? + AM_RANGE(0x7c0000, 0x7c0001) AM_READ(input_port_0_word_r) + AM_RANGE(0x7e0000, 0x7e0001) AM_READ(input_port_1_word_r) + AM_RANGE(0x7e0002, 0x7e0003) AM_READ(input_port_2_word_r) + AM_RANGE(0x700000, 0x700007) AM_READ(littlerb_vdp_r) AM_WRITE(littlerb_vdp_w) + AM_RANGE(0x780000, 0x780001) AM_WRITE(MWA16_NOP) + + /* below are fake.. just to see the data */ + AM_RANGE(0xc00000, 0xc7ffff) AM_RAM AM_BASE(&littlerb_region1) + AM_RANGE(0xd00000, 0xd00fff) AM_RAM AM_BASE(&littlerb_region2) + AM_RANGE(0xe00000, 0xe0003f) AM_RAM AM_BASE(&littlerb_region3) + AM_RANGE(0xf00000, 0xf7ffff) AM_RAM AM_BASE(&littlerb_region4) + + + + +ADDRESS_MAP_END + + +static INPUT_PORTS_START( littlerb ) + PORT_START /* 16bit */ + PORT_DIPNAME( 0x0003, 0x0001, DEF_STR( Lives ) ) + PORT_DIPSETTING( 0x0003, "2" ) + PORT_DIPSETTING( 0x0001, "3" ) + PORT_DIPSETTING( 0x0002, "4" ) + PORT_DIPSETTING( 0x0000, "5" ) + PORT_DIPNAME( 0x001c, 0x0004, DEF_STR( Coin_B ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 5C_1C ) ) + PORT_DIPSETTING( 0x0010, DEF_STR( 4C_1C ) ) + PORT_DIPSETTING( 0x0008, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x0018, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0004, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x0014, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x000c, DEF_STR( 1C_3C ) ) + PORT_DIPSETTING( 0x001c, DEF_STR( 1C_4C ) ) + PORT_DIPNAME( 0x00e0, 0x0020, DEF_STR( Coin_A ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 5C_1C ) ) + PORT_DIPSETTING( 0x0080, DEF_STR( 4C_1C ) ) + PORT_DIPSETTING( 0x0040, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x00c0, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0020, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x00a0, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x0060, DEF_STR( 1C_3C ) ) + PORT_DIPSETTING( 0x00e0, DEF_STR( 1C_4C ) ) + 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, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0800, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, 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_DIPNAME( 0x4000, 0x4000, "GAME/TEST??" ) // changes what gets uploaded + PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + + PORT_START /* 16bit */ + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY 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_START1 ) + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START2 ) + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_DIPNAME( 0x1000, 0x1000, "???" ) + PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START /* 16bit */ + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END + +#if 0 +PALETTE_INIT( littlerb ) +{ + int i; + for(i = 0; i < 256; i++) + palette_set_color(machine,i,MAKE_RGB(i,i,i)); +} +#endif + +static void draw_sprite(mame_bitmap *bitmap, int xsize,int ysize, int offset, int xpos, int ypos ) +{ + UINT16* spritegfx = littlerb_region4; + int x,y; + + for (y=0;y<ysize;y++) + { + for (x=0;x<xsize;x++) + { + int drawxpos, drawypos; + UINT8 pix1 = spritegfx[offset]&0x0f; + UINT8 pix2 = (spritegfx[offset]>>8)&0x0f; + drawxpos = xpos+x*2; + drawypos = ypos+y; + + if ((drawxpos < 320) && (drawypos < 256) && (drawxpos >= 0) && (drawypos >=0)) + { + if(pix1&0xf) *BITMAP_ADDR16(bitmap, drawypos, drawxpos) = pix1; + } + drawxpos++; + if ((drawxpos < 320) && (drawypos < 256) && (drawxpos >= 0) && (drawypos >=0)) + { + if(pix2&0xf) *BITMAP_ADDR16(bitmap, drawypos, drawxpos) = pix2; + } + + offset++; + + offset&=0x3ffff; + } + } +} + +static VIDEO_UPDATE(littlerb) +{ + int x,y,offs, code; + int xsize,ysize; + UINT16* spriteregion = &littlerb_region4[0x400]; + fillbitmap(bitmap, get_black_pen(machine), cliprect); + + /* the spriteram format is something like this .. */ + for (offs=0x26/2;offs<0xc00;offs+=6) // start at 00x26? + { + x = spriteregion[offs+2] & 0x01ff; + ysize = (spriteregion[offs+5] & 0x007f); + y = (spriteregion[offs+3] & 0x01ff); // 1? + xsize = (spriteregion[offs+4] & 0x007f)/2; + + // the code seems to be the same address as the blitter writes + // e.g ffc010000 + code = (spriteregion[offs+0] & 0xfff0)>>4; + code |= (spriteregion[offs+1] & 0x003f)<<12; + draw_sprite(bitmap,xsize,ysize,code,x-8,y-16); + } + + return 0; +} + +static MACHINE_DRIVER_START( littlerb ) + MDRV_CPU_ADD(M68000, 12000000) + MDRV_CPU_PROGRAM_MAP(littlerb_main, 0) + MDRV_CPU_VBLANK_INT(irq4_line_hold,1) + + MDRV_SCREEN_REFRESH_RATE(60) + MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) + + MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MDRV_SCREEN_SIZE(512, 256) + MDRV_SCREEN_VISIBLE_AREA(0*8, 320-1, 0*8, 256-1) + + MDRV_PALETTE_LENGTH(256) + +// MDRV_PALETTE_INIT(littlerb) + MDRV_VIDEO_START(generic_bitmapped) + MDRV_VIDEO_UPDATE(littlerb) +MACHINE_DRIVER_END + +ROM_START( littlerb ) + ROM_REGION( 0x100000, REGION_CPU1, 0 ) /* 68000 Code */ + ROM_LOAD16_BYTE( "roma.u53", 0x00001, 0x80000, CRC(172fbc13) SHA1(cd165ca0d0546e2634cf182dc98004cbfb02cf9f) ) + ROM_LOAD16_BYTE( "romb.u29", 0x00000, 0x80000, CRC(b2fb1d61) SHA1(9a9d7176c241928d07af651e5f7f21d4f019701d) ) + + ROM_REGION( 0x80000, REGION_SOUND1, 0 ) /* sound samples */ + ROM_LOAD16_BYTE( "romc.u26", 0x00001, 0x40000, CRC(f193c5b6) SHA1(95548a40e2b5064c558b36cabbf507d23678b1b2) ) + ROM_LOAD16_BYTE( "romd.u32", 0x00000, 0x40000, CRC(d6b81583) SHA1(b7a63d18a41ccac4d3db9211de0b0cdbc914317a) ) +ROM_END + + +GAME( 1993, littlerb, 0, littlerb, littlerb, 0, ROT0, "TCH", "Little Robin", GAME_NOT_WORKING|GAME_NO_SOUND ) |