2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
17 #define SCSI_BUFFER_SIZE 0x10000
19 static const _TCHAR* scsi_phase_name[9] = {
31 #define SCSI_PHASE_DATA_OUT 0 // C/D = 0, MSG = 0, I/O = 0
32 #define SCSI_PHASE_DATA_IN 1 // C/D = 0, MSG = 0, I/O = 1
33 #define SCSI_PHASE_COMMAND 4 // C/D = 1, MSG = 0, I/O = 0
34 #define SCSI_PHASE_STATUS 5 // C/D = 1, MSG = 0, I/O = 1
35 #define SCSI_PHASE_MESSAGE_OUT 6 // C/D = 1, MSG = 1, I/O = 0
36 #define SCSI_PHASE_MESSAGE_IN 7 // C/D = 1, MSG = 1, I/O = 1
37 #define SCSI_PHASE_BUS_FREE 8 // C/D = 0, MSG = 0, I/O = 0
39 // http://www.geocities.jp/pd4pc/HardSoft/SCSI/SCSI_Command.htm
41 #define SCSI_CMD_CHANGE_DEF 0x40 // Change Definition (Optional)
42 #define SCSI_CMD_COMPARE 0x39 // Compare (O)
43 #define SCSI_CMD_COPY 0x18 // Copy (O)
44 #define SCSI_CMD_COP_VERIFY 0x3A // Copy and Verify (O)
45 #define SCSI_CMD_INQUIRY 0x12 // Inquiry (MANDATORY)
46 #define SCSI_CMD_LOG_SELECT 0x4C // Log Select (O)
47 #define SCSI_CMD_LOG_SENSE 0x4D // Log Sense (O)
48 #define SCSI_CMD_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific)
49 #define SCSI_CMD_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific)
50 #define SCSI_CMD_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific)
51 #define SCSI_CMD_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific)
52 #define SCSI_CMD_READ_BUFF 0x3C // Read Buffer (O)
53 #define SCSI_CMD_REQ_SENSE 0x03 // Request Sense (MANDATORY)
54 #define SCSI_CMD_SEND_DIAG 0x1D // Send Diagnostic (O)
55 #define SCSI_CMD_RCV_DIAG 0x1C // Receive Diagnostic Results (O)
56 #define SCSI_CMD_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY)
57 #define SCSI_CMD_WRITE_BUFF 0x3B // Write Buffer (O)
58 #define SCSI_CMD_FORMAT 0x04 // Format Unit (MANDATORY)
59 #define SCSI_CMD_LCK_UN_CAC 0x36 // Lock Unlock Cache (O)
60 #define SCSI_CMD_PREFETCH 0x34 // Prefetch (O)
61 #define SCSI_CMD_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O)
62 #define SCSI_CMD_READ6 0x08 // Read 6-byte (MANDATORY)
63 #define SCSI_CMD_READ10 0x28 // Read 10-byte (MANDATORY)
64 #define SCSI_CMD_READ12 0xa8 // Read 10-byte (MANDATORY)
65 #define SCSI_CMD_RD_CAPAC 0x25 // Read Capacity (MANDATORY)
66 #define SCSI_CMD_RD_DEFECT 0x37 // Read Defect Data (O)
67 #define SCSI_CMD_READ_LONG 0x3E // Read Long (O)
68 #define SCSI_CMD_REASS_BLK 0x07 // Reassign Blocks (O)
69 #define SCSI_CMD_RELEASE 0x17 // Release Unit (MANDATORY)
70 #define SCSI_CMD_RESERVE 0x16 // Reserve Unit (MANDATORY)
71 #define SCSI_CMD_REZERO 0x01 // Rezero Unit (O)
72 #define SCSI_CMD_SRCH_DAT_E 0x31 // Search Data Equal (O)
73 #define SCSI_CMD_SRCH_DAT_H 0x30 // Search Data High (O)
74 #define SCSI_CMD_SRCH_DAT_L 0x32 // Search Data Low (O)
75 #define SCSI_CMD_SEEK6 0x0B // Seek 6-Byte (O)
76 #define SCSI_CMD_SEEK10 0x2B // Seek 10-Byte (O)
77 #define SCSI_CMD_SET_LIMIT 0x33 // Set Limits (O)
78 #define SCSI_CMD_START_STP 0x1B // Start/Stop Unit (O)
79 #define SCSI_CMD_SYNC_CACHE 0x35 // Synchronize Cache (O)
80 #define SCSI_CMD_VERIFY 0x2F // Verify (O)
81 #define SCSI_CMD_WRITE6 0x0A // Write 6-Byte (MANDATORY)
82 #define SCSI_CMD_WRITE10 0x2A // Write 10-Byte (MANDATORY)
83 #define SCSI_CMD_WRITE12 0xAA // Write 10-Byte (MANDATORY)
84 #define SCSI_CMD_WRT_VERIFY 0x2E // Write and Verify (O)
85 #define SCSI_CMD_WRITE_LONG 0x3F // Write Long (O)
86 #define SCSI_CMD_WRITE_SAME 0x41 // Write Same (O)
87 #define SCSI_CMD_PLAYAUD_10 0x45 // Play Audio 10-Byte (O)
88 #define SCSI_CMD_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O)
89 #define SCSI_CMD_PLAYAUDMSF 0x47 // Play Audio MSF (O)
90 #define SCSI_CMD_PLAYA_TKIN 0x48 // Play Audio Track/Index (O)
91 #define SCSI_CMD_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O)
92 #define SCSI_CMD_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O)
93 #define SCSI_CMD_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY)
94 #define SCSI_CMD_READHEADER 0x44 // Read Header (O)
95 #define SCSI_CMD_SUBCHANNEL 0x42 // Read Subchannel (O)
96 #define SCSI_CMD_READ_TOC 0x43 // Read TOC (O)
98 #define SCSI_STATUS_GOOD 0x00 // Status Good
99 #define SCSI_STATUS_CHKCOND 0x02 // Check Condition
100 #define SCSI_STATUS_CONDMET 0x04 // Condition Met
101 #define SCSI_STATUS_BUSY 0x08 // Busy
102 #define SCSI_STATUS_INTERM 0x10 // Intermediate
103 #define SCSI_STATUS_INTCDMET 0x14 // Intermediate-Condition Met
104 #define SCSI_STATUS_RESCONF 0x18 // Reservation Conflict
105 #define SCSI_STATUS_COMTERM 0x22 // Command Terminated
106 #define SCSI_STATUS_QFULL 0x28 // Queue Full
108 #define SCSI_SERROR_CURRENT 0x70 // Current Errors
109 #define SCSI_SERROR_DEFERED 0x71 // Deferred Errors
111 #define SCSI_KEY_NOSENSE 0x00 // No Sense
112 #define SCSI_KEY_RECERROR 0x01 // Recovered Error
113 #define SCSI_KEY_NOTREADY 0x02 // Not Ready
114 #define SCSI_KEY_MEDIUMERR 0x03 // Medium Error
115 #define SCSI_KEY_HARDERROR 0x04 // Hardware Error
116 #define SCSI_KEY_ILLGLREQ 0x05 // Illegal Request
117 #define SCSI_KEY_UNITATT 0x06 // Unit Attention
118 #define SCSI_KEY_DATAPROT 0x07 // Data Protect
119 #define SCSI_KEY_BLANKCHK 0x08 // Blank Check
120 #define SCSI_KEY_VENDSPEC 0x09 // Vendor Specific
121 #define SCSI_KEY_COPYABORT 0x0A // Copy Abort
122 #define SCSI_KEY_ABORT 0x0B // Abort
123 #define SCSI_KEY_EQUAL 0x0C // Equal (Search)
124 #define SCSI_KEY_VOLOVRFLW 0x0D // Volume Overflow
125 #define SCSI_KEY_MISCOMP 0x0E // Miscompare (Search)
126 #define SCSI_KEY_RESERVED 0x0F // Reserved
128 #define SCSI_SENSE_NOSENSE 0x00 // No Sense
129 #define SCSI_SENSE_NOTREADY 0x04 // Not Ready
130 #define SCSI_SENSE_NORECORDFND 0x14 // No Record Found
131 #define SCSI_SENSE_SEEKERR 0x15 // Seek Error
132 #define SCSI_SENSE_ILLGLBLKADDR 0x21 // Illegal Block Address
133 #define SCSI_SENSE_WRITEPROTCT 0x27 // Write Protected
137 class SCSI_DEV : public DEVICE
140 outputs_t outputs_dat;
141 outputs_t outputs_bsy;
142 outputs_t outputs_cd;
143 outputs_t outputs_io;
144 outputs_t outputs_msg;
145 outputs_t outputs_req;
148 bool sel_status, atn_status, ack_status, rst_status;
149 bool selected, atn_pending;
151 int phase, next_phase, next_req;
152 int event_sel, event_phase, event_req;
153 uint32_t first_req_clock;
154 double next_req_usec;
159 SCSI_DEV(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
161 initialize_output_signals(&outputs_dat);
162 initialize_output_signals(&outputs_bsy);
163 initialize_output_signals(&outputs_cd);
164 initialize_output_signals(&outputs_io);
165 initialize_output_signals(&outputs_msg);
166 initialize_output_signals(&outputs_req);
168 set_device_name(_T("SCSI DEVICE"));
176 void write_signal(int id, uint32_t data, uint32_t mask);
177 void event_callback(int event_id, int err);
179 void save_state(FILEIO* state_fio);
180 bool load_state(FILEIO* state_fio);
183 void set_context_interface(DEVICE* device)
185 #ifdef SCSI_HOST_WIDE
186 register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 0xffff);
188 register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 0xff);
190 register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 1 << scsi_id);
191 register_output_signal(&outputs_bsy, device, SIG_SCSI_BSY, 1 << scsi_id);
192 register_output_signal(&outputs_cd, device, SIG_SCSI_CD, 1 << scsi_id);
193 register_output_signal(&outputs_io, device, SIG_SCSI_IO, 1 << scsi_id);
194 register_output_signal(&outputs_msg, device, SIG_SCSI_MSG, 1 << scsi_id);
195 register_output_signal(&outputs_req, device, SIG_SCSI_REQ, 1 << scsi_id);
197 uint8_t get_sense_code()
201 void set_sense_code(uint8_t value)
205 void set_phase(int value);
206 void set_phase_delay(int value, double usec);
207 void set_dat(int value);
208 void set_bsy(int value);
209 void set_cd(int value);
210 void set_io(int value);
211 void set_msg(int value);
212 void set_req(int value);
213 void set_req_delay(int value, double usec);
215 virtual void reset_device() {}
216 virtual bool is_device_existing()
220 virtual bool is_device_ready()
224 virtual uint32_t physical_block_size()
228 virtual uint32_t logical_block_size()
232 virtual uint32_t max_logical_block_addr()
236 virtual int get_command_length(int value);
237 virtual void start_command();
238 virtual bool read_buffer(int length);
239 virtual bool write_buffer(int length);
241 uint8_t get_cur_command()
245 uint8_t get_logical_unit_number()
247 return command[1] >> 5;
253 uint64_t position, remain;
255 char vendor_id[8 + 1];
256 char product_id[16 + 1];
259 bool is_hot_swappable;