// license:BSD-3-Clause // copyright-holders:Tyson Smith /* * wd33c9x.h */ #ifndef MAME_MACHINE_WD33C9X_H #define MAME_MACHINE_WD33C9X_H #pragma once #include "machine/nscsi_bus.h" class wd33c9x_base_device : public nscsi_device, public nscsi_slot_card_interface { public: auto irq_cb() { return m_irq_cb.bind(); } auto drq_cb() { return m_drq_cb.bind(); } // Direct Addressing Interface uint8_t dir_r(offs_t offset); void dir_w(offs_t offset, uint8_t data); // Indirect Addressing Interface uint8_t indir_r(offs_t offset); void indir_w(offs_t offset, uint8_t data); // Alternative Indirect Addressing Interface uint8_t indir_addr_r(); void indir_addr_w(uint8_t data); uint8_t indir_reg_r(); void indir_reg_w(uint8_t data); // Master Reset (MR) Interface DECLARE_WRITE_LINE_MEMBER(reset_w); // DMA Interface (for use with DRQ) uint8_t dma_r(); void dma_w(const uint8_t data); protected: wd33c9x_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); virtual void device_start() override; virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void scsi_ctrl_changed() override; private: static const char *const state_names[]; static const char *const substate_names[]; static constexpr uint8_t NUM_REGS = 0x20; static constexpr uint8_t REGS_MASK = NUM_REGS - 1; uint8_t m_addr; uint8_t m_regs[NUM_REGS]; uint8_t m_command_length; uint8_t m_last_message; void start_command(); void step(bool timeout); void set_scsi_state(uint16_t state); void set_scsi_state_sub(uint8_t sub); uint16_t m_scsi_state; uint8_t m_mode; uint8_t m_xfr_phase; void load_transfer_count(); bool decrement_transfer_count(); uint32_t m_transfer_count; uint8_t data_fifo_pop(); void data_fifo_push(const uint8_t data); bool data_fifo_empty() const; bool data_fifo_full() const; void data_fifo_reset(); static constexpr uint8_t DATA_FIFO_SIZE = 12; uint8_t m_data_fifo[DATA_FIFO_SIZE]; uint8_t m_data_fifo_pos; uint8_t m_data_fifo_size; uint32_t send_byte(const uint32_t value = 0, const uint32_t mask = 0); uint8_t irq_fifo_pop(); void irq_fifo_push(const uint8_t status); bool irq_fifo_empty() const; bool irq_fifo_full() const; void irq_fifo_reset(); static constexpr uint8_t IRQ_FIFO_SIZE = 8; uint8_t m_irq_fifo[IRQ_FIFO_SIZE]; uint8_t m_irq_fifo_pos; uint8_t m_irq_fifo_size; void update_irq(); devcb_write_line m_irq_cb; void set_drq(); void clear_drq(); devcb_write_line m_drq_cb; bool m_drq_state; void delay(uint32_t cycles); void delay_cycles(uint32_t cycles); emu_timer *m_timer; bool set_command_length(const uint8_t cc); uint8_t get_msg_out() const; }; class wd33c92_device : public wd33c9x_base_device { public: wd33c92_device(const machine_config &mconfig, const char *tag, device_t *owner) : wd33c92_device(mconfig, tag, owner, 0) { } wd33c92_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class wd33c93_device : public wd33c9x_base_device { public: wd33c93_device(const machine_config &mconfig, const char *tag, device_t *owner) : wd33c93_device(mconfig, tag, owner, 0) { } wd33c93_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class wd33c93a_device : public wd33c9x_base_device { public: wd33c93a_device(const machine_config &mconfig, const char *tag, device_t *owner) : wd33c93a_device(mconfig, tag, owner, 0) { } wd33c93a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class wd33c93b_device : public wd33c9x_base_device { public: wd33c93b_device(const machine_config &mconfig, const char *tag, device_t *owner) : wd33c93b_device(mconfig, tag, owner, 0) { } wd33c93b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; DECLARE_DEVICE_TYPE(WD33C92, wd33c92_device) DECLARE_DEVICE_TYPE(WD33C93, wd33c93_device) DECLARE_DEVICE_TYPE(WD33C93A, wd33c93a_device) DECLARE_DEVICE_TYPE(WD33C93B, wd33c93b_device) #endif // MAME_MACHINE_WD33C9X_H