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:
184 case SCSI_CMD_WRITE6:
185 case SCSI_CMD_WRITE10:
186 case SCSI_CMD_WRITE12:
189 if(!write_buffer(buffer->count())) {
190 // change to status phase
191 set_dat(SCSI_STATUS_CHKCOND);
192 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
196 // request to write next data
198 next_req_usec += 1000000.0 / bytes_per_sec;
199 double usec = next_req_usec - get_passed_usec(first_req_clock);
200 set_req_delay(1, (usec > 1.0) ? usec : 1.0);
208 // request to write next data
209 set_req_delay(1, 1.0);
214 case SCSI_CMD_WRITE6:
215 case SCSI_CMD_WRITE10:
216 case SCSI_CMD_WRITE12:
218 if(!buffer->empty()) {
219 if(!write_buffer(buffer->count())) {
220 // change to status phase
221 set_dat(SCSI_STATUS_CHKCOND);
222 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
229 if(!buffer->empty()) {
234 // change to status phase
235 set_dat(SCSI_STATUS_GOOD);
236 set_sense_code(SCSI_SENSE_NOSENSE);
237 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
241 case SCSI_PHASE_DATA_IN:
244 if(buffer->count() == 0) {
245 int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
246 if(!read_buffer(length)) {
247 // change to status phase
248 set_dat(SCSI_STATUS_CHKCOND);
249 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
253 // request to read next data
254 set_dat(buffer->read());
257 case SCSI_CMD_READ10:
258 case SCSI_CMD_READ12:
260 next_req_usec += 1000000.0 / bytes_per_sec;
261 double usec = next_req_usec - get_passed_usec(first_req_clock);
262 set_req_delay(1, (usec > 1.0) ? usec : 1.0);
266 set_req_delay(1, 1.0);
270 // change to status phase
271 set_dat(SCSI_STATUS_GOOD);
272 set_sense_code(SCSI_SENSE_NOSENSE);
273 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
277 case SCSI_PHASE_COMMAND:
278 if(command_index < get_command_length(command[0])) {
279 // request next command
280 set_req_delay(1, 1.0);
287 case SCSI_PHASE_STATUS:
288 // create message data table
291 buffer->write(0x00); // command complete message
292 // change to message in phase
293 set_dat(buffer->read());
294 set_phase_delay(SCSI_PHASE_MESSAGE_IN, 1.0);
297 case SCSI_PHASE_MESSAGE_OUT:
298 if((buffer->read() & 0xb8) == 0x80) {
299 // identify, change to command phase
300 memset(command, 0, sizeof(command));
302 set_phase_delay(SCSI_PHASE_COMMAND, 10.0);
304 // abort, change to bus free phase
305 set_phase_delay(SCSI_PHASE_BUS_FREE, 10.0);
309 case SCSI_PHASE_MESSAGE_IN:
311 // request to read next data
312 set_dat(buffer->read());
313 set_req_delay(1, 1.0);
315 // change to bus free phase
316 set_phase_delay(SCSI_PHASE_BUS_FREE, 1.0);
327 bool prev_status = rst_status;
328 rst_status = ((data & mask) != 0);
330 if(!prev_status & rst_status) {
332 #ifdef _SCSI_DEBUG_LOG
333 this->out_debug_log(_T("[SCSI_DEV:ID=%d] RST signal raised\n"), scsi_id);
336 set_phase(SCSI_PHASE_BUS_FREE);
343 void SCSI_DEV::event_callback(int event_id, int err)
348 if((data_bus & 0x7f) == (1 << scsi_id)) {
349 if(is_device_existing()) {
350 // this device is selected!
351 #ifdef _SCSI_DEBUG_LOG
352 this->out_debug_log(_T("[SCSI_DEV:ID=%d] This device is selected\n"), scsi_id);
362 set_phase(next_phase);
372 void SCSI_DEV::set_phase(int value)
374 #ifdef _SCSI_DEBUG_LOG
375 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Phase %s -> %s\n"), scsi_id, scsi_phase_name[phase], scsi_phase_name[value]);
377 if(event_phase != -1) {
378 cancel_event(this, event_phase);
385 if(value == SCSI_PHASE_BUS_FREE) {
392 set_req_delay(1, 10.0);
397 void SCSI_DEV::set_phase_delay(int value, double usec)
402 if(event_phase != -1) {
403 cancel_event(this, event_phase);
406 register_event(this, EVENT_PHASE, usec, false, &event_phase);
411 void SCSI_DEV::set_dat(int value)
413 #ifdef _SCSI_DEBUG_LOG
414 // emu->force_out_debug_log(_T("[SCSI_DEV:ID=%d] DATA = %02x\n"), scsi_id, value);
416 write_signals(&outputs_dat, value);
419 void SCSI_DEV::set_bsy(int value)
421 #ifdef _SCSI_DEBUG_LOG
422 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] BUSY = %d\n"), scsi_id, value ? 1 : 0);
424 write_signals(&outputs_bsy, value ? 0xffffffff : 0);
427 void SCSI_DEV::set_cd(int value)
429 #ifdef _SCSI_DEBUG_LOG
430 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] C/D = %d\n"), scsi_id, value ? 1 : 0);
432 write_signals(&outputs_cd, value ? 0xffffffff : 0);
435 void SCSI_DEV::set_io(int value)
437 #ifdef _SCSI_DEBUG_LOG
438 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] I/O = %d\n"), scsi_id, value ? 1 : 0);
440 write_signals(&outputs_io, value ? 0xffffffff : 0);
443 void SCSI_DEV::set_msg(int value)
445 #ifdef _SCSI_DEBUG_LOG
446 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] MSG = %d\n"), scsi_id, value ? 1 : 0);
448 write_signals(&outputs_msg, value ? 0xffffffff : 0);
451 void SCSI_DEV::set_req(int value)
453 #ifdef _SCSI_DEBUG_LOG
454 this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0);
456 if(event_req != -1) {
457 cancel_event(this, event_req);
460 if(value && first_req_clock == 0) {
461 first_req_clock = get_current_clock();
464 write_signals(&outputs_req, value ? 0xffffffff : 0);
467 void SCSI_DEV::set_req_delay(int value, double usec)
472 if(event_req != -1) {
473 cancel_event(this, event_req);
476 register_event(this, EVENT_REQ, usec, false, &event_req);
481 int SCSI_DEV::get_command_length(int value)
483 switch((value >> 5) & 7) {
498 void SCSI_DEV::start_command()
501 case SCSI_CMD_TST_U_RDY:
502 #ifdef _SCSI_DEBUG_LOG
503 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Test Unit Ready\n"), scsi_id);
505 // change to status phase
506 if(!is_device_ready()) {
507 set_dat(SCSI_STATUS_CHKCOND);
508 set_sense_code(SCSI_SENSE_NOTREADY);
510 set_dat(SCSI_STATUS_GOOD);
511 set_sense_code(SCSI_SENSE_NOSENSE);
513 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
516 case SCSI_CMD_REQ_SENSE:
517 #ifdef _SCSI_DEBUG_LOG
518 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Request Sense\n"), scsi_id);
521 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
522 position *= physical_block_size();
525 // create sense data table
527 buffer->write(SCSI_SERROR_CURRENT);
529 buffer->write(is_device_ready() ? SCSI_KEY_NOSENSE : SCSI_KEY_UNITATT);
543 // change to data in phase
544 set_dat(buffer->read());
545 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
548 case SCSI_CMD_INQUIRY:
549 #ifdef _SCSI_DEBUG_LOG
550 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Inquiry\n"), scsi_id);
553 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
554 position *= physical_block_size();
557 // create inquiry data table
559 buffer->write(device_type);
560 buffer->write(is_removable ? 0x80 : 0x00);
561 buffer->write(0x02); // ANSI SCSI2
562 buffer->write(0x01); // ANSI-CCS
567 for(int i = 0; i < (int)strlen(vendor_id) && i < 8; i++) {
568 buffer->write(vendor_id[i]);
570 for(int i = strlen(vendor_id); i < 8; i++) {
573 for(int i = 0; i < (int)strlen(product_id) && i < 16; i++) {
574 buffer->write(vendor_id[i]);
576 for(int i = strlen(product_id); i < 16; i++) {
579 // change to data in phase
580 set_dat(buffer->read());
581 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
584 case SCSI_CMD_RD_CAPAC:
585 #ifdef _SCSI_DEBUG_LOG
586 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read Capacity\n"), scsi_id);
589 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
590 position *= physical_block_size();
593 // create capacity data table
595 buffer->write((max_logical_block_addr() >> 24) & 0xff);
596 buffer->write((max_logical_block_addr() >> 16) & 0xff);
597 buffer->write((max_logical_block_addr() >> 8) & 0xff);
598 buffer->write((max_logical_block_addr() >> 0) & 0xff);
599 buffer->write(( logical_block_size() >> 24) & 0xff);
600 buffer->write(( logical_block_size() >> 16) & 0xff);
601 buffer->write(( logical_block_size() >> 8) & 0xff);
602 buffer->write(( logical_block_size() >> 0) & 0xff);
603 // change to data in phase
604 set_dat(buffer->read());
605 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
608 case SCSI_CMD_FORMAT:
609 #ifdef _SCSI_DEBUG_LOG
610 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Format Unit\n"), scsi_id);
612 if(command[1] & 0x10) {
613 // change to data out phase for extra bytes
615 set_phase_delay(SCSI_PHASE_DATA_OUT, 10.0);
617 // no extra bytes, change to status phase
618 set_dat(SCSI_STATUS_GOOD);
619 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
623 case SCSI_CMD_RD_DEFECT:
624 #ifdef _SCSI_DEBUG_LOG
625 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read Defect Data\n"), scsi_id);
629 // create detect data table
632 buffer->write(command[2]);
633 buffer->write(0x00); // msb of defect list length
634 buffer->write(0x00); // lsb of defect list length
635 // change to data in phase
636 set_dat(buffer->read());
637 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
641 #ifdef _SCSI_DEBUG_LOG
642 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 6-byte\n"), scsi_id);
645 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
646 position *= physical_block_size();
648 remain = command[4] * logical_block_size();
652 int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
653 if(!read_buffer(length)) {
654 // change to status phase
655 set_dat(SCSI_STATUS_CHKCOND);
656 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
659 // change to data in phase
660 set_dat(buffer->read());
661 set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
663 // transfer length is zero, change to status phase
664 set_dat(SCSI_STATUS_GOOD);
665 set_sense_code(SCSI_SENSE_NOSENSE);
666 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
670 case SCSI_CMD_WRITE6:
671 #ifdef _SCSI_DEBUG_LOG
672 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 6-Byte\n"), scsi_id);
675 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
676 position *= physical_block_size();
678 remain = command[4] * logical_block_size();
682 // change to data in phase
683 set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
685 // transfer length is zero, change to status phase
686 set_dat(SCSI_STATUS_GOOD);
687 set_sense_code(SCSI_SENSE_NOSENSE);
688 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
692 case SCSI_CMD_READ10:
693 #ifdef _SCSI_DEBUG_LOG
694 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 10-byte\n"), scsi_id);
697 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
698 position *= physical_block_size();
700 remain = command[7] * 0x100 + command[8];
701 remain *= logical_block_size();
705 int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
706 if(!read_buffer(length)) {
707 // change to status phase
708 set_dat(SCSI_STATUS_CHKCOND);
709 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
712 // change to data in phase
713 set_dat(buffer->read());
714 set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
716 // transfer length is zero, change to status phase
717 set_dat(SCSI_STATUS_GOOD);
718 set_sense_code(SCSI_SENSE_NOSENSE);
719 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
723 case SCSI_CMD_WRITE10:
724 #ifdef _SCSI_DEBUG_LOG
725 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 10-Byte\n"), scsi_id);
728 case SCSI_CMD_WRT_VERIFY:
729 #ifdef _SCSI_DEBUG_LOG
730 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write and Verify\n"), scsi_id);
734 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
735 position *= physical_block_size();
737 remain = command[7] * 0x100 + command[8];
738 remain *= logical_block_size();
742 // change to data in phase
743 set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
745 // transfer length is zero, change to status phase
746 set_dat(SCSI_STATUS_GOOD);
747 set_sense_code(SCSI_SENSE_NOSENSE);
748 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
752 case SCSI_CMD_READ12:
753 #ifdef _SCSI_DEBUG_LOG
754 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 12-byte\n"), scsi_id);
757 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
758 position *= physical_block_size();
760 remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9];
761 remain *= logical_block_size();
765 int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain;
766 if(!read_buffer(length)) {
767 // change to status phase
768 set_dat(SCSI_STATUS_CHKCOND);
769 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
772 // change to data in phase
773 set_dat(buffer->read());
774 set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
776 // transfer length is zero, change to status phase
777 set_dat(SCSI_STATUS_GOOD);
778 set_sense_code(SCSI_SENSE_NOSENSE);
779 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
783 case SCSI_CMD_WRITE12:
784 #ifdef _SCSI_DEBUG_LOG
785 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 12-Byte\n"), scsi_id);
788 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
789 position *= physical_block_size();
791 remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9];
792 remain *= logical_block_size();
796 // change to data in phase
797 set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
799 // transfer length is zero, change to status phase
800 set_dat(SCSI_STATUS_GOOD);
801 set_sense_code(SCSI_SENSE_NOSENSE);
802 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
807 #ifdef _SCSI_DEBUG_LOG
808 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Unknown %02X\n"), scsi_id, command[0]);
810 set_dat(SCSI_STATUS_GOOD);
811 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
815 bool SCSI_DEV::read_buffer(int length)
817 for(int i = 0; i < length; i++) {
821 set_sense_code(SCSI_SENSE_NOSENSE);
825 bool SCSI_DEV::write_buffer(int length)
827 for(int i = 0; i < length; i++) {
831 set_sense_code(SCSI_SENSE_NOSENSE);
835 #define STATE_VERSION 2
837 bool SCSI_DEV::process_state(FILEIO* state_fio, bool loading)
839 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
842 if(!state_fio->StateCheckInt32(this_device_id)) {
845 state_fio->StateValue(data_bus);
846 state_fio->StateValue(sel_status);
847 state_fio->StateValue(atn_status);
848 state_fio->StateValue(ack_status);
849 state_fio->StateValue(rst_status);
850 state_fio->StateValue(selected);
851 state_fio->StateValue(atn_pending);
852 state_fio->StateValue(phase);
853 state_fio->StateValue(next_phase);
854 state_fio->StateValue(next_req);
855 state_fio->StateValue(event_sel);
856 state_fio->StateValue(event_phase);
857 state_fio->StateValue(event_req);
858 state_fio->StateValue(first_req_clock);
859 state_fio->StateValue(next_req_usec);
860 state_fio->StateArray(command, sizeof(command), 1);
861 state_fio->StateValue(command_index);
862 if(!buffer->process_state((void *)state_fio, loading)) {
865 state_fio->StateValue(position);
866 state_fio->StateValue(remain);
867 state_fio->StateValue(sense_code);