2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
16 //#define _SCSI_DEBUG_LOG
18 void SCSI_DEV::initialize()
21 buffer = new FIFO(SCSI_BUFFER_SIZE);
22 phase = SCSI_PHASE_BUS_FREE;
25 void SCSI_DEV::release()
31 void SCSI_DEV::reset()
34 sel_status = atn_status = ack_status = rst_status = false;
35 selected = atn_pending = false;
37 event_sel = event_phase = event_req = -1;
38 set_phase(SCSI_PHASE_BUS_FREE);
39 set_sense_code(SCSI_SENSE_NOSENSE);
42 void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask)
46 data_bus = data & mask;
51 bool prev_status = sel_status;
52 sel_status = ((data & mask) != 0);
54 if(phase != SCSI_PHASE_BUS_FREE) {
55 // this device is already selected
56 } else if(!prev_status && sel_status) {
58 #ifdef SCSI_DEV_IMMEDIATE_SELECT
59 event_callback(EVENT_SEL, 0);
62 cancel_event(this, event_sel);
64 register_event(this, EVENT_SEL, 20.0, false, &event_sel);
66 } else if(prev_status && !sel_status) {
69 cancel_event(this, event_sel);
74 // change to message out phase
76 set_phase_delay(SCSI_PHASE_MESSAGE_OUT, 10.0);
77 // set_phase(SCSI_PHASE_MESSAGE_OUT);
79 // change to command phase
80 memset(command, 0, sizeof(command));
82 set_phase_delay(SCSI_PHASE_COMMAND, 10.0);
83 // set_phase(SCSI_PHASE_COMMAND);
92 bool prev_status = atn_status;
93 atn_status = ((data & mask) != 0);
95 if(phase == SCSI_PHASE_BUS_FREE) {
96 // this device is not selected
97 } else if(!prev_status && atn_status) {
99 #ifdef _SCSI_DEBUG_LOG
100 this->out_debug_log(_T("[SCSI_DEV:ID=%d] ATN signal raised\n"), scsi_id);
103 // wait until ack=off
106 // change to message out phase
109 set_phase_delay(SCSI_PHASE_MESSAGE_OUT, 10.0);
118 initiator ---> device
131 initiator <--- device
144 bool prev_status = ack_status;
145 ack_status = ((data & mask) != 0);
147 if(phase == SCSI_PHASE_BUS_FREE) {
148 // this device is not selected
149 } else if(!prev_status & ack_status) {
152 case SCSI_PHASE_DATA_OUT:
153 buffer->write(data_bus);
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);
163 case SCSI_PHASE_COMMAND:
164 command[command_index++] = data_bus;
167 case SCSI_PHASE_MESSAGE_OUT:
168 buffer->write(data_bus);
171 set_req_delay(0, 0.1);
172 } else if(prev_status && !ack_status) {
175 // change to message out phase
178 set_phase_delay(SCSI_PHASE_MESSAGE_OUT, 10.0);
181 case SCSI_PHASE_DATA_OUT:
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);
191 buffer->clear(); // just in case
194 case SCSI_CMD_WRITE6:
195 case SCSI_CMD_WRITE10:
196 case SCSI_CMD_WRITE12:
197 // request to write next data
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);
205 // request to write next data
206 set_req_delay(1, 1.0);
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);
218 buffer->clear(); // just in case
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);
227 case SCSI_PHASE_DATA_IN:
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);
239 // request to read next data
240 set_dat(buffer->read());
243 case SCSI_CMD_READ10:
244 case SCSI_CMD_READ12:
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);
252 set_req_delay(1, 1.0);
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);
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);
273 case SCSI_PHASE_STATUS:
274 // create message data table
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);
283 case SCSI_PHASE_MESSAGE_OUT:
284 if((buffer->read() & 0xb8) == 0x80) {
285 // identify, change to command phase
286 memset(command, 0, sizeof(command));
288 set_phase_delay(SCSI_PHASE_COMMAND, 10.0);
290 // abort, change to bus free phase
291 set_phase_delay(SCSI_PHASE_BUS_FREE, 10.0);
295 case SCSI_PHASE_MESSAGE_IN:
297 // request to read next data
298 set_dat(buffer->read());
299 set_req_delay(1, 1.0);
301 // change to bus free phase
302 set_phase_delay(SCSI_PHASE_BUS_FREE, 1.0);
313 bool prev_status = rst_status;
314 rst_status = ((data & mask) != 0);
316 if(!prev_status & rst_status) {
318 #ifdef _SCSI_DEBUG_LOG
319 this->out_debug_log(_T("[SCSI_DEV:ID=%d] RST signal raised\n"), scsi_id);
322 set_phase(SCSI_PHASE_BUS_FREE);
329 void SCSI_DEV::event_callback(int event_id, int err)
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);
348 set_phase(next_phase);
358 void SCSI_DEV::set_phase(int value)
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]);
363 if(event_phase != -1) {
364 cancel_event(this, event_phase);
371 if(value == SCSI_PHASE_BUS_FREE) {
378 set_req_delay(1, 10.0);
383 void SCSI_DEV::set_phase_delay(int value, double usec)
388 if(event_phase != -1) {
389 cancel_event(this, event_phase);
392 register_event(this, EVENT_PHASE, usec, false, &event_phase);
397 void SCSI_DEV::set_dat(int value)
399 #ifdef _SCSI_DEBUG_LOG
400 // emu->force_out_debug_log(_T("[SCSI_DEV:ID=%d] DATA = %02x\n"), scsi_id, value);
402 write_signals(&outputs_dat, value);
405 void SCSI_DEV::set_bsy(int value)
407 #ifdef _SCSI_DEBUG_LOG
408 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] BUSY = %d\n"), scsi_id, value ? 1 : 0);
410 write_signals(&outputs_bsy, value ? 0xffffffff : 0);
413 void SCSI_DEV::set_cd(int value)
415 #ifdef _SCSI_DEBUG_LOG
416 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] C/D = %d\n"), scsi_id, value ? 1 : 0);
418 write_signals(&outputs_cd, value ? 0xffffffff : 0);
421 void SCSI_DEV::set_io(int value)
423 #ifdef _SCSI_DEBUG_LOG
424 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] I/O = %d\n"), scsi_id, value ? 1 : 0);
426 write_signals(&outputs_io, value ? 0xffffffff : 0);
429 void SCSI_DEV::set_msg(int value)
431 #ifdef _SCSI_DEBUG_LOG
432 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] MSG = %d\n"), scsi_id, value ? 1 : 0);
434 write_signals(&outputs_msg, value ? 0xffffffff : 0);
437 void SCSI_DEV::set_req(int value)
439 #ifdef _SCSI_DEBUG_LOG
440 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0);
442 if(event_req != -1) {
443 cancel_event(this, event_req);
446 if(value && first_req_clock == 0) {
447 first_req_clock = get_current_clock();
450 write_signals(&outputs_req, value ? 0xffffffff : 0);
453 void SCSI_DEV::set_req_delay(int value, double usec)
458 if(event_req != -1) {
459 cancel_event(this, event_req);
462 register_event(this, EVENT_REQ, usec, false, &event_req);
467 int SCSI_DEV::get_command_length(int value)
469 switch((value >> 5) & 7) {
484 void SCSI_DEV::start_command()
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);
491 // change to status phase
492 if(!is_device_ready()) {
493 set_dat(SCSI_STATUS_CHKCOND);
494 set_sense_code(SCSI_SENSE_NOTREADY);
496 set_dat(SCSI_STATUS_GOOD);
497 set_sense_code(SCSI_SENSE_NOSENSE);
499 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
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);
507 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
508 position *= physical_block_size();
512 // create sense data table
514 for(int i = 0; i < remain; 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;
521 buffer->write(value);
523 // change to data in phase
524 set_dat(buffer->read());
525 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
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);
533 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
534 position *= physical_block_size();
537 // create inquiry data table
539 buffer->write(device_type);
540 buffer->write(is_removable ? 0x80 : 0x00);
541 buffer->write(0x02); // ANSI SCSI2
542 buffer->write(0x01); // ANSI-CCS
547 for(int i = 0; i < (int)strlen(vendor_id) && i < 8; i++) {
548 buffer->write(vendor_id[i]);
550 for(int i = strlen(vendor_id); i < 8; i++) {
553 for(int i = 0; i < (int)strlen(product_id) && i < 16; i++) {
554 buffer->write(vendor_id[i]);
556 for(int i = strlen(product_id); i < 16; i++) {
559 // change to data in phase
560 set_dat(buffer->read());
561 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
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);
569 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
570 position *= physical_block_size();
573 // create capacity data table
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);
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);
592 if(command[1] & 0x10) {
593 // change to data out phase for extra bytes
595 set_phase_delay(SCSI_PHASE_DATA_OUT, 10.0);
597 // no extra bytes, change to status phase
598 set_dat(SCSI_STATUS_GOOD);
599 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
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);
609 // create detect data table
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);
621 #ifdef _SCSI_DEBUG_LOG
622 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 6-byte\n"), scsi_id);
625 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
626 position *= physical_block_size();
628 remain = command[4] * logical_block_size();
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);
639 // change to data in phase
640 set_dat(buffer->read());
641 set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
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);
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);
655 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
656 position *= physical_block_size();
658 remain = command[4] * logical_block_size();
662 // change to data in phase
663 set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
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);
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);
677 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
678 position *= physical_block_size();
680 remain = command[7] * 0x100 + command[8];
681 remain *= logical_block_size();
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);
692 // change to data in phase
693 set_dat(buffer->read());
694 set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
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);
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);
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);
714 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
715 position *= physical_block_size();
717 remain = command[7] * 0x100 + command[8];
718 remain *= logical_block_size();
722 // change to data in phase
723 set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
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);
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);
737 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
738 position *= physical_block_size();
740 remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9];
741 remain *= logical_block_size();
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);
752 // change to data in phase
753 set_dat(buffer->read());
754 set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
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);
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);
768 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
769 position *= physical_block_size();
771 remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9];
772 remain *= logical_block_size();
776 // change to data in phase
777 set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
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);
787 #ifdef _SCSI_DEBUG_LOG
788 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Unknown %02X\n"), scsi_id, command[0]);
790 set_dat(SCSI_STATUS_GOOD);
791 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
795 bool SCSI_DEV::read_buffer(int length)
797 for(int i = 0; i < length; i++) {
801 set_sense_code(SCSI_SENSE_NOSENSE);
805 bool SCSI_DEV::write_buffer(int length)
807 for(int i = 0; i < length; i++) {
811 set_sense_code(SCSI_SENSE_NOSENSE);
815 #define STATE_VERSION 2
817 bool SCSI_DEV::process_state(FILEIO* state_fio, bool loading)
819 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
822 if(!state_fio->StateCheckInt32(this_device_id)) {
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)) {
845 state_fio->StateValue(position);
846 state_fio->StateValue(remain);
847 state_fio->StateValue(sense_code);