add palette dma (RAM to private buffer) to all seibu cop games

moved some of the Raiden 2 cop emulation to a new device (just the memory DMA stuff, including private buffer copy code) and started sharing it with legionna.c in order to avoid code duplication.  We can slowly move other duplicate code over too and eventually kill the old seicop.c
This commit is contained in:
David Haywood 2014-09-15 20:55:32 +00:00
parent 0bf0ae5118
commit 030ae5f67a
13 changed files with 510 additions and 1001 deletions

4
.gitattributes vendored
View File

@ -2948,8 +2948,6 @@ src/emu/machine/s3c24xx.inc svneol=native#text/plain
src/emu/machine/s3c44b0.c svneol=native#text/plain
src/emu/machine/s3c44b0.h svneol=native#text/plain
src/emu/machine/saturn.c svneol=native#text/plain
src/emu/machine/seibu_cop.c svneol=native#text/plain
src/emu/machine/seibu_cop.h svneol=native#text/plain
src/emu/machine/serflash.c svneol=native#text/plain
src/emu/machine/serflash.h svneol=native#text/plain
src/emu/machine/smc91c9x.c svneol=native#text/plain
@ -7019,6 +7017,8 @@ src/mame/machine/playch10.c svneol=native#text/plain
src/mame/machine/pxa255.h svneol=native#text/plain
src/mame/machine/qix.c svneol=native#text/plain
src/mame/machine/r2crypt.c svneol=native#text/plain
src/mame/machine/raiden2cop.c svneol=native#text/plain
src/mame/machine/raiden2cop.h svneol=native#text/plain
src/mame/machine/rainbow.c svneol=native#text/plain
src/mame/machine/retofinv.c svneol=native#text/plain
src/mame/machine/scramble.c svneol=native#text/plain

View File

@ -1409,15 +1409,6 @@ ifneq ($(filter SATURN,$(MACHINES)),)
MACHINEOBJS += $(MACHINEOBJ)/saturn.o
endif
#-------------------------------------------------
#
#@src/emu/machine/seibu_cop.h,MACHINES += SEIBU_COP
#-------------------------------------------------
ifneq ($(filter SEIBU_COP,$(MACHINES)),)
MACHINEOBJS += $(MACHINEOBJ)/seibu_cop.o
endif
#-------------------------------------------------
#
#@src/emu/machine/serflash.h,MACHINES += SERFLASH

View File

