home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
cdrom.zip
/
DDK
/
BASE
/
SRC
/
DEV
/
DASD
/
CDROM
/
MITSUMI
/
cdready.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-18
|
19KB
|
496 lines
#define INCL_DOSINFOSEG
#define INCL_NOPMAPI
#define INCL_NO_SCB
#define INCL_INITRP_ONLY
#include <os2.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <sas.h>
#include "devcmd.h"
#include "iorb.h"
#include "reqpkt.h"
#include "addcalls.h"
#include "dskinit.h"
#include <scsi.h>
#include <cdbscsi.h>
#include <cmd.h>
#include <devhelp.h>
#include <cdb.h>
#include "proto.h"
#include <string.h>
#include <memory.h>
extern PGINFOSEG near PGinfo;
extern ULONG near DevHlp;
extern PUCHAR near Read_IOBuffer;
extern USHORT near IrqNum;
extern USHORT near DrvBlockSize;
UCHAR PreviousOpCode,PreviousStatus;
extern UCHAR near Mode;
extern UCHAR near wDrvVer[4];
TOCINFO TOCInfoArea[101] = { {0,},};
UCHAR bPlayFlag = FALSE ;
UCHAR bPauseFlag = FALSE ;
UCHAR bChangeFlag ;
UCHAR bInfoFlag = 0 ;
UCHAR bMedChgFlag = CHANGED ;
UCHAR bMedChkFlag = FALSE ;
UCHAR bMedChkCalled = FALSE ;
UCHAR bStatus =0;
USHORT bStatusFlag=0;
extern UCHAR near bCFlag, near last_data_byte;
UCHAR TOC_Cache=0;
UCHAR bMinTno=0, bMaxTno =0,bChanged=0;
ULONG ulVSSize =0;
ULONG ulLeadOut =0;
UCHAR CD_ID=0;
USHORT wBlkLen =0;
ULONG Specialbuffer=NULL;
BOOL GetTocInfo()
{
USHORT i=0,state,First_Track_in_Session,Last_Track_in_Session,count,Status,q,Delta=0;
CDROMSTAT Data ;
BOOL Flag=FALSE,SeekRunning,ModeSetState;
ULONG Clock=0L,Addr;
UCHAR m,s,f;
#define NoneFound 0
#define FirstFound 1
#define LastFound 2
#define AllFound 3
#define MaxFound 7
#define LowTrack 0xa0
#define HighTrack 0xa1
#define BridgeTrk 0xb0
#define MaxTrack 0x99
CD_ID=0;
Addr=MinFrame;
newloop:;
SeekRunning=FALSE;
ModeSetState=FALSE;
for(i=0; i<5; i++)
{
DPRINTF(("Seeking to %08lX\n",Addr));
bStatusFlag=DriveCommand(Seek,Addr,NULL,NULL,(USHORT)NULL);
DPRINTF(("Seeking to %08lX status=%04X\n",Addr,bStatusFlag));
if( !COMMANDCHECK(bStatusFlag) && !TIMEOUT(bStatusFlag))
{
SeekRunning=TRUE;
break;
} /* end if */
else
{
DUMMYWAIT;
if(i==3)
{
bStatusFlag=DriveCommand(Stop,NULL,NULL,NULL,(USHORT)NULL);
bStatusFlag=DriveCommand(SetDriveMode,(ULONG)MuteData,NULL,NULL,(USHORT)NULL);
goto newloop;
} /* end if */
}
} /* end for */
if(SeekRunning)
{
for(i=0; i<8; i++)
{
DPRINTF(("Setting Drive mode\n"));
bStatusFlag=DriveCommand(SetDriveMode,(ULONG)(MuteData|TocData),NULL,NULL,(USHORT)NULL);
if(!COMMANDCHECK(bStatusFlag))
{
ModeSetState=TRUE;
break;
} /* end if */
} /* end for */
}
DUMMYWAIT;
if(SeekRunning)
{
DPRINTF(("Starting Track search for tracks %d thru %d\n", bMinTno+Delta,bMaxTno));
for(state=NoneFound,count=400,i=bMinTno+Delta;i<=bMaxTno && count ; count--)
{
DUMMYWAIT;
while(TIMEOUT(bStatusFlag=(UCHAR)(Status=DriveCommand(ReadSubQ,NULL,NULL,&Data,sizeof(Data.TrackInfo)))))
DUMMYWAIT;
DPRINTF(("SubqLoop status=%04X\n",bStatusFlag));
if(!TIMEOUT(Status))
{
if(!COMMANDCHECK(bStatusFlag) && !DISCCHANGE(bStatusFlag) && DISCIN(bStatusFlag) && !READERROR(bStatusFlag))
{
DPRINTF((" Q Status = %04X\n", bStatusFlag));
DPRINTF(("Track Q info TNO = %02X, AMin= %02X, Index = %02X ADR=%02X\n",
Data.TrackInfo.TNO,
BCD2Bin(Data.TrackInfo.AMin),
Data.TrackInfo.Index,
Data.TrackInfo.S.ADR));
if(Data.TrackInfo.TNO==0)
{
if(state!=MaxFound)
{
if(state!=AllFound)
{
if(Data.TrackInfo.Index==LowTrack)
{
if(!(state & FirstFound))
{
if(BCD2Bin(Data.TrackInfo.AMin)==i)
{
DPRINTF(("firsttrack index found = %d\n",BCD2Bin(Data.TrackInfo.AMin)));
First_Track_in_Session=BCD2Bin(Data.TrackInfo.AMin);
DPRINTF(("First=%d\n",First_Track_in_Session));
state |= FirstFound;
} /* end if */
} /* end if */
} /* end if */
else if(Data.TrackInfo.Index==HighTrack)
{
if(!(state & LastFound))
{
DPRINTF(("lasttrack index found = %d\n",BCD2Bin(Data.TrackInfo.AMin)));
Last_Track_in_Session=BCD2Bin(Data.TrackInfo.AMin);
DPRINTF(("Last=%d\n",Last_Track_in_Session));
state |= LastFound;
} /* end if */
} /* end else */
} /* end if */
else
{
if(Data.TrackInfo.Index<=MaxTrack)
{
if(i==BCD2Bin(Data.TrackInfo.Index))
{
DPRINTF(("Saving track info for Track %d\n",BCD2Bin(Data.TrackInfo.Index)));
TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].Control=Data.TrackInfo.S.Control;
TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].ADR=Data.TrackInfo.S.ADR;
TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].min=BCD2Bin(Data.TrackInfo.AMin);
TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].sec=BCD2Bin(Data.TrackInfo.ASec);
TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].frame=BCD2Bin(Data.TrackInfo.AFrame);
TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].start= MAKEULONG( MAKEUSHORT( BCD2Bin(Data.TrackInfo.AFrame),
BCD2Bin(Data.TrackInfo.ASec ) ),
MAKEUSHORT( BCD2Bin(Data.TrackInfo.AMin),
0 ) ) ;
DevHelp_RAS( 184 ,i , sizeof(TOCINFO), &TOCInfoArea[i]);
if(i==Last_Track_in_Session) // if last track in this session
{ // go for more
state=MaxFound;
DPRINTF(("Max Track in session found\n"));
Delta=i;
} /* end if */
i++;
} /* end if */
} /* end if */
} /* end else */
} /* end if */
else if(Data.TrackInfo.Index==BridgeTrk)
{
f =BCD2Bin(Data.TrackInfo.Frame);
s =BCD2Bin(Data.TrackInfo.Sec);
m =BCD2Bin(Data.TrackInfo.Min);
s +=2; // go two seconds into new area
if(s>=60) // if new seconds is >one minute would allow
{
m++; // adjust minutes
s-=60; // adjust downward seconds
} /* end if */
Addr=MAKEULONG( MAKEUSHORT(f,s ),
MAKEUSHORT(m,0));
DPRINTF(("Bridge track found = %08lX\n",Addr));
while(TIMEOUT(DriveCommand(SetDriveMode,(ULONG)MuteData,NULL,NULL,(USHORT)NULL)));
DUMMYWAIT;
DUMMYWAIT;
DUMMYWAIT;
DUMMYWAIT;
DUMMYWAIT;
DUMMYWAIT;
DUMMYWAIT;
DUMMYWAIT;
DPRINTF(("Seeking to last session now for tracks %d thru %d status=%04X\n",i,bMaxTno,bStatusFlag));
goto newloop;
} /* end if */
} /* end if */
} /* end if */
else
{
DevHelp_RAS( 183 ,0xaa , sizeof(PGinfo->msecs), &(PGinfo->msecs));
DPRINTF(("Aborting track search Status=%04X\n",bStatusFlag));
break;
} /* end else */
} /* end if */
else
{
DevHelp_RAS( 183 ,0xab , sizeof(PGinfo->msecs), &(PGinfo->msecs));
DPRINTF(("Aborting track search timeout Status=%04X\n",bStatusFlag));
break;
}
} /* end for */
}
bStatusFlag=DriveCommand(SetDriveMode,(ULONG)MuteData,NULL,NULL,(USHORT)NULL);
// bStatusFlag=DriveCommand(Stop,0,NULL,NULL,NULL);
if(count==0 && i<bMaxTno)
{
goto newloop;
} /* end if */
if(state==MaxFound)
{
DevHelp_RAS( 184 ,0xaa , sizeof(PGinfo->msecs), &(PGinfo->msecs));
Flag=TRUE;
} /* end if */
return Flag;
}
BOOL CacheTOC(PCDROMSTAT Data,UCHAR checksum)
{
BOOL Flag=TRUE;
DPRINTF(("Caching TOC\n"));
bInfoFlag &= CLR_VS; // clear the flag just to make sure
TOC_Cache=0; // clear toc indicator, just in case
ulVSSize = AdrRed2Hsg(MAKEULONG( MAKEUSHORT( BCD2Bin(Data->TOC.LeadoutFrame),
BCD2Bin(Data->TOC.LeadoutSec ) ),
MAKEUSHORT( BCD2Bin(Data->TOC.LeadoutMin),
0 ) ) )-1;
bMinTno =BCD2Bin(Data->TOC.FirstTrack);
bMaxTno =BCD2Bin(Data->TOC.LastTrack);
DPRINTF(("FirstTrack=%d LastTrack=%d\n",bMinTno,bMaxTno));
TOCInfoArea[0].min=BCD2Bin(Data->TOC.LeadoutMin);
TOCInfoArea[0].sec=BCD2Bin(Data->TOC.LeadoutSec );
TOCInfoArea[0].frame=BCD2Bin(Data->TOC.LeadoutFrame);
TOCInfoArea[0].ADR =0;
TOCInfoArea[0].Control=AUDIODISC(bStatusFlag) ? TCI_AUDIO : TCI_DATA;
DPRINTF((" Low & high track = %d %d status=%02X\n",bMinTno,bMaxTno,bStatusFlag));
ulLeadOut = MAKEULONG( MAKEUSHORT( BCD2Bin(Data->TOC.LeadoutFrame),
BCD2Bin(Data->TOC.LeadoutSec ) ),
MAKEUSHORT( BCD2Bin(Data->TOC.LeadoutMin),
0 ) ) ;
TOCInfoArea[bMaxTno+1].start=ulLeadOut; // start after last track, used in read SRD
TOCInfoArea[bMaxTno+1].Control=TCI_DATA; // start after last track, used in read SRD
DPRINTF(("Getting TrackInfo\n"));
SetDataMode(SuspendData);
if(GetTocInfo())
{
DPRINTF(("TrackInfo completed ok\n"));
bInfoFlag |= SET_VS ;
TOC_Cache=checksum;
Flag=FALSE;
if(TOCInfoArea[bMinTno].Control & TCI_DATA)
{
while(TIMEOUT(DriveCommand( DriveConfig,MODEFLAG ,0, 0, 0)))
DUMMYWAIT;
while(TIMEOUT(DriveCommand( DriveConfig,IRQFLAG ,IrqNum?(PreIrq|ErrIrq):0, 0, 0)))
DUMMYWAIT;
if (wDrvVer[0]=='D')
{
while(TIMEOUT(DriveCommand( DriveConfig,RETRYCOUNT ,3, 0, 0)))
DUMMYWAIT;
}
while(TIMEOUT(DriveCommand( SetDriveMode,MuteData ,0, 0, 0)))
DUMMYWAIT;
#ifndef TEST
#ifndef DEBUG
TryIrq(FALSE);
SpecialRead();
#endif
#endif
} /* end if */
}
else
{
DPRINTF(("TrackInfo failed\n"));
}
return Flag;
}
BOOL ReadyHardware( PIORBH pIORB, USHORT OpCode )
{
USHORT CmdCode = pIORB->CommandCode ;
USHORT SubCmd = pIORB->CommandModifier ;
CDROMSTAT Data ;
UCHAR i,temp ;
PUCHAR t;
for(i=1; i<15; i++)
{
bStatusFlag=DriveStatus(Spincount); // get drives status
if(COMMANDCHECK(bStatusFlag) || TIMEOUT(bStatusFlag) ||
((PreviousOpCode==SCSI_MODE_SELECT) && (LOBYTE(bStatusFlag)==0) && (PreviousStatus!=0))
)
{
DevHelp_RAS( 160 ,OpCode<<8 | bStatusFlag , sizeof(PGinfo->msecs), &(PGinfo->msecs));
DUMMYWAIT;
} /* end if */
else
{
break;
} /* end else */
} /* end for */
PreviousOpCode=OpCode;
PreviousStatus=LOBYTE(bStatusFlag);
DevHelp_RAS( 160 ,OpCode<<8 | bStatusFlag , sizeof(PGinfo->msecs), &(PGinfo->msecs));
if(!COMMANDCHECK(bStatusFlag)) // no command error
{
if(DISCIN(bStatusFlag)) // is there a disc in the drive?
{ // calculate checksum of toc data, should be only one match possible
// get TOC
if(!(bInfoFlag & SET_VS))
{
bPlayFlag = bPauseFlag = FALSE ;
bStatusFlag=DriveCommand(ReadToc,NULL,NULL,&Data,sizeof(Data.TOC));
if(!COMMANDCHECK(bStatusFlag) && !READERROR(bStatusFlag) && (Data.TOC.LastTrack<MaxTrack))
{
DevHelp_RAS( 184 ,0 , sizeof(Data.TOC), &Data);
DPRINTF(("Disk in drive\n"));
for(i=1,t=(PUCHAR)&Data,temp=*t,t++;i<sizeof(Data.TOC) ; i++,t++)
{
temp^=*t;
} /* end for */
DPRINTF(("Checksum=%02X==Saved=%02X\n",temp,TOC_Cache));
// if(temp==TOC_Cache) // does the checksum matched the saved one?
// {
// DPRINTF(("Checksums match\n"));
// bInfoFlag |= SET_VS ; // same disk as last time
// } /* end if */
// else
// {
DPRINTF(("Checksums do NOT match\n"));
IORB_CmdErr(IOERR_MEDIA_CHANGED, pIORB,SCSI_SK_UNITATTN,ASC_MEDIUM_CHANGED);
if(CacheTOC(&Data,temp)) // did caching go ok?
{
DPRINTF(("Caching failed?\n"));
switch (OpCode) // no failures for some non-disk dependant opcodes
{
case SCSI_READ_CAPACITY:
case SCSI_MODE_SELECT:
case SCSI_MODE_SENSE:
break;
default:
IORB_CmdErr(IOERR_UNIT_NOT_READY, pIORB,SCSI_SK_NOTRDY,0);
DevHelp_RAS( 162 ,OpCode<<8 | bStatusFlag , sizeof(PGinfo->msecs), &(PGinfo->msecs));
return TRUE;
break;
} /* endswitch */
} /* end if */
// } /* end else */
} /* end if */
else
{
DPRINTF(("TOC failed status=%02X\n",bStatusFlag));
DevHelp_RAS( 183 ,0xaa , sizeof(PGinfo->msecs), &(PGinfo->msecs));
IORB_CmdErr(IOERR_UNIT_NOT_READY, pIORB,SCSI_SK_NOTRDY,0);
DevHelp_RAS( 162 ,OpCode<<8 | bStatusFlag , sizeof(PGinfo->msecs), &(PGinfo->msecs));
return TRUE;
} /* end else */
} /* end if */
} /* end if */
else
{
DPRINTF(("NO Disk in drive\n"));
bPlayFlag = bPauseFlag = FALSE ;
switch (OpCode) // no failures for some non-disk dependant opcodes
{
case SCSI_MODE_SELECT:
case SCSI_MODE_SENSE:
case SCSI_LOCK_UNLOCK:
case SCSI_START_STOP_UNIT:
case ADD_READ_DISK_INFO: //rme - fix for photo CD
break;
default:
IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, pIORB,SCSI_SK_NOTRDY,0);
DevHelp_RAS( 162 ,OpCode<<8 | bStatusFlag ,sizeof(PGinfo->msecs), &(PGinfo->msecs) );
return TRUE;
break;
} /* endswitch */
} /* end else */
} /* end if */
else // no disc present
{
DPRINTF(("Drive Status Command failed %02X\n",bStatusFlag));
switch (OpCode) // no failures for some non-disk dependant opcodes
{
case SCSI_READ_CAPACITY:
case SCSI_MODE_SELECT:
case SCSI_MODE_SENSE:
break;
default:
IORB_CmdErr(IOERR_UNIT_NOT_READY, pIORB,SCSI_SK_NOTRDY,0);
DevHelp_RAS( 162 ,OpCode<<8 | bStatusFlag , sizeof(PGinfo->msecs), &(PGinfo->msecs));
return TRUE;
break;
} /* endswitch */
} /* end else */
return FALSE;
}
void SpecialRead( void)
{
USHORT Status,i;
CDROMSTAT c;
UCHAR CurrentMode=Mode1;
#define SpecialAddr 0x00000210L
PRawSector SpecialBuffer;
do
{
DUMMYWAIT;
Status=DriveCommand( ModeSet,Mode1 ,0, 0, 0); // set mode 1 first
Mode = Mode1;
} while (TIMEOUT(Status)); /* end do */
DriveCommand( SetDriveMode,DataLength|EccBit|MuteData ,0, 0, 0);
if(!Specialbuffer)
{
#if defined(DEBUG) | defined(TEST)
Specialbuffer=malloc(sizeof(RawSector));
#else
DevHelp_AllocPhys(sizeof(RawSector),0, (PULONG)&Specialbuffer);
#endif
} /* end if */
if(Specialbuffer)
{
#if defined(DEBUG) | defined(TEST)
SpecialBuffer=(PRawSector)Specialbuffer;
#else
DevHelp_PhysToGDT((ULONG)Specialbuffer, sizeof(RawSector), FP_SEG(Read_IOBuffer));
SpecialBuffer=(PRawSector)Read_IOBuffer;
#endif
for(i=0; i<2; i++)
{
Status=DriveCommand( Read, SpecialAddr, 1,(PCDROMSTAT)SpecialBuffer ,sizeof(RawSector)); // read
if(!READERROR(Status) && !COMMANDCHECK(Status) && !TIMEOUT(Status))
{
if(Mode==Mode2)
{
DriveCommand( SetDriveMode,TestMode|MuteData ,0, 0, 0);
while(TIMEOUT(DriveCommand( DriveConfig,BLOCKSIZE ,DrvBlockSize, 0, 0)))
DUMMYWAIT;
break;
} /* end if */
else
{
Status=DriveCommand( ModeSet,Mode1 ,0, 0, 0); // try mode 2 now
DriveCommand( SetDriveMode,MuteData ,0, 0, 0);
break;
} /* end else */
} /* end if */
else
{
Mode=Mode2;
Status=DriveCommand( ModeSet,Mode2 ,0, 0, 0); // try mode 2 now
} /* end else */
} /* end for */
} /* end if */
}