Merge pull request #58 from TC1995/master

Added Read Track Information command in ATAPI and SCSI.
This commit is contained in:
OBattler
2016-12-25 17:14:45 +01:00
committed by GitHub
8 changed files with 95 additions and 96 deletions

View File

@@ -1040,6 +1040,7 @@ static CDROM ioctl_cdrom=
ioctl_read_capacity,
ioctl_read_header,
ioctl_read_disc_information,
ioctl_read_track_information,
ioctl_sector_data_type,
ioctl_readsector_raw,
ioctl_playaudio,

View File

@@ -419,6 +419,7 @@ static CDROM iso_cdrom =
NULL,
NULL,
NULL,
NULL,
iso_sector_data_type,
iso_readsector_raw,
iso_playaudio,

View File

@@ -130,6 +130,7 @@ static CDROM null_cdrom =
NULL,
NULL,
NULL,
NULL,
null_sector_data_type,
null_readsector_raw,
null_playaudio,

View File

@@ -11,9 +11,10 @@ typedef struct CDROM
int (*readtoc_raw)(uint8_t *b, int msf, int maxlen);
uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf);
void (*read_capacity)(uint8_t *b);
void (*read_header)(uint8_t *in_cdb, uint8_t *b);
void (*read_header)(uint8_t *in_cdb, uint8_t *b);
void (*read_disc_information)(uint8_t *b);
int (*sector_data_type)(int sector, int ismsf);
void (*read_track_information)(uint8_t *in_cdb, uint8_t *b);
int (*sector_data_type)(int sector, int ismsf);
void (*readsector_raw)(uint8_t *b, int sector, int ismsf);
void (*playaudio)(uint32_t pos, uint32_t len, int ismsf);
void (*seek)(uint32_t pos);

View File

