Make DECO RM-C3 into a device and use for dec8 games

This commit is contained in:
Bryan McPhail 2017-06-28 10:08:16 -04:00
parent 455fc201af
commit e92e9af132
6 changed files with 434 additions and 98 deletions

View File

@ -1629,6 +1629,8 @@ files {
MAME_DIR .. "src/mame/machine/deco146.h",
MAME_DIR .. "src/mame/video/decbac06.cpp",
MAME_DIR .. "src/mame/video/decbac06.h",
MAME_DIR .. "src/mame/video/decrmc3.cpp",
MAME_DIR .. "src/mame/video/decrmc3.h",
MAME_DIR .. "src/mame/video/deco16ic.cpp",
MAME_DIR .. "src/mame/video/deco16ic.h",
MAME_DIR .. "src/mame/video/decocomn.cpp",
@ -2066,6 +2068,7 @@ files {
MAME_DIR .. "src/mame/includes/ginganin.h",
MAME_DIR .. "src/mame/video/ginganin.cpp",
MAME_DIR .. "src/mame/drivers/homerun.cpp",
MAME_DIR .. "src/mame/drivers/homerun.cpp",
MAME_DIR .. "src/mame/includes/homerun.h",
MAME_DIR .. "src/mame/video/homerun.cpp",
MAME_DIR .. "src/mame/drivers/megasys1.cpp",

View File

@ -567,8 +567,8 @@ WRITE8_MEMBER(dec8_state::flip_screen_w){ flip_screen_set(data); }
static ADDRESS_MAP_START( lastmisn_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x0000, 0x0fff) AM_RAM AM_SHARE("share1")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1800, 0x1800) AM_READ_PORT("IN0")
AM_RANGE(0x1801, 0x1801) AM_READ_PORT("IN1")
AM_RANGE(0x1802, 0x1802) AM_READ_PORT("IN2")
@ -593,8 +593,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( lastmisn_sub_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x0000, 0x0fff) AM_RAM AM_SHARE("share1")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1800, 0x1800) AM_READ_PORT("IN0")
AM_RANGE(0x1801, 0x1801) AM_READ_PORT("IN1")
AM_RANGE(0x1802, 0x1802) AM_READ_PORT("IN2")
@ -613,8 +613,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( shackled_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x0000, 0x0fff) AM_RAM AM_SHARE("share1")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1800, 0x1800) AM_READ_PORT("IN0")
AM_RANGE(0x1801, 0x1801) AM_READ_PORT("IN1")
AM_RANGE(0x1802, 0x1802) AM_READ_PORT("IN2")
@ -637,8 +637,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( shackled_sub_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x0000, 0x0fff) AM_RAM AM_SHARE("share1")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1800, 0x1800) AM_READ_PORT("IN0")
AM_RANGE(0x1801, 0x1801) AM_READ_PORT("IN1")
AM_RANGE(0x1802, 0x1802) AM_READ_PORT("IN2")
@ -664,8 +664,8 @@ static ADDRESS_MAP_START( gondo_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x0000, 0x17ff) AM_RAM
AM_RANGE(0x1800, 0x1fff) AM_RAM_WRITE(dec8_videoram_w) AM_SHARE("videoram")
AM_RANGE(0x2000, 0x27ff) AM_READWRITE(dec8_bg_data_r, dec8_bg_data_w) AM_SHARE("bg_data")
AM_RANGE(0x2800, 0x2bff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x2c00, 0x2fff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x2800, 0x2bff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x2c00, 0x2fff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x3000, 0x37ff) AM_RAM AM_SHARE("spriteram") /* Sprites */
AM_RANGE(0x3800, 0x3800) AM_READ_PORT("DSW0") /* Dip 1 */
AM_RANGE(0x3801, 0x3801) AM_READ_PORT("DSW1") /* Dip 2 */
@ -687,8 +687,8 @@ static ADDRESS_MAP_START( garyoret_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x0000, 0x17ff) AM_RAM
AM_RANGE(0x1800, 0x1fff) AM_RAM_WRITE(dec8_videoram_w) AM_SHARE("videoram")
AM_RANGE(0x2000, 0x27ff) AM_READWRITE(dec8_bg_data_r, dec8_bg_data_w) AM_SHARE("bg_data")
AM_RANGE(0x2800, 0x2bff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x2c00, 0x2fff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x2800, 0x2bff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x2c00, 0x2fff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x3000, 0x37ff) AM_RAM AM_SHARE("spriteram") /* Sprites */
AM_RANGE(0x3800, 0x3800) AM_READ_PORT("DSW0") /* Dip 1 */
AM_RANGE(0x3801, 0x3801) AM_READ_PORT("DSW1") /* Dip 2 */
@ -731,8 +731,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( csilver_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x0000, 0x0fff) AM_RAM AM_SHARE("share1")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1800, 0x1800) AM_READ_PORT("IN1")
AM_RANGE(0x1801, 0x1801) AM_READ_PORT("IN0")
AM_RANGE(0x1803, 0x1803) AM_READ_PORT("IN2")
@ -756,8 +756,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( csilver_sub_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x0000, 0x0fff) AM_RAM AM_SHARE("share1")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1000, 0x13ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x1400, 0x17ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x1803, 0x1803) AM_READ_PORT("IN2")
AM_RANGE(0x1804, 0x1804) AM_READ_PORT("DSW1")
AM_RANGE(0x1800, 0x1804) AM_WRITE(shackled_int_w)
@ -777,7 +777,7 @@ static ADDRESS_MAP_START( oscar_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x2000, 0x27ff) AM_RAM_WRITE(dec8_videoram_w) AM_SHARE("videoram")
AM_RANGE(0x2800, 0x2fff) AM_DEVREADWRITE("tilegen1", deco_bac06_device, pf_data_8bit_r, pf_data_8bit_w)
AM_RANGE(0x3000, 0x37ff) AM_RAM AM_SHARE("spriteram") /* Sprites */
AM_RANGE(0x3800, 0x3bff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x3800, 0x3bff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x3c00, 0x3c00) AM_READ_PORT("IN0")
AM_RANGE(0x3c01, 0x3c01) AM_READ_PORT("IN1")
AM_RANGE(0x3c02, 0x3c02) AM_READ_PORT("IN2") /* VBL & coins */
@ -815,8 +815,8 @@ static ADDRESS_MAP_START( srdarwin_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x1805, 0x1806) AM_WRITE(srdarwin_control_w) /* Scroll & Bank */
AM_RANGE(0x2000, 0x2000) AM_READWRITE(i8751_h_r, dec8_sound_w) /* Sound */
AM_RANGE(0x2001, 0x2001) AM_READWRITE(i8751_l_r, flip_screen_w) /* Flipscreen */
AM_RANGE(0x2800, 0x288f) AM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x3000, 0x308f) AM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x2800, 0x288f) AM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x3000, 0x308f) AM_DEVWRITE("palette", deco_rmc3_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x3800, 0x3800) AM_READ_PORT("DSW0") /* Dip 1 */
AM_RANGE(0x3801, 0x3801) AM_READ_PORT("IN0") /* Player 1 */
AM_RANGE(0x3802, 0x3802) AM_READ_PORT("IN1") /* Player 2 (cocktail) + VBL */
@ -832,7 +832,7 @@ static ADDRESS_MAP_START( cobra_map, AS_PROGRAM, 8, dec8_state )
AM_RANGE(0x1800, 0x1fff) AM_RAM
AM_RANGE(0x2000, 0x27ff) AM_RAM_WRITE(dec8_videoram_w) AM_SHARE("videoram")
AM_RANGE(0x2800, 0x2fff) AM_RAM AM_SHARE("spriteram")
AM_RANGE(0x3000, 0x31ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x3000, 0x31ff) AM_RAM_DEVWRITE("palette", deco_rmc3_device, write) AM_SHARE("palette")
AM_RANGE(0x3200, 0x37ff) AM_WRITEONLY /* Unused */
AM_RANGE(0x3800, 0x3800) AM_READ_PORT("IN0") /* Player 1 */
AM_RANGE(0x3801, 0x3801) AM_READ_PORT("IN1") /* Player 2 */
@ -2019,9 +2019,9 @@ static MACHINE_CONFIG_START( lastmisn )
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", shackled)
MCFG_PALETTE_ADD("palette", 1024)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR_DECO)
MCFG_DEVICE_ADD("palette", DECO_RMC3, 0) // xxxxBBBBGGGGRRRR with custom weighting
MCFG_DECO_RMC3_SET_PALETTE_SIZE(1024)
MCFG_VIDEO_START_OVERRIDE(dec8_state,lastmisn)
/* sound hardware */
@ -2073,9 +2073,9 @@ static MACHINE_CONFIG_START( shackled )
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", shackled)
MCFG_PALETTE_ADD("palette", 1024)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR_DECO)
MCFG_DEVICE_ADD("palette", DECO_RMC3, 0) // xxxxBBBBGGGGRRRR with custom weighting
MCFG_DECO_RMC3_SET_PALETTE_SIZE(1024)
MCFG_VIDEO_START_OVERRIDE(dec8_state,shackled)
/* sound hardware */
@ -2127,9 +2127,9 @@ static MACHINE_CONFIG_START( gondo )
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", gondo)
MCFG_PALETTE_ADD("palette", 1024)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR_DECO)
MCFG_DEVICE_ADD("palette", DECO_RMC3, 0) // xxxxBBBBGGGGRRRR with custom weighting
MCFG_DECO_RMC3_SET_PALETTE_SIZE(1024)
MCFG_VIDEO_START_OVERRIDE(dec8_state,gondo)
/* sound hardware */
@ -2181,9 +2181,9 @@ static MACHINE_CONFIG_START( garyoret )
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", gondo)
MCFG_PALETTE_ADD("palette", 1024)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR_DECO)
MCFG_DEVICE_ADD("palette", DECO_RMC3, 0) // xxxxBBBBGGGGRRRR with custom weighting
MCFG_DECO_RMC3_SET_PALETTE_SIZE(1024)
MCFG_VIDEO_START_OVERRIDE(dec8_state,garyoret)
/* sound hardware */
@ -2239,10 +2239,7 @@ static MACHINE_CONFIG_START( ghostb )
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", ghostb)
MCFG_PALETTE_ADD("palette", 1024)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR_DECO)
MCFG_PALETTE_INIT_OWNER(dec8_state,ghostb)
MCFG_DECO_RMC3_ADD_PROMS("palette","proms",1024) // xxxxBBBBGGGGRRRR with custom weighting
MCFG_VIDEO_START_OVERRIDE(dec8_state,ghostb)
/* sound hardware */
@ -2299,9 +2296,9 @@ static MACHINE_CONFIG_START( csilver )
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", shackled)
MCFG_PALETTE_ADD("palette", 1024)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR_DECO)
MCFG_DEVICE_ADD("palette", DECO_RMC3, 0) // xxxxBBBBGGGGRRRR with custom weighting
MCFG_DECO_RMC3_SET_PALETTE_SIZE(1024)
MCFG_VIDEO_START_OVERRIDE(dec8_state,lastmisn)
/* sound hardware */
@ -2362,9 +2359,9 @@ static MACHINE_CONFIG_START( oscar )
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", oscar)
MCFG_PALETTE_ADD("palette", 512)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR_DECO)
MCFG_DEVICE_ADD("palette", DECO_RMC3, 0) // xxxxBBBBGGGGRRRR with custom weighting
MCFG_DECO_RMC3_SET_PALETTE_SIZE(1024)
MCFG_VIDEO_START_OVERRIDE(dec8_state,oscar)
/* sound hardware */
@ -2408,9 +2405,9 @@ static MACHINE_CONFIG_START( srdarwin )
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", srdarwin)
MCFG_PALETTE_ADD("palette", 144)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR_DECO)
MCFG_DEVICE_ADD("palette", DECO_RMC3, 0) // xxxxBBBBGGGGRRRR with custom weighting
MCFG_DECO_RMC3_SET_PALETTE_SIZE(144)
MCFG_VIDEO_START_OVERRIDE(dec8_state,srdarwin)
/* sound hardware */
@ -2466,9 +2463,9 @@ static MACHINE_CONFIG_START( cobracom )
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", cobracom)
MCFG_PALETTE_ADD("palette", 256)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR_DECO)
MCFG_DEVICE_ADD("palette", DECO_RMC3, 0) // xxxxBBBBGGGGRRRR with custom weighting
MCFG_DECO_RMC3_SET_PALETTE_SIZE(256)
MCFG_VIDEO_START_OVERRIDE(dec8_state,cobracom)
/* sound hardware */

