DMA hooked up

This commit is contained in:
Angelo Salese 2012-09-30 23:08:53 +00:00
parent 9c8255b28a
commit d8e4cef532
2 changed files with 208 additions and 18 deletions

View File

@ -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);
}
}

View File

@ -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);
};