OSDN Git Service

36f9553f3d62cc4aa3d4fb8272f83166803b78e9
[csp-qt/common_source_project-fm7.git] / source / src / vm / scsi_dev.h
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2016.03.01-
6
7         [ SCSI base device ]
8 */
9
10 #ifndef _SCSI_DEV_H_
11 #define _SCSI_DEV_H_
12
13 #include "vm.h"
14 #include "../emu.h"
15 #include "device.h"
16
17 #define SCSI_BUFFER_SIZE        0x10000
18
19 static const _TCHAR* scsi_phase_name[9] = {
20         _T("Data Out"),
21         _T("Data In"),
22         _T("Reserved Out"),
23         _T("Reverved In"),
24         _T("Command"),
25         _T("Status"),
26         _T("Message Out"),
27         _T("Message In"),
28         _T("Bus Free"),
29 };
30
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
38
39 // http://www.geocities.jp/pd4pc/HardSoft/SCSI/SCSI_Command.htm
40
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)
97
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
107
108 #define SCSI_SERROR_CURRENT     0x70    // Current Errors
109 #define SCSI_SERROR_DEFERED     0x71    // Deferred Errors
110
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
127
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
134
135 class FIFO;
136
137 class SCSI_DEV : public DEVICE
138 {
139 private:
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;
146         
147         uint32_t data_bus;
148         bool sel_status, atn_status, ack_status, rst_status;
149         bool selected, atn_pending;
150         
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;
155         
156         uint8_t sense_code;
157         
158 public:
159         SCSI_DEV(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
160         {
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);
167                 
168                 set_device_name(_T("SCSI DEVICE"));
169         }
170         ~SCSI_DEV() {}
171         
172         // common functions
173         void initialize();
174         void release();
175         void reset();
176         void write_signal(int id, uint32_t data, uint32_t mask);
177         void event_callback(int event_id, int err);
178         void decl_state();
179         void save_state(FILEIO* state_fio);
180         bool load_state(FILEIO* state_fio);
181         
182         // unique functions
183         void set_context_interface(DEVICE* device)
184         {
185 #ifdef SCSI_HOST_WIDE
186                 register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 0xffff);
187 #else
188                 register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 0xff);
189 #endif
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);
196         }
197         uint8_t get_sense_code()
198         {
199                 return sense_code;
200         }
201         void set_sense_code(uint8_t value)
202         {
203                 sense_code = value;
204         }
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);
214         
215         virtual void reset_device() {}
216         virtual bool is_device_existing()
217         {
218                 return true;
219         }
220         virtual bool is_device_ready()
221         {
222                 return true;
223         }
224         virtual uint32_t physical_block_size()
225         {
226                 return 0;
227         }
228         virtual uint32_t logical_block_size()
229         {
230                 return 0;
231         }
232         virtual uint32_t max_logical_block_addr()
233         {
234                 return 0;
235         }
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);
240         
241         uint8_t get_cur_command()
242         {
243                 return command[0];
244         }
245         uint8_t get_logical_unit_number()
246         {
247                 return command[1] >> 5;
248         }
249         uint8_t command[12];
250         int command_index;
251         
252         FIFO *buffer;
253         uint64_t position, remain;
254         
255         char vendor_id[8 + 1];
256         char product_id[16 + 1];
257         uint8_t device_type;
258         bool is_removable;
259         bool is_hot_swappable;
260         double seek_time;
261         int bytes_per_sec;
262         
263         int scsi_id;
264 };
265
266 #endif
267