OSDN Git Service

[General] Merge Upstream 2018-12-18.
[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                                                         // flush buffer
184                                                         if(buffer->full()) {
185                                                                 if(!write_buffer(buffer->count())) {
186                                                                         // change to status phase
187                                                                         set_dat(SCSI_STATUS_CHKCOND);
188                                                                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
189                                                                         break;
190                                                                 }
191                                                                 buffer->clear(); // just in case
192                                                         }
193                                                         switch(command[0]) {
194                                                         case SCSI_CMD_WRITE6:
195                                                         case SCSI_CMD_WRITE10:
196                                                         case SCSI_CMD_WRITE12:
197                                                                 // request to write next data
198                                                                 {
199                                                                         next_req_usec += 1000000.0 / bytes_per_sec;
200                                                                         double usec = next_req_usec - get_passed_usec(first_req_clock);
201                                                                         set_req_delay(1, (usec > 1.0) ? usec : 1.0);
202                                                                 }
203                                                                 break;
204                                                         default:
205                                                                 // request to write next data
206                                                                 set_req_delay(1, 1.0);
207                                                                 break;
208                                                         }
209                                                 } else {
210                                                         // flush buffer
211                                                         if(!buffer->empty()) {
212                                                                 if(!write_buffer(buffer->count())) {
213                                                                         // change to status phase
214                                                                         set_dat(SCSI_STATUS_CHKCOND);
215                                                                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
216                                                                         break;
217                                                                 }
218                                                                 buffer->clear(); // just in case
219                                                         }
220                                                         // change to status phase
221                                                         set_dat(SCSI_STATUS_GOOD);
222                                                         set_sense_code(SCSI_SENSE_NOSENSE);
223                                                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
224                                                 }
225                                                 break;
226                                                 
227                                         case SCSI_PHASE_DATA_IN:
228                                                 if(--remain > 0) {
229                                                         // update buffer
230                                                         if(buffer->count() == 0) {
231                                                                 int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
232                                                                 if(!read_buffer(length)) {
233                                                                         // change to status phase
234                                                                         set_dat(SCSI_STATUS_CHKCOND);
235                                                                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
236                                                                         break;
237                                                                 }
238                                                         }
239                                                         // request to read next data
240                                                         set_dat(buffer->read());
241                                                         switch(command[0]) {
242                                                         case SCSI_CMD_READ6:
243                                                         case SCSI_CMD_READ10:
244                                                         case SCSI_CMD_READ12:
245                                                                 {
246                                                                         next_req_usec += 1000000.0 / bytes_per_sec;
247                                                                         double usec = next_req_usec - get_passed_usec(first_req_clock);
248                                                                         set_req_delay(1, (usec > 1.0) ? usec : 1.0);
249                                                                 }
250                                                                 break;
251                                                         default:
252                                                                 set_req_delay(1, 1.0);
253                                                                 break;
254                                                         }
255                                                 } else {
256                                                         // change to status phase
257                                                         set_dat(SCSI_STATUS_GOOD);
258                                                         set_sense_code(SCSI_SENSE_NOSENSE);
259                                                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
260                                                 }
261                                                 break;
262                                                 
263                                         case SCSI_PHASE_COMMAND:
264                                                 if(command_index < get_command_length(command[0])) {
265                                                         // request next command
266                                                         set_req_delay(1, 1.0);
267                                                 } else {
268                                                         // start command
269                                                         start_command();
270                                                 }
271                                                 break;
272                                                 
273                                         case SCSI_PHASE_STATUS:
274                                                 // create message data table
275                                                 remain = 1;
276                                                 buffer->clear();
277                                                 buffer->write(0x00); // command complete message
278                                                 // change to message in phase
279                                                 set_dat(buffer->read());
280                                                 set_phase_delay(SCSI_PHASE_MESSAGE_IN, 1.0);
281                                                 break;
282                                                 
283                                         case SCSI_PHASE_MESSAGE_OUT:
284                                                 if((buffer->read() & 0xb8) == 0x80) {
285                                                         // identify, change to command phase
286                                                         memset(command, 0, sizeof(command));
287                                                         command_index = 0;
288                                                         set_phase_delay(SCSI_PHASE_COMMAND, 10.0);
289                                                 } else {
290                                                         // abort, change to bus free phase
291                                                         set_phase_delay(SCSI_PHASE_BUS_FREE, 10.0);
292                                                 }
293                                                 break;
294                                                 
295                                         case SCSI_PHASE_MESSAGE_IN:
296                                                 if(--remain > 0) {
297                                                         // request to read next data
298                                                         set_dat(buffer->read());
299                                                         set_req_delay(1, 1.0);
300                                                 } else {
301                                                         // change to bus free phase
302                                                         set_phase_delay(SCSI_PHASE_BUS_FREE, 1.0);
303                                                 }
304                                                 break;
305                                         }
306                                 }
307                         }
308                 }
309                 break;
310                 
311         case SIG_SCSI_RST:
312                 {
313                         bool prev_status = rst_status;
314                         rst_status = ((data & mask) != 0);
315                         
316                         if(!prev_status & rst_status) {
317                                 // L -> H
318                                 #ifdef _SCSI_DEBUG_LOG
319                                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] RST signal raised\n"), scsi_id);
320                                 #endif
321                                 reset_device();
322                                 set_phase(SCSI_PHASE_BUS_FREE);
323                         }
324                 }
325                 break;
326         }
327 }
328
329 void SCSI_DEV::event_callback(int event_id, int err)
330 {
331         switch(event_id) {
332         case EVENT_SEL:
333                 event_sel = -1;
334                 if((data_bus & 0x7f) == (1 << scsi_id)) {
335                         if(is_device_existing()) {
336                                 // this device is selected!
337                                 #ifdef _SCSI_DEBUG_LOG
338                                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] This device is selected\n"), scsi_id);
339                                 #endif
340                                 set_bsy(true);
341                                 selected = true;
342                         }
343                 }
344                 break;
345                 
346         case EVENT_PHASE:
347                 event_phase = -1;
348                 set_phase(next_phase);
349                 break;
350                 
351         case EVENT_REQ:
352                 event_req = -1;
353                 set_req(next_req);
354                 break;
355         }
356 }
357
358 void SCSI_DEV::set_phase(int value)
359 {
360         #ifdef _SCSI_DEBUG_LOG
361                 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Phase %s -> %s\n"), scsi_id, scsi_phase_name[phase], scsi_phase_name[value]);
362         #endif
363         if(event_phase != -1) {
364                 cancel_event(this, event_phase);
365                 event_phase = -1;
366         }
367         set_io (value & 1);
368         set_msg(value & 2);
369         set_cd (value & 4);
370         
371         if(value == SCSI_PHASE_BUS_FREE) {
372                 set_bsy(false);
373                 set_req(0);
374                 selected = false;
375         } else {
376                 first_req_clock = 0;
377 //              set_bsy(true);
378                 set_req_delay(1, 10.0);
379         }
380         phase = value;
381 }
382
383 void SCSI_DEV::set_phase_delay(int value, double usec)
384 {
385         if(usec <= 0.0) {
386                 set_phase(value);
387         } else {
388                 if(event_phase != -1) {
389                         cancel_event(this, event_phase);
390                         event_phase = -1;
391                 }
392                 register_event(this, EVENT_PHASE, usec, false, &event_phase);
393                 next_phase = value;
394         }
395 }
396
397 void SCSI_DEV::set_dat(int value)
398 {
399         #ifdef _SCSI_DEBUG_LOG
400 //              emu->force_out_debug_log(_T("[SCSI_DEV:ID=%d] DATA = %02x\n"), scsi_id, value);
401         #endif
402         write_signals(&outputs_dat, value);
403 }
404
405 void SCSI_DEV::set_bsy(int value)
406 {
407         #ifdef _SCSI_DEBUG_LOG
408 //              this->out_debug_log(_T("[SCSI_DEV:ID=%d] BUSY = %d\n"), scsi_id, value ? 1 : 0);
409         #endif
410         write_signals(&outputs_bsy, value ? 0xffffffff : 0);
411 }
412
413 void SCSI_DEV::set_cd(int value)
414 {
415         #ifdef _SCSI_DEBUG_LOG
416 //              this->out_debug_log(_T("[SCSI_DEV:ID=%d] C/D = %d\n"), scsi_id, value ? 1 : 0);
417         #endif
418         write_signals(&outputs_cd,  value ? 0xffffffff : 0);
419 }
420
421 void SCSI_DEV::set_io(int value)
422 {
423         #ifdef _SCSI_DEBUG_LOG
424 //              this->out_debug_log(_T("[SCSI_DEV:ID=%d] I/O = %d\n"), scsi_id, value ? 1 : 0);
425         #endif
426         write_signals(&outputs_io,  value ? 0xffffffff : 0);
427 }
428
429 void SCSI_DEV::set_msg(int value)
430 {
431         #ifdef _SCSI_DEBUG_LOG
432 //              this->out_debug_log(_T("[SCSI_DEV:ID=%d] MSG = %d\n"), scsi_id, value ? 1 : 0);
433         #endif
434         write_signals(&outputs_msg, value ? 0xffffffff : 0);
435 }
436
437 void SCSI_DEV::set_req(int value)
438 {
439         #ifdef _SCSI_DEBUG_LOG
440 //              this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0);
441         #endif
442         if(event_req != -1) {
443                 cancel_event(this, event_req);
444                 event_req = -1;
445         }
446         if(value && first_req_clock == 0) {
447                 first_req_clock = get_current_clock();
448                 next_req_usec = 0.0;
449         }
450         write_signals(&outputs_req, value ? 0xffffffff : 0);
451 }
452
453 void SCSI_DEV::set_req_delay(int value, double usec)
454 {
455         if(usec <= 0.0) {
456                 set_req(value);
457         } else {
458                 if(event_req != -1) {
459                         cancel_event(this, event_req);
460                         event_req = -1;
461                 }
462                 register_event(this, EVENT_REQ, usec, false, &event_req);
463                 next_req = value;
464         }
465 }
466
467 int SCSI_DEV::get_command_length(int value)
468 {
469         switch((value >> 5) & 7) {
470         case 0:
471         case 3:
472         case 6:
473         case 7:
474                 return 6;
475         case 1:
476         case 2:
477                 return 10;
478         case 5:
479                 return 12;
480         }
481         return 6;
482 }
483
484 void SCSI_DEV::start_command()
485 {
486         switch(command[0]) {
487         case SCSI_CMD_TST_U_RDY:
488                 #ifdef _SCSI_DEBUG_LOG
489                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Test Unit Ready\n"), scsi_id);
490                 #endif
491                 // change to status phase
492                 if(!is_device_ready()) {
493                         set_dat(SCSI_STATUS_CHKCOND);
494                         set_sense_code(SCSI_SENSE_NOTREADY);
495                 } else {
496                         set_dat(SCSI_STATUS_GOOD);
497                         set_sense_code(SCSI_SENSE_NOSENSE);
498                 }
499                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
500                 break;
501                 
502         case SCSI_CMD_REQ_SENSE:
503                 #ifdef _SCSI_DEBUG_LOG
504                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Request Sense\n"), scsi_id);
505                 #endif
506                 // start position
507                 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
508                 position *= physical_block_size();
509                 // transfer length
510 //              remain = 16;
511                 remain = command[4];
512                 // create sense data table
513                 buffer->clear();
514                 for(int i = 0; i < remain; i++) {
515                         int value = 0;
516                         switch(i) {
517                         case 0: value = SCSI_SERROR_CURRENT; break;
518                         case 2: value = is_device_ready() ? SCSI_KEY_NOSENSE : SCSI_KEY_UNITATT; break;
519                         case 7: value = 0x08; break;
520                         }
521                         buffer->write(value);
522                 }
523                 // change to data in phase
524                 set_dat(buffer->read());
525                 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
526                 break;
527                 
528         case SCSI_CMD_INQUIRY:
529                 #ifdef _SCSI_DEBUG_LOG
530                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Inquiry\n"), scsi_id);
531                 #endif
532                 // start position
533                 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
534                 position *= physical_block_size();
535                 // transfer length
536                 remain = 32;
537                 // create inquiry data table
538                 buffer->clear();
539                 buffer->write(device_type);
540                 buffer->write(is_removable ? 0x80 : 0x00);
541                 buffer->write(0x02); // ANSI SCSI2
542                 buffer->write(0x01); // ANSI-CCS
543                 buffer->write(0x10);
544                 buffer->write(0x00);
545                 buffer->write(0x00);
546                 buffer->write(0x18);
547                 for(int i = 0; i < (int)strlen(vendor_id) && i < 8; i++) {
548                         buffer->write(vendor_id[i]);
549                 }
550                 for(int i = strlen(vendor_id); i < 8; i++) {
551                         buffer->write(0x20);
552                 }
553                 for(int i = 0; i < (int)strlen(product_id) && i < 16; i++) {
554                         buffer->write(vendor_id[i]);
555                 }
556                 for(int i = strlen(product_id); i < 16; i++) {
557                         buffer->write(0x20);
558                 }
559                 // change to data in phase
560                 set_dat(buffer->read());
561                 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
562                 break;
563                 
564         case SCSI_CMD_RD_CAPAC:
565                 #ifdef _SCSI_DEBUG_LOG
566                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read Capacity\n"), scsi_id);
567                 #endif
568                 // start position
569                 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
570                 position *= physical_block_size();
571                 // transfer length
572                 remain = 8;
573                 // create capacity data table
574                 buffer->clear();
575                 buffer->write((max_logical_block_addr() >> 24) & 0xff);
576                 buffer->write((max_logical_block_addr() >> 16) & 0xff);
577                 buffer->write((max_logical_block_addr() >>  8) & 0xff);
578                 buffer->write((max_logical_block_addr() >>  0) & 0xff);
579                 buffer->write((    logical_block_size() >> 24) & 0xff);
580                 buffer->write((    logical_block_size() >> 16) & 0xff);
581                 buffer->write((    logical_block_size() >>  8) & 0xff);
582                 buffer->write((    logical_block_size() >>  0) & 0xff);
583                 // change to data in phase
584                 set_dat(buffer->read());
585                 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
586                 break;
587                 
588         case SCSI_CMD_FORMAT:
589                 #ifdef _SCSI_DEBUG_LOG
590                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Format Unit\n"), scsi_id);
591                 #endif
592                 if(command[1] & 0x10) {
593                         // change to data out phase for extra bytes
594                         remain = 4;
595                         set_phase_delay(SCSI_PHASE_DATA_OUT, 10.0);
596                 } else {
597                         // no extra bytes, change to status phase
598                         set_dat(SCSI_STATUS_GOOD);
599                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
600                 }
601                 break;
602                 
603         case SCSI_CMD_RD_DEFECT:
604                 #ifdef _SCSI_DEBUG_LOG
605                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read Defect Data\n"), scsi_id);
606                 #endif
607                 // transfer length
608                 remain = 4;
609                 // create detect data table
610                 buffer->clear();
611                 buffer->write(0x00);
612                 buffer->write(command[2]);
613                 buffer->write(0x00); // msb of defect list length
614                 buffer->write(0x00); // lsb of defect list length
615                 // change to data in phase
616                 set_dat(buffer->read());
617                 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
618                 break;
619                 
620         case SCSI_CMD_READ6:
621                 #ifdef _SCSI_DEBUG_LOG
622                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 6-byte\n"), scsi_id);
623                 #endif
624                 // start position
625                 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
626                 position *= physical_block_size();
627                 // transfer length
628                 remain = command[4] * logical_block_size();
629                 if(remain != 0) {
630                         // read data buffer
631                         buffer->clear();
632                         int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
633                         if(!read_buffer(length)) {
634                                 // change to status phase
635                                 set_dat(SCSI_STATUS_CHKCOND);
636                                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
637                                 break;
638                         }
639                         // change to data in phase
640                         set_dat(buffer->read());
641                         set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
642                 } else {
643                         // transfer length is zero, change to status phase
644                         set_dat(SCSI_STATUS_GOOD);
645                         set_sense_code(SCSI_SENSE_NOSENSE);
646                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
647                 }
648                 break;
649                 
650         case SCSI_CMD_WRITE6:
651                 #ifdef _SCSI_DEBUG_LOG
652                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 6-Byte\n"), scsi_id);
653                 #endif
654                 // start position
655                 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
656                 position *= physical_block_size();
657                 // transfer length
658                 remain = command[4] * logical_block_size();
659                 if(remain != 0) {
660                         // clear data buffer
661                         buffer->clear();
662                         // change to data in phase
663                         set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
664                 } else {
665                         // transfer length is zero, change to status phase
666                         set_dat(SCSI_STATUS_GOOD);
667                         set_sense_code(SCSI_SENSE_NOSENSE);
668                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
669                 }
670                 break;
671                 
672         case SCSI_CMD_READ10:
673                 #ifdef _SCSI_DEBUG_LOG
674                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 10-byte\n"), scsi_id);
675                 #endif
676                 // start position
677                 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
678                 position *= physical_block_size();
679                 // transfer length
680                 remain = command[7] * 0x100 + command[8];
681                 remain *= logical_block_size();
682                 if(remain != 0) {
683                         // read data buffer
684                         buffer->clear();
685                         int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
686                         if(!read_buffer(length)) {
687                                 // change to status phase
688                                 set_dat(SCSI_STATUS_CHKCOND);
689                                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
690                                 break;
691                         }
692                         // change to data in phase
693                         set_dat(buffer->read());
694                         set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
695                 } else {
696                         // transfer length is zero, change to status phase
697                         set_dat(SCSI_STATUS_GOOD);
698                         set_sense_code(SCSI_SENSE_NOSENSE);
699                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
700                 }
701                 break;
702                 
703         case SCSI_CMD_WRITE10:
704                 #ifdef _SCSI_DEBUG_LOG
705                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 10-Byte\n"), scsi_id);
706                 #endif
707                 goto WRITE10;
708         case SCSI_CMD_WRT_VERIFY:
709                 #ifdef _SCSI_DEBUG_LOG
710                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write and Verify\n"), scsi_id);
711                 #endif
712         WRITE10:
713                 // start position
714                 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
715                 position *= physical_block_size();
716                 // transfer length
717                 remain = command[7] * 0x100 + command[8];
718                 remain *= logical_block_size();
719                 if(remain != 0) {
720                         // clear data buffer
721                         buffer->clear();
722                         // change to data in phase
723                         set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
724                 } else {
725                         // transfer length is zero, change to status phase
726                         set_dat(SCSI_STATUS_GOOD);
727                         set_sense_code(SCSI_SENSE_NOSENSE);
728                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
729                 }
730                 break;
731                 
732         case SCSI_CMD_READ12:
733                 #ifdef _SCSI_DEBUG_LOG
734                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 12-byte\n"), scsi_id);
735                 #endif
736                 // start position
737                 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
738                 position *= physical_block_size();
739                 // transfer length
740                 remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9];
741                 remain *= logical_block_size();
742                 if(remain != 0) {
743                         // read data buffer
744                         buffer->clear();
745                         int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
746                         if(!read_buffer(length)) {
747                                 // change to status phase
748                                 set_dat(SCSI_STATUS_CHKCOND);
749                                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
750                                 break;
751                         }
752                         // change to data in phase
753                         set_dat(buffer->read());
754                         set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
755                 } else {
756                         // transfer length is zero, change to status phase
757                         set_dat(SCSI_STATUS_GOOD);
758                         set_sense_code(SCSI_SENSE_NOSENSE);
759                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
760                 }
761                 break;
762                 
763         case SCSI_CMD_WRITE12:
764                 #ifdef _SCSI_DEBUG_LOG
765                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 12-Byte\n"), scsi_id);
766                 #endif
767                 // start position
768                 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
769                 position *= physical_block_size();
770                 // transfer length
771                 remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9];
772                 remain *= logical_block_size();
773                 if(remain != 0) {
774                         // clear data buffer
775                         buffer->clear();
776                         // change to data in phase
777                         set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
778                 } else {
779                         // transfer length is zero, change to status phase
780                         set_dat(SCSI_STATUS_GOOD);
781                         set_sense_code(SCSI_SENSE_NOSENSE);
782                         set_phase_delay(SCSI_PHASE_STATUS, 10.0);
783                 }
784                 break;
785                 
786         default:
787                 #ifdef _SCSI_DEBUG_LOG
788                         this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Unknown %02X\n"), scsi_id, command[0]);
789                 #endif
790                 set_dat(SCSI_STATUS_GOOD);
791                 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
792         }
793 }
794
795 bool SCSI_DEV::read_buffer(int length)
796 {
797         for(int i = 0; i < length; i++) {
798                 buffer->write(0);
799                 position++;
800         }
801         set_sense_code(SCSI_SENSE_NOSENSE);
802         return true;
803 }
804
805 bool SCSI_DEV::write_buffer(int length)
806 {
807         for(int i = 0; i < length; i++) {
808                 buffer->read();
809                 position++;
810         }
811         set_sense_code(SCSI_SENSE_NOSENSE);
812         return true;
813 }
814
815 #define STATE_VERSION   2
816
817 bool SCSI_DEV::process_state(FILEIO* state_fio, bool loading)
818 {
819         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
820                 return false;
821         }
822         if(!state_fio->StateCheckInt32(this_device_id)) {
823                 return false;
824         }
825         state_fio->StateValue(data_bus);
826         state_fio->StateValue(sel_status);
827         state_fio->StateValue(atn_status);
828         state_fio->StateValue(ack_status);
829         state_fio->StateValue(rst_status);
830         state_fio->StateValue(selected);
831         state_fio->StateValue(atn_pending);
832         state_fio->StateValue(phase);
833         state_fio->StateValue(next_phase);
834         state_fio->StateValue(next_req);
835         state_fio->StateValue(event_sel);
836         state_fio->StateValue(event_phase);
837         state_fio->StateValue(event_req);
838         state_fio->StateValue(first_req_clock);
839         state_fio->StateValue(next_req_usec);
840         state_fio->StateArray(command, sizeof(command), 1);
841         state_fio->StateValue(command_index);
842         if(!buffer->process_state((void *)state_fio, loading)) {
843                 return false;
844         }
845         state_fio->StateValue(position);
846         state_fio->StateValue(remain);
847         state_fio->StateValue(sense_code);
848         return true;
849 }