mirror of
https://github.com/holub/mame
synced 2025-07-06 02:18:09 +03:00
DMA hooked up
This commit is contained in:
parent
9c8255b28a
commit
d8e4cef532
@ -20,8 +20,8 @@ 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(dma_fill_val_lo_w)
|
||||
AM_RANGE(0x042a, 0x042b) AM_WRITE(dma_fill_val_hi_w)
|
||||
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)
|
||||
@ -91,8 +91,12 @@ void seibu_cop_device::device_config_complete()
|
||||
// or initialize to defaults if none provided
|
||||
else
|
||||
{
|
||||
memset(&m_in_mreq_cb, 0, sizeof(m_in_mreq_cb));
|
||||
memset(&m_out_mreq_cb, 0, sizeof(m_out_mreq_cb));
|
||||
memset(&m_in_byte_cb, 0, sizeof(m_in_byte_cb));
|
||||
memset(&m_in_word_cb, 0, sizeof(m_in_word_cb));
|
||||
memset(&m_in_dword_cb, 0, sizeof(m_in_dword_cb));
|
||||
memset(&m_out_byte_cb, 0, sizeof(m_out_byte_cb));
|
||||
memset(&m_out_word_cb, 0, sizeof(m_out_word_cb));
|
||||
memset(&m_out_dword_cb, 0, sizeof(m_out_dword_cb));
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,6 +116,13 @@ void seibu_cop_device::device_validity_check(validity_checker &valid) const
|
||||
|
||||
void seibu_cop_device::device_start()
|
||||
{
|
||||
// resolve callbacks
|
||||
m_in_byte_func.resolve(m_in_byte_cb, *this);
|
||||
m_in_word_func.resolve(m_in_word_cb, *this);
|
||||
m_in_word_func.resolve(m_in_dword_cb, *this);
|
||||
m_out_byte_func.resolve(m_out_byte_cb, *this);
|
||||
m_out_word_func.resolve(m_out_word_cb, *this);
|
||||
m_out_dword_func.resolve(m_out_dword_cb, *this);
|
||||
|
||||
}
|
||||
|
||||
@ -138,16 +149,16 @@ const address_space_config *seibu_cop_device::memory_space_config(address_spacen
|
||||
// READ/WRITE HANDLERS
|
||||
//**************************************************************************
|
||||
|
||||
WRITE16_MEMBER(seibu_cop_device::dma_fill_val_lo_w)
|
||||
WRITE16_MEMBER(seibu_cop_device::fill_val_lo_w)
|
||||
{
|
||||
COMBINE_DATA(&m_dma_fill_val_lo);
|
||||
m_dma_fill_val = (m_dma_fill_val_lo) | (m_dma_fill_val_hi << 16);
|
||||
COMBINE_DATA(&m_fill_val_lo);
|
||||
m_fill_val = (m_fill_val_lo) | (m_fill_val_hi << 16);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(seibu_cop_device::dma_fill_val_hi_w)
|
||||
WRITE16_MEMBER(seibu_cop_device::fill_val_hi_w)
|
||||
{
|
||||
COMBINE_DATA(&m_dma_fill_val_hi);
|
||||
m_dma_fill_val = (m_dma_fill_val_lo) | (m_dma_fill_val_hi << 16);
|
||||
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)
|
||||
@ -204,6 +215,10 @@ WRITE16_MEMBER(seibu_cop_device::dma_trigger_w)
|
||||
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));
|
||||
@ -213,3 +228,163 @@ 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_func(dst, m_in_word_func(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_func(src + (m_dma_pal_fade_table * 0x400))) & 0x7c00) >> 5;
|
||||
bt = fade_table(bt|(m_pal_brightness_val ^ 0));
|
||||
b = ((m_in_word_func(src)) & 0x7c00) >> 5;
|
||||
b = fade_table(b|(m_pal_brightness_val ^ 0x1f));
|
||||
pal_val = ((b + bt) & 0x1f) << 10;
|
||||
gt = ((m_in_word_func(src + (m_dma_pal_fade_table * 0x400))) & 0x03e0);
|
||||
gt = fade_table(gt|(m_pal_brightness_val ^ 0));
|
||||
g = ((m_in_word_func(src)) & 0x03e0);
|
||||
g = fade_table(g|(m_pal_brightness_val ^ 0x1f));
|
||||
pal_val |= ((g + gt) & 0x1f) << 5;
|
||||
rt = ((m_in_word_func(src + (m_dma_pal_fade_table * 0x400))) & 0x001f) << 5;
|
||||
rt = fade_table(rt|(m_pal_brightness_val ^ 0));
|
||||
r = ((m_in_word_func(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_func(src + (m_dma_pal_fade_table * 0x400)) & 0x7c00) >> 10;
|
||||
b = (m_in_word_func(src) & 0x7c00) >> 10;
|
||||
gt =(m_in_word_func(src + (m_dma_pal_fade_table * 0x400)) & 0x03e0) >> 5;
|
||||
g = (m_in_word_func(src) & 0x03e0) >> 5;
|
||||
rt =(m_in_word_func(src + (m_dma_pal_fade_table * 0x400)) & 0x001f) >> 0;
|
||||
r = (m_in_word_func(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_func(src);
|
||||
}
|
||||
|
||||
m_out_word_func(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_func(i, m_fill_val);
|
||||
}
|
||||
}
|
||||
|
||||
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_func(i, m_fill_val);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE16_MEMBER( seibu_cop_device::dma_write_trigger_w )
|
||||
{
|
||||
switch(m_dma_exec_param & 0x1f8)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,12 @@ Template for skeleton device
|
||||
struct seibu_cop_interface
|
||||
{
|
||||
// memory accessors
|
||||
devcb_read8 m_in_mreq_cb;
|
||||
devcb_write8 m_out_mreq_cb;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@ -47,8 +51,9 @@ public:
|
||||
// I/O operations
|
||||
DECLARE_WRITE16_MEMBER( write );
|
||||
DECLARE_READ16_MEMBER( read );
|
||||
DECLARE_WRITE16_MEMBER(dma_fill_val_lo_w);
|
||||
DECLARE_WRITE16_MEMBER(dma_fill_val_hi_w);
|
||||
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);
|
||||
@ -67,18 +72,28 @@ protected:
|
||||
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
|
||||
|
||||
private:
|
||||
devcb_resolved_read8 m_in_mreq_func;
|
||||
devcb_resolved_write8 m_out_mreq_func;
|
||||
devcb_resolved_read16 m_in_byte_func;
|
||||
devcb_resolved_read16 m_in_word_func;
|
||||
devcb_resolved_read16 m_in_dword_func;
|
||||
devcb_resolved_write16 m_out_byte_func;
|
||||
devcb_resolved_write16 m_out_word_func;
|
||||
devcb_resolved_write16 m_out_dword_func;
|
||||
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_dma_fill_val_lo,m_dma_fill_val_hi;
|
||||
UINT32 m_dma_fill_val;
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user