OSDN Git Service

f7a8f521cf46b6cbd24f3e0f01c4661877dd1ce7
[csp-qt/common_source_project-fm7.git] / source / src / vm / scsi_dev.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2016.03.01-
6
7         [ SCSI base device ]
8 */
9
10 #include "scsi_dev.h"
11 #include "../fifo.h"
12
13 #define EVENT_SEL       0
14 #define EVENT_PHASE     1
15 #define EVENT_REQ       2
16 //#define _SCSI_DEBUG_LOG
17
18 void SCSI_DEV::initialize()
19 {
20         DEVICE::initialize();
21         buffer = new FIFO(SCSI_BUFFER_SIZE);
22         phase = SCSI_PHASE_BUS_FREE;
23 }
24
25 void SCSI_DEV::release()
26 {
27         buffer->release();
28         delete buffer;
29 }
30
31 void SCSI_DEV::reset()
32 {
33         data_bus = 0;
34         sel_status = atn_status = ack_status = rst_status = false;
35         selected = atn_pending = false;
36         
37         event_sel = event_phase = event_req = -1;
38         set_phase(SCSI_PHASE_BUS_FREE);
39         set_sense_code(SCSI_SENSE_NOSENSE);
40 }
41
42 void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask)
43 {
44         switch(id) {
45         case SIG_SCSI_DAT:
46                 data_bus = data & mask;
47                 break;
48                 
49         case SIG_SCSI_SEL:
50                 {
51                         bool prev_status = sel_status;
52                         sel_status = ((data & mask) != 0);
53                         
54                         if(phase != SCSI_PHASE_BUS_FREE) {
55                                 // this device is already selected
56                         } else if(!prev_status && sel_status) {
57                                 // L -> H
58 #ifdef SCSI_DEV_IMMEDIATE_SELECT
59                                 event_callback(EVENT_SEL, 0);
60 #else
61                                 if(event_sel != -1) {
62                                         cancel_event(this, event_sel);
63                                 }
64                                 register_event(this, EVENT_SEL, 20.0, false, &event_sel);
65 #endif
66                         } else if(prev_status && !sel_status) {
67                                 // H -> L
68                                 if(event_sel != -1) {
69                                         cancel_event(this, event_sel);
70                                         event_sel = -1;
71                                 }
72                                 if(selected) {
73                                         if(atn_status) {
74                                                 // change to message out phase
75                                                 buffer->clear();
76                                                 set_phase_delay(SCSI_PHASE_MESSAGE_OUT, 10.0);
77 //                                              set_phase(SCSI_PHASE_MESSAGE_OUT);
78                                         } else {
79                                                 // change to command phase
80                                                 memset(command, 0, sizeof(command));
81                                                 command_index = 0;
82                                                 set_phase_delay(SCSI_PHASE_COMMAND, 10.0);
83 //                                              set_phase(SCSI_PHASE_COMMAND);
84                                         }
85                                 }
86                         }
87                 }
88                 break;
89                 
90         case SIG_SCSI_ATN:
91                 {
92                         bool prev_status = atn_status;
93                         atn_status = ((data & mask) != 0);
94                         
95                         if(phase == SCSI_PHASE_BUS_FREE) {
96                                 // this device is not selected
97                         } else if(!prev_status && atn_status) {
98                                 // L -> H
99                                 #ifdef _SCSI_DEBUG_LOG
100                                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] ATN signal raised\n"), scsi_id);
101                                 #endif
102                                 if(ack_status) {
103                                         // wait until ack=off
104                                         atn_pending = true;
105                                 } else {
106                                         // change to message out phase
107                                         atn_pending = false;
108                                         buffer->clear();
109                                         set_phase_delay(SCSI_PHASE_MESSAGE_OUT, 10.0);
110                                 }
111                         }
112                 }
113                 break;
114                 
115         case SIG_SCSI_ACK:
116                 {
117 /*
118                         initiator --->  device
119
120                         wait req=on
121                                         set req=on
122                                         wait ack=on
123                         write data
124                         set ack=on
125                         wait req=off
126                                         read data
127                                         set req=off
128                                         wait ack=off
129                         set ack=off
130
131                         initiator <---  device
132
133                         wait req=on
134                                         write data
135                                         set req=on
136                                         wait ack=on
137                         read data
138                         set ack=on
139                         wait req=off
140                                         set req=off
141                                         wait ack=off
142                         set ack=off
143 */
144                         bool prev_status = ack_status;
145                         ack_status = ((data & mask) != 0);
146                         
147                         if(phase == SCSI_PHASE_BUS_FREE) {
148                                 // this device is not selected
149                         } else if(!prev_status & ack_status) {
150                                 // L -> H
151                                 switch(phase) {
152                                 case SCSI_PHASE_DATA_OUT:
153                                         buffer->write(data_bus);
154                                         
155                                         // check defect list length in format unit data
156                                         if(command[0] == SCSI_CMD_FORMAT) {
157                                                 if(buffer->count() == 4) {
158                                                         remain += buffer->read_not_remove(2) * 256 + buffer->read_not_remove(3);
159                                                 }
160                                         }
161                                         break;
162                                         
163                                 case SCSI_PHASE_COMMAND:
164                                         command[command_index++] = data_bus;
165                                         break;
166                                         
167                                 case SCSI_PHASE_MESSAGE_OUT:
168                                         buffer->write(data_bus);
169                                         break;
170                                 }
171                                 set_req_delay(0, 0.1);
172                         } else if(prev_status && !ack_status) {
173                                 // H -> L
174                                 if(atn_pending) {
175                                         // change to message out phase
176                                         atn_pending = false;
177                                         buffer->clear();
178                                         set_phase_delay(SCSI_PHASE_MESSAGE_OUT, 10.0);
179                                 } else {
180                                         switch(phase) {
181                                         case SCSI_PHASE_DATA_OUT:
182                                                 if(--remain > 0) {
183                                                         switch(command[0]) {
184                                                         case SCSI_CMD_WRITE6:
185                                                         case SCSI_CMD_WRITE10:
186                                                         case SCSI_CMD_WRITE12:
187                                                                 // flush buffer
188                                                                 if(buffer->full()) {
189                                                                         if(!write_buffer(buffer->count())) {
190                                                                                 // change to status phase
191                                                                                 set_dat(SCSI_STATUS_CHKCOND);
192                                                                                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
193                                                                                 break;
194                                                                         }
195                                                                 }
196                                                                 // request to write next data
197                                                                 {
198                                                                         next_req_usec += 1000000.0 / bytes_per_sec;
199                                                                         double usec = next_req_usec - get_passed_usec(first_req_clock);
200                                                                         set_req_delay(1, (usec > 1.0) ? usec : 1.0);
201                                                                 }
202                                                                 break;
203                                                         default:
204                                                                 // flush buffer
205                                                                 if(buffer->full()) {
206                                                                         buffer->clear();
207                                                                 }
208                                                                 // request to write next data
209                                                                 set_req_delay(1, 1.0);
210                                                                 break;
211                                                         }
212                                                 } else {
213                                                         switch(command[0]) {
214                                                         case SCSI_CMD_WRITE6:
215                                                         case SCSI_CMD_WRITE10:
216                                                         case SCSI_CMD_WRITE12:
217                                                                 // flush buffer
218                                                                 if(!buffer->empty()) {
219                                                                         if(!write_buffer(buffer->count())) {
220                                                                                 // change to status phase
221                                                                                 set_dat(SCSI_STATUS_CHKCOND);
222                                                                                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
223                                                                                 break;
224                                                                         }
225                                                                 }
226                                                                 break;
227                                                         default:
228                                                                 // flush buffer
229                                                                 if(!buffer->empty()) {
230                                                                         buffer->clear();
231                                                                 }
232                                                                 break;
233                                                         }
234                                                         // change to status phase
235                                                         set_dat(SCSI_STATUS_GOOD);
236                                                         set_sense_code(SCSI_SENSE_NOSENSE);
237                                                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
238                                                 }
239                                                 break;
240                                                 
241                                         case SCSI_PHASE_DATA_IN:
242                                                 if(--remain > 0) {
243                                                         // update buffer
244                                                         if(buffer->count() == 0) {
245                                                                 int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
246                                                                 if(!read_buffer(length)) {
247                                                                         // change to status phase
248                                                                         set_dat(SCSI_STATUS_CHKCOND);
249                                                                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
250                                                                         break;
251                                                                 }
252                                                         }
253                                                         // request to read next data
254                                                         set_dat(buffer->read());
255                                                         switch(command[0]) {
256                                                         case SCSI_CMD_READ6:
257                                                         case SCSI_CMD_READ10:
258                                                         case SCSI_CMD_READ12:
259                                                                 {
260                                                                         next_req_usec += 1000000.0 / bytes_per_sec;
261                                                                         double usec = next_req_usec - get_passed_usec(first_req_clock);
262                                                                         set_req_delay(1, (usec > 1.0) ? usec : 1.0);
263                                                                 }
264                                                                 break;
265                                                         default:
266                                                                 set_req_delay(1, 1.0);
267                                                                 break;
268                                                         }
269                                                 } else {
270                                                         // change to status phase
271                                                         set_dat(SCSI_STATUS_GOOD);
272                                                         set_sense_code(SCSI_SENSE_NOSENSE);
273                                                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
274                                                 }
275                                                 break;
276                                                 
277                                         case SCSI_PHASE_COMMAND:
278                                                 if(command_index < get_command_length(command[0])) {
279                                                         // request next command
280                                                         set_req_delay(1, 1.0);
281                                                 } else {
282                                                         // start command
283                                                         start_command();
284                                                 }
285                                                 break;
286                                                 
287                                         case SCSI_PHASE_STATUS:
288                                                 // create message data table
289                                                 remain = 1;
290                                                 buffer->clear();
291                                                 buffer->write(0x00); // command complete message
292                                                 // change to message in phase
293                                                 set_dat(buffer->read());
294                                                 set_phase_delay(SCSI_PHASE_MESSAGE_IN, 1.0);
295                                                 break;
296                                                 
297                                         case SCSI_PHASE_MESSAGE_OUT:
298                                                 if((buffer->read() & 0xb8) == 0x80) {
299                                                         // identify, change to command phase
300                                                         memset(command, 0, sizeof(command));
301                                                         command_index = 0;
302                                                         set_phase_delay(SCSI_PHASE_COMMAND, 10.0);
303                                                 } else {
304                                                         // abort, change to bus free phase
305                                                         set_phase_delay(SCSI_PHASE_BUS_FREE, 10.0);
306                                                 }
307                                                 break;
308                                                 
309                                         case SCSI_PHASE_MESSAGE_IN:
310                                                 if(--remain > 0) {
311                                                         // request to read next data
312                                                         set_dat(buffer->read());
313                                                         set_req_delay(1, 1.0);
314                                                 } else {
315                                                         // change to bus free phase
316                                                         set_phase_delay(SCSI_PHASE_BUS_FREE, 1.0);
317                                                 }
318                                                 break;
319                                         }
320                                 }
321                         }
322                 }
323                 break;
324                 
325         case SIG_SCSI_RST:
326                 {
327                         bool prev_status = rst_status;
328                         rst_status = ((data & mask) != 0);
329                         
330                         if(!prev_status & rst_status) {
331                                 // L -> H
332                                 #ifdef _SCSI_DEBUG_LOG
333                                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] RST signal raised\n"), scsi_id);
334                                 #endif
335                                 reset_device();
336                                 set_phase(SCSI_PHASE_BUS_FREE);
337                         }
338                 }
339                 break;
340         }
341 }
342
343 void SCSI_DEV::event_callback(int event_id, int err)
344 {
345         switch(event_id) {
346         case EVENT_SEL:
347                 event_sel = -1;
348                 if((data_bus & 0x7f) == (1 << scsi_id)) {
349                         if(is_device_existing()) {
350                                 // this device is selected!
351                                 #ifdef _SCSI_DEBUG_LOG
352                                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] This device is selected\n"), scsi_id);
353                                 #endif
354                                 set_bsy(true);
355                                 selected = true;
356                         }
357                 }
358                 break;
359                 
360         case EVENT_PHASE:
361                 event_phase = -1;
362                 set_phase(next_phase);
363                 break;
364                 
365         case EVENT_REQ:
366                 event_req = -1;
367                 set_req(next_req);
368                 break;
369         }
370 }
371
372 void SCSI_DEV::set_phase(int value)
373 {
374         #ifdef _SCSI_DEBUG_LOG
375                 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Phase %s -> %s\n"), scsi_id, scsi_phase_name[phase], scsi_phase_name[value]);
376         #endif
377         if(event_phase != -1) {
378                 cancel_event(this, event_phase);
379                 event_phase = -1;
380         }
381         set_io (value & 1);
382         set_msg(value & 2);
383         set_cd (value & 4);
384         
385         if(value == SCSI_PHASE_BUS_FREE) {
386                 set_bsy(false);
387                 set_req(0);
388                 selected = false;
389         } else {
390                 first_req_clock = 0;
391 //              set_bsy(true);
392                 set_req_delay(1, 10.0);
393         }
394         phase = value;
395 }
396
397 void SCSI_DEV::set_phase_delay(int value, double usec)
398 {
399         if(usec <= 0.0) {
400                 set_phase(value);
401         } else {
402                 if(event_phase != -1) {
403                         cancel_event(this, event_phase);
404                         event_phase = -1;
405                 }
406                 register_event(this, EVENT_PHASE, usec, false, &event_phase);
407                 next_phase = value;
408         }
409 }
410
411 void SCSI_DEV::set_dat(int value)
412 {
413         #ifdef _SCSI_DEBUG_LOG
414 //              emu->force_out_debug_log(_T("[SCSI_DEV:ID=%d] DATA = %02x\n"), scsi_id, value);
415         #endif
416         write_signals(&outputs_dat, value);
417 }
418
419 void SCSI_DEV::set_bsy(int value)
420 {
421         #ifdef _SCSI_DEBUG_LOG
422 //              this->out_debug_log(_T("[SCSI_DEV:ID=%d] BUSY = %d\n"), scsi_id, value ? 1 : 0);
423         #endif
424         write_signals(&outputs_bsy, value ? 0xffffffff : 0);
425 }
426
427 void SCSI_DEV::set_cd(int value)
428 {
429         #ifdef _SCSI_DEBUG_LOG
430 //              this->out_debug_log(_T("[SCSI_DEV:ID=%d] C/D = %d\n"), scsi_id, value ? 1 : 0);
431         #endif
432         write_signals(&outputs_cd,  value ? 0xffffffff : 0);
433 }
434
435 void SCSI_DEV::set_io(int value)
436 {
437         #ifdef _SCSI_DEBUG_LOG
438 //              this->out_debug_log(_T("[SCSI_DEV:ID=%d] I/O = %d\n"), scsi_id, value ? 1 : 0);
439         #endif
440         write_signals(&outputs_io,  value ? 0xffffffff : 0);
441 }
442
443 void SCSI_DEV::set_msg(int value)
444 {
445         #ifdef _SCSI_DEBUG_LOG
446 //              this->out_debug_log(_T("[SCSI_DEV:ID=%d] MSG = %d\n"), scsi_id, value ? 1 : 0);
447         #endif
448         write_signals(&outputs_msg, value ? 0xffffffff : 0);
449 }
450
451 void SCSI_DEV::set_req(int value)
452 {
453         #ifdef _SCSI_DEBUG_LOG
454                 this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0);
455         #endif
456         if(event_req != -1) {
457                 cancel_event(this, event_req);
458                 event_req = -1;
459         }
460         if(value && first_req_clock == 0) {
461                 first_req_clock = get_current_clock();
462                 next_req_usec = 0.0;
463         }
464         write_signals(&outputs_req, value ? 0xffffffff : 0);
465 }
466
467 void SCSI_DEV::set_req_delay(int value, double usec)
468 {
469         if(usec <= 0.0) {
470                 set_req(value);
471         } else {
472                 if(event_req != -1) {
473                         cancel_event(this, event_req);
474                         event_req = -1;
475                 }
476                 register_event(this, EVENT_REQ, usec, false, &event_req);
477                 next_req = value;
478         }
479 }
480
481 int SCSI_DEV::get_command_length(int value)
482 {
483         switch((value >> 5) & 7) {
484         case 0:
485         case 3:
486         case 6:
487         case 7:
488                 return 6;
489         case 1:
490         case 2:
491                 return 10;
492         case 5:
493                 return 12;
494         }
495         return 6;
496 }
497
498 void SCSI_DEV::start_command()
499 {
500         switch(command[0]) {
501         case SCSI_CMD_TST_U_RDY:
502                 #ifdef _SCSI_DEBUG_LOG
503                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Test Unit Ready\n"), scsi_id);
504                 #endif
505                 // change to status phase
506                 if(!is_device_ready()) {
507                         set_dat(SCSI_STATUS_CHKCOND);
508                         set_sense_code(SCSI_SENSE_NOTREADY);
509                 } else {
510                         set_dat(SCSI_STATUS_GOOD);
511                         set_sense_code(SCSI_SENSE_NOSENSE);
512                 }
513                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
514                 break;
515                 
516         case SCSI_CMD_REQ_SENSE:
517                 #ifdef _SCSI_DEBUG_LOG
518                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Request Sense\n"), scsi_id);
519                 #endif
520                 // start position
521                 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
522                 position *= physical_block_size();
523                 // transfer length
524                 remain = 16;
525                 // create sense data table
526                 buffer->clear();
527                 buffer->write(SCSI_SERROR_CURRENT);
528                 buffer->write(0x00);
529                 buffer->write(is_device_ready() ? SCSI_KEY_NOSENSE : SCSI_KEY_UNITATT);
530                 buffer->write(0x00);
531                 buffer->write(0x00);
532                 buffer->write(0x00);
533                 buffer->write(0x00);
534                 buffer->write(0x08);
535                 buffer->write(0x00);
536                 buffer->write(0x00);
537                 buffer->write(0x00);
538                 buffer->write(0x00);
539                 buffer->write(0x00);
540                 buffer->write(0x00);
541                 buffer->write(0x00);
542                 buffer->write(0x00);
543                 // change to data in phase
544                 set_dat(buffer->read());
545                 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
546                 break;
547                 
548         case SCSI_CMD_INQUIRY:
549                 #ifdef _SCSI_DEBUG_LOG
550                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Inquiry\n"), scsi_id);
551                 #endif
552                 // start position
553                 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
554                 position *= physical_block_size();
555                 // transfer length
556                 remain = 32;
557                 // create inquiry data table
558                 buffer->clear();
559                 buffer->write(device_type);
560                 buffer->write(is_removable ? 0x80 : 0x00);
561                 buffer->write(0x02); // ANSI SCSI2
562                 buffer->write(0x01); // ANSI-CCS
563                 buffer->write(0x10);
564                 buffer->write(0x00);
565                 buffer->write(0x00);
566                 buffer->write(0x18);
567                 for(int i = 0; i < (int)strlen(vendor_id) && i < 8; i++) {
568                         buffer->write(vendor_id[i]);
569                 }
570                 for(int i = strlen(vendor_id); i < 8; i++) {
571                         buffer->write(0x20);
572                 }
573                 for(int i = 0; i < (int)strlen(product_id) && i < 16; i++) {
574                         buffer->write(vendor_id[i]);
575                 }
576                 for(int i = strlen(product_id); i < 16; i++) {
577                         buffer->write(0x20);
578                 }
579                 // change to data in phase
580                 set_dat(buffer->read());
581                 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
582                 break;
583                 
584         case SCSI_CMD_RD_CAPAC:
585                 #ifdef _SCSI_DEBUG_LOG
586                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read Capacity\n"), scsi_id);
587                 #endif
588                 // start position
589                 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
590                 position *= physical_block_size();
591                 // transfer length
592                 remain = 8;
593                 // create capacity data table
594                 buffer->clear();
595                 buffer->write((max_logical_block_addr() >> 24) & 0xff);
596                 buffer->write((max_logical_block_addr() >> 16) & 0xff);
597                 buffer->write((max_logical_block_addr() >>  8) & 0xff);
598                 buffer->write((max_logical_block_addr() >>  0) & 0xff);
599                 buffer->write((    logical_block_size() >> 24) & 0xff);
600                 buffer->write((    logical_block_size() >> 16) & 0xff);
601                 buffer->write((    logical_block_size() >>  8) & 0xff);
602                 buffer->write((    logical_block_size() >>  0) & 0xff);
603                 // change to data in phase
604                 set_dat(buffer->read());
605                 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
606                 break;
607                 
608         case SCSI_CMD_FORMAT:
609                 #ifdef _SCSI_DEBUG_LOG
610                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Format Unit\n"), scsi_id);
611                 #endif
612                 if(command[1] & 0x10) {
613                         // change to data out phase for extra bytes
614                         remain = 4;
615                         set_phase_delay(SCSI_PHASE_DATA_OUT, 10.0);
616                 } else {
617                         // no extra bytes, change to status phase
618                         set_dat(SCSI_STATUS_GOOD);
619                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
620                 }
621                 break;
622                 
623         case SCSI_CMD_RD_DEFECT:
624                 #ifdef _SCSI_DEBUG_LOG
625                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read Defect Data\n"), scsi_id);
626                 #endif
627                 // transfer length
628                 remain = 4;
629                 // create detect data table
630                 buffer->clear();
631                 buffer->write(0x00);
632                 buffer->write(command[2]);
633                 buffer->write(0x00); // msb of defect list length
634                 buffer->write(0x00); // lsb of defect list length
635                 // change to data in phase
636                 set_dat(buffer->read());
637                 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
638                 break;
639                 
640         case SCSI_CMD_READ6:
641                 #ifdef _SCSI_DEBUG_LOG
642                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 6-byte\n"), scsi_id);
643                 #endif
644                 // start position
645                 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
646                 position *= physical_block_size();
647                 // transfer length
648                 remain = command[4] * logical_block_size();
649                 if(remain != 0) {
650                         // read data buffer
651                         buffer->clear();
652                         int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
653                         if(!read_buffer(length)) {
654                                 // change to status phase
655                                 set_dat(SCSI_STATUS_CHKCOND);
656                                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
657                                 break;
658                         }
659                         // change to data in phase
660                         set_dat(buffer->read());
661                         set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
662                 } else {
663                         // transfer length is zero, change to status phase
664                         set_dat(SCSI_STATUS_GOOD);
665                         set_sense_code(SCSI_SENSE_NOSENSE);
666                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
667                 }
668                 break;
669                 
670         case SCSI_CMD_WRITE6:
671                 #ifdef _SCSI_DEBUG_LOG
672                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 6-Byte\n"), scsi_id);
673                 #endif
674                 // start position
675                 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
676                 position *= physical_block_size();
677                 // transfer length
678                 remain = command[4] * logical_block_size();
679                 if(remain != 0) {
680                         // clear data buffer
681                         buffer->clear();
682                         // change to data in phase
683                         set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
684                 } else {
685                         // transfer length is zero, change to status phase
686                         set_dat(SCSI_STATUS_GOOD);
687                         set_sense_code(SCSI_SENSE_NOSENSE);
688                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
689                 }
690                 break;
691                 
692         case SCSI_CMD_READ10:
693                 #ifdef _SCSI_DEBUG_LOG
694                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 10-byte\n"), scsi_id);
695                 #endif
696                 // start position
697                 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
698                 position *= physical_block_size();
699                 // transfer length
700                 remain = command[7] * 0x100 + command[8];
701                 remain *= logical_block_size();
702                 if(remain != 0) {
703                         // read data buffer
704                         buffer->clear();
705                         int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
706                         if(!read_buffer(length)) {
707                                 // change to status phase
708                                 set_dat(SCSI_STATUS_CHKCOND);
709                                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
710                                 break;
711                         }
712                         // change to data in phase
713                         set_dat(buffer->read());
714                         set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
715                 } else {
716                         // transfer length is zero, change to status phase
717                         set_dat(SCSI_STATUS_GOOD);
718                         set_sense_code(SCSI_SENSE_NOSENSE);
719                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
720                 }
721                 break;
722                 
723         case SCSI_CMD_WRITE10:
724                 #ifdef _SCSI_DEBUG_LOG
725                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 10-Byte\n"), scsi_id);
726                 #endif
727                 goto WRITE10;
728         case SCSI_CMD_WRT_VERIFY:
729                 #ifdef _SCSI_DEBUG_LOG
730                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write and Verify\n"), scsi_id);
731                 #endif
732         WRITE10:
733                 // start position
734                 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
735                 position *= physical_block_size();
736                 // transfer length
737                 remain = command[7] * 0x100 + command[8];
738                 remain *= logical_block_size();
739                 if(remain != 0) {
740                         // clear data buffer
741                         buffer->clear();
742                         // change to data in phase
743                         set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
744                 } else {
745                         // transfer length is zero, change to status phase
746                         set_dat(SCSI_STATUS_GOOD);
747                         set_sense_code(SCSI_SENSE_NOSENSE);
748                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
749                 }
750                 break;
751                 
752         case SCSI_CMD_READ12:
753                 #ifdef _SCSI_DEBUG_LOG
754                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 12-byte\n"), scsi_id);
755                 #endif
756                 // start position
757                 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
758                 position *= physical_block_size();
759                 // transfer length
760                 remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9];
761                 remain *= logical_block_size();
762                 if(remain != 0) {
763                         // read data buffer
764                         buffer->clear();
765                         int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
766                         if(!read_buffer(length)) {
767                                 // change to status phase
768                                 set_dat(SCSI_STATUS_CHKCOND);
769                                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
770                                 break;
771                         }
772                         // change to data in phase
773                         set_dat(buffer->read());
774                         set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
775                 } else {
776                         // transfer length is zero, change to status phase
777                         set_dat(SCSI_STATUS_GOOD);
778                         set_sense_code(SCSI_SENSE_NOSENSE);
779                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
780                 }
781                 break;
782                 
783         case SCSI_CMD_WRITE12:
784                 #ifdef _SCSI_DEBUG_LOG
785                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 12-Byte\n"), scsi_id);
786                 #endif
787                 // start position
788                 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
789                 position *= physical_block_size();
790                 // transfer length
791                 remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9];
792                 remain *= logical_block_size();
793                 if(remain != 0) {
794                         // clear data buffer
795                         buffer->clear();
796                         // change to data in phase
797                         set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
798                 } else {
799                         // transfer length is zero, change to status phase
800                         set_dat(SCSI_STATUS_GOOD);
801                         set_sense_code(SCSI_SENSE_NOSENSE);
802                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
803                 }
804                 break;
805                 
806         default:
807                 #ifdef _SCSI_DEBUG_LOG
808                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Unknown %02X\n"), scsi_id, command[0]);
809                 #endif
810                 set_dat(SCSI_STATUS_GOOD);
811                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
812         }
813 }
814
815 bool SCSI_DEV::read_buffer(int length)
816 {
817         for(int i = 0; i < length; i++) {
818                 buffer->write(0);
819                 position++;
820         }
821         set_sense_code(SCSI_SENSE_NOSENSE);
822         return true;
823 }
824
825 bool SCSI_DEV::write_buffer(int length)
826 {
827         for(int i = 0; i < length; i++) {
828                 buffer->read();
829                 position++;
830         }
831         set_sense_code(SCSI_SENSE_NOSENSE);
832         return true;
833 }
834
835 #define STATE_VERSION   2
836
837 bool SCSI_DEV::process_state(FILEIO* state_fio, bool loading)
838 {
839         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
840                 return false;
841         }
842         if(!state_fio->StateCheckInt32(this_device_id)) {
843                 return false;
844         }
845         state_fio->StateValue(data_bus);
846         state_fio->StateValue(sel_status);
847         state_fio->StateValue(atn_status);
848         state_fio->StateValue(ack_status);
849         state_fio->StateValue(rst_status);
850         state_fio->StateValue(selected);
851         state_fio->StateValue(atn_pending);
852         state_fio->StateValue(phase);
853         state_fio->StateValue(next_phase);
854         state_fio->StateValue(next_req);
855         state_fio->StateValue(event_sel);
856         state_fio->StateValue(event_phase);
857         state_fio->StateValue(event_req);
858         state_fio->StateValue(first_req_clock);
859         state_fio->StateValue(next_req_usec);
860         state_fio->StateArray(command, sizeof(command), 1);
861         state_fio->StateValue(command_index);
862         if(!buffer->process_state((void *)state_fio, loading)) {
863                 return false;
864         }
865         state_fio->StateValue(position);
866         state_fio->StateValue(remain);
867         state_fio->StateValue(sense_code);
868         return true;
869 }