// 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/m68000.h" #define ISR_MST 0x80 // Master #define ISR_TRX 0x40 // Transmitter #define ISR_BB 0x20 // Busy #define ISR_PIN 0x10 // No Pending Interrupt #define ISR_AL 0x08 // Arbitration Lost #define ISR_AAS 0x04 // Addressed As Slave #define ISR_AD0 0x02 // Address Zero #define ISR_LRB 0x01 // Last Received Bit #define UMR_OM 0xc0 #define UMR_OM_NORMAL 0x00 #define UMR_OM_ECHO 0x40 #define UMR_OM_LOOPBACK 0x80 #define UMR_OM_RLOOP 0xc0 #define UMR_TXC 0x10 #define UMR_PC 0x08 #define UMR_P 0x04 #define UMR_SB 0x02 #define UMR_CL 0x01 #define USR_RB 0x80 #define USR_FE 0x40 #define USR_PE 0x20 #define USR_OE 0x10 #define USR_TXEMT 0x08 #define USR_TXRDY 0x04 #define USR_RXRDY 0x01 #define TSR_OV0 0x80 #define TSR_MA1 0x40 #define TSR_CAP1 0x20 #define TSR_OV1 0x10 #define TSR_MA2 0x08 #define TSR_CAP2 0x04 #define TSR_OV2 0x02 #define TCR_E1 0xc0 #define TCR_E1_NONE 0x00 #define TCR_E1_RISING 0x40 #define TCR_E1_FALLING 0x80 #define TCR_E1_BOTH 0xc0 #define TCR_M1 0x30 #define TCR_M1_NONE 0x00 #define TCR_M1_MATCH 0x10 #define TCR_M1_CAPTURE 0x20 #define TCR_M1_COUNT 0x30 #define TCR_E2 0x0c #define TCR_E2_NONE 0x00 #define TCR_E2_RISING 0x04 #define TCR_E2_FALLING 0x08 #define TCR_E2_BOTH 0x0c #define TCR_M2 0x03 #define TCR_M2_NONE 0x00 #define TCR_M2_MATCH 0x01 #define TCR_M2_CAPTURE 0x02 #define TCR_M2_COUNT 0x03 #define CSR_COC 0x80 #define CSR_NDT 0x20 #define CSR_ERR 0x10 #define CSR_CA 0x08 #define CER_EC 0x1f #define CER_NONE 0x00 #define CER_TIMING 0x02 #define CER_BUSERR_MEM 0x09 #define CER_BUSERR_DEV 0x0a #define CER_SOFT_ABORT 0x11 #define DCR1_ERM 0x80 #define DCR1_DT 0x30 #define DCR2_ERM 0x80 #define DCR2_DT 0x30 #define DCR2_DS 0x08 #define OCR_D 0x80 #define OCR_D_M2D 0x00 #define OCR_D_D2M 0x80 #define OCR_OS 0x30 #define OCR_OS_BYTE 0x00 #define OCR_OS_WORD 0x10 #define SCR2_MAC 0x0c #define SCR2_MAC_NONE 0x00 #define SCR2_MAC_INC 0x04 #define SCR2_DAC 0x03 #define SCR2_DAC_NONE 0x00 #define SCR2_DAC_INC 0x01 #define CCR_SO 0x80 #define CCR_SA 0x10 #define CCR_INE 0x08 #define CCR_IPL 0x07 //************************************************************************** // TYPE DEFINITIONS //************************************************************************** // ======================> scc68070_device class scc68070_device : public scc68070_base_device { public: scc68070_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t 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(); } 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); // external callbacks void uart_rx(uint8_t data); TIMER_CALLBACK_MEMBER( timer0_callback ); TIMER_CALLBACK_MEMBER( rx_callback ); TIMER_CALLBACK_MEMBER( tx_callback ); // 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; }; 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; }; 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); // 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 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; // 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