1 // license:BSD-3-Clause 2 // copyright-holders:Patrick Mackinlay 3 4 #ifndef MAME_MACHINE_CXD1185_H 5 #define MAME_MACHINE_CXD1185_H 6 7 #pragma once 8 9 #include "machine/nscsi_bus.h" 10 11 class cxd1185_device 12 : public nscsi_device 13 , public nscsi_slot_card_interface 14 { 15 public: 16 cxd1185_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); 17 18 // device configuration irq_out_cb()19 auto irq_out_cb() { return m_irq_out_cb.bind(); } drq_out_cb()20 auto drq_out_cb() { return m_drq_out_cb.bind(); } port_out_cb()21 auto port_out_cb() { return m_port_out_cb.bind(); } 22 23 void map(address_map &map); 24 25 // dma and port handlers 26 u8 dma_r(); 27 void dma_w(u8 data); 28 void port_w(u8 data); 29 30 protected: 31 // device_t overrides 32 virtual void device_start() override; 33 virtual void device_reset() override; 34 35 // ncsci_device overrides 36 virtual void scsi_ctrl_changed() override; 37 38 // register handlers 39 u8 status_r(); 40 u8 scsi_data_r(); 41 template <unsigned Register> u8 int_req_r(); 42 u8 scsi_ctrl_monitor_r(); 43 u8 fifo_status_r(); scsi_id_r()44 u8 scsi_id_r() { return m_scsi_id; } count_r()45 template <unsigned Byte> u8 count_r() { return u8(m_count >> (Byte * 8)); } int_auth_r()46 template <unsigned Register> u8 int_auth_r() { return m_int_auth[Register]; } mode_r()47 u8 mode_r() { return m_mode; } sync_ctrl_r()48 u8 sync_ctrl_r() { return m_sync_ctrl; } scsi_ctrl_r()49 u8 scsi_ctrl_r() { return m_scsi_ctrl; } ioport_r()50 u8 ioport_r() { return m_ioport; } 51 52 void command_w(u8 data); 53 void scsi_data_w(u8 data); 54 void environ_w(u8 data); 55 void timer_w(u8 data); scsi_id_w(u8 data)56 void scsi_id_w(u8 data) { m_scsi_id = data; } count_w(u8 data)57 template <unsigned Byte> void count_w(u8 data) { m_count &= ~(0xffU << (Byte * 8)); m_count |= u32(data) << (Byte * 8); } 58 template <unsigned Register> void int_auth_w(u8 data); mode_w(u8 data)59 void mode_w(u8 data) { m_mode = data; } sync_ctrl_w(u8 data)60 void sync_ctrl_w(u8 data) { m_sync_ctrl = data; } 61 void scsi_ctrl_w(u8 data); 62 void ioport_w(u8 data); 63 64 // state machine 65 void state_timer(void *ptr, s32 param); 66 int state_step(); 67 68 // other logic 69 void reset_chip(); 70 void reset_fifo(); 71 void int_check(); 72 void set_drq(bool asserted); 73 74 private: 75 devcb_write_line m_irq_out_cb; 76 devcb_write_line m_drq_out_cb; 77 devcb_write8 m_port_out_cb; 78 79 emu_timer *m_state_timer; 80 enum state : unsigned 81 { 82 IDLE, 83 84 // arbitration 85 ARB_BUS_FREE, 86 ARB_START, 87 ARB_EVALUATE, 88 89 // selection 90 SEL_START, 91 SEL_DELAY, 92 SEL_WAIT_BSY, 93 SEL_COMPLETE, 94 95 // information transfer 96 XFR_INFO, 97 XFR_IN, 98 XFR_IN_NEXT, 99 XFR_IN_REQ, 100 XFR_IN_DRAIN, 101 XFR_OUT, 102 XFR_OUT_NEXT, 103 XFR_OUT_REQ, 104 XFR_INFO_DONE, 105 106 // scsi bus reset 107 BUS_RESET, 108 BUS_RESET_DONE, 109 110 COMPLETE, 111 } 112 m_state; 113 114 // internal state 115 bool m_irq_asserted; 116 bool m_drq_asserted; 117 util::fifo <u8, 16> m_fifo; 118 bool m_pio_data_mode; 119 bool m_pio_ctrl_mode; 120 u32 m_scsi_ctrl_state; 121 122 enum status_mask : u8 123 { 124 CIP = 0x01, // command in progress 125 MIRQ = 0x02, // monitor irq 126 TRBZ = 0x04, // transfer byte count zero 127 TARG = 0x08, // target 128 INIT = 0x10, // initiator 129 130 MDBP = 0x40, // monitor scsi bus DBP 131 MRST = 0x80, // monitor scsi bus RST 132 }; 133 enum command_mask : u8 134 { 135 CMD = 0x0f, // command code 136 TRBE = 0x10, // transfer byte counter enable 137 DMA = 0x20, // dma mode 138 CAT = 0xc0, // command category 139 140 CMD_RESET = 0x01, 141 CMD_SEL_ATN = 0x42, 142 CMD_XFR_PAD = 0xc1, 143 }; 144 enum int_req1 : u8 145 { 146 ARBF = 0x01, // arbitration fail 147 SWOA = 0x02, // selection without atn 148 SWA = 0x04, // selection with atn 149 RSL = 0x08, // reselected 150 STO = 0x10, // selection time over 151 }; 152 enum int_req2 : u8 153 { 154 RMSG = 0x01, // req in message phase 155 SPE = 0x02, // scsi bus parity error 156 DPE = 0x04, // data bus parity error 157 DATN = 0x08, // drive atn 158 PHC = 0x10, // phase change 159 SRST = 0x20, // scsi reset 160 DCNT = 0x40, // disconnected 161 FNC = 0x80, // function complete 162 }; 163 enum fifo_status_mask : u8 164 { 165 FC = 0x0f, // fifo count 166 FIF = 0x10, // fifo is full 167 168 FIE = 0x80, // fifo is empty 169 }; 170 enum environ_mask : u8 171 { 172 FS0 = 0x01, 173 FS1 = 0x02, 174 FS = 0x03, // clock division ratio 175 176 SIRM = 0x10, // irq active low 177 DPEN = 0x20, // data bus parity enable 178 SDPM = 0x40, // data bus parity even 179 DIFE = 0x80, // differential mode 180 }; 181 enum scsi_ctrl_monitor_mask : u8 182 { 183 MATN = 0x01, 184 MACK = 0x02, 185 MREQ = 0x04, 186 MIO = 0x08, 187 MCD = 0x10, 188 MMSG = 0x20, 189 MSEL = 0x40, 190 MBSY = 0x80, 191 }; 192 enum scsi_id_mask : u8 193 { 194 OID = 0x07, // owner id 195 SMOD = 0x10, // single initiator mode 196 SID = 0xe0, // selecting id 197 TID = 0xe0, // target id 198 }; 199 enum mode_mask : u8 200 { 201 BDMA = 0x01, // burst dma mode 202 SSPE = 0x04, // ignore selection scsi parity error 203 SPHI = 0x08, // scsi phase change ignore 204 TMSL = 0x10, // scsi reset timer enable 205 HATN = 0x20, // halt on atn 206 HSPE = 0x40, // halt on scsi parity error 207 HDPE = 0x80, // halt on data bus parity error 208 }; 209 enum sync_ctrl_mask : u8 210 { 211 TOF = 0x0f, // transfer offset 212 TPD = 0xf0, // transfer cycle 213 }; 214 enum io_port_mask : u8 215 { 216 PRT = 0x0f, // i/o port data 217 PCN = 0xf0, // i/o port control 218 }; 219 enum scsi_ctrl_mask : u8 220 { 221 AATN = 0x01, 222 AACK = 0x02, 223 AREQ = 0x04, 224 AIO = 0x08, 225 ACD = 0x10, 226 AMSG = 0x20, 227 ASEL = 0x40, 228 ABSY = 0x80, 229 }; 230 231 // registers 232 u8 m_status; 233 u8 m_command; 234 u8 m_int_req[2]; 235 u8 m_environ; 236 unsigned m_sel_time; 237 unsigned m_rst_time; 238 u8 m_scsi_id; 239 u8 m_int_auth[2]; 240 u8 m_mode; 241 u32 m_count; 242 u8 m_sync_ctrl; 243 u8 m_scsi_ctrl; 244 u8 m_ioport; 245 }; 246 247 DECLARE_DEVICE_TYPE(CXD1185, cxd1185_device) 248 249 #endif // MAME_MACHINE_CXD1185_H 250