Added bread-and-butter DMA CH 0 for SH7032, used by Casio Loopy for RAM fill.

This commit is contained in:
angelosa 2015-07-08 01:03:17 +02:00
parent b58f781202
commit 7fae92816c
3 changed files with 79 additions and 3 deletions

View file

@ -154,7 +154,9 @@ static ADDRESS_MAP_START( sh7021_map, AS_PROGRAM, 32, sh2a_device )
// overrides
AM_RANGE(0x05ffff40, 0x05ffff43) AM_READWRITE(dma_sar0_r, dma_sar0_w)
AM_RANGE(0x05ffff44, 0x05ffff47) AM_READWRITE(dma_dar0_r, dma_dar0_w)
AM_RANGE(0x05ffff48, 0x05ffff4b) AM_READWRITE16(dmaor_r, dmaor_w,0xffff0000)
AM_RANGE(0x05ffff48, 0x05ffff4b) AM_READWRITE16(dma_tcr0_r, dma_tcr0_w,0x0000ffff)
AM_RANGE(0x05ffff4c, 0x05ffff4f) AM_READWRITE16(dma_chcr0_r, dma_chcr0_w, 0x0000ffff)
// fall-back
AM_RANGE(0x05fffe00, 0x05ffffff) AM_READWRITE16(sh7021_r,sh7021_w,0xffffffff) // SH-7032H internal i/o
// AM_RANGE(0x07000000, 0x070003ff) AM_RAM AM_SHARE("oram")// on-chip RAM, actually at 0xf000000 (1 kb)

View file

@ -149,6 +149,7 @@ protected:
virtual UINT32 disasm_min_opcode_bytes() const { return 2; }
virtual UINT32 disasm_max_opcode_bytes() const { return 2; }
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
address_space *m_program, *m_decrypted_program;
private:
address_space_config m_program_config, m_decrypted_program_config;
@ -195,7 +196,6 @@ private:
UINT32 m_pcflushes[16]; // pcflush entries
INT8 m_irq_line_state[17];
address_space *m_program, *m_decrypted_program;
protected:
direct_read_data *m_direct;
private:
@ -504,11 +504,16 @@ public:
DECLARE_WRITE32_MEMBER(dma_sar0_w);
DECLARE_READ32_MEMBER(dma_dar0_r);
DECLARE_WRITE32_MEMBER(dma_dar0_w);
DECLARE_READ16_MEMBER(dmaor_r);
DECLARE_WRITE16_MEMBER(dmaor_w);
DECLARE_READ16_MEMBER(dma_tcr0_r);
DECLARE_WRITE16_MEMBER(dma_tcr0_w);
DECLARE_READ16_MEMBER(dma_chcr0_r);
DECLARE_WRITE16_MEMBER(dma_chcr0_w);
DECLARE_READ16_MEMBER(sh7021_r);
DECLARE_WRITE16_MEMBER(sh7021_w);
void sh7032_dma_exec(int ch);
private:
UINT16 m_sh7021_regs[0x200];
struct
@ -516,7 +521,9 @@ private:
UINT32 sar; /**< Source Address Register */
UINT32 dar; /**< Destination Address Register */
UINT16 tcr; /**< Transfer Count Register */
UINT16 chcr; /**< Channel Control Register */
} m_dma[4];
UINT16 m_dmaor; /**< DMA Operation Register (status flags) */
};

View file

@ -885,6 +885,50 @@ void sh2_device::sh2_exception(const char *message, int irqline)
/*
SH-7021 on-chip device
*/
void sh2a_device::sh7032_dma_exec(int ch)
{
const short dma_word_size[4] = { 0, +1, -1, 0 };
UINT8 rs = (m_dma[ch].chcr >> 8) & 0xf; /**< Resource Select bits */
if(rs != 0xc) // Auto-Request
{
logerror("Warning: SH7032 DMA enables non auto-request transfer\n");
return;
}
// channel enable & master enable
if((m_dma[ch].chcr & 1) == 0 || (m_dmaor & 1) == 0)
return;
printf("%08x %08x %04x\n",m_dma[ch].sar,m_dma[ch].dar,m_dma[ch].chcr);
UINT8 dm = (m_dma[ch].chcr >> 14) & 3; /**< Destination Address Mode bits */
UINT8 sm = (m_dma[ch].chcr >> 12) & 3; /**< Source Address Mode bits */
bool ts = (m_dma[ch].chcr & 8); /**< Transfer Size bit */
int src_word_size = dma_word_size[sm] * ((ts == true) ? 2 : 1);
int dst_word_size = dma_word_size[dm] * ((ts == true) ? 2 : 1);
UINT32 src_addr = m_dma[ch].sar;
UINT32 dst_addr = m_dma[ch].dar;
UINT32 size_index = m_dma[ch].tcr;
if(size_index == 0)
size_index = 0x10000;
if(ts == false)
logerror("SH7032: DMA byte mode check\n");
for(int index = size_index;index>-1;index--)
{
if(ts == true)
m_program->write_word(dst_addr,m_program->read_word(src_addr));
else
m_program->write_byte(dst_addr,m_program->read_byte(src_addr));
src_addr += src_word_size;
dst_addr += dst_word_size;
}
m_dma[ch].chcr &= ~1; /**< @todo non-instant DMA */
printf("%02x %02x %02x %1d\n",sm,dm,rs,ts);
}
READ32_MEMBER(sh2a_device::dma_sar0_r)
{
@ -913,10 +957,33 @@ READ16_MEMBER(sh2a_device::dma_tcr0_r)
WRITE16_MEMBER(sh2a_device::dma_tcr0_w)
{
printf("%04x\n",data);
//printf("%04x\n",data);
COMBINE_DATA(&m_dma[0].tcr);
}
READ16_MEMBER(sh2a_device::dma_chcr0_r)
{
return m_dma[0].chcr;
}
WRITE16_MEMBER(sh2a_device::dma_chcr0_w)
{
//printf("%04x CHCR0\n",data);
COMBINE_DATA(&m_dma[0].chcr);
sh7032_dma_exec(0);
}
READ16_MEMBER(sh2a_device::dmaor_r)
{
return m_dmaor;
}
WRITE16_MEMBER(sh2a_device::dmaor_w)
{
COMBINE_DATA(&m_dmaor);
sh7032_dma_exec(0);
}
/*!
@brief Dummy debug interface
*/