summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/wd33c9x.h
blob: bdfb84fe8d9b8466d225e1fd07f56dd1fe760858 (plain) (tree)
1
2
3
4
5
6
7
8





                                

                              




                              
                                                                                 





                                                 

                                                

                                        

                                                  

                                                    



                                        

                                      
                                           
 
                                           












                                                                                                                               

                                                  




                                                          
                               








                                             















                                                                              





































                                                                                                        
                                                 

       

                                                                                       


         
                                                                                                        
























                                                                                                         

                                             


                                              
                                
// 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