OSDN Git Service

[DOC] For release 2017-01-24.
[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 class FIFO;
129
130 class SCSI_DEV : public DEVICE
131 {
132 private:
133         outputs_t outputs_dat;
134         outputs_t outputs_bsy;
135         outputs_t outputs_cd;
136         outputs_t outputs_io;
137         outputs_t outputs_msg;
138         outputs_t outputs_req;
139         
140         uint32_t data_bus;
141         bool sel_status, atn_status, ack_status, rst_status;
142         bool selected, atn_pending;
143         
144         int phase, next_phase, next_req;
145         int event_sel, event_phase, event_req;
146         uint32_t first_req_clock;
147         double next_req_usec;
148         
149 public:
150         SCSI_DEV(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
151         {
152                 initialize_output_signals(&outputs_dat);
153                 initialize_output_signals(&outputs_bsy);
154                 initialize_output_signals(&outputs_cd);
155                 initialize_output_signals(&outputs_io);
156                 initialize_output_signals(&outputs_msg);
157                 initialize_output_signals(&outputs_req);
158                 
159                 max_logical_block_addr = 0;     // uninitialized
160                 set_device_name(_T("SCSI DEVICE"));
161         }
162         ~SCSI_DEV() {}
163         
164         // common functions
165         void initialize();
166         void release();
167         void reset();
168         void write_signal(int id, uint32_t data, uint32_t mask);
169         void event_callback(int event_id, int err);
170         void save_state(FILEIO* state_fio);
171         bool load_state(FILEIO* state_fio);
172         
173         // unique functions
174         void set_context_interface(DEVICE* device)
175         {
176 #ifdef SCSI_HOST_WIDE
177                 register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 0xffff);
178 #else
179                 register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 0xff);
180 #endif
181                 register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 1 << scsi_id);
182                 register_output_signal(&outputs_bsy, device, SIG_SCSI_BSY, 1 << scsi_id);
183                 register_output_signal(&outputs_cd,  device, SIG_SCSI_CD,  1 << scsi_id);
184                 register_output_signal(&outputs_io,  device, SIG_SCSI_IO,  1 << scsi_id);
185                 register_output_signal(&outputs_msg, device, SIG_SCSI_MSG, 1 << scsi_id);
186                 register_output_signal(&outputs_req, device, SIG_SCSI_REQ, 1 << scsi_id);
187         }
188         void set_phase(int value);
189         void set_phase_delay(int value, double usec);
190         void set_dat(int value);
191         void set_bsy(int value);
192         void set_cd(int value);
193         void set_io(int value);
194         void set_msg(int value);
195         void set_req(int value);
196         void set_req_delay(int value, double usec);
197         
198         virtual void reset_device() {}
199         virtual bool is_device_ready()
200         {
201                 return true;
202         }
203         virtual int get_command_length(int value);
204         virtual void start_command();
205         virtual void read_buffer(int length);
206         virtual void write_buffer(int length);
207         virtual void initialize_max_logical_block_addr() {}
208         
209         uint8_t get_cur_command()
210         {
211                 return command[0];
212         }
213         uint8_t command[12];
214         int command_index;
215         
216         FIFO *buffer;
217         uint64_t position, remain;
218         
219         char vendor_id[8 + 1];
220         char product_id[16 + 1];
221         uint8_t device_type;
222         bool is_removable;
223         int physical_block_size;
224         int logical_block_size;
225         uint32_t max_logical_block_addr;
226         double seek_time;
227         int bytes_per_sec;
228         
229         int scsi_id;
230 };
231
232 #endif
233