From 9ee1e664967ca9e16c6e050ca6b17b66d2076f93 Mon Sep 17 00:00:00 2001 From: hap Date: Thu, 12 Dec 2024 16:49:41 +0100 Subject: hd6305: move common peripherals to base class --- src/devices/cpu/m6805/hd6305.cpp | 192 +++++++++++++++++++++------------------ src/devices/cpu/m6805/hd6305.h | 118 ++++++++++++------------ src/mame/sega/system1.cpp | 3 +- src/mame/yamaha/mks3.cpp | 2 +- 4 files changed, 168 insertions(+), 147 deletions(-) diff --git a/src/devices/cpu/m6805/hd6305.cpp b/src/devices/cpu/m6805/hd6305.cpp index e16e8e43d38..fb8e6a23c20 100644 --- a/src/devices/cpu/m6805/hd6305.cpp +++ b/src/devices/cpu/m6805/hd6305.cpp @@ -1,14 +1,18 @@ // license:BSD-3-Clause // copyright-holders:Aaron Giles, Vas Crabb, Olivier Galibert +/* +Hitachi HD6305 series + +TODO: +- add HD6305Y2 peripherals (nothing to test it with?) +- add HD63705Z0 peripherals + +*/ #include "emu.h" #include "hd6305.h" #include "m6805defs.h" -/**************************************************************************** - * HD6305 section - ****************************************************************************/ - hd6305_device::hd6305_device( machine_config const &mconfig, char const *tag, @@ -16,44 +20,20 @@ hd6305_device::hd6305_device( uint32_t clock, device_type const type, configuration_params const ¶ms, - address_map_constructor internal_map) - : m6805_base_device(mconfig, tag, owner, clock, type, params, internal_map) + address_map_constructor internal_map) : + m6805_base_device(mconfig, tag, owner, clock, type, params, internal_map), + m_sci_clk(*this), + m_sci_tx(*this), + m_read_port(*this, 0xff), + m_write_port(*this) { } -hd6305v0_device::hd6305v0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : hd6305_device( - mconfig, - tag, - owner, - clock, - HD6305V0, - { s_hmos_s_ops, s_hmos_cycles, 14, 0x00ff, 0x00c0, 0x1fff, 0x1ffc }, - address_map_constructor(FUNC(hd6305v0_device::internal_map), this)), - m_read_port(*this, 0xff), - m_write_port(*this), - m_sci_clk(*this), - m_sci_tx(*this) -{ -} +// common peripherals -void hd6305v0_device::internal_map(address_map &map) +void hd6305_device::device_start() { - map(0x0000, 0x0003).rw(FUNC(hd6305v0_device::port_r), FUNC(hd6305v0_device::port_w)); - map(0x0004, 0x0007).rw(FUNC(hd6305v0_device::port_ddr_r), FUNC(hd6305v0_device::port_ddr_w)); - map(0x0008, 0x0008).rw(FUNC(hd6305v0_device::timer_data_r), FUNC(hd6305v0_device::timer_data_w)); - map(0x0009, 0x0009).rw(FUNC(hd6305v0_device::timer_ctrl_r), FUNC(hd6305v0_device::timer_ctrl_w)); - map(0x000a, 0x000a).rw(FUNC(hd6305v0_device::misc_r), FUNC(hd6305v0_device::misc_w)); - map(0x0010, 0x0010).rw(FUNC(hd6305v0_device::sci_ctrl_r), FUNC(hd6305v0_device::sci_ctrl_w)); - map(0x0011, 0x0011).rw(FUNC(hd6305v0_device::sci_ssr_r), FUNC(hd6305v0_device::sci_ssr_w)); - map(0x0012, 0x0012).rw(FUNC(hd6305v0_device::sci_data_r), FUNC(hd6305v0_device::sci_data_w)); - map(0x0040, 0x00ff).ram(); - map(0x1000, 0x1fff).rom().region(DEVICE_SELF, 0); -} - -void hd6305v0_device::device_start() -{ - hd6305_device::device_start(); + m6805_base_device::device_start(); save_item(NAME(m_port_data)); save_item(NAME(m_port_ddr)); @@ -69,13 +49,13 @@ void hd6305v0_device::device_start() save_item(NAME(m_sci_tx_byte)); save_item(NAME(m_sci_tx_step)); - m_timer_timer = timer_alloc(FUNC(hd6305v0_device::timer_cb), this); - m_timer_sci = timer_alloc(FUNC(hd6305v0_device::sci_cb), this); + m_timer_timer = timer_alloc(FUNC(hd6305_device::timer_cb), this); + m_timer_sci = timer_alloc(FUNC(hd6305_device::sci_cb), this); } -void hd6305v0_device::device_reset() +void hd6305_device::device_reset() { - hd6305_device::device_reset(); + m6805_base_device::device_reset(); std::fill(m_port_data.begin(), m_port_data.end(), 0x00); std::fill(m_port_ddr.begin(), m_port_ddr.end(), 0x00); @@ -99,7 +79,7 @@ void hd6305v0_device::device_reset() m_sci_tx(1); } -u8 hd6305v0_device::port_r(offs_t port) +u8 hd6305_device::port_r(offs_t port) { if(m_port_ddr[port] == 0xff) return m_port_data[port]; @@ -107,7 +87,7 @@ u8 hd6305v0_device::port_r(offs_t port) return (m_port_ddr[port] & m_port_data[port]) | (m_read_port[port]() & ~m_port_ddr[port]); } -void hd6305v0_device::port_w(offs_t port, u8 data) +void hd6305_device::port_w(offs_t port, u8 data) { if(data != m_port_data[port]) { m_port_data[port] = data; @@ -115,12 +95,12 @@ void hd6305v0_device::port_w(offs_t port, u8 data) } } -u8 hd6305v0_device::port_ddr_r(offs_t port) +u8 hd6305_device::port_ddr_r(offs_t port) { return m_port_ddr[port]; } -void hd6305v0_device::port_ddr_w(offs_t port, u8 data) +void hd6305_device::port_ddr_w(offs_t port, u8 data) { if(data != m_port_ddr[port]) { logerror("port %d ddr %c%c%c%c%c%c%c%c\n", @@ -139,7 +119,7 @@ void hd6305v0_device::port_ddr_w(offs_t port, u8 data) } } -void hd6305v0_device::timer_update_regs() +void hd6305_device::timer_update_regs() { u32 counter = m_prescaler; u64 tc = machine().time().as_ticks(clock())/4; @@ -147,7 +127,7 @@ void hd6305v0_device::timer_update_regs() u32 next_counter = counter + cycles; u32 shift = BIT(m_tcr, 0, 3); - u32 steps = shift ? (((next_counter >> (shift-1)) + 1) >> 1) - (((counter >> (shift-1)) + 1) >> 1): cycles; + u32 steps = shift ? (((next_counter >> (shift-1)) + 1) >> 1) - (((counter >> (shift-1)) + 1) >> 1) : cycles; m_tdr -= steps; m_prescaler = next_counter & 0x7f; @@ -155,11 +135,11 @@ void hd6305v0_device::timer_update_regs() if(!m_tdr && steps) { m_tcr |= 0x80; if(!BIT(m_tcr, 6)) - m_pending_interrupts |= 1 << M6805V0_INT_TIMER1; + m_pending_interrupts |= 1 << HD6305_INT_TIMER1; } } -void hd6305v0_device::timer_wait_next_timeout() +void hd6305_device::timer_wait_next_timeout() { u32 shift = BIT(m_tcr, 0, 3); u32 cycles; @@ -177,26 +157,26 @@ void hd6305v0_device::timer_wait_next_timeout() m_timer_timer->adjust(attotime::from_ticks(cycles*4, clock())); } -u8 hd6305v0_device::timer_data_r() +u8 hd6305_device::timer_data_r() { timer_update_regs(); return m_tdr; } -void hd6305v0_device::timer_data_w(u8 data) +void hd6305_device::timer_data_w(u8 data) { timer_update_regs(); m_tdr = data; timer_wait_next_timeout(); } -u8 hd6305v0_device::timer_ctrl_r() +u8 hd6305_device::timer_ctrl_r() { timer_update_regs(); return m_tcr; } -void hd6305v0_device::timer_ctrl_w(u8 data) +void hd6305_device::timer_ctrl_w(u8 data) { timer_update_regs(); u8 old = m_tcr; @@ -213,9 +193,9 @@ void hd6305v0_device::timer_ctrl_w(u8 data) logerror("WARNING: timer mode not implemented\n"); } if((m_tcr & 0xc0) == 0x80) - m_pending_interrupts |= 1 << M6805V0_INT_TIMER1; + m_pending_interrupts |= 1 << HD6305_INT_TIMER1; else - m_pending_interrupts &= ~(1 << M6805V0_INT_TIMER1); + m_pending_interrupts &= ~(1 << HD6305_INT_TIMER1); if(BIT(m_tcr, 3)) { m_prescaler = 0x7f; m_tcr &= ~0x08; @@ -225,18 +205,18 @@ void hd6305v0_device::timer_ctrl_w(u8 data) } -TIMER_CALLBACK_MEMBER(hd6305v0_device::timer_cb) +TIMER_CALLBACK_MEMBER(hd6305_device::timer_cb) { timer_update_regs(); timer_wait_next_timeout(); } -u8 hd6305v0_device::misc_r() +u8 hd6305_device::misc_r() { return m_mr; } -void hd6305v0_device::misc_w(u8 data) +void hd6305_device::misc_w(u8 data) { m_mr = (m_mr & data & 0x80) | (data & 0x60) | 0x1f; logerror("misc %02x int2=%s, %s int=%s\n", data, @@ -245,17 +225,17 @@ void hd6305v0_device::misc_w(u8 data) BIT(m_mr, 5) ? "edge" : "level"); } -void hd6305v0_device::sci_timer_step() +void hd6305_device::sci_timer_step() { m_timer_sci->adjust(attotime::from_ticks(1 << (BIT(m_scr, 0, 4) + 2), clock())); } -TIMER_CALLBACK_MEMBER(hd6305v0_device::sci_cb) +TIMER_CALLBACK_MEMBER(hd6305_device::sci_cb) { if(m_sci_tx_step == 16) { m_ssr |= 0x80; if(!BIT(m_ssr, 5)) - m_pending_interrupts |= 1 << M6805V0_INT_SCI; + m_pending_interrupts |= 1 << HD6305_INT_SCI; if(m_sci_tx_filled) { m_sci_tx_filled = false; @@ -281,12 +261,12 @@ TIMER_CALLBACK_MEMBER(hd6305v0_device::sci_cb) sci_timer_step(); } -u8 hd6305v0_device::sci_ctrl_r() +u8 hd6305_device::sci_ctrl_r() { return m_scr; } -void hd6305v0_device::sci_ctrl_w(u8 data) +void hd6305_device::sci_ctrl_w(u8 data) { m_scr = data; logerror("sci ctrl %02x d3=%s d4=%s d5=%s rate=%d\n", data, @@ -296,12 +276,12 @@ void hd6305v0_device::sci_ctrl_w(u8 data) clock()/(1 << (BIT(data, 0, 4) + 3))); } -u8 hd6305v0_device::sci_ssr_r() +u8 hd6305_device::sci_ssr_r() { return m_ssr; } -void hd6305v0_device::sci_ssr_w(u8 data) +void hd6305_device::sci_ssr_w(u8 data) { m_ssr = ((m_ssr & data) & 0xc0) | (data & 0x38) | 7; logerror("sci ssr w %02x sci irq=%s, %s timer2 irq=%s, %s%s\n", data, @@ -312,18 +292,18 @@ void hd6305v0_device::sci_ssr_w(u8 data) BIT(m_ssr, 3) ? "reset sci prescaler" : ""); if((m_ssr & 0xa0) == 0x80) - m_pending_interrupts |= 1 << M6805V0_INT_SCI; + m_pending_interrupts |= 1 << HD6305_INT_SCI; else - m_pending_interrupts &= ~(1 << M6805V0_INT_SCI); + m_pending_interrupts &= ~(1 << HD6305_INT_SCI); } -u8 hd6305v0_device::sci_data_r() +u8 hd6305_device::sci_data_r() { logerror("sci data r\n"); return 0x00; } -void hd6305v0_device::sci_data_w(u8 data) +void hd6305_device::sci_data_w(u8 data) { m_sci_tx_data = data; if(m_sci_tx_step == 0) { @@ -338,10 +318,10 @@ void hd6305v0_device::sci_data_w(u8 data) m_sci_tx_filled = true; } -void hd6305v0_device::execute_set_input(int inputnum, int state) +void hd6305_device::execute_set_input(int inputnum, int state) { // TODO: edge vs. level on int1 - if(inputnum == M6805V0_INT_IRQ1 || inputnum == M6805V0_INT_IRQ2) { + if(inputnum == HD6305_INT_IRQ1 || inputnum == HD6305_INT_IRQ2) { if(m_irq_state[inputnum] != state) { m_irq_state[inputnum] = state; @@ -351,34 +331,69 @@ void hd6305v0_device::execute_set_input(int inputnum, int state) } } -void hd6305v0_device::interrupt_vector() +void hd6305_device::interrupt_vector() { - if((m_pending_interrupts & (1 << M6805V0_INT_IRQ1)) != 0) { - m_pending_interrupts &= ~(1 << M6805V0_INT_IRQ1); + if((m_pending_interrupts & (1 << HD6305_INT_IRQ1)) != 0) { + m_pending_interrupts &= ~(1 << HD6305_INT_IRQ1); rm16(0x1ffa, m_pc); } - else if((m_pending_interrupts & (1 << M6805V0_INT_IRQ2)) != 0) { - m_pending_interrupts &= ~(1 << M6805V0_INT_IRQ2); + else if((m_pending_interrupts & (1 << HD6305_INT_IRQ2)) != 0) { + m_pending_interrupts &= ~(1 << HD6305_INT_IRQ2); rm16(0x1ff8, m_pc); } - else if((m_pending_interrupts & (1 << M6805V0_INT_TIMER1)) != 0) { + else if((m_pending_interrupts & (1 << HD6305_INT_TIMER1)) != 0) { // TODO: 1ff6 when in wait... - m_pending_interrupts &= ~(1 << M6805V0_INT_TIMER1); + m_pending_interrupts &= ~(1 << HD6305_INT_TIMER1); rm16(0x1ff8, m_pc); } - else if((m_pending_interrupts & (1 << M6805V0_INT_TIMER2)) != 0) { - m_pending_interrupts &= ~(1 << M6805V0_INT_TIMER2); + else if((m_pending_interrupts & (1 << HD6305_INT_TIMER2)) != 0) { + m_pending_interrupts &= ~(1 << HD6305_INT_TIMER2); rm16(0x1ff4, m_pc); } - else if((m_pending_interrupts & (1 << M6805V0_INT_SCI)) != 0) { - m_pending_interrupts &= ~(1 << M6805V0_INT_SCI); + else if((m_pending_interrupts & (1 << HD6305_INT_SCI)) != 0) { + m_pending_interrupts &= ~(1 << HD6305_INT_SCI); rm16(0x1ff4, m_pc); } } -hd6305y2_device::hd6305y2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : hd6305_device( +/**************************************************************************** + * HD6305V0 section + ****************************************************************************/ + +hd6305v0_device::hd6305v0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + hd6305_device( + mconfig, + tag, + owner, + clock, + HD6305V0, + { s_hmos_s_ops, s_hmos_cycles, 14, 0x00ff, 0x00c0, 0x1fff, 0x1ffc }, + address_map_constructor(FUNC(hd6305v0_device::internal_map), this)) +{ +} + +void hd6305v0_device::internal_map(address_map &map) +{ + map(0x0000, 0x0003).rw(FUNC(hd6305v0_device::port_r), FUNC(hd6305v0_device::port_w)); + map(0x0004, 0x0007).rw(FUNC(hd6305v0_device::port_ddr_r), FUNC(hd6305v0_device::port_ddr_w)); + map(0x0008, 0x0008).rw(FUNC(hd6305v0_device::timer_data_r), FUNC(hd6305v0_device::timer_data_w)); + map(0x0009, 0x0009).rw(FUNC(hd6305v0_device::timer_ctrl_r), FUNC(hd6305v0_device::timer_ctrl_w)); + map(0x000a, 0x000a).rw(FUNC(hd6305v0_device::misc_r), FUNC(hd6305v0_device::misc_w)); + map(0x0010, 0x0010).rw(FUNC(hd6305v0_device::sci_ctrl_r), FUNC(hd6305v0_device::sci_ctrl_w)); + map(0x0011, 0x0011).rw(FUNC(hd6305v0_device::sci_ssr_r), FUNC(hd6305v0_device::sci_ssr_w)); + map(0x0012, 0x0012).rw(FUNC(hd6305v0_device::sci_data_r), FUNC(hd6305v0_device::sci_data_w)); + map(0x0040, 0x00ff).ram(); + map(0x1000, 0x1fff).rom().region(DEVICE_SELF, 0); +} + + +/**************************************************************************** + * HD6305Y2 section + ****************************************************************************/ + +hd6305y2_device::hd6305y2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + hd6305_device( mconfig, tag, owner, @@ -395,8 +410,13 @@ void hd6305y2_device::internal_map(address_map &map) map(0x0040, 0x013f).ram(); } -hd63705z0_device::hd63705z0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : hd6305_device( + +/**************************************************************************** + * HD63705Z0 section + ****************************************************************************/ + +hd63705z0_device::hd63705z0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + hd6305_device( mconfig, tag, owner, diff --git a/src/devices/cpu/m6805/hd6305.h b/src/devices/cpu/m6805/hd6305.h index 08155f5b9d4..d96af0e597b 100644 --- a/src/devices/cpu/m6805/hd6305.h +++ b/src/devices/cpu/m6805/hd6305.h @@ -23,6 +23,10 @@ DECLARE_DEVICE_TYPE(HD63705Z0, hd63705z0_device) class hd6305_device : public m6805_base_device { +public: + auto write_sci_tx() { return m_sci_tx.bind(); } + auto write_sci_clk() { return m_sci_clk.bind(); } + protected: // construction/destruction hd6305_device( @@ -34,64 +38,13 @@ protected: configuration_params const ¶ms, address_map_constructor internal_map); - virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == INPUT_LINE_NMI; } - - virtual bool test_il() override { return m_nmi_state != CLEAR_LINE; } -}; - -// ======================> hd6305v0_device - -class hd6305v0_device : public hd6305_device -{ -public: - // construction/destruction - hd6305v0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - auto write_sci_tx() { return m_sci_tx.bind(); } - auto write_sci_clk() { return m_sci_clk.bind(); } - - auto read_porta() { return m_read_port [0].bind(); } - auto write_porta() { return m_write_port[0].bind(); } - auto read_portb() { return m_read_port [1].bind(); } - auto write_portb() { return m_write_port[1].bind(); } - auto read_portc() { return m_read_port [2].bind(); } - auto write_portc() { return m_write_port[2].bind(); } - auto read_portd() { return m_read_port [3].bind(); } - auto write_portd() { return m_write_port[3].bind(); } - -protected: virtual void device_start() override ATTR_COLD; virtual void device_reset() override ATTR_COLD; virtual void execute_set_input(int inputnum, int state) override; + virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == INPUT_LINE_NMI; } virtual void interrupt_vector() override; -private: - devcb_read8::array<4> m_read_port; - devcb_write8::array<4> m_write_port; - devcb_write_line m_sci_clk; - devcb_write_line m_sci_tx; - - emu_timer *m_timer_timer; - emu_timer *m_timer_sci; - - std::array m_port_data; - std::array m_port_ddr; - - u64 m_timer_last_update; - - u8 m_tdr; - u8 m_prescaler; - u8 m_tcr; - u8 m_ssr; - u8 m_scr; - u8 m_mr; - u8 m_sci_tx_data; - - bool m_sci_tx_filled; - u8 m_sci_tx_byte; - u8 m_sci_tx_step; - - void internal_map(address_map &map) ATTR_COLD; + virtual bool test_il() override { return m_nmi_state != CLEAR_LINE; } u8 port_r(offs_t port); void port_w(offs_t port, u8 data); @@ -119,6 +72,53 @@ private: TIMER_CALLBACK_MEMBER(timer_cb); TIMER_CALLBACK_MEMBER(sci_cb); + + devcb_write_line m_sci_clk; + devcb_write_line m_sci_tx; + + // maximum 9 I/O ports + devcb_read8::array<9> m_read_port; + devcb_write8::array<9> m_write_port; + std::array m_port_data; + std::array m_port_ddr; + + emu_timer *m_timer_timer; + emu_timer *m_timer_sci; + + u64 m_timer_last_update; + + u8 m_tdr; + u8 m_prescaler; + u8 m_tcr; + u8 m_ssr; + u8 m_scr; + u8 m_mr; + u8 m_sci_tx_data; + + bool m_sci_tx_filled; + u8 m_sci_tx_byte; + u8 m_sci_tx_step; +}; + +// ======================> hd6305v0_device + +class hd6305v0_device : public hd6305_device +{ +public: + // construction/destruction + hd6305v0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + auto read_porta() { return m_read_port [0].bind(); } + auto write_porta() { return m_write_port[0].bind(); } + auto read_portb() { return m_read_port [1].bind(); } + auto write_portb() { return m_write_port[1].bind(); } + auto read_portc() { return m_read_port [2].bind(); } + auto write_portc() { return m_write_port[2].bind(); } + auto read_portd() { return m_read_port [3].bind(); } + auto write_portd() { return m_write_port[3].bind(); } + +private: + void internal_map(address_map &map) ATTR_COLD; }; // ======================> hd6305y2_device @@ -151,14 +151,14 @@ private: }; /**************************************************************************** - * 6805V0 section + * HD6305 section ****************************************************************************/ -#define M6805V0_INT_IRQ1 0x00 -#define M6805V0_INT_IRQ2 0x01 -#define M6805V0_INT_TIMER1 0x02 -#define M6805V0_INT_TIMER2 0x03 -#define M6805V0_INT_SCI 0x04 +#define HD6305_INT_IRQ1 0x00 +#define HD6305_INT_IRQ2 0x01 +#define HD6305_INT_TIMER1 0x02 +#define HD6305_INT_TIMER2 0x03 +#define HD6305_INT_SCI 0x04 /**************************************************************************** * HD63705 section diff --git a/src/mame/sega/system1.cpp b/src/mame/sega/system1.cpp index c535eeff7dd..17b06281aa7 100644 --- a/src/mame/sega/system1.cpp +++ b/src/mame/sega/system1.cpp @@ -2225,7 +2225,8 @@ void system1_state::sys1ppi(machine_config &config) GENERIC_LATCH_8(config, m_soundlatch); - // 1st SN audio output actually goes to 2nd SN audio input (pin 9) + // 1st SN audio output actually goes to 2nd SN audio input (pin 9), + // with a resistor in between, so the volume is lowered a bit. SN76489A(config, m_sn[0], SOUND_CLOCK/4).add_route(ALL_OUTPUTS, "mono", 0.40); // 2nd SN's clock is selectable via jumper diff --git a/src/mame/yamaha/mks3.cpp b/src/mame/yamaha/mks3.cpp index 11daa5321d4..7e7155fbe04 100644 --- a/src/mame/yamaha/mks3.cpp +++ b/src/mame/yamaha/mks3.cpp @@ -296,6 +296,6 @@ void mks3_device::req_w(int state) return; m_req = state; - m_cpu->set_input_line(M6805V0_INT_IRQ1, m_req); + m_cpu->set_input_line(HD6305_INT_IRQ1, m_req); logerror("req %d\n", m_req); } -- cgit v1.2.3