2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
17 void SCSI_DEV::initialize()
20 buffer = new FIFO(SCSI_BUFFER_SIZE);
21 phase = SCSI_PHASE_BUS_FREE;
24 void SCSI_DEV::release()
30 void SCSI_DEV::reset()
33 sel_status = atn_status = ack_status = rst_status = false;
34 selected = atn_pending = false;
36 event_sel = event_phase = event_req = -1;
37 set_phase(SCSI_PHASE_BUS_FREE);
40 void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask)
44 data_bus = data & mask;
49 bool prev_status = sel_status;
50 sel_status = ((data & mask) != 0);
52 if(phase != SCSI_PHASE_BUS_FREE) {
53 // this device is already selected
54 } else if(!prev_status && sel_status) {
56 #ifdef SCSI_DEV_IMMEDIATE_SELECT
57 event_callback(EVENT_SEL, 0);
60 cancel_event(this, event_sel);
62 register_event(this, EVENT_SEL, 20.0, false, &event_sel);
64 } else if(prev_status && !sel_status) {
67 cancel_event(this, event_sel);
72 // change to message out phase
74 set_phase_delay(SCSI_PHASE_MESSAGE_OUT, 10.0);
75 // set_phase(SCSI_PHASE_MESSAGE_OUT);
77 // change to command phase
78 memset(command, 0, sizeof(command));
80 set_phase_delay(SCSI_PHASE_COMMAND, 10.0);
81 // set_phase(SCSI_PHASE_COMMAND);
90 bool prev_status = atn_status;
91 atn_status = ((data & mask) != 0);
93 if(phase == SCSI_PHASE_BUS_FREE) {
94 // this device is not selected
95 } else if(!prev_status && atn_status) {
97 #ifdef _SCSI_DEBUG_LOG
98 this->out_debug_log(_T("[SCSI_DEV:ID=%d] ATN signal raised\n"), scsi_id);
101 // wait until ack=off
104 // change to message out phase
107 set_phase_delay(SCSI_PHASE_MESSAGE_OUT, 10.0);
116 initiator ---> device
129 initiator <--- device
142 bool prev_status = ack_status;
143 ack_status = ((data & mask) != 0);
145 if(phase == SCSI_PHASE_BUS_FREE) {
146 // this device is not selected
147 } else if(!prev_status & ack_status) {
150 case SCSI_PHASE_DATA_OUT:
151 buffer->write(data_bus);
153 // check defect list length in format unit data
154 if(command[0] == SCSI_CMD_FORMAT) {
155 if(buffer->count() == 4) {
156 remain += buffer->read_not_remove(2) * 256 + buffer->read_not_remove(3);
161 case SCSI_PHASE_COMMAND:
162 command[command_index++] = data_bus;
165 case SCSI_PHASE_MESSAGE_OUT:
166 buffer->write(data_bus);
170 } else if(prev_status && !ack_status) {
173 // change to message out phase
176 set_phase_delay(SCSI_PHASE_MESSAGE_OUT, 10.0);
179 case SCSI_PHASE_DATA_OUT:
182 case SCSI_CMD_WRITE6:
183 case SCSI_CMD_WRITE10:
184 case SCSI_CMD_WRITE12:
187 write_buffer(buffer->count());
189 // request to write next data
191 next_req_usec += 1000000.0 / bytes_per_sec;
192 double usec = next_req_usec - get_passed_usec(first_req_clock);
193 set_req_delay(1, (usec > 1.0) ? usec : 1.0);
201 // request to write next data
202 set_req_delay(1, 1.0);
207 case SCSI_CMD_WRITE6:
208 case SCSI_CMD_WRITE10:
209 case SCSI_CMD_WRITE12:
211 if(!buffer->empty()) {
212 write_buffer(buffer->count());
217 if(!buffer->empty()) {
222 // change to status phase
223 set_dat(SCSI_STATUS_GOOD);
224 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
228 case SCSI_PHASE_DATA_IN:
231 if(buffer->count() == 0) {
232 if(remain > SCSI_BUFFER_SIZE) {
233 read_buffer(SCSI_BUFFER_SIZE);
235 read_buffer((int)remain);
238 // request to read next data
239 set_dat(buffer->read());
242 case SCSI_CMD_READ10:
243 case SCSI_CMD_READ12:
245 next_req_usec += 1000000.0 / bytes_per_sec;
246 double usec = next_req_usec - get_passed_usec(first_req_clock);
247 set_req_delay(1, (usec > 1.0) ? usec : 1.0);
251 set_req_delay(1, 1.0);
255 // change to status phase
256 set_dat(SCSI_STATUS_GOOD);
257 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
261 case SCSI_PHASE_COMMAND:
262 if(command_index < get_command_length(command[0])) {
263 // request next command
264 set_req_delay(1, 1.0);
271 case SCSI_PHASE_STATUS:
272 // create message data table
275 buffer->write(0x00); // command complete message
276 // change to message in phase
277 set_dat(buffer->read());
278 set_phase_delay(SCSI_PHASE_MESSAGE_IN, 1.0);
281 case SCSI_PHASE_MESSAGE_OUT:
282 if((buffer->read() & 0xb8) == 0x80) {
283 // identify, change to command phase
284 memset(command, 0, sizeof(command));
286 set_phase_delay(SCSI_PHASE_COMMAND, 10.0);
288 // abort, change to bus free phase
289 set_phase_delay(SCSI_PHASE_BUS_FREE, 10.0);
293 case SCSI_PHASE_MESSAGE_IN:
295 // request to read next data
296 set_dat(buffer->read());
297 set_req_delay(1, 1.0);
299 // change to bus free phase
300 set_phase_delay(SCSI_PHASE_BUS_FREE, 1.0);
311 bool prev_status = rst_status;
312 rst_status = ((data & mask) != 0);
314 if(!prev_status & rst_status) {
316 #ifdef _SCSI_DEBUG_LOG
317 this->out_debug_log(_T("[SCSI_DEV:ID=%d] RST signal raised\n"), scsi_id);
320 set_phase(SCSI_PHASE_BUS_FREE);
327 void SCSI_DEV::event_callback(int event_id, int err)
332 if((data_bus & 0x7f) == (1 << scsi_id)) {
333 if(is_device_existing()) {
334 // this device is selected!
335 #ifdef _SCSI_DEBUG_LOG
336 this->out_debug_log(_T("[SCSI_DEV:ID=%d] This device is selected\n"), scsi_id);
346 set_phase(next_phase);
356 void SCSI_DEV::set_phase(int value)
358 #ifdef _SCSI_DEBUG_LOG
359 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Phase %s -> %s\n"), scsi_id, scsi_phase_name[phase], scsi_phase_name[value]);
361 if(event_phase != -1) {
362 cancel_event(this, event_phase);
369 if(value == SCSI_PHASE_BUS_FREE) {
376 set_req_delay(1, 10.0);
381 void SCSI_DEV::set_phase_delay(int value, double usec)
386 if(event_phase != -1) {
387 cancel_event(this, event_phase);
390 register_event(this, EVENT_PHASE, usec, false, &event_phase);
395 void SCSI_DEV::set_dat(int value)
397 #ifdef _SCSI_DEBUG_LOG
398 // emu->force_out_debug_log(_T("[SCSI_DEV:ID=%d] DATA = %02x\n"), scsi_id, value);
400 write_signals(&outputs_dat, value);
403 void SCSI_DEV::set_bsy(int value)
405 #ifdef _SCSI_DEBUG_LOG
406 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] BUSY = %d\n"), scsi_id, value ? 1 : 0);
408 write_signals(&outputs_bsy, value ? 0xffffffff : 0);
411 void SCSI_DEV::set_cd(int value)
413 #ifdef _SCSI_DEBUG_LOG
414 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] C/D = %d\n"), scsi_id, value ? 1 : 0);
416 write_signals(&outputs_cd, value ? 0xffffffff : 0);
419 void SCSI_DEV::set_io(int value)
421 #ifdef _SCSI_DEBUG_LOG
422 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] I/O = %d\n"), scsi_id, value ? 1 : 0);
424 write_signals(&outputs_io, value ? 0xffffffff : 0);
427 void SCSI_DEV::set_msg(int value)
429 #ifdef _SCSI_DEBUG_LOG
430 // this->out_debug_log(_T("[SCSI_DEV:ID=%d] MSG = %d\n"), scsi_id, value ? 1 : 0);
432 write_signals(&outputs_msg, value ? 0xffffffff : 0);
435 void SCSI_DEV::set_req(int value)
437 #ifdef _SCSI_DEBUG_LOG
438 this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0);
440 if(event_req != -1) {
441 cancel_event(this, event_req);
444 if(value && first_req_clock == 0) {
445 first_req_clock = get_current_clock();
448 write_signals(&outputs_req, value ? 0xffffffff : 0);
451 void SCSI_DEV::set_req_delay(int value, double usec)
456 if(event_req != -1) {
457 cancel_event(this, event_req);
460 register_event(this, EVENT_REQ, usec, false, &event_req);
465 int SCSI_DEV::get_command_length(int value)
467 switch((value >> 5) & 7) {
482 void SCSI_DEV::start_command()
485 case SCSI_CMD_TST_U_RDY:
486 #ifdef _SCSI_DEBUG_LOG
487 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Test Unit Ready\n"), scsi_id);
489 // change to status phase
490 set_dat(is_device_ready() ? SCSI_STATUS_GOOD : SCSI_STATUS_CHKCOND);
491 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
494 case SCSI_CMD_REQ_SENSE:
495 #ifdef _SCSI_DEBUG_LOG
496 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Request Sense\n"), scsi_id);
499 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
500 position *= physical_block_size();
503 // create sense data table
505 buffer->write(SCSI_SERROR_CURRENT);
507 buffer->write(is_device_ready() ? SCSI_KEY_NOSENSE : SCSI_KEY_UNITATT);
521 // change to data in phase
522 set_dat(buffer->read());
523 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
526 case SCSI_CMD_INQUIRY:
527 #ifdef _SCSI_DEBUG_LOG
528 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Inquiry\n"), scsi_id);
531 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
532 position *= physical_block_size();
535 // create inquiry data table
537 buffer->write(device_type);
538 buffer->write(is_removable ? 0x80 : 0x00);
539 buffer->write(0x02); // ANSI SCSI2
540 buffer->write(0x01); // ANSI-CCS
545 for(int i = 0; i < (int)strlen(vendor_id) && i < 8; i++) {
546 buffer->write(vendor_id[i]);
548 for(int i = strlen(vendor_id); i < 8; i++) {
551 for(int i = 0; i < (int)strlen(product_id) && i < 16; i++) {
552 buffer->write(vendor_id[i]);
554 for(int i = strlen(product_id); i < 16; i++) {
557 // change to data in phase
558 set_dat(buffer->read());
559 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
562 case SCSI_CMD_RD_CAPAC:
563 #ifdef _SCSI_DEBUG_LOG
564 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read Capacity\n"), scsi_id);
567 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
568 position *= physical_block_size();
571 // create capacity data table
573 buffer->write((max_logical_block_addr() >> 24) & 0xff);
574 buffer->write((max_logical_block_addr() >> 16) & 0xff);
575 buffer->write((max_logical_block_addr() >> 8) & 0xff);
576 buffer->write((max_logical_block_addr() >> 0) & 0xff);
577 buffer->write(( logical_block_size() >> 24) & 0xff);
578 buffer->write(( logical_block_size() >> 16) & 0xff);
579 buffer->write(( logical_block_size() >> 8) & 0xff);
580 buffer->write(( logical_block_size() >> 0) & 0xff);
581 // change to data in phase
582 set_dat(buffer->read());
583 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
586 case SCSI_CMD_FORMAT:
587 #ifdef _SCSI_DEBUG_LOG
588 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Format Unit\n"), scsi_id);
590 if(command[1] & 0x10) {
591 // change to data out phase for extra bytes
593 set_phase_delay(SCSI_PHASE_DATA_OUT, 10.0);
595 // no extra bytes, change to status phase
596 set_dat(SCSI_STATUS_GOOD);
597 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
601 case SCSI_CMD_RD_DEFECT:
602 #ifdef _SCSI_DEBUG_LOG
603 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read Defect Data\n"), scsi_id);
607 // create detect data table
610 buffer->write(command[2]);
611 buffer->write(0x00); // msb of defect list length
612 buffer->write(0x00); // lsb of defect list length
613 // change to data in phase
614 set_dat(buffer->read());
615 set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
619 #ifdef _SCSI_DEBUG_LOG
620 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 6-byte\n"), scsi_id);
623 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
624 position *= physical_block_size();
626 remain = command[4] * logical_block_size();
630 if(remain > SCSI_BUFFER_SIZE) {
631 read_buffer(SCSI_BUFFER_SIZE);
633 read_buffer((int)remain);
635 // change to data in phase
636 set_dat(buffer->read());
637 set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
639 // transfer length is zero, change to status phase
640 set_dat(SCSI_STATUS_GOOD);
641 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
645 case SCSI_CMD_WRITE6:
646 #ifdef _SCSI_DEBUG_LOG
647 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 6-Byte\n"), scsi_id);
650 position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
651 position *= physical_block_size();
653 remain = command[4] * logical_block_size();
657 // change to data in phase
658 set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
660 // transfer length is zero, change to status phase
661 set_dat(SCSI_STATUS_GOOD);
662 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
666 case SCSI_CMD_READ10:
667 #ifdef _SCSI_DEBUG_LOG
668 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 10-byte\n"), scsi_id);
671 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
672 position *= physical_block_size();
674 remain = command[7] * 0x100 + command[8];
675 remain *= logical_block_size();
679 if(remain > SCSI_BUFFER_SIZE) {
680 read_buffer(SCSI_BUFFER_SIZE);
682 read_buffer((int)remain);
684 // change to data in phase
685 set_dat(buffer->read());
686 set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
688 // transfer length is zero, change to status phase
689 set_dat(SCSI_STATUS_GOOD);
690 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
694 case SCSI_CMD_WRITE10:
695 #ifdef _SCSI_DEBUG_LOG
696 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 10-Byte\n"), scsi_id);
699 case SCSI_CMD_WRT_VERIFY:
700 #ifdef _SCSI_DEBUG_LOG
701 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write and Verify\n"), scsi_id);
705 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
706 position *= physical_block_size();
708 remain = command[7] * 0x100 + command[8];
709 remain *= logical_block_size();
713 // change to data in phase
714 set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
716 // transfer length is zero, change to status phase
717 set_dat(SCSI_STATUS_GOOD);
718 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
722 case SCSI_CMD_READ12:
723 #ifdef _SCSI_DEBUG_LOG
724 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 12-byte\n"), scsi_id);
727 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
728 position *= physical_block_size();
730 remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9];
731 remain *= logical_block_size();
735 if(remain > SCSI_BUFFER_SIZE) {
736 read_buffer(SCSI_BUFFER_SIZE);
738 read_buffer((int)remain);
740 // change to data in phase
741 set_dat(buffer->read());
742 set_phase_delay(SCSI_PHASE_DATA_IN, seek_time);
744 // transfer length is zero, change to status phase
745 set_dat(SCSI_STATUS_GOOD);
746 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
750 case SCSI_CMD_WRITE12:
751 #ifdef _SCSI_DEBUG_LOG
752 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 12-Byte\n"), scsi_id);
755 position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5];
756 position *= physical_block_size();
758 remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9];
759 remain *= logical_block_size();
763 // change to data in phase
764 set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
766 // transfer length is zero, change to status phase
767 set_dat(SCSI_STATUS_GOOD);
768 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
772 case SASI_CMD_SPECIFY:
773 #ifdef _SCSI_DEBUG_LOG
774 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: SASI Command 0xC2\n"), scsi_id);
780 // change to data in phase
781 set_phase_delay(SCSI_PHASE_DATA_OUT, 1.0);
785 #ifdef _SCSI_DEBUG_LOG
786 this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Unknown %02X\n"), scsi_id, command[0]);
788 set_dat(SCSI_STATUS_GOOD);
789 set_phase_delay(SCSI_PHASE_STATUS, 10.0);
793 void SCSI_DEV::read_buffer(int length)
795 for(int i = 0; i < length; i++) {
801 void SCSI_DEV::write_buffer(int length)
803 for(int i = 0; i < length; i++) {
809 #define STATE_VERSION 2
811 #include "../statesub.h"
813 void SCSI_DEV::decl_state()
815 // ToDo: Add Fix Value.
816 // enter_decl_state(STATE_VERSION);
818 DECL_STATE_ENTRY_UINT32(data_bus);
819 DECL_STATE_ENTRY_BOOL(sel_status);
820 DECL_STATE_ENTRY_BOOL(atn_status);
821 DECL_STATE_ENTRY_BOOL(ack_status);
822 DECL_STATE_ENTRY_BOOL(rst_status);
823 DECL_STATE_ENTRY_BOOL(selected);
824 DECL_STATE_ENTRY_BOOL(atn_pending);
825 DECL_STATE_ENTRY_INT32(phase);
826 DECL_STATE_ENTRY_INT32(next_phase);
827 DECL_STATE_ENTRY_INT32(next_req);
828 DECL_STATE_ENTRY_INT32(event_sel);
829 DECL_STATE_ENTRY_INT32(event_phase);
830 DECL_STATE_ENTRY_INT32(event_req);
831 DECL_STATE_ENTRY_UINT32(first_req_clock);
832 DECL_STATE_ENTRY_DOUBLE(next_req_usec);
833 DECL_STATE_ENTRY_1D_ARRAY(command, sizeof(command));
834 DECL_STATE_ENTRY_INT32(command_index);
835 DECL_STATE_ENTRY_FIFO(buffer);
836 DECL_STATE_ENTRY_UINT64(position);
837 DECL_STATE_ENTRY_UINT64(remain);
839 // leave_decl_state();
841 void SCSI_DEV::save_state(FILEIO* state_fio)
843 if(state_entry != NULL) {
844 state_entry->save_state(state_fio);
846 // state_fio->FputUint32(STATE_VERSION);
847 // state_fio->FputInt32(this_device_id);
849 // state_fio->FputUint32(data_bus);
850 // state_fio->FputBool(sel_status);
851 // state_fio->FputBool(atn_status);
852 // state_fio->FputBool(ack_status);
853 // state_fio->FputBool(rst_status);
854 // state_fio->FputBool(selected);
855 // state_fio->FputBool(atn_pending);
856 // state_fio->FputInt32(phase);
857 // state_fio->FputInt32(next_phase);
858 // state_fio->FputInt32(next_req);
859 // state_fio->FputInt32(event_sel);
860 // state_fio->FputInt32(event_phase);
861 // state_fio->FputInt32(event_req);
862 // state_fio->FputUint32(first_req_clock);
863 // state_fio->FputDouble(next_req_usec);
864 // state_fio->Fwrite(command, sizeof(command), 1);
865 // state_fio->FputInt32(command_index);
866 // buffer->save_state((void *)state_fio);
867 // state_fio->FputUint64(position);
868 // state_fio->FputUint64(remain);
871 bool SCSI_DEV::load_state(FILEIO* state_fio)
874 if(state_entry != NULL) {
875 mb = state_entry->load_state(state_fio);
877 if(!mb) return false;
878 // if(state_fio->FgetUint32() != STATE_VERSION) {
881 // if(state_fio->FgetInt32() != this_device_id) {
884 // data_bus = state_fio->FgetUint32();
885 // sel_status = state_fio->FgetBool();
886 // atn_status = state_fio->FgetBool();
887 // ack_status = state_fio->FgetBool();
888 // rst_status = state_fio->FgetBool();
889 // selected = state_fio->FgetBool();
890 // atn_pending = state_fio->FgetBool();
891 // phase = state_fio->FgetInt32();
892 // next_phase = state_fio->FgetInt32();
893 // next_req = state_fio->FgetInt32();
894 // event_sel = state_fio->FgetInt32();
895 // event_phase = state_fio->FgetInt32();
896 // event_req = state_fio->FgetInt32();
897 // first_req_clock = state_fio->FgetUint32();
898 // next_req_usec = state_fio->FgetDouble();
899 // state_fio->Fread(command, sizeof(command), 1);
900 // command_index = state_fio->FgetInt32();
901 // if(!buffer->load_state((void *)state_fio)) {
904 // position = state_fio->FgetUint64();
905 // remain = state_fio->FgetUint64();