diff --git a/src/emu/cpu/sh2/sh2.c b/src/emu/cpu/sh2/sh2.c index 420be31c5fa..2cba2b28205 100644 --- a/src/emu/cpu/sh2/sh2.c +++ b/src/emu/cpu/sh2/sh2.c @@ -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) diff --git a/src/emu/cpu/sh2/sh2.h b/src/emu/cpu/sh2/sh2.h index 38b772f2e58..c53b6baad59 100644 --- a/src/emu/cpu/sh2/sh2.h +++ b/src/emu/cpu/sh2/sh2.h @@ -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) */ }; diff --git a/src/emu/cpu/sh2/sh2comn.c b/src/emu/cpu/sh2/sh2comn.c index be0be0f01d2..ac575438cda 100644 --- a/src/emu/cpu/sh2/sh2comn.c +++ b/src/emu/cpu/sh2/sh2comn.c @@ -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 */