summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author cam900 <dbtlrchl@naver.com>2018-02-22 22:31:46 +0900
committer Vas Crabb <cuavas@users.noreply.github.com>2018-02-23 00:31:46 +1100
commitb3f415334dc38f5da3b344230252b0154e4b5a39 (patch)
treef8e5e6bd3b3cc4f90da416d0c32a296fc3702760
parentd53fed6b1e7e334d49bc02472a18ac27ebbe3e3c (diff)
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
-rw-r--r--src/mame/drivers/deco_mlc.cpp145
-rw-r--r--src/mame/includes/deco_mlc.h64
-rw-r--r--src/mame/video/deco_mlc.cpp128
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 <algorithm>
/***************************************************************************/
@@ -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<uint8_t> buf1(length);
+ std::vector<uint8_t> 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<sh2_device *>(m_maincpu.target())->sh2drc_add_pcflush(0x3234);
dynamic_cast<sh2_device *>(m_maincpu.target())->sh2drc_add_pcflush(0x32dc);
- dynamic_cast<sh2_device *>(m_maincpu.target())->sh2drc_add_fastram(0x0100000, 0x01088ff, 0, &m_mlc_ram[0]);
- dynamic_cast<sh2_device *>(m_maincpu.target())->sh2drc_add_fastram(0x0108a00, 0x011ffff, 0, &m_mlc_ram[0x8a00/4]);
- dynamic_cast<sh2_device *>(m_maincpu.target())->sh2drc_add_fastram(0x0200080, 0x02000ff, 0, &m_mlc_clip_ram[0]);
- dynamic_cast<sh2_device *>(m_maincpu.target())->sh2drc_add_fastram(0x0280000, 0x029ffff, 0, &m_mlc_vram[0]);
+ dynamic_cast<sh2_device *>(m_maincpu.target())->sh2drc_add_fastram(0x0100000, 0x01088ff, 0, &m_mainram[0]);
+ dynamic_cast<sh2_device *>(m_maincpu.target())->sh2drc_add_fastram(0x0108a00, 0x011ffff, 0, &m_mainram[0x8a00/4]);
+ dynamic_cast<sh2_device *>(m_maincpu.target())->sh2drc_add_fastram(0x0200080, 0x02000ff, 0, &m_clip_ram[0]);
+ dynamic_cast<sh2_device *>(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<cpu_device> m_maincpu;
+ required_device<eeprom_serial_93cxx_device> m_eeprom;
+ required_device<ymz280b_device> m_ymz;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<screen_device> m_screen;
+ required_device<palette_device> m_palette;
optional_device<deco146_device> m_deco146;
- required_shared_ptr<uint32_t> m_mlc_ram;
+
+ required_shared_ptr<uint32_t> m_mainram;
required_shared_ptr<uint32_t> m_irq_ram;
- required_shared_ptr<uint32_t> m_mlc_clip_ram;
- required_shared_ptr<uint32_t> m_mlc_vram;
+ required_shared_ptr<uint32_t> m_clip_ram;
+ required_shared_ptr<uint32_t> m_vram;
+
+ required_region_ptr<uint8_t> 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<uint16_t[]> m_spriteram;
+ std::unique_ptr<uint16_t[]> m_spriteram_spare;
+ std::unique_ptr<uint16_t[]> m_buffered_spriteram;
- std::unique_ptr<uint16_t[]> m_mlc_spriteram;
- std::unique_ptr<uint16_t[]> m_mlc_spriteram_spare;
- std::unique_ptr<uint16_t[]> 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<cpu_device> m_maincpu;
- required_device<eeprom_serial_93cxx_device> m_eeprom;
- required_device<ymz280b_device> m_ymz;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<screen_device> m_screen;
- required_device<palette_device> m_palette;
- required_shared_ptr<uint32_t> m_generic_paletteram_32;
- required_region_ptr<uint8_t> 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 <algorithm>
+
/******************************************************************************/
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<bitmap_rgb32>(512, 512 );
- m_mlc_buffered_spriteram = std::make_unique<uint16_t[]>(0x3000/2);
- m_mlc_spriteram_spare = std::make_unique<uint16_t[]>(0x3000/2);
- m_mlc_spriteram = std::make_unique<uint16_t[]>(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<uint16_t[]>(0x3000/4);
+ m_spriteram_spare = std::make_unique<uint16_t[]>(0x3000/4);
+ m_spriteram = std::make_unique<uint16_t[]>(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; x<ex; x++ )
@@ -119,14 +112,16 @@ static void mlc_drawgfxzoomline(deco_mlc_state *state,
}
}
else
- {
- const uint8_t *source = code_base1 + (srcline) * gfx->rowbytes();
-
+ { /* TODO : 8bpp and alpha can use simultaneously? */
int x, x_index = x_index_base;
for( x=sx; x<ex; x++ )
{
- int c = source[x_index>>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<min_y)
continue;
@@ -262,31 +253,33 @@ void deco_mlc_state::draw_sprites( const rectangle &cliprect, int scanline, uint
continue;
- user_clip.min_x=m_mlc_clip_ram[(clipper*4)+2];
- user_clip.max_x=m_mlc_clip_ram[(clipper*4)+3];
+ user_clip.min_x=m_clip_ram[(clipper*4)+2];
+ user_clip.max_x=m_clip_ram[(clipper*4)+3];
user_clip &= cliprect;
/* Any colours out of range (for the bpp value) trigger 'shadow' mode */
- if (color & (m_colour_mask+1))
+ shadowMode = (color & (m_shadow_mask)) ? 1 : 0; // shadow mode (OK for skullfng)
+ if ((color & (m_colour_mask+1)) || (shadowMode))
alpha=0x80;
else
alpha=0xff;
+
color&=m_colour_mask;
/* If this bit is set, combine this block with the next one */
- if (mlc_spriteram[offs+1]&0x1000) {
+ if (spriteram[offs+1]&0x1000) {
use8bppMode=1;
/* In 8bpp the palette base is stored in the next block */
if (offs-8>=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);