From b30d6d96f9e61c80cb8fe6ea4e135ec6fe00951a Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 25 Jan 2018 14:21:51 +0900 Subject: Split Data East ACE Chip Emulation (#3100) * Split Data East ACE Chip Emulation * Add deco_ace.cpp * Update deco_ace.cpp * Update deco_ace.h * Update boogwing.h * Update boogwing.cpp alpha blend/palette effect improvements * Update boogwing.cpp * Update deco_ace.cpp * Update deco32.h * Update deco32.cpp split DECO ACE Emulation * Update deco32.cpp * Update deco32.cpp * Update deco_ace.cpp * Copyright holder / some update. Demote Boogie Wings with MACHINE_IMPERFECT_GRAPHICS * Typo * Typo(2) * Revert copyright holder, nw * deco_ace.cpp : doc update * deco_ace.cpp : revert copyright holder, update docs, convert multiplicative fade algorithm to fixed point, implement additive fading effect. deco32.cpp : update docs boogwing.cpp : update alpha blending notes * deco_ace : Revert "convert multiplicative fade algorithm to fixed point" --- scripts/target/mame/arcade.lua | 2 + src/mame/drivers/boogwing.cpp | 54 ++++---- src/mame/drivers/deco32.cpp | 24 ++-- src/mame/includes/boogwing.h | 11 +- src/mame/includes/deco32.h | 10 +- src/mame/video/boogwing.cpp | 19 +-- src/mame/video/deco32.cpp | 93 +------------- src/mame/video/deco_ace.cpp | 271 +++++++++++++++++++++++++++++++++++++++++ src/mame/video/deco_ace.h | 74 +++++++++++ 9 files changed, 422 insertions(+), 136 deletions(-) create mode 100644 src/mame/video/deco_ace.cpp create mode 100644 src/mame/video/deco_ace.h diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 9620917c985..1236e464c3f 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -1553,6 +1553,8 @@ files { MAME_DIR .. "src/mame/includes/deco32.h", MAME_DIR .. "src/mame/video/deco32.cpp", MAME_DIR .. "src/mame/video/dvi.cpp", + MAME_DIR .. "src/mame/video/deco_ace.cpp", + MAME_DIR .. "src/mame/video/deco_ace.h", MAME_DIR .. "src/mame/video/deco_zoomspr.cpp", MAME_DIR .. "src/mame/video/deco_zoomspr.h", MAME_DIR .. "src/mame/drivers/decocass.cpp", diff --git a/src/mame/drivers/boogwing.cpp b/src/mame/drivers/boogwing.cpp index 6aa6059e59a..6f148c43135 100644 --- a/src/mame/drivers/boogwing.cpp +++ b/src/mame/drivers/boogwing.cpp @@ -53,12 +53,15 @@ Driver by Bryan McPhail and David Haywood. + DECO 99 "ACE" Chip hooked up by cam900. + Todo: * Sprite priorities aren't verified to be 100% accurate. (Addendum - all known issues seem to be correct - see Sprite Priority Notes below). * There may be some kind of fullscreen palette effect (controlled by bit 3 in priority word - used at end of each level, and on final boss). * A shadow effect (used in level 1) is not implemented. + * ACE Chip aren't fully emulated. Sprite Priority Notes: * On the Imperial Science Museum level at the beginning, you fly behind a wall, but your @@ -93,6 +96,8 @@ #include "screen.h" #include "speaker.h" +#define MAIN_XTAL XTAL(28'000'000) +#define SOUND_XTAL XTAL(32'220'000) READ16_MEMBER( boogwing_state::boogwing_protection_region_0_104_r ) { @@ -111,12 +116,18 @@ WRITE16_MEMBER( boogwing_state::boogwing_protection_region_0_104_w ) m_deco104->write_data( space, deco146_addr, data, mem_mask, cs ); } +WRITE16_MEMBER( boogwing_state::priority_w ) +{ + COMBINE_DATA(&m_priority); + m_deco_ace->set_palette_effect_max((m_priority & 0x8) ? 0x6ff : 0xfff); +} + static ADDRESS_MAP_START( boogwing_map, AS_PROGRAM, 16, boogwing_state ) AM_RANGE(0x000000, 0x0fffff) AM_ROM AM_RANGE(0x200000, 0x20ffff) AM_RAM - AM_RANGE(0x220000, 0x220001) AM_DEVWRITE("deco_common", decocomn_device, priority_w) + AM_RANGE(0x220000, 0x220001) AM_WRITE(priority_w) AM_RANGE(0x220002, 0x22000f) AM_NOP AM_RANGE(0x240000, 0x240001) AM_DEVWRITE("spriteram", buffered_spriteram16_device, write) @@ -143,10 +154,10 @@ static ADDRESS_MAP_START( boogwing_map, AS_PROGRAM, 16, boogwing_state ) AM_RANGE(0x280000, 0x28000f) AM_NOP // ? AM_RANGE(0x282000, 0x282001) AM_NOP // Palette setup? - AM_RANGE(0x282008, 0x282009) AM_DEVWRITE("deco_common", decocomn_device, palette_dma_w) - AM_RANGE(0x284000, 0x285fff) AM_DEVWRITE("deco_common", decocomn_device, buffered_palette_w) AM_SHARE("paletteram") + AM_RANGE(0x282008, 0x282009) AM_DEVWRITE("deco_ace", deco_ace_device, palette_dma_w) + AM_RANGE(0x284000, 0x285fff) AM_DEVREADWRITE("deco_ace", deco_ace_device, buffered_palette16_r, buffered_palette16_w) - AM_RANGE(0x3c0000, 0x3c004f) AM_RAM // ? + AM_RANGE(0x3c0000, 0x3c004f) AM_DEVREADWRITE("deco_ace", deco_ace_device, ace_r, ace_w) ADDRESS_MAP_END static ADDRESS_MAP_START( decrypted_opcodes_map, AS_OPCODES, 16, boogwing_state ) @@ -300,6 +311,11 @@ GFXDECODE_END /**********************************************************************************/ +void boogwing_state::machine_reset() +{ + m_priority = 0; +} + WRITE8_MEMBER(boogwing_state::sound_bankswitch_w) { m_oki2->set_rom_bank((data & 2) >> 1); @@ -324,31 +340,27 @@ DECO16IC_BANK_CB_MEMBER(boogwing_state::bank_callback2) MACHINE_CONFIG_START(boogwing_state::boogwing) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", M68000, 14000000) /* DE102 */ + MCFG_CPU_ADD("maincpu", M68000, MAIN_XTAL/2) /* DE102 */ MCFG_CPU_PROGRAM_MAP(boogwing_map) MCFG_CPU_DECRYPTED_OPCODES_MAP(decrypted_opcodes_map) MCFG_CPU_VBLANK_INT_DRIVER("screen", boogwing_state, irq6_line_hold) - MCFG_CPU_ADD("audiocpu", H6280, 32220000/4) + MCFG_CPU_ADD("audiocpu", H6280, SOUND_XTAL/4) MCFG_CPU_PROGRAM_MAP(audio_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(58) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) - MCFG_SCREEN_SIZE(40*8, 32*8) - MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1) + MCFG_SCREEN_RAW_PARAMS(MAIN_XTAL / 4, 442, 0, 320, 274, 8, 248) // same as robocop2(cninja.cpp)? verify this from real pcb. MCFG_SCREEN_UPDATE_DRIVER(boogwing_state, screen_update_boogwing) MCFG_PALETTE_ADD("palette", 2048) MCFG_GFXDECODE_ADD("gfxdecode", "palette", boogwing) - MCFG_BUFFERED_SPRITERAM16_ADD("spriteram") MCFG_BUFFERED_SPRITERAM16_ADD("spriteram2") - MCFG_DECOCOMN_ADD("deco_common") - MCFG_DECOCOMN_PALETTE("palette") + MCFG_DECO_ACE_ADD("deco_ace") + MCFG_DECO_ACE_PALETTE("palette") MCFG_DEVICE_ADD("tilegen1", DECO16IC, 0) MCFG_DECO16IC_SPLIT(0) @@ -399,17 +411,17 @@ MACHINE_CONFIG_START(boogwing_state::boogwing) /* sound hardware */ MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") - MCFG_YM2151_ADD("ymsnd", 32220000/9) + MCFG_YM2151_ADD("ymsnd", SOUND_XTAL/9) MCFG_YM2151_IRQ_HANDLER(INPUTLINE("audiocpu", 1)) /* IRQ2 */ MCFG_YM2151_PORT_WRITE_HANDLER(WRITE8(boogwing_state, sound_bankswitch_w)) MCFG_SOUND_ROUTE(0, "lspeaker", 0.80) MCFG_SOUND_ROUTE(1, "rspeaker", 0.80) - MCFG_OKIM6295_ADD("oki1", 32220000/32, PIN7_HIGH) + MCFG_OKIM6295_ADD("oki1", SOUND_XTAL/32, PIN7_HIGH) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.40) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.40) - MCFG_OKIM6295_ADD("oki2", 32220000/16, PIN7_HIGH) + MCFG_OKIM6295_ADD("oki2", SOUND_XTAL/16, PIN7_HIGH) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.30) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.30) MACHINE_CONFIG_END @@ -649,8 +661,8 @@ DRIVER_INIT_MEMBER(boogwing_state,boogwing) memcpy(dst, src, 0x100000); } -GAME( 1992, boogwing, 0, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "Boogie Wings (Euro v1.5, 92.12.07)", MACHINE_SUPPORTS_SAVE ) -GAME( 1992, boogwingu,boogwing, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "Boogie Wings (USA v1.7, 92.12.14)", MACHINE_SUPPORTS_SAVE ) -GAME( 1992, boogwinga,boogwing, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "Boogie Wings (Asia v1.5, 92.12.07)", MACHINE_SUPPORTS_SAVE ) -GAME( 1992, ragtime, boogwing, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "The Great Ragtime Show (Japan v1.5, 92.12.07)", MACHINE_SUPPORTS_SAVE ) -GAME( 1992, ragtimea, boogwing, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "The Great Ragtime Show (Japan v1.3, 92.11.26)", MACHINE_SUPPORTS_SAVE ) +GAME( 1992, boogwing, 0, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "Boogie Wings (Euro v1.5, 92.12.07)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1992, boogwingu,boogwing, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "Boogie Wings (USA v1.7, 92.12.14)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1992, boogwinga,boogwing, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "Boogie Wings (Asia v1.5, 92.12.07)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1992, ragtime, boogwing, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "The Great Ragtime Show (Japan v1.5, 92.12.07)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1992, ragtimea, boogwing, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "The Great Ragtime Show (Japan v1.3, 92.11.26)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/deco32.cpp b/src/mame/drivers/deco32.cpp index 3c0a9bcb6e0..0cf5d5d3b3b 100644 --- a/src/mame/drivers/deco32.cpp +++ b/src/mame/drivers/deco32.cpp @@ -34,12 +34,12 @@ Tattoo Assassins uses DE Pinball soundboard 520-5077-00 R - Todo: + TODO: - Tattoo Assassins & Dragongun use an unemulated chip (Ace/Jack) for + Tattoo Assassins & Night slashers use an less emulated chip (Ace/Jack) for special blending effects. It's exact effect is unclear. - Video backgrounds in Dragongun? + Video backgrounds(intel DVI) in Dragongun? Locked'N Loaded (parent set) is a slightly different hardware revision: board # DE-0420-1 where the US set is DE-0359-2. @@ -564,14 +564,14 @@ static ADDRESS_MAP_START( tattass_map, AS_PROGRAM, 32, nslasher_state ) AM_RANGE(0x140000, 0x140003) AM_WRITE(vblank_ack_w) AM_RANGE(0x150000, 0x150003) AM_WRITE(tattass_control_w) /* Volume port/Eprom/Priority */ AM_RANGE(0x162000, 0x162fff) AM_RAM /* 'Jack' RAM!? */ - AM_RANGE(0x163000, 0x16309f) AM_RAM_WRITE(ace_ram_w) AM_SHARE("ace_ram") + AM_RANGE(0x163000, 0x16309f) AM_DEVREADWRITE16("deco_ace", deco_ace_device, ace_r, ace_w, 0x0000ffff) /* 'Ace' RAM */ AM_RANGE(0x164000, 0x164003) AM_WRITENOP /* Palette control BG2/3 ($1a constant) */ AM_RANGE(0x164004, 0x164007) AM_WRITENOP /* Palette control Obj1 ($6 constant) */ AM_RANGE(0x164008, 0x16400b) AM_WRITENOP /* Palette control Obj2 ($5 constant) */ AM_RANGE(0x16400c, 0x16400f) AM_WRITENOP - AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram") + AM_RANGE(0x168000, 0x169fff) AM_DEVREADWRITE("deco_ace", deco_ace_device, buffered_palette_r, buffered_palette_w) AM_RANGE(0x16c000, 0x16c003) AM_WRITENOP - AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(palette_dma_w) + AM_RANGE(0x16c008, 0x16c00b) AM_DEVWRITE16("deco_ace", deco_ace_device, palette_dma_w, 0xffffffff) AM_RANGE(0x170000, 0x171fff) AM_READWRITE(spriteram_r, spriteram_w) AM_RANGE(0x174000, 0x174003) AM_WRITENOP /* Sprite DMA mode (2) */ AM_RANGE(0x174010, 0x174013) AM_WRITE(buffer_spriteram_w) @@ -601,14 +601,14 @@ static ADDRESS_MAP_START( nslasher_map, AS_PROGRAM, 32, nslasher_state ) AM_RANGE(0x140000, 0x140003) AM_WRITE(vblank_ack_w) AM_RANGE(0x150000, 0x150003) AM_WRITE8(eeprom_w, 0x000000ff) AM_RANGE(0x150000, 0x150003) AM_WRITE8(volume_w, 0x0000ff00) - AM_RANGE(0x163000, 0x16309f) AM_RAM_WRITE(ace_ram_w) AM_SHARE("ace_ram") /* 'Ace' RAM!? */ + AM_RANGE(0x163000, 0x16309f) AM_DEVREADWRITE16("deco_ace", deco_ace_device, ace_r, ace_w, 0x0000ffff) /* 'Ace' RAM */ AM_RANGE(0x164000, 0x164003) AM_WRITENOP /* Palette control BG2/3 ($1a constant) */ AM_RANGE(0x164004, 0x164007) AM_WRITENOP /* Palette control Obj1 ($4 constant) */ AM_RANGE(0x164008, 0x16400b) AM_WRITENOP /* Palette control Obj2 ($6 constant) */ AM_RANGE(0x16400c, 0x16400f) AM_WRITENOP - AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram") + AM_RANGE(0x168000, 0x169fff) AM_DEVREADWRITE("deco_ace", deco_ace_device, buffered_palette_r, buffered_palette_w) AM_RANGE(0x16c000, 0x16c003) AM_WRITENOP - AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(palette_dma_w) + AM_RANGE(0x16c008, 0x16c00b) AM_DEVWRITE16("deco_ace", deco_ace_device, palette_dma_w, 0xffffffff) AM_RANGE(0x170000, 0x171fff) AM_READWRITE(spriteram_r, spriteram_w) AM_RANGE(0x174000, 0x174003) AM_WRITENOP /* Sprite DMA mode (2) */ AM_RANGE(0x174010, 0x174013) AM_WRITE(buffer_spriteram_w) @@ -2283,6 +2283,9 @@ MACHINE_CONFIG_START(nslasher_state::tattass) MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_RAW_PARAMS(XTAL(28'000'000) / 4, 442, 0, 320, 274, 8, 248) MCFG_SCREEN_UPDATE_DRIVER(nslasher_state, screen_update_nslasher) + + MCFG_DECO_ACE_ADD("deco_ace") + MCFG_DECO_ACE_PALETTE("palette") MCFG_DEVICE_ADD("tilegen1", DECO16IC, 0) MCFG_DECO16IC_SPLIT(0) @@ -2360,6 +2363,9 @@ MACHINE_CONFIG_START(nslasher_state::nslasher) MCFG_SCREEN_RAW_PARAMS(XTAL(28'322'000) / 4, 442, 0, 320, 274, 8, 248) MCFG_SCREEN_UPDATE_DRIVER(nslasher_state, screen_update_nslasher) + MCFG_DECO_ACE_ADD("deco_ace") + MCFG_DECO_ACE_PALETTE("palette") + MCFG_DEVICE_ADD("tilegen1", DECO16IC, 0) MCFG_DECO16IC_SPLIT(0) MCFG_DECO16IC_WIDTH12(1) diff --git a/src/mame/includes/boogwing.h b/src/mame/includes/boogwing.h index 7a8aa57acd9..2b84d5e146b 100644 --- a/src/mame/includes/boogwing.h +++ b/src/mame/includes/boogwing.h @@ -8,9 +8,8 @@ #include "sound/okim6295.h" #include "video/deco16ic.h" -#include "video/decocomn.h" +#include "video/deco_ace.h" #include "video/bufsprite.h" -#include "video/decocomn.h" #include "video/decospr.h" #include "machine/deco104.h" @@ -22,7 +21,7 @@ public: m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu"), m_deco104(*this, "ioprot"), - m_decocomn(*this, "deco_common"), + m_deco_ace(*this, "deco_ace"), m_deco_tilegen1(*this, "tilegen1"), m_deco_tilegen2(*this, "tilegen2"), m_oki1(*this, "oki1"), @@ -43,7 +42,7 @@ public: required_device m_maincpu; required_device m_audiocpu; optional_device m_deco104; - required_device m_decocomn; + required_device m_deco_ace; required_device m_deco_tilegen1; required_device m_deco_tilegen2; required_device m_oki1; @@ -60,8 +59,12 @@ public: required_device m_palette; required_shared_ptr m_decrypted_opcodes; + uint16_t m_priority; + DECLARE_WRITE8_MEMBER(sound_bankswitch_w); + DECLARE_WRITE16_MEMBER(priority_w); DECLARE_DRIVER_INIT(boogwing); + virtual void machine_reset() override; virtual void video_start() override; uint32_t screen_update_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); diff --git a/src/mame/includes/deco32.h b/src/mame/includes/deco32.h index 4f0b8551adb..f6c52df7853 100644 --- a/src/mame/includes/deco32.h +++ b/src/mame/includes/deco32.h @@ -4,6 +4,7 @@ #include "video/bufsprite.h" #include "video/decospr.h" #include "video/deco16ic.h" +#include "video/deco_ace.h" #include "machine/deco_irq.h" #include "machine/eepromser.h" #include "machine/gen_latch.h" @@ -171,8 +172,9 @@ class nslasher_state : public deco32_state public: nslasher_state(const machine_config &mconfig, device_type type, const char *tag) : deco32_state(mconfig, type, tag), - m_ace_ram(*this, "ace_ram") + m_deco_ace(*this, "deco_ace") { } + required_device m_deco_ace; DECLARE_WRITE32_MEMBER(tattass_control_w); DECLARE_WRITE_LINE_MEMBER(tattass_sound_irq_w); @@ -180,8 +182,6 @@ public: DECLARE_READ32_MEMBER(spriteram2_r); DECLARE_WRITE32_MEMBER(spriteram2_w); DECLARE_WRITE32_MEMBER(buffer_spriteram2_w); - DECLARE_WRITE32_MEMBER(ace_ram_w); - DECLARE_WRITE32_MEMBER(palette_dma_w); DECLARE_DRIVER_INIT(tattass); DECLARE_DRIVER_INIT(nslasher); @@ -196,11 +196,8 @@ public: void tattass(machine_config &config); void nslasher(machine_config &config); private: - void updateAceRam(); void mixDualAlphaSprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx0, gfx_element *gfx1, int mixAlphaTilemap); - required_shared_ptr m_ace_ram; - std::unique_ptr m_tilemap_alpha_bitmap; uint16_t m_spriteram16_2[0x1000]; @@ -213,7 +210,6 @@ private: int m_pendingCommand; int m_readBitCount; int m_byteAddr; - int m_ace_ram_dirty; }; class dragngun_state : public deco32_state diff --git a/src/mame/video/boogwing.cpp b/src/mame/video/boogwing.cpp index 924fb0be30c..4a0ed307585 100644 --- a/src/mame/video/boogwing.cpp +++ b/src/mame/video/boogwing.cpp @@ -7,8 +7,10 @@ void boogwing_state::video_start() { + m_priority = 0; m_sprgen1->alloc_sprite_bitmap(); m_sprgen2->alloc_sprite_bitmap(); + save_item(NAME(m_priority)); } @@ -28,7 +30,7 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c bitmap_ind16 *sprite_bitmap1, *sprite_bitmap2; bitmap_ind8* priority_bitmap; - uint16_t priority = m_decocomn->priority_r(); + uint16_t priority = m_priority; sprite_bitmap1 = &m_sprgen1->get_sprite_temp_bitmap(); sprite_bitmap2 = &m_sprgen2->get_sprite_temp_bitmap(); @@ -58,10 +60,10 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c int pri1, pri2; int spri1, spri2, alpha2; - alpha2 = 0xff; + alpha2 = m_deco_ace->get_alpha((pix2 >> 4) & 0xf); // pix1 sprite vs pix2 sprite - if (pix1 & 0x400) // todo - check only in pri mode 2?? + if (pix1 & 0x400) // TODO - check only in pri mode 2?? spri1 = 8; else spri1 = 32; @@ -100,7 +102,8 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c // Transparency if (pix2 & 0x100) - alpha2 = 0x80; + alpha2 = 0x80; // TODO : Uses 0x10-0x14 of Aceram? + // alpha2 = m_deco_ace->get_alpha(0x14 + ((pix & 0xf0) > 0x50) ? 0x5 : ((pix2 >> 4) & 0x7)); This fixes explosion effects, but this is HACK. // pix2 sprite vs playfield switch (priority) @@ -109,7 +112,7 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c { // Additional sprite alpha in this mode if (pix2 & 0x400) - alpha2 = 0x80; + alpha2 = 0x80; // TODO // Sprite vs playfield if ((pix2 & 0x600) == 0x600) @@ -161,7 +164,7 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c { if ((!drawnpixe1) || (spri2 > spri1)) { - if (alpha2==0xff) + if (alpha2>=0xff) { dstline[x] = paldata[(pix2&0xff)+0x700]; } @@ -181,7 +184,7 @@ uint32_t boogwing_state::screen_update_boogwing(screen_device &screen, bitmap_rg { address_space &space = machine().dummy_space(); uint16_t flip = m_deco_tilegen1->pf_control_r(space, 0, 0xffff); - uint16_t priority = m_decocomn->priority_r(); + uint16_t priority = m_priority; /* Draw sprite planes to bitmaps for later mixing */ m_sprgen2->draw_sprites(bitmap, cliprect, m_spriteram2->buffer(), 0x400, true); @@ -191,6 +194,8 @@ uint32_t boogwing_state::screen_update_boogwing(screen_device &screen, bitmap_rg m_deco_tilegen1->pf_update(m_pf1_rowscroll, m_pf2_rowscroll); m_deco_tilegen2->pf_update(m_pf3_rowscroll, m_pf4_rowscroll); + m_deco_ace->palette_update(); + /* Draw playfields */ bitmap.fill(m_palette->pen(0x400), cliprect); /* pen not confirmed */ screen.priority().fill(0); diff --git a/src/mame/video/deco32.cpp b/src/mame/video/deco32.cpp index 38ba17dcc17..8dd87b22f23 100644 --- a/src/mame/video/deco32.cpp +++ b/src/mame/video/deco32.cpp @@ -22,77 +22,6 @@ WRITE32_MEMBER( dragngun_state::spriteram_dma_w ) memset(m_spriteram->live(),0,0x2000); } -WRITE32_MEMBER( nslasher_state::ace_ram_w ) -{ - /* Some notes pieced together from Tattoo Assassins info: - - Bytes 0 to 0x58 - object alpha control? - Bytes 0x5c to 0x7c - tilemap alpha control - - 0 = opaque, 0x10 = 50% transparent, 0x20 = fully transparent - - Byte 0x00: ACEO000P0 - P8 - 1P0 - 1P8 - O010C1 - o010C8 - ?? - - Hardware fade registers: - - Byte 0x80: fadeptred - Byte 0x84: fadeptgreen - Byte 0x88: fadeptblue - Byte 0x8c: fadestred - Byte 0x90: fadestgreen - Byte 0x94: fadestblue - Byte 0x98: fadetype - - The 'ST' value lerps between the 'PT' value and the palette entries. So, if PT==0, - then ST ranging from 0 to 255 will cause a fade to black (when ST==255 the palette - becomes zero). - - 'fadetype' - 1100 for multiplicative fade, 1000 for additive - */ - if (offset>=(0x80/4) && (data!=m_ace_ram[offset])) - m_ace_ram_dirty=1; - - COMBINE_DATA(&m_ace_ram[offset]); -} - -void nslasher_state::updateAceRam() -{ - int r,g,b,i; - uint8_t fadeptr=m_ace_ram[0x20]; - uint8_t fadeptg=m_ace_ram[0x21]; - uint8_t fadeptb=m_ace_ram[0x22]; - uint8_t fadepsr=m_ace_ram[0x23]; - uint8_t fadepsg=m_ace_ram[0x24]; - uint8_t fadepsb=m_ace_ram[0x25]; -// uint8_t mode=m_ace_ram[0x26]; - - m_ace_ram_dirty=0; - - for (i=0; i<2048; i++) - { - /* Lerp palette entry to 'fadept' according to 'fadeps' */ - b = (m_generic_paletteram_32[i] >>16) & 0xff; - g = (m_generic_paletteram_32[i] >> 8) & 0xff; - r = (m_generic_paletteram_32[i] >> 0) & 0xff; - - if (i>255) /* Screenshots seem to suggest ACE fades do not affect playfield 1 palette (0-255) */ - { - /* Yeah, this should really be fixed point, I know */ - b = (uint8_t)((float)b + (((float)fadeptb - (float)b) * (float)fadepsb/255.0f)); - g = (uint8_t)((float)g + (((float)fadeptg - (float)g) * (float)fadepsg/255.0f)); - r = (uint8_t)((float)r + (((float)fadeptr - (float)r) * (float)fadepsr/255.0f)); - } - - m_palette->set_pen_color(i,rgb_t(r,g,b)); - } -} - /******************************************************************************/ /* Later games have double buffered paletteram - the real palette ram is @@ -121,13 +50,6 @@ WRITE32_MEMBER( deco32_state::palette_dma_w ) } } -WRITE32_MEMBER( nslasher_state::palette_dma_w ) -{ - for (int i = 0; i < m_palette->entries(); i++) - if (m_dirty_palette[i]) - m_ace_ram_dirty = 1; -} - /******************************************************************************/ void deco32_state::video_start() @@ -158,16 +80,12 @@ VIDEO_START_MEMBER( fghthist_state, fghthist ) VIDEO_START_MEMBER( nslasher_state, nslasher ) { int width, height; - m_dirty_palette = std::make_unique(4096); width = m_screen->width(); height = m_screen->height(); m_tilemap_alpha_bitmap=std::make_unique(width, height ); m_sprgen1->alloc_sprite_bitmap(); m_sprgen2->alloc_sprite_bitmap(); - memset(m_dirty_palette.get(),0,4096); - save_pointer(NAME(m_dirty_palette.get()), 4096); - save_item(NAME(m_ace_ram_dirty)); save_item(NAME(m_spriteram16_2)); save_item(NAME(m_spriteram16_2_buffered)); @@ -388,7 +306,7 @@ void nslasher_state::mixDualAlphaSprites(screen_device &screen, bitmap_rgb32 &bi */ /* Alpha values are tied to ACE ram... */ - //int alpha=((m_ace_ram[0x0 + (((priColAlphaPal1&0xf0)>>4)/2)]) * 8)-1; + //int alpha=m_deco_ace->get_alpha(((priColAlphaPal1&0xf0)>>4)/2); //if (alpha<0) // alpha=0; @@ -436,11 +354,11 @@ void nslasher_state::mixDualAlphaSprites(screen_device &screen, bitmap_rgb32 &bi && ((priColAlphaPal1&0xff)==0 || (pri1&0x3)==2 || (pri1&0x3)==3 || alpha1)) { /* Alpha values are tied to ACE ram */ - int alpha=((m_ace_ram[0x17 + (((p&0xf0)>>4)/2)]) * 8)-1; + int alpha=m_deco_ace->get_alpha(0x17 + (((p&0xf0)>>4)/2)); if (alpha<0) alpha=0; - destLine[x]=alpha_blend_r32(destLine[x], pal2[p], 255-alpha); + destLine[x]=alpha_blend_r32(destLine[x], pal2[p], alpha); } } } @@ -455,11 +373,10 @@ uint32_t nslasher_state::screen_update_nslasher(screen_device &screen, bitmap_rg m_deco_tilegen2->pf_update(m_pf3_rowscroll, m_pf4_rowscroll); /* This is not a conclusive test for deciding if tilemap needs alpha blending */ - if (m_ace_ram[0x17]!=0x0 && m_pri) + if (m_deco_ace->get_aceram(0x17)!=0x0 && m_pri) alphaTilemap=1; - if (m_ace_ram_dirty) - updateAceRam(); + m_deco_ace->palette_update(); screen.priority().fill(0, cliprect); diff --git a/src/mame/video/deco_ace.cpp b/src/mame/video/deco_ace.cpp new file mode 100644 index 00000000000..c61e9047a51 --- /dev/null +++ b/src/mame/video/deco_ace.cpp @@ -0,0 +1,271 @@ +// license:BSD-3-Clause +// copyright-holders:Bryan McPhail +/************************************************************************* + + deco_ace.cpp + + Data East 99 "ACE" Chip Emulation + + Original source (from deco32.cpp) by Bryan McPhail, Splited by cam900. + +**************************************************************************/ +/*Some notes pieced together from Tattoo Assassins info(from deco32.cpp): + + Bytes 0 to 0x1f : Alpha Control + Tattoo Assassins : + Bytes 0x00 to 0x16(0x58) - object alpha control? + Bytes 0x17(0x5c) to 0x1f(0x7c) - tilemap alpha control + + Boogie Wings: + Bytes 0x00 to 0x0f(0x1f) - object alpha control (if ((pix & 0x100) == 0)) + Bytes 0x10(0x20) to 0x13(0x26) - another object alpha control? + Bytes 0x14(0x28) to 0x19(0x32) - fixed value 0x1c 0x18 0x14 0x10 0x0c 0x08. it controls explosion object's alpha? + Bytes 0x1a(0x34) to 0x1f(0x3f) - tilemap alpha control? + + 0 = opaque, 0x10 = 50% transparent, 0x20 = fully transparent + + Byte 0x00: ACEO000P0 + P8 + 1P0 + 1P8 + O010C1 + o010C8 + ?? + + Hardware fade registers: + + Byte 0x20(0x80): fadeptred + Byte 0x21(0x84): fadeptgreen + Byte 0x22(0x88): fadeptblue + Byte 0x23(0x8c): fadestred + Byte 0x24(0x90): fadestgreen + Byte 0x25(0x94): fadestblue + Byte 0x26(0x98): fadetype + Byte 0x27(0x9c): unused/unknown + + The 'ST' value lerps between the 'PT' value and the palette entries. So, if PT==0, + then ST ranging from 0 to 255 will cause a fade to black (when ST==255 the palette + becomes zero). + + 'fadetype' - 1100 for multiplicative fade, 1000 for additive + + TODO: + additive fade is correct? verify additive fading from real pcb. +*/ + + +#include "emu.h" +#include "video/deco_ace.h" + + +DEFINE_DEVICE_TYPE(DECO_ACE, deco_ace_device, "deco_ace", "Data East 99 'ACE' Chip") + +deco_ace_device::deco_ace_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, DECO_ACE, tag, owner, clock), + device_video_interface(mconfig, *this), + m_dirty_palette(0), + m_palette_effect_min(0x100), + m_palette_effect_max(0xfff), + m_palette(*this, finder_base::DUMMY_TAG), + m_paletteram(nullptr), + m_paletteram_buffered(nullptr), + m_ace_ram(nullptr) +{ +} + +//------------------------------------------------- +// static_set_palette_tag: Set the tag of the +// palette device +//------------------------------------------------- + +void deco_ace_device::static_set_palette_tag(device_t &device, const char *tag) +{ + downcast(device).m_palette.set_tag(tag); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void deco_ace_device::device_start() +{ + m_paletteram = make_unique_clear(4096); + m_paletteram_buffered = make_unique_clear(4096); + m_ace_ram = make_unique_clear(0x28); + + save_item(NAME(m_dirty_palette)); + save_pointer(NAME(m_paletteram.get()), 4096); + save_pointer(NAME(m_paletteram_buffered.get()), 4096); + save_pointer(NAME(m_ace_ram.get()), 0x28); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void deco_ace_device::device_reset() +{ + m_palette_effect_min = 0x100; /* Screenshots seem to suggest ACE fades do not affect playfield 1 palette (0-255) */ + m_palette_effect_max = 0xfff; + memset(m_ace_ram.get(),0,0x28); + m_dirty_palette = 1; +} + +/***************************************************************************** + DEVICE HANDLERS +*****************************************************************************/ + +/* Games have double buffered paletteram - the real palette ram is +only updated on a DMA call */ + +// nslasher +READ32_MEMBER( deco_ace_device::buffered_palette_r ) +{ + return m_paletteram[offset]; +} + +WRITE32_MEMBER( deco_ace_device::buffered_palette_w ) +{ + COMBINE_DATA(&m_paletteram[offset]); +} + +// boogwing has 16 bit cpu data bus(M68000 Based) +READ16_MEMBER( deco_ace_device::buffered_palette16_r ) +{ + if ((offset & 1) == 0) + return (m_paletteram[offset >> 1] >> 16) & 0xffff; + else + return m_paletteram[offset >> 1] & 0xffff; +} + +WRITE16_MEMBER( deco_ace_device::buffered_palette16_w ) +{ + if ((offset & 1) == 0) + m_paletteram[offset >> 1] = (m_paletteram[offset >> 1] & ~(mem_mask<<16)) | ((data & mem_mask)<<16); + else + m_paletteram[offset >> 1] = (m_paletteram[offset >> 1] & ~mem_mask) | (data & mem_mask); +} + +READ16_MEMBER( deco_ace_device::ace_r ) +{ + return m_ace_ram[offset]; +} + +WRITE16_MEMBER( deco_ace_device::ace_w ) +{ + COMBINE_DATA(&m_ace_ram[offset]); + if ((offset >= 0x20) && (offset <= 0x26)) + m_dirty_palette = 1; +} + +void deco_ace_device::palette_update() +{ + if (m_dirty_palette != 0) + { + int r,g,b,i; + uint8_t fadeptr=m_ace_ram[0x20] & 0xff; + uint8_t fadeptg=m_ace_ram[0x21] & 0xff; + uint8_t fadeptb=m_ace_ram[0x22] & 0xff; + uint8_t fadepsr=m_ace_ram[0x23] & 0xff; + uint8_t fadepsg=m_ace_ram[0x24] & 0xff; + uint8_t fadepsb=m_ace_ram[0x25] & 0xff; + uint16_t mode=m_ace_ram[0x26] & 0xffff; + + m_dirty_palette=0; + + for (i=0; i<2048; i++) + { + /* Lerp palette entry to 'fadept' according to 'fadeps' */ + b = (m_paletteram_buffered[i] >>16) & 0xff; + g = (m_paletteram_buffered[i] >> 8) & 0xff; + r = (m_paletteram_buffered[i] >> 0) & 0xff; + + if ((i>=m_palette_effect_min) && (i<=m_palette_effect_max)) + { + switch (mode) + { + default: + case 0x1100: // multiplicative fade + /* Yeah, this should really be fixed point, I know */ + b = (uint8_t)((float)b + (((float)fadeptb - (float)b) * (float)fadepsb/255.0f)); + g = (uint8_t)((float)g + (((float)fadeptg - (float)g) * (float)fadepsg/255.0f)); + r = (uint8_t)((float)r + (((float)fadeptr - (float)r) * (float)fadepsr/255.0f)); + break; + case 0x1000: // additive fade, correct? + b = b + fadepsb; + g = g + fadepsg; + r = r + fadepsr; + break; + } + + if (b < 0) b = 0; + if (b > 0xff) b = 0xff; + if (g < 0) g = 0; + if (g > 0xff) g = 0xff; + if (r < 0) r = 0; + if (r > 0xff) r = 0xff; + } + + m_palette->set_pen_color(i,rgb_t(r,g,b)); + } + } +} + +/************************************************************************* + + set_palette_effect_max : Change Palette effect max bound (uses boogwing) + +*************************************************************************/ + +void deco_ace_device::set_palette_effect_max(uint32_t val) +{ + if (m_palette_effect_max != val) + { + m_palette_effect_max = val; + m_dirty_palette = 1; + } +} + +/************************************************************************* + + get_alpha : Get alpha value (ACE RAM Area 0x00 - 0x1f) + +*************************************************************************/ + +uint8_t deco_ace_device::get_alpha(uint8_t val) +{ + val &= 0x1f; + int alpha = m_ace_ram[val] & 0xff; + if (alpha > 0x20) + { + return 0x80; // TODO + } + else + { + alpha = 255 - (alpha << 3); + if (alpha < 0) + alpha = 0; + + return (uint8_t)alpha; + } +} + +/************************************************************************* + + get_aceram : Get ACE RAM value + +*************************************************************************/ + +uint16_t deco_ace_device::get_aceram(uint8_t val) +{ + val &= 0x3f; + return m_ace_ram[val]; +} + +WRITE16_MEMBER( deco_ace_device::palette_dma_w ) +{ + memcpy(m_paletteram_buffered.get(), m_paletteram.get(), 4096); + m_dirty_palette = 1; +} + +/*****************************************************************************************/ diff --git a/src/mame/video/deco_ace.h b/src/mame/video/deco_ace.h new file mode 100644 index 00000000000..1dae766fce8 --- /dev/null +++ b/src/mame/video/deco_ace.h @@ -0,0 +1,74 @@ +// license:BSD-3-Clause +// copyright-holders:Bryan McPhail +/************************************************************************* + + deco_ace.h + + Data East 99 "ACE" Chip Emulation + + Original source (from deco32.cpp) by Bryan McPhail, Splited by cam900. + +**************************************************************************/ +#ifndef MAME_VIDEO_DECO_ACE_H +#define MAME_VIDEO_DECO_ACE_H + +#pragma once + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + + +class deco_ace_device : public device_t, + public device_video_interface +{ +public: + deco_ace_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // static configuration + static void static_set_palette_tag(device_t &device, const char *tag); + + DECLARE_READ32_MEMBER( buffered_palette_r ); + DECLARE_READ16_MEMBER( buffered_palette16_r ); + DECLARE_READ16_MEMBER( ace_r ); + DECLARE_WRITE32_MEMBER( buffered_palette_w ); + DECLARE_WRITE16_MEMBER( buffered_palette16_w ); + DECLARE_WRITE16_MEMBER( ace_w ); + void palette_update(); + void set_palette_effect_max(uint32_t val); + uint16_t get_aceram(uint8_t val); + uint8_t get_alpha(uint8_t val); + DECLARE_WRITE16_MEMBER( palette_dma_w ); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + // internal state + uint8_t m_dirty_palette; + uint32_t m_palette_effect_min; + uint32_t m_palette_effect_max; + required_device m_palette; + std::unique_ptr m_paletteram; + std::unique_ptr m_paletteram_buffered; + std::unique_ptr m_ace_ram; +}; + +DECLARE_DEVICE_TYPE(DECO_ACE, deco_ace_device) + + + +/*************************************************************************** + DEVICE CONFIGURATION MACROS +***************************************************************************/ + +#define MCFG_DECO_ACE_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, DECO_ACE, 0) + +#define MCFG_DECO_ACE_PALETTE(_palette_tag) \ + deco_ace_device::static_set_palette_tag(*device, "^" _palette_tag); + +#endif // MAME_VIDEO_DECO_ACE_H -- cgit v1.2.3