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 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;
|
||||
}
|
||||
|
||||
return len;
|
||||
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;
|
||||
@@ -854,9 +894,13 @@ static int ioctl_readtoc_raw(unsigned char *b, int maxlen)
|
||||
b[len++]=toc.Descriptors[i].Msf[1];
|
||||
b[len++]=toc.Descriptors[i].Msf[2];
|
||||
}
|
||||
|
||||
b[0] = (len >> 8) & 0xff;
|
||||
b[1] = len & 0xff;
|
||||
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
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 */
|
||||
*q++ = 0; /* reserved */
|
||||
lba_to_msf(q, last_block);
|
||||
q += 3;
|
||||
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 */
|
||||
*q++ = 0;
|
||||
*q++ = 0;
|
||||
*q++ = 0;
|
||||
*q++ = 0;
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
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;
|
||||
// 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;
|
||||
|
||||
18
src/ide.c
18
src/ide.c
@@ -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;
|
||||
|
||||
@@ -1698,13 +1699,14 @@ void callbackide(int ide_board)
|
||||
|
||||
case WIN_PACKETCMD: /* ATAPI Packet */
|
||||
if (!IDE_DRIVE_IS_CDROM(ide)) goto abort_cmd;
|
||||
// pclog("Packet callback! %i %08X\n",ide->packetstatus,ide);
|
||||
// pclog("Packet callback! %i %08X\n",ide->packetstatus,ide);
|
||||
|
||||
if (ide->packetstatus == ATAPI_STATUS_IDLE)
|
||||
{
|
||||
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:
|
||||
@@ -2297,7 +2300,7 @@ static void atapicommand(int ide_board)
|
||||
len=(idebufferb[8]|(idebufferb[7]<<8));
|
||||
|
||||
temp=idebufferb[2] & 0x3F;
|
||||
|
||||
|
||||
memset(idebufferb, 0, len);
|
||||
alloc_length = len;
|
||||
// for (c=0;c<len;c++) idebufferb[c]=0;
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user