From b3f415334dc38f5da3b344230252b0154e4b5a39 Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 22 Feb 2018 22:31:46 +0900 Subject: deco_mlc.* Updates (#3233) * deco_mlc.* Updates Cleanup unuseds/duplicates Add notes, Add Sprite drawing when 8bpp and alpha using simultaneously Implement alpha/shadow selectable bits Demote Skull Fang with MACHINE_IMPERFECT_GRAPHICS, Because these blending, raster effect features isn't fully emulated currently Correct game name/region related each ROM versions * deco_mlc : Minor spacing fix * deco_mlc: Updates Fix spacing, Add notes, Minor cleanup, Implement more blending mode * deco_mlc : Change m_mainCpuIsArm to m_irqLevel for when discovered non-DECO156 CPU Games with different IRQ pin is connected Accurate shadowMode * deco_mlc : Minor cleanup, Revert some cleanup functions skullfng : Restore MACHINE_NOT_WORKING flag because random hangs when playing sif * deco_mlc : Apply previous commit * deco_mlc : Fix notes --- src/mame/drivers/deco_mlc.cpp | 145 +++++++++++++++++++++++------------------- src/mame/includes/deco_mlc.h | 64 +++++++++---------- src/mame/video/deco_mlc.cpp | 128 +++++++++++++++++-------------------- 3 files changed, 172 insertions(+), 165 deletions(-) diff --git a/src/mame/drivers/deco_mlc.cpp b/src/mame/drivers/deco_mlc.cpp index 681b9304a37..fd8cf69c1c8 100644 --- a/src/mame/drivers/deco_mlc.cpp +++ b/src/mame/drivers/deco_mlc.cpp @@ -89,11 +89,17 @@ Stadium Hero contains a '146' protection chip on the ROM/CPU pcb, but it is barely used by the game (only checked at startup). See decoprot.c - Driver todo: + Driver TODO: stadhr96 - protection? issues (or 156 co-processor? or timing?) avengrgs - doesn't generate enough line interrupts? ddream95 seems to have a dual screen mode(??) hoops** - crash entering test mode (regression from 0.113 era?) + skullfng - slowdowns not verified from real PCB, Random hangs sometimes + + Graphic TODO: + blending, raster effect features isn't fully emulated currently + Not verified : Can sprites effect 8bpp and alpha blending simultaneously? + Not verified what palette highest bits actually doing Driver by Bryan McPhail, bmcphail@tendril.co.uk, thank you to Avedis and The Guru. @@ -108,6 +114,7 @@ #include "cpu/sh/sh2.h" #include "speaker.h" +#include /***************************************************************************/ @@ -163,7 +170,7 @@ READ32_MEMBER(deco_mlc_state::mlc_scanline_r) } -WRITE32_MEMBER(deco_mlc_state::avengrs_eprom_w) +WRITE32_MEMBER(deco_mlc_state::eeprom_w) { if (ACCESSING_BITS_8_15) { uint8_t ebyte=(data>>8)&0xff; @@ -182,30 +189,44 @@ WRITE32_MEMBER(deco_mlc_state::avengrs_eprom_w) logerror("%s: eprom_w %08x mask %08x\n",machine().describe_context(),data,mem_mask); } -WRITE32_MEMBER(deco_mlc_state::avengrs_palette_w) -{ - COMBINE_DATA(&m_generic_paletteram_32[offset]); - /* x bbbbb ggggg rrrrr */ - m_palette->set_pen_color(offset,pal5bit(m_generic_paletteram_32[offset] >> 0),pal5bit(m_generic_paletteram_32[offset] >> 5),pal5bit(m_generic_paletteram_32[offset] >> 10)); -} - - TIMER_DEVICE_CALLBACK_MEMBER(deco_mlc_state::interrupt_gen) { // logerror("hit scanline IRQ %d (%08x)\n", m_screen->vpos(), info.i); - m_maincpu->set_input_line(m_mainCpuIsArm ? ARM_IRQ_LINE : 1, HOLD_LINE); + m_maincpu->set_input_line(m_irqLevel, HOLD_LINE); } -WRITE32_MEMBER(deco_mlc_state::mlc_irq_w) +WRITE32_MEMBER(deco_mlc_state::irq_ram_w) { // int scanline=m_screen->vpos(); COMBINE_DATA(&m_irq_ram[offset]); + /* + TODO : Accurate this from real PCB + Word 0 : Used but Unknown + skullfng : 0x00000cf3 + hoops** : 0xffffdfff + avengrgs : 0x00000cd3 + stadhr96 : 0x000028f3 + + Word 1 : 0xc0 at shadow, 0x00 at alpha, Other bits unknown + skullfng : 0x000000c0 or 0x00000000 + hoops** : 0xfffffffc + avengrgs : 0xffffffff + stadhr96 : 0x0000fcc0 + + Word 2 : Used but unknown + skullfng : 0x00200008 + hoops** : 0x00000000 + avengrgs : 0x00000000 + stadhr96 : 0x00200008 + + Word 3 : Unknown(Always 0) + */ switch (offset*4) { case 0x10: /* IRQ ack. Value written doesn't matter */ - m_maincpu->set_input_line(m_mainCpuIsArm ? ARM_IRQ_LINE : 1, CLEAR_LINE); + m_maincpu->set_input_line(m_irqLevel, CLEAR_LINE); return; case 0x14: /* Prepare scanline interrupt */ if(m_irq_ram[0x14/4] == -1) // TODO: likely to be anything that doesn't fit into the screen v-pos range. @@ -223,15 +244,7 @@ WRITE32_MEMBER(deco_mlc_state::mlc_irq_w) } - -READ32_MEMBER(deco_mlc_state::mlc_vram_r) -{ - return m_mlc_vram[offset]&0xffff; -} - - - -READ32_MEMBER( deco_mlc_state::mlc_spriteram_r ) +READ32_MEMBER( deco_mlc_state::spriteram_r ) { uint32_t retdata = 0; @@ -242,14 +255,14 @@ READ32_MEMBER( deco_mlc_state::mlc_spriteram_r ) if (ACCESSING_BITS_0_15) { - retdata |= m_mlc_spriteram[offset]; + retdata |= m_spriteram[offset]; } return retdata; } -WRITE32_MEMBER( deco_mlc_state::mlc_spriteram_w ) +WRITE32_MEMBER( deco_mlc_state::spriteram_w ) { if (ACCESSING_BITS_16_31) { @@ -258,7 +271,7 @@ WRITE32_MEMBER( deco_mlc_state::mlc_spriteram_w ) if (ACCESSING_BITS_0_15) { data &=0x0000ffff; - COMBINE_DATA(&m_mlc_spriteram[offset]); + COMBINE_DATA(&m_spriteram[offset]); } } @@ -284,45 +297,45 @@ WRITE16_MEMBER( deco_mlc_state::sh96_protection_region_0_146_w ) ADDRESS_MAP_START(deco_mlc_state::avengrgs_map) AM_RANGE(0x0000000, 0x00fffff) AM_ROM AM_MIRROR(0xff000000) - AM_RANGE(0x0100000, 0x011ffff) AM_RAM AM_SHARE("mlc_ram") AM_MIRROR(0xff000000) + AM_RANGE(0x0100000, 0x011ffff) AM_RAM AM_SHARE("mainram") AM_MIRROR(0xff000000) AM_RANGE(0x0200000, 0x0200003) AM_READ(mlc_200000_r) AM_MIRROR(0xff000000) AM_RANGE(0x0200004, 0x0200007) AM_READ(mlc_200004_r) AM_MIRROR(0xff000000) AM_RANGE(0x0200070, 0x0200073) AM_READ(mlc_200070_r) AM_MIRROR(0xff000000) AM_RANGE(0x0200074, 0x0200077) AM_READ(mlc_scanline_r) AM_MIRROR(0xff000000) AM_RANGE(0x020007c, 0x020007f) AM_READ(mlc_20007c_r) AM_MIRROR(0xff000000) - AM_RANGE(0x0200000, 0x020007f) AM_WRITE(mlc_irq_w) AM_SHARE("irq_ram") AM_MIRROR(0xff000000) - AM_RANGE(0x0200080, 0x02000ff) AM_RAM AM_SHARE("mlc_clip_ram") AM_MIRROR(0xff000000) - AM_RANGE(0x0204000, 0x0206fff) AM_READWRITE( mlc_spriteram_r, mlc_spriteram_w ) AM_MIRROR(0xff000000) - AM_RANGE(0x0280000, 0x029ffff) AM_RAM AM_SHARE("mlc_vram") AM_MIRROR(0xff000000) - AM_RANGE(0x0300000, 0x0307fff) AM_RAM_WRITE(avengrs_palette_w) AM_SHARE("paletteram") AM_MIRROR(0xff000000) + AM_RANGE(0x0200000, 0x020007f) AM_WRITE(irq_ram_w) AM_SHARE("irq_ram") AM_MIRROR(0xff000000) + AM_RANGE(0x0200080, 0x02000ff) AM_RAM AM_SHARE("clip_ram") AM_MIRROR(0xff000000) + AM_RANGE(0x0204000, 0x0206fff) AM_READWRITE( spriteram_r, spriteram_w ) AM_MIRROR(0xff000000) + AM_RANGE(0x0280000, 0x029ffff) AM_RAM AM_SHARE("vram") AM_MIRROR(0xff000000) + AM_RANGE(0x0300000, 0x0307fff) AM_DEVREADWRITE16("palette", palette_device, read16, write16, 0x0000ffff).cswidth(32) AM_SHARE("palette") AM_MIRROR(0xff000000) AM_RANGE(0x0400000, 0x0400003) AM_READ_PORT("INPUTS") AM_MIRROR(0xff000000) AM_RANGE(0x0440000, 0x0440003) AM_READ_PORT("INPUTS2") AM_MIRROR(0xff000000) AM_RANGE(0x0440004, 0x0440007) AM_READ_PORT("INPUTS3") AM_MIRROR(0xff000000) AM_RANGE(0x0440008, 0x044000b) AM_READ(mlc_440008_r) AM_MIRROR(0xff000000) AM_RANGE(0x044001c, 0x044001f) AM_READWRITE(mlc_44001c_r, mlc_44001c_w) AM_MIRROR(0xff000000) - AM_RANGE(0x0500000, 0x0500003) AM_WRITE(avengrs_eprom_w) AM_MIRROR(0xff000000) + AM_RANGE(0x0500000, 0x0500003) AM_WRITE(eeprom_w) AM_MIRROR(0xff000000) AM_RANGE(0x0600000, 0x0600007) AM_DEVREADWRITE8("ymz", ymz280b_device, read, write, 0xff000000) AM_MIRROR(0xff000000) ADDRESS_MAP_END ADDRESS_MAP_START(deco_mlc_state::decomlc_map) AM_RANGE(0x0000000, 0x00fffff) AM_ROM - AM_RANGE(0x0100000, 0x011ffff) AM_RAM AM_SHARE("mlc_ram") + AM_RANGE(0x0100000, 0x011ffff) AM_RAM AM_SHARE("mainram") AM_RANGE(0x0200000, 0x0200003) AM_READ(mlc_200000_r) AM_RANGE(0x0200004, 0x0200007) AM_READ(mlc_200004_r) AM_RANGE(0x0200070, 0x0200073) AM_READ(mlc_200070_r) AM_RANGE(0x0200074, 0x0200077) AM_READ(mlc_scanline_r) AM_RANGE(0x020007c, 0x020007f) AM_READ(mlc_20007c_r) - AM_RANGE(0x0200000, 0x020007f) AM_WRITE(mlc_irq_w) AM_SHARE("irq_ram") - AM_RANGE(0x0200080, 0x02000ff) AM_RAM AM_SHARE("mlc_clip_ram") - AM_RANGE(0x0204000, 0x0206fff) AM_READWRITE( mlc_spriteram_r, mlc_spriteram_w ) - AM_RANGE(0x0280000, 0x029ffff) AM_RAM AM_SHARE("mlc_vram") - AM_RANGE(0x0300000, 0x0307fff) AM_RAM_WRITE(avengrs_palette_w) AM_SHARE("paletteram") + AM_RANGE(0x0200000, 0x020007f) AM_WRITE(irq_ram_w) AM_SHARE("irq_ram") + AM_RANGE(0x0200080, 0x02000ff) AM_RAM AM_SHARE("clip_ram") + AM_RANGE(0x0204000, 0x0206fff) AM_READWRITE( spriteram_r, spriteram_w ) + AM_RANGE(0x0280000, 0x029ffff) AM_RAM AM_SHARE("vram") + AM_RANGE(0x0300000, 0x0307fff) AM_DEVREADWRITE16("palette", palette_device, read16, write16, 0x0000ffff).cswidth(32) AM_SHARE("palette") AM_RANGE(0x0400000, 0x0400003) AM_READ_PORT("INPUTS") AM_RANGE(0x0440000, 0x0440003) AM_READ_PORT("INPUTS2") AM_RANGE(0x0440004, 0x0440007) AM_READ_PORT("INPUTS3") AM_RANGE(0x0440008, 0x044000b) AM_READ(mlc_440008_r) AM_RANGE(0x044001c, 0x044001f) AM_READWRITE(mlc_44001c_r, mlc_44001c_w) - AM_RANGE(0x0500000, 0x0500003) AM_WRITE(avengrs_eprom_w) + AM_RANGE(0x0500000, 0x0500003) AM_WRITE(eeprom_w) AM_RANGE(0x0600000, 0x0600007) AM_DEVREADWRITE8("ymz", ymz280b_device, read, write, 0xff000000) AM_RANGE(0x070f000, 0x070ffff) AM_READWRITE16(sh96_protection_region_0_146_r, sh96_protection_region_0_146_w, 0xffff0000) ADDRESS_MAP_END @@ -510,12 +523,14 @@ MACHINE_CONFIG_START(deco_mlc_state::avengrgs) MCFG_SCREEN_REFRESH_RATE(58) MCFG_SCREEN_SIZE(40*8, 32*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1) - MCFG_SCREEN_UPDATE_DRIVER(deco_mlc_state, screen_update_mlc) + MCFG_SCREEN_UPDATE_DRIVER(deco_mlc_state, screen_update) MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(deco_mlc_state, screen_vblank_mlc)) MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_SCANLINE) MCFG_GFXDECODE_ADD("gfxdecode", "palette", deco_mlc) MCFG_PALETTE_ADD("palette", 2048) + MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR) + MCFG_PALETTE_MEMBITS(16) MCFG_VIDEO_START_OVERRIDE(deco_mlc_state,mlc) @@ -543,12 +558,14 @@ MACHINE_CONFIG_START(deco_mlc_state::mlc) MCFG_SCREEN_REFRESH_RATE(58) MCFG_SCREEN_SIZE(40*8, 32*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1) - MCFG_SCREEN_UPDATE_DRIVER(deco_mlc_state, screen_update_mlc) + MCFG_SCREEN_UPDATE_DRIVER(deco_mlc_state, screen_update) MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(deco_mlc_state, screen_vblank_mlc)) MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_SCANLINE) MCFG_GFXDECODE_ADD("gfxdecode", "palette", deco_mlc) MCFG_PALETTE_ADD("palette", 2048) + MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR) + MCFG_PALETTE_MEMBITS(16) MCFG_VIDEO_START_OVERRIDE(deco_mlc_state,mlc) @@ -595,7 +612,7 @@ Notes: mode, reading as 8 bit gave a good read. Others read in 16 bit mode) */ -ROM_START( avengrgs ) +ROM_START( avengrgs ) // America/Europe Version 1.0, 1996.01.18 ROM_REGION( 0x100000, "maincpu", 0 ) ROM_LOAD32_WORD_SWAP( "sf_00-0.7k", 0x000002, 0x80000, CRC(7d20e2df) SHA1(e8be1751029aea74680ac00cd7f3cf84e1adfc56) ) ROM_LOAD32_WORD_SWAP( "sf_01-0.7l", 0x000000, 0x80000, CRC(f37c0a01) SHA1(8c4e28cde9e93457197b1849e6c9ef9516b5732f) ) @@ -626,7 +643,7 @@ ROM_START( avengrgs ) ROM_LOAD( "avengrgs.nv", 0x00, 0x80, CRC(c0e84b4e) SHA1(e7afca68cc5fa69ded32bc0a1dcc6a59fe7f081b) ) ROM_END -ROM_START( avengrgsj ) +ROM_START( avengrgsj ) // Japan Version 1.2, 1996.01.17 ROM_REGION( 0x100000, "maincpu", 0 ) ROM_LOAD32_WORD_SWAP( "sd_00-2.7k", 0x000002, 0x80000, CRC(136be46a) SHA1(7679f5f78f7983d43ecdb9bdd04e45792a13d9f2) ) ROM_LOAD32_WORD_SWAP( "sd_01-2.7l", 0x000000, 0x80000, CRC(9d87f576) SHA1(dd20cd060d020d81f4e012be10d0211be7526641) ) @@ -873,7 +890,7 @@ void deco_mlc_state::descramble_sound( ) /* the same as simpl156 / heavy smash? */ uint8_t *rom = memregion("ymz")->base(); int length = memregion("ymz")->bytes(); - std::vector buf1(length); + std::vector buf(length); uint32_t x; @@ -888,15 +905,15 @@ void deco_mlc_state::descramble_sound( ) 7, 6, 5, 4, 3, 2, 1 ); - buf1[addr] = rom[x]; + buf[addr] = rom[x]; } - memcpy(rom,&buf1[0],length); + std::copy(buf.begin(),buf.end(),&rom[0]); } READ32_MEMBER(deco_mlc_state::avengrgs_speedup_r) { - uint32_t a=m_mlc_ram[0x89a0/4]; + uint32_t a=m_mainram[0x89a0/4]; uint32_t p=m_maincpu->pc(); if ((p==0x3234 || p==0x32dc) && (a&1)) m_maincpu->spin_until_interrupt(); @@ -913,12 +930,12 @@ DRIVER_INIT_MEMBER(deco_mlc_state,avengrgs) dynamic_cast(m_maincpu.target())->sh2drc_add_pcflush(0x3234); dynamic_cast(m_maincpu.target())->sh2drc_add_pcflush(0x32dc); - dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0100000, 0x01088ff, 0, &m_mlc_ram[0]); - dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0108a00, 0x011ffff, 0, &m_mlc_ram[0x8a00/4]); - dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0200080, 0x02000ff, 0, &m_mlc_clip_ram[0]); - dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0280000, 0x029ffff, 0, &m_mlc_vram[0]); + dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0100000, 0x01088ff, 0, &m_mainram[0]); + dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0108a00, 0x011ffff, 0, &m_mainram[0x8a00/4]); + dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0200080, 0x02000ff, 0, &m_clip_ram[0]); + dynamic_cast(m_maincpu.target())->sh2drc_add_fastram(0x0280000, 0x029ffff, 0, &m_vram[0]); - m_mainCpuIsArm = 0; + m_irqLevel = 1; m_maincpu->space(AS_PROGRAM).install_read_handler(0x01089a0, 0x01089a3, read32_delegate(FUNC(deco_mlc_state::avengrgs_speedup_r),this)); descramble_sound(); } @@ -929,21 +946,21 @@ DRIVER_INIT_MEMBER(deco_mlc_state,mlc) effective clock rate here to compensate otherwise we have slowdowns in Skull Fang where there probably shouldn't be. */ m_maincpu->set_clock_scale(2.0f); - m_mainCpuIsArm = 1; + m_irqLevel = ARM_IRQ_LINE; deco156_decrypt(machine()); descramble_sound(); } /***************************************************************************/ -GAME( 1995, avengrgs, 0, avengrgs, mlc, deco_mlc_state, avengrgs, ROT0, "Data East Corporation", "Avengers In Galactic Storm (US)", 0 ) -GAME( 1995, avengrgsj,avengrgs, avengrgs, mlc, deco_mlc_state, avengrgs, ROT0, "Data East Corporation", "Avengers In Galactic Storm (Japan)", 0 ) -GAME( 1996, stadhr96, 0, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Stadium Hero '96 (World, EAJ)", MACHINE_IMPERFECT_GRAPHICS ) // Rom labels are EAJ ^^ -GAME( 1996, stadhr96u,stadhr96, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Stadium Hero '96 (USA, EAH)", MACHINE_IMPERFECT_GRAPHICS ) // Rom labels are EAH ^^ -GAME( 1996, stadhr96j,stadhr96, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Stadium Hero '96 (Japan, EAD)", MACHINE_IMPERFECT_GRAPHICS ) // Rom labels are EAD (this isn't a Konami region code!) -GAME( 1996, skullfng, 0, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT270, "Data East Corporation", "Skull Fang (World)", 0 ) /* Version 1.13, Europe, Master 96.02.19 */ -GAME( 1996, skullfngj,skullfng, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT270, "Data East Corporation", "Skull Fang (Japan)", 0 ) /* Version 1.09, Japan, Master 96.02.08 */ -GAME( 1996, skullfnga,skullfng, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT270, "Data East Corporation", "Skull Fang (Asia)", 0 ) /* Version 1.13, Asia, Master 96.02.19 */ -GAME( 1996, hoops96, 0, mlc_5bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Hoops '96 (Europe/Asia 2.0)", 0 ) -GAME( 1995, ddream95, hoops96, mlc_5bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Dunk Dream '95 (Japan 1.4, EAM)", 0 ) -GAME( 1995, hoops95, hoops96, mlc_5bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Hoops (Europe/Asia 1.7)", 0 ) +GAME( 1995, avengrgs, 0, avengrgs, mlc, deco_mlc_state, avengrgs, ROT0, "Data East Corporation", "Avengers In Galactic Storm (US/Europe 1.0)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1995, avengrgsj,avengrgs, avengrgs, mlc, deco_mlc_state, avengrgs, ROT0, "Data East Corporation", "Avengers In Galactic Storm (Japan 1.2)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1996, stadhr96, 0, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Stadium Hero '96 (Europe, EAJ)", MACHINE_IMPERFECT_GRAPHICS ) // Rom labels are EAJ ^^ +GAME( 1996, stadhr96u,stadhr96, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Stadium Hero '96 (USA, EAH)", MACHINE_IMPERFECT_GRAPHICS ) // Rom labels are EAH ^^ +GAME( 1996, stadhr96j,stadhr96, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Stadium Hero '96 (Japan, EAD)", MACHINE_IMPERFECT_GRAPHICS ) // Rom labels are EAD (this isn't a Konami region code!) +GAME( 1996, skullfng, 0, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT270, "Data East Corporation", "Skull Fang (Europe 1.13)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* Version 1.13, Europe, Master 96.02.19 13:45 */ +GAME( 1996, skullfngj,skullfng, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT270, "Data East Corporation", "Skull Fang (Japan 1.09)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* Version 1.09, Japan, Master 96.02.08 14:39 */ +GAME( 1996, skullfnga,skullfng, mlc_6bpp, mlc, deco_mlc_state, mlc, ROT270, "Data East Corporation", "Skull Fang (Asia 1.13)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* Version 1.13, Asia, Master 96.02.19 13:49 */ +GAME( 1996, hoops96, 0, mlc_5bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Hoops '96 (Europe/Asia 2.0)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1995, ddream95, hoops96, mlc_5bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Dunk Dream '95 (Japan 1.4, EAM)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1995, hoops95, hoops96, mlc_5bpp, mlc, deco_mlc_state, mlc, ROT0, "Data East Corporation", "Hoops (Europe/Asia 1.7)", MACHINE_IMPERFECT_GRAPHICS ) diff --git a/src/mame/includes/deco_mlc.h b/src/mame/includes/deco_mlc.h index 2634992f76c..3f6282797bb 100644 --- a/src/mame/includes/deco_mlc.h +++ b/src/mame/includes/deco_mlc.h @@ -13,77 +13,77 @@ class deco_mlc_state : public driver_device public: deco_mlc_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_deco146(*this, "ioprot"), - m_mlc_ram(*this, "mlc_ram"), - m_irq_ram(*this, "irq_ram"), - m_mlc_clip_ram(*this, "mlc_clip_ram"), - m_mlc_vram(*this, "mlc_vram"), m_maincpu(*this, "maincpu"), m_eeprom(*this, "eeprom"), m_ymz(*this, "ymz"), m_gfxdecode(*this, "gfxdecode"), m_screen(*this, "screen"), m_palette(*this, "palette"), - m_generic_paletteram_32(*this, "paletteram"), + m_deco146(*this, "ioprot"), + m_mainram(*this, "mainram"), + m_irq_ram(*this, "irq_ram"), + m_clip_ram(*this, "clip_ram"), + m_vram(*this, "vram"), m_gfx2(*this,"gfx2") { } - + + required_device m_maincpu; + required_device m_eeprom; + required_device m_ymz; + required_device m_gfxdecode; + required_device m_screen; + required_device m_palette; optional_device m_deco146; - required_shared_ptr m_mlc_ram; + + required_shared_ptr m_mainram; required_shared_ptr m_irq_ram; - required_shared_ptr m_mlc_clip_ram; - required_shared_ptr m_mlc_vram; + required_shared_ptr m_clip_ram; + required_shared_ptr m_vram; + + required_region_ptr m_gfx2; + timer_device *m_raster_irq_timer; - int m_mainCpuIsArm; + int m_irqLevel; uint32_t m_mlc_raster_table_1[4*256]; uint32_t m_mlc_raster_table_2[4*256]; uint32_t m_mlc_raster_table_3[4*256]; uint32_t m_vbl_i; int m_lastScanline[9]; uint32_t m_colour_mask; + uint32_t m_shadow_mask; + + std::unique_ptr m_spriteram; + std::unique_ptr m_spriteram_spare; + std::unique_ptr m_buffered_spriteram; - std::unique_ptr m_mlc_spriteram; - std::unique_ptr m_mlc_spriteram_spare; - std::unique_ptr m_mlc_buffered_spriteram; DECLARE_READ32_MEMBER(mlc_440008_r); DECLARE_READ32_MEMBER(mlc_44001c_r); DECLARE_WRITE32_MEMBER(mlc_44001c_w); - DECLARE_WRITE32_MEMBER(avengrs_palette_w); DECLARE_READ32_MEMBER(mlc_200000_r); DECLARE_READ32_MEMBER(mlc_200004_r); DECLARE_READ32_MEMBER(mlc_200070_r); DECLARE_READ32_MEMBER(mlc_20007c_r); DECLARE_READ32_MEMBER(mlc_scanline_r); - DECLARE_WRITE32_MEMBER(mlc_irq_w); - DECLARE_READ32_MEMBER(mlc_vram_r); + DECLARE_WRITE32_MEMBER(irq_ram_w); DECLARE_READ32_MEMBER(avengrgs_speedup_r); - DECLARE_WRITE32_MEMBER(avengrs_eprom_w); - DECLARE_READ32_MEMBER(mlc_spriteram_r); - DECLARE_WRITE32_MEMBER(mlc_spriteram_w); - + DECLARE_WRITE32_MEMBER(eeprom_w); + DECLARE_READ32_MEMBER(spriteram_r); + DECLARE_WRITE32_MEMBER(spriteram_w); + DECLARE_READ16_MEMBER( sh96_protection_region_0_146_r ); + DECLARE_WRITE16_MEMBER( sh96_protection_region_0_146_w ); DECLARE_DRIVER_INIT(mlc); DECLARE_DRIVER_INIT(avengrgs); DECLARE_MACHINE_RESET(mlc); DECLARE_VIDEO_START(mlc); - uint32_t screen_update_mlc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); DECLARE_WRITE_LINE_MEMBER(screen_vblank_mlc); TIMER_DEVICE_CALLBACK_MEMBER(interrupt_gen); void draw_sprites( const rectangle &cliprect, int scanline, uint32_t* dest); void descramble_sound( ); - required_device m_maincpu; - required_device m_eeprom; - required_device m_ymz; - required_device m_gfxdecode; - required_device m_screen; - required_device m_palette; - required_shared_ptr m_generic_paletteram_32; - required_region_ptr m_gfx2; - DECLARE_READ16_MEMBER( sh96_protection_region_0_146_r ); - DECLARE_WRITE16_MEMBER( sh96_protection_region_0_146_w ); void mlc(machine_config &config); void mlc_6bpp(machine_config &config); void avengrgs(machine_config &config); diff --git a/src/mame/video/deco_mlc.cpp b/src/mame/video/deco_mlc.cpp index a97b1c2e10d..85f066de120 100644 --- a/src/mame/video/deco_mlc.cpp +++ b/src/mame/video/deco_mlc.cpp @@ -13,27 +13,24 @@ #include "emu.h" #include "includes/deco_mlc.h" +#include + /******************************************************************************/ VIDEO_START_MEMBER(deco_mlc_state,mlc) { - if (m_gfxdecode->gfx(0)->granularity()==16) - m_colour_mask=0x7f; - else if (m_gfxdecode->gfx(0)->granularity()==32) - m_colour_mask=0x3f; - else - m_colour_mask=0x1f; + int max_color = (0x800 / m_gfxdecode->gfx(0)->granularity()); + m_colour_mask=max_color - 1; + m_shadow_mask=max_color << 1; // temp_bitmap = std::make_unique(512, 512 ); - m_mlc_buffered_spriteram = std::make_unique(0x3000/2); - m_mlc_spriteram_spare = std::make_unique(0x3000/2); - m_mlc_spriteram = std::make_unique(0x3000/2); - - - save_pointer(NAME(m_mlc_spriteram.get()), 0x3000/2); - save_pointer(NAME(m_mlc_spriteram_spare.get()), 0x3000/2); - save_pointer(NAME(m_mlc_buffered_spriteram.get()), 0x3000/2); + m_buffered_spriteram = std::make_unique(0x3000/4); + m_spriteram_spare = std::make_unique(0x3000/4); + m_spriteram = std::make_unique(0x3000/4); + save_pointer(NAME(m_spriteram.get()), 0x3000/4); + save_pointer(NAME(m_spriteram_spare.get()), 0x3000/4); + save_pointer(NAME(m_buffered_spriteram.get()), 0x3000/4); } @@ -41,9 +38,10 @@ static void mlc_drawgfxzoomline(deco_mlc_state *state, uint32_t* dest,const rectangle &clip,gfx_element *gfx, uint32_t code1,uint32_t code2, uint32_t color,int flipx,int sx, int transparent_color,int use8bpp, - int scalex, int alpha, int srcline ) + int scalex, int alpha, int srcline, int shadowMode, int alphaMode ) { if (!scalex) return; + uint32_t shadowval = shadowMode ? 0xffffffff : 0; /* scalex and scaley are 16.16 fixed point numbers @@ -55,7 +53,6 @@ static void mlc_drawgfxzoomline(deco_mlc_state *state, /* KW 991012 -- Added code to force clip to bitmap boundary */ - int sprite_screen_width = (scalex*16+(sx&0xffff))>>16; sx>>=16; @@ -78,8 +75,6 @@ static void mlc_drawgfxzoomline(deco_mlc_state *state, x_index_base = 0; } - - if( sx < clip.min_x) { /* clip left */ int pixels = clip.min_x-sx; @@ -97,14 +92,12 @@ static void mlc_drawgfxzoomline(deco_mlc_state *state, { /* skip if inner loop doesn't draw anything */ const pen_t *pal = &state->m_palette->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors())); const uint8_t *code_base1 = gfx->get_data(code1 % gfx->elements()); - + const uint8_t *code_base2 = gfx->get_data(code2 % gfx->elements()); + const uint8_t *source1 = code_base1 + (srcline) * gfx->rowbytes(); + const uint8_t *source2 = code_base2 + (srcline) * gfx->rowbytes(); /* no alpha */ - if (alpha == 0xff) + if ((alpha == 0xff) && (!shadowMode)) { - const uint8_t *code_base2 = gfx->get_data(code2 % gfx->elements()); - const uint8_t *source1 = code_base1 + (srcline) * gfx->rowbytes(); - const uint8_t *source2 = code_base2 + (srcline) * gfx->rowbytes(); - int x, x_index = x_index_base; for( x=sx; xrowbytes(); - + { /* TODO : 8bpp and alpha can use simultaneously? */ int x, x_index = x_index_base; for( x=sx; x>16]; - if( c != transparent_color ) dest[x] = alpha_blend_r32(dest[x], 0, alpha); //pal[c]); + int c = source1[x_index>>16]; + if (use8bpp) + c=(c<<4)|source2[x_index>>16]; + + // alphaMode & 0xc0 = 0xc0 : Shadow, 0 : Alpha, Other bits unknown + if( c != transparent_color ) dest[x] = alpha_blend_r32(dest[x], (alphaMode & 0xc0) ? shadowval : pal[c], shadowMode ? 0x80 : alpha); x_index += dx; } } @@ -150,18 +145,19 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint int hibits=0; int tileFormat=0; int rasterMode=0; + int shadowMode=0; int clipper=0; rectangle user_clip; - uint16_t* mlc_spriteram=m_mlc_buffered_spriteram.get(); // spriteram32 + uint16_t* spriteram=m_buffered_spriteram.get(); //printf("%d - (%08x %08x %08x) (%08x %08x %08x) (%08x %08x %08x)\n", scanline, m_irq_ram[6], m_irq_ram[7], m_irq_ram[8], m_irq_ram[9], m_irq_ram[10], m_irq_ram[11] , m_irq_ram[12] , m_irq_ram[13] , m_irq_ram[14]); for (offs = (0x3000/4)-8; offs>=0; offs-=8) { - if ((mlc_spriteram[offs+0]&0x8000)==0) + if ((spriteram[offs+0]&0x8000)==0) continue; - if ((mlc_spriteram[offs+1]&0x2000) && (m_screen->frame_number() & 1)) + if ((spriteram[offs+1]&0x2000) && (m_screen->frame_number() & 1)) continue; /* @@ -203,17 +199,17 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint Word 3: 0xffff - Low-bits of tile index */ - y = mlc_spriteram[offs+2]&0x7ff; - x = mlc_spriteram[offs+3]&0x7ff; + y = spriteram[offs+2]&0x7ff; + x = spriteram[offs+3]&0x7ff; if (x&0x400) x=-(0x400-(x&0x3ff)); if (y&0x400) y=-(0x400-(y&0x3ff)); - fx = mlc_spriteram[offs+1]&0x8000; - fy = mlc_spriteram[offs+1]&0x4000; - color = mlc_spriteram[offs+1]&0xff; + fx = spriteram[offs+1]&0x8000; + fy = spriteram[offs+1]&0x4000; + color = spriteram[offs+1]&0xff; - int raster_select = (mlc_spriteram[offs+1]&0x0180)>>7; + int raster_select = (spriteram[offs+1]&0x0180)>>7; // there are 3 different sets of raster values, must be a way to selects @@ -225,17 +221,14 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint // have the scroll effect applied to them. all clip windows are the same // so there is no reason to select a clip window other than to be using it // to select a set of raster-set scroll regs? - rasterMode = (mlc_spriteram[offs+1]>>10)&0x1; - - + rasterMode = (spriteram[offs+1]>>10)&0x1; + clipper = (spriteram[offs+1]>>8)&0x3; - clipper = (mlc_spriteram[offs+1]>>8)&0x3; - - indx = mlc_spriteram[offs+0]&0x3fff; - yscale = mlc_spriteram[offs+4]&0x3ff; - xscale = mlc_spriteram[offs+5]&0x3ff; + indx = spriteram[offs+0]&0x3fff; + yscale = spriteram[offs+4]&0x3ff; + xscale = spriteram[offs+5]&0x3ff; colorOffset = 0; /* Clip windows - this mapping seems odd, but is correct for Skull Fang and StadHr96, @@ -243,17 +236,15 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint clipper=((clipper&2)>>1)|((clipper&1)<<1); // Swap low two bits - - int upperclip = (mlc_spriteram[offs+1]>>10)&0x2; + int upperclip = (spriteram[offs+1]>>10)&0x2; // this is used on some ingame gfx in stadhr96 // to clip the images of your guys on the bases if (upperclip) clipper |= 0x4; - - int min_y = m_mlc_clip_ram[(clipper*4)+0]; - int max_y = m_mlc_clip_ram[(clipper*4)+1]; + int min_y = m_clip_ram[(clipper*4)+0]; + int max_y = m_clip_ram[(clipper*4)+1]; if (scanline=0) { - color = (mlc_spriteram[offs+1-8]&0x7f); - indx2 = mlc_spriteram[offs+0-8]&0x3fff; + color = (spriteram[offs+1-8]&0x7f); + indx2 = spriteram[offs+0-8]&0x3fff; } } else use8bppMode=0; /* Lookup tiles/size in sprite index ram OR in the lookup rom */ - if (mlc_spriteram[offs+0]&0x4000) { + if (spriteram[offs+0]&0x4000) { index_ptr8=rom + indx*8; /* Byte ptr */ h=(index_ptr8[1]>>0)&0xf; w=(index_ptr8[3]>>0)&0xf; @@ -319,7 +312,7 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint } else { indx&=0x1fff; - index_ptr=m_mlc_vram + indx*4; + index_ptr=m_vram + indx*4; h=(index_ptr[0]>>8)&0xf; w=(index_ptr[1]>>8)&0xf; @@ -327,7 +320,7 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint if (!w) w=16; if (use8bppMode) { - uint32_t* index_ptr2=m_mlc_vram + ((indx2*4)&0x7fff); + uint32_t* index_ptr2=m_vram + ((indx2*4)&0x7fff); sprite2=((index_ptr2[2]&0x3)<<16) | (index_ptr2[3]&0xffff); } @@ -373,6 +366,7 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint if (raster_select==1 || raster_select==2 || raster_select==3) { + shadowMode = 0; // TODO : Raster enable and shadow mode can't use simultaneously? int irq_base_reg; /* 6, 9, 12 are possible */ if (raster_select== 1) irq_base_reg = 6; // OK upper screen.. left? else if (raster_select== 2) irq_base_reg = 9; // OK upper screen.. main / center @@ -393,7 +387,6 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint { // possibly disabled? } - } xscale *= extra_x_scale; @@ -505,7 +498,7 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint } else { - const uint32_t* ptr=m_mlc_vram + ((tile)&0x7fff); + const uint32_t* ptr=m_vram + ((tile)&0x7fff); tile=(*ptr)&0xffff; if (tileFormat) @@ -528,7 +521,8 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint tile,tile2, color + colorOffset,fx,realxbase, 0, - use8bppMode,(xscale),alpha, srcline); + use8bppMode,(xscale),alpha, srcline, + shadowMode, m_irq_ram[0x04/4]); } @@ -547,19 +541,15 @@ WRITE_LINE_MEMBER(deco_mlc_state::screen_vblank_mlc) lookup table. Without buffering incorrect one frame glitches are seen in several places, especially in Hoops. */ - memcpy(m_mlc_buffered_spriteram.get(), m_mlc_spriteram.get(), 0x3000/2); + std::copy(&m_spriteram[0], &m_spriteram[0x3000/4], &m_buffered_spriteram[0]); } } -uint32_t deco_mlc_state::screen_update_mlc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +uint32_t deco_mlc_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { // temp_bitmap->fill(0, cliprect); bitmap.fill(m_palette->pen(0), cliprect); /* Pen 0 fill colour confirmed from Skull Fang level 2 */ - - - - for (int i=cliprect.min_y;i<=cliprect.max_y;i++) { uint32_t *dest = &bitmap.pix32(i); -- cgit v1.2.3