OSDN Git Service

[General] Merge Upstream 2018-12-18.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Sat, 12 Jan 2019 09:22:09 +0000 (18:22 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Sat, 12 Jan 2019 09:22:09 +0000 (18:22 +0900)
source/src/vm/scsi_cdrom.cpp
source/src/vm/scsi_dev.cpp
source/src/vm/scsi_hdd.cpp
source/src/vm/scsi_host.cpp

index 52aab9b..6a0510f 100644 (file)
@@ -1,4 +1,4 @@
-/*
+k/*
        Skelton for retropc emulator
 
        Author : Takeda.Toshiya
        Skelton for retropc emulator
 
        Author : Takeda.Toshiya
@@ -430,8 +430,25 @@ void SCSI_CDROM::start_command()
                #ifdef _SCSI_DEBUG_LOG
                        this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Read Mode Select 6-byte\n"), scsi_id);
                #endif
                #ifdef _SCSI_DEBUG_LOG
                        this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Read Mode Select 6-byte\n"), scsi_id);
                #endif
-               read_mode = (command[4] != 0);
-               break;
+               // start position
+//             position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
+//             position *= physical_block_size();
+               position = 0;
+               // transfer length
+//             remain = command[4];// * logical_block_size();
+               remain = 11;
+               if(remain != 0) {
+                       // clear data buffer
+                       buffer->clear();
+                       // change to data in phase
+                       set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
+               } else {
+                       // transfer length is zero, change to status phase
+                       set_dat(SCSI_STATUS_GOOD);
+                       set_sense_code(SCSI_SENSE_NOSENSE);
+                       set_phase_delay(SCSI_PHASE_STATUS, 10.0);
+               }
+               return;
                
        case 0xd8:
                #ifdef _SCSI_DEBUG_LOG
                
        case 0xd8:
                #ifdef _SCSI_DEBUG_LOG
@@ -724,6 +741,9 @@ void SCSI_CDROM::start_command()
                        case 0x00:      /* Get first and last track numbers */
                                buffer->write(TO_BCD(1));
                                buffer->write(TO_BCD(track_num));
                        case 0x00:      /* Get first and last track numbers */
                                buffer->write(TO_BCD(1));
                                buffer->write(TO_BCD(track_num));
+                               // PC-8801 CD BIOS invites 4 bytes ?
+                               buffer->write(0);
+                               buffer->write(0);
                                break;
                        case 0x01:      /* Get total disk size in MSF format */
                                {
                                break;
                        case 0x01:      /* Get total disk size in MSF format */
                                {
@@ -731,6 +751,8 @@ void SCSI_CDROM::start_command()
                                        buffer->write((msf >> 16) & 0xff);
                                        buffer->write((msf >>  8) & 0xff);
                                        buffer->write((msf >>  0) & 0xff);
                                        buffer->write((msf >> 16) & 0xff);
                                        buffer->write((msf >>  8) & 0xff);
                                        buffer->write((msf >>  0) & 0xff);
+                                       // PC-8801 CD BIOS invites 4 bytes ?
+                                       buffer->write(0);
                                }
                                break;
                        case 0x02:      /* Get track information */
                                }
                                break;
                        case 0x02:      /* Get track information */
@@ -809,8 +831,9 @@ bool SCSI_CDROM::read_buffer(int length)
                }
        }
        while(length > 0) {
                }
        }
        while(length > 0) {
-               uint8_t tmp_buffer[SCSI_BUFFER_SIZE];
-               int tmp_length = min(length, (int)sizeof(tmp_buffer));
+               uint8_t tmp_buffer[2352];
+//             int tmp_length = min(length, (int)sizeof(tmp_buffer));
+               int tmp_length = 2352 - offset;
                
                if(fio_img->Fread(tmp_buffer, tmp_length, 1) != 1) {
                        #ifdef _SCSI_DEBUG_LOG
                
                if(fio_img->Fread(tmp_buffer, tmp_length, 1) != 1) {
                        #ifdef _SCSI_DEBUG_LOG
@@ -820,8 +843,8 @@ bool SCSI_CDROM::read_buffer(int length)
                        set_sense_code(SCSI_SENSE_ILLGLBLKADDR); //SCSI_SENSE_NORECORDFND
                        return false;
                }
                        set_sense_code(SCSI_SENSE_ILLGLBLKADDR); //SCSI_SENSE_NORECORDFND
                        return false;
                }
-               for(int i = 0; i < tmp_length && length > 0; i++) {
-                       if(offset >= 16 && offset < 16 + 2048) {
+               for(int i = 0; i < tmp_length; i++) {
+                       if(offset >= 16 && offset < 16 + logical_block_size()) {
                                int value = tmp_buffer[i];
                                buffer->write(value);
                                length--;
                                int value = tmp_buffer[i];
                                buffer->write(value);
                                length--;
@@ -837,6 +860,28 @@ bool SCSI_CDROM::read_buffer(int length)
        return true;
 }
 
        return true;
 }
 
+bool SCSI_CDROM::write_buffer(int length)
+{
+       for(int i = 0; i < length; i++) {
+               int value = buffer->read();
+               if(command[0] == SCSI_CMD_MODE_SEL6) {
+                       if(i == 4) {
+                               #ifdef _SCSI_DEBUG_LOG
+                                       this->out_debug_log(_T("[SCSI_DEV:ID=%d] NEC Read Mode = %02X\n"), scsi_id, value);
+                               #endif
+                               read_mode = (value != 0);
+                       } else if(i == 10) {
+                               #ifdef _SCSI_DEBUG_LOG
+                                       this->out_debug_log(_T("[SCSI_DEV:ID=%d] NEC Retry Count = %02X\n"), scsi_id, value);
+                               #endif
+                       }
+               }
+               position++;
+       }
+       set_sense_code(SCSI_SENSE_NOSENSE);
+       return true;
+}
+
 int get_frames_from_msf(const char *string)
 {
        const char *ptr = string;
 int get_frames_from_msf(const char *string)
 {
        const char *ptr = string;
index f7a8f52..1db8e2d 100644 (file)
@@ -180,19 +180,20 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask)
                                        switch(phase) {
                                        case SCSI_PHASE_DATA_OUT:
                                                if(--remain > 0) {
                                        switch(phase) {
                                        case SCSI_PHASE_DATA_OUT:
                                                if(--remain > 0) {
+                                                       // flush buffer
+                                                       if(buffer->full()) {
+                                                               if(!write_buffer(buffer->count())) {
+                                                                       // change to status phase
+                                                                       set_dat(SCSI_STATUS_CHKCOND);
+                                                                       set_phase_delay(SCSI_PHASE_STATUS, 10.0);
+                                                                       break;
+                                                               }
+                                                               buffer->clear(); // just in case
+                                                       }
                                                        switch(command[0]) {
                                                        case SCSI_CMD_WRITE6:
                                                        case SCSI_CMD_WRITE10:
                                                        case SCSI_CMD_WRITE12:
                                                        switch(command[0]) {
                                                        case SCSI_CMD_WRITE6:
                                                        case SCSI_CMD_WRITE10:
                                                        case SCSI_CMD_WRITE12:
-                                                               // flush buffer
-                                                               if(buffer->full()) {
-                                                                       if(!write_buffer(buffer->count())) {
-                                                                               // change to status phase
-                                                                               set_dat(SCSI_STATUS_CHKCOND);
-                                                                               set_phase_delay(SCSI_PHASE_STATUS, 10.0);
-                                                                               break;
-                                                                       }
-                                                               }
                                                                // request to write next data
                                                                {
                                                                        next_req_usec += 1000000.0 / bytes_per_sec;
                                                                // request to write next data
                                                                {
                                                                        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)
                                                                }
                                                                break;
                                                        default:
                                                                }
                                                                break;
                                                        default:
-                                                               // flush buffer
-                                                               if(buffer->full()) {
-                                                                       buffer->clear();
-                                                               }
                                                                // request to write next data
                                                                set_req_delay(1, 1.0);
                                                                break;
                                                        }
                                                } else {
                                                                // request to write next data
                                                                set_req_delay(1, 1.0);
                                                                break;
                                                        }
                                                } else {
-                                                       switch(command[0]) {
-                                                       case SCSI_CMD_WRITE6:
-                                                       case SCSI_CMD_WRITE10:
-                                                       case SCSI_CMD_WRITE12:
-                                                               // flush buffer
-                                                               if(!buffer->empty()) {
-                                                                       if(!write_buffer(buffer->count())) {
-                                                                               // change to status phase
-                                                                               set_dat(SCSI_STATUS_CHKCOND);
-                                                                               set_phase_delay(SCSI_PHASE_STATUS, 10.0);
-                                                                               break;
-                                                                       }
-                                                               }
-                                                               break;
-                                                       default:
-                                                               // flush buffer
-                                                               if(!buffer->empty()) {
-                                                                       buffer->clear();
+                                                       // flush buffer
+                                                       if(!buffer->empty()) {
+                                                               if(!write_buffer(buffer->count())) {
+                                                                       // change to status phase
+                                                                       set_dat(SCSI_STATUS_CHKCOND);
+                                                                       set_phase_delay(SCSI_PHASE_STATUS, 10.0);
+                                                                       break;
                                                                }
                                                                }
-                                                               break;
+                                                               buffer->clear(); // just in case
                                                        }
                                                        // change to status phase
                                                        set_dat(SCSI_STATUS_GOOD);
                                                        }
                                                        // change to status phase
                                                        set_dat(SCSI_STATUS_GOOD);
@@ -451,7 +437,7 @@ void SCSI_DEV::set_msg(int value)
 void SCSI_DEV::set_req(int value)
 {
        #ifdef _SCSI_DEBUG_LOG
 void SCSI_DEV::set_req(int value)
 {
        #ifdef _SCSI_DEBUG_LOG
-               this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0);
+//             this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0);
        #endif
        if(event_req != -1) {
                cancel_event(this, event_req);
        #endif
        if(event_req != -1) {
                cancel_event(this, event_req);
@@ -521,25 +507,19 @@ void SCSI_DEV::start_command()
                position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
                position *= physical_block_size();
                // transfer length
                position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
                position *= physical_block_size();
                // transfer length
-               remain = 16;
+//             remain = 16;
+               remain = command[4];
                // create sense data table
                buffer->clear();
                // create sense data table
                buffer->clear();
-               buffer->write(SCSI_SERROR_CURRENT);
-               buffer->write(0x00);
-               buffer->write(is_device_ready() ? SCSI_KEY_NOSENSE : SCSI_KEY_UNITATT);
-               buffer->write(0x00);
-               buffer->write(0x00);
-               buffer->write(0x00);
-               buffer->write(0x00);
-               buffer->write(0x08);
-               buffer->write(0x00);
-               buffer->write(0x00);
-               buffer->write(0x00);
-               buffer->write(0x00);
-               buffer->write(0x00);
-               buffer->write(0x00);
-               buffer->write(0x00);
-               buffer->write(0x00);
+               for(int i = 0; i < remain; i++) {
+                       int value = 0;
+                       switch(i) {
+                       case 0: value = SCSI_SERROR_CURRENT; break;
+                       case 2: value = is_device_ready() ? SCSI_KEY_NOSENSE : SCSI_KEY_UNITATT; break;
+                       case 7: value = 0x08; break;
+                       }
+                       buffer->write(value);
+               }
                // change to data in phase
                set_dat(buffer->read());
                set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
                // change to data in phase
                set_dat(buffer->read());
                set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
index 09d254c..faf03bd 100644 (file)
@@ -123,6 +123,14 @@ uint32_t SCSI_HDD::max_logical_block_addr()
 
 bool SCSI_HDD::read_buffer(int length)
 {
 
 bool SCSI_HDD::read_buffer(int length)
 {
+       if(!(command[0] == SCSI_CMD_READ6 || command[0] == SCSI_CMD_READ10 || command[0] == SCSI_CMD_READ12)) {
+               for(int i = 0; i < length; i++) {
+                       buffer->write(0);
+                       position++;
+               }
+               set_sense_code(SCSI_SENSE_NOSENSE);
+               return true;
+       }
        HARDDISK *unit = disk[get_logical_unit_number()];
        
        if(!(unit != NULL && unit->mounted())) {
        HARDDISK *unit = disk[get_logical_unit_number()];
        
        if(!(unit != NULL && unit->mounted())) {
@@ -149,6 +157,14 @@ bool SCSI_HDD::read_buffer(int length)
 
 bool SCSI_HDD::write_buffer(int length)
 {
 
 bool SCSI_HDD::write_buffer(int length)
 {
+       if(!(command[0] == SCSI_CMD_WRITE6 || command[0] == SCSI_CMD_WRITE10 || command[0] == SCSI_CMD_WRITE12)) {
+               for(int i = 0; i < length; i++) {
+                       buffer->read();
+                       position++;
+               }
+               set_sense_code(SCSI_SENSE_NOSENSE);
+               return true;
+       }
        HARDDISK *unit = disk[get_logical_unit_number()];
        
        if(!(unit != NULL && unit->mounted())) {
        HARDDISK *unit = disk[get_logical_unit_number()];
        
        if(!(unit != NULL && unit->mounted())) {
index 8c6632d..82773a2 100644 (file)
@@ -77,7 +77,7 @@ void SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask)
                
        case SIG_SCSI_ACK:
                #ifdef _SCSI_DEBUG_LOG
                
        case SIG_SCSI_ACK:
                #ifdef _SCSI_DEBUG_LOG
-                       this->out_debug_log(_T("[SCSI_HOST] ACK = %d\n"), (data & mask) ? 1 : 0);
+//                     this->out_debug_log(_T("[SCSI_HOST] ACK = %d\n"), (data & mask) ? 1 : 0);
                #endif
                write_signals(&outputs_ack, (data & mask) ? 0xffffffff : 0);
                ack_status = data & mask;
                #endif
                write_signals(&outputs_ack, (data & mask) ? 0xffffffff : 0);
                ack_status = data & mask;