📄 sbpcd.c
字号:
/*==========================================================================*/
static int convert_UPC(u_char *p)
{
int i;
p++;
if (!new_drive) p[13]=0;
for (i=0;i<7;i++)
{
if (new_drive) DS[d].UPC_buf[i]=swap_nibbles(*p++);
else
{
DS[d].UPC_buf[i]=((*p++)<<4)&0xFF;
DS[d].UPC_buf[i] |= *p++;
}
}
DS[d].UPC_buf[6] &= 0xF0;
return (0);
}
/*==========================================================================*/
static int xx_ReadUPC(void)
{
int i;
DS[d].diskstate_flags &= ~upc_bit;
clr_cmdbuf();
if (new_drive)
{
drvcmd[0]=0x88;
response_count=8;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
}
else
{
drvcmd[0]=0x08;
response_count=0;
flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
}
i=cmd_out();
if (i<0) return (i);
if (!new_drive)
{
response_count=16;
i=xx_ReadPacket();
if (i<0) return (i);
}
DS[d].UPC_ctl_adr=0;
if (new_drive) i=0;
else i=2;
if ((infobuf[i]&0x80)!=0)
{
convert_UPC(&infobuf[i]);
DS[d].UPC_ctl_adr &= 0xF0;
DS[d].UPC_ctl_adr |= 0x02;
}
DS[d].diskstate_flags |= upc_bit;
return (0);
}
/*==========================================================================*/
static int yy_CheckMultiSession(void)
{
int i;
DS[d].diskstate_flags &= ~multisession_bit;
DS[d].f_multisession=0;
clr_cmdbuf();
if (new_drive)
{
drvcmd[0]=0x8D;
response_count=6;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
i=cmd_out();
if (i<0) return (i);
if ((infobuf[0]&0x80)!=0)
{
DPRINTF((DBG_MUL,"SBPCD: MultiSession CD detected: %02X %02X %02X %02X %02X %02X\n",
infobuf[0], infobuf[1], infobuf[2],
infobuf[3], infobuf[4], infobuf[5]));
DS[d].f_multisession=1;
DS[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]),
make16(infobuf[2],infobuf[3])));
}
}
DS[d].diskstate_flags |= multisession_bit;
return (0);
}
/*==========================================================================*/
static void check_datarate(void)
{
#ifdef CDMKE
int i=0;
timed_out=0;
datarate=0;
/* set a timer to make (timed_out!=0) after 1.1 seconds */
DPRINTF((DBG_TIM,"SBPCD: timer started (110).\n"));
sti(); /* to avoid possible "printf" bug */
SET_TIMER(mark_timeout,110);
do
{
i=inb(CDi_status);
datarate++;
#if 00000
if (datarate>0x0FFFFFFF) break;
#endif 00000
}
while (!timed_out); /* originally looping for 1.1 seconds */
CLEAR_TIMER;
DPRINTF((DBG_TIM,"SBPCD: datarate: %d\n", datarate));
if (datarate<65536) datarate=65536;
maxtim16=datarate*16;
maxtim04=datarate*4;
maxtim02=datarate*2;
maxtim_8=datarate/32;
#if MANY_SESSION
maxtim_data=datarate/100;
#else
maxtim_data=datarate/300;
#endif MANY_SESSION
DPRINTF((DBG_TIM,"SBPCD: maxtim_8 %d, maxtim_data %d.\n",
maxtim_8, maxtim_data));
#endif CDMKE
}
/*==========================================================================*/
static int check_version(void)
{
int i, j;
/* clear any pending error state */
clr_cmdbuf();
drvcmd[0]=0x82;
response_count=9;
flags_cmd_out=f_putcmd;
cmd_out();
/* read drive version */
clr_cmdbuf();
for (i=0;i<12;i++) infobuf[i]=0;
drvcmd[0]=0x83;
response_count=12;
flags_cmd_out=f_putcmd;
i=cmd_out();
if (i<0) DPRINTF((DBG_INI,"SBPCD: cmd_83 returns %d\n",i));
DPRINTF((DBG_INI,"SBPCD: infobuf = \""));
for (i=0;i<12;i++) DPRINTF((DBG_INI,"%c",infobuf[i]));
DPRINTF((DBG_INI,"\"\n"));
for (i=0;i<4;i++) if (infobuf[i]!=drive_family[i]) break;
if (i==4)
{
DS[d].drive_model[0]=infobuf[i++];
DS[d].drive_model[1]=infobuf[i++];
DS[d].drive_model[2]='-';
DS[d].drive_model[3]='x';
DS[d].drv_type=drv_new;
}
else
{
for (i=0;i<8;i++) if (infobuf[i]!=drive_vendor[i]) break;
if (i!=8) return (-1);
DS[d].drive_model[0]='2';
DS[d].drive_model[1]='x';
DS[d].drive_model[2]='-';
DS[d].drive_model[3]='x';
DS[d].drv_type=drv_old;
}
for (j=0;j<4;j++) DS[d].firmware_version[j]=infobuf[i+j];
j = (DS[d].firmware_version[0] & 0x0F) * 100 +
(DS[d].firmware_version[2] & 0x0F) *10 +
(DS[d].firmware_version[3] & 0x0F);
if (new_drive)
{
if (j<100) DS[d].drv_type=drv_099;
else DS[d].drv_type=drv_100;
}
else if (j<200) DS[d].drv_type=drv_199;
else if (j<201) DS[d].drv_type=drv_200;
else if (j<210) DS[d].drv_type=drv_201;
else if (j<211) DS[d].drv_type=drv_210;
else if (j<300) DS[d].drv_type=drv_211;
else DS[d].drv_type=drv_300;
return (0);
}
/*==========================================================================*/
static int switch_drive(int num)
{
int i;
d=num;
i=num;
if (sbpro_type) i=(i&0x01)<<1|(i&0x02)>>1;
OUT(CDo_enable,i);
DPRINTF((DBG_DID,"SBPCD: switch_drive: drive %d activated.\n",DS[d].drv_minor));
return (0);
}
/*==========================================================================*/
/*
* probe for the presence of drives on the selected controller
*/
static int check_drives(void)
{
int i, j;
char *printk_header="";
DPRINTF((DBG_INI,"SBPCD: check_drives entered.\n"));
ndrives=0;
for (j=0;j<NR_SBPCD;j++)
{
DS[j].drv_minor=j;
switch_drive(j);
DPRINTF((DBG_ID,"SBPCD: check_drives: drive %d activated.\n",j));
i=check_version();
DPRINTF((DBG_ID,"SBPCD: check_version returns %d.\n",i));
if (i>=0)
{
ndrives++;
DS[d].drv_options=drv_pattern[j];
if (!new_drive) DS[d].drv_options&=~(speed_auto|speed_300|speed_150);
printk("%sDrive %d: %s%.4s (%.4s)\n", printk_header,
DS[d].drv_minor,
drive_family,
DS[d].drive_model,
DS[d].firmware_version);
printk_header=" - ";
}
else DS[d].drv_minor=-1;
}
if (ndrives==0) return (-1);
return (0);
}
/*==========================================================================*/
#if 000
static void timewait(void)
{
int i;
for (i=0; i<65500; i++);
}
#endif 000
/*==========================================================================*/
#if FUTURE
/*
* obtain if requested service disturbs current audio state
*/
static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc)
{
switch (audio_state) /* audio status from controller */
{
case aud_11: /* "audio play in progress" */
case audx11:
switch (func) /* DOS command code */
{
case cmd_07: /* input flush */
case cmd_0d: /* open device */
case cmd_0e: /* close device */
case cmd_0c: /* ioctl output */
return (1);
case cmd_03: /* ioctl input */
switch (subfunc)
/* DOS ioctl input subfunction */
{
case cxi_00:
case cxi_06:
case cxi_09:
return (1);
default:
return (ERROR15);
}
return (1);
default:
return (ERROR15);
}
return (1);
case aud_12: /* "audio play paused" */
case audx12:
return (1);
default:
return (2);
}
}
#endif FUTURE
/*==========================================================================*/
/* allowed is only
* ioctl_o, flush_input, open_device, close_device,
* tell_address, tell_volume, tell_capabiliti,
* tell_framesize, tell_CD_changed, tell_audio_posi
*/
static int check_allowed1(u_char func1, u_char func2)
{
#if 000
if (func1==ioctl_o) return (0);
if (func1==read_long) return (-1);
if (func1==read_long_prefetch) return (-1);
if (func1==seek) return (-1);
if (func1==audio_play) return (-1);
if (func1==audio_pause) return (-1);
if (func1==audio_resume) return (-1);
if (func1!=ioctl_i) return (0);
if (func2==tell_SubQ_run_tot) return (-1);
if (func2==tell_cdsize) return (-1);
if (func2==tell_TocDescrip) return (-1);
if (func2==tell_TocEntry) return (-1);
if (func2==tell_subQ_info) return (-1);
if (new_drive) if (func2==tell_SubChanInfo) return (-1);
if (func2==tell_UPC) return (-1);
#else
return (0);
#endif 000
}
/*==========================================================================*/
static int check_allowed2(u_char func1, u_char func2)
{
#if 000
if (func1==read_long) return (-1);
if (func1==read_long_prefetch) return (-1);
if (func1==seek) return (-1);
if (func1==audio_play) return (-1);
if (func1!=ioctl_o) return (0);
if (new_drive)
{
if (func2==EjectDisk) return (-1);
if (func2==CloseTray) return (-1);
}
#else
return (0);
#endif 000
}
/*==========================================================================*/
static int check_allowed3(u_char func1, u_char func2)
{
#if 000
if (func1==ioctl_i)
{
if (func2==tell_address) return (0);
if (func2==tell_capabiliti) return (0);
if (func2==tell_CD_changed) return (0);
if (!new_drive) if (func2==tell_SubChanInfo) return (0);
return (-1);
}
if (func1==ioctl_o)
{
if (func2==DriveReset) return (0);
if (!new_drive)
{
if (func2==EjectDisk) return (0);
if (func2==LockDoor) return (0);
if (func2==CloseTray) return (0);
}
return (-1);
}
if (func1==flush_input) return (-1);
if (func1==read_long) return (-1);
if (func1==read_long_prefetch) return (-1);
if (func1==seek) return (-1);
if (func1==audio_play) return (-1);
if (func1==audio_pause) return (-1);
if (func1==audio_resume) return (-1);
#else
return (0);
#endif 000
}
/*==========================================================================*/
static int seek_pos_audio_end(void)
{
int i;
i=msf2blk(DS[d].pos_audio_end)-1;
if (i<0) return (-1);
i=xx_Seek(i,0);
return (i);
}
/*==========================================================================*/
static int ReadToC(void)
{
int i, j;
DS[d].diskstate_flags &= ~toc_bit;
DS[d].ored_ctl_adr=0;
for (j=DS[d].n_first_track;j<=DS[d].n_last_track;j++)
{
i=xx_ReadTocEntry(j);
if (i<0) return (i);
DS[d].TocBuffer[j].nixbyte=DS[d].TocEnt_nixbyte;
DS[d].TocBuffer[j].ctl_adr=DS[d].TocEnt_ctl_adr;
DS[d].TocBuffer[j].number=DS[d].TocEnt_number;
DS[d].TocBuffer[j].format=DS[d].TocEnt_format;
DS[d].TocBuffer[j].address=DS[d].TocEnt_address;
DS[d].ored_ctl_adr |= DS[d].TocEnt_ctl_adr;
}
/* fake entry for LeadOut Track */
DS[d].TocBuffer[j].nixbyte=0;
DS[d].TocBuffer[j].ctl_adr=0;
DS[d].TocBuffer[j].number=0;
DS[d].TocBuffer[j].format=0;
DS[d].TocBuffer[j].address=DS[d].size_msf;
DS[d].diskstate_flags |= toc_bit;
return (0);
}
/*==========================================================================*/
static int DiskInfo(void)
{
int i;
i=SetSpeed();
if (i<0)
{
DPRINTF((DBG_INF,"SBPCD: DiskInfo: first SetSpeed returns %d\n", i));
i=SetSpeed();
if (i<0)
{
DPRINTF((DBG_INF,"SBPCD: DiskInfo: second SetSpeed returns %d\n", i));
return (i);
}
}
i=xx_ModeSense();
if (i<0)
{
DPRINTF((DBG_INF,"SBPCD: DiskInfo: first xx_ModeSense returns %d\n", i));
i=xx_ModeSense();
if (i<0)
{
DPRINTF((DBG_INF,"SBPCD: DiskInfo: second xx_ModeSense returns %d\n", i));
return (i);
}
return (i);
}
i=xx_ReadCapacity();
if (i<0)
{
DPRINTF((DBG_INF,"SBPCD: DiskInfo: first ReadCapacity returns %d\n", i));
i=xx_ReadCapacity();
if (i<0)
{
DPRINTF((DBG_INF,"SBPCD: DiskInfo: second ReadCapacity returns %d\n", i));
return (i);
}
return (i);
}
i=xx_ReadTocDescr();
if (i<0)
{
DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadTocDescr returns %d\n", i));
return (i);
}
i=ReadToC();
if (i<0)
{
DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadToC returns %d\n", i));
return (i);
}
i=yy_CheckMultiSession();
if (i<0)
{
DPRINTF((DBG_INF,"SBPCD: DiskInfo: yy_CheckMultiSession returns %d\n", i));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -