ATAPI BAD COMMAND response now correctly sets IDE sector count to 3;

ATAPI READ TOC PMA ATIP command now uses direct SCSI passthrough when using IOCtl on Windows;
ATAPI READ TOC PMA ATIP command now supports non-MSF raw mode;
ATAPI READ TOC PMA ATIP command now returns the given maximum length if the actual length of the data is above it;
ATAPI READ TOC PMA ATPI command on Windows IOCtl now returns size of data in the returned buffer's header.
This commit is contained in:
OBattler
2016-12-25 01:57:56 +01:00
parent e46a34a505
commit c7443b47b5
6 changed files with 112 additions and 31 deletions

View File

@@ -482,7 +482,7 @@ static int SCSICommand(const UCHAR *cdb, UCHAR *buf, uint32_t len)
DWORD ioctl_bytes;
DWORD out_size;
int ioctl_rv = 0;
UCHAR tbuf[2856];
UCHAR tbuf[65535];
struct sptd_with_sense
{
SCSI_PASS_THROUGH_DIRECT s;
@@ -759,6 +759,10 @@ static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, in
}
if (single) break;
}
if (len > maxlen)
{
len = maxlen;
}
b[0] = (uint8_t)(((len-2) >> 8) & 0xff);
b[1] = (uint8_t)((len-2) & 0xff);
/* pclog("Table of Contents (%i bytes) : \n",size);
@@ -811,9 +815,45 @@ static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen)
b[len++]=temp;
}
if (len > maxlen)
{
len = maxlen;
}
b[0] = ((len - 2) >> 8) & 0xff;
b[1] = (len - 2) & 0xff;
return len;
}
static void ioctl_readtoc_raw(uint8_t *b, int msf, int maxlen)
{
UCHAR cdb[12];
UCHAR buf[65535];
int len = 0;
ioctl_open(0);
cdb[0] = 0x43;
cdb[1] = msf ? 2 : 0;
cdb[2] = 2;
cdb[3] = cdb[4] = cdb[5] = cdb[6] = 0;
cdb[7] = (maxlen >> 8) & 0xff;
cdb[8] = maxlen & 0xff;
cdb[9] = cdb[10] = cdb[11] = 0;
SCSICommand(cdb, buf, 65535);
len = buf[0];
len <<= 8;
len |= buf[1];
len += 2;
memcpy(b, buf, len);
ioctl_close();
}
#if 0
static int ioctl_readtoc_raw(unsigned char *b, int maxlen)
{
int len=4;
@@ -855,8 +895,12 @@ static int ioctl_readtoc_raw(unsigned char *b, int maxlen)
b[len++]=toc.Descriptors[i].Msf[2];
}
b[0] = (len >> 8) & 0xff;
b[1] = len & 0xff;
return len;
}
#endif
static uint32_t ioctl_size()
{

View File

@@ -221,6 +221,10 @@ static int iso_readtoc(unsigned char *buf, unsigned char start_track, int msf, i
*q++ = last_block;
}
len = q - buf;
if (len > maxlen)
{
len = maxlen;
}
buf[0] = (uint8_t)(((len-2) >> 8) & 0xff);
buf[1] = (uint8_t)((len-2) & 0xff);
return len;
@@ -243,10 +247,14 @@ static int iso_readtoc_session(unsigned char *buf, int msf, int maxlen)
*q++ = 0; /* frame */
*q++ = 0;
if (maxlen < 12)
{
return maxlen;
}
return 12;
}
static int iso_readtoc_raw(unsigned char *buf, int maxlen)
static int iso_readtoc_raw(unsigned char *buf, int msf, int maxlen)
{
uint8_t *q;
int len;
@@ -288,9 +296,19 @@ static int iso_readtoc_raw(unsigned char *buf, int maxlen)
*q++ = 0; /* frame */
last_block = image_size >> 11;
/* this is raw, must be msf */
if (msf)
{
*q++ = 0; /* reserved */
lba_to_msf(q, last_block);
q += 3;
}
else
{
*q++ = (last_block >> 24) & 0xff;
*q++ = (last_block >> 16) & 0xff;
*q++ = (last_block >> 8) & 0xff;
*q++ = last_block & 0xff;
}
*q++ = 1; /* session number */
*q++ = 0x14; /* ADR, control */
@@ -300,12 +318,25 @@ static int iso_readtoc_raw(unsigned char *buf, int maxlen)
*q++ = 0; /* sec */
*q++ = 0; /* frame */
/* same here */
if (msf)
{
*q++ = 0; /* reserved */
lba_to_msf(q, 0);
q += 3;
}
else
{
*q++ = 0;
*q++ = 0;
*q++ = 0;
*q++ = 0;
}
len = q - buf;
if (len > maxlen)
{
len = maxlen;
}
buf[0] = (uint8_t)(((len-2) >> 8) & 0xff);
buf[1] = (uint8_t)((len-2) & 0xff);
return len;

View File

@@ -81,7 +81,7 @@ static int null_readtoc_session(unsigned char *b, int msf, int maxlen)
return 0;
}
static int null_readtoc_raw(unsigned char *b, int maxlen)
static int null_readtoc_raw(unsigned char *b, int msf, int maxlen)
{
return 0;
}