@@ -2549,6 +2549,49 @@ static void atapicommand(int ide_board)
idecallback[ide_board]=60*IDE_TIME;
ide->packlen=len;
break;
case GPCMD_READ_TRACK_INFORMATION:
if ((idebufferb[3] != 1) || (idebufferb[2] != 1))
{
ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/
ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR;
if (SCSISense.SenseKey == SENSE_UNIT_ATTENTION)
ide->error |= MCR_ERR;
SCSISense.Asc = ASC_INV_FIELD_IN_CMD_PACKET;
ide->packetstatus = ATAPI_STATUS_ERROR;
idecallback[ide_board]=50*IDE_TIME;
return;
}
if (cdrom->read_track_information)
{
cdrom->read_track_information(idebufferb, idebufferb);
}
else
{
idebufferb[1] = 34;
idebufferb[2] = 1; /* track number (LSB) */
idebufferb[3] = 1; /* session number (LSB) */
idebufferb[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */
idebufferb[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */
idebufferb[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */
idebufferb[8] = 0; /* track start address is 0 */
idebufferb[24] = (cdrom->size() >> 24) & 0xff; /* track size */
idebufferb[25] = (cdrom->size() >> 16) & 0xff; /* track size */
idebufferb[26] = (cdrom->size() >> 8) & 0xff; /* track size */
idebufferb[27] = cdrom->size() & 0xff; /* track size */
idebufferb[32] = 0; /* track number (MSB) */
idebufferb[33] = 0; /* session number (MSB) */
}
len=36;
ide->packetstatus = ATAPI_STATUS_DATA;
ide->cylinder=len;
ide->secount=2;
ide->pos=0;
idecallback[ide_board]=60*IDE_TIME;
ide->packlen=len;
break;
case GPCMD_PLAY_AUDIO_10:
case GPCMD_PLAY_AUDIO_12:

View File

@@ -32,6 +32,7 @@
#define GPCMD_PAUSE_RESUME 0x4b
#define GPCMD_STOP_PLAY_SCAN 0x4e
#define GPCMD_READ_DISC_INFORMATION 0x51
#define GPCMD_READ_TRACK_INFORMATION 0x52
#define GPCMD_MODE_SELECT_10 0x55
#define GPCMD_MODE_SENSE_10 0x5a
#define GPCMD_PLAY_AUDIO_12 0xa5

View File

@@ -1036,6 +1036,15 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb)
SCSIDMAResetPosition(id);
break;
case GPCMD_READ_TRACK_INFORMATION:
SCSIPhase = SCSI_PHASE_DATAIN;
SCSIStatus = SCSI_STATUS_OK;
SCSICallback[id]=60*SCSI_TIME;
SCSIDevices[id].CmdBufferLength = 36;
SCSIDMAResetPosition(id);
break;
case GPCMD_READ_DVD_STRUCTURE:
{
int len;
@@ -1542,7 +1551,42 @@ SCSIOut:
SCSIDevices[id].CmdBuffer[8] = 0x00; /* CD-ROM */
}
break;
case GPCMD_READ_TRACK_INFORMATION:
if ((SCSIDevices[id].Cdb[3] != 1) || (SCSIDevices[id].Cdb[2] != 1))
{
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
if (SCSISense.UnitAttention)
{
SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0);
}
SCSICallback[id]=50*SCSI_TIME;
return;
}
if (cdrom->read_track_information)
{
cdrom->read_track_information(SCSIDevices[id].Cdb, SCSIDevices[id].CmdBuffer);
}
else
{
SCSIDevices[id].CmdBuffer[1] = 34;
SCSIDevices[id].CmdBuffer[2] = 1; /* track number (LSB) */
SCSIDevices[id].CmdBuffer[3] = 1; /* session number (LSB) */
SCSIDevices[id].CmdBuffer[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */
SCSIDevices[id].CmdBuffer[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */
SCSIDevices[id].CmdBuffer[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */
SCSIDevices[id].CmdBuffer[8] = 0; /* track start address is 0 */
SCSIDevices[id].CmdBuffer[24] = (cdrom->size() >> 24) & 0xff; /* track size */
SCSIDevices[id].CmdBuffer[25] = (cdrom->size() >> 16) & 0xff; /* track size */
SCSIDevices[id].CmdBuffer[26] = (cdrom->size() >> 8) & 0xff; /* track size */
SCSIDevices[id].CmdBuffer[27] = cdrom->size() & 0xff; /* track size */
SCSIDevices[id].CmdBuffer[32] = 0; /* track number (MSB) */
SCSIDevices[id].CmdBuffer[33] = 0; /* session number (MSB) */
}
break;
case GPCMD_READ_DVD_STRUCTURE:
memset(SCSIDevices[id].CmdBuffer, 0, datalen > 256 * 512 + 4 ? 256 * 512 + 4 : datalen);

View File

@@ -1,93 +0,0 @@
/* Copyright holders: SA1988
see COPYING for more details
*/
/* ATAPI/SCSI Commands */
#define TEST_UNIT_READY 0x00
#define REQUEST_SENSE 0x03
#define READ_6 0x08
#define INQUIRY 0x12
#define MODE_SELECT 0x15
#define MODE_SENSE 0x1a /*actually MODE_SENSE_6 but I want to match QEMU's scheme*/
#define START_STOP 0x1b /*LOAD_UNLOAD is the same*/
#define ALLOW_MEDIUM_REMOVAL 0x1e
#define READ_CAPACITY_10 0x25
#define READ_10 0x28
#define SEEK_10 0x2b
#define READ_SUBCHANNEL 0x42 /*unimplemented on QEMU, so I came up with this name for this command*/
#define READ_TOC 0x43
#define READ_HEADER 0x44 /*unimplemented on QEMU, so I came up with this name for this command*/
#define PLAY_AUDIO_10 0x45
#define GET_CONFIGURATION 0x46
#define PLAY_AUDIO_MSF 0x47
#define GET_EVENT_NOTIFICATION 0x4a
#define PAUSE_RESUME 0x4b
#define STOP_PLAY_SCAN 0x4e
#define READ_DISC_INFORMATION 0x51
#define MODE_SELECT_10 0x55
#define MODE_SENSE_10 0x5a
#define PLAY_AUDIO_12 0xa5 /*deprecated*/
#define READ_12 0xa8
#define READ_DVD_STRUCTURE 0xad
#define SET_CD_SPEED 0xbb
#define MECHANISM_STATUS 0xbd
#define READ_CD 0xbe
#define SEND_DVD_STRUCTURE 0xbf
/* SCSI Sense Keys */
#define SENSE_NONE 0
#define SENSE_NOT_READY 2
#define SENSE_ILLEGAL_REQUEST 5
#define SENSE_UNIT_ATTENTION 6
/* SCSI Additional Sense Codes */
#define ASC_ILLEGAL_OPCODE 0x20
#define ASC_INV_FIELD_IN_CMD_PACKET 0x24
#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28
#define ASC_MEDIUM_NOT_PRESENT 0x3a
/* Mode page codes for mode sense/set */
#define GPMODE_R_W_ERROR_PAGE 0x01
#define GPMODE_CDROM_PAGE 0x0d
#define GPMODE_CDROM_AUDIO_PAGE 0x0e
#define GPMODE_CAPABILITIES_PAGE 0x2a
#define GPMODE_ALL_PAGES 0x3f
/*
* SCSI Status codes
*/
#define GOOD 0x00
#define CHECK_CONDITION 0x02
#define CONDITION_GOOD 0x04
#define BUSY 0x08
#define INTERMEDIATE_GOOD 0x10
#define INTERMEDIATE_C_GOOD 0x14
#define RESERVATION_CONFLICT 0x18
#define COMMAND_TERMINATED 0x22
#define TASK_SET_FULL 0x28
#define ACA_ACTIVE 0x30
#define TASK_ABORTED 0x40
#define STATUS_MASK 0x3e
/* Event notification classes for GET EVENT STATUS NOTIFICATION */
#define GESN_NO_EVENTS 0
#define GESN_OPERATIONAL_CHANGE 1
#define GESN_POWER_MANAGEMENT 2
#define GESN_EXTERNAL_REQUEST 3
#define GESN_MEDIA 4
#define GESN_MULTIPLE_HOSTS 5
#define GESN_DEVICE_BUSY 6
/* Event codes for MEDIA event status notification */
#define MEC_NO_CHANGE 0
#define MEC_EJECT_REQUESTED 1
#define MEC_NEW_MEDIA 2
#define MEC_MEDIA_REMOVAL 3 /* only for media changers */
#define MEC_MEDIA_CHANGED 4 /* only for media changers */
#define MEC_BG_FORMAT_COMPLETED 5 /* MRW or DVD+RW b/g format completed */
#define MEC_BG_FORMAT_RESTARTED 6 /* MRW or DVD+RW b/g format restarted */
#define MS_TRAY_OPEN 1
#define MS_MEDIA_PRESENT 2
#define CHECK_READY 2
#define ALLOW_UA 1