@ -1,376 +0,0 @@
// license:MAME
// copyright-holders:Angelo Salese
/***************************************************************************
Seibu COP protection device
(this header needs expanding!)
***************************************************************************/
#include "emu.h"
#include "machine/seibu_cop.h"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// device type definition
const device_type SEIBU_COP = &device_creator<seibu_cop_device>;
static ADDRESS_MAP_START( seibu_cop_io, AS_0, 16, seibu_cop_device )
AM_RANGE(0x0428, 0x0429) AM_WRITE(fill_val_lo_w)
AM_RANGE(0x042a, 0x042b) AM_WRITE(fill_val_hi_w)
AM_RANGE(0x045a, 0x045b) AM_WRITE(pal_brightness_val_w)
AM_RANGE(0x045c, 0x045d) AM_WRITE(pal_brightness_mode_w)
AM_RANGE(0x0474, 0x0475) AM_WRITE(dma_unk_param_w)
AM_RANGE(0x0476, 0x0477) AM_WRITE(dma_pal_fade_table_w)
AM_RANGE(0x0478, 0x0479) AM_WRITE(dma_src_w)
AM_RANGE(0x047a, 0x047b) AM_WRITE(dma_size_w)
AM_RANGE(0x047c, 0x047d) AM_WRITE(dma_dst_w)
AM_RANGE(0x047e, 0x047f) AM_READWRITE(dma_trigger_r, dma_trigger_w)
ADDRESS_MAP_END
//**************************************************************************
// INLINE HELPERS
//**************************************************************************
//-------------------------------------------------
// readbyte - read a byte at the given address
//-------------------------------------------------
inline UINT16 seibu_cop_device::read_word(offs_t address)
{
return space().read_word(address);
}
//-------------------------------------------------
// writebyte - write a byte at the given address
//-------------------------------------------------
inline void seibu_cop_device::write_word(offs_t address, UINT16 data)
{
space().write_word(address, data);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// seibu_cop_device - constructor
//-------------------------------------------------
seibu_cop_device::seibu_cop_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, SEIBU_COP, "seibu_cop", tag, owner, clock, "seibu_cop", __FILE__),
device_memory_interface(mconfig, *this),
m_in_byte_cb(*this),
m_in_word_cb(*this),
m_in_dword_cb(*this),
m_out_byte_cb(*this),
m_out_word_cb(*this),
m_out_dword_cb(*this),
m_space_config("io", ENDIANNESS_LITTLE, 16, 16, 0, NULL, *ADDRESS_MAP_NAME(seibu_cop_io))
{
}
//-------------------------------------------------
// device_validity_check - perform validity checks
// on this device
//-------------------------------------------------
void seibu_cop_device::device_validity_check(validity_checker &valid) const
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void seibu_cop_device::device_start()
{
// resolve callbacks
m_in_byte_cb.resolve_safe(0);
m_in_word_cb.resolve_safe(0);
m_in_dword_cb.resolve_safe(0);
m_out_byte_cb.resolve_safe();
m_out_word_cb.resolve_safe();
m_out_dword_cb.resolve_safe();
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void seibu_cop_device::device_reset()
{
}
//-------------------------------------------------
// memory_space_config - return a description of
// any address spaces owned by this device
//-------------------------------------------------
const address_space_config *seibu_cop_device::memory_space_config(address_spacenum spacenum) const
{
return (spacenum == AS_0) ? &m_space_config : NULL;
}
//**************************************************************************
// READ/WRITE HANDLERS
//**************************************************************************
WRITE16_MEMBER(seibu_cop_device::fill_val_lo_w)
{
COMBINE_DATA(&m_fill_val_lo);
m_fill_val = (m_fill_val_lo) | (m_fill_val_hi << 16);
}
WRITE16_MEMBER(seibu_cop_device::fill_val_hi_w)
{
COMBINE_DATA(&m_fill_val_hi);
m_fill_val = (m_fill_val_lo) | (m_fill_val_hi << 16);
}
WRITE16_MEMBER(seibu_cop_device::pal_brightness_val_w)
{
COMBINE_DATA(&m_pal_brightness_val);
/* TODO: add checks for bits 15-6 */
}
WRITE16_MEMBER(seibu_cop_device::pal_brightness_mode_w)
{
COMBINE_DATA(&m_pal_brightness_mode);
/* TODO: add checks for anything that isn't 4 or 5 */
}
WRITE16_MEMBER(seibu_cop_device::dma_unk_param_w)
{
/*
This sets up a DMA mode of some sort
0x0e00: grainbow, cupsoc
0x0a00: legionna, godzilla, denjinmk
0x0600: heatbrl
0x1e00: zeroteam, xsedae
raiden2 and raidendx doesn't set this up, this could indicate that this is related to the non-private buffer DMAs
(both only uses 0x14 and 0x15 as DMAs afaik)
*/
COMBINE_DATA(&m_dma_unk_param);
}
WRITE16_MEMBER(seibu_cop_device::dma_pal_fade_table_w)
{
COMBINE_DATA(&m_dma_pal_fade_table);
}
WRITE16_MEMBER(seibu_cop_device::dma_src_w)
{
COMBINE_DATA(&m_dma_src[m_dma_trigger]);
}
WRITE16_MEMBER(seibu_cop_device::dma_size_w)
{
COMBINE_DATA(&m_dma_size[m_dma_trigger]);
}
WRITE16_MEMBER(seibu_cop_device::dma_dst_w)
{
COMBINE_DATA(&m_dma_dst[m_dma_trigger]);
}
READ16_MEMBER(seibu_cop_device::dma_trigger_r)
{
return m_dma_exec_param;
}
WRITE16_MEMBER(seibu_cop_device::dma_trigger_w)
{
COMBINE_DATA(&m_dma_exec_param);
m_dma_trigger = m_dma_exec_param & 7;
}
//**************************************************************************
// READ/WRITE HANDLERS (device to CPU / CPU to device)
//**************************************************************************
READ16_MEMBER( seibu_cop_device::read )
{
return read_word(offset + (0x400/2));
}
WRITE16_MEMBER( seibu_cop_device::write )
{
write_word(offset + (0x400/2),data);
}
void seibu_cop_device::normal_dma_transfer(void)
{
UINT32 src,dst,size,i;
src = (m_dma_src[m_dma_trigger] << 6);
dst = (m_dma_dst[m_dma_trigger] << 6);
size = ((m_dma_size[m_dma_trigger] << 5) - (m_dma_dst[m_dma_trigger] << 6) + 0x20)/2;
for(i = 0;i < size;i++)
{
m_out_word_cb(dst, m_in_word_cb(src));
src+=2;
dst+=2;
}
}
/* RE from Seibu Cup Soccer bootleg */
const UINT8 seibu_cop_device::fade_table(int v)
{
int low = v & 0x001f;
int high = v & 0x03e0;
return (low * (high | (high >> 5)) + 0x210) >> 10;
}
void seibu_cop_device::palette_dma_transfer(void)
{
UINT32 src,dst,size,i;
/*
Apparently all of those are just different DMA channels, brightness effects are done through a RAM table and the pal_brightness_val / mode
0x80 is used by Legionnaire
0x81 is used by SD Gundam and Godzilla
0x82 is used by Zero Team and X Se Dae
0x86 is used by Seibu Cup Soccer
0x87 is used by Denjin Makai
TODO:
- Denjin Makai mode 4 is totally guessworked.
- SD Gundam doesn't fade colors correctly, it should have the text layer / sprites with normal gradient and the rest dimmed in most cases,
presumably bad RAM table or bad algorithm
*/
src = (m_dma_src[m_dma_trigger] << 6);
dst = (m_dma_dst[m_dma_trigger] << 6);
size = ((m_dma_size[m_dma_trigger] << 5) - (m_dma_dst[m_dma_trigger] << 6) + 0x20)/2;
//printf("SRC: %08x %08x DST:%08x SIZE:%08x TRIGGER: %08x %02x %02x\n",cop_dma_src[cop_dma_trigger] << 6,cop_dma_fade_table * 0x400,cop_dma_dst[cop_dma_trigger] << 6,cop_dma_size[cop_dma_trigger] << 5,cop_dma_trigger,pal_brightness_val,pal_brightness_mode);
for(i = 0;i < size;i++)
{
UINT16 pal_val;
int r,g,b;
int rt,gt,bt;
if(m_pal_brightness_mode == 5)
{
bt = ((m_in_word_cb(src + (m_dma_pal_fade_table * 0x400))) & 0x7c00) >> 5;
bt = fade_table(bt|(m_pal_brightness_val ^ 0));
b = ((m_in_word_cb(src)) & 0x7c00) >> 5;
b = fade_table(b|(m_pal_brightness_val ^ 0x1f));
pal_val = ((b + bt) & 0x1f) << 10;
gt = ((m_in_word_cb(src + (m_dma_pal_fade_table * 0x400))) & 0x03e0);
gt = fade_table(gt|(m_pal_brightness_val ^ 0));
g = ((m_in_word_cb(src)) & 0x03e0);
g = fade_table(g|(m_pal_brightness_val ^ 0x1f));
pal_val |= ((g + gt) & 0x1f) << 5;
rt = ((m_in_word_cb(src + (m_dma_pal_fade_table * 0x400))) & 0x001f) << 5;
rt = fade_table(rt|(m_pal_brightness_val ^ 0));
r = ((m_in_word_cb(src)) & 0x001f) << 5;
r = fade_table(r|(m_pal_brightness_val ^ 0x1f));
pal_val |= ((r + rt) & 0x1f);
}
else if(m_pal_brightness_mode == 4) //Denjin Makai
{
bt =(m_in_word_cb(src + (m_dma_pal_fade_table * 0x400)) & 0x7c00) >> 10;
b = (m_in_word_cb(src) & 0x7c00) >> 10;
gt =(m_in_word_cb(src + (m_dma_pal_fade_table * 0x400)) & 0x03e0) >> 5;
g = (m_in_word_cb(src) & 0x03e0) >> 5;
rt =(m_in_word_cb(src + (m_dma_pal_fade_table * 0x400)) & 0x001f) >> 0;
r = (m_in_word_cb(src) & 0x001f) >> 0;
if(m_pal_brightness_val == 0x10)
pal_val = bt << 10 | gt << 5 | rt << 0;
else if(m_pal_brightness_val == 0xff) // TODO: might be the back plane or it still doesn't do any mod, needs PCB tests
pal_val = 0;
else
{
bt = fade_table(bt<<5|((m_pal_brightness_val*2) ^ 0));
b = fade_table(b<<5|((m_pal_brightness_val*2) ^ 0x1f));
pal_val = ((b + bt) & 0x1f) << 10;
gt = fade_table(gt<<5|((m_pal_brightness_val*2) ^ 0));
g = fade_table(g<<5|((m_pal_brightness_val*2) ^ 0x1f));
pal_val |= ((g + gt) & 0x1f) << 5;
rt = fade_table(rt<<5|((m_pal_brightness_val*2) ^ 0));
r = fade_table(r<<5|((m_pal_brightness_val*2) ^ 0x1f));
pal_val |= ((r + rt) & 0x1f);
}
}
else
{
printf("Seibu COP: palette DMA used with mode %02x!\n",m_pal_brightness_mode);
pal_val = m_in_word_cb(src);
}
m_out_word_cb(dst, pal_val);
src+=2;
dst+=2;
}
}
void seibu_cop_device::fill_word_transfer(void)
{
UINT32 length, address;
int i;
//if(cop_dma_dst[cop_dma_trigger] != 0x0000) // Invalid?
// return;
address = (m_dma_src[m_dma_trigger] << 6);
length = ((m_dma_size[m_dma_trigger]+1) << 4);
for (i=address;i<address+length;i+=4)
{
m_out_dword_cb(i, m_fill_val, 0xffff);
}
}
void seibu_cop_device::fill_dword_transfer(void)
{
UINT32 length, address;
int i;
if(m_dma_dst[m_dma_trigger] != 0x0000) // Invalid? TODO: log & check this
return;
address = (m_dma_src[m_dma_trigger] << 6);
length = (m_dma_size[m_dma_trigger]+1) << 5;
//printf("%08x %08x\n",address,length);
for (i=address;i<address+length;i+=4)
{
m_out_dword_cb(i, m_fill_val, 0xffff);
}
}
WRITE16_MEMBER( seibu_cop_device::dma_write_trigger_w )
{
switch(m_dma_exec_param & 0xfff8)
{
case 0x008: normal_dma_transfer(); break;
case 0x010: break; // private buffer copy, TODO
case 0x080: palette_dma_transfer(); break;
case 0x110: fill_word_transfer(); break; // Godzilla uses this
case 0x118: fill_dword_transfer(); break;
default:
logerror("Seibu COP: used unemulated DMA type %04x\n",m_dma_exec_param);
}
}

View File

@ -1,118 +0,0 @@
/***************************************************************************
Seibu COP device
***************************************************************************/
#pragma once
#ifndef __SEIBU_COPDEV_H__
#define __SEIBU_COPDEV_H__
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_SEIBU_COP_IN_BYTE_CB(_devcb) \
devcb = &seibu_cop_device::set_in_byte_callback(*device, DEVCB_##_devcb);
#define MCFG_SEIBU_COP_IN_WORD_CB(_devcb) \
devcb = &seibu_cop_device::set_in_word_callback(*device, DEVCB_##_devcb);
#define MCFG_SEIBU_COP_IN_DWORD_CB(_devcb) \
devcb = &seibu_cop_device::set_in_dword_callback(*device, DEVCB_##_devcb);
#define MCFG_SEIBU_COP_OUT_BYTE_CB(_devcb) \
devcb = &seibu_cop_device::set_out_byte_callback(*device, DEVCB_##_devcb);
#define MCFG_SEIBU_COP_OUT_WORD_CB(_devcb) \
devcb = &seibu_cop_device::set_out_word_callback(*device, DEVCB_##_devcb);
#define MCFG_SEIBU_COP_OUT_DWORD_CB(_devcb) \
devcb = &seibu_cop_device::set_out_dword_callback(*device, DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> seibu_cop_device
class seibu_cop_device : public device_t,
public device_memory_interface
{
public:
// construction/destruction
seibu_cop_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
template<class _Object> static devcb_base &set_in_byte_callback(device_t &device, _Object object) { return downcast<seibu_cop_device &>(device).m_in_byte_cb.set_callback(object); }
template<class _Object> static devcb_base &set_in_word_callback(device_t &device, _Object object) { return downcast<seibu_cop_device &>(device).m_in_word_cb.set_callback(object); }
template<class _Object> static devcb_base &set_in_dword_callback(device_t &device, _Object object) { return downcast<seibu_cop_device &>(device).m_in_dword_cb.set_callback(object); }
template<class _Object> static devcb_base &set_out_byte_callback(device_t &device, _Object object) { return downcast<seibu_cop_device &>(device).m_out_byte_cb.set_callback(object); }
template<class _Object> static devcb_base &set_out_word_callback(device_t &device, _Object object) { return downcast<seibu_cop_device &>(device).m_out_word_cb.set_callback(object); }
template<class _Object> static devcb_base &set_out_dword_callback(device_t &device, _Object object) { return downcast<seibu_cop_device &>(device).m_out_dword_cb.set_callback(object); }
// I/O operations
DECLARE_WRITE16_MEMBER( write );
DECLARE_READ16_MEMBER( read );
DECLARE_WRITE16_MEMBER( dma_write_trigger_w );
DECLARE_WRITE16_MEMBER(fill_val_lo_w);
DECLARE_WRITE16_MEMBER(fill_val_hi_w);
DECLARE_WRITE16_MEMBER(pal_brightness_val_w);
DECLARE_WRITE16_MEMBER(pal_brightness_mode_w);
DECLARE_WRITE16_MEMBER(dma_unk_param_w);
DECLARE_WRITE16_MEMBER(dma_pal_fade_table_w);
DECLARE_WRITE16_MEMBER(dma_src_w);
DECLARE_WRITE16_MEMBER(dma_size_w);
DECLARE_WRITE16_MEMBER(dma_dst_w);
DECLARE_READ16_MEMBER(dma_trigger_r);
DECLARE_WRITE16_MEMBER(dma_trigger_w);
protected:
// device-level overrides
virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start();
virtual void device_reset();
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
private:
devcb_read16 m_in_byte_cb;
devcb_read16 m_in_word_cb;
devcb_read16 m_in_dword_cb;
devcb_write16 m_out_byte_cb;
devcb_write16 m_out_word_cb;
devcb_write16 m_out_dword_cb;
inline UINT16 read_word(offs_t address);
inline void write_word(offs_t address, UINT16 data);
UINT16 m_dma_unk_param, m_dma_pal_fade_table, m_dma_src[8], m_dma_dst[8], m_dma_size[8], m_dma_exec_param;
UINT8 m_dma_trigger;
UINT16 m_fill_val_lo,m_fill_val_hi;
UINT32 m_fill_val;
UINT16 m_pal_brightness_val, m_pal_brightness_mode;
const address_space_config m_space_config;
const UINT8 fade_table(int v);
void normal_dma_transfer(void);
void palette_dma_transfer(void);
void fill_word_transfer(void);
void fill_dword_transfer(void);
};
// device type definition
extern const device_type SEIBU_COP;
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
#endif

View File

@ -89,7 +89,7 @@ static ADDRESS_MAP_START( legionna_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x101800, 0x101fff) AM_RAM // _WRITE(legionna_foreground_w) AM_SHARE("fore_data")
AM_RANGE(0x102000, 0x1027ff) AM_RAM // _WRITE(legionna_midground_w) AM_SHARE("mid_data")
AM_RANGE(0x102800, 0x1037ff) AM_RAM // _WRITE(legionna_text_w) AM_SHARE("textram")
AM_RANGE(0x104000, 0x104fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") /* palette xRRRRxGGGGxBBBBx ? */
AM_RANGE(0x104000, 0x104fff) AM_RAM // _DEVWRITE("palette", palette_device, write) AM_SHARE("palette") /* palette xRRRRxGGGGxBBBBx ? */
AM_RANGE(0x105000, 0x105fff) AM_RAM AM_SHARE("spriteram")
AM_RANGE(0x106000, 0x107fff) AM_RAM
AM_RANGE(0x108000, 0x11ffff) AM_RAM /* main ram */
@ -105,7 +105,7 @@ static ADDRESS_MAP_START( heatbrl_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x101800, 0x101fff) AM_RAM // _WRITE(legionna_midground_w) AM_SHARE("mid_data")
AM_RANGE(0x102000, 0x102fff) AM_RAM // _WRITE(legionna_text_w) AM_SHARE("textram")
AM_RANGE(0x103000, 0x103fff) AM_RAM AM_SHARE("spriteram")
AM_RANGE(0x104000, 0x104fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x104000, 0x104fff) AM_RAM // _DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x108000, 0x11ffff) AM_RAM
ADDRESS_MAP_END
@ -119,7 +119,7 @@ static ADDRESS_MAP_START( godzilla_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x102000, 0x1027ff) AM_RAM // _WRITE(legionna_midground_w) AM_SHARE("mid_data")
AM_RANGE(0x102800, 0x1037ff) AM_RAM // _WRITE(legionna_text_w) AM_SHARE("textram")
AM_RANGE(0x103800, 0x103fff) AM_RAM // check?
AM_RANGE(0x104000, 0x104fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x104000, 0x104fff) AM_RAM // _DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x105000, 0x105fff) AM_RAM AM_SHARE("spriteram")
AM_RANGE(0x106000, 0x1067ff) AM_RAM
AM_RANGE(0x106800, 0x106fff) AM_RAM
@ -127,13 +127,15 @@ static ADDRESS_MAP_START( godzilla_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x108000, 0x11ffff) AM_RAM
ADDRESS_MAP_END
/* did they swap the lines, or does the protection device swap the words during the DMA?? */
WRITE16_MEMBER(legionna_state::denjin_paletteram16_xBBBBBGGGGGRRRRR_word_w)
WRITE16_MEMBER(legionna_state::wordswapram_w)
{
offset^=1;
m_palette->write(space,offset,data,mem_mask);
COMBINE_DATA(&m_wordswapram[offset]);
}
static ADDRESS_MAP_START( denjinmk_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x1003ff) AM_RAM
@ -143,7 +145,7 @@ static ADDRESS_MAP_START( denjinmk_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x101800, 0x101fff) AM_RAM // _WRITE(legionna_foreground_w) AM_SHARE("fore_data")
AM_RANGE(0x102000, 0x1027ff) AM_RAM // _WRITE(legionna_midground_w) AM_SHARE("mid_data")
AM_RANGE(0x102800, 0x103fff) AM_RAM // _WRITE(legionna_text_w) AM_SHARE("textram")
AM_RANGE(0x104000, 0x104fff) AM_RAM_WRITE(denjin_paletteram16_xBBBBBGGGGGRRRRR_word_w) AM_SHARE("palette")
AM_RANGE(0x104000, 0x104fff) AM_RAM_WRITE(wordswapram_w) AM_SHARE("wordswapram")
AM_RANGE(0x105000, 0x105fff) AM_RAM AM_SHARE("spriteram")
AM_RANGE(0x106000, 0x107fff) AM_RAM
AM_RANGE(0x108000, 0x11dfff) AM_RAM
@ -159,7 +161,7 @@ static ADDRESS_MAP_START( grainbow_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x101000, 0x1017ff) AM_RAM // _WRITE(legionna_foreground_w) AM_SHARE("fore_data")
AM_RANGE(0x101800, 0x101fff) AM_RAM // _WRITE(legionna_midground_w) AM_SHARE("mid_data")
AM_RANGE(0x102000, 0x102fff) AM_RAM // _WRITE(legionna_text_w) AM_SHARE("textram")
AM_RANGE(0x103000, 0x103fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x103000, 0x103fff) AM_RAM // _DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x104000, 0x104fff) AM_RAM//_WRITE(paletteram_xBBBBBGGGGGRRRRR_word_w) AM_SHARE("paletteram")
AM_RANGE(0x105000, 0x105fff) AM_RAM
AM_RANGE(0x106000, 0x106fff) AM_RAM
@ -175,7 +177,7 @@ static ADDRESS_MAP_START( cupsoc_mem, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x101000, 0x1017ff) AM_RAM // _WRITE(legionna_foreground_w) AM_SHARE("fore_data")
AM_RANGE(0x101800, 0x101fff) AM_RAM // _WRITE(legionna_midground_w) AM_SHARE("mid_data")
AM_RANGE(0x102000, 0x102fff) AM_RAM // _WRITE(legionna_text_w) AM_SHARE("textram")
AM_RANGE(0x103000, 0x103fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x103000, 0x103fff) AM_RAM // _DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x104000, 0x104fff) AM_RAM
AM_RANGE(0x105000, 0x106fff) AM_RAM
AM_RANGE(0x107000, 0x1077ff) AM_RAM AM_SHARE("spriteram")
@ -194,7 +196,7 @@ static ADDRESS_MAP_START( cupsocs_mem, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x101000, 0x1017ff) AM_RAM // _WRITE(legionna_foreground_w) AM_SHARE("fore_data")
AM_RANGE(0x101800, 0x101fff) AM_RAM // _WRITE(legionna_midground_w) AM_SHARE("mid_data")
AM_RANGE(0x102000, 0x102fff) AM_RAM // _WRITE(legionna_text_w) AM_SHARE("textram")
AM_RANGE(0x103000, 0x103fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x103000, 0x103fff) AM_RAM // _DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x104000, 0x104fff) AM_RAM
AM_RANGE(0x105000, 0x106fff) AM_RAM
AM_RANGE(0x107000, 0x1077ff) AM_RAM AM_SHARE("spriteram")
@ -213,7 +215,7 @@ static ADDRESS_MAP_START( cupsocbl_mem, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x101000, 0x1017ff) AM_RAM // _WRITE(legionna_foreground_w) AM_SHARE("fore_data")
AM_RANGE(0x101800, 0x101fff) AM_RAM // _WRITE(legionna_midground_w) AM_SHARE("mid_data")
AM_RANGE(0x102000, 0x102fff) AM_RAM // _WRITE(legionna_text_w) AM_SHARE("textram")
AM_RANGE(0x103000, 0x103fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x103000, 0x103fff) AM_RAM // _DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x104000, 0x104fff) AM_RAM
AM_RANGE(0x105000, 0x106fff) AM_RAM
AM_RANGE(0x107000, 0x1077ff) AM_RAM AM_SHARE("spriteram")
@ -1066,7 +1068,8 @@ static MACHINE_CONFIG_START( legionna, legionna_state )
SEIBU_SOUND_SYSTEM_CPU(14318180/4)
MCFG_SEIBU_COP_ADD("seibucop")
MCFG_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
MCFG_RAIDEN2COP_ADD("raiden2cop")
MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@ -1079,7 +1082,7 @@ static MACHINE_CONFIG_START( legionna, legionna_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", legionna)
MCFG_PALETTE_ADD_INIT_BLACK("palette", 128*16)
MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
//MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
MCFG_VIDEO_START_OVERRIDE(legionna_state,legionna)
@ -1098,7 +1101,8 @@ static MACHINE_CONFIG_START( heatbrl, legionna_state )
SEIBU_SOUND_SYSTEM_CPU(14318180/4)
MCFG_SEIBU_COP_ADD("seibucop")
MCFG_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
MCFG_RAIDEN2COP_ADD("raiden2cop")
MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@ -1112,7 +1116,7 @@ static MACHINE_CONFIG_START( heatbrl, legionna_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", heatbrl)
MCFG_PALETTE_ADD_INIT_BLACK("palette", 128*16)
MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
//MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
MCFG_VIDEO_START_OVERRIDE(legionna_state,legionna)
@ -1130,7 +1134,8 @@ static MACHINE_CONFIG_START( godzilla, legionna_state )
SEIBU2_SOUND_SYSTEM_CPU(14318180/4)
MCFG_SEIBU_COP_ADD("seibucop")
MCFG_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
MCFG_RAIDEN2COP_ADD("raiden2cop")
MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@ -1145,7 +1150,7 @@ static MACHINE_CONFIG_START( godzilla, legionna_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", heatbrl)
MCFG_PALETTE_ADD_INIT_BLACK("palette", 128*16)
MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
//MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
MCFG_VIDEO_START_OVERRIDE(legionna_state,godzilla)
@ -1163,7 +1168,8 @@ static MACHINE_CONFIG_START( denjinmk, legionna_state )
SEIBU2_SOUND_SYSTEM_CPU(14318180/4)
MCFG_SEIBU_COP_ADD("seibucop")
MCFG_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
MCFG_RAIDEN2COP_ADD("raiden2cop")
MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@ -1177,7 +1183,7 @@ static MACHINE_CONFIG_START( denjinmk, legionna_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", heatbrl)
MCFG_PALETTE_ADD_INIT_BLACK("palette", 128*16)
MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
//MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
MCFG_VIDEO_START_OVERRIDE(legionna_state,denjinmk)
@ -1195,7 +1201,8 @@ static MACHINE_CONFIG_START( grainbow, legionna_state )
SEIBU2_SOUND_SYSTEM_CPU(14318180/4)
MCFG_SEIBU_COP_ADD("seibucop")
MCFG_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
MCFG_RAIDEN2COP_ADD("raiden2cop")
MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@ -1209,7 +1216,7 @@ static MACHINE_CONFIG_START( grainbow, legionna_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", grainbow)
MCFG_PALETTE_ADD_INIT_BLACK("palette", 128*16)
MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
//MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
MCFG_VIDEO_START_OVERRIDE(legionna_state,grainbow)
@ -1228,7 +1235,8 @@ static MACHINE_CONFIG_START( cupsoc, legionna_state )
SEIBU_SOUND_SYSTEM_CPU(14318180/4)
MCFG_SEIBU_COP_ADD("seibucop")
MCFG_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
MCFG_RAIDEN2COP_ADD("raiden2cop")
MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@ -1242,7 +1250,7 @@ static MACHINE_CONFIG_START( cupsoc, legionna_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", cupsoc)
MCFG_PALETTE_ADD_INIT_BLACK("palette", 128*16)
MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
//MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
MCFG_VIDEO_START_OVERRIDE(legionna_state,cupsoc)
@ -1263,7 +1271,9 @@ static MACHINE_CONFIG_START( cupsocbl, legionna_state )
MCFG_CPU_VBLANK_INT_DRIVER("screen", legionna_state, irq4_line_hold) /* VBL */
MCFG_SEIBU_COP_ADD("seibucop")
MCFG_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
MCFG_RAIDEN2COP_ADD("raiden2cop")
MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(WRITE16(legionna_state, videowrite_cb_w))
/*Different Sound hardware*/
//SEIBU_SOUND_SYSTEM_CPU(14318180/4)
@ -1283,7 +1293,7 @@ static MACHINE_CONFIG_START( cupsocbl, legionna_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", heatbrl_csb)
MCFG_PALETTE_ADD_INIT_BLACK("palette", 128*16)
MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
//MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
MCFG_VIDEO_START_OVERRIDE(legionna_state,cupsoc)

View File

@ -279,59 +279,8 @@ WRITE16_MEMBER(raiden2_state::cop_pgm_trigger_w)
cop_latch_trigger = data;
}
WRITE16_MEMBER(raiden2_state::cop_dma_adr_rel_w)
{
COMBINE_DATA(&cop_dma_adr_rel);
}
WRITE16_MEMBER(raiden2_state::cop_dma_v1_w)
{
COMBINE_DATA(&cop_dma_v1);
}
WRITE16_MEMBER(raiden2_state::cop_dma_v2_w)
{
COMBINE_DATA(&cop_dma_v2);
}
WRITE16_MEMBER(raiden2_state::cop_dma_dst_w)
{
COMBINE_DATA(&cop_dma_dst[cop_dma_mode]);
}
READ16_MEMBER(raiden2_state::cop_dma_mode_r)
{
return cop_dma_mode;
}
WRITE16_MEMBER(raiden2_state::cop_dma_mode_w)
{
COMBINE_DATA(&cop_dma_mode);
}
WRITE16_MEMBER(raiden2_state::cop_dma_src_w)
{
COMBINE_DATA(&cop_dma_src[cop_dma_mode]);
}
WRITE16_MEMBER(raiden2_state::cop_dma_size_w)
{
COMBINE_DATA(&cop_dma_size[cop_dma_mode]);
}
WRITE16_MEMBER(raiden2_state::cop_pal_brightness_val_w)
{
COMBINE_DATA(&pal_brightness_val);
}
/* RE from Seibu Cup Soccer bootleg */
const UINT8 raiden2_state::fade_table(int v)
{
int low = v & 0x001f;
int high = v & 0x03e0;
return (low * (high | (high >> 5)) + 0x210) >> 10;
}
WRITE16_MEMBER(raiden2_state::m_videoram_private_w)
{
@ -361,136 +310,6 @@ WRITE16_MEMBER(raiden2_state::m_videoram_private_w)
}
}
WRITE16_MEMBER(raiden2_state::cop_dma_trigger_w)
{
/*
printf("COP DMA mode=%x adr=%x size=%x vals=%x %x %x\n",
cop_dma_mode,
cop_dma_src[cop_dma_mode]<<6,
cop_dma_size[cop_dma_mode]<<4,
cop_dma_v1,
cop_dma_v2,
cop_dma_dst[cop_dma_mode]);
*/
switch(cop_dma_mode) {
case 0x14: {
/* TODO: this transfers the whole VRAM, not only spriteram!
For whatever reason, this stopped working as soon as I've implemented DMA slot concept.
Raiden 2 uses this DMA with cop_dma_dst == 0xfffe, effectively changing the order of the uploaded VRAMs.
Also the size is used for doing a sprite limit trickery.
*/
// based on legionna this should probably only transfer tilemaps, although maybe on this HW things are different
// we might be misinterpreting params. For legionna.c it always points to the start of RAM where the tilemaps are
// for zeroteam likewise, but for Raiden 2 the pointer is wrong??
// tilemap DMA
{
int src = cop_dma_src[cop_dma_mode] << 6;
if (src == 0xcfc0) src = 0xd000; // R2, why?? everything else sets the right pointer
for (int i = 0; i < 0x2800 /2; i++)
{
UINT16 tileval = space.read_word(src);
src += 2;
//m_videoramout_cb(space, i, tileval, 0xffff);
m_videoram_private_w(space, i, tileval, 0xffff);
}
}
// sprite DMA part
static int rsize = ((0x80 - cop_dma_size[cop_dma_mode]) & 0x7f) +1;
sprites_cur_start = 0x1000 - (rsize << 5);
#if 0
int rsize = 32*(0x7f-cop_dma_size);
int radr = 64*cop_dma_adr - rsize;
for(int i=0; i<rsize; i+=2)
sprites[i/2] = space.read_word(radr+i);
sprites_cur_start = rsize;
#endif
break;
}
// case 0x15: points at palette in legionna.c and here
case 0x82: {
UINT32 src,dst,size;
int i;
src = (cop_dma_src[cop_dma_mode] << 6);
dst = (cop_dma_dst[cop_dma_mode] << 6);
size = ((cop_dma_size[cop_dma_mode] << 5) - (cop_dma_dst[cop_dma_mode] << 6) + 0x20)/2;
//printf("%08x %08x %08x\n",src,dst,size);
for(i = 0;i < size;i++)
{
UINT16 pal_val;
int r,g,b;
int rt,gt,bt;
bt = (space.read_word(src + (cop_dma_adr_rel * 0x400)) & 0x7c00) >> 5;
bt = fade_table(bt|(pal_brightness_val ^ 0));
b = ((space.read_word(src)) & 0x7c00) >> 5;
b = fade_table(b|(pal_brightness_val ^ 0x1f));
pal_val = ((b + bt) & 0x1f) << 10;
gt = (space.read_word(src + (cop_dma_adr_rel * 0x400)) & 0x03e0);
gt = fade_table(gt|(pal_brightness_val ^ 0));
g = ((space.read_word(src)) & 0x03e0);
g = fade_table(g|(pal_brightness_val ^ 0x1f));
pal_val |= ((g + gt) & 0x1f) << 5;
rt = (space.read_word(src + (cop_dma_adr_rel * 0x400)) & 0x001f) << 5;
rt = fade_table(rt|(pal_brightness_val ^ 0));
r = ((space.read_word(src)) & 0x001f) << 5;
r = fade_table(r|(pal_brightness_val ^ 0x1f));
pal_val |= ((r + rt) & 0x1f);
space.write_word(dst, pal_val);
src+=2;
dst+=2;
}
break;
}
case 0x09: {
UINT32 src,dst,size;
int i;
src = (cop_dma_src[cop_dma_mode] << 6);
dst = (cop_dma_dst[cop_dma_mode] << 6);
size = ((cop_dma_size[cop_dma_mode] << 5) - (cop_dma_dst[cop_dma_mode] << 6) + 0x20)/2;
// printf("%08x %08x %08x\n",src,dst,size);
for(i = 0;i < size;i++)
{
space.write_word(dst, space.read_word(src));
src+=2;
dst+=2;
}
break;
}
case 0x118:
case 0x11f: {
UINT32 length, address;
int i;
if(cop_dma_dst[cop_dma_mode] != 0x0000) // Invalid?
return;
address = (cop_dma_src[cop_dma_mode] << 6);
length = (cop_dma_size[cop_dma_mode]+1) << 5;
//printf("%08x %08x\n",address,length);
for (i=address;i<address+length;i+=4)
{
space.write_dword(i, (cop_dma_v1) | (cop_dma_v2 << 16));
}
}
}
}
WRITE16_MEMBER(raiden2_state::cop_itoa_low_w)
{
cop_itoa = (cop_itoa & ~UINT32(mem_mask)) | (data & mem_mask);
@ -849,7 +668,7 @@ void raiden2_state::combine32(UINT32 *val, int offset, UINT16 data, UINT16 mem_m
void raiden2_state::draw_sprites(const rectangle &cliprect)
{
UINT16 *source = sprites + sprites_cur_start/2;
UINT16 *source = sprites + (0x1000/2)-4;
sprite_buffer.fill(0xf, cliprect);
gfx_element *gfx = m_gfxdecode->gfx(2);
@ -1605,8 +1424,8 @@ static ADDRESS_MAP_START( raiden2_cop_mem, AS_PROGRAM, 16, raiden2_state )
AM_RANGE(0x00420, 0x00421) AM_WRITE(cop_itoa_low_w)
AM_RANGE(0x00422, 0x00423) AM_WRITE(cop_itoa_high_w)
AM_RANGE(0x00424, 0x00425) AM_WRITE(cop_itoa_digit_count_w)
AM_RANGE(0x00428, 0x00429) AM_WRITE(cop_dma_v1_w)
AM_RANGE(0x0042a, 0x0042b) AM_WRITE(cop_dma_v2_w)
AM_RANGE(0x00428, 0x00429) AM_DEVWRITE("raiden2cop", raiden2cop_device, cop_dma_v1_w)
AM_RANGE(0x0042a, 0x0042b) AM_DEVWRITE("raiden2cop", raiden2cop_device, cop_dma_v2_w)
AM_RANGE(0x00432, 0x00433) AM_WRITE(cop_pgm_data_w)
AM_RANGE(0x00434, 0x00435) AM_WRITE(cop_pgm_addr_w)
AM_RANGE(0x00436, 0x00437) AM_WRITE(cop_hitbox_baseadr_w)
@ -1619,15 +1438,15 @@ static ADDRESS_MAP_START( raiden2_cop_mem, AS_PROGRAM, 16, raiden2_state )
AM_RANGE(0x00454, 0x00455) AM_WRITE(cop_sort_lookup_hi_w)
AM_RANGE(0x00456, 0x00457) AM_WRITE(cop_sort_lookup_lo_w)
AM_RANGE(0x00458, 0x00459) AM_WRITE(cop_sort_param_w)
AM_RANGE(0x0045a, 0x0045b) AM_WRITE(cop_pal_brightness_val_w) //palette DMA brightness val, used by X Se Dae / Zero Team
AM_RANGE(0x0045c, 0x0045d) AM_WRITENOP //palette DMA brightness mode, used by X Se Dae / Zero Team (sets to 5)
AM_RANGE(0x0045a, 0x0045b) AM_DEVWRITE("raiden2cop", raiden2cop_device, cop_pal_brightness_val_w) //palette DMA brightness val, used by X Se Dae / Zero Team
AM_RANGE(0x0045c, 0x0045d) AM_DEVWRITE("raiden2cop", raiden2cop_device, cop_pal_brightness_mode_w) //palette DMA brightness mode, used by X Se Dae / Zero Team (sets to 5)
AM_RANGE(0x00470, 0x00471) AM_READWRITE(cop_tile_bank_2_r,cop_tile_bank_2_w)
AM_RANGE(0x00476, 0x00477) AM_WRITE(cop_dma_adr_rel_w)
AM_RANGE(0x00478, 0x00479) AM_WRITE(cop_dma_src_w)
AM_RANGE(0x0047a, 0x0047b) AM_WRITE(cop_dma_size_w)
AM_RANGE(0x0047c, 0x0047d) AM_WRITE(cop_dma_dst_w)
AM_RANGE(0x0047e, 0x0047f) AM_READWRITE(cop_dma_mode_r, cop_dma_mode_w)
AM_RANGE(0x00476, 0x00477) AM_DEVWRITE("raiden2cop", raiden2cop_device, cop_dma_adr_rel_w)
AM_RANGE(0x00478, 0x00479) AM_DEVWRITE("raiden2cop", raiden2cop_device,cop_dma_src_w)
AM_RANGE(0x0047a, 0x0047b) AM_DEVWRITE("raiden2cop", raiden2cop_device,cop_dma_size_w)
AM_RANGE(0x0047c, 0x0047d) AM_DEVWRITE("raiden2cop", raiden2cop_device,cop_dma_dst_w)
AM_RANGE(0x0047e, 0x0047f) AM_DEVREADWRITE("raiden2cop", raiden2cop_device, cop_dma_mode_r, cop_dma_mode_w)
AM_RANGE(0x004a0, 0x004a9) AM_READWRITE(cop_reg_high_r, cop_reg_high_w)
AM_RANGE(0x004c0, 0x004c9) AM_READWRITE(cop_reg_low_r, cop_reg_low_w)
AM_RANGE(0x00500, 0x00505) AM_WRITE(cop_cmd_w)
@ -1662,7 +1481,7 @@ static ADDRESS_MAP_START( raiden2_cop_mem, AS_PROGRAM, 16, raiden2_state )
AM_RANGE(0x006da, 0x006db) AM_WRITE(sprite_prot_y_w)
AM_RANGE(0x006dc, 0x006dd) AM_READWRITE(sprite_prot_maxx_r, sprite_prot_maxx_w)
AM_RANGE(0x006de, 0x006df) AM_WRITE(sprite_prot_src_w)
AM_RANGE(0x006fc, 0x006fd) AM_WRITE(cop_dma_trigger_w)
AM_RANGE(0x006fc, 0x006fd) AM_DEVWRITE("raiden2cop", raiden2cop_device,cop_dma_trigger_w)
AM_RANGE(0x006fe, 0x006ff) AM_WRITE(cop_sort_dma_trig_w) // sort-DMA trigger
AM_RANGE(0x00762, 0x00763) AM_READ(sprite_prot_dst1_r)
@ -1691,7 +1510,7 @@ static ADDRESS_MAP_START( raiden2_mem, AS_PROGRAM, 16, raiden2_state )
AM_RANGE(0x0f800, 0x0ffff) AM_RAM /* Stack area */
AM_RANGE(0x10000, 0x1efff) AM_RAM
AM_RANGE(0x1f000, 0x1ffff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x1f000, 0x1ffff) AM_RAM //_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x20000, 0x2ffff) AM_ROMBANK("mainbank1")
AM_RANGE(0x30000, 0x3ffff) AM_ROMBANK("mainbank2")
@ -1728,7 +1547,7 @@ static ADDRESS_MAP_START( zeroteam_mem, AS_PROGRAM, 16, raiden2_state )
AM_RANGE(0x0c000, 0x0c7ff) AM_RAM // _WRITE(raiden2_foreground_w) AM_SHARE("fore_data")
AM_RANGE(0x0c800, 0x0cfff) AM_RAM // _WRITE(raiden2_midground_w) AM_SHARE("mid_data")
AM_RANGE(0x0d000, 0x0dfff) AM_RAM // _WRITE(raiden2_text_w) AM_SHARE("text_data")
AM_RANGE(0x0e000, 0x0efff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x0e000, 0x0efff) AM_RAM // _DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x0f000, 0x0ffff) AM_RAM AM_SHARE("sprites")
AM_RANGE(0x10000, 0x1ffff) AM_RAM
@ -1759,7 +1578,7 @@ static ADDRESS_MAP_START( xsedae_mem, AS_PROGRAM, 16, raiden2_state )
AM_RANGE(0x0c000, 0x0c7ff) AM_RAM // _WRITE(raiden2_foreground_w) AM_SHARE("fore_data")
AM_RANGE(0x0c800, 0x0cfff) AM_RAM // _WRITE(raiden2_midground_w) AM_SHARE("mid_data")
AM_RANGE(0x0d000, 0x0dfff) AM_RAM // _WRITE(raiden2_text_w) AM_SHARE("text_data")
AM_RANGE(0x0e000, 0x0efff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x0e000, 0x0efff) AM_RAM // _DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x0f000, 0x0ffff) AM_RAM AM_SHARE("sprites")
AM_RANGE(0x10000, 0x1ffff) AM_RAM
@ -2097,12 +1916,15 @@ static MACHINE_CONFIG_START( raiden2, raiden2_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", raiden2)
MCFG_PALETTE_ADD("palette", 2048)
MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
//MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
MCFG_DEVICE_ADD("crtc", SEIBU_CRTC, 0)
MCFG_SEIBU_CRTC_LAYER_EN_CB(WRITE16(raiden2_state, tilemap_enable_w))
MCFG_SEIBU_CRTC_LAYER_SCROLL_CB(WRITE16(raiden2_state, tile_scroll_w))
MCFG_RAIDEN2COP_ADD("raiden2cop")
MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(WRITE16(raiden2_state, m_videoram_private_w))
MCFG_VIDEO_START_OVERRIDE(raiden2_state,raiden2)
/* sound hardware */
@ -2154,12 +1976,15 @@ static MACHINE_CONFIG_START( zeroteam, raiden2_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", raiden2)
MCFG_PALETTE_ADD("palette", 2048)
MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
//MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
MCFG_DEVICE_ADD("crtc", SEIBU_CRTC, 0)
MCFG_SEIBU_CRTC_LAYER_EN_CB(WRITE16(raiden2_state, tilemap_enable_w))
MCFG_SEIBU_CRTC_LAYER_SCROLL_CB(WRITE16(raiden2_state, tile_scroll_w))
MCFG_RAIDEN2COP_ADD("raiden2cop")
MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(WRITE16(raiden2_state, m_videoram_private_w))
MCFG_VIDEO_START_OVERRIDE(raiden2_state,raiden2)
/* sound hardware */

View File

@ -1,4 +1,6 @@
#include "sound/okim6295.h"
#include "machine/raiden2cop.h"
class legionna_state : public driver_device
{
@ -14,7 +16,9 @@ public:
m_audiocpu(*this, "audiocpu"),
m_oki(*this, "oki"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette") { }
m_palette(*this, "palette"),
m_wordswapram(*this, "wordswapram")
{ }
required_shared_ptr<UINT16> m_spriteram;
UINT16* m_back_data;
@ -36,7 +40,7 @@ public:
UINT16 m_mid_gfx_bank;
DECLARE_WRITE16_MEMBER(videowrite_cb_w);
DECLARE_WRITE16_MEMBER(denjin_paletteram16_xBBBBBGGGGGRRRRR_word_w);
DECLARE_WRITE16_MEMBER(wordswapram_w);
DECLARE_WRITE16_MEMBER(legionna_background_w);
DECLARE_WRITE16_MEMBER(legionna_midground_w);
DECLARE_WRITE16_MEMBER(legionna_foreground_w);
@ -70,6 +74,8 @@ public:
required_device<okim6295_device> m_oki;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
optional_shared_ptr<UINT16> m_wordswapram;
};
/*----------- defined in video/legionna.c -----------*/

View File

@ -1,4 +1,5 @@
#include "audio/seibu.h"
#include "machine/raiden2cop.h"
class raiden2_state : public driver_device
{
@ -17,7 +18,8 @@ public:
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
tile_buffer(320, 256),
sprite_buffer(320, 256)
sprite_buffer(320, 256),
m_raiden2cop(*this, "raiden2cop")
{ }
UINT16 *back_data, *fore_data, *mid_data, *text_data;
@ -30,18 +32,10 @@ public:
DECLARE_WRITE16_MEMBER( cop_itoa_low_w );
DECLARE_WRITE16_MEMBER( cop_itoa_high_w );
DECLARE_WRITE16_MEMBER( cop_itoa_digit_count_w );
DECLARE_WRITE16_MEMBER( cop_dma_v1_w );
DECLARE_WRITE16_MEMBER( cop_dma_v2_w );
DECLARE_WRITE16_MEMBER( cop_scale_w );
DECLARE_WRITE16_MEMBER( cop_angle_target_w );
DECLARE_WRITE16_MEMBER( cop_angle_step_w );
DECLARE_WRITE16_MEMBER( cop_dma_adr_rel_w );
DECLARE_WRITE16_MEMBER( cop_dma_src_w );
DECLARE_WRITE16_MEMBER( cop_dma_size_w );
DECLARE_WRITE16_MEMBER( cop_dma_dst_w );
DECLARE_READ16_MEMBER( cop_dma_mode_r );
DECLARE_WRITE16_MEMBER( cop_dma_mode_w );
DECLARE_WRITE16_MEMBER( cop_pal_brightness_val_w );
DECLARE_READ16_MEMBER ( cop_reg_high_r );
DECLARE_WRITE16_MEMBER( cop_reg_high_w );
DECLARE_READ16_MEMBER ( cop_reg_low_r );
@ -65,7 +59,6 @@ public:
DECLARE_WRITE16_MEMBER( cop_angle_compare_w );
DECLARE_WRITE16_MEMBER( cop_angle_mod_val_w );
DECLARE_WRITE16_MEMBER ( cop_dma_trigger_w );
DECLARE_WRITE16_MEMBER ( raiden2_bank_w );
DECLARE_READ16_MEMBER ( cop_tile_bank_2_r );
DECLARE_WRITE16_MEMBER ( cop_tile_bank_2_w );
@ -108,9 +101,6 @@ public:
UINT32 cop_regs[8], cop_itoa;
UINT16 cop_status, cop_scale, cop_itoa_digit_count, cop_angle, cop_dist;
UINT8 cop_itoa_digits[10];
UINT16 cop_dma_mode, cop_dma_src[0x200], cop_dma_dst[0x200], cop_dma_size[0x200], cop_dma_v1, cop_dma_v2, cop_dma_adr_rel;
UINT16 sprites_cur_start;
UINT16 pal_brightness_val;
UINT16 cop_func_trigger[0x100/8]; /* function trigger */
UINT16 cop_func_value[0x100/8]; /* function value (?) */
@ -179,13 +169,15 @@ public:
INTERRUPT_GEN_MEMBER(raiden2_interrupt);
UINT16 rps();
UINT16 rpc();
const UINT8 fade_table(int v);
void combine32(UINT32 *val, int offset, UINT16 data, UINT16 mem_mask);
void sprcpt_init(void);
void blend_layer(bitmap_rgb32 &bitmap, const rectangle &cliprect, bitmap_ind16 &source, int layer);
void tilemap_draw_and_blend(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *tilemap);
required_device<raiden2cop_device> m_raiden2cop;
};
/*----------- defined in machine/r2crypt.c -----------*/

View File

@ -0,0 +1,339 @@
/***************************************************************************
Seibu Cop (Co-Processor) emulation
(new implementation, based on Raiden 2 code)
***************************************************************************/
#include "emu.h"
#include "raiden2cop.h"
const device_type RAIDEN2COP = &device_creator<raiden2cop_device>;
raiden2cop_device::raiden2cop_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, RAIDEN2COP, "RAIDEN2COP", tag, owner, clock, "raiden2cop", __FILE__),
m_videoramout_cb(*this),
m_palette(*this, ":palette")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void raiden2cop_device::device_start()
{
m_videoramout_cb.resolve_safe();
}
WRITE16_MEMBER(raiden2cop_device::cop_dma_adr_rel_w)
{
COMBINE_DATA(&cop_dma_adr_rel);
}
WRITE16_MEMBER(raiden2cop_device::cop_dma_v1_w)
{
COMBINE_DATA(&cop_dma_v1);
}
WRITE16_MEMBER(raiden2cop_device::cop_dma_v2_w)
{
COMBINE_DATA(&cop_dma_v2);
}
WRITE16_MEMBER(raiden2cop_device::cop_dma_dst_w)
{
COMBINE_DATA(&cop_dma_dst[cop_dma_mode]);
}
READ16_MEMBER(raiden2cop_device::cop_dma_mode_r)
{
return cop_dma_mode;
}
WRITE16_MEMBER(raiden2cop_device::cop_dma_mode_w)
{
COMBINE_DATA(&cop_dma_mode);
}
WRITE16_MEMBER(raiden2cop_device::cop_dma_src_w)
{
COMBINE_DATA(&cop_dma_src[cop_dma_mode]);
}
WRITE16_MEMBER(raiden2cop_device::cop_dma_size_w)
{
COMBINE_DATA(&cop_dma_size[cop_dma_mode]);
}
WRITE16_MEMBER(raiden2cop_device::cop_pal_brightness_val_w)
{
COMBINE_DATA(&pal_brightness_val);
}
WRITE16_MEMBER(raiden2cop_device::cop_pal_brightness_mode_w)
{
COMBINE_DATA(&pal_brightness_mode);
}
/* RE from Seibu Cup Soccer bootleg */
const UINT8 raiden2cop_device::fade_table(int v)
{
int low = v & 0x001f;
int high = v & 0x03e0;
return (low * (high | (high >> 5)) + 0x210) >> 10;
}
WRITE16_MEMBER(raiden2cop_device::cop_dma_trigger_w)
{
#if 0
if (cop_dma_mode != 0x14 && cop_dma_mode != 0x15)
{
printf("COP DMA mode=%x adr=%x size=%x vals=%x %x %x\n",
cop_dma_mode,
cop_dma_src[cop_dma_mode] << 6,
cop_dma_size[cop_dma_mode] << 4,
cop_dma_v1,
cop_dma_v2,
cop_dma_dst[cop_dma_mode]);
}
#endif
switch (cop_dma_mode)
{
/********************************************************************************************************************/
case 0x14:
{ // ALL games use this - tilemap DMA (RAM -> private buffer)
{
int src = cop_dma_src[cop_dma_mode] << 6;
if (src == 0xcfc0) src = 0xd000; // R2, why?? everything else sets the right pointer (it also sets up odd size / dest regs, they probably counteract this)
for (int i = 0; i < 0x2800 / 2; i++)
{
UINT16 tileval = space.read_word(src);
src += 2;
m_videoramout_cb(space, i, tileval, 0xffff);
}
}
break;
}
/********************************************************************************************************************/
case 0x15:
{ // ALL games use this - palette DMA (RAM -> private buffer)
int src = cop_dma_src[cop_dma_mode] << 6;
for (int i = 0; i < 0x1000 / 2; i++) // todo, use length register
{
UINT16 palval = space.read_word(src);
src += 2;
m_palette->set_pen_color(i, pal5bit(palval >> 0), pal5bit(palval >> 5), pal5bit(palval >> 10));
}
break;
}
/********************************************************************************************************************/
case 0x80:
case 0x81:
case 0x82:
case 0x83:
case 0x84:
case 0x85:
case 0x86:
case 0x87:
{ // these are typically used to transfer palette data from one RAM buffer to another, applying fade values to it prior to the 0x15 transfer
UINT32 src, dst, size, i;
/*
Apparently all of those are just different DMA channels, brightness effects are done through a RAM table and the pal_brightness_val / mode
0x80 is used by Legionnaire
0x81 is used by SD Gundam and Godzilla
0x82 is used by Zero Team and X Se Dae
0x86 is used by Seibu Cup Soccer
0x87 is used by Denjin Makai
TODO:
- Denjin Makai mode 4 is totally guessworked.
- SD Gundam doesn't fade colors correctly, it should have the text layer / sprites with normal gradient and the rest dimmed in most cases,
presumably bad RAM table or bad algorithm
*/
//if(dma_trigger != 0x87)
//printf("SRC: %08x %08x DST:%08x SIZE:%08x TRIGGER: %08x %02x %02x\n",cop_dma_src[cop_dma_mode] << 6,cop_dma_adr_rel * 0x400,cop_dma_dst[cop_dma_mode] << 6,cop_dma_size[cop_dma_mode] << 5,cop_dma_mode,pal_brightness_val,pal_brightness_mode);
src = (cop_dma_src[cop_dma_mode] << 6);
dst = (cop_dma_dst[cop_dma_mode] << 6);
size = ((cop_dma_size[cop_dma_mode] << 5) - (cop_dma_dst[cop_dma_mode] << 6) + 0x20) / 2;
for (i = 0; i < size; i++)
{
UINT16 pal_val;
int r, g, b;
int rt, gt, bt;
if (pal_brightness_mode == 5)
{
bt = ((space.read_word(src + (cop_dma_adr_rel * 0x400))) & 0x7c00) >> 5;
bt = fade_table(bt | (pal_brightness_val ^ 0));
b = ((space.read_word(src)) & 0x7c00) >> 5;
b = fade_table(b | (pal_brightness_val ^ 0x1f));
pal_val = ((b + bt) & 0x1f) << 10;
gt = ((space.read_word(src + (cop_dma_adr_rel * 0x400))) & 0x03e0);
gt = fade_table(gt | (pal_brightness_val ^ 0));
g = ((space.read_word(src)) & 0x03e0);
g = fade_table(g | (pal_brightness_val ^ 0x1f));
pal_val |= ((g + gt) & 0x1f) << 5;
rt = ((space.read_word(src + (cop_dma_adr_rel * 0x400))) & 0x001f) << 5;
rt = fade_table(rt | (pal_brightness_val ^ 0));
r = ((space.read_word(src)) & 0x001f) << 5;
r = fade_table(r | (pal_brightness_val ^ 0x1f));
pal_val |= ((r + rt) & 0x1f);
}
else if (pal_brightness_mode == 4) //Denjin Makai
{
UINT16 targetpaldata = space.read_word(src + (cop_dma_adr_rel * 0x400));
UINT16 paldata = space.read_word(src); // ^1 !!! (why?)
bt = (targetpaldata & 0x7c00) >> 10;
b = (paldata & 0x7c00) >> 10;
gt = (targetpaldata & 0x03e0) >> 5;
g = (paldata & 0x03e0) >> 5;
rt = (targetpaldata & 0x001f) >> 0;
r = (paldata & 0x001f) >> 0;
if (pal_brightness_val == 0x10)
pal_val = bt << 10 | gt << 5 | rt << 0;
else if (pal_brightness_val == 0xff) // TODO: might be the back plane or it still doesn't do any mod, needs PCB tests
pal_val = 0;
else
{
bt = fade_table(bt << 5 | ((pal_brightness_val * 2) ^ 0));
b = fade_table(b << 5 | ((pal_brightness_val * 2) ^ 0x1f));
pal_val = ((b + bt) & 0x1f) << 10;
gt = fade_table(gt << 5 | ((pal_brightness_val * 2) ^ 0));
g = fade_table(g << 5 | ((pal_brightness_val * 2) ^ 0x1f));
pal_val |= ((g + gt) & 0x1f) << 5;
rt = fade_table(rt << 5 | ((pal_brightness_val * 2) ^ 0));
r = fade_table(r << 5 | ((pal_brightness_val * 2) ^ 0x1f));
pal_val |= ((r + rt) & 0x1f);
}
}
else
{
printf("Warning: palette DMA used with mode %02x!\n", pal_brightness_mode);
pal_val = space.read_word(src);
}
space.write_word(dst, pal_val);
src += 2;
dst += 2;
}
break;
}
/********************************************************************************************************************/
case 0x09: {
UINT32 src, dst, size;
int i;
src = (cop_dma_src[cop_dma_mode] << 6);
dst = (cop_dma_dst[cop_dma_mode] << 6);
size = ((cop_dma_size[cop_dma_mode] << 5) - (cop_dma_dst[cop_dma_mode] << 6) + 0x20) / 2;
// printf("%08x %08x %08x\n",src,dst,size);
for (i = 0; i < size; i++)
{
space.write_word(dst, space.read_word(src));
src += 2;
dst += 2;
}
break;
}
/********************************************************************************************************************/
case 0x0e: // Godzilla / Seibu Cup Soccer
{
UINT32 src, dst, size, i;
src = (cop_dma_src[cop_dma_mode] << 6);
dst = (cop_dma_dst[cop_dma_mode] << 6);
size = ((cop_dma_size[cop_dma_mode] << 5) - (cop_dma_dst[cop_dma_mode] << 6) + 0x20) / 2;
for (i = 0; i < size; i++)
{
space.write_word(dst, space.read_word(src));
src += 2;
dst += 2;
}
break;
}
/********************************************************************************************************************/
case 0x116: // Godzilla
{
UINT32 length, address;
int i;
//if(cop_dma_dst[cop_dma_mode] != 0x0000) // Invalid?
// return;
address = (cop_dma_src[cop_dma_mode] << 6);
length = ((cop_dma_size[cop_dma_mode] + 1) << 4);
for (i = address; i < address + length; i += 4)
{
space.write_dword(i, (cop_dma_v1) | (cop_dma_v2 << 16));
}
break;
}
/********************************************************************************************************************/
case 0x118:
case 0x119:
case 0x11a:
case 0x11b:
case 0x11c:
case 0x11d:
case 0x11e:
case 0x11f: {
UINT32 length, address;
int i;
if (cop_dma_dst[cop_dma_mode] != 0x0000) // Invalid?
return;
address = (cop_dma_src[cop_dma_mode] << 6);
length = (cop_dma_size[cop_dma_mode] + 1) << 5;
//printf("%08x %08x\n",address,length);
for (i = address; i < address + length; i += 4)
{
space.write_dword(i, (cop_dma_v1) | (cop_dma_v2 << 16));
}
/*
UINT32 length, address;
int i;
if(cop_dma_dst[cop_dma_mode] != 0x0000) // Invalid?
return;
address = (cop_dma_src[cop_dma_mode] << 6);
length = (cop_dma_size[cop_dma_mode]+1) << 5;
//printf("%08x %08x\n",address,length);
for (i=address;i<address+length;i+=4)
{
space.write_dword(i, m_fill_val);
}
*/
break;
}
}
}

View File

@ -0,0 +1,61 @@
/***************************************************************************
Seibu Cop (Co-Processor) emulation
(new implementation, based on Raiden 2 code)
***************************************************************************/
#ifndef RAIDEN2COP_H
#define RAIDEN2COP_H
#define MCFG_RAIDEN2COP_ADD(_tag ) \
MCFG_DEVICE_ADD(_tag, RAIDEN2COP, 0)
#define MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(_devcb) \
devcb = &raiden2cop_device::set_m_videoramout_cb(*device, DEVCB_##_devcb);
class raiden2cop_device : public device_t
{
public:
raiden2cop_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
UINT16 cop_dma_v1, cop_dma_v2, cop_dma_mode;
UINT16 cop_dma_src[0x200], cop_dma_dst[0x200], cop_dma_size[0x200];
UINT16 cop_dma_adr_rel;
UINT16 pal_brightness_val;
UINT16 pal_brightness_mode;
DECLARE_WRITE16_MEMBER( cop_dma_v1_w );
DECLARE_WRITE16_MEMBER( cop_dma_v2_w );
DECLARE_WRITE16_MEMBER( cop_dma_adr_rel_w );
DECLARE_WRITE16_MEMBER( cop_dma_src_w );
DECLARE_WRITE16_MEMBER( cop_dma_size_w );
DECLARE_WRITE16_MEMBER( cop_dma_dst_w );
DECLARE_READ16_MEMBER( cop_dma_mode_r );
DECLARE_WRITE16_MEMBER( cop_dma_mode_w );
DECLARE_WRITE16_MEMBER( cop_pal_brightness_val_w );
DECLARE_WRITE16_MEMBER( cop_pal_brightness_mode_w );
DECLARE_WRITE16_MEMBER ( cop_dma_trigger_w );
const UINT8 fade_table(int v);
template<class _Object> static devcb_base &set_m_videoramout_cb(device_t &device, _Object object) { return downcast<raiden2cop_device &>(device).m_videoramout_cb.set_callback(object); }
protected:
// device-level overrides
virtual void device_start();
private:
// internal state
devcb_write16 m_videoramout_cb;
required_device<palette_device> m_palette;
};
extern const device_type RAIDEN2COP;
#endif /* RAIDEN2COP_H */

View File

@ -1607,8 +1607,6 @@ seibu_cop_legacy_device::seibu_cop_legacy_device(const machine_config &mconfig,
m_cop_438(0),
m_cop_43a(0),
m_cop_43c(0),
m_cop_dma_fade_table(0),
m_cop_dma_trigger(0),
m_cop_scale(0),
m_cop_rng_max_value(0),
m_copd2_offs(0),
@ -1632,23 +1630,17 @@ seibu_cop_legacy_device::seibu_cop_legacy_device(const machine_config &mconfig,
m_cop_rom_addr_unk(0),
m_u1(0),
m_u2(0),
m_fill_val(0),
m_pal_brightness_val(0),
m_pal_brightness_mode(0),
m_cop_sprite_dma_src(0),
m_cop_sprite_dma_abs_x(0),
m_cop_sprite_dma_abs_y(0),
m_cop_sprite_dma_size(0),
m_cop_sprite_dma_param(0),
m_videoramout_cb(*this)
m_raiden2cop(*this, ":raiden2cop")
{
memset(m_copd2_table, 0, sizeof(UINT16)*0x100);
memset(m_copd2_table_2, 0, sizeof(UINT16)*0x100/8);
memset(m_copd2_table_3, 0, sizeof(UINT16)*0x100/8);
memset(m_copd2_table_4, 0, sizeof(UINT16)*0x100/8);
memset(m_cop_dma_src, 0, sizeof(UINT16)*0x200);
memset(m_cop_dma_size, 0, sizeof(UINT16)*0x200);
memset(m_cop_dma_dst, 0, sizeof(UINT16)*0x200);
memset(m_seibu_vregs, 0, sizeof(UINT16)*0x50/2);
for (int i = 0; i < 8; i++)
@ -1674,13 +1666,12 @@ void seibu_cop_legacy_device::device_config_complete()
void seibu_cop_legacy_device::device_start()
{
m_cop_mcu_ram = reinterpret_cast<UINT16 *>(machine().root_device().memshare("cop_mcu_ram")->ptr());
m_videoramout_cb.resolve_safe();
save_item(NAME(m_cop_438));
save_item(NAME(m_cop_43a));
save_item(NAME(m_cop_43c));
save_item(NAME(m_cop_dma_fade_table));
save_item(NAME(m_cop_dma_trigger));
//save_item(NAME(m_cop_dma_fade_table));
//save_item(NAME(m_cop_dma_trigger));
save_item(NAME(m_cop_scale));
save_item(NAME(m_cop_rng_max_value));
save_item(NAME(m_copd2_offs));
@ -1704,9 +1695,9 @@ void seibu_cop_legacy_device::device_start()
save_item(NAME(m_cop_rom_addr_unk));
save_item(NAME(m_u1));
save_item(NAME(m_u2));
save_item(NAME(m_fill_val));
save_item(NAME(m_pal_brightness_val));
save_item(NAME(m_pal_brightness_mode));
// save_item(NAME(m_fill_val));
// save_item(NAME(m_pal_brightness_val));
// save_item(NAME(m_pal_brightness_mode));
save_item(NAME(m_cop_sprite_dma_src));
save_item(NAME(m_cop_sprite_dma_abs_x));
save_item(NAME(m_cop_sprite_dma_abs_y));
@ -1716,9 +1707,9 @@ void seibu_cop_legacy_device::device_start()
save_item(NAME(m_copd2_table_2));
save_item(NAME(m_copd2_table_3));
save_item(NAME(m_copd2_table_4));
save_item(NAME(m_cop_dma_src));
save_item(NAME(m_cop_dma_size));
save_item(NAME(m_cop_dma_dst));
// save_item(NAME(m_cop_dma_src));
// save_item(NAME(m_cop_dma_size));
// save_item(NAME(m_cop_dma_dst));
save_item(NAME(m_seibu_vregs));
}
@ -2216,6 +2207,7 @@ WRITE16_MEMBER( seibu_cop_legacy_device::copdxbl_0_w )
which seems common to all the games
*/
#if 0
/* RE from Seibu Cup Soccer bootleg */
static const UINT8 fade_table(int v)
{
@ -2224,7 +2216,7 @@ static const UINT8 fade_table(int v)
return (low * (high | (high >> 5)) + 0x210) >> 10;
}
#endif
#define COP_CMD(_1_,_2_,_3_,_4_,_5_,_6_,_7_,_8_,_m_u1_,_m_u2_) \
(m_copd2_table[command+0] == _1_ && m_copd2_table[command+1] == _2_ && m_copd2_table[command+2] == _3_ && m_copd2_table[command+3] == _4_ && \
@ -2430,10 +2422,12 @@ WRITE16_MEMBER( seibu_cop_legacy_device::generic_cop_w )
*/
break;
case (0x028/2):
case (0x02a/2):
m_fill_val = (m_cop_mcu_ram[0x028/2]) | (m_cop_mcu_ram[0x02a/2] << 16);
break;
// ram fill
case (0x028 / 2) : m_raiden2cop->cop_dma_v1_w(space, offset, data, mem_mask); break;
case (0x02a / 2) : m_raiden2cop->cop_dma_v2_w(space, offset, data, mem_mask); break;
/* max possible value returned by the RNG at 0x5a*, trusted */
case (0x02c/2): m_cop_rng_max_value = m_cop_mcu_ram[0x2c/2] & 0xff; break;
@ -2459,9 +2453,9 @@ WRITE16_MEMBER( seibu_cop_legacy_device::generic_cop_w )
case (0x04a/2): { m_cop_rom_addr_hi = data & 0xffff; break; }
/* brightness control */
case (0x05a/2): m_pal_brightness_val = data & 0xff; break;
case (0x05c/2): m_pal_brightness_mode = data & 0xff; break;
case (0x05a / 2) : m_raiden2cop->cop_pal_brightness_val_w(space, offset, data, mem_mask); break;
case (0x05c / 2) : m_raiden2cop->cop_pal_brightness_mode_w(space, offset, data, mem_mask); break;
/* DMA / layer clearing section */
case (0x074/2):
/*
@ -2475,44 +2469,19 @@ WRITE16_MEMBER( seibu_cop_legacy_device::generic_cop_w )
*/
break;
/* used in palette DMAs, for fading effects */
case (0x076/2):
m_cop_dma_fade_table = data;
break;
case (0x076 / 2) : m_raiden2cop->cop_dma_adr_rel_w(space, offset, data, mem_mask); break; /* used in palette DMAs, for fading effects */
case (0x078 / 2) : m_raiden2cop->cop_dma_src_w(space, offset, data, mem_mask); break; /* DMA source address */
case (0x07a / 2) : m_raiden2cop->cop_dma_size_w(space, offset, data, mem_mask); break;/* DMA length */
case (0x07c/2): m_raiden2cop->cop_dma_dst_w(space, offset, data, mem_mask); break; /* DMA destination */
case (0x07e/2): m_raiden2cop->cop_dma_mode_w(space, offset, data, mem_mask); break; /* DMA parameter */
case (0x078/2): /* DMA source address */
{
m_cop_dma_src[m_cop_dma_trigger] = data; // << 6 to get actual address
//seibu_cop_log("%06x: COPX set layer clear address to %04x (actual %08x)\n", space.device().safe_pc(), data, data<<6);
break;
}
case (0x07a/2): /* DMA length */
{
m_cop_dma_size[m_cop_dma_trigger] = data;
//seibu_cop_log("%06x: COPX set layer clear length to %04x (actual %08x)\n", space.device().safe_pc(), data, data<<5);
break;
}
case (0x07c/2): /* DMA destination */
{
m_cop_dma_dst[m_cop_dma_trigger] = data;
//seibu_cop_log("%06x: COPX set layer clear value to %04x (actual %08x)\n", space.device().safe_pc(), data, data<<6);
break;
}
case (0x07e/2): /* DMA parameter */
{
m_cop_dma_trigger = data;
//seibu_cop_log("%06x: COPX set layer clear trigger? to %04x\n", space.device().safe_pc(), data);
if (data>=0x1ff)
{
seibu_cop_log("invalid DMA trigger!, >0x1ff\n");
m_cop_dma_trigger = 0;
}
break;
}
case (0x08c/2): m_cop_sprite_dma_abs_y = (m_cop_mcu_ram[0x08c/2]); break;
case (0x08e/2): m_cop_sprite_dma_abs_x = (m_cop_mcu_ram[0x08e/2]); break;
@ -3088,191 +3057,8 @@ WRITE16_MEMBER( seibu_cop_legacy_device::generic_cop_w )
}
/* DMA go register */
case (0x2fc/2):
{
//seibu_cop_log("%06x: COPX execute current layer clear??? %04x\n", space.device().safe_pc(), data);
//printf("SRC: %08x %08x DST:%08x SIZE:%08x TRIGGER: %08x\n",m_cop_dma_src[m_cop_dma_trigger] << 6,m_cop_dma_fade_table,m_cop_dma_dst[m_cop_dma_trigger] << 6,m_cop_dma_size[m_cop_dma_trigger] << 5,m_cop_dma_trigger);
case (0x2fc/2): m_raiden2cop->cop_dma_trigger_w(space, offset, data, mem_mask); break;
if (m_cop_dma_trigger >= 0x80 && m_cop_dma_trigger <= 0x87)
{
UINT32 src,dst,size,i;
/*
Apparently all of those are just different DMA channels, brightness effects are done through a RAM table and the m_pal_brightness_val / mode
0x80 is used by Legionnaire
0x81 is used by SD Gundam and Godzilla
0x82 is used by Zero Team and X Se Dae
0x86 is used by Seibu Cup Soccer
0x87 is used by Denjin Makai
TODO:
- Denjin Makai mode 4 is totally guessworked.
- SD Gundam doesn't fade colors correctly, it should have the text layer / sprites with normal gradient and the rest dimmed in most cases,
presumably bad RAM table or bad algorithm
*/
//if(dma_trigger != 0x87)
//printf("SRC: %08x %08x DST:%08x SIZE:%08x TRIGGER: %08x %02x %02x\n",m_cop_dma_src[m_cop_dma_trigger] << 6,m_cop_dma_fade_table * 0x400,m_cop_dma_dst[m_cop_dma_trigger] << 6,m_cop_dma_size[m_cop_dma_trigger] << 5,m_cop_dma_trigger,m_pal_brightness_val,m_pal_brightness_mode);
src = (m_cop_dma_src[m_cop_dma_trigger] << 6);
dst = (m_cop_dma_dst[m_cop_dma_trigger] << 6);
size = ((m_cop_dma_size[m_cop_dma_trigger] << 5) - (m_cop_dma_dst[m_cop_dma_trigger] << 6) + 0x20)/2;
for(i = 0;i < size;i++)
{
UINT16 pal_val;
int r,g,b;
int rt,gt,bt;
if(m_pal_brightness_mode == 5)
{
bt = ((space.read_word(src + (m_cop_dma_fade_table * 0x400))) & 0x7c00) >> 5;
bt = fade_table(bt|(m_pal_brightness_val ^ 0));
b = ((space.read_word(src)) & 0x7c00) >> 5;
b = fade_table(b|(m_pal_brightness_val ^ 0x1f));
pal_val = ((b + bt) & 0x1f) << 10;
gt = ((space.read_word(src + (m_cop_dma_fade_table * 0x400))) & 0x03e0);
gt = fade_table(gt|(m_pal_brightness_val ^ 0));
g = ((space.read_word(src)) & 0x03e0);
g = fade_table(g|(m_pal_brightness_val ^ 0x1f));
pal_val |= ((g + gt) & 0x1f) << 5;
rt = ((space.read_word(src + (m_cop_dma_fade_table * 0x400))) & 0x001f) << 5;
rt = fade_table(rt|(m_pal_brightness_val ^ 0));
r = ((space.read_word(src)) & 0x001f) << 5;
r = fade_table(r|(m_pal_brightness_val ^ 0x1f));
pal_val |= ((r + rt) & 0x1f);
}
else if(m_pal_brightness_mode == 4) //Denjin Makai
{
bt =(space.read_word(src + (m_cop_dma_fade_table * 0x400)) & 0x7c00) >> 10;
b = (space.read_word(src) & 0x7c00) >> 10;
gt =(space.read_word(src + (m_cop_dma_fade_table * 0x400)) & 0x03e0) >> 5;
g = (space.read_word(src) & 0x03e0) >> 5;
rt =(space.read_word(src + (m_cop_dma_fade_table * 0x400)) & 0x001f) >> 0;
r = (space.read_word(src) & 0x001f) >> 0;
if(m_pal_brightness_val == 0x10)
pal_val = bt << 10 | gt << 5 | rt << 0;
else if(m_pal_brightness_val == 0xff) // TODO: might be the back plane or it still doesn't do any mod, needs PCB tests
pal_val = 0;
else
{
bt = fade_table(bt<<5|((m_pal_brightness_val*2) ^ 0));
b = fade_table(b<<5|((m_pal_brightness_val*2) ^ 0x1f));
pal_val = ((b + bt) & 0x1f) << 10;
gt = fade_table(gt<<5|((m_pal_brightness_val*2) ^ 0));
g = fade_table(g<<5|((m_pal_brightness_val*2) ^ 0x1f));
pal_val |= ((g + gt) & 0x1f) << 5;
rt = fade_table(rt<<5|((m_pal_brightness_val*2) ^ 0));
r = fade_table(r<<5|((m_pal_brightness_val*2) ^ 0x1f));
pal_val |= ((r + rt) & 0x1f);
}
}
else
{
printf("Warning: palette DMA used with mode %02x!\n",m_pal_brightness_mode);
pal_val = space.read_word(src);
}
space.write_word(dst, pal_val);
src+=2;
dst+=2;
}
return;
}
/* Seibu Cup Soccer trigger this*/
if (m_cop_dma_trigger == 0x0e)
{
UINT32 src,dst,size,i;
src = (m_cop_dma_src[m_cop_dma_trigger] << 6);
dst = (m_cop_dma_dst[m_cop_dma_trigger] << 6);
size = ((m_cop_dma_size[m_cop_dma_trigger] << 5) - (m_cop_dma_dst[m_cop_dma_trigger] << 6) + 0x20)/2;
for(i = 0;i < size;i++)
{
space.write_word(dst, space.read_word(src));
src+=2;
dst+=2;
}
return;
}
/* do the fill */
if (m_cop_dma_trigger >= 0x118 && m_cop_dma_trigger <= 0x11f)
{
UINT32 length, address;
int i;
if(m_cop_dma_dst[m_cop_dma_trigger] != 0x0000) // Invalid?
return;
address = (m_cop_dma_src[m_cop_dma_trigger] << 6);
length = (m_cop_dma_size[m_cop_dma_trigger]+1) << 5;
//printf("%08x %08x\n",address,length);
for (i=address;i<address+length;i+=4)
{
space.write_dword(i, m_fill_val);
}
return;
}
/* Godzilla specific */
if (m_cop_dma_trigger == 0x116)
{
UINT32 length, address;
int i;
//if(m_cop_dma_dst[m_cop_dma_trigger] != 0x0000) // Invalid?
// return;
address = (m_cop_dma_src[m_cop_dma_trigger] << 6);
length = ((m_cop_dma_size[m_cop_dma_trigger]+1) << 4);
for (i=address;i<address+length;i+=4)
{
space.write_dword(i, m_fill_val);
}
return;
}
/* private buffer copies - tilemaps */
if (m_cop_dma_trigger == 0x14)
{
// AM_RANGE(0x101000, 0x1017ff) AM_RAM // _WRITE(legionna_background_w) AM_SHARE("back_data")
// AM_RANGE(0x101800, 0x101fff) AM_RAM // _WRITE(legionna_foreground_w) AM_SHARE("fore_data")
// AM_RANGE(0x102000, 0x1027ff) AM_RAM // _WRITE(legionna_midground_w) AM_SHARE("mid_data")
// AM_RANGE(0x102800, 0x1037ff) AM_RAM // _WRITE(legionna_text_w) AM_SHARE("textram")
int src = m_cop_dma_src[m_cop_dma_trigger] << 6;
for (int i = 0; i < 0x2800 /2; i++)
{
UINT16 tileval = space.read_word(src);
//printf("reading source %04x (data is %04x)\n", src, data);
src += 2;
m_videoramout_cb(space, i, tileval, 0xffff);
}
return;
}
/* private buffer copy - palette? */
if (m_cop_dma_trigger == 0x15)
{
//printf("SRC: %08x %08x DST:%08x SIZE:%08x TRIGGER: %08x\n",m_cop_dma_src[m_cop_dma_trigger] << 6,m_cop_dma_fade_table,m_cop_dma_dst[m_cop_dma_trigger] << 6,m_cop_dma_size[m_cop_dma_trigger] << 5,m_cop_dma_trigger);
}
return;
printf("SRC: %08x %08x DST:%08x SIZE:%08x TRIGGER: %08x\n",m_cop_dma_src[m_cop_dma_trigger] << 6,m_cop_dma_fade_table,m_cop_dma_dst[m_cop_dma_trigger] << 6,m_cop_dma_size[m_cop_dma_trigger] << 5,m_cop_dma_trigger);
break;
}
/* sort-DMA, oh my ... */
case (0x054/2): { m_cop_sort_lookup = (m_cop_sort_lookup&0x0000ffff)|(m_cop_mcu_ram[offset]<<16); break; }

View File

@ -1,4 +1,6 @@
#include "raiden2cop.h"
struct collision_info
{
collision_info():
@ -18,8 +20,6 @@ struct collision_info
UINT16 hitbox_x,hitbox_y;
};
#define MCFG_VIDEORAM_OUT_CB(_devcb) \
devcb = &seibu_cop_legacy_device::set_m_videoramout_cb(*device, DEVCB_##_devcb);
class seibu_cop_legacy_device : public device_t
{
@ -44,10 +44,6 @@ seibu_cop_legacy_device(const machine_config &mconfig, const char *tag, device_t
DECLARE_READ16_MEMBER( legionna_mcu_r );
DECLARE_WRITE16_MEMBER( legionna_mcu_w );
//DECLARE_READ16_MEMBER( raiden2_mcu_r ); unused
//DECLARE_WRITE16_MEMBER( raiden2_mcu_w ); unused
template<class _Object> static devcb_base &set_m_videoramout_cb(device_t &device, _Object object) { return downcast<seibu_cop_legacy_device &>(device).m_videoramout_cb.set_callback(object); }
protected:
// device-level overrides
virtual void device_config_complete();
@ -63,11 +59,7 @@ private:
UINT16 m_cop_438;
UINT16 m_cop_43a;
UINT16 m_cop_43c;
UINT16 m_cop_dma_src[0x200];
UINT16 m_cop_dma_size[0x200];
UINT16 m_cop_dma_dst[0x200];
UINT16 m_cop_dma_fade_table;
UINT16 m_cop_dma_trigger;
UINT16 m_cop_scale;
UINT8 m_cop_rng_max_value;
UINT16 m_copd2_offs;
@ -83,8 +75,7 @@ private:
int m_r0, m_r1;
UINT16 m_cop_rom_addr_lo,m_cop_rom_addr_hi,m_cop_rom_addr_unk;
UINT16 m_u1,m_u2;
UINT32 m_fill_val;
UINT8 m_pal_brightness_val,m_pal_brightness_mode;
UINT32 m_cop_sprite_dma_src;
int m_cop_sprite_dma_abs_x,m_cop_sprite_dma_abs_y,m_cop_sprite_dma_size;
UINT32 m_cop_sprite_dma_param;
@ -96,7 +87,8 @@ private:
UINT8 cop_calculate_collsion_detection();
DECLARE_READ16_MEMBER( generic_cop_r );
DECLARE_WRITE16_MEMBER( generic_cop_w );
devcb_write16 m_videoramout_cb;
required_device<raiden2cop_device> m_raiden2cop;
};
@ -104,3 +96,4 @@ extern const device_type SEIBU_COP_LEGACY;
#define MCFG_SEIBU_COP_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, SEIBU_COP_LEGACY, 0)

View File

@ -515,7 +515,6 @@ MACHINES += SATURN
MACHINES += SCSI
MACHINES += SCUDSP
#MACHINES += SECFLASH
MACHINES += SEIBU_COP
MACHINES += SERFLASH
MACHINES += SMC91C9X
MACHINES += SMPC
@ -1766,6 +1765,7 @@ $(MAMEOBJ)/seibu.a: \
$(DRIVERS)/panicr.o \
$(DRIVERS)/raiden.o $(VIDEO)/raiden.o \
$(DRIVERS)/raiden2.o $(MACHINE)/r2crypt.o \
$(MACHINE)/raiden2cop.o \
$(DRIVERS)/r2dx_v33.o \
$(DRIVERS)/seibuspi.o $(MACHINE)/seibuspi.o $(VIDEO)/seibuspi.o \
$(DRIVERS)/sengokmj.o \