View File

@ -6,6 +6,7 @@
#include "video/decbac06.h"
#include "video/deckarn.h"
#include "video/decmxc06.h"
#include "video/decrmc3.h"
class dec8_state : public driver_device
{
@ -45,7 +46,7 @@ public:
optional_device<deco_karnovsprites_device> m_spritegen_krn;
optional_device<deco_mxc06_device> m_spritegen_mxc;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<deco_rmc3_device> m_palette;
required_device<generic_latch_8_device> m_soundlatch;
/* memory pointers */
@ -148,7 +149,6 @@ public:
DECLARE_VIDEO_START(gondo);
DECLARE_VIDEO_START(garyoret);
DECLARE_VIDEO_START(ghostb);
DECLARE_PALETTE_INIT(ghostb);
DECLARE_VIDEO_START(oscar);
DECLARE_VIDEO_START(srdarwin);
DECLARE_VIDEO_START(cobracom);

View File

@ -46,54 +46,6 @@ sprites.
#include "emu.h"
#include "includes/dec8.h"
/***************************************************************************
Convert the color PROMs into a more useable format.
Real Ghostbusters has two 1024x8 palette PROM, other games in this driver
use palette RAM.
Real Ghostbusters, Cobra Command, Gondomania, Oscar at least are confirmed
to use two custom resistor packs marked DECO RM-C3 to convert the digital
palette for analog output.
Each pack contains two channels with resistor values of 220 ohms,
470 ohms, 1 kohm, 2.2 kohm and 4.8 kohm, however the highest resistance is
not used as these games are only 4 bits per channel.
This leads to weightings per bit of 0xe, 0x1f, 0x43, 0x8f.
***************************************************************************/
PALETTE_INIT_MEMBER(dec8_state,ghostb)
{
const uint8_t *color_prom = memregion("proms")->base();
int i;
for (i = 0; i < palette.entries(); i++)
{
int bit0, bit1, bit2, bit3, r, g, b;
bit0 = (color_prom[i] >> 0) & 0x01;
bit1 = (color_prom[i] >> 1) & 0x01;
bit2 = (color_prom[i] >> 2) & 0x01;
bit3 = (color_prom[i] >> 3) & 0x01;
r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
bit0 = (color_prom[i] >> 4) & 0x01;
bit1 = (color_prom[i] >> 5) & 0x01;
bit2 = (color_prom[i] >> 6) & 0x01;
bit3 = (color_prom[i] >> 7) & 0x01;
g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
bit0 = (color_prom[i + palette.entries()] >> 0) & 0x01;
bit1 = (color_prom[i + palette.entries()] >> 1) & 0x01;
bit2 = (color_prom[i + palette.entries()] >> 2) & 0x01;
bit3 = (color_prom[i + palette.entries()] >> 3) & 0x01;
b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
palette.set_pen_color(i, rgb_t(r, g, b));
}
}
WRITE8_MEMBER(dec8_state::dec8_bg_data_w)
{
m_bg_data[offset] = data;

253
src/mame/video/decrmc3.cpp Normal file
View File

@ -0,0 +1,253 @@
// license:BSD-3-Clause
// copyright-holders:Bryan McPhail
/***************************************************************************
decrmc3.cpp
Data East custom palette device.
***************************************************************************/
#include "emu.h"
#include "decrmc3.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(DECO_RMC3, deco_rmc3_device, "deco_rmc3", "DECO RM-C3 PALETTE")
deco_rmc3_device::deco_rmc3_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, DECO_RMC3, tag, owner, clock),
device_palette_interface(mconfig, *this),
m_entries(0),
m_indirect_entries(0),
m_prom_region(*this, finder_base::DUMMY_TAG),
m_init(deco_rmc3_palette_init_delegate())
{
}
//**************************************************************************
// INITIALIZATION AND CONFIGURATION
//**************************************************************************
void deco_rmc3_device::static_set_init(device_t &device, deco_rmc3_palette_init_delegate init)
{
downcast<deco_rmc3_device &>(device).m_init = init;
}
void deco_rmc3_device::static_set_entries(device_t &device, u32 entries)
{
downcast<deco_rmc3_device &>(device).m_entries = entries;
}
void deco_rmc3_device::static_set_indirect_entries(device_t &device, u32 entries)
{
downcast<deco_rmc3_device &>(device).m_indirect_entries = entries;
}
void deco_rmc3_device::static_set_prom_region(device_t &device, const char *region)
{
downcast<deco_rmc3_device &>(device).m_prom_region.set_tag(region);
}
//**************************************************************************
// GENERIC WRITE HANDLERS
//**************************************************************************
//-------------------------------------------------
// update_for_write - given a write of a given
// length to a given byte offset, update all
// potentially modified palette entries
//-------------------------------------------------
inline void deco_rmc3_device::update_for_write(offs_t byte_offset, int bytes_modified, bool indirect)
{
assert((m_indirect_entries != 0) == indirect);
// determine how many entries were modified
int bpe = m_paletteram.bytes_per_entry();
assert(bpe != 0);
int count = (bytes_modified + bpe - 1) / bpe;
// for each entry modified, fetch the palette data and set the pen color or indirect color
offs_t base = byte_offset / bpe;
for (int index = 0; index < count; index++)
{
if (indirect)
set_indirect_color(base + index, deco_rgb_decoder(read_entry(base + index)));
else
set_pen_color(base + index, deco_rgb_decoder(read_entry(base + index)));
}
}
//-------------------------------------------------
// write - write a byte to the base paletteram
//-------------------------------------------------
WRITE8_MEMBER(deco_rmc3_device::write)
{
m_paletteram.write8(offset, data);
update_for_write(offset, 1);
}
WRITE16_MEMBER(deco_rmc3_device::write)
{
m_paletteram.write16(offset, data, mem_mask);
update_for_write(offset * 2, 2);
}
WRITE32_MEMBER(deco_rmc3_device::write)
{
m_paletteram.write32(offset, data, mem_mask);
update_for_write(offset * 4, 4);
}
READ8_MEMBER(deco_rmc3_device::read)
{
return m_paletteram.read8(offset);
}
READ16_MEMBER(deco_rmc3_device::read)
{
return m_paletteram.read16(offset);
}
READ32_MEMBER(deco_rmc3_device::read)
{
return m_paletteram.read32(offset);
}
//-------------------------------------------------
// write_ext - write a byte to the extended
// paletteram
//-------------------------------------------------
WRITE8_MEMBER(deco_rmc3_device::write_ext)
{
m_paletteram_ext.write8(offset, data);
update_for_write(offset, 1);
}
WRITE16_MEMBER(deco_rmc3_device::write_ext)
{
m_paletteram_ext.write16(offset, data, mem_mask);
update_for_write(offset * 2, 2);
}
//-------------------------------------------------
// write_indirect - write a byte to the base
// paletteram, updating indirect colors
//-------------------------------------------------
WRITE8_MEMBER(deco_rmc3_device::write_indirect)
{
m_paletteram.write8(offset, data);
update_for_write(offset, 1, true);
}
//-------------------------------------------------
// write_ext - write a byte to the extended
// paletteram, updating indirect colors
//-------------------------------------------------
WRITE8_MEMBER(deco_rmc3_device::write_indirect_ext)
{
m_paletteram_ext.write8(offset, data);
update_for_write(offset, 1, true);
}
//**************************************************************************
// DEVICE MANAGEMENT
//**************************************************************************
//-------------------------------------------------
// device_start - start up the device
//-------------------------------------------------
void deco_rmc3_device::device_start()
{
// bind the init function
m_init.bind_relative_to(*owner());
// find the memory, if present
const memory_share *share = memshare(tag());
if (share != nullptr)
{
// find the extended (split) memory, if present
std::string tag_ext = std::string(tag()).append("_ext");
const memory_share *share_ext = memshare(tag_ext.c_str());
// determine bytes per entry and configure
int bytes_per_entry = 2;
if (share_ext == nullptr)
m_paletteram.set(*share, bytes_per_entry);
else
{
m_paletteram.set(*share, bytes_per_entry / 2);
m_paletteram_ext.set(*share_ext, bytes_per_entry / 2);
}
}
// call the initialization helper if present
if (!m_init.isnull())
m_init(*this);
}
// This conversion mimics the specific weighting used by the Data East
// custom resistor pack marked DECO RM-C3 to convert the digital
// palette for analog output. It is used on games such as The Real
// Ghostbusters, Gondomania, Cobra Command, Psychonics Oscar.
//
// Resistor values are 220 ohms (MSB), 470 ohms, 1 kohm, 2.2 kohm (LSB)
void deco_rmc3_device::palette_init_proms(deco_rmc3_device &palette)
{
if (!m_prom_region.found())
throw emu_fatalerror("Unable to find color PROM region '%s'.", m_prom_region.finder_tag());
const u8 *colors = m_prom_region->base();
for (int i = 0; i < palette.entries(); i++)
{
u8 r = colors[i]&0xf;
u8 g = (colors[i]>>4)&0xf;
u8 b = colors[i + palette.entries()]&0xf;
r = 0x0e * BIT(r,0) + 0x1f * BIT(r,1) + 0x43 * BIT(r,2) + 0x8f * BIT(r,3);
g = 0x0e * BIT(g,0) + 0x1f * BIT(g,1) + 0x43 * BIT(g,2) + 0x8f * BIT(g,3);
b = 0x0e * BIT(b,0) + 0x1f * BIT(b,1) + 0x43 * BIT(b,2) + 0x8f * BIT(b,3);
palette.set_pen_color(i, rgb_t(r,g,b));
}
}
rgb_t deco_rmc3_device::deco_rgb_decoder(u32 raw)
{
u8 r = raw&0xf;
u8 g = (raw>>4)&0xf;
u8 b = (raw>>8)&0xf;
r = 0x0e * BIT(r,0) + 0x1f * BIT(r,1) + 0x43 * BIT(r,2) + 0x8f * BIT(r,3);
g = 0x0e * BIT(g,0) + 0x1f * BIT(g,1) + 0x43 * BIT(g,2) + 0x8f * BIT(g,3);
b = 0x0e * BIT(b,0) + 0x1f * BIT(b,1) + 0x43 * BIT(b,2) + 0x8f * BIT(b,3);
return rgb_t(r, g, b);
}

131
src/mame/video/decrmc3.h Normal file
View File

@ -0,0 +1,131 @@
// license:BSD-3-Clause
// copyright-holders:Bryan McPhail
/***************************************************************************
decrmc3.h
Data East custom palette device.
****************************************************************************
Data East RM-C3 is a custom resistor pack used to convert a digital
palette to an analog output. The conversion is non-linear with high bits
weighted a little more than low bits compared to linear.
******************************************************************************/
#pragma once
#ifndef MAME_VIDEO_DECORMC3_H
#define MAME_VIDEO_DECORMC3_H
//**************************************************************************
// DEVICE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_DECO_RMC3_ADD(_tag, _entries) \
MCFG_DEVICE_ADD(_tag, DECO_RMC3, 0) \
MCFG_DECO_RMC3_SET_PALETTE_SIZE(_entries)
#define MCFG_DECO_RMC3_MODIFY MCFG_DEVICE_MODIFY
#define MCFG_DECO_RMC3_SET_PALETTE_SIZE(_entries) \
deco_rmc3_device::static_set_entries(*device, _entries);
#define MCFG_DECO_RMC3_INDIRECT_ENTRIES(_entries) \
deco_rmc3_device::static_set_indirect_entries(*device, _entries);
// other standard palettes
#define MCFG_DECO_RMC3_ADD_PROMS(_tag, _region, _entries) \
MCFG_DECO_RMC3_ADD(_tag, _entries) \
deco_rmc3_device::static_set_prom_region(*device, "^" _region); \
deco_rmc3_device::static_set_init(*device, deco_rmc3_palette_init_delegate(FUNC(deco_rmc3_device::palette_init_proms), downcast<deco_rmc3_device *>(device)));
//#define MCFG_DECO_RMC3_INIT_OWNER(_class, _method)
// deco_rmc3_device::static_set_init(*device, deco_rmc3_palette_init_delegate(&_class::PALETTE_INIT_NAME(_method), #_class "::palette_init_" #_method, downcast<_class *>(owner)));
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// device type definition
DECLARE_DEVICE_TYPE(DECO_RMC3, deco_rmc3_device)
typedef device_delegate<void (deco_rmc3_device &)> deco_rmc3_palette_init_delegate;
class deco_rmc3_device : public device_t, public device_palette_interface
{
public:
// construction/destruction
deco_rmc3_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// static configuration
static void static_set_init(device_t &device, deco_rmc3_palette_init_delegate init);
static void static_set_membits(device_t &device, int membits);
static void static_set_endianness(device_t &device, endianness_t endianness);
static void static_set_entries(device_t &device, u32 entries);
static void static_set_indirect_entries(device_t &device, u32 entries);
static void static_set_prom_region(device_t &device, const char *region);
// palette RAM accessors
memory_array &basemem() { return m_paletteram; }
memory_array &extmem() { return m_paletteram_ext; }
// raw entry reading
u32 read_entry(pen_t pen) const
{
u32 data = m_paletteram.read(pen);
if (m_paletteram_ext.base() != nullptr)
data |= m_paletteram_ext.read(pen) << (8 * m_paletteram.bytes_per_entry());
return data;
}
// generic read/write handlers
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
DECLARE_WRITE8_MEMBER(write_ext);
DECLARE_WRITE8_MEMBER(write_indirect);
DECLARE_WRITE8_MEMBER(write_indirect_ext);
DECLARE_READ16_MEMBER(read);
DECLARE_WRITE16_MEMBER(write);
DECLARE_WRITE16_MEMBER(write_ext);
DECLARE_READ32_MEMBER(read);
DECLARE_WRITE32_MEMBER(write);
void palette_init_proms(deco_rmc3_device &palette);
// helper to update palette when data changed
void update() { if (!m_init.isnull()) m_init(*this); }
protected:
// device-level overrides
virtual void device_start() override;
// device_palette_interface overrides
virtual u32 palette_entries() const override { return m_entries; }
virtual u32 palette_indirect_entries() const override { return m_indirect_entries; }
private:
void update_for_write(offs_t byte_offset, int bytes_modified, bool indirect = false);
rgb_t deco_rgb_decoder(u32 raw);
// configuration state
u32 m_entries; // number of entries in the palette
u32 m_indirect_entries; // number of indirect colors in the palette
// bool m_enable_shadows; // are shadows enabled?
// bool m_enable_hilights; // are hilights enabled?
// int m_membits; // width of palette RAM, if different from native
// bool m_membits_supplied; // true if membits forced in static config
// endianness_t m_endianness; // endianness of palette RAM, if different from native
// bool m_endianness_supplied; // true if endianness forced in static config
optional_memory_region m_prom_region; // region where the color PROMs are
deco_rmc3_palette_init_delegate m_init;
// palette RAM
memory_array m_paletteram; // base memory
memory_array m_paletteram_ext; // extended memory
};
#endif // MAME_VIDEO_DECORMC3_H