diff options
Diffstat (limited to 'src/devices/cpu/m68000/tmp68301.h')
-rw-r--r-- | src/devices/cpu/m68000/tmp68301.h | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/src/devices/cpu/m68000/tmp68301.h b/src/devices/cpu/m68000/tmp68301.h new file mode 100644 index 00000000000..c521f6b6c1f --- /dev/null +++ b/src/devices/cpu/m68000/tmp68301.h @@ -0,0 +1,320 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +#ifndef MAME_CPU_M68000_TMP68301_H +#define MAME_CPU_M68000_TMP68301_H + +#pragma once + +#include "m68000mcu.h" + +class tmp68301_device : public m68000_mcu_device +{ +public: + tmp68301_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + void set_serial_external_clock(u32 hz) { m_serial_external_clock = hz; } + auto parallel_r_cb() { return m_parallel_r_cb.bind(); } + auto parallel_w_cb() { return m_parallel_w_cb.bind(); } + + void rx0_w(int state) { serial_rx_w(0, state); } + void rx1_w(int state) { serial_rx_w(1, state); } + void rx2_w(int state) { serial_rx_w(2, state); } + + auto tx0_handler() { return m_tx_cb[0].bind(); } + auto tx1_handler() { return m_tx_cb[1].bind(); } + auto tx2_handler() { return m_tx_cb[2].bind(); } + + void timer_in_w(int state); + +protected: + tmp68301_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + devcb_read16 m_parallel_r_cb; + devcb_write16 m_parallel_w_cb; + devcb_write_line::array<3> m_tx_cb; + + void device_start() override ATTR_COLD; + void device_reset() override ATTR_COLD; + void execute_set_input(int inputnum, int state) override; + + void internal_update(uint64_t current_time = 0) override; + + virtual u8 base_timer_irq() const noexcept { return 4; } + + void internal_map(address_map &map) ATTR_COLD; + void cpu_space_map(address_map &map) ATTR_COLD; + + // Address decoder + u8 m_amar[2], m_aamr[2], m_aacr[3]; + u8 m_ator; + u16 m_arelr; + + void show_cs(int cs); + void show_iack(); + + void amar_w(int reg, u8 data); + void aamr_w(int reg, u8 data); + void aacr_w(int reg, u8 data); + + u8 amar0_r(); + void amar0_w(u8 data); + u8 amar1_r(); + void amar1_w(u8 data); + + u8 aamr0_r(); + void aamr0_w(u8 data); + u8 aamr1_r(); + void aamr1_w(u8 data); + + u8 aacr0_r(); + void aacr0_w(u8 data); + u8 aacr1_r(); + void aacr1_w(u8 data); + u8 aacr2_r(); + void aacr2_w(u8 data); + + u8 ator_r(); + void ator_w(u8 data); + + u16 arelr_r(); + void arelr_w(offs_t, u16 data, u16 mem_mask); + + + // Interrupt controller + static const char *const interrupt_slot_names[11]; + static const int interrupt_vector_to_slot[32]; + static const int interrupt_slot_to_priority[11]; + + u16 m_external_interrupt_state; + u32 m_interrupt_state; + u8 m_icr[10]; + u16 m_imr, m_ipr, m_iisr; + u8 m_ivnr, m_ieir; + + u8 icr_r(offs_t reg); + void icr_w(offs_t reg, u8 data); + u16 imr_r(); + void imr_w(offs_t, u16 data, u16 mem_mask); + u16 ipr_r(); + void ipr_w(offs_t, u16 data, u16 mem_mask); + u16 iisr_r(); + void iisr_w(offs_t, u16 data, u16 mem_mask); + u8 ivnr_r(); + void ivnr_w(u8 data); + u8 ieir_r(); + void ieir_w(u8 data); + u8 interrupt_callback(); + void interrupt_update(); + void interrupt_internal_trigger(int vector); + std::tuple<u32, u8, u32> interrupt_get_current() const; + + // Parallel interface + static const int parallel_mode_table[16]; + static const char *const parallel_mode_names[10]; + + u16 m_pdir; + u8 m_pcr, m_psr, m_pcmr, m_pmr; + u16 m_pdr; + u8 m_ppr1, m_ppr2; + u8 m_parallel_mode; + + u8 parallel_get_interrupt() const; + + u16 pdir_r(); + void pdir_w(offs_t, u16 data, u16 mem_mask); + u8 pcr_r(); + void pcr_w(u8 data); + u8 psr_r(); + void psr_w(u8 data); + u8 pcmr_r(); + void pcmr_w(u8 data); + u8 pmr_r(); + void pmr_w(u8 data); + u16 pdr_r(); + void pdr_w(offs_t, u16 data, u16 mem_mask); + u8 ppr1_r(); + void ppr1_w(u8 data); + u8 ppr2_r(); + void ppr2_w(u8 data); + + + // Serial interface + enum { + SCR_INTM = 0x01, + SCR_RES = 0x20, + SCR_CKSE = 0x80, + + SMR_ST = 0x01, + SMR_TXINTM = 0x02, + SMR_CL_SFT = 2, + SMR_PEN = 0x10, + SMR_PEO = 0x20, + SMR_ERINTM = 0x40, + SMR_RXINTM = 0x80, + + SCMR_TXEN = 0x01, + SCMR_DTR = 0x02, + SCMR_RXEN = 0x04, + SCMR_SBRK = 0x08, + SCMR_ERS = 0x10, + SCMR_RTS = 0x20, + + SSR_TXRDY = 0x01, + SSR_RXRDY = 0x02, + SSR_TXE = 0x04, + SSR_PE = 0x08, + SSR_OE = 0x10, + SSR_FE = 0x20, + SSR_RBRK = 0x40, + SSR_DSR = 0x80, + + SR_INT_ERR = 0, + SR_INT_RX = 1, + SR_INT_TX = 2, + SR_INT_UNK = 3, + + }; + + enum { + SR_IDLE, + SR_START, + SR_BIT_0, + SR_BIT_1, + SR_BIT_2, + SR_BIT_3, + SR_BIT_4, + SR_BIT_5, + SR_BIT_6, + SR_BIT_7, + SR_PARITY, + SR_STOP, + SR_DONE, + }; + + u64 m_serial_tx_next_event[3], m_serial_rx_next_event[3]; + u64 m_serial_gclk[3]; + u32 m_serial_external_clock; + u8 m_smr[3], m_scmr[3], m_sbrr[3], m_ssr[3], m_sdrr[3], m_sdrt[3], m_sr_intr[3], m_serial_rx[3], m_serial_tx[3]; + u8 m_serial_tx_state[3], m_serial_rx_state[3], m_serial_rx_line[3]; + u8 m_spr, m_scr; + + static u8 sbrr_to_div(u8 value); + void serial_clock_update(int ch); + u64 serial_get_next_edge(int ch); + bool serial_validate_interrupt(u8 vector) const; + void serial_check_interrupt(int ch); + void serial_tx_update(int ch); + void serial_rx_update(int ch); + void serial_rx_w(int ch, int state); + void ssr_set(int ch, u8 val, u8 mask); + + void smr_w(int ch, u8 data); + void scmr_w(int ch, u8 data); + void sbrr_w(int ch, u8 data); + u8 sdr_r(int ch); + void sdr_w(int ch, u8 data); + + u8 smr0_r(); + void smr0_w(u8 data); + u8 smr1_r(); + void smr1_w(u8 data); + u8 smr2_r(); + void smr2_w(u8 data); + u8 scmr0_r(); + void scmr0_w(u8 data); + u8 scmr1_r(); + void scmr1_w(u8 data); + u8 scmr2_r(); + void scmr2_w(u8 data); + u8 sbrr0_r(); + void sbrr0_w(u8 data); + u8 sbrr1_r(); + void sbrr1_w(u8 data); + u8 sbrr2_r(); + void sbrr2_w(u8 data); + u8 ssr0_r(); + u8 ssr1_r(); + u8 ssr2_r(); + u8 sdr0_r(); + void sdr0_w(u8 data); + u8 sdr1_r(); + void sdr1_w(u8 data); + u8 sdr2_r(); + void sdr2_w(u8 data); + u8 spr_r(); + void spr_w(u8 data); + u8 scr_r(); + void scr_w(u8 data); + + // 16-bit timer + enum { + TCR_CK = 14, + TCR_P = 10, + TCR_T = 8, + TCR_N1 = 0x0080, + TCR_RP = 0x0040, + TCR_MR = 4, + TCR_INT = 0x0004, + TCR_CS = 0x0002, + TCR_TS = 0x0001 + }; + + u64 m_timer_next_event[3], m_timer_last_sync[3]; + u16 m_tcr[3], m_tmcr1[3], m_tmcr2[3], m_tctr[3]; + + static const int timer_source_id[3][2]; + static const char *const timer_source_names[3][4]; + static const int timer_divider[16]; + + void timer_update(int ch); + void timer_sync(int ch); + void timer_predict(int ch); + + void tcr_w(int ch, u16 data, u16 mem_mask); + void tmcr1_w(int ch, u16 data, u16 mem_mask); + void tmcr2_w(int ch, u16 data, u16 mem_mask); + void tctr_w(int ch, u16 data, u16 mem_mask); + + void tcr0_w(offs_t, u16 data, u16 mem_mask); + u16 tcr0_r(); + void tcr1_w(offs_t, u16 data, u16 mem_mask); + u16 tcr1_r(); + void tcr2_w(offs_t, u16 data, u16 mem_mask); + u16 tcr2_r(); + + void tmcr01_w(offs_t, u16 data, u16 mem_mask); + u16 tmcr01_r(); + + void tmcr11_w(offs_t, u16 data, u16 mem_mask); + u16 tmcr11_r(); + void tmcr12_w(offs_t, u16 data, u16 mem_mask); + u16 tmcr12_r(); + + void tmcr21_w(offs_t, u16 data, u16 mem_mask); + u16 tmcr21_r(); + void tmcr22_w(offs_t, u16 data, u16 mem_mask); + u16 tmcr22_r(); + + void tctr0_w(offs_t, u16 data, u16 mem_mask); + u16 tctr0_r(); + void tctr1_w(offs_t, u16 data, u16 mem_mask); + u16 tctr1_r(); + void tctr2_w(offs_t, u16 data, u16 mem_mask); + u16 tctr2_r(); + +}; + +class tmp68303_device : public tmp68301_device +{ +public: + tmp68303_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +private: + virtual u8 base_timer_irq() const noexcept override { return 3; } +}; + +DECLARE_DEVICE_TYPE(TMP68301, tmp68301_device) +DECLARE_DEVICE_TYPE(TMP68303, tmp68303_device) + + +#endif |