View File

@@ -8,7 +8,7 @@ typedef struct CDROM
int (*medium_changed)(void);
int (*readtoc)(uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single);
int (*readtoc_session)(uint8_t *b, int msf, int maxlen);
int (*readtoc_raw)(uint8_t *b, int maxlen);
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);

View File

@@ -666,7 +666,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
} */
}
fdc.dor=val;
// printf("DOR now %02X (%04X:%04X)\n",val, CS, cpu_state.pc);
printf("DOR now %02X (%04X:%04X)\n",val, CS, cpu_state.pc);
return;
case 3:
/* TDR */
@@ -686,10 +686,10 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
fdc.perp &= 0xfc;
fdc_reset();
}
// pclog("DSR now: %02X\n", val);
pclog("DSR now: %02X\n", val);
return;
case 5: /*Command register*/
// pclog("CMD now: %02X\n", val);
pclog("CMD now: %02X\n", val);
if ((fdc.stat & 0xf0) == 0xb0)
{
if (fdc.pcjr || !fdc.fifo)
@@ -793,6 +793,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
fdc.stat |= 0x90;
break;
case 8: /*Sense interrupt status*/
if (!fdc.fintr && !fdc_reset_stat) pclog("Attempted SENSE INTERRUPT STATUS without FINTR\n");
if (!fdc.fintr && !fdc_reset_stat) goto bad_command;
// printf("Sense interrupt status %i\n",curdrive);
fdc.lastdrive = fdc.drive;
@@ -1216,7 +1217,7 @@ bad_command:
case 7:
if (!AT) return;
fdc.rate=val&3;
// pclog("Rate now: %i\n", val & 3);
pclog("Rate now: %i\n", val & 3);
disc_3f7=val;
return;
@@ -1254,7 +1255,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
break;
case 2:
temp = fdc.dor;
// pclog("Read DOR: %02X\n", fdc.dor);
pclog("Read DOR: %02X\n", fdc.dor);
break;
case 3:
drive = real_drive(fdc.dor & 3);
@@ -1284,7 +1285,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
return 0;
}
temp=fdc.stat;
// pclog("Read MSR: %02X\n", fdc.stat);
pclog("Read MSR: %02X\n", fdc.stat);
break;
case 5: /*Data*/
fdc.stat&=~0x80;
@@ -1296,14 +1297,14 @@ uint8_t fdc_read(uint16_t addr, void *priv)
{
temp = fdc_fifo_buf_read();
}
// pclog("Read DAT: %02X\n", temp);
pclog("Read DAT: %02X\n", temp);
break;
}
if (paramstogo)
{
paramstogo--;
temp=fdc.res[10 - paramstogo];
// pclog("Read result: %02X\n", temp);
pclog("Read result: %02X\n", temp);
// pclog("Read param %i %02X\n",10-paramstogo,temp);
if (!paramstogo)
{
@@ -1322,15 +1323,16 @@ uint8_t fdc_read(uint16_t addr, void *priv)
fdc.stat = 0x80;
lastbyte=0;
temp=fdc.dat;
// pclog("Read DAT: %02X\n", temp);
pclog("Read DAT: %02X\n", temp);
fdc.data_ready = 0;
}
if (discint==0xA)
/* What the heck is this even doing?! */
/* if (discint==0xA)
{
timer_process();
disctime = 1024 * (1 << TIMER_SHIFT);
timer_update_outstanding();
}
} */
fdc.stat &= 0xf0;
break;
case 7: /*Disk change*/
@@ -1345,7 +1347,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
{
temp |= 0x7F;
}
// pclog("Read CCR: %02X\n", temp);
pclog("Read CCR: %02X\n", temp);
// printf("- DC %i %02X %02X %i %i - ",fdc.dor & 3, fdc.dor, 0x10 << (fdc.dor & 3), discchanged[fdc.dor & 1], driveempty[fdc.dor & 1]);
// discchanged[fdc.dor&1]=0;
break;

View File

@@ -1114,6 +1114,7 @@ uint8_t readide(int ide_board, uint16_t addr)
else
{
temp = (uint8_t)ide->secount;
// pclog("Returning sector count: %i\n", temp);
}
break;
@@ -1704,7 +1705,8 @@ void callbackide(int ide_board)
{
readcdmode=0;
ide->pos=0;
ide->secount = (uint8_t)((ide->secount&0xF8)|1);
// ide->secount = (uint8_t)((ide->secount&0xF8)|1);
ide->secount = 1;
ide->atastat = READY_STAT | DRQ_STAT |(ide->atastat&ERR_STAT);
//ide_irq_raise(ide);
// pclog("1 Preparing to recieve packet max DRQ count %04X\n",ide->cylinder);
@@ -1818,7 +1820,7 @@ void atapi_command_send_init(IDE *ide, uint8_t command, int req_length, int allo
if ((ide->cylinder & 1) && !(alloc_length <= ide->cylinder))
{
pclog("Odd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%04x\n", ide->cylinder, command, ide->cylinder - 1);
// pclog("Odd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%04x\n", ide->cylinder, command, ide->cylinder - 1);
ide->cylinder--;
}
@@ -1889,9 +1891,9 @@ static void atapicommand(int ide_board)
int ret;
int real_pos;
#if 0
pclog("ATAPI command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n",idebufferb[0],SCSISense.SenseKey,SCSISense.Asc,SCSISense.Ascq,ins,SCSISense.UnitAttention);
// pclog("ATAPI command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n",idebufferb[0],SCSISense.SenseKey,SCSISense.Asc,SCSISense.Ascq,ins,SCSISense.UnitAttention);
#if 0
int CdbLength;
for (CdbLength = 1; CdbLength < 12; CdbLength++)
pclog("ATAPI CDB[%d] = 0x%02X\n", CdbLength, idebufferb[CdbLength]);
@@ -2076,7 +2078,7 @@ static void atapicommand(int ide_board)
case 2: /*Raw*/
// pclog("ATAPI: READ TOC type requested: Raw TOC\n");
len=idebufferb[8]+(idebufferb[7]<<8);
len=cdrom->readtoc_raw(idebufferb,len);
len=cdrom->readtoc_raw(idebufferb,msf,len);
break;
default:
// pclog("ATAPI: Unknown READ TOC type requested: %i\n", (idebufferb[9]>>6));
@@ -2101,6 +2103,7 @@ static void atapicommand(int ide_board)
ide->pos=0;
idecallback[ide_board]=60*IDE_TIME;
ide->packlen=len;
// pclog("READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", toc_format, ide->cylinder, idebufferb[1]);
return;
case GPCMD_READ_CD:
@@ -2854,6 +2857,7 @@ atapi_out:
SCSISense.SenseKey = SENSE_ILLEGAL_REQUEST;
SCSISense.Asc = ASC_ILLEGAL_OPCODE;
ide->packetstatus = ATAPI_STATUS_ERROR;
ide->secount = 3;
idecallback[ide_board]=50*IDE_TIME;
break;