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:
@@ -482,7 +482,7 @@ static int SCSICommand(const UCHAR *cdb, UCHAR *buf, uint32_t len)
|
|||||||
DWORD ioctl_bytes;
|
DWORD ioctl_bytes;
|
||||||
DWORD out_size;
|
DWORD out_size;
|
||||||
int ioctl_rv = 0;
|
int ioctl_rv = 0;
|
||||||
UCHAR tbuf[2856];
|
UCHAR tbuf[65535];
|
||||||
struct sptd_with_sense
|
struct sptd_with_sense
|
||||||
{
|
{
|
||||||
SCSI_PASS_THROUGH_DIRECT s;
|
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 (single) break;
|
||||||
}
|
}
|
||||||
|
if (len > maxlen)
|
||||||
|
{
|
||||||
|
len = maxlen;
|
||||||
|
}
|
||||||
b[0] = (uint8_t)(((len-2) >> 8) & 0xff);
|
b[0] = (uint8_t)(((len-2) >> 8) & 0xff);
|
||||||
b[1] = (uint8_t)((len-2) & 0xff);
|
b[1] = (uint8_t)((len-2) & 0xff);
|
||||||
/* pclog("Table of Contents (%i bytes) : \n",size);
|
/* 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;
|
b[len++]=temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len > maxlen)
|
||||||
|
{
|
||||||
|
len = maxlen;
|
||||||
|
}
|
||||||
|
b[0] = ((len - 2) >> 8) & 0xff;
|
||||||
|
b[1] = (len - 2) & 0xff;
|
||||||
return len;
|
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)
|
static int ioctl_readtoc_raw(unsigned char *b, int maxlen)
|
||||||
{
|
{
|
||||||
int len=4;
|
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[len++]=toc.Descriptors[i].Msf[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b[0] = (len >> 8) & 0xff;
|
||||||
|
b[1] = len & 0xff;
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static uint32_t ioctl_size()
|
static uint32_t ioctl_size()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -221,6 +221,10 @@ static int iso_readtoc(unsigned char *buf, unsigned char start_track, int msf, i
|
|||||||
*q++ = last_block;
|
*q++ = last_block;
|
||||||
}
|
}
|
||||||
len = q - buf;
|
len = q - buf;
|
||||||
|
if (len > maxlen)
|
||||||
|
{
|
||||||
|
len = maxlen;
|
||||||
|
}
|
||||||
buf[0] = (uint8_t)(((len-2) >> 8) & 0xff);
|
buf[0] = (uint8_t)(((len-2) >> 8) & 0xff);
|
||||||
buf[1] = (uint8_t)((len-2) & 0xff);
|
buf[1] = (uint8_t)((len-2) & 0xff);
|
||||||
return len;
|
return len;
|
||||||
@@ -243,10 +247,14 @@ static int iso_readtoc_session(unsigned char *buf, int msf, int maxlen)
|
|||||||
*q++ = 0; /* frame */
|
*q++ = 0; /* frame */
|
||||||
*q++ = 0;
|
*q++ = 0;
|
||||||
|
|
||||||
|
if (maxlen < 12)
|
||||||
|
{
|
||||||
|
return maxlen;
|
||||||
|
}
|
||||||
return 12;
|
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;
|
uint8_t *q;
|
||||||
int len;
|
int len;
|
||||||
@@ -288,9 +296,19 @@ static int iso_readtoc_raw(unsigned char *buf, int maxlen)
|
|||||||
*q++ = 0; /* frame */
|
*q++ = 0; /* frame */
|
||||||
last_block = image_size >> 11;
|
last_block = image_size >> 11;
|
||||||
/* this is raw, must be msf */
|
/* this is raw, must be msf */
|
||||||
|
if (msf)
|
||||||
|
{
|
||||||
*q++ = 0; /* reserved */
|
*q++ = 0; /* reserved */
|
||||||
lba_to_msf(q, last_block);
|
lba_to_msf(q, last_block);
|
||||||
q += 3;
|
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++ = 1; /* session number */
|
||||||
*q++ = 0x14; /* ADR, control */
|
*q++ = 0x14; /* ADR, control */
|
||||||
@@ -300,12 +318,25 @@ static int iso_readtoc_raw(unsigned char *buf, int maxlen)
|
|||||||
*q++ = 0; /* sec */
|
*q++ = 0; /* sec */
|
||||||
*q++ = 0; /* frame */
|
*q++ = 0; /* frame */
|
||||||
/* same here */
|
/* same here */
|
||||||
|
if (msf)
|
||||||
|
{
|
||||||
|
*q++ = 0; /* reserved */
|
||||||
|
lba_to_msf(q, 0);
|
||||||
|
q += 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*q++ = 0;
|
*q++ = 0;
|
||||||
*q++ = 0;
|
*q++ = 0;
|
||||||
*q++ = 0;
|
*q++ = 0;
|
||||||
*q++ = 0;
|
*q++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
len = q - buf;
|
len = q - buf;
|
||||||
|
if (len > maxlen)
|
||||||
|
{
|
||||||
|
len = maxlen;
|
||||||
|
}
|
||||||
buf[0] = (uint8_t)(((len-2) >> 8) & 0xff);
|
buf[0] = (uint8_t)(((len-2) >> 8) & 0xff);
|
||||||
buf[1] = (uint8_t)((len-2) & 0xff);
|
buf[1] = (uint8_t)((len-2) & 0xff);
|
||||||
return len;
|
return len;
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ static int null_readtoc_session(unsigned char *b, int msf, int maxlen)
|
|||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ typedef struct CDROM
|
|||||||
int (*medium_changed)(void);
|
int (*medium_changed)(void);
|
||||||
int (*readtoc)(uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single);
|
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_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);
|
uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf);
|
||||||
void (*read_capacity)(uint8_t *b);
|
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);
|
||||||
|
|||||||
26
src/fdc.c
26
src/fdc.c
@@ -666,7 +666,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
fdc.dor=val;
|
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;
|
return;
|
||||||
case 3:
|
case 3:
|
||||||
/* TDR */
|
/* TDR */
|
||||||
@@ -686,10 +686,10 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
fdc.perp &= 0xfc;
|
fdc.perp &= 0xfc;
|
||||||
fdc_reset();
|
fdc_reset();
|
||||||
}
|
}
|
||||||
// pclog("DSR now: %02X\n", val);
|
pclog("DSR now: %02X\n", val);
|
||||||
return;
|
return;
|
||||||
case 5: /*Command register*/
|
case 5: /*Command register*/
|
||||||
// pclog("CMD now: %02X\n", val);
|
pclog("CMD now: %02X\n", val);
|
||||||
if ((fdc.stat & 0xf0) == 0xb0)
|
if ((fdc.stat & 0xf0) == 0xb0)
|
||||||
{
|
{
|
||||||
if (fdc.pcjr || !fdc.fifo)
|
if (fdc.pcjr || !fdc.fifo)
|
||||||
@@ -793,6 +793,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
fdc.stat |= 0x90;
|
fdc.stat |= 0x90;
|
||||||
break;
|
break;
|
||||||
case 8: /*Sense interrupt status*/
|
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;
|
if (!fdc.fintr && !fdc_reset_stat) goto bad_command;
|
||||||
// printf("Sense interrupt status %i\n",curdrive);
|
// printf("Sense interrupt status %i\n",curdrive);
|
||||||
fdc.lastdrive = fdc.drive;
|
fdc.lastdrive = fdc.drive;
|
||||||
@@ -1216,7 +1217,7 @@ bad_command:
|
|||||||
case 7:
|
case 7:
|
||||||
if (!AT) return;
|
if (!AT) return;
|
||||||
fdc.rate=val&3;
|
fdc.rate=val&3;
|
||||||
// pclog("Rate now: %i\n", val & 3);
|
pclog("Rate now: %i\n", val & 3);
|
||||||
|
|
||||||
disc_3f7=val;
|
disc_3f7=val;
|
||||||
return;
|
return;
|
||||||
@@ -1254,7 +1255,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
temp = fdc.dor;
|
temp = fdc.dor;
|
||||||
// pclog("Read DOR: %02X\n", fdc.dor);
|
pclog("Read DOR: %02X\n", fdc.dor);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
drive = real_drive(fdc.dor & 3);
|
drive = real_drive(fdc.dor & 3);
|
||||||
@@ -1284,7 +1285,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
temp=fdc.stat;
|
temp=fdc.stat;
|
||||||
// pclog("Read MSR: %02X\n", fdc.stat);
|
pclog("Read MSR: %02X\n", fdc.stat);
|
||||||
break;
|
break;
|
||||||
case 5: /*Data*/
|
case 5: /*Data*/
|
||||||
fdc.stat&=~0x80;
|
fdc.stat&=~0x80;
|
||||||
@@ -1296,14 +1297,14 @@ uint8_t fdc_read(uint16_t addr, void *priv)
|
|||||||
{
|
{
|
||||||
temp = fdc_fifo_buf_read();
|
temp = fdc_fifo_buf_read();
|
||||||
}
|
}
|
||||||
// pclog("Read DAT: %02X\n", temp);
|
pclog("Read DAT: %02X\n", temp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (paramstogo)
|
if (paramstogo)
|
||||||
{
|
{
|
||||||
paramstogo--;
|
paramstogo--;
|
||||||
temp=fdc.res[10 - 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);
|
// pclog("Read param %i %02X\n",10-paramstogo,temp);
|
||||||
if (!paramstogo)
|
if (!paramstogo)
|
||||||
{
|
{
|
||||||
@@ -1322,15 +1323,16 @@ uint8_t fdc_read(uint16_t addr, void *priv)
|
|||||||
fdc.stat = 0x80;
|
fdc.stat = 0x80;
|
||||||
lastbyte=0;
|
lastbyte=0;
|
||||||
temp=fdc.dat;
|
temp=fdc.dat;
|
||||||
// pclog("Read DAT: %02X\n", temp);
|
pclog("Read DAT: %02X\n", temp);
|
||||||
fdc.data_ready = 0;
|
fdc.data_ready = 0;
|
||||||
}
|
}
|
||||||
if (discint==0xA)
|
/* What the heck is this even doing?! */
|
||||||
|
/* if (discint==0xA)
|
||||||
{
|
{
|
||||||
timer_process();
|
timer_process();
|
||||||
disctime = 1024 * (1 << TIMER_SHIFT);
|
disctime = 1024 * (1 << TIMER_SHIFT);
|
||||||
timer_update_outstanding();
|
timer_update_outstanding();
|
||||||
}
|
} */
|
||||||
fdc.stat &= 0xf0;
|
fdc.stat &= 0xf0;
|
||||||
break;
|
break;
|
||||||
case 7: /*Disk change*/
|
case 7: /*Disk change*/
|
||||||
@@ -1345,7 +1347,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
|
|||||||
{
|
{
|
||||||
temp |= 0x7F;
|
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]);
|
// 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;
|
// discchanged[fdc.dor&1]=0;
|
||||||
break;
|
break;
|
||||||
|
|||||||
14
src/ide.c
14
src/ide.c
@@ -1114,6 +1114,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
temp = (uint8_t)ide->secount;
|
temp = (uint8_t)ide->secount;
|
||||||
|
// pclog("Returning sector count: %i\n", temp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1704,7 +1705,8 @@ void callbackide(int ide_board)
|
|||||||
{
|
{
|
||||||
readcdmode=0;
|
readcdmode=0;
|
||||||
ide->pos=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->atastat = READY_STAT | DRQ_STAT |(ide->atastat&ERR_STAT);
|
||||||
//ide_irq_raise(ide);
|
//ide_irq_raise(ide);
|
||||||
// pclog("1 Preparing to recieve packet max DRQ count %04X\n",ide->cylinder);
|
// 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))
|
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--;
|
ide->cylinder--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1889,9 +1891,9 @@ static void atapicommand(int ide_board)
|
|||||||
int ret;
|
int ret;
|
||||||
int real_pos;
|
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;
|
int CdbLength;
|
||||||
for (CdbLength = 1; CdbLength < 12; CdbLength++)
|
for (CdbLength = 1; CdbLength < 12; CdbLength++)
|
||||||
pclog("ATAPI CDB[%d] = 0x%02X\n", CdbLength, idebufferb[CdbLength]);
|
pclog("ATAPI CDB[%d] = 0x%02X\n", CdbLength, idebufferb[CdbLength]);
|
||||||
@@ -2076,7 +2078,7 @@ static void atapicommand(int ide_board)
|
|||||||
case 2: /*Raw*/
|
case 2: /*Raw*/
|
||||||
// pclog("ATAPI: READ TOC type requested: Raw TOC\n");
|
// pclog("ATAPI: READ TOC type requested: Raw TOC\n");
|
||||||
len=idebufferb[8]+(idebufferb[7]<<8);
|
len=idebufferb[8]+(idebufferb[7]<<8);
|
||||||
len=cdrom->readtoc_raw(idebufferb,len);
|
len=cdrom->readtoc_raw(idebufferb,msf,len);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// pclog("ATAPI: Unknown READ TOC type requested: %i\n", (idebufferb[9]>>6));
|
// 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;
|
ide->pos=0;
|
||||||
idecallback[ide_board]=60*IDE_TIME;
|
idecallback[ide_board]=60*IDE_TIME;
|
||||||
ide->packlen=len;
|
ide->packlen=len;
|
||||||
|
// pclog("READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", toc_format, ide->cylinder, idebufferb[1]);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GPCMD_READ_CD:
|
case GPCMD_READ_CD:
|
||||||
@@ -2854,6 +2857,7 @@ atapi_out:
|
|||||||
SCSISense.SenseKey = SENSE_ILLEGAL_REQUEST;
|
SCSISense.SenseKey = SENSE_ILLEGAL_REQUEST;
|
||||||
SCSISense.Asc = ASC_ILLEGAL_OPCODE;
|
SCSISense.Asc = ASC_ILLEGAL_OPCODE;
|
||||||
ide->packetstatus = ATAPI_STATUS_ERROR;
|
ide->packetstatus = ATAPI_STATUS_ERROR;
|
||||||
|
ide->secount = 3;
|
||||||
idecallback[ide_board]=50*IDE_TIME;
|
idecallback[ide_board]=50*IDE_TIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user