Common Source Code Project for Qt (a.k.a for FM-7).
Revision | 89a913067210d1169704559b0a56b35cc9381c4f (tree) |
---|---|
Zeit | 2019-01-12 18:22:09 |
Autor | K.Ohta <whatisthis.sowhat@gmai...> |
Commiter | K.Ohta |
[General] Merge Upstream 2018-12-18.
@@ -1,4 +1,4 @@ | ||
1 | -/* | |
1 | +k/* | |
2 | 2 | Skelton for retropc emulator |
3 | 3 | |
4 | 4 | Author : Takeda.Toshiya |
@@ -430,8 +430,25 @@ void SCSI_CDROM::start_command() | ||
430 | 430 | #ifdef _SCSI_DEBUG_LOG |
431 | 431 | this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Read Mode Select 6-byte\n"), scsi_id); |
432 | 432 | #endif |
433 | - read_mode = (command[4] != 0); | |
434 | - break; | |
433 | + // start position | |
434 | +// position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]; | |
435 | +// position *= physical_block_size(); | |
436 | + position = 0; | |
437 | + // transfer length | |
438 | +// remain = command[4];// * logical_block_size(); | |
439 | + remain = 11; | |
440 | + if(remain != 0) { | |
441 | + // clear data buffer | |
442 | + buffer->clear(); | |
443 | + // change to data in phase | |
444 | + set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time); | |
445 | + } else { | |
446 | + // transfer length is zero, change to status phase | |
447 | + set_dat(SCSI_STATUS_GOOD); | |
448 | + set_sense_code(SCSI_SENSE_NOSENSE); | |
449 | + set_phase_delay(SCSI_PHASE_STATUS, 10.0); | |
450 | + } | |
451 | + return; | |
435 | 452 | |
436 | 453 | case 0xd8: |
437 | 454 | #ifdef _SCSI_DEBUG_LOG |
@@ -724,6 +741,9 @@ void SCSI_CDROM::start_command() | ||
724 | 741 | case 0x00: /* Get first and last track numbers */ |
725 | 742 | buffer->write(TO_BCD(1)); |
726 | 743 | buffer->write(TO_BCD(track_num)); |
744 | + // PC-8801 CD BIOS invites 4 bytes ? | |
745 | + buffer->write(0); | |
746 | + buffer->write(0); | |
727 | 747 | break; |
728 | 748 | case 0x01: /* Get total disk size in MSF format */ |
729 | 749 | { |
@@ -731,6 +751,8 @@ void SCSI_CDROM::start_command() | ||
731 | 751 | buffer->write((msf >> 16) & 0xff); |
732 | 752 | buffer->write((msf >> 8) & 0xff); |
733 | 753 | buffer->write((msf >> 0) & 0xff); |
754 | + // PC-8801 CD BIOS invites 4 bytes ? | |
755 | + buffer->write(0); | |
734 | 756 | } |
735 | 757 | break; |
736 | 758 | case 0x02: /* Get track information */ |
@@ -809,8 +831,9 @@ bool SCSI_CDROM::read_buffer(int length) | ||
809 | 831 | } |
810 | 832 | } |
811 | 833 | while(length > 0) { |
812 | - uint8_t tmp_buffer[SCSI_BUFFER_SIZE]; | |
813 | - int tmp_length = min(length, (int)sizeof(tmp_buffer)); | |
834 | + uint8_t tmp_buffer[2352]; | |
835 | +// int tmp_length = min(length, (int)sizeof(tmp_buffer)); | |
836 | + int tmp_length = 2352 - offset; | |
814 | 837 | |
815 | 838 | if(fio_img->Fread(tmp_buffer, tmp_length, 1) != 1) { |
816 | 839 | #ifdef _SCSI_DEBUG_LOG |
@@ -820,8 +843,8 @@ bool SCSI_CDROM::read_buffer(int length) | ||
820 | 843 | set_sense_code(SCSI_SENSE_ILLGLBLKADDR); //SCSI_SENSE_NORECORDFND |
821 | 844 | return false; |
822 | 845 | } |
823 | - for(int i = 0; i < tmp_length && length > 0; i++) { | |
824 | - if(offset >= 16 && offset < 16 + 2048) { | |
846 | + for(int i = 0; i < tmp_length; i++) { | |
847 | + if(offset >= 16 && offset < 16 + logical_block_size()) { | |
825 | 848 | int value = tmp_buffer[i]; |
826 | 849 | buffer->write(value); |
827 | 850 | length--; |
@@ -837,6 +860,28 @@ bool SCSI_CDROM::read_buffer(int length) | ||
837 | 860 | return true; |
838 | 861 | } |
839 | 862 | |
863 | +bool SCSI_CDROM::write_buffer(int length) | |
864 | +{ | |
865 | + for(int i = 0; i < length; i++) { | |
866 | + int value = buffer->read(); | |
867 | + if(command[0] == SCSI_CMD_MODE_SEL6) { | |
868 | + if(i == 4) { | |
869 | + #ifdef _SCSI_DEBUG_LOG | |
870 | + this->out_debug_log(_T("[SCSI_DEV:ID=%d] NEC Read Mode = %02X\n"), scsi_id, value); | |
871 | + #endif | |
872 | + read_mode = (value != 0); | |
873 | + } else if(i == 10) { | |
874 | + #ifdef _SCSI_DEBUG_LOG | |
875 | + this->out_debug_log(_T("[SCSI_DEV:ID=%d] NEC Retry Count = %02X\n"), scsi_id, value); | |
876 | + #endif | |
877 | + } | |
878 | + } | |
879 | + position++; | |
880 | + } | |
881 | + set_sense_code(SCSI_SENSE_NOSENSE); | |
882 | + return true; | |
883 | +} | |
884 | + | |
840 | 885 | int get_frames_from_msf(const char *string) |
841 | 886 | { |
842 | 887 | const char *ptr = string; |
@@ -180,19 +180,20 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) | ||
180 | 180 | switch(phase) { |
181 | 181 | case SCSI_PHASE_DATA_OUT: |
182 | 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 | + } | |
183 | 193 | switch(command[0]) { |
184 | 194 | case SCSI_CMD_WRITE6: |
185 | 195 | case SCSI_CMD_WRITE10: |
186 | 196 | case SCSI_CMD_WRITE12: |
187 | - // flush buffer | |
188 | - if(buffer->full()) { | |
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); | |
193 | - break; | |
194 | - } | |
195 | - } | |
196 | 197 | // request to write next data |
197 | 198 | { |
198 | 199 | next_req_usec += 1000000.0 / bytes_per_sec; |
@@ -201,35 +202,20 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) | ||
201 | 202 | } |
202 | 203 | break; |
203 | 204 | default: |
204 | - // flush buffer | |
205 | - if(buffer->full()) { | |
206 | - buffer->clear(); | |
207 | - } | |
208 | 205 | // request to write next data |
209 | 206 | set_req_delay(1, 1.0); |
210 | 207 | break; |
211 | 208 | } |
212 | 209 | } else { |
213 | - switch(command[0]) { | |
214 | - case SCSI_CMD_WRITE6: | |
215 | - case SCSI_CMD_WRITE10: | |
216 | - case SCSI_CMD_WRITE12: | |
217 | - // flush buffer | |
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); | |
223 | - break; | |
224 | - } | |
225 | - } | |
226 | - break; | |
227 | - default: | |
228 | - // flush buffer | |
229 | - if(!buffer->empty()) { | |
230 | - buffer->clear(); | |
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; | |
231 | 217 | } |
232 | - break; | |
218 | + buffer->clear(); // just in case | |
233 | 219 | } |
234 | 220 | // change to status phase |
235 | 221 | set_dat(SCSI_STATUS_GOOD); |
@@ -451,7 +437,7 @@ void SCSI_DEV::set_msg(int value) | ||
451 | 437 | void SCSI_DEV::set_req(int value) |
452 | 438 | { |
453 | 439 | #ifdef _SCSI_DEBUG_LOG |
454 | - this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0); | |
440 | +// this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0); | |
455 | 441 | #endif |
456 | 442 | if(event_req != -1) { |
457 | 443 | cancel_event(this, event_req); |
@@ -521,25 +507,19 @@ void SCSI_DEV::start_command() | ||
521 | 507 | position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]; |
522 | 508 | position *= physical_block_size(); |
523 | 509 | // transfer length |
524 | - remain = 16; | |
510 | +// remain = 16; | |
511 | + remain = command[4]; | |
525 | 512 | // create sense data table |
526 | 513 | buffer->clear(); |
527 | - buffer->write(SCSI_SERROR_CURRENT); | |
528 | - buffer->write(0x00); | |
529 | - buffer->write(is_device_ready() ? SCSI_KEY_NOSENSE : SCSI_KEY_UNITATT); | |
530 | - buffer->write(0x00); | |
531 | - buffer->write(0x00); | |
532 | - buffer->write(0x00); | |
533 | - buffer->write(0x00); | |
534 | - buffer->write(0x08); | |
535 | - buffer->write(0x00); | |
536 | - buffer->write(0x00); | |
537 | - buffer->write(0x00); | |
538 | - buffer->write(0x00); | |
539 | - buffer->write(0x00); | |
540 | - buffer->write(0x00); | |
541 | - buffer->write(0x00); | |
542 | - buffer->write(0x00); | |
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 | + } | |
543 | 523 | // change to data in phase |
544 | 524 | set_dat(buffer->read()); |
545 | 525 | set_phase_delay(SCSI_PHASE_DATA_IN, 10.0); |
@@ -123,6 +123,14 @@ uint32_t SCSI_HDD::max_logical_block_addr() | ||
123 | 123 | |
124 | 124 | bool SCSI_HDD::read_buffer(int length) |
125 | 125 | { |
126 | + if(!(command[0] == SCSI_CMD_READ6 || command[0] == SCSI_CMD_READ10 || command[0] == SCSI_CMD_READ12)) { | |
127 | + for(int i = 0; i < length; i++) { | |
128 | + buffer->write(0); | |
129 | + position++; | |
130 | + } | |
131 | + set_sense_code(SCSI_SENSE_NOSENSE); | |
132 | + return true; | |
133 | + } | |
126 | 134 | HARDDISK *unit = disk[get_logical_unit_number()]; |
127 | 135 | |
128 | 136 | if(!(unit != NULL && unit->mounted())) { |
@@ -149,6 +157,14 @@ bool SCSI_HDD::read_buffer(int length) | ||
149 | 157 | |
150 | 158 | bool SCSI_HDD::write_buffer(int length) |
151 | 159 | { |
160 | + if(!(command[0] == SCSI_CMD_WRITE6 || command[0] == SCSI_CMD_WRITE10 || command[0] == SCSI_CMD_WRITE12)) { | |
161 | + for(int i = 0; i < length; i++) { | |
162 | + buffer->read(); | |
163 | + position++; | |
164 | + } | |
165 | + set_sense_code(SCSI_SENSE_NOSENSE); | |
166 | + return true; | |
167 | + } | |
152 | 168 | HARDDISK *unit = disk[get_logical_unit_number()]; |
153 | 169 | |
154 | 170 | if(!(unit != NULL && unit->mounted())) { |
@@ -77,7 +77,7 @@ void SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask) | ||
77 | 77 | |
78 | 78 | case SIG_SCSI_ACK: |
79 | 79 | #ifdef _SCSI_DEBUG_LOG |
80 | - this->out_debug_log(_T("[SCSI_HOST] ACK = %d\n"), (data & mask) ? 1 : 0); | |
80 | +// this->out_debug_log(_T("[SCSI_HOST] ACK = %d\n"), (data & mask) ? 1 : 0); | |
81 | 81 | #endif |
82 | 82 | write_signals(&outputs_ack, (data & mask) ? 0xffffffff : 0); |
83 | 83 | ack_status = data & mask; |