// license:BSD-3-Clause // copyright-holders:Ryan Holtz /****************************************************************************** SCC68070 SoC peripheral emulation ------------------- written by Ryan Holtz ******************************************************************************* STATUS: - Skeleton. Just enough for the CD-i to run. TODO: - Proper handling of the 68070's internal devices (UART, DMA, Timers, etc.) *******************************************************************************/ #ifndef MAME_MACHINE_SCC68070_H #define MAME_MACHINE_SCC68070_H #pragma once #include "cpu/m68000/scc68070.h" //************************************************************************** // TYPE DEFINITIONS //************************************************************************** enum scc68070_ocr_bits { SCC68070_OCR_D = 0x80, SCC68070_OCR_D_M2D = 0x00, SCC68070_OCR_D_D2M = 0x80, SCC68070_OCR_OS = 0x30, SCC68070_OCR_OS_BYTE = 0x00, SCC68070_OCR_OS_WORD = 0x10 }; // ======================> scc68070_device class scc68070_device : public scc68070_base_device { public: scc68070_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock); auto iack2_callback() { return m_iack2_callback.bind(); } auto iack4_callback() { return m_iack4_callback.bind(); } auto iack5_callback() { return m_iack5_callback.bind(); } auto iack7_callback() { return m_iack7_callback.bind(); } auto uart_tx_callback() { return m_uart_tx_callback.bind(); } auto uart_rtsn_callback() { return m_uart_rtsn_callback.bind(); } auto i2c_scl_w() { return m_i2c_scl_callback.bind(); } auto i2c_sda_w() { return m_i2c_sdaw_callback.bind(); } auto i2c_sda_r() { return m_i2c_sdar_callback.bind(); } DECLARE_WRITE_LINE_MEMBER(in2_w); DECLARE_WRITE_LINE_MEMBER(in4_w); DECLARE_WRITE_LINE_MEMBER(in5_w); DECLARE_WRITE_LINE_MEMBER(nmi_w); DECLARE_WRITE_LINE_MEMBER(int1_w); DECLARE_WRITE_LINE_MEMBER(int2_w); DECLARE_WRITE_LINE_MEMBER(write_scl); TIMER_CALLBACK_MEMBER(timer0_callback); TIMER_CALLBACK_MEMBER(rx_callback); TIMER_CALLBACK_MEMBER(tx_callback); TIMER_CALLBACK_MEMBER(i2c_callback); // external callbacks void uart_rx(uint8_t data); void uart_ctsn(int state); // register structures struct i2c_regs_t { uint8_t reserved0; uint8_t data_register; uint8_t reserved1; uint8_t address_register; uint8_t reserved2; uint8_t status_register; uint8_t reserved3; uint8_t control_register; uint8_t reserved; uint8_t clock_control_register; emu_timer* timer; bool scl_out_state; bool scl_in_state; bool sda_out_state; bool sda_in_state; uint8_t clock_change_state; uint8_t clocks; uint8_t state; uint8_t counter; bool first_byte; bool ack_or_nak_sent; }; struct uart_regs_t { uint8_t reserved0; uint8_t mode_register; uint8_t reserved1; uint8_t status_register; uint8_t reserved2; uint8_t clock_select; uint8_t reserved3; uint8_t command_register; uint8_t reserved4; uint8_t transmit_holding_register; uint8_t reserved5; uint8_t receive_holding_register; int16_t receive_pointer; uint8_t receive_buffer[32768]; emu_timer* rx_timer; int16_t transmit_pointer; uint8_t transmit_buffer[32768]; emu_timer* tx_timer; bool transmit_ctsn; }; struct timer_regs_t { uint8_t timer_status_register; uint8_t timer_control_register; uint16_t reload_register; uint16_t timer0; uint16_t timer1; uint16_t timer2; emu_timer* timer0_timer; }; struct dma_channel_t { uint8_t channel_status; uint8_t channel_error; uint8_t reserved0[2]; uint8_t device_control; uint8_t operation_control; uint8_t sequence_control; uint8_t channel_control; uint8_t reserved1[3]; uint16_t transfer_counter; uint32_t memory_address_counter; uint8_t reserved2[4]; uint32_t device_address_counter; uint8_t reserved3[40]; }; struct dma_regs_t { dma_channel_t channel[2]; }; struct mmu_desc_t { uint16_t attr; uint16_t length; uint8_t undefined; uint8_t segment; uint16_t base; }; struct mmu_regs_t { uint8_t status; uint8_t control; uint8_t reserved[0x3e]; mmu_desc_t desc[8]; }; dma_regs_t& dma() { return m_dma; } protected: // device-level overrides virtual void device_resolve_objects() override; virtual void device_start() override; virtual void device_reset() override; // device_execute_interface overrides virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 2 - 1) / 2; } virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 2); } // m68000_base_device overrides virtual void m68k_reset_peripherals() override; private: void internal_map(address_map &map); void cpu_space_map(address_map &map); void update_ipl(); uint8_t iack_r(offs_t offset); // Interrupts uint8_t lir_r(); void lir_w(uint8_t data); uint8_t picr1_r(); void picr1_w(uint8_t data); uint8_t picr2_r(); void picr2_w(uint8_t data); // I2C interface uint8_t idr_r(); void idr_w(uint8_t data); uint8_t iar_r(); void iar_w(uint8_t data); uint8_t isr_r(); void isr_w(uint8_t data); uint8_t icr_r(); void icr_w(uint8_t data); uint8_t iccr_r(); void iccr_w(uint8_t data); void set_i2c_timer(); void i2c_process_falling_scl(); void i2c_process_rising_scl(); void i2c_next_state(); // UART interface uint8_t umr_r(); void umr_w(uint8_t data); uint8_t usr_r(); uint8_t ucsr_r(); void ucsr_w(uint8_t data); uint8_t ucr_r(); void ucr_w(uint8_t data); uint8_t uth_r(); void uth_w(uint8_t data); uint8_t urh_r(); // Timers uint16_t timer_r(offs_t offset, uint16_t mem_mask); void timer_w(offs_t offset, uint16_t data, uint16_t mem_mask); // DMA controller uint16_t dma_r(offs_t offset, uint16_t mem_mask); void dma_w(offs_t offset, uint16_t data, uint16_t mem_mask); // MMU uint16_t mmu_r(offs_t offset, uint16_t mem_mask); void mmu_w(offs_t offset, uint16_t data, uint16_t mem_mask); void uart_rx_check(); void uart_tx_check(); void uart_tx(uint8_t data); void uart_do_tx(); void set_timer_callback(int channel); // callbacks devcb_read8 m_iack2_callback; devcb_read8 m_iack4_callback; devcb_read8 m_iack5_callback; devcb_read8 m_iack7_callback; devcb_write8 m_uart_tx_callback; devcb_write_line m_uart_rtsn_callback; devcb_write_line m_i2c_scl_callback; devcb_write_line m_i2c_sdaw_callback; devcb_read8 m_i2c_sdar_callback; // internal state uint8_t m_ipl; int m_in2_line; int m_in4_line; int m_in5_line; int m_nmi_line; int m_int1_line; int m_int2_line; uint8_t m_lir; uint8_t m_picr1; uint8_t m_picr2; bool m_timer_int; bool m_i2c_int; bool m_uart_rx_int; bool m_uart_tx_int; i2c_regs_t m_i2c; uart_regs_t m_uart; timer_regs_t m_timers; dma_regs_t m_dma; mmu_regs_t m_mmu; }; // device type definition DECLARE_DEVICE_TYPE(SCC68070, scc68070_device) #endif // MAME_MACHINE_SCC68070_H