From 37dda0012c1b4113ab6b124956ee6989af2ceffd Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Sat, 3 Jun 2023 17:57:05 +0200 Subject: h8_dma: reorganize, upgrade --- src/devices/cpu/h8/h8.cpp | 46 ++- src/devices/cpu/h8/h8.h | 10 +- src/devices/cpu/h8/h8.lst | 34 +- src/devices/cpu/h8/h83002.cpp | 47 ++- src/devices/cpu/h8/h83002.h | 6 +- src/devices/cpu/h8/h83003.cpp | 81 ++-- src/devices/cpu/h8/h83003.h | 10 +- src/devices/cpu/h8/h83042.cpp | 26 ++ src/devices/cpu/h8/h83042.h | 4 + src/devices/cpu/h8/h83048.cpp | 26 ++ src/devices/cpu/h8/h83048.h | 4 + src/devices/cpu/h8/h8_dma.cpp | 920 +++++++++++++++++++++++++---------------- src/devices/cpu/h8/h8_dma.h | 302 +++++++++----- src/devices/cpu/h8/h8s2320.cpp | 54 +-- src/devices/cpu/h8/h8s2320.h | 6 +- src/devices/cpu/h8/h8s2357.cpp | 27 ++ src/devices/cpu/h8/h8s2357.h | 4 + src/devices/cpu/h8/h8s2655.cpp | 28 ++ src/devices/cpu/h8/h8s2655.h | 4 + src/devices/machine/t10mmc.cpp | 1 - src/devices/video/zr36110.cpp | 2 +- src/mame/nichibutsu/hrdvd.cpp | 53 ++- 22 files changed, 1095 insertions(+), 600 deletions(-) diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp index 3cc5a687ee3..39354db53ce 100644 --- a/src/devices/cpu/h8/h8.cpp +++ b/src/devices/cpu/h8/h8.cpp @@ -115,6 +115,7 @@ void h8_device::device_start() save_item(NAME(m_irq_level)); save_item(NAME(m_taken_irq_level)); save_item(NAME(m_irq_nmi)); + save_item(NAME(m_current_dma)); set_icountptr(m_icount); @@ -133,6 +134,8 @@ void h8_device::device_start() m_requested_state = -1; m_dma_device = nullptr; m_dtc_device = nullptr; + + memset(m_dma_channel, 0, sizeof(m_dma_channel)); } void h8_device::device_reset() @@ -147,25 +150,46 @@ void h8_device::device_reset() m_irq_nmi = false; m_taken_irq_vector = 0; m_taken_irq_level = -1; - m_current_dma = nullptr; + m_current_dma = -1; m_current_dtc = nullptr; } bool h8_device::trigger_dma(int vector) { - return (m_dma_device && m_dma_device->trigger_dma(vector)) || (m_dtc_device && m_dtc_device->trigger_dtc(vector)); + bool dma_triggered = false; + bool drop_interrupt = false; + for(int i=0; i != 8; i++) + if(m_dma_channel[i] && ((m_dma_channel[i]->m_flags & (h8_dma_state::ACTIVE|h8_dma_state::SUSPENDED)) == (h8_dma_state::ACTIVE|h8_dma_state::SUSPENDED)) && m_dma_channel[i]->m_trigger_vector == vector) { + m_dma_channel[i]->m_flags &= ~h8_dma_state::SUSPENDED; + dma_triggered = true; + if(m_dma_channel[i]->m_flags & h8_dma_state::EAT_INTERRUPT) + drop_interrupt = true; + } + + // DMA can mask interrupt to the DTC + if(!drop_interrupt && m_dtc_device && m_dtc_device->trigger_dtc(vector)) + drop_interrupt = true; + + if(dma_triggered) + update_active_dma_channel(); + + return drop_interrupt; } -void h8_device::set_current_dma(h8_dma_state *state) +void h8_device::set_dma_channel(h8_dma_state *state) { - m_current_dma = state; - if(!state) - logerror("DMA done\n"); - else { - logerror("New current dma s=%x d=%x is=%d id=%d count=%x m=%d autoreq=%d\n", - state->m_source, state->m_dest, state->m_incs, state->m_incd, - state->m_count, state->m_mode_16 ? 16 : 8, state->m_autoreq); + m_dma_channel[state->m_id] = state; +} + +void h8_device::update_active_dma_channel() +{ + for(int i=0; i != 8; i++) { + if(m_dma_channel[i] && ((m_dma_channel[i]->m_flags & (h8_dma_state::ACTIVE|h8_dma_state::SUSPENDED)) == h8_dma_state::ACTIVE)) { + m_current_dma = i; + return; + } } + m_current_dma = -1; } void h8_device::set_current_dtc(h8_dtc_state *state) @@ -396,7 +420,7 @@ void h8_device::prefetch_done() if(m_requested_state != -1) { m_inst_state = m_requested_state; m_requested_state = -1; - } else if(m_current_dma && !m_current_dma->m_suspended) + } else if(m_current_dma != -1) m_inst_state = STATE_DMA; else if(m_current_dtc) m_inst_state = STATE_DTC; diff --git a/src/devices/cpu/h8/h8.h b/src/devices/cpu/h8/h8.h index ac8e7de259b..6bf6d3ddb76 100644 --- a/src/devices/cpu/h8/h8.h +++ b/src/devices/cpu/h8/h8.h @@ -14,7 +14,7 @@ #pragma once -class h8_dma_device; +class h8gen_dma_device; class h8_dtc_device; struct h8_dma_state; struct h8_dtc_state; @@ -66,7 +66,8 @@ public: void internal_update(); void set_irq(int irq_vector, int irq_level, bool irq_nmi); bool trigger_dma(int vector); - void set_current_dma(h8_dma_state *state); + void set_dma_channel(h8_dma_state *state); + void update_active_dma_channel(); void set_current_dtc(h8_dtc_state *state); void request_state(int state); bool access_is_dma() const { return m_inst_state == STATE_DMA || m_inst_state == STATE_DTC; } @@ -117,9 +118,10 @@ protected: memory_access<32, 1, 0, ENDIANNESS_BIG>::cache m_cache; memory_access<32, 1, 0, ENDIANNESS_BIG>::specific m_program; memory_access<16, 1, -1, ENDIANNESS_BIG>::specific m_io; - h8_dma_device *m_dma_device; + h8gen_dma_device *m_dma_device; h8_dtc_device *m_dtc_device; - h8_dma_state *m_current_dma; + h8_dma_state *m_dma_channel[8]; + int m_current_dma; h8_dtc_state *m_current_dtc; uint32_t m_PPC; /* previous program counter */ diff --git a/src/devices/cpu/h8/h8.lst b/src/devices/cpu/h8/h8.lst index 681463691bb..4bb446ac551 100644 --- a/src/devices/cpu/h8/h8.lst +++ b/src/devices/cpu/h8/h8.lst @@ -200,25 +200,27 @@ macro jsr32 %opc %spreg prefetch_noirq 10003 dma - if(m_current_dma->m_count == 1) - m_dma_device->count_last(m_current_dma->m_id); - if(m_current_dma->m_mode_16) { - m_TMP1 = read16(m_current_dma->m_source); - write16(m_current_dma->m_dest, m_TMP1); + m_TMP2 = m_current_dma; + if(m_dma_channel[m_TMP2]->m_flags & h8_dma_state::MODE_16) { + m_TMP1 = read16(m_dma_channel[m_TMP2]->m_source); + if(m_dma_channel[m_TMP2]->m_count == 1 && !(m_dma_channel[m_TMP2]->m_flags & (h8_dma_state::BLOCK|h8_dma_state::REPEAT))) + m_dma_device->count_last(m_dma_channel[m_TMP2]->m_id); + write16(m_dma_channel[m_TMP2]->m_dest, m_TMP1); } else { - m_TMP1 = read8(m_current_dma->m_source); - write8(m_current_dma->m_dest, m_TMP1); + m_TMP1 = read8(m_dma_channel[m_TMP2]->m_source); + if(m_dma_channel[m_TMP2]->m_count == 1 && !(m_dma_channel[m_TMP2]->m_flags & (h8_dma_state::BLOCK|h8_dma_state::REPEAT))) + m_dma_device->count_last(m_dma_channel[m_TMP2]->m_id); + write8(m_dma_channel[m_TMP2]->m_dest, m_TMP1); } - m_current_dma->m_source += m_current_dma->m_incs; - m_current_dma->m_dest += m_current_dma->m_incd; - m_current_dma->m_count--; - if(!m_current_dma->m_autoreq) - m_current_dma->m_suspended = true; - if(!m_current_dma->m_count) { - uint8_t id = m_current_dma->m_id; - m_current_dma = nullptr; - m_dma_device->count_done(id); + m_dma_channel[m_TMP2]->m_source += m_dma_channel[m_TMP2]->m_incs; + m_dma_channel[m_TMP2]->m_dest += m_dma_channel[m_TMP2]->m_incd; + m_dma_channel[m_TMP2]->m_count--; + if(m_dma_channel[m_TMP2]->m_flags & h8_dma_state::SUSPEND_AFTER_TRANSFER) { + m_dma_channel[m_TMP2]->m_flags |= h8_dma_state::SUSPENDED; + update_active_dma_channel(); } + if(!m_dma_channel[m_TMP2]->m_count) + m_dma_device->count_done(m_TMP2); prefetch_done(); 10004 dtc s20 diff --git a/src/devices/cpu/h8/h83002.cpp b/src/devices/cpu/h8/h83002.cpp index 1c003e67b41..f73dc4dcce0 100644 --- a/src/devices/cpu/h8/h83002.cpp +++ b/src/devices/cpu/h8/h83002.cpp @@ -39,26 +39,26 @@ void h83002_device::map(address_map &map) map(base | 0xfd10, base | 0xff0f).ram(); - map(base | 0xff20, base | 0xff21).rw(m_dma0, FUNC(h8_dma_channel_device::marah_r), FUNC(h8_dma_channel_device::marah_w)); - map(base | 0xff22, base | 0xff23).rw(m_dma0, FUNC(h8_dma_channel_device::maral_r), FUNC(h8_dma_channel_device::maral_w)); - map(base | 0xff24, base | 0xff25).rw(m_dma0, FUNC(h8_dma_channel_device::etcra_r), FUNC(h8_dma_channel_device::etcra_w)); - map(base | 0xff26, base | 0xff26).rw(m_dma0, FUNC(h8_dma_channel_device::ioara8_r), FUNC(h8_dma_channel_device::ioara8_w)); - map(base | 0xff27, base | 0xff27).rw(m_dma0, FUNC(h8_dma_channel_device::dtcra_r), FUNC(h8_dma_channel_device::dtcra_w)); - map(base | 0xff28, base | 0xff29).rw(m_dma0, FUNC(h8_dma_channel_device::marbh_r), FUNC(h8_dma_channel_device::marbh_w)); - map(base | 0xff2a, base | 0xff2b).rw(m_dma0, FUNC(h8_dma_channel_device::marbl_r), FUNC(h8_dma_channel_device::marbl_w)); - map(base | 0xff2c, base | 0xff2d).rw(m_dma0, FUNC(h8_dma_channel_device::etcrb_r), FUNC(h8_dma_channel_device::etcrb_w)); - map(base | 0xff2e, base | 0xff2e).rw(m_dma0, FUNC(h8_dma_channel_device::ioarb8_r), FUNC(h8_dma_channel_device::ioarb8_w)); - map(base | 0xff2f, base | 0xff2f).rw(m_dma0, FUNC(h8_dma_channel_device::dtcrb_r), FUNC(h8_dma_channel_device::dtcrb_w)); - map(base | 0xff30, base | 0xff31).rw(m_dma1, FUNC(h8_dma_channel_device::marah_r), FUNC(h8_dma_channel_device::marah_w)); - map(base | 0xff32, base | 0xff33).rw(m_dma1, FUNC(h8_dma_channel_device::maral_r), FUNC(h8_dma_channel_device::maral_w)); - map(base | 0xff34, base | 0xff35).rw(m_dma1, FUNC(h8_dma_channel_device::etcra_r), FUNC(h8_dma_channel_device::etcra_w)); - map(base | 0xff36, base | 0xff36).rw(m_dma1, FUNC(h8_dma_channel_device::ioara8_r), FUNC(h8_dma_channel_device::ioara8_w)); - map(base | 0xff37, base | 0xff37).rw(m_dma1, FUNC(h8_dma_channel_device::dtcra_r), FUNC(h8_dma_channel_device::dtcra_w)); - map(base | 0xff38, base | 0xff39).rw(m_dma1, FUNC(h8_dma_channel_device::marbh_r), FUNC(h8_dma_channel_device::marbh_w)); - map(base | 0xff3a, base | 0xff3b).rw(m_dma1, FUNC(h8_dma_channel_device::marbl_r), FUNC(h8_dma_channel_device::marbl_w)); - map(base | 0xff3c, base | 0xff3d).rw(m_dma1, FUNC(h8_dma_channel_device::etcrb_r), FUNC(h8_dma_channel_device::etcrb_w)); - map(base | 0xff3e, base | 0xff3e).rw(m_dma1, FUNC(h8_dma_channel_device::ioarb8_r), FUNC(h8_dma_channel_device::ioarb8_w)); - map(base | 0xff3f, base | 0xff3f).rw(m_dma1, FUNC(h8_dma_channel_device::dtcrb_r), FUNC(h8_dma_channel_device::dtcrb_w)); + map(base | 0xff20, base | 0xff21).rw(m_dma0, FUNC(h8h_dma_channel_device::marah_r), FUNC(h8h_dma_channel_device::marah_w)); + map(base | 0xff22, base | 0xff23).rw(m_dma0, FUNC(h8h_dma_channel_device::maral_r), FUNC(h8h_dma_channel_device::maral_w)); + map(base | 0xff24, base | 0xff25).rw(m_dma0, FUNC(h8h_dma_channel_device::etcra_r), FUNC(h8h_dma_channel_device::etcra_w)); + map(base | 0xff26, base | 0xff26).rw(m_dma0, FUNC(h8h_dma_channel_device::ioara8_r), FUNC(h8h_dma_channel_device::ioara8_w)); + map(base | 0xff27, base | 0xff27).rw(m_dma0, FUNC(h8h_dma_channel_device::dtcra_r), FUNC(h8h_dma_channel_device::dtcra_w)); + map(base | 0xff28, base | 0xff29).rw(m_dma0, FUNC(h8h_dma_channel_device::marbh_r), FUNC(h8h_dma_channel_device::marbh_w)); + map(base | 0xff2a, base | 0xff2b).rw(m_dma0, FUNC(h8h_dma_channel_device::marbl_r), FUNC(h8h_dma_channel_device::marbl_w)); + map(base | 0xff2c, base | 0xff2d).rw(m_dma0, FUNC(h8h_dma_channel_device::etcrb_r), FUNC(h8h_dma_channel_device::etcrb_w)); + map(base | 0xff2e, base | 0xff2e).rw(m_dma0, FUNC(h8h_dma_channel_device::ioarb8_r), FUNC(h8h_dma_channel_device::ioarb8_w)); + map(base | 0xff2f, base | 0xff2f).rw(m_dma0, FUNC(h8h_dma_channel_device::dtcrb_r), FUNC(h8h_dma_channel_device::dtcrb_w)); + map(base | 0xff30, base | 0xff31).rw(m_dma1, FUNC(h8h_dma_channel_device::marah_r), FUNC(h8h_dma_channel_device::marah_w)); + map(base | 0xff32, base | 0xff33).rw(m_dma1, FUNC(h8h_dma_channel_device::maral_r), FUNC(h8h_dma_channel_device::maral_w)); + map(base | 0xff34, base | 0xff35).rw(m_dma1, FUNC(h8h_dma_channel_device::etcra_r), FUNC(h8h_dma_channel_device::etcra_w)); + map(base | 0xff36, base | 0xff36).rw(m_dma1, FUNC(h8h_dma_channel_device::ioara8_r), FUNC(h8h_dma_channel_device::ioara8_w)); + map(base | 0xff37, base | 0xff37).rw(m_dma1, FUNC(h8h_dma_channel_device::dtcra_r), FUNC(h8h_dma_channel_device::dtcra_w)); + map(base | 0xff38, base | 0xff39).rw(m_dma1, FUNC(h8h_dma_channel_device::marbh_r), FUNC(h8h_dma_channel_device::marbh_w)); + map(base | 0xff3a, base | 0xff3b).rw(m_dma1, FUNC(h8h_dma_channel_device::marbl_r), FUNC(h8h_dma_channel_device::marbl_w)); + map(base | 0xff3c, base | 0xff3d).rw(m_dma1, FUNC(h8h_dma_channel_device::etcrb_r), FUNC(h8h_dma_channel_device::etcrb_w)); + map(base | 0xff3e, base | 0xff3e).rw(m_dma1, FUNC(h8h_dma_channel_device::ioarb8_r), FUNC(h8h_dma_channel_device::ioarb8_w)); + map(base | 0xff3f, base | 0xff3f).rw(m_dma1, FUNC(h8h_dma_channel_device::dtcrb_r), FUNC(h8h_dma_channel_device::dtcrb_w)); map(base | 0xff60, base | 0xff60).rw(m_timer16, FUNC(h8_timer16_device::tstr_r), FUNC(h8_timer16_device::tstr_w)); map(base | 0xff61, base | 0xff61).rw(m_timer16, FUNC(h8_timer16_device::tsyr_r), FUNC(h8_timer16_device::tsyr_w)); @@ -145,10 +145,9 @@ void h83002_device::device_add_mconfig(machine_config &config) { H8H_INTC(config, m_intc, *this); H8_ADC_3337(config, m_adc, *this, m_intc, 60); - H8_DMA(config, m_dma, *this); - // (H8/2002.pdf) Table 8-11 DMAC Activation Sources - H8_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc, 44, h8_dma_channel_device::NONE, 24, h8_dma_channel_device::DREQ_EDGE, h8_dma_channel_device::DREQ_LEVEL, 28, 32, 36, 54, 53); - H8_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc, 46, h8_dma_channel_device::NONE, 24, h8_dma_channel_device::DREQ_EDGE, h8_dma_channel_device::DREQ_LEVEL, 28, 32, 36, 54, 53); + H8H_DMA(config, m_dma, *this); + H8H_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc, false, false); + H8H_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc, false, false); H8_PORT(config, m_port4, *this, h8_device::PORT_4, 0x00, 0x00); H8_PORT(config, m_port6, *this, h8_device::PORT_6, 0x80, 0x80); H8_PORT(config, m_port7, *this, h8_device::PORT_7, 0x00, 0x00); diff --git a/src/devices/cpu/h8/h83002.h b/src/devices/cpu/h8/h83002.h index 8cbb9eb117b..fc4bc651359 100644 --- a/src/devices/cpu/h8/h83002.h +++ b/src/devices/cpu/h8/h83002.h @@ -44,9 +44,9 @@ public: protected: required_device m_intc; required_device m_adc; - optional_device m_dma; - optional_device m_dma0; - optional_device m_dma1; + required_device m_dma; + required_device m_dma0; + required_device m_dma1; required_device m_port4; required_device m_port6; required_device m_port7; diff --git a/src/devices/cpu/h8/h83003.cpp b/src/devices/cpu/h8/h83003.cpp index bfd5c055a69..2da98ccab4a 100644 --- a/src/devices/cpu/h8/h83003.cpp +++ b/src/devices/cpu/h8/h83003.cpp @@ -43,41 +43,41 @@ void h83003_device::map(address_map &map) map(base | 0xfd10, base | 0xff0f).ram(); - map(base | 0xff20, base | 0xff21).rw(m_dma0, FUNC(h8_dma_channel_device::marah_r), FUNC(h8_dma_channel_device::marah_w)); - map(base | 0xff22, base | 0xff23).rw(m_dma0, FUNC(h8_dma_channel_device::maral_r), FUNC(h8_dma_channel_device::maral_w)); - map(base | 0xff24, base | 0xff25).rw(m_dma0, FUNC(h8_dma_channel_device::etcra_r), FUNC(h8_dma_channel_device::etcra_w)); - map(base | 0xff26, base | 0xff26).rw(m_dma0, FUNC(h8_dma_channel_device::ioara8_r), FUNC(h8_dma_channel_device::ioara8_w)); - map(base | 0xff27, base | 0xff27).rw(m_dma0, FUNC(h8_dma_channel_device::dtcra_r), FUNC(h8_dma_channel_device::dtcra_w)); - map(base | 0xff28, base | 0xff29).rw(m_dma0, FUNC(h8_dma_channel_device::marbh_r), FUNC(h8_dma_channel_device::marbh_w)); - map(base | 0xff2a, base | 0xff2b).rw(m_dma0, FUNC(h8_dma_channel_device::marbl_r), FUNC(h8_dma_channel_device::marbl_w)); - map(base | 0xff2c, base | 0xff2d).rw(m_dma0, FUNC(h8_dma_channel_device::etcrb_r), FUNC(h8_dma_channel_device::etcrb_w)); - map(base | 0xff2e, base | 0xff2e).rw(m_dma0, FUNC(h8_dma_channel_device::ioarb8_r), FUNC(h8_dma_channel_device::ioarb8_w)); - map(base | 0xff2f, base | 0xff2f).rw(m_dma0, FUNC(h8_dma_channel_device::dtcrb_r), FUNC(h8_dma_channel_device::dtcrb_w)); - map(base | 0xff30, base | 0xff31).rw(m_dma1, FUNC(h8_dma_channel_device::marah_r), FUNC(h8_dma_channel_device::marah_w)); - map(base | 0xff32, base | 0xff33).rw(m_dma1, FUNC(h8_dma_channel_device::maral_r), FUNC(h8_dma_channel_device::maral_w)); - map(base | 0xff34, base | 0xff35).rw(m_dma1, FUNC(h8_dma_channel_device::etcra_r), FUNC(h8_dma_channel_device::etcra_w)); - map(base | 0xff36, base | 0xff36).rw(m_dma1, FUNC(h8_dma_channel_device::ioara8_r), FUNC(h8_dma_channel_device::ioara8_w)); - map(base | 0xff37, base | 0xff37).rw(m_dma1, FUNC(h8_dma_channel_device::dtcra_r), FUNC(h8_dma_channel_device::dtcra_w)); - map(base | 0xff38, base | 0xff39).rw(m_dma1, FUNC(h8_dma_channel_device::marbh_r), FUNC(h8_dma_channel_device::marbh_w)); - map(base | 0xff3a, base | 0xff3b).rw(m_dma1, FUNC(h8_dma_channel_device::marbl_r), FUNC(h8_dma_channel_device::marbl_w)); - map(base | 0xff3c, base | 0xff3d).rw(m_dma1, FUNC(h8_dma_channel_device::etcrb_r), FUNC(h8_dma_channel_device::etcrb_w)); - map(base | 0xff3e, base | 0xff3e).rw(m_dma1, FUNC(h8_dma_channel_device::ioarb8_r), FUNC(h8_dma_channel_device::ioarb8_w)); - map(base | 0xff3f, base | 0xff3f).rw(m_dma1, FUNC(h8_dma_channel_device::dtcrb_r), FUNC(h8_dma_channel_device::dtcrb_w)); - map(base | 0xff40, base | 0xff41).rw(m_dma2, FUNC(h8_dma_channel_device::marah_r), FUNC(h8_dma_channel_device::marah_w)); - map(base | 0xff42, base | 0xff43).rw(m_dma2, FUNC(h8_dma_channel_device::maral_r), FUNC(h8_dma_channel_device::maral_w)); - map(base | 0xff44, base | 0xff45).rw(m_dma2, FUNC(h8_dma_channel_device::etcra_r), FUNC(h8_dma_channel_device::etcra_w)); - map(base | 0xff46, base | 0xff46).rw(m_dma2, FUNC(h8_dma_channel_device::ioara8_r), FUNC(h8_dma_channel_device::ioara8_w)); - map(base | 0xff47, base | 0xff47).rw(m_dma2, FUNC(h8_dma_channel_device::dtcra_r), FUNC(h8_dma_channel_device::dtcra_w)); - map(base | 0xff48, base | 0xff49).rw(m_dma2, FUNC(h8_dma_channel_device::marbh_r), FUNC(h8_dma_channel_device::marbh_w)); - map(base | 0xff4a, base | 0xff4b).rw(m_dma2, FUNC(h8_dma_channel_device::marbl_r), FUNC(h8_dma_channel_device::marbl_w)); - map(base | 0xff4c, base | 0xff4d).rw(m_dma2, FUNC(h8_dma_channel_device::etcrb_r), FUNC(h8_dma_channel_device::etcrb_w)); - map(base | 0xff4e, base | 0xff4e).rw(m_dma2, FUNC(h8_dma_channel_device::ioarb8_r), FUNC(h8_dma_channel_device::ioarb8_w)); - map(base | 0xff4f, base | 0xff4f).rw(m_dma2, FUNC(h8_dma_channel_device::dtcrb_r), FUNC(h8_dma_channel_device::dtcrb_w)); - map(base | 0xff50, base | 0xff51).rw(m_dma3, FUNC(h8_dma_channel_device::marah_r), FUNC(h8_dma_channel_device::marah_w)); - map(base | 0xff52, base | 0xff53).rw(m_dma3, FUNC(h8_dma_channel_device::maral_r), FUNC(h8_dma_channel_device::maral_w)); - map(base | 0xff54, base | 0xff55).rw(m_dma3, FUNC(h8_dma_channel_device::etcra_r), FUNC(h8_dma_channel_device::etcra_w)); - map(base | 0xff56, base | 0xff56).rw(m_dma3, FUNC(h8_dma_channel_device::ioara8_r), FUNC(h8_dma_channel_device::ioara8_w)); - map(base | 0xff57, base | 0xff57).rw(m_dma3, FUNC(h8_dma_channel_device::dtcra_r), FUNC(h8_dma_channel_device::dtcra_w)); + map(base | 0xff20, base | 0xff21).rw(m_dma0, FUNC(h8h_dma_channel_device::marah_r), FUNC(h8h_dma_channel_device::marah_w)); + map(base | 0xff22, base | 0xff23).rw(m_dma0, FUNC(h8h_dma_channel_device::maral_r), FUNC(h8h_dma_channel_device::maral_w)); + map(base | 0xff24, base | 0xff25).rw(m_dma0, FUNC(h8h_dma_channel_device::etcra_r), FUNC(h8h_dma_channel_device::etcra_w)); + map(base | 0xff26, base | 0xff26).rw(m_dma0, FUNC(h8h_dma_channel_device::ioara8_r), FUNC(h8h_dma_channel_device::ioara8_w)); + map(base | 0xff27, base | 0xff27).rw(m_dma0, FUNC(h8h_dma_channel_device::dtcra_r), FUNC(h8h_dma_channel_device::dtcra_w)); + map(base | 0xff28, base | 0xff29).rw(m_dma0, FUNC(h8h_dma_channel_device::marbh_r), FUNC(h8h_dma_channel_device::marbh_w)); + map(base | 0xff2a, base | 0xff2b).rw(m_dma0, FUNC(h8h_dma_channel_device::marbl_r), FUNC(h8h_dma_channel_device::marbl_w)); + map(base | 0xff2c, base | 0xff2d).rw(m_dma0, FUNC(h8h_dma_channel_device::etcrb_r), FUNC(h8h_dma_channel_device::etcrb_w)); + map(base | 0xff2e, base | 0xff2e).rw(m_dma0, FUNC(h8h_dma_channel_device::ioarb8_r), FUNC(h8h_dma_channel_device::ioarb8_w)); + map(base | 0xff2f, base | 0xff2f).rw(m_dma0, FUNC(h8h_dma_channel_device::dtcrb_r), FUNC(h8h_dma_channel_device::dtcrb_w)); + map(base | 0xff30, base | 0xff31).rw(m_dma1, FUNC(h8h_dma_channel_device::marah_r), FUNC(h8h_dma_channel_device::marah_w)); + map(base | 0xff32, base | 0xff33).rw(m_dma1, FUNC(h8h_dma_channel_device::maral_r), FUNC(h8h_dma_channel_device::maral_w)); + map(base | 0xff34, base | 0xff35).rw(m_dma1, FUNC(h8h_dma_channel_device::etcra_r), FUNC(h8h_dma_channel_device::etcra_w)); + map(base | 0xff36, base | 0xff36).rw(m_dma1, FUNC(h8h_dma_channel_device::ioara8_r), FUNC(h8h_dma_channel_device::ioara8_w)); + map(base | 0xff37, base | 0xff37).rw(m_dma1, FUNC(h8h_dma_channel_device::dtcra_r), FUNC(h8h_dma_channel_device::dtcra_w)); + map(base | 0xff38, base | 0xff39).rw(m_dma1, FUNC(h8h_dma_channel_device::marbh_r), FUNC(h8h_dma_channel_device::marbh_w)); + map(base | 0xff3a, base | 0xff3b).rw(m_dma1, FUNC(h8h_dma_channel_device::marbl_r), FUNC(h8h_dma_channel_device::marbl_w)); + map(base | 0xff3c, base | 0xff3d).rw(m_dma1, FUNC(h8h_dma_channel_device::etcrb_r), FUNC(h8h_dma_channel_device::etcrb_w)); + map(base | 0xff3e, base | 0xff3e).rw(m_dma1, FUNC(h8h_dma_channel_device::ioarb8_r), FUNC(h8h_dma_channel_device::ioarb8_w)); + map(base | 0xff3f, base | 0xff3f).rw(m_dma1, FUNC(h8h_dma_channel_device::dtcrb_r), FUNC(h8h_dma_channel_device::dtcrb_w)); + map(base | 0xff40, base | 0xff41).rw(m_dma2, FUNC(h8h_dma_channel_device::marah_r), FUNC(h8h_dma_channel_device::marah_w)); + map(base | 0xff42, base | 0xff43).rw(m_dma2, FUNC(h8h_dma_channel_device::maral_r), FUNC(h8h_dma_channel_device::maral_w)); + map(base | 0xff44, base | 0xff45).rw(m_dma2, FUNC(h8h_dma_channel_device::etcra_r), FUNC(h8h_dma_channel_device::etcra_w)); + map(base | 0xff46, base | 0xff46).rw(m_dma2, FUNC(h8h_dma_channel_device::ioara8_r), FUNC(h8h_dma_channel_device::ioara8_w)); + map(base | 0xff47, base | 0xff47).rw(m_dma2, FUNC(h8h_dma_channel_device::dtcra_r), FUNC(h8h_dma_channel_device::dtcra_w)); + map(base | 0xff48, base | 0xff49).rw(m_dma2, FUNC(h8h_dma_channel_device::marbh_r), FUNC(h8h_dma_channel_device::marbh_w)); + map(base | 0xff4a, base | 0xff4b).rw(m_dma2, FUNC(h8h_dma_channel_device::marbl_r), FUNC(h8h_dma_channel_device::marbl_w)); + map(base | 0xff4c, base | 0xff4d).rw(m_dma2, FUNC(h8h_dma_channel_device::etcrb_r), FUNC(h8h_dma_channel_device::etcrb_w)); + map(base | 0xff4e, base | 0xff4e).rw(m_dma2, FUNC(h8h_dma_channel_device::ioarb8_r), FUNC(h8h_dma_channel_device::ioarb8_w)); + map(base | 0xff4f, base | 0xff4f).rw(m_dma2, FUNC(h8h_dma_channel_device::dtcrb_r), FUNC(h8h_dma_channel_device::dtcrb_w)); + map(base | 0xff50, base | 0xff51).rw(m_dma3, FUNC(h8h_dma_channel_device::marah_r), FUNC(h8h_dma_channel_device::marah_w)); + map(base | 0xff52, base | 0xff53).rw(m_dma3, FUNC(h8h_dma_channel_device::maral_r), FUNC(h8h_dma_channel_device::maral_w)); + map(base | 0xff54, base | 0xff55).rw(m_dma3, FUNC(h8h_dma_channel_device::etcra_r), FUNC(h8h_dma_channel_device::etcra_w)); + map(base | 0xff56, base | 0xff56).rw(m_dma3, FUNC(h8h_dma_channel_device::ioara8_r), FUNC(h8h_dma_channel_device::ioara8_w)); + map(base | 0xff57, base | 0xff57).rw(m_dma3, FUNC(h8h_dma_channel_device::dtcra_r), FUNC(h8h_dma_channel_device::dtcra_w)); map(base | 0xff60, base | 0xff60).rw(m_timer16, FUNC(h8_timer16_device::tstr_r), FUNC(h8_timer16_device::tstr_w)); map(base | 0xff61, base | 0xff61).rw(m_timer16, FUNC(h8_timer16_device::tsyr_r), FUNC(h8_timer16_device::tsyr_w)); @@ -168,12 +168,11 @@ void h83003_device::device_add_mconfig(machine_config &config) { H8H_INTC(config, m_intc, *this); H8_ADC_3337(config, m_adc, *this, m_intc, 60); - H8_DMA(config, m_dma, *this); - // (h8-3002.pdf) Table 8-11 DMAC Activation Sources - H8_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc, 44, h8_dma_channel_device::NONE, 24, h8_dma_channel_device::DREQ_EDGE, h8_dma_channel_device::DREQ_LEVEL, 28, 32, 36, 54, 53); - H8_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc, 46, h8_dma_channel_device::NONE, 24, h8_dma_channel_device::DREQ_EDGE, h8_dma_channel_device::DREQ_LEVEL, 28, 32, 36, 54, 53); - H8_DMA_CHANNEL(config, m_dma2, *this, m_dma, m_intc, 48, h8_dma_channel_device::NONE, 24, h8_dma_channel_device::DREQ_EDGE, h8_dma_channel_device::DREQ_LEVEL, 28, 32, 36, 54, 53); - H8_DMA_CHANNEL(config, m_dma3, *this, m_dma, m_intc, 50, h8_dma_channel_device::NONE, 24, h8_dma_channel_device::DREQ_EDGE, h8_dma_channel_device::DREQ_LEVEL, 28, 32, 36, 54, 53); + H8H_DMA(config, m_dma, *this); + H8H_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc, false, false); + H8H_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc, false, false); + H8H_DMA_CHANNEL(config, m_dma2, *this, m_dma, m_intc, false, true); + H8H_DMA_CHANNEL(config, m_dma3, *this, m_dma, m_intc, false, true); H8_PORT(config, m_port4, *this, h8_device::PORT_4, 0x00, 0x00); H8_PORT(config, m_port5, *this, h8_device::PORT_5, 0x0f, 0x00); H8_PORT(config, m_port6, *this, h8_device::PORT_6, 0x80, 0x80); diff --git a/src/devices/cpu/h8/h83003.h b/src/devices/cpu/h8/h83003.h index 06e8b044f71..5446d60c240 100644 --- a/src/devices/cpu/h8/h83003.h +++ b/src/devices/cpu/h8/h83003.h @@ -46,11 +46,11 @@ public: protected: required_device m_intc; required_device m_adc; - required_device m_dma; - required_device m_dma0; - required_device m_dma1; - required_device m_dma2; - required_device m_dma3; + required_device m_dma; + required_device m_dma0; + required_device m_dma1; + required_device m_dma2; + required_device m_dma3; required_device m_port4; required_device m_port5; required_device m_port6; diff --git a/src/devices/cpu/h8/h83042.cpp b/src/devices/cpu/h8/h83042.cpp index 6146c7c8b80..c0779b2b21c 100644 --- a/src/devices/cpu/h8/h83042.cpp +++ b/src/devices/cpu/h8/h83042.cpp @@ -11,6 +11,9 @@ h83042_device::h83042_device(const machine_config &mconfig, device_type type, co h8h_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(h83042_device::map), this)), m_intc(*this, "intc"), m_adc(*this, "adc"), + m_dma(*this, "dma"), + m_dma0(*this, "dma:0"), + m_dma1(*this, "dma:1"), m_port1(*this, "port1"), m_port2(*this, "port2"), m_port3(*this, "port3"), @@ -58,6 +61,26 @@ void h83042_device::map(address_map &map) map(base | 0xf710, base | 0xff0f).ram(); + map(base | 0xff20, base | 0xff21).rw(m_dma0, FUNC(h8h_dma_channel_device::marah_r), FUNC(h8h_dma_channel_device::marah_w)); + map(base | 0xff22, base | 0xff23).rw(m_dma0, FUNC(h8h_dma_channel_device::maral_r), FUNC(h8h_dma_channel_device::maral_w)); + map(base | 0xff24, base | 0xff25).rw(m_dma0, FUNC(h8h_dma_channel_device::etcra_r), FUNC(h8h_dma_channel_device::etcra_w)); + map(base | 0xff26, base | 0xff26).rw(m_dma0, FUNC(h8h_dma_channel_device::ioara8_r), FUNC(h8h_dma_channel_device::ioara8_w)); + map(base | 0xff27, base | 0xff27).rw(m_dma0, FUNC(h8h_dma_channel_device::dtcra_r), FUNC(h8h_dma_channel_device::dtcra_w)); + map(base | 0xff28, base | 0xff29).rw(m_dma0, FUNC(h8h_dma_channel_device::marbh_r), FUNC(h8h_dma_channel_device::marbh_w)); + map(base | 0xff2a, base | 0xff2b).rw(m_dma0, FUNC(h8h_dma_channel_device::marbl_r), FUNC(h8h_dma_channel_device::marbl_w)); + map(base | 0xff2c, base | 0xff2d).rw(m_dma0, FUNC(h8h_dma_channel_device::etcrb_r), FUNC(h8h_dma_channel_device::etcrb_w)); + map(base | 0xff2e, base | 0xff2e).rw(m_dma0, FUNC(h8h_dma_channel_device::ioarb8_r), FUNC(h8h_dma_channel_device::ioarb8_w)); + map(base | 0xff2f, base | 0xff2f).rw(m_dma0, FUNC(h8h_dma_channel_device::dtcrb_r), FUNC(h8h_dma_channel_device::dtcrb_w)); + map(base | 0xff30, base | 0xff31).rw(m_dma1, FUNC(h8h_dma_channel_device::marah_r), FUNC(h8h_dma_channel_device::marah_w)); + map(base | 0xff32, base | 0xff33).rw(m_dma1, FUNC(h8h_dma_channel_device::maral_r), FUNC(h8h_dma_channel_device::maral_w)); + map(base | 0xff34, base | 0xff35).rw(m_dma1, FUNC(h8h_dma_channel_device::etcra_r), FUNC(h8h_dma_channel_device::etcra_w)); + map(base | 0xff36, base | 0xff36).rw(m_dma1, FUNC(h8h_dma_channel_device::ioara8_r), FUNC(h8h_dma_channel_device::ioara8_w)); + map(base | 0xff37, base | 0xff37).rw(m_dma1, FUNC(h8h_dma_channel_device::dtcra_r), FUNC(h8h_dma_channel_device::dtcra_w)); + map(base | 0xff38, base | 0xff39).rw(m_dma1, FUNC(h8h_dma_channel_device::marbh_r), FUNC(h8h_dma_channel_device::marbh_w)); + map(base | 0xff3a, base | 0xff3b).rw(m_dma1, FUNC(h8h_dma_channel_device::marbl_r), FUNC(h8h_dma_channel_device::marbl_w)); + map(base | 0xff3c, base | 0xff3d).rw(m_dma1, FUNC(h8h_dma_channel_device::etcrb_r), FUNC(h8h_dma_channel_device::etcrb_w)); + map(base | 0xff3e, base | 0xff3e).rw(m_dma1, FUNC(h8h_dma_channel_device::ioarb8_r), FUNC(h8h_dma_channel_device::ioarb8_w)); + map(base | 0xff3f, base | 0xff3f).rw(m_dma1, FUNC(h8h_dma_channel_device::dtcrb_r), FUNC(h8h_dma_channel_device::dtcrb_w)); map(base | 0xff60, base | 0xff60).rw(m_timer16, FUNC(h8_timer16_device::tstr_r), FUNC(h8_timer16_device::tstr_w)); map(base | 0xff61, base | 0xff61).rw(m_timer16, FUNC(h8_timer16_device::tsyr_r), FUNC(h8_timer16_device::tsyr_w)); map(base | 0xff62, base | 0xff62).rw(m_timer16, FUNC(h8_timer16_device::tmdr_r), FUNC(h8_timer16_device::tmdr_w)); @@ -153,6 +176,9 @@ void h83042_device::device_add_mconfig(machine_config &config) { H8H_INTC(config, m_intc, *this); H8_ADC_3337(config, m_adc, *this, m_intc, 60); + H8H_DMA(config, m_dma, *this); + H8H_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc, false, false); + H8H_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc, false, false); H8_PORT(config, m_port1, *this, h8_device::PORT_1, 0x00, 0x00); H8_PORT(config, m_port2, *this, h8_device::PORT_2, 0x00, 0x00); H8_PORT(config, m_port3, *this, h8_device::PORT_3, 0x00, 0x00); diff --git a/src/devices/cpu/h8/h83042.h b/src/devices/cpu/h8/h83042.h index f49b2bfb793..69426c1bde9 100644 --- a/src/devices/cpu/h8/h83042.h +++ b/src/devices/cpu/h8/h83042.h @@ -24,6 +24,7 @@ #include "h8h.h" #include "h8_adc.h" +#include "h8_dma.h" #include "h8_port.h" #include "h8_intc.h" #include "h8_timer16.h" @@ -42,6 +43,9 @@ protected: required_device m_intc; required_device m_adc; + required_device m_dma; + required_device m_dma0; + required_device m_dma1; required_device m_port1; required_device m_port2; required_device m_port3; diff --git a/src/devices/cpu/h8/h83048.cpp b/src/devices/cpu/h8/h83048.cpp index 86b24132e31..568fed827cc 100644 --- a/src/devices/cpu/h8/h83048.cpp +++ b/src/devices/cpu/h8/h83048.cpp @@ -12,6 +12,9 @@ h83048_device::h83048_device(const machine_config &mconfig, device_type type, co h8h_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(h83048_device::map), this)), m_intc(*this, "intc"), m_adc(*this, "adc"), + m_dma(*this, "dma"), + m_dma0(*this, "dma:0"), + m_dma1(*this, "dma:1"), m_port1(*this, "port1"), m_port2(*this, "port2"), m_port3(*this, "port3"), @@ -63,6 +66,26 @@ void h83048_device::map(address_map &map) map(base | m_ram_start, base | 0xff0f).ram(); + map(base | 0xff20, base | 0xff21).rw(m_dma0, FUNC(h8h_dma_channel_device::marah_r), FUNC(h8h_dma_channel_device::marah_w)); + map(base | 0xff22, base | 0xff23).rw(m_dma0, FUNC(h8h_dma_channel_device::maral_r), FUNC(h8h_dma_channel_device::maral_w)); + map(base | 0xff24, base | 0xff25).rw(m_dma0, FUNC(h8h_dma_channel_device::etcra_r), FUNC(h8h_dma_channel_device::etcra_w)); + map(base | 0xff26, base | 0xff26).rw(m_dma0, FUNC(h8h_dma_channel_device::ioara8_r), FUNC(h8h_dma_channel_device::ioara8_w)); + map(base | 0xff27, base | 0xff27).rw(m_dma0, FUNC(h8h_dma_channel_device::dtcra_r), FUNC(h8h_dma_channel_device::dtcra_w)); + map(base | 0xff28, base | 0xff29).rw(m_dma0, FUNC(h8h_dma_channel_device::marbh_r), FUNC(h8h_dma_channel_device::marbh_w)); + map(base | 0xff2a, base | 0xff2b).rw(m_dma0, FUNC(h8h_dma_channel_device::marbl_r), FUNC(h8h_dma_channel_device::marbl_w)); + map(base | 0xff2c, base | 0xff2d).rw(m_dma0, FUNC(h8h_dma_channel_device::etcrb_r), FUNC(h8h_dma_channel_device::etcrb_w)); + map(base | 0xff2e, base | 0xff2e).rw(m_dma0, FUNC(h8h_dma_channel_device::ioarb8_r), FUNC(h8h_dma_channel_device::ioarb8_w)); + map(base | 0xff2f, base | 0xff2f).rw(m_dma0, FUNC(h8h_dma_channel_device::dtcrb_r), FUNC(h8h_dma_channel_device::dtcrb_w)); + map(base | 0xff30, base | 0xff31).rw(m_dma1, FUNC(h8h_dma_channel_device::marah_r), FUNC(h8h_dma_channel_device::marah_w)); + map(base | 0xff32, base | 0xff33).rw(m_dma1, FUNC(h8h_dma_channel_device::maral_r), FUNC(h8h_dma_channel_device::maral_w)); + map(base | 0xff34, base | 0xff35).rw(m_dma1, FUNC(h8h_dma_channel_device::etcra_r), FUNC(h8h_dma_channel_device::etcra_w)); + map(base | 0xff36, base | 0xff36).rw(m_dma1, FUNC(h8h_dma_channel_device::ioara8_r), FUNC(h8h_dma_channel_device::ioara8_w)); + map(base | 0xff37, base | 0xff37).rw(m_dma1, FUNC(h8h_dma_channel_device::dtcra_r), FUNC(h8h_dma_channel_device::dtcra_w)); + map(base | 0xff38, base | 0xff39).rw(m_dma1, FUNC(h8h_dma_channel_device::marbh_r), FUNC(h8h_dma_channel_device::marbh_w)); + map(base | 0xff3a, base | 0xff3b).rw(m_dma1, FUNC(h8h_dma_channel_device::marbl_r), FUNC(h8h_dma_channel_device::marbl_w)); + map(base | 0xff3c, base | 0xff3d).rw(m_dma1, FUNC(h8h_dma_channel_device::etcrb_r), FUNC(h8h_dma_channel_device::etcrb_w)); + map(base | 0xff3e, base | 0xff3e).rw(m_dma1, FUNC(h8h_dma_channel_device::ioarb8_r), FUNC(h8h_dma_channel_device::ioarb8_w)); + map(base | 0xff3f, base | 0xff3f).rw(m_dma1, FUNC(h8h_dma_channel_device::dtcrb_r), FUNC(h8h_dma_channel_device::dtcrb_w)); map(base | 0xff60, base | 0xff60).rw(m_timer16, FUNC(h8_timer16_device::tstr_r), FUNC(h8_timer16_device::tstr_w)); map(base | 0xff61, base | 0xff61).rw(m_timer16, FUNC(h8_timer16_device::tsyr_r), FUNC(h8_timer16_device::tsyr_w)); map(base | 0xff62, base | 0xff62).rw(m_timer16, FUNC(h8_timer16_device::tmdr_r), FUNC(h8_timer16_device::tmdr_w)); @@ -158,6 +181,9 @@ void h83048_device::device_add_mconfig(machine_config &config) { H8H_INTC(config, m_intc, *this); H8_ADC_3337(config, m_adc, *this, m_intc, 60); + H8H_DMA(config, m_dma, *this); + H8H_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc, false, false); + H8H_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc, false, false); H8_PORT(config, m_port1, *this, h8_device::PORT_1, 0x00, 0x00); H8_PORT(config, m_port2, *this, h8_device::PORT_2, 0x00, 0x00); H8_PORT(config, m_port3, *this, h8_device::PORT_3, 0x00, 0x00); diff --git a/src/devices/cpu/h8/h83048.h b/src/devices/cpu/h8/h83048.h index 7ad31651c4d..3849662861e 100644 --- a/src/devices/cpu/h8/h83048.h +++ b/src/devices/cpu/h8/h83048.h @@ -24,6 +24,7 @@ #include "h8h.h" #include "h8_adc.h" +#include "h8_dma.h" #include "h8_port.h" #include "h8_intc.h" #include "h8_timer16.h" @@ -45,6 +46,9 @@ protected: required_device m_intc; required_device m_adc; + required_device m_dma; + required_device m_dma0; + required_device m_dma1; required_device m_port1; required_device m_port2; required_device m_port3; diff --git a/src/devices/cpu/h8/h8_dma.cpp b/src/devices/cpu/h8/h8_dma.cpp index 1d9f23ff8cf..25f96212374 100644 --- a/src/devices/cpu/h8/h8_dma.cpp +++ b/src/devices/cpu/h8/h8_dma.cpp @@ -1,561 +1,767 @@ #include "emu.h" #include "h8_dma.h" -DEFINE_DEVICE_TYPE(H8_DMA, h8_dma_device, "h8_dma", "H8 DMA controller") -DEFINE_DEVICE_TYPE(H8_DMA_CHANNEL, h8_dma_channel_device, "h8_dma_channel", "H8 DMA channel") - -h8_dma_device::h8_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, H8_DMA, tag, owner, clock), +/* + h: + mar[01][ab][hl] + ioar[01][ab] + etcr[01][ab] + dtcr[01][ab] + + s: + mar[01][ab][hl] + ioar[01][ab] + etcr[01][ab] + dmawer + dmatcr + dmacr[01][ab] + dmabcr[hl] + + */ + +DEFINE_DEVICE_TYPE(H8H_DMA, h8h_dma_device, "h8h_dma", "H8H DMA controller") +DEFINE_DEVICE_TYPE(H8S_DMA, h8s_dma_device, "h8s_dma", "H8S DMA controller") +DEFINE_DEVICE_TYPE(H8H_DMA_CHANNEL, h8h_dma_channel_device, "h8h_dma_channel", "H8H DMA channel") +DEFINE_DEVICE_TYPE(H8S_DMA_CHANNEL, h8s_dma_channel_device, "h8s_dma_channel", "H8S DMA channel") + + +// H8 top device, common code + +h8gen_dma_device::h8gen_dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, type, tag, owner, clock), m_cpu(*this, finder_base::DUMMY_TAG), - m_dmach0(*this, "0"), - m_dmach1(*this, "1") + m_dmach(*this, "%u", 0) { } -void h8_dma_device::device_start() +void h8gen_dma_device::device_start() { - m_dmach0->set_id(0<<1); - m_dmach1->set_id(1<<1); - - save_item(NAME(m_dmabcr)); - save_item(NAME(m_dmawer)); - save_item(NAME(m_dreq)); + for(int i=0; i != 4; i++) + if(m_dmach[i]) + m_dmach[i]->set_id(i<<1); } -void h8_dma_device::device_reset() +void h8gen_dma_device::device_reset() { - m_dmabcr = 0x0000; - m_dmawer = 0x00; - m_dreq[0] = m_dreq[1] = false; } -bool h8_dma_device::trigger_dma(int vector) +void h8gen_dma_device::count_last(int id) { - // Don't shortcut! Both dmas may be started - bool start0 = m_dmach0->start_test(vector); - bool start1 = m_dmach1->start_test(vector); - - return start0 || start1; + m_cpu->set_input_line(H8_INPUT_LINE_TEND0 + (id >> 1), ASSERT_LINE); } -void h8_dma_device::count_last(int id) +void h8gen_dma_device::count_done(int id) { - if(id & 2) - m_dmach1->count_last(id & 1); - else - m_dmach0->count_last(id & 1); + m_cpu->set_input_line(H8_INPUT_LINE_TEND0 + (id >> 1), CLEAR_LINE); + m_dmach[id >> 1]->count_done(id & 1); } -void h8_dma_device::count_done(int id) +void h8gen_dma_device::set_input(int inputnum, int state) { - if(id & 2) - m_dmach1->count_done(id & 1); - else - m_dmach0->count_done(id & 1); -} - -void h8_dma_device::clear_dte(int id) -{ - m_dmabcr &= ~(0x0010 << id); + if(inputnum >= H8_INPUT_LINE_DREQ0 && inputnum <= H8_INPUT_LINE_DREQ3) { + int idx = inputnum - H8_INPUT_LINE_DREQ0; + if(m_dmach[idx]) + m_dmach[idx]->set_dreq(state); + } } -void h8_dma_device::set_input(int inputnum, int state) +void h8gen_dma_device::start_stop_test() { - if(inputnum == H8_INPUT_LINE_DREQ0) { - if(state == ASSERT_LINE) { - m_dmach0->start_test(h8_dma_channel_device::DREQ_LEVEL); - if(!m_dreq[0]) - m_dmach0->start_test(h8_dma_channel_device::DREQ_EDGE); - } - m_dreq[0] = (state == ASSERT_LINE); - } else if(inputnum == H8_INPUT_LINE_DREQ1) { - if(state == ASSERT_LINE) { - m_dmach1->start_test(h8_dma_channel_device::DREQ_LEVEL); - if(!m_dreq[1]) - m_dmach1->start_test(h8_dma_channel_device::DREQ_EDGE); + u8 chnmap = active_channels(); + for(int i=0; i != 8; i++) { + if(BIT(chnmap, i)) { + if(!(m_dmach[i >> 1]->m_state[i & 1].m_flags & h8_dma_state::ACTIVE)) + m_dmach[i >> 1]->start(i & 1); + + } else { + if(m_dmach[i >> 1] && (m_dmach[i >> 1]->m_state[i & 1].m_flags & h8_dma_state::ACTIVE)) { + logerror("forced abort %d\n", i); + exit(0); + } } - m_dreq[1] = (state == ASSERT_LINE); - } else - logerror("input line %d not supported for h8_dma_device\n", inputnum); -} - -uint8_t h8_dma_device::dmawer_r() -{ - logerror("dmawer_r %02x\n", m_dmawer); - return m_dmawer; -} - -void h8_dma_device::dmawer_w(uint8_t data) -{ - m_dmawer = data; - logerror("dmawer_w %02x\n", data); -} - -uint8_t h8_dma_device::dmatcr_r() -{ - logerror("dmatcr_r %02x\n", m_dmatcr); - return m_dmatcr; + } } -void h8_dma_device::dmatcr_w(uint8_t data) -{ - m_dmatcr = data; - logerror("dmatcr_w %02x\n", data); -} -uint16_t h8_dma_device::dmabcr_r() -{ - logerror("dmabcr_r %04x\n", m_dmabcr); - return m_dmabcr; -} -void h8_dma_device::dmabcr_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_dmabcr); - logerror("dmabcr_w %04x\n", m_dmabcr); - m_dmach0->set_bcr(m_dmabcr & 0x4000, m_dmabcr & 0x1000, m_dmabcr >> 8, m_dmabcr >> 4, m_dmabcr >> 0); - m_dmach1->set_bcr(m_dmabcr & 0x8000, m_dmabcr & 0x2000, m_dmabcr >> 10, m_dmabcr >> 6, m_dmabcr >> 2); -} +// DMA channel, common code -h8_dma_channel_device::h8_dma_channel_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, H8_DMA_CHANNEL, tag, owner, clock), +h8gen_dma_channel_device::h8gen_dma_channel_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, type, tag, owner, clock), m_cpu(*this, finder_base::DUMMY_TAG), - m_dma(*this, finder_base::DUMMY_TAG), m_intc(*this, finder_base::DUMMY_TAG) { } -void h8_dma_channel_device::set_info(int irq_base, int v0, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int v9, int va, int vb, int vc, int vd, int ve, int vf) -{ - m_irq_base = irq_base; - m_activation_vectors[ 0] = v0; - m_activation_vectors[ 1] = v1; - m_activation_vectors[ 2] = v2; - m_activation_vectors[ 3] = v3; - m_activation_vectors[ 4] = v4; - m_activation_vectors[ 5] = v5; - m_activation_vectors[ 6] = v6; - m_activation_vectors[ 7] = v7; - m_activation_vectors[ 8] = v8; - m_activation_vectors[ 9] = v9; - m_activation_vectors[10] = va; - m_activation_vectors[11] = vb; - m_activation_vectors[12] = vc; - m_activation_vectors[13] = vd; - m_activation_vectors[14] = ve; - m_activation_vectors[15] = vf; - memset(m_state, 0, sizeof(m_state)); -} - -void h8_dma_channel_device::device_start() +void h8gen_dma_channel_device::device_start() { save_item(STRUCT_MEMBER(m_state, m_source)); save_item(STRUCT_MEMBER(m_state, m_dest)); save_item(STRUCT_MEMBER(m_state, m_incs)); save_item(STRUCT_MEMBER(m_state, m_incd)); save_item(STRUCT_MEMBER(m_state, m_count)); + save_item(STRUCT_MEMBER(m_state, m_flags)); save_item(STRUCT_MEMBER(m_state, m_id)); - save_item(STRUCT_MEMBER(m_state, m_autoreq)); - save_item(STRUCT_MEMBER(m_state, m_suspended)); - save_item(STRUCT_MEMBER(m_state, m_mode_16)); + save_item(STRUCT_MEMBER(m_state, m_trigger_vector)); save_item(NAME(m_mar)); save_item(NAME(m_ioar)); save_item(NAME(m_etcr)); - save_item(NAME(m_dmacr)); - save_item(NAME(m_dtcr)); - save_item(NAME(m_dta)); - save_item(NAME(m_dte)); - save_item(NAME(m_dtie)); - save_item(NAME(m_fae)); - save_item(NAME(m_sae)); + save_item(NAME(m_dreq)); } -void h8_dma_channel_device::device_reset() +void h8gen_dma_channel_device::device_reset() { - m_dmacr = 0x0000; + int base_id = m_state[0].m_id; + memset(m_state, 0, sizeof(m_state)); + m_state[0].m_id = base_id; + m_state[1].m_id = base_id+1; + m_mar[0] = m_mar[1] = 0; m_ioar[0] = m_ioar[1] = 0; m_etcr[0] = m_etcr[1] = 0; - m_dtcr[0] = m_dtcr[1] = 0; - m_fae = m_sae = false; - m_dta = m_dte = m_dtie = 0; + m_dreq = false; +} + +void h8gen_dma_channel_device::set_id(int id) +{ + for(int i=0; i != 2; i++) { + m_state[i].m_id = id | i; + m_cpu->set_dma_channel(m_state + i); + } } -void h8_dma_channel_device::set_id(int id) +void h8gen_dma_channel_device::set_dreq(int state) { - m_state[0].m_id = id; - m_state[1].m_id = id | 1; + if(m_dreq == state) + return; + + m_dreq = state; + + // Only subchannel B/1 can react to dreq. + + if(m_dreq) { + if(((m_state[1].m_flags & (h8_dma_state::ACTIVE|h8_dma_state::SUSPENDED)) == (h8_dma_state::ACTIVE|h8_dma_state::SUSPENDED)) && (m_state[1].m_trigger_vector == DREQ_LEVEL || m_state[1].m_trigger_vector == DREQ_EDGE)) { + m_state[1].m_flags &= ~h8_dma_state::SUSPENDED; + m_cpu->update_active_dma_channel(); + } + } else { + if(((m_state[1].m_flags & (h8_dma_state::ACTIVE|h8_dma_state::SUSPENDED)) == h8_dma_state::ACTIVE) && m_state[1].m_trigger_vector == DREQ_LEVEL) { + m_state[1].m_flags |= h8_dma_state::SUSPENDED; + m_cpu->update_active_dma_channel(); + } + } } -uint16_t h8_dma_channel_device::marah_r() +u16 h8gen_dma_channel_device::marah_r() { logerror("marah_r %06x\n", m_mar[0]); return m_mar[0] >> 16; } -void h8_dma_channel_device::marah_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void h8gen_dma_channel_device::marah_w(offs_t offset, u16 data, u16 mem_mask) { if(ACCESSING_BITS_0_7) m_mar[0] = ((data & 0x00ff) << 16) | (m_mar[0] & 0xffff); logerror("marah_w %06x\n", m_mar[0]); } -uint16_t h8_dma_channel_device::maral_r() +u16 h8gen_dma_channel_device::maral_r() { logerror("maral_r %06x\n", m_mar[0]); return m_mar[0]; } -void h8_dma_channel_device::maral_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void h8gen_dma_channel_device::maral_w(offs_t offset, u16 data, u16 mem_mask) { m_mar[0] = (m_mar[0] & ~mem_mask) | (data & mem_mask); logerror("maral_w %06x\n", m_mar[0]); } -uint16_t h8_dma_channel_device::ioara_r() +u16 h8gen_dma_channel_device::ioara_r() { return m_ioar[0]; } -uint8_t h8_dma_channel_device::ioara8_r() +u8 h8gen_dma_channel_device::ioara8_r() { - return m_ioar[0] & 0x00ff; + return m_ioar[0]; } -void h8_dma_channel_device::ioara_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void h8gen_dma_channel_device::ioara_w(offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(&m_ioar[0]); + m_ioar[0] &= ~m_ioar_mask; logerror("ioara_w %04x\n", m_ioar[0]); } -void h8_dma_channel_device::ioara8_w(uint8_t data) +void h8gen_dma_channel_device::ioara8_w(u8 data) { - m_ioar[0] = data | 0xff00; - logerror("ioara_w %04x\n", m_ioar[0]); + m_ioar[0] = data; + logerror("ioara_w %02x\n", m_ioar[0]); } -uint16_t h8_dma_channel_device::etcra_r() +u16 h8gen_dma_channel_device::etcra_r() { logerror("etcra_r %04x\n", m_etcr[0]); return m_etcr[0]; } -void h8_dma_channel_device::etcra_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void h8gen_dma_channel_device::etcra_w(offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(&m_etcr[0]); logerror("etcra_w %04x\n", m_etcr[0]); } -uint16_t h8_dma_channel_device::marbh_r() +u16 h8gen_dma_channel_device::marbh_r() { logerror("marbh_r %06x\n", m_mar[1]); return m_mar[1] >> 16; } -void h8_dma_channel_device::marbh_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void h8gen_dma_channel_device::marbh_w(offs_t offset, u16 data, u16 mem_mask) { if(ACCESSING_BITS_0_7) m_mar[1] = ((data & 0x00ff) << 16) | (m_mar[1] & 0xffff); logerror("marbh_w %06x\n", m_mar[1]); } -uint16_t h8_dma_channel_device::marbl_r() +u16 h8gen_dma_channel_device::marbl_r() { logerror("marbl_r %06x\n", m_mar[1]); return m_mar[1]; } -void h8_dma_channel_device::marbl_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void h8gen_dma_channel_device::marbl_w(offs_t offset, u16 data, u16 mem_mask) { m_mar[1] = (m_mar[1] & ~mem_mask) | (data & mem_mask); logerror("marbl_w %06x\n", m_mar[1]); } -uint16_t h8_dma_channel_device::ioarb_r() +u16 h8gen_dma_channel_device::ioarb_r() { return m_ioar[1]; } -uint8_t h8_dma_channel_device::ioarb8_r() +u8 h8gen_dma_channel_device::ioarb8_r() { - return m_ioar[1] & 0x00ff; + return m_ioar[1]; } -void h8_dma_channel_device::ioarb_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void h8gen_dma_channel_device::ioarb_w(offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(&m_ioar[1]); + m_ioar[1] &= ~m_ioar_mask; logerror("ioarb_w %04x\n", m_ioar[1]); } -void h8_dma_channel_device::ioarb8_w(uint8_t data) +void h8gen_dma_channel_device::ioarb8_w(u8 data) { - m_ioar[1] = data | 0xff00; - logerror("ioarb_w %04x\n", m_ioar[1]); + m_ioar[1] = data; + logerror("ioarb_w %02x\n", m_ioar[1]); } -uint16_t h8_dma_channel_device::etcrb_r() +u16 h8gen_dma_channel_device::etcrb_r() { logerror("etcrb_r %04x\n", m_etcr[1]); return m_etcr[1]; } -void h8_dma_channel_device::etcrb_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void h8gen_dma_channel_device::etcrb_w(offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(&m_etcr[1]); logerror("etcrb_w %04x\n", m_etcr[1]); } -uint16_t h8_dma_channel_device::dmacr_r() +void h8gen_dma_channel_device::start(int submodule) { - logerror("dmacr_r %04x\n", m_dmacr); - return m_dmacr; + int mode = channel_mode(); + s8 vector = trigger_vector(submodule); + + m_state[submodule].m_flags = h8_dma_state::ACTIVE | channel_flags(submodule); + m_state[submodule].m_trigger_vector = vector; + + if(mode == FAE_NORMAL || mode == FAE_BLOCK) { + m_state[submodule].m_source = m_mar[0]; + m_state[submodule].m_dest = m_mar[1]; + + } else { + if(m_state[submodule].m_flags & h8_dma_state::MAR_IS_DEST) { + m_state[submodule].m_source = mode == SAE_DACK ? (0x80000000 | (m_state[submodule].m_id >> 1)) : (m_ioar[submodule] | m_ioar_mask); + m_state[submodule].m_dest = m_mar[submodule]; + } else { + m_state[submodule].m_source = m_mar[submodule]; + m_state[submodule].m_dest = mode == SAE_DACK ? (0x80000000 | (m_state[submodule].m_id >> 1)) : (m_ioar[submodule] | m_ioar_mask); + } + } + + m_state[submodule].m_bcount = 0; + + if(mode == FAE_BLOCK) { + m_state[submodule].m_count = m_etcr[0] & 0xff ? m_etcr[0] & 0xff : 0x100; + m_state[submodule].m_bcount = m_etcr[1] ? m_etcr[1] : 0x10000; + if(m_state[submodule].m_bcount > 1) + m_state[submodule].m_flags |= h8_dma_state::BLOCK; + + } else if(m_state[submodule].m_flags & h8_dma_state::REPEAT) + m_state[submodule].m_count = m_etcr[0] & 0xff ? m_etcr[0] & 0xff : 0x100; + else + m_state[submodule].m_count = m_etcr[0] ? m_etcr[0] : 0x10000; + + if(!(vector == AUTOREQ_CS || vector == AUTOREQ_B || (vector == DREQ_LEVEL && m_dreq))) + m_state[submodule].m_flags |= h8_dma_state::SUSPENDED; + if(!(vector == AUTOREQ_CS || vector == AUTOREQ_B || vector == DREQ_LEVEL || mode == FAE_BLOCK)) + m_state[submodule].m_flags |= h8_dma_state::SUSPEND_AFTER_TRANSFER; + + int step = m_state[submodule].m_flags & h8_dma_state::MODE_16 ? 2 : 1; + + m_state[submodule].m_incs = m_state[submodule].m_flags & h8_dma_state::SOURCE_IDLE ? 0 : m_state[submodule].m_flags & h8_dma_state::SOURCE_DECREMENT ? -step : step; + m_state[submodule].m_incd = m_state[submodule].m_flags & h8_dma_state::DEST_IDLE ? 0 : m_state[submodule].m_flags & h8_dma_state::DEST_DECREMENT ? -step : step; + + logerror("%c: setup src=%s%s dst=%s%s count=%x bcount=%x trigger=%s%s%s%s%s%s%s%s%s\n", + 'A' + submodule, + m_state[submodule].m_source & 0x80000000 ? util::string_format("dack%d", m_state[submodule].m_source & 1) : util::string_format("%06x", m_state[submodule].m_source), + m_state[submodule].m_incs > 0 ? util::string_format("+%x", m_state[submodule].m_incs) : m_state[submodule].m_incs < 0 ? util::string_format("-%x", -m_state[submodule].m_incs) : "", + m_state[submodule].m_dest & 0x80000000 ? util::string_format("dack%d", m_state[submodule].m_dest & 1) : util::string_format("%06x", m_state[submodule].m_dest), + m_state[submodule].m_incd > 0 ? util::string_format("+%x", m_state[submodule].m_incd) : m_state[submodule].m_incd < 0 ? util::string_format("-%x", -m_state[submodule].m_incd) : "", + m_state[submodule].m_count, + m_state[submodule].m_bcount, + vector == AUTOREQ_CS ? "autoreq-cycle-steal" : vector == AUTOREQ_B ? "autoreq-burst" : vector == DREQ_LEVEL ? "dreq-level" : vector == DREQ_EDGE ? "dreq-edge" : util::string_format("%d", vector), + m_state[submodule].m_flags & h8_dma_state::SUSPENDED ? " suspended" : "", + m_state[submodule].m_flags & h8_dma_state::SUSPEND_AFTER_TRANSFER ? " suspend-after-transfer" : "", + m_state[submodule].m_flags & h8_dma_state::BLOCK ? " block" : "", + m_state[submodule].m_flags & h8_dma_state::REPEAT ? " repeat" : "", + m_state[submodule].m_flags & h8_dma_state::MODE_16 ? " word" : " byte", + m_state[submodule].m_flags & h8_dma_state::MAR_IS_DEST ? " mar-is-dest" : " ", + m_state[submodule].m_flags & h8_dma_state::FAE ? " fae" : "", + m_state[submodule].m_flags & h8_dma_state::EAT_INTERRUPT ? " eat-interrupt" : "", + m_state[submodule].m_flags & h8_dma_state::TEND_INTERRUPT ? " tend-interrupt" : ""); +} + +void h8gen_dma_channel_device::dma_done(int submodule) +{ + m_state[submodule].m_flags &= ~h8_dma_state::ACTIVE; + m_cpu->update_active_dma_channel(); + if(m_state[submodule].m_flags & h8_dma_state::TEND_INTERRUPT) + m_intc->internal_interrupt(m_irq_base + (m_state[submodule].m_flags & h8_dma_state::FAE ? m_state[0].m_id : m_state[submodule].m_id)); +} + +void h8gen_dma_channel_device::count_done(int submodule) +{ + if(m_state[submodule].m_flags & h8_dma_state::BLOCK) { + if(m_state[submodule].m_flags & h8_dma_state::MAR_IS_DEST) + m_state[submodule].m_dest = m_mar[1]; + else + m_state[submodule].m_source = m_mar[0]; + m_state[submodule].m_count = m_etcr[0] & 0xff00 ? m_etcr[0] >> 8 : 0x100; + + m_state[submodule].m_bcount --; + if(m_state[submodule].m_bcount == 1) + m_state[submodule].m_flags &= ~h8_dma_state::BLOCK; + + if(m_state[submodule].m_trigger_vector != DREQ_LEVEL) { + m_state[submodule].m_flags |= h8_dma_state::SUSPENDED; + m_cpu->update_active_dma_channel(); + } + + } else if(m_state[submodule].m_flags & h8_dma_state::REPEAT) { + if(m_state[submodule].m_flags & h8_dma_state::MAR_IS_DEST) + m_state[submodule].m_dest = m_mar[submodule]; + else + m_state[submodule].m_source = m_mar[submodule]; + m_state[submodule].m_count = m_etcr[submodule] & 0xff ? m_etcr[submodule] & 0xff : 0x100; + + } else + dma_done(submodule); } -void h8_dma_channel_device::dmacr_w(offs_t offset, uint16_t data, uint16_t mem_mask) + +// H8H top device specifics + +h8h_dma_device::h8h_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + h8gen_dma_device(mconfig, H8H_DMA, tag, owner, clock) { - COMBINE_DATA(&m_dmacr); - logerror("dmacr_w %04x\n", m_dmacr); - start_test(-1); } -// H8H DMA -uint8_t h8_dma_channel_device::dtcra_r() +u8 h8h_dma_device::active_channels() const +{ + u8 res = 0; + for(int i=0; i != 4; i++) + if(m_dmach[i]) + res |= downcast(m_dmach[i].target())->active_channels() << (2*i); + return res; +} + + +// H8S top device specifics + +h8s_dma_device::h8s_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + h8gen_dma_device(mconfig, H8S_DMA, tag, owner, clock) +{ +} + +void h8s_dma_device::device_start() +{ + h8gen_dma_device::device_start(); + save_item(NAME(m_dmabcr)); + save_item(NAME(m_dmatcr)); + save_item(NAME(m_dmawer)); +} + +void h8s_dma_device::device_reset() +{ + h8gen_dma_device::device_reset(); + m_dmabcr = 0x0000; + m_dmatcr = 0x00; + m_dmawer = 0x00; +} + +u8 h8s_dma_device::active_channels() const +{ + u8 res = 0; + for(int i=0; i != 2; i++) + if(BIT(m_dmabcr, 14+i)) { + if(((m_dmabcr >> (4+2*i)) & 3) == 3) + res |= 2 << (2*i); + } else { + if(BIT(m_dmabcr, 4+2*i)) + res |= 1 << (2*i); + if(BIT(m_dmabcr, 5+2*i)) + res |= 2 << (2*i); + } + return res; +} + + +u8 h8s_dma_device::dmawer_r() +{ + logerror("dmawer_r %02x\n", m_dmawer); + return m_dmawer; +} + +void h8s_dma_device::dmawer_w(u8 data) +{ + m_dmawer = data; + logerror("dmawer_w %02x\n", data); +} + +u8 h8s_dma_device::dmatcr_r() +{ + logerror("dmatcr_r %02x\n", m_dmatcr); + return m_dmatcr; +} + +void h8s_dma_device::dmatcr_w(u8 data) +{ + m_dmatcr = data; + logerror("dmatcr_w %02x\n", data); +} + +u16 h8s_dma_device::dmabcr_r() +{ + logerror("dmabcr_r %04x\n", m_dmabcr); + return m_dmabcr; +} + +void h8s_dma_device::dmabcr_w(offs_t offset, u16 data, u16 mem_mask) +{ + COMBINE_DATA(&m_dmabcr); + logerror("dmabcr_w %04x\n", m_dmabcr); + start_stop_test(); +} + +void h8s_dma_device::channel_done(int id) +{ + m_dmabcr &= ~(0x0010 << id); +} + +int h8s_dma_device::channel_mode(int id, bool block) const +{ + if(BIT(m_dmabcr, 14+id)) { + // fae mode + return block ? h8h_dma_channel_device::FAE_BLOCK : h8h_dma_channel_device::FAE_NORMAL; + + } else { + // sae mode + return BIT(m_dmabcr, 12+id) ? h8h_dma_channel_device::SAE_DACK : h8h_dma_channel_device::SAE; + } +} + + std::tuple h8s_dma_device::get_fae_dtie_dta(int id) const +{ + bool fae = BIT(m_dmabcr, 14+(id >> 1)); + bool dtie = BIT(m_dmabcr, id); + bool dta = BIT(m_dmabcr, 8+id); + return std::tie(fae, dtie, dta); +} + + +// H8H channels specifics + +h8h_dma_channel_device::h8h_dma_channel_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + h8gen_dma_channel_device(mconfig, H8H_DMA_CHANNEL, tag, owner, clock), + m_dma(*this, finder_base::DUMMY_TAG) +{ + m_irq_base = 44; + m_ioar_mask = 0xffff00; +} + +void h8h_dma_channel_device::device_start() +{ + h8gen_dma_channel_device::device_start(); + save_item(NAME(m_dtcr)); +} + +void h8h_dma_channel_device::device_reset() +{ + h8gen_dma_channel_device::device_reset(); + m_dtcr[0] = m_dtcr[1] = 0; +} + +u8 h8h_dma_channel_device::dtcra_r() { logerror("dtcra_r %02x\n", m_dtcr[0]); return m_dtcr[0]; } -void h8_dma_channel_device::dtcra_w(uint8_t data) +void h8h_dma_channel_device::dtcra_w(u8 data) { m_dtcr[0] = data; logerror("dtcra_w %02x\n", m_dtcr[0]); - if((m_dtcr[0] & 0x80) && (m_dtcr[1] & 0x80)) { // if both DTME and DTE are set, start DMA - h8h_sync(); - } + m_dma->start_stop_test(); } -uint8_t h8_dma_channel_device::dtcrb_r() +u8 h8h_dma_channel_device::dtcrb_r() { logerror("dtcrb_r %02x\n", m_dtcr[1]); return m_dtcr[1]; } -void h8_dma_channel_device::dtcrb_w(uint8_t data) +void h8h_dma_channel_device::dtcrb_w(u8 data) { m_dtcr[1] = data; logerror("dtcrb_w %02x\n", m_dtcr[1]); - if((m_dtcr[0] & 0x80) && (m_dtcr[1] & 0x80)) { // if both DTME and DTE are set, start DMA - h8h_sync(); + m_dma->start_stop_test(); +} + +void h8h_dma_channel_device::dma_done(int submodule) +{ + m_dtcr[submodule] &= ~0x80; + h8gen_dma_channel_device::dma_done(submodule); +} + +int h8h_dma_channel_device::channel_mode() const +{ + switch(m_dtcr[0] & 7) { + case 6: return FAE_NORMAL; + case 7: return FAE_BLOCK; + default: return SAE; } } -void h8_dma_channel_device::h8h_sync() +u16 h8h_dma_channel_device::channel_flags(int submodule) const { - // update DMACR - m_dmacr = 0; - if(BIT(m_dtcr[0], 6)) m_dmacr |= 1 << 15; // DTSZ - m_dmacr |= ((m_dtcr[0] & 0b110000) >> 4) << 13; // SAID/DTID, SAIDE/RPE - m_dmacr |= ((m_dtcr[1] & 0b110000) >> 4) << 5; // DAID/DTID, DAIDE/RPE - - uint8_t dte = 0; - if(BIT(m_dtcr[0], 7)) dte |= 0b01; // DTE - if(BIT(m_dtcr[1], 7)) dte |= 0b10; // DTME/DTE - - bool fae = (m_dtcr[0] & 0b110) == 0b110; // A channel operates in full address mode when DTS2A and DTS1A are both set to 1. - bool sae = false; // don't support - uint8_t dta = 0; // don't support - uint8_t dtie = 0; - if(fae) { - // Full address mode - if(BIT(m_dtcr[0], 3)) dtie = 0b11; - if(BIT(m_dtcr[0], 0)) { - // Block Transfer Mode - m_dmacr |= 1 << 11; // BLKE - if(BIT(m_dtcr[1], 3)) m_dmacr |= 1 << 12; // BLKDIR (TMS) - switch(m_dtcr[1] & 0b111) { // DTP (DTS) - case 0b000: m_dmacr |= 0b1000; break; // ITU channel 0 - case 0b001: m_dmacr |= 0b1001; break; // ITU channel 1 - case 0b010: m_dmacr |= 0b1010; break; // ITU channel 2 - case 0b011: m_dmacr |= 0b1011; break; // ITU channel 3 - case 0b110: m_dmacr |= 0b1000; break; // DREQ falling edge - } - } else { - // Normal Mode - switch(m_dtcr[1] & 0b111) { // DTP (DTS) - case 0b000: m_dmacr |= 0b0111; break; // Auto-request (burst mode) - case 0b010: m_dmacr |= 0b0110; break; // Auto-request (cycle-steal mode) - case 0b110: m_dmacr |= 0b0010; break; // DREQ falling edge - case 0b111: m_dmacr |= 0b0011; break; // DREQ low-level - } - } + u16 res = h8_dma_state::EAT_INTERRUPT; + + if((m_dtcr[0] & 6) == 6) { + // FAE mode, expect submodule==1 + res |= h8_dma_state::FAE; + + if(BIT(m_dtcr[0], 6)) + res |= h8_dma_state::MODE_16; + if(BIT(m_dtcr[0], 3)) + res |= h8_dma_state::TEND_INTERRUPT; + + if(!BIT(m_dtcr[0], 4)) + res |= h8_dma_state::SOURCE_IDLE; + else if(BIT(m_dtcr[0], 5)) + res |= h8_dma_state::SOURCE_DECREMENT; + + if(!BIT(m_dtcr[1], 4)) + res |= h8_dma_state::DEST_IDLE; + else if(BIT(m_dtcr[1], 5)) + res |= h8_dma_state::DEST_DECREMENT; + + if(!BIT(m_dtcr[1], 3)) + res |= h8_dma_state::MAR_IS_DEST; + } else { - // Short address mode - if(BIT(m_dtcr[0], 3)) dtie |= 0b01; - if(BIT(m_dtcr[1], 3)) dtie |= 0b10; - for(int submodule = 0; submodule < 2; submodule++) { - switch(m_dtcr[submodule] & 0b111) { // DTP, DTDIR (DTS) - case 0b000: m_dmacr |= 0b01000 << (submodule ? 0 : 8); break; // ITU channel 0 - case 0b001: m_dmacr |= 0b01001 << (submodule ? 0 : 8); break; // ITU channel 1 - case 0b010: m_dmacr |= 0b01010 << (submodule ? 0 : 8); break; // ITU channel 2 - case 0b011: m_dmacr |= 0b01011 << (submodule ? 0 : 8); break; // ITU channel 3 - //case 0b011: m_dmacr |= 0b10001 << (submodule ? 0 : 8); break; // A/D converter conversion end (H8/3006) - case 0b100: m_dmacr |= 0b00100 << (submodule ? 0 : 8); break; // SCI channel 0 transmission data empty - case 0b101: m_dmacr |= 0b10101 << (submodule ? 0 : 8); break; // SCI channel 0 receive data full - case 0b110: m_dmacr |= 0b00010 << (submodule ? 0 : 8); break; // DREQ falling edge (B only) - case 0b111: m_dmacr |= 0b00011 << (submodule ? 0 : 8); break; // DREQ low-level (B only) - } + if(BIT(m_dtcr[submodule], 6)) + res |= h8_dma_state::MODE_16; + if(BIT(m_dtcr[submodule], 3)) + res |= h8_dma_state::TEND_INTERRUPT; + + int vector = trigger_vector(submodule); + if(!(vector == 23 || vector >= 52)) // adc & sci + res |= h8_dma_state::MAR_IS_DEST | h8_dma_state::SOURCE_IDLE; + else + res |= h8_dma_state::DEST_IDLE; + + if(BIT(m_dtcr[submodule], 5)) + res |= (res & h8_dma_state::MAR_IS_DEST) ? h8_dma_state::DEST_DECREMENT : h8_dma_state::SOURCE_DECREMENT; + + if(BIT(m_dtcr[submodule], 4)) { + if(BIT(m_dtcr[submodule], 3)) + res |= h8_dma_state::DEST_IDLE | h8_dma_state::SOURCE_IDLE; + else + res |= h8_dma_state::REPEAT; } } + return res; +} + +u8 h8h_dma_channel_device::active_channels() const +{ + u8 res = 0; + if((m_dtcr[0] & 6) == 6) { + if(BIT(m_dtcr[0], 7) && BIT(m_dtcr[1], 7)) + res |= 2; + } else { + if(BIT(m_dtcr[0], 7)) + res |= 1; + if(BIT(m_dtcr[1], 7)) + res |= 2; + } + return res; +} - set_bcr(fae, sae, dta, dte, dtie); +s8 h8h_dma_channel_device::trigger_vector(int submodule) const +{ + static const s8 faen[8] = { AUTOREQ_B, NONE, AUTOREQ_CS, NONE, NONE, NONE, DREQ_EDGE, DREQ_LEVEL }; + static const s8 faeb[8] = { 24, 28, 32, 36, NONE, NONE, DREQ_EDGE, NONE }; + static const s8 sae[8] = { 24, 28, 32, 36, 54, 53, DREQ_EDGE, DREQ_LEVEL }; + s8 vector = NONE; + switch(channel_mode()) { + case FAE_NORMAL: vector = faen[m_dtcr[submodule] & 7]; break; + case FAE_BLOCK: vector = faeb[m_dtcr[submodule] & 7]; break; + case SAE: vector = sae [m_dtcr[submodule] & 7]; break; + } - start_test(-1); + if(m_has_adc && vector == 36) + vector = 23; + if(m_targets_sci1 && (vector == 53 || vector == 54)) + vector += 4; + return vector; } -void h8_dma_channel_device::set_bcr(bool fae, bool sae, uint8_t dta, uint8_t dte, uint8_t dtie) + + +// H8S channels specifics + +h8s_dma_channel_device::h8s_dma_channel_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + h8gen_dma_channel_device(mconfig, H8S_DMA_CHANNEL, tag, owner, clock), + m_dma(*this, finder_base::DUMMY_TAG) { - m_fae = fae; - m_sae = sae; - m_dta = dta & 3; - m_dte = dte & 3; - m_dtie = dtie & 3; - logerror("fae=%d sae=%d dta=%d dte=%d dtie=%d\n", fae, sae, dta & 3, dte & 3, dtie & 3); - start_test(-1); + m_irq_base = 72; + m_ioar_mask = 0xff0000; } -bool h8_dma_channel_device::start_test(int vector) +void h8s_dma_channel_device::device_start() { - if(m_fae) { - if(m_dte != 3) - return false; + h8gen_dma_channel_device::device_start(); + save_item(NAME(m_dmacr)); +} - if(m_dmacr & 0x0800) { - throw emu_fatalerror("%s: DMA startup test in full address/block mode unimplemented.\n", tag()); +void h8s_dma_channel_device::device_reset() +{ + h8gen_dma_channel_device::device_reset(); + m_dmacr = 0; +} - } else { - // Normal Mode - if(vector == -1) { - start(0); - return true; - } else { - // DREQ trigger - if(((m_dmacr & 0b111) == 0b0010 && vector == DREQ_EDGE) || ((m_dmacr & 0b111) == 0b0011 && vector == DREQ_LEVEL)) { - m_state[0].m_suspended = false; - return true; - } - } - return false; - } - } else { - if(m_dte == 0) - return false; - - if(vector == -1) { - // A has priority over B - if(m_dte & 2) - start(1); - if(m_dte & 1) - start(0); - return true; - } else if(m_dte & 2) { - // DREQ trigger (B only) - if(((m_dmacr & 0b111) == 0b0010 && vector == DREQ_EDGE) || ((m_dmacr & 0b111) == 0b0011 && vector == DREQ_LEVEL)) { - m_state[1].m_suspended = false; - return true; - } - } - return false; - } +u16 h8s_dma_channel_device::dmacr_r() +{ + logerror("dmacr_r %04x\n", m_dmacr); + return m_dmacr; } -void h8_dma_channel_device::start(int submodule) +void h8s_dma_channel_device::dmacr_w(offs_t offset, u16 data, u16 mem_mask) { - if(m_fae) { - if(m_dmacr & 0x0800) - throw emu_fatalerror("%s: DMA start in full address/block mode unimplemented.\n", tag()); - else { - m_state[submodule].m_source = m_mar[0]; - m_state[submodule].m_dest = m_mar[1]; - m_state[submodule].m_count = m_etcr[0] ? m_etcr[0] : 0x10000; - m_state[submodule].m_mode_16 = m_dmacr & 0x8000; - m_state[submodule].m_autoreq = (m_dmacr & 6) == 6 || (m_dmacr & 7) == 3; // autoreq or dreq level - m_state[submodule].m_suspended = (m_dmacr & 6) != 6; // non-auto-request transfers start suspended - int32_t step = m_state[submodule].m_mode_16 ? 2 : 1; - m_state[submodule].m_incs = m_dmacr & 0x2000 ? m_dmacr & 0x4000 ? -step : step : 0; - m_state[submodule].m_incd = m_dmacr & 0x0020 ? m_dmacr & 0x0040 ? -step : step : 0; - m_cpu->set_current_dma(m_state + submodule); - } - } else { - uint8_t cr = submodule ? m_dmacr & 0x00ff : m_dmacr >> 8; - m_state[submodule].m_mode_16 = cr & 0x80; - m_state[submodule].m_autoreq = false; - m_state[submodule].m_suspended = true; - int32_t step = m_state[submodule].m_mode_16 ? 2 : 1; - if(!(cr & 0x20)) { - // Sequential mode - m_state[submodule].m_count = m_etcr[submodule] ? m_etcr[submodule] : 0x10000; - m_state[submodule].m_incs = cr & 0x40 ? -step : step; - } else if(m_dtie & (1 << submodule)) { - // Idle mode - m_state[submodule].m_count = m_etcr[submodule] ? m_etcr[submodule] : 0x10000; - m_state[submodule].m_incs = 0; - } else { - // Repeat mode - m_state[submodule].m_count = m_etcr[submodule] & 0x00ff ? m_etcr[submodule] & 0x00ff : 0x100; - m_state[submodule].m_incs = cr & 0x40 ? -step : step; - } - if(cr & 0x10) { - m_state[submodule].m_source = 0xff0000 | m_ioar[submodule]; - m_state[submodule].m_dest = m_mar[submodule]; - m_state[submodule].m_incd = m_state[submodule].m_incs; - m_state[submodule].m_incs = 0; - } else { - m_state[submodule].m_source = m_mar[submodule]; - m_state[submodule].m_dest = 0xff0000 | m_ioar[submodule]; - m_state[submodule].m_incd = 0; - } - m_cpu->set_current_dma(m_state + submodule); - } + COMBINE_DATA(&m_dmacr); + logerror("dmacr_w %04x\n", m_dmacr); } -void h8_dma_channel_device::count_last(int submodule) +void h8s_dma_channel_device::dma_done(int submodule) { - logerror("count last on %d\n", submodule); - if(!m_state[submodule].m_autoreq) // "The TEND signal goes low during the last write cycle." - m_cpu->set_input_line(H8_INPUT_LINE_TEND0 + (m_state[submodule].m_id >> 1), ASSERT_LINE); + m_dma->channel_done(m_state[submodule].m_id); + h8gen_dma_channel_device::dma_done(submodule); } -void h8_dma_channel_device::count_done(int submodule) +int h8s_dma_channel_device::channel_mode() const { - if(!m_state[submodule].m_autoreq) - m_cpu->set_input_line(H8_INPUT_LINE_TEND0 + (m_state[submodule].m_id >> 1), CLEAR_LINE); - if(m_fae) { - if(m_dmacr & 0x0800) - throw emu_fatalerror("%s: DMA count done full address/block mode unimplemented.\n", tag()); - else { - m_dte &= ~1; - m_dma->clear_dte(m_state[0].m_id); - m_dtcr[0] &= ~0x80; // clear DTE (for H8H) - if(m_dtie & 1) - m_intc->internal_interrupt(m_irq_base + submodule); - } + return m_dma->channel_mode(m_state[0].m_id >> 1, BIT(m_dmacr, 11)); +} + +u16 h8s_dma_channel_device::channel_flags(int submodule) const +{ + auto [fae, dtie, dta] = m_dma->get_fae_dtie_dta(m_state[submodule].m_id); + u16 res = 0; + + if(fae) { + // FAE mode, expect submodule==1 + res |= h8_dma_state::FAE; + + if(BIT(m_dmacr, 15)) + res |= h8_dma_state::MODE_16; + if(!BIT(m_dmacr, 13)) + res |= h8_dma_state::SOURCE_IDLE; + else if(!BIT(m_dmacr, 14)) + res |= h8_dma_state::SOURCE_DECREMENT; + + if(!BIT(m_dmacr, 5)) + res |= h8_dma_state::DEST_IDLE; + else if(!BIT(m_dmacr, 6)) + res |= h8_dma_state::DEST_DECREMENT; + + if(!BIT(m_dmacr, 12)) + res |= h8_dma_state::MAR_IS_DEST; + } else { - uint8_t cr = submodule ? m_dmacr & 0x00ff : m_dmacr >> 8; - if((cr & 0x20) && !(m_dtie & (1 << submodule))) { - // Repeat mode - m_state[submodule].m_count = m_etcr[submodule] & 0x00ff ? m_etcr[submodule] & 0x00ff : 0x100; - if(cr & 0x10) - m_state[submodule].m_dest = m_mar[submodule]; + u8 cr = submodule ? m_dmacr : m_dmacr >> 8; + if(BIT(cr, 7)) + res |= h8_dma_state::MODE_16; + + if(BIT(cr, 4)) + res |= h8_dma_state::MAR_IS_DEST | h8_dma_state::SOURCE_IDLE; + else + res |= h8_dma_state::DEST_IDLE; + + if(BIT(cr, 6)) + res |= (res & h8_dma_state::MAR_IS_DEST) ? h8_dma_state::DEST_DECREMENT : h8_dma_state::SOURCE_DECREMENT; + + if(BIT(cr, 5)) { + if(dtie) + res |= h8_dma_state::DEST_IDLE | h8_dma_state::SOURCE_IDLE; else - m_state[submodule].m_source = m_mar[submodule]; - } else { - m_dte &= ~(1 << submodule); - m_dma->clear_dte(m_state[0].m_id + submodule); - m_dtcr[submodule] &= ~0x80; // clear DTE (for H8H) - if(m_dtie & (1 << submodule)) - m_intc->internal_interrupt(m_irq_base + submodule); + res |= h8_dma_state::REPEAT; } } + + if(dtie) + res |= h8_dma_state::TEND_INTERRUPT; + if(dta) + res |= h8_dma_state::EAT_INTERRUPT; + + return res; +} + +s8 h8s_dma_channel_device::trigger_vector(int submodule) const +{ + static const s8 vectors[0x10] = { NONE, 28, DREQ_EDGE, DREQ_LEVEL, 82, 81, 86, 85, 32, 40, 44, 48, 56, 60, NONE, NONE }; + static const s8 vectorsn[0x10] = { NONE, NONE, DREQ_EDGE, DREQ_LEVEL, NONE, NONE, AUTOREQ_CS, AUTOREQ_B, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE }; + + if(submodule) { + // fae normal mode has a special table + if(channel_mode() == FAE_NORMAL) + return vectorsn[m_dmacr & 15]; + else + return vectors[m_dmacr & 15]; + + } else { + s8 vector = vectors[(m_dmacr >> 8) & 15]; + // subchannel A doesn't do dreq + if(vector < NONE) + vector = NONE; + return vector; + } } diff --git a/src/devices/cpu/h8/h8_dma.h b/src/devices/cpu/h8/h8_dma.h index cf851a22b40..87e69d68765 100644 --- a/src/devices/cpu/h8/h8_dma.h +++ b/src/devices/cpu/h8/h8_dma.h @@ -17,16 +17,32 @@ #include "h8_intc.h" struct h8_dma_state { - uint32_t m_source, m_dest; - int32_t m_incs, m_incd; - uint32_t m_count; - int m_id; - bool m_autoreq; // activate by auto-request - bool m_suspended; - bool m_mode_16; + enum { + ACTIVE = 0x0001, // DMA is configured + SUSPENDED = 0x0002, // DMA currently suspended until trigger happens + SUSPEND_AFTER_TRANSFER = 0x0004, // Auto-suspend DMA after each transfer + BLOCK = 0x0008, // FAE block mode (cleared on last block) + REPEAT = 0x0010, // SAE repeat mode + MODE_16 = 0x0020, // Transfer 16-bits values + EAT_INTERRUPT = 0x0040, // Discard interrupt when used as trigger + TEND_INTERRUPT = 0x0080, // Interrupt on end of transfer + SOURCE_DECREMENT = 0x0100, // Decrement source instead of increment (folded into incs/incd) + DEST_DECREMENT = 0x0200, // Decrement source instead of increment (folded into incs/incd) + SOURCE_IDLE = 0x0400, // Don't increment/decrement source (folded into incs/incd) + DEST_IDLE = 0x0800, // Don't increment/decrement destination (folded into incs/incd) + MAR_IS_DEST = 0x1000, // MAR is destination in SAE (folded), destibation is the block in fae block + FAE = 0x2000, // FAE mode (for interrupt generation) + }; + + u32 m_source, m_dest; + s32 m_incs, m_incd; + u32 m_count, m_bcount; + u16 m_flags; + u8 m_id; + s8 m_trigger_vector; }; -class h8_dma_channel_device; +class h8gen_dma_channel_device; enum { // mind the order, all DREQ, TEND need to be sequential @@ -41,136 +57,220 @@ enum { H8_INPUT_LINE_TEND3, }; -class h8_dma_device : public device_t { -public: - h8_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - template h8_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu) : - h8_dma_device(mconfig, tag, owner) - { - m_cpu.set_tag(std::forward(cpu)); - } +class h8h_dma_device; +class h8s_dma_device; - uint8_t dmawer_r(); - void dmawer_w(uint8_t data); - uint8_t dmatcr_r(); - void dmatcr_w(uint8_t data); - uint16_t dmabcr_r(); - void dmabcr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); +DECLARE_DEVICE_TYPE(H8H_DMA, h8h_dma_device) +DECLARE_DEVICE_TYPE(H8S_DMA, h8s_dma_device) +class h8gen_dma_device : public device_t { +public: bool trigger_dma(int vector); void count_last(int id); void count_done(int id); - void clear_dte(int id); void set_input(int inputnum, int state); + void start_stop_test(); protected: required_device m_cpu; - required_device m_dmach0, m_dmach1; + optional_device_array m_dmach; virtual void device_start() override; virtual void device_reset() override; - bool m_dreq[2]; + virtual u8 active_channels() const = 0; + + h8gen_dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock = 0); +}; + +class h8h_dma_device : public h8gen_dma_device +{ +public: + h8h_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + template h8h_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu) + : h8h_dma_device(mconfig, tag, owner) + { + m_cpu.set_tag(std::forward(cpu)); + } + + u8 active_channels() const override; +}; + - uint8_t m_dmawer, m_dmatcr; - uint16_t m_dmabcr; +class h8s_dma_device : public h8gen_dma_device +{ +public: + h8s_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + template h8s_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu) + : h8s_dma_device(mconfig, tag, owner) + { + m_cpu.set_tag(std::forward(cpu)); + } + + u8 dmawer_r(); + void dmawer_w(u8 data); + u8 dmatcr_r(); + void dmatcr_w(u8 data); + u16 dmabcr_r(); + void dmabcr_w(offs_t offset, u16 data, u16 mem_mask = ~0); + + void channel_done(int id); + int channel_mode(int id, bool block) const; + std::tuple get_fae_dtie_dta(int id) const; + +protected: + u8 m_dmawer, m_dmatcr; + u16 m_dmabcr; + + void device_start() override; + void device_reset() override; + + u8 active_channels() const override; }; -class h8_dma_channel_device : public device_t { + + + +class h8gen_dma_channel_device : public device_t { public: enum { - NONE = -1, - DREQ_LEVEL = -2, - DREQ_EDGE = -3 + NONE = 0, + DREQ_LEVEL = -1, + DREQ_EDGE = -2, + AUTOREQ_CS = -3, + AUTOREQ_B = -4, }; enum { - MODE8_MEM_MEM, - MODE8_DACK_MEM, - MODE8_MEM_DACK, - MODE16_MEM_MEM, - MODE16_DACK_MEM, - MODE16_MEM_DACK + FAE_NORMAL, + FAE_BLOCK, + SAE, + SAE_DACK, }; - h8_dma_channel_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template h8_dma_channel_device(const machine_config &mconfig, const char *tag, device_t *owner, - T &&cpu, U &&dma, V &&intc, int irq_base, int v0, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, - int v9 = h8_dma_channel_device::NONE, - int va = h8_dma_channel_device::NONE, - int vb = h8_dma_channel_device::NONE, - int vc = h8_dma_channel_device::NONE, - int vd = h8_dma_channel_device::NONE, - int ve = h8_dma_channel_device::NONE, - int vf = h8_dma_channel_device::NONE) - : h8_dma_channel_device(mconfig, tag, owner, 0) - { - m_cpu.set_tag(std::forward(cpu)); - m_dma.set_tag(std::forward(dma)); - m_intc.set_tag(std::forward(intc)); - set_info(irq_base, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, va, vb, vc, vd, ve, vf); - } - void set_info(int irq_base, int v0, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int v9, int va, int vb, int vc, int vd, int ve, int vf); - - uint16_t marah_r(); - void marah_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t maral_r(); - void maral_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t ioara_r(); - uint8_t ioara8_r(); - void ioara_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void ioara8_w(uint8_t data); - uint16_t etcra_r(); - void etcra_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t marbh_r(); - void marbh_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t marbl_r(); - void marbl_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t ioarb_r(); - uint8_t ioarb8_r(); - void ioarb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void ioarb8_w(uint8_t data); - uint16_t etcrb_r(); - void etcrb_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t dmacr_r(); - void dmacr_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - - // H8H DMA - uint8_t dtcra_r(); - void dtcra_w(uint8_t data); - uint8_t dtcrb_r(); - void dtcrb_w(uint8_t data); + h8_dma_state m_state[2]; + + h8gen_dma_channel_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + u16 marah_r(); + void marah_w(offs_t offset, u16 data, u16 mem_mask = ~0); + u16 maral_r(); + void maral_w(offs_t offset, u16 data, u16 mem_mask = ~0); + u16 ioara_r(); + u8 ioara8_r(); + void ioara_w(offs_t offset, u16 data, u16 mem_mask = ~0); + void ioara8_w(u8 data); + u16 etcra_r(); + void etcra_w(offs_t offset, u16 data, u16 mem_mask = ~0); + u16 marbh_r(); + void marbh_w(offs_t offset, u16 data, u16 mem_mask = ~0); + u16 marbl_r(); + void marbl_w(offs_t offset, u16 data, u16 mem_mask = ~0); + u16 ioarb_r(); + u8 ioarb8_r(); + void ioarb_w(offs_t offset, u16 data, u16 mem_mask = ~0); + void ioarb8_w(u8 data); + u16 etcrb_r(); + void etcrb_w(offs_t offset, u16 data, u16 mem_mask = ~0); void set_id(int id); - void set_bcr(bool fae, bool sae, uint8_t dta, uint8_t dte, uint8_t dtie); - bool start_test(int vector); - void count_last(int submodule); void count_done(int submodule); + void start_stop_test(); + bool transfer_test_interrupt(int vector); + void set_dreq(int state); + void start(int submodule); + protected: required_device m_cpu; - required_device m_dma; required_device m_intc; - h8_dma_state m_state[2]; int m_irq_base; + u32 m_ioar_mask; // ff0000 for h8s, ffff00 for h8h - int m_activation_vectors[16]; - - uint32_t m_mar[2]; - uint16_t m_ioar[2], m_etcr[2], m_dmacr; - uint8_t m_dtcr[2]; // H8H - uint8_t m_dta, m_dte, m_dtie; - bool m_fae; // Full-Address Mode - bool m_sae; // Short-Address Mode + u32 m_mar[2]; + u16 m_ioar[2], m_etcr[2]; + bool m_dreq; virtual void device_start() override; virtual void device_reset() override; - void h8h_sync(); // call set_bcr with contents from DTCR - void start(int submodule); + virtual void dma_done(int subchannel); + virtual int channel_mode() const = 0; + virtual u16 channel_flags(int submodule) const = 0; + virtual s8 trigger_vector(int submodule) const = 0; +}; + +class h8h_dma_channel_device : public h8gen_dma_channel_device +{ +public: + h8h_dma_channel_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + template h8h_dma_channel_device(const machine_config &mconfig, const char *tag, device_t *owner, + T &&cpu, U &&dma, V &&intc, bool has_adc, bool targets_sci1) + : h8h_dma_channel_device(mconfig, tag, owner) + { + m_cpu.set_tag(std::forward(cpu)); + m_dma.set_tag(std::forward(dma)); + m_intc.set_tag(std::forward(intc)); + m_has_adc = has_adc; + m_targets_sci1 = targets_sci1; + } + + u8 dtcra_r(); + void dtcra_w(u8 data); + u8 dtcrb_r(); + void dtcrb_w(u8 data); + + u8 active_channels() const; + +protected: + required_device m_dma; + u8 m_dtcr[2]; + bool m_has_adc; + bool m_targets_sci1; + + void device_start() override; + void device_reset() override; + void dma_done(int subchannel) override; + + int channel_mode() const override; + u16 channel_flags(int submodule) const override; + s8 trigger_vector(int submodule) const override; +}; + +class h8s_dma_channel_device : public h8gen_dma_channel_device +{ +public: + h8s_dma_channel_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + template h8s_dma_channel_device(const machine_config &mconfig, const char *tag, device_t *owner, + T &&cpu, U &&dma, V &&intc) + : h8s_dma_channel_device(mconfig, tag, owner) + { + m_cpu.set_tag(std::forward(cpu)); + m_dma.set_tag(std::forward(dma)); + m_intc.set_tag(std::forward(intc)); + } + + u16 dmacr_r(); + void dmacr_w(offs_t offset, u16 data, u16 mem_mask = ~0); + +protected: + u16 m_dmacr; + + required_device m_dma; + void device_start() override; + void device_reset() override; + void dma_done(int subchannel) override; + + int channel_mode() const override; + u16 channel_flags(int submodule) const override; + s8 trigger_vector(int submodule) const override; }; -DECLARE_DEVICE_TYPE(H8_DMA, h8_dma_device) -DECLARE_DEVICE_TYPE(H8_DMA_CHANNEL, h8_dma_channel_device) +DECLARE_DEVICE_TYPE(H8H_DMA_CHANNEL, h8h_dma_channel_device) +DECLARE_DEVICE_TYPE(H8S_DMA_CHANNEL, h8s_dma_channel_device) #endif // MAME_CPU_H8_H8_DMA_H diff --git a/src/devices/cpu/h8/h8s2320.cpp b/src/devices/cpu/h8/h8s2320.cpp index 1442033252e..bbbcf966766 100644 --- a/src/devices/cpu/h8/h8s2320.cpp +++ b/src/devices/cpu/h8/h8s2320.cpp @@ -141,27 +141,29 @@ void h8s2320_device::map(address_map &map) map(0xfffec4, 0xfffecd).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w)); map(0xfffece, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::iprk_r), FUNC(h8s_intc_device::iprk_w)); - map(0xfffee0, 0xfffee1).rw(m_dma0, FUNC(h8_dma_channel_device::marah_r), FUNC(h8_dma_channel_device::marah_w)); - map(0xfffee2, 0xfffee3).rw(m_dma0, FUNC(h8_dma_channel_device::maral_r), FUNC(h8_dma_channel_device::maral_w)); - map(0xfffee4, 0xfffee5).rw(m_dma0, FUNC(h8_dma_channel_device::ioara_r), FUNC(h8_dma_channel_device::ioara_w)); - map(0xfffee6, 0xfffee7).rw(m_dma0, FUNC(h8_dma_channel_device::etcra_r), FUNC(h8_dma_channel_device::etcra_w)); - map(0xfffee8, 0xfffee9).rw(m_dma0, FUNC(h8_dma_channel_device::marbh_r), FUNC(h8_dma_channel_device::marbh_w)); - map(0xfffeea, 0xfffeeb).rw(m_dma0, FUNC(h8_dma_channel_device::marbl_r), FUNC(h8_dma_channel_device::marbl_w)); - map(0xfffeec, 0xfffeed).rw(m_dma0, FUNC(h8_dma_channel_device::ioarb_r), FUNC(h8_dma_channel_device::ioarb_w)); - map(0xfffeee, 0xfffeef).rw(m_dma0, FUNC(h8_dma_channel_device::etcrb_r), FUNC(h8_dma_channel_device::etcrb_w)); - map(0xfffef0, 0xfffef1).rw(m_dma1, FUNC(h8_dma_channel_device::marah_r), FUNC(h8_dma_channel_device::marah_w)); - map(0xfffef2, 0xfffef3).rw(m_dma1, FUNC(h8_dma_channel_device::maral_r), FUNC(h8_dma_channel_device::maral_w)); - map(0xfffef4, 0xfffef5).rw(m_dma1, FUNC(h8_dma_channel_device::ioara_r), FUNC(h8_dma_channel_device::ioara_w)); - map(0xfffef6, 0xfffef7).rw(m_dma1, FUNC(h8_dma_channel_device::etcra_r), FUNC(h8_dma_channel_device::etcra_w)); - map(0xfffef8, 0xfffef9).rw(m_dma1, FUNC(h8_dma_channel_device::marbh_r), FUNC(h8_dma_channel_device::marbh_w)); - map(0xfffefa, 0xfffefb).rw(m_dma1, FUNC(h8_dma_channel_device::marbl_r), FUNC(h8_dma_channel_device::marbl_w)); - map(0xfffefc, 0xfffefd).rw(m_dma1, FUNC(h8_dma_channel_device::ioarb_r), FUNC(h8_dma_channel_device::ioarb_w)); - map(0xfffefe, 0xfffeff).rw(m_dma1, FUNC(h8_dma_channel_device::etcrb_r), FUNC(h8_dma_channel_device::etcrb_w)); - map(0xffff00, 0xffff00).rw(m_dma, FUNC(h8_dma_device::dmawer_r), FUNC(h8_dma_device::dmawer_w)); - map(0xffff01, 0xffff01).rw(m_dma, FUNC(h8_dma_device::dmatcr_r), FUNC(h8_dma_device::dmatcr_w)); - map(0xffff02, 0xffff03).rw(m_dma0, FUNC(h8_dma_channel_device::dmacr_r), FUNC(h8_dma_channel_device::dmacr_w)); - map(0xffff04, 0xffff05).rw(m_dma1, FUNC(h8_dma_channel_device::dmacr_r), FUNC(h8_dma_channel_device::dmacr_w)); - map(0xffff06, 0xffff07).rw(m_dma, FUNC(h8_dma_device::dmabcr_r), FUNC(h8_dma_device::dmabcr_w)); + if(type() != H8S2321) { + map(0xfffee0, 0xfffee1).rw(m_dma0, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w)); + map(0xfffee2, 0xfffee3).rw(m_dma0, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w)); + map(0xfffee4, 0xfffee5).rw(m_dma0, FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w)); + map(0xfffee6, 0xfffee7).rw(m_dma0, FUNC(h8s_dma_channel_device::etcra_r), FUNC(h8s_dma_channel_device::etcra_w)); + map(0xfffee8, 0xfffee9).rw(m_dma0, FUNC(h8s_dma_channel_device::marbh_r), FUNC(h8s_dma_channel_device::marbh_w)); + map(0xfffeea, 0xfffeeb).rw(m_dma0, FUNC(h8s_dma_channel_device::marbl_r), FUNC(h8s_dma_channel_device::marbl_w)); + map(0xfffeec, 0xfffeed).rw(m_dma0, FUNC(h8s_dma_channel_device::ioarb_r), FUNC(h8s_dma_channel_device::ioarb_w)); + map(0xfffeee, 0xfffeef).rw(m_dma0, FUNC(h8s_dma_channel_device::etcrb_r), FUNC(h8s_dma_channel_device::etcrb_w)); + map(0xfffef0, 0xfffef1).rw(m_dma1, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w)); + map(0xfffef2, 0xfffef3).rw(m_dma1, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w)); + map(0xfffef4, 0xfffef5).rw(m_dma1, FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w)); + map(0xfffef6, 0xfffef7).rw(m_dma1, FUNC(h8s_dma_channel_device::etcra_r), FUNC(h8s_dma_channel_device::etcra_w)); + map(0xfffef8, 0xfffef9).rw(m_dma1, FUNC(h8s_dma_channel_device::marbh_r), FUNC(h8s_dma_channel_device::marbh_w)); + map(0xfffefa, 0xfffefb).rw(m_dma1, FUNC(h8s_dma_channel_device::marbl_r), FUNC(h8s_dma_channel_device::marbl_w)); + map(0xfffefc, 0xfffefd).rw(m_dma1, FUNC(h8s_dma_channel_device::ioarb_r), FUNC(h8s_dma_channel_device::ioarb_w)); + map(0xfffefe, 0xfffeff).rw(m_dma1, FUNC(h8s_dma_channel_device::etcrb_r), FUNC(h8s_dma_channel_device::etcrb_w)); + map(0xffff00, 0xffff00).rw(m_dma, FUNC(h8s_dma_device::dmawer_r), FUNC(h8s_dma_device::dmawer_w)); + map(0xffff01, 0xffff01).rw(m_dma, FUNC(h8s_dma_device::dmatcr_r), FUNC(h8s_dma_device::dmatcr_w)); + map(0xffff02, 0xffff03).rw(m_dma0, FUNC(h8s_dma_channel_device::dmacr_r), FUNC(h8s_dma_channel_device::dmacr_w)); + map(0xffff04, 0xffff05).rw(m_dma1, FUNC(h8s_dma_channel_device::dmacr_r), FUNC(h8s_dma_channel_device::dmacr_w)); + map(0xffff06, 0xffff07).rw(m_dma, FUNC(h8s_dma_device::dmabcr_r), FUNC(h8s_dma_device::dmabcr_w)); + } map(0xffff2c, 0xffff2c).rw(m_intc, FUNC(h8s_intc_device::iscrh_r), FUNC(h8s_intc_device::iscrh_w)); map(0xffff2d, 0xffff2d).rw(m_intc, FUNC(h8s_intc_device::iscrl_r), FUNC(h8s_intc_device::iscrl_w)); map(0xffff2e, 0xffff2e).rw(m_intc, FUNC(h8s_intc_device::ier_r), FUNC(h8s_intc_device::ier_w)); @@ -263,15 +265,15 @@ void h8s2320_device::map(address_map &map) map(0xfffff8, 0xfffffb).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w)); } -// TODO: the 2321 doesn't have the dma subdevice - void h8s2320_device::device_add_mconfig(machine_config &config) { H8S_INTC(config, m_intc, *this); H8_ADC_2320(config, m_adc, *this, m_intc, 28); - H8_DMA(config, m_dma, *this); - H8_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc, 72, h8_dma_channel_device::NONE, 28, h8_dma_channel_device::NONE, h8_dma_channel_device::NONE, 82, 81, 86, 85, 32, 40, 44, 48, 56, 60); - H8_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc, 74, h8_dma_channel_device::NONE, 28, h8_dma_channel_device::DREQ_EDGE, h8_dma_channel_device::DREQ_LEVEL, 82, 81, 86, 85, 32, 40, 44, 48, 56, 60); + if(type() != H8S2321) { + H8S_DMA(config, m_dma, *this); + H8S_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc); + H8S_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc); + } H8_DTC(config, m_dtc, *this, m_intc, 24); H8_PORT(config, m_port1, *this, h8_device::PORT_1, 0x00, 0x00); H8_PORT(config, m_port2, *this, h8_device::PORT_2, 0x00, 0x00); diff --git a/src/devices/cpu/h8/h8s2320.h b/src/devices/cpu/h8/h8s2320.h index aa6c4acf3f2..3979754eeec 100644 --- a/src/devices/cpu/h8/h8s2320.h +++ b/src/devices/cpu/h8/h8s2320.h @@ -52,9 +52,9 @@ public: protected: required_device m_intc; required_device m_adc; - optional_device m_dma; - optional_device m_dma0; - optional_device m_dma1; + optional_device m_dma; + optional_device m_dma0; + optional_device m_dma1; required_device m_dtc; required_device m_port1; required_device m_port2; diff --git a/src/devices/cpu/h8/h8s2357.cpp b/src/devices/cpu/h8/h8s2357.cpp index 4045ee3d4d4..eb1a4a7b0d9 100644 --- a/src/devices/cpu/h8/h8s2357.cpp +++ b/src/devices/cpu/h8/h8s2357.cpp @@ -14,6 +14,9 @@ h8s2357_device::h8s2357_device(const machine_config &mconfig, device_type type, h8s2000_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(h8s2357_device::map), this)), m_intc(*this, "intc"), m_adc(*this, "adc"), + m_dma(*this, "dma"), + m_dma0(*this, "dma:0"), + m_dma1(*this, "dma:1"), m_port1(*this, "port1"), m_port2(*this, "port2"), m_port3(*this, "port3"), @@ -113,6 +116,27 @@ void h8s2357_device::map(address_map &map) map(0xfffebf, 0xfffebf).w(m_portg, FUNC(h8_port_device::ddr_w)); map(0xfffec4, 0xfffecd).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w)); map(0xfffece, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::iprk_r), FUNC(h8s_intc_device::iprk_w)); + map(0xfffee0, 0xfffee1).rw(m_dma0, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w)); + map(0xfffee2, 0xfffee3).rw(m_dma0, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w)); + map(0xfffee4, 0xfffee5).rw(m_dma0, FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w)); + map(0xfffee6, 0xfffee7).rw(m_dma0, FUNC(h8s_dma_channel_device::etcra_r), FUNC(h8s_dma_channel_device::etcra_w)); + map(0xfffee8, 0xfffee9).rw(m_dma0, FUNC(h8s_dma_channel_device::marbh_r), FUNC(h8s_dma_channel_device::marbh_w)); + map(0xfffeea, 0xfffeeb).rw(m_dma0, FUNC(h8s_dma_channel_device::marbl_r), FUNC(h8s_dma_channel_device::marbl_w)); + map(0xfffeec, 0xfffeed).rw(m_dma0, FUNC(h8s_dma_channel_device::ioarb_r), FUNC(h8s_dma_channel_device::ioarb_w)); + map(0xfffeee, 0xfffeef).rw(m_dma0, FUNC(h8s_dma_channel_device::etcrb_r), FUNC(h8s_dma_channel_device::etcrb_w)); + map(0xfffef0, 0xfffef1).rw(m_dma1, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w)); + map(0xfffef2, 0xfffef3).rw(m_dma1, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w)); + map(0xfffef4, 0xfffef5).rw(m_dma1, FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w)); + map(0xfffef6, 0xfffef7).rw(m_dma1, FUNC(h8s_dma_channel_device::etcra_r), FUNC(h8s_dma_channel_device::etcra_w)); + map(0xfffef8, 0xfffef9).rw(m_dma1, FUNC(h8s_dma_channel_device::marbh_r), FUNC(h8s_dma_channel_device::marbh_w)); + map(0xfffefa, 0xfffefb).rw(m_dma1, FUNC(h8s_dma_channel_device::marbl_r), FUNC(h8s_dma_channel_device::marbl_w)); + map(0xfffefc, 0xfffefd).rw(m_dma1, FUNC(h8s_dma_channel_device::ioarb_r), FUNC(h8s_dma_channel_device::ioarb_w)); + map(0xfffefe, 0xfffeff).rw(m_dma1, FUNC(h8s_dma_channel_device::etcrb_r), FUNC(h8s_dma_channel_device::etcrb_w)); + map(0xffff00, 0xffff00).rw(m_dma, FUNC(h8s_dma_device::dmawer_r), FUNC(h8s_dma_device::dmawer_w)); + map(0xffff01, 0xffff01).rw(m_dma, FUNC(h8s_dma_device::dmatcr_r), FUNC(h8s_dma_device::dmatcr_w)); + map(0xffff02, 0xffff03).rw(m_dma0, FUNC(h8s_dma_channel_device::dmacr_r), FUNC(h8s_dma_channel_device::dmacr_w)); + map(0xffff04, 0xffff05).rw(m_dma1, FUNC(h8s_dma_channel_device::dmacr_r), FUNC(h8s_dma_channel_device::dmacr_w)); + map(0xffff06, 0xffff07).rw(m_dma, FUNC(h8s_dma_device::dmabcr_r), FUNC(h8s_dma_device::dmabcr_w)); map(0xffff2c, 0xffff2c).rw(m_intc, FUNC(h8s_intc_device::iscrh_r), FUNC(h8s_intc_device::iscrh_w)); map(0xffff2d, 0xffff2d).rw(m_intc, FUNC(h8s_intc_device::iscrl_r), FUNC(h8s_intc_device::iscrl_w)); map(0xffff2e, 0xffff2e).rw(m_intc, FUNC(h8s_intc_device::ier_r), FUNC(h8s_intc_device::ier_w)); @@ -213,6 +237,9 @@ void h8s2357_device::device_add_mconfig(machine_config &config) { H8S_INTC(config, m_intc, *this); H8_ADC_2357(config, m_adc, *this, m_intc, 28); + H8S_DMA(config, m_dma, *this); + H8S_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc); + H8S_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc); H8_PORT(config, m_port1, *this, h8_device::PORT_1, 0x00, 0x00); H8_PORT(config, m_port2, *this, h8_device::PORT_2, 0x00, 0x00); H8_PORT(config, m_port3, *this, h8_device::PORT_3, 0xc0, 0xc0); diff --git a/src/devices/cpu/h8/h8s2357.h b/src/devices/cpu/h8/h8s2357.h index 1fbe1653e1d..b89d299628b 100644 --- a/src/devices/cpu/h8/h8s2357.h +++ b/src/devices/cpu/h8/h8s2357.h @@ -28,6 +28,7 @@ #include "h8s2000.h" #include "h8_intc.h" #include "h8_adc.h" +#include "h8_dma.h" #include "h8_port.h" #include "h8_timer8.h" #include "h8_timer16.h" @@ -44,6 +45,9 @@ public: protected: required_device m_intc; required_device m_adc; + required_device m_dma; + required_device m_dma0; + required_device m_dma1; required_device m_port1; required_device m_port2; required_device m_port3; diff --git a/src/devices/cpu/h8/h8s2655.cpp b/src/devices/cpu/h8/h8s2655.cpp index e4e3597539c..6da24f7f919 100644 --- a/src/devices/cpu/h8/h8s2655.cpp +++ b/src/devices/cpu/h8/h8s2655.cpp @@ -10,6 +10,9 @@ h8s2655_device::h8s2655_device(const machine_config &mconfig, device_type type, h8s2600_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(h8s2655_device::map), this)), m_intc(*this, "intc"), m_adc(*this, "adc"), + m_dma(*this, "dma"), + m_dma0(*this, "dma:0"), + m_dma1(*this, "dma:1"), m_port1(*this, "port1"), m_port2(*this, "port2"), m_port3(*this, "port3"), @@ -92,6 +95,28 @@ void h8s2655_device::map(address_map &map) map(0xfffec2, 0xfffec2).rw(m_intc, FUNC(h8s_intc_device::icrc_r), FUNC(h8s_intc_device::icrc_w)); map(0xfffec4, 0xfffecd).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w)); map(0xfffece, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::iprk_r), FUNC(h8s_intc_device::iprk_w)); + + map(0xfffee0, 0xfffee1).rw(m_dma0, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w)); + map(0xfffee2, 0xfffee3).rw(m_dma0, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w)); + map(0xfffee4, 0xfffee5).rw(m_dma0, FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w)); + map(0xfffee6, 0xfffee7).rw(m_dma0, FUNC(h8s_dma_channel_device::etcra_r), FUNC(h8s_dma_channel_device::etcra_w)); + map(0xfffee8, 0xfffee9).rw(m_dma0, FUNC(h8s_dma_channel_device::marbh_r), FUNC(h8s_dma_channel_device::marbh_w)); + map(0xfffeea, 0xfffeeb).rw(m_dma0, FUNC(h8s_dma_channel_device::marbl_r), FUNC(h8s_dma_channel_device::marbl_w)); + map(0xfffeec, 0xfffeed).rw(m_dma0, FUNC(h8s_dma_channel_device::ioarb_r), FUNC(h8s_dma_channel_device::ioarb_w)); + map(0xfffeee, 0xfffeef).rw(m_dma0, FUNC(h8s_dma_channel_device::etcrb_r), FUNC(h8s_dma_channel_device::etcrb_w)); + map(0xfffef0, 0xfffef1).rw(m_dma1, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w)); + map(0xfffef2, 0xfffef3).rw(m_dma1, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w)); + map(0xfffef4, 0xfffef5).rw(m_dma1, FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w)); + map(0xfffef6, 0xfffef7).rw(m_dma1, FUNC(h8s_dma_channel_device::etcra_r), FUNC(h8s_dma_channel_device::etcra_w)); + map(0xfffef8, 0xfffef9).rw(m_dma1, FUNC(h8s_dma_channel_device::marbh_r), FUNC(h8s_dma_channel_device::marbh_w)); + map(0xfffefa, 0xfffefb).rw(m_dma1, FUNC(h8s_dma_channel_device::marbl_r), FUNC(h8s_dma_channel_device::marbl_w)); + map(0xfffefc, 0xfffefd).rw(m_dma1, FUNC(h8s_dma_channel_device::ioarb_r), FUNC(h8s_dma_channel_device::ioarb_w)); + map(0xfffefe, 0xfffeff).rw(m_dma1, FUNC(h8s_dma_channel_device::etcrb_r), FUNC(h8s_dma_channel_device::etcrb_w)); + map(0xffff00, 0xffff00).rw(m_dma, FUNC(h8s_dma_device::dmawer_r), FUNC(h8s_dma_device::dmawer_w)); + map(0xffff01, 0xffff01).rw(m_dma, FUNC(h8s_dma_device::dmatcr_r), FUNC(h8s_dma_device::dmatcr_w)); + map(0xffff02, 0xffff03).rw(m_dma0, FUNC(h8s_dma_channel_device::dmacr_r), FUNC(h8s_dma_channel_device::dmacr_w)); + map(0xffff04, 0xffff05).rw(m_dma1, FUNC(h8s_dma_channel_device::dmacr_r), FUNC(h8s_dma_channel_device::dmacr_w)); + map(0xffff06, 0xffff07).rw(m_dma, FUNC(h8s_dma_device::dmabcr_r), FUNC(h8s_dma_device::dmabcr_w)); map(0xffff2c, 0xffff2c).rw(m_intc, FUNC(h8s_intc_device::iscrh_r), FUNC(h8s_intc_device::iscrh_w)); map(0xffff2d, 0xffff2d).rw(m_intc, FUNC(h8s_intc_device::iscrl_r), FUNC(h8s_intc_device::iscrl_w)); map(0xffff2e, 0xffff2e).rw(m_intc, FUNC(h8s_intc_device::ier_r), FUNC(h8s_intc_device::ier_w)); @@ -192,6 +217,9 @@ void h8s2655_device::device_add_mconfig(machine_config &config) { H8S_INTC(config, m_intc, *this); H8_ADC_2655(config, m_adc, *this, m_intc, 28); + H8S_DMA(config, m_dma, *this); + H8S_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc); + H8S_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc); H8_PORT(config, m_port1, *this, h8_device::PORT_1, 0x00, 0x00); H8_PORT(config, m_port2, *this, h8_device::PORT_2, 0x00, 0x00); H8_PORT(config, m_port3, *this, h8_device::PORT_3, 0xc0, 0xc0); diff --git a/src/devices/cpu/h8/h8s2655.h b/src/devices/cpu/h8/h8s2655.h index 78732dab259..523db25e385 100644 --- a/src/devices/cpu/h8/h8s2655.h +++ b/src/devices/cpu/h8/h8s2655.h @@ -20,6 +20,7 @@ #include "h8s2600.h" #include "h8_intc.h" #include "h8_adc.h" +#include "h8_dma.h" #include "h8_port.h" #include "h8_timer8.h" #include "h8_timer16.h" @@ -36,6 +37,9 @@ public: protected: required_device m_intc; required_device m_adc; + required_device m_dma; + required_device m_dma0; + required_device m_dma1; required_device m_port1; required_device m_port2; required_device m_port3; diff --git a/src/devices/machine/t10mmc.cpp b/src/devices/machine/t10mmc.cpp index 7af508ff70d..b9f62352c4f 100644 --- a/src/devices/machine/t10mmc.cpp +++ b/src/devices/machine/t10mmc.cpp @@ -927,7 +927,6 @@ void t10mmc::ReadData( uint8_t *data, int dataLength ) break; case T10MMC_CMD_READ_DISC_STRUCTURE: - m_device->machine().debug_break(); m_device->logerror("T10MMC: READ DISC STRUCTURE, data\n"); data[0] = data[1] = 0; data[2] = data[3] = 0; diff --git a/src/devices/video/zr36110.cpp b/src/devices/video/zr36110.cpp index abe4d5661a8..3521e8cfaaf 100644 --- a/src/devices/video/zr36110.cpp +++ b/src/devices/video/zr36110.cpp @@ -301,7 +301,7 @@ void zr36110_device::cmdx_w(u16 data) void zr36110_device::dma8_w(u8 data) { - logerror("dna %02x\n", data); + // logerror("dma %02x\n", data); } void zr36110_device::dma_w(u16 data) diff --git a/src/mame/nichibutsu/hrdvd.cpp b/src/mame/nichibutsu/hrdvd.cpp index 3a2981c5f15..439a123e6c9 100644 --- a/src/mame/nichibutsu/hrdvd.cpp +++ b/src/mame/nichibutsu/hrdvd.cpp @@ -97,8 +97,14 @@ public: uint16_t m_mux_data; - uint8_t m_p5, m_pa, m_pb; + uint8_t m_p6, m_pa, m_pb; + bool m_mpeg_dreq; + + void mpeg_dreq_w(int state); + + uint16_t p6_r(); + void p6_w(uint16_t data); uint16_t pb_r(); void pb_w(uint16_t data); void pa_w(uint16_t data); @@ -113,6 +119,7 @@ public: void ata_irq(int state); void ata_drq(int state); + virtual void machine_start() override; virtual void machine_reset() override; void general_init(int patchaddress, int patchvalue); @@ -124,6 +131,29 @@ public: static void dvdrom_config(device_t *device); }; +void hrdvd_state::mpeg_dreq_w(int state) +{ + m_mpeg_dreq = state; + m_subcpu->set_input_line(H8_INPUT_LINE_DREQ0, m_mpeg_dreq && !(m_p6 & 0x04)); +} + +uint16_t hrdvd_state::p6_r() +{ + return m_p6; +} + +void hrdvd_state::p6_w(uint16_t data) +{ + u8 delta = data ^ m_p6; + m_p6 = data; + if(delta & 0x02) + m_mpeg->reset(); + + m_subcpu->set_input_line(H8_INPUT_LINE_DREQ0, m_mpeg_dreq && !(m_p6 & 0x04)); + + logerror("p6 %02x\n", m_p6); +} + uint16_t hrdvd_state::pb_r() { return m_pb; @@ -241,17 +271,15 @@ void hrdvd_state::hrdvd_sub_map(address_map &map) map(0x040018, 0x040019).rw(m_ata, FUNC(hrdvd_ata_controller_device::dma_read), FUNC(hrdvd_ata_controller_device::dma_write)); map(0x040028, 0x04002f).rw(m_ata, FUNC(hrdvd_ata_controller_device::read), FUNC(hrdvd_ata_controller_device::write)); - map(0x060000, 0x06bfff).ram(); - - map(0x078000, 0x07ffff).mirror(0xf80000).ram(); //.share("nvram"); + map(0x060000, 0x07ffff).mirror(0xf80000).ram(); //.share("nvram"); } void hrdvd_state::hrdvd_sub_io_map(address_map &map) { + map(h8_device::PORT_6, h8_device::PORT_6).rw(FUNC(hrdvd_state::p6_r), FUNC(hrdvd_state::p6_w)); map(h8_device::PORT_A, h8_device::PORT_A).w (FUNC(hrdvd_state::pa_w)); map(h8_device::PORT_B, h8_device::PORT_B).rw(FUNC(hrdvd_state::pb_r), FUNC(hrdvd_state::pb_w)); -// map(h8_device::PORT_6, h8_device::PORT_6).noprw(); } @@ -402,11 +430,22 @@ static INPUT_PORTS_START( hrdvd ) INPUT_PORTS_END +void hrdvd_state::machine_start() +{ + save_item(NAME(m_mux_data)); + save_item(NAME(m_p6)); + save_item(NAME(m_pa)); + save_item(NAME(m_pb)); + save_item(NAME(m_mpeg_dreq)); +} + void hrdvd_state::machine_reset() { - m_p5 = 0; + m_mux_data = 0; + m_p6 = 0; m_pa = 0; m_pb = 0; + m_mpeg_dreq = false; } void hrdvd_state::ata_irq(int state) @@ -474,7 +513,7 @@ void hrdvd_state::hrdvd(machine_config &config) SCREEN(config, m_screen, SCREEN_TYPE_RASTER); ZR36110(config, m_mpeg, 27_MHz_XTAL/2); - m_mpeg->drq_w().set_inputline(m_maincpu, H8_INPUT_LINE_DREQ0); + m_mpeg->drq_w().set(FUNC(hrdvd_state::mpeg_dreq_w)); NN71003F(config, m_mpega, 0); m_mpega->add_route(0, m_lspeaker, 1.0); -- cgit v1.2.3