OSDN Git Service

[General] Completely merge upstream 2019-01-11.
[csp-qt/common_source_project-fm7.git] / source / src / vm / scsi_cdrom.cpp
index 387d7b8..3c18cbc 100644 (file)
@@ -17,8 +17,8 @@
 #define CDDA_PLAYING   1
 #define CDDA_PAUSED    2
 
-//#define _SCSI_DEBUG_LOG
-//#define _CDROM_DEBUG_LOG
+#define _SCSI_DEBUG_LOG
+#define _CDROM_DEBUG_LOG
 
 // 0-99 is reserved for SCSI_DEV class
 #define EVENT_CDDA                                             100
@@ -69,6 +69,7 @@ void SCSI_CDROM::reset()
        event_cdda_delay_play = -1;
        event_delay_interrupt = -1;
        SCSI_DEV::reset();
+       read_mode = false;
        set_cdda_status(CDDA_OFF);
        read_sectors = 0;
        // Q: Does not seek to track 0? 20181118 K.O
@@ -76,6 +77,31 @@ void SCSI_CDROM::reset()
 
 }
 
+void SCSI_CDROM::write_signal(int id, uint32_t data, uint32_t mask)
+{
+       bool _b = ((data & mask) != 0);
+       switch(id) {
+       case SIG_SCSI_CDROM_CDDA_STOP:
+               if(cdda_status != CDDA_OFF) {
+                       if(_b) set_cdda_status(CDDA_OFF);
+               }
+               break;
+       case SIG_SCSI_CDROM_CDDA_PLAY:
+               if(cdda_status != CDDA_PLAYING) {
+                       if(_b) set_cdda_status(CDDA_PLAYING);
+               }
+               break;
+       case SIG_SCSI_CDROM_CDDA_PAUSE:
+               if(cdda_status != CDDA_PAUSED) {
+                       if(_b) set_cdda_status(CDDA_PAUSED);
+               }
+               break;
+       default:
+               SCSI_DEV::write_signal(id, data, mask);
+               break;
+       }
+}
+
 uint32_t SCSI_CDROM::read_signal(int id)
 {
        switch(id) {
@@ -400,6 +426,30 @@ void SCSI_CDROM::start_command()
                }
                break;
                
+       case SCSI_CMD_MODE_SEL6:
+               #ifdef _SCSI_DEBUG_LOG
+                       this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Read Mode Select 6-byte\n"), scsi_id);
+               #endif
+               // 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
                this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Set Audio Playback Start Position CMD=%02x ARG=%02x %02x %02x %02x\n"), scsi_id, command[9], command[2], command[3], command[4], command[5]);
@@ -691,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));
+                               // PC-8801 CD BIOS invites 4 bytes ?
+                               buffer->write(0);
+                               buffer->write(0);
                                break;
                        case 0x01:      /* Get total disk size in MSF format */
                                {
@@ -698,6 +751,8 @@ void SCSI_CDROM::start_command()
                                        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 */
@@ -776,8 +831,9 @@ bool SCSI_CDROM::read_buffer(int length)
                }
        }
        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
@@ -787,8 +843,8 @@ bool SCSI_CDROM::read_buffer(int length)
                        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--;
@@ -804,6 +860,28 @@ bool SCSI_CDROM::read_buffer(int length)
        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;
@@ -1370,6 +1448,7 @@ bool SCSI_CDROM::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(event_delay_interrupt);
        state_fio->StateValue(read_sectors);
 //     state_fio->StateValue(mix_loop_num);
+       state_fio->StateValue(read_mode);
        state_fio->StateValue(volume_m);
        if(loading) {
                offset = state_fio->FgetUint32_LE();