// license:BSD-3-Clause // copyright-holders:Curt Coder /********************************************************************** Motorola MC68901 Multi Function Peripheral emulation Copyright MESS Team. Visit http://mamedev.org for licensing and usage restrictions. ********************************************************************** _____ _____ R/_W 1 |* \_/ | 48 _CS RS1 2 | | 47 _DS RS2 3 | | 46 _DTACK RS3 4 | | 45 _IACK RS4 5 | | 44 D7 RS5 6 | | 43 D6 TC 7 | | 42 D5 SO 8 | | 41 D4 SI 9 | | 40 D3 RC 10 | | 39 D2 Vcc 11 | | 38 D1 NC 12 | MC68901 | 37 D0 TAO 13 | MK68901 | 36 GND TBO 14 | | 35 CLK TCO 15 | | 34 _IEI TDO 16 | | 33 _IEO XTAL1 17 | | 32 _IRQ XTAL2 18 | | 31 _RR TAI 19 | | 30 _TR TBI 20 | | 29 I7 _RESET 21 | | 28 I6 I0 22 | | 27 I5 I1 23 | | 26 I4 I2 24 |_____________| 25 I3 **********************************************************************/ #pragma once #ifndef __MC68901__ #define __MC68901__ #include "emu.h" //************************************************************************** // INTERFACE CONFIGURATION MACROS //************************************************************************** #define MCFG_MC68901_TIMER_CLOCK(_clk) \ mc68901_device::set_timer_clock(*device, _clk); #define MCFG_MC68901_RX_CLOCK(_clk) \ mc68901_device::set_rx_clock(*device, _clk); #define MCFG_MC68901_TX_CLOCK(_clk) \ mc68901_device::set_tx_clock(*device, _clk); #define MCFG_MC68901_OUT_IRQ_CB(_devcb) \ devcb = &mc68901_device::set_out_irq_callback(*device, DEVCB_##_devcb); #define MCFG_MC68901_OUT_GPIO_CB(_devcb) \ devcb = &mc68901_device::set_out_gpio_callback(*device, DEVCB_##_devcb); #define MCFG_MC68901_OUT_TAO_CB(_devcb) \ devcb = &mc68901_device::set_out_tao_callback(*device, DEVCB_##_devcb); #define MCFG_MC68901_OUT_TBO_CB(_devcb) \ devcb = &mc68901_device::set_out_tbo_callback(*device, DEVCB_##_devcb); #define MCFG_MC68901_OUT_TCO_CB(_devcb) \ devcb = &mc68901_device::set_out_tco_callback(*device, DEVCB_##_devcb); #define MCFG_MC68901_OUT_TDO_CB(_devcb) \ devcb = &mc68901_device::set_out_tdo_callback(*device, DEVCB_##_devcb); #define MCFG_MC68901_OUT_SO_CB(_devcb) \ devcb = &mc68901_device::set_out_so_callback(*device, DEVCB_##_devcb); /*#define MCFG_MC68901_OUT_RR_CB(_devcb) \ devcb = &mc68901_device::set_out_rr_callback(*device, DEVCB_##_devcb); #define MCFG_MC68901_OUT_TR_CB(_devcb) \ devcb = &mc68901_device::set_out_tr_callback(*device, DEVCB_##_devcb);*/ //************************************************************************** // TYPE DEFINITIONS //************************************************************************** // ======================> mc68901_device class mc68901_device : public device_t, public device_serial_interface { public: // construction/destruction mc68901_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); static void set_timer_clock(device_t &device, int timer_clock) { downcast(device).m_timer_clock = timer_clock; } static void set_rx_clock(device_t &device, int rx_clock) { downcast(device).m_rx_clock = rx_clock; } static void set_tx_clock(device_t &device, int tx_clock) { downcast(device).m_tx_clock = tx_clock; } template static devcb_base &set_out_irq_callback(device_t &device, _Object object) { return downcast(device).m_out_irq_cb.set_callback(object); } template static devcb_base &set_out_gpio_callback(device_t &device, _Object object) { return downcast(device).m_out_gpio_cb.set_callback(object); } template static devcb_base &set_out_tao_callback(device_t &device, _Object object) { return downcast(device).m_out_tao_cb.set_callback(object); } template static devcb_base &set_out_tbo_callback(device_t &device, _Object object) { return downcast(device).m_out_tbo_cb.set_callback(object); } template static devcb_base &set_out_tco_callback(device_t &device, _Object object) { return downcast(device).m_out_tco_cb.set_callback(object); } template static devcb_base &set_out_tdo_callback(device_t &device, _Object object) { return downcast(device).m_out_tdo_cb.set_callback(object); } template static devcb_base &set_out_so_callback(device_t &device, _Object object) { return downcast(device).m_out_so_cb.set_callback(object); } //template static devcb_base &set_rr_callback(device_t &device, _Object object) { return downcast(device).m_out_rr_cb.set_callback(object); } //template static devcb_base &set_tr_callback(device_t &device, _Object object) { return downcast(device).m_out_tr_cb.set_callback(object); } DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); int get_vector(); DECLARE_WRITE_LINE_MEMBER( i0_w ); DECLARE_WRITE_LINE_MEMBER( i1_w ); DECLARE_WRITE_LINE_MEMBER( i2_w ); DECLARE_WRITE_LINE_MEMBER( i3_w ); DECLARE_WRITE_LINE_MEMBER( i4_w ); DECLARE_WRITE_LINE_MEMBER( i5_w ); DECLARE_WRITE_LINE_MEMBER( i6_w ); DECLARE_WRITE_LINE_MEMBER( i7_w ); DECLARE_WRITE_LINE_MEMBER( tai_w ); DECLARE_WRITE_LINE_MEMBER( tbi_w ); DECLARE_WRITE_LINE_MEMBER( write_rx ); protected: // device-level overrides virtual void device_start(); virtual void device_reset(); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); // device_serial_interface overrides virtual void tra_callback(); virtual void tra_complete(); virtual void rcv_complete(); void check_interrupts(); void take_interrupt(UINT16 mask); void rx_buffer_full(); void rx_error(); void timer_count(int index); void timer_input(int index, int value); void gpio_input(int bit, int state); void gpio_output(); void register_w(offs_t offset, UINT8 data); private: enum { TIMER_A = 0, TIMER_B, TIMER_C, TIMER_D }; enum { REGISTER_GPIP = 0, REGISTER_AER, REGISTER_DDR, REGISTER_IERA, REGISTER_IERB, REGISTER_IPRA, REGISTER_IPRB, REGISTER_ISRA, REGISTER_ISRB, REGISTER_IMRA, REGISTER_IMRB, REGISTER_VR, REGISTER_TACR, REGISTER_TBCR, REGISTER_TCDCR, REGISTER_TADR, REGISTER_TBDR, REGISTER_TCDR, REGISTER_TDDR, REGISTER_SCR, REGISTER_UCR, REGISTER_RSR, REGISTER_TSR, REGISTER_UDR }; enum { INT_GPI0 = 0, INT_GPI1, INT_GPI2, INT_GPI3, INT_TIMER_D, INT_TIMER_C, INT_GPI4, INT_GPI5, INT_TIMER_B, INT_XMIT_ERROR, INT_XMIT_BUFFER_EMPTY, INT_RCV_ERROR, INT_RCV_BUFFER_FULL, INT_TIMER_A, INT_GPI6, INT_GPI7 }; enum { GPIP_0 = 0, GPIP_1, GPIP_2, GPIP_3, GPIP_4, GPIP_5, GPIP_6, GPIP_7 }; enum { SERIAL_START = 0, SERIAL_DATA, SERIAL_PARITY, SERIAL_STOP }; enum { XMIT_OFF = 0, XMIT_STARTING, XMIT_ON, XMIT_BREAK, XMIT_STOPPING }; static const int INT_MASK_GPIO[]; static const int INT_MASK_TIMER[]; static const int GPIO_TIMER[]; static const int PRESCALER[]; int m_timer_clock; /* timer clock */ int m_rx_clock; /* serial receive clock */ int m_tx_clock; /* serial transmit clock */ devcb_write_line m_out_irq_cb; devcb_write8 m_out_gpio_cb; devcb_write_line m_out_tao_cb; devcb_write_line m_out_tbo_cb; devcb_write_line m_out_tco_cb; devcb_write_line m_out_tdo_cb; devcb_write_line m_out_so_cb; //devcb_write_line m_out_rr_cb; //devcb_write_line m_out_tr_cb; //int m_device_type; /* device type */ /* registers */ UINT8 m_gpip; /* general purpose I/O register */ UINT8 m_aer; /* active edge register */ UINT8 m_ddr; /* data direction register */ UINT16 m_ier; /* interrupt enable register */ UINT16 m_ipr; /* interrupt pending register */ UINT16 m_isr; /* interrupt in-service register */ UINT16 m_imr; /* interrupt mask register */ UINT8 m_vr; /* vector register */ UINT8 m_tacr; /* timer A control register */ UINT8 m_tbcr; /* timer B control register */ UINT8 m_tcdcr; /* timers C and D control register */ UINT8 m_tdr[4]; /* timer data registers */ UINT8 m_scr; /* synchronous character register */ UINT8 m_ucr; /* USART control register */ UINT8 m_tsr; /* transmitter status register */ UINT8 m_rsr; /* receiver status register */ UINT8 m_transmit_buffer; /* USART data register */ int m_transmit_pending; UINT8 m_receive_buffer; int m_receive_pending; UINT8 m_gpio_input; UINT8 m_gpio_output; /* counter timer state */ UINT8 m_tmc[4]; /* timer main counters */ int m_ti[4]; /* timer in latch */ int m_to[4]; /* timer out latch */ /* interrupt state */ //int m_irqlevel; /* interrupt level latch */ /* serial state */ UINT8 m_next_rsr; /* receiver status register latch */ int m_rsr_read; /* receiver status register read flag */ // timers emu_timer *m_timer[4]; /* counter timers */ }; // device type definition extern const device_type MC68901; #endif