OSDN Git Service

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