中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
作者:
标题: cd-rom驱动的源代码(未测试) 上一主题 | 下一主题
070
高级用户

苏醒的沉睡者


积分 659
发帖 217
注册 2003-2-15
来自 福建
状态 离线
『楼 主』:  cd-rom驱动的源代码(未测试)

/* CD-ROM low level driver 0.00a
/* 80x86-version
/*
/* Written by V.M.G.van Acht
/* (c) 1998 by Octagone
/*
*/

#include "stdio.h"

/* prototypes								*/
void		Wait		(unsigned int count);
unsigned int 	ReadIDEReg	(unsigned int regnum);
void 		WriteIDEReg	(unsigned int regnum,unsigned int data);
int		WriteIDECommand (unsigned int *data,unsigned int devnum);
int        	ReadIDEData	(unsigned int *data,unsigned int len);
int		WriteATAPICommand(unsigned char *data,unsigned int devnum,unsigned int maxlen);
int		ReadATAPIData	(unsigned char *data,unsigned int len);
int		WriteATAPIData	(unsigned char *data,unsigned int len);
struct structATAPIError	        ATAPIError	(unsigned char devnum);
int 		PlayAudio	(unsigned long startsect,unsigned long endsect,unsigned int devnum);
int		StopAudio	(unsigned int devnum);
int		PauseAudio	(unsigned int OnOff,unsigned int devnum);
int		SetCDSpeed	(unsigned int speed,unsigned int devnum);
unsigned long	LBA2MSF		(unsigned long LBA);
unsigned long	MSF2LBA		(unsigned long MSF);
void		PrintMSF	(unsigned long MSF,int flag);
int		ReadCDSector	(unsigned long sectnum,unsigned char *data,unsigned int len,unsigned int devnum);
void 		PrintText	(unsigned int *data,unsigned int len);
void		PrintFileName	(unsigned char *data,unsigned char DOSJolietRomeo);
int  		ReadTOC		(unsigned char *data,struct structISOHdr *ISOHdr,unsigned long *DirTable,unsigned int devnum);
int		ReadISOHdr	(unsigned long sector,struct structISOHdr *ISOHdr,unsigned long *DirTable,unsigned int devnum);
void		ResetInquiry	(unsigned long *DirTable,unsigned int devnum);
unsigned int	SearchDir	(unsigned long *DirTable);
int		Inquiry		(unsigned long *DirTable,unsigned char *SourceName,unsigned char *data,unsigned int devnum);
int		ChangeDirectory (unsigned long *DirTable,unsigned char *SourceName,unsigned int devnum);
int		ChangeDirectoryUp(unsigned long *DirTable,unsigned int devnum);
int		OpenFile	(unsigned long *DirTable,unsigned char *SourceName,unsigned char *FilePointer,unsigned int devnum);
int		ReadFileBytes	(unsigned char *FilePointer,unsigned int length,unsigned char *data);
int		NameMatch	(unsigned char *SourceName,unsigned char *CheckName,unsigned char DOSJolietRomeo);
void		CopyBytes	(unsigned char *source,unsigned char *dest,unsigned int len);
unsigned long	Char2Long	(unsigned char *bytes);
unsigned int	Char2Int	(unsigned char *bytes);
void		Int2Char	(unsigned int value,unsigned char *bytes);
void		Long2Char	(unsigned long value,unsigned char *bytes);
unsigned long	Char2LongMSBLSB (unsigned char *bytes);
unsigned int	Char2IntMSBLSB	(unsigned char *bytes);
void		Int2CharMSBLSB	(unsigned int value,unsigned char *bytes);
void		Long2CharMSBLSB	(unsigned long value,unsigned char *bytes);

/* structures                                                   	*/

struct	     structFileTime
	     {
	      unsigned char	Year;
	      unsigned char	Month;
	      unsigned char	Day;
	      unsigned char	Hour;
	      unsigned char	Minute;
	      unsigned char	Second;
	      signed char	Greenwich;
	     };

struct	     structHdrTime
	     {
	      unsigned char Year[4];
	      unsigned char Month[2];
	      unsigned char Day[2];
	      unsigned char Hour[2];
	      unsigned char Minute[2];
	      unsigned char Second[2];
	      unsigned char Hundredth[2];
	      char	    Greenwich;
	     };

struct	     structDirRecord
	     {
	      unsigned char     RecordLen;
	      unsigned char	ExtAttributeLen;
	      unsigned long     LocationExtent;
	      unsigned long	DataLen;
	      struct structFileTime DateTime;
	      unsigned char	FileFlags;
	      unsigned char	FileUnitSize;
	      unsigned char	InterleaveGapSize;
	      unsigned int	VolumeSequenceNumber;
	      unsigned char	FileIdentifierLen;
	      unsigned char     FileIdentifier[256];
	     };


struct	     structISOHdr
	     {
	      unsigned char     StructureVersion;
	      unsigned long	VolumeSpaceSize;
	      unsigned int 	VolumeSetSize;
	      unsigned int  	VolumeSequenceNumber;
	      unsigned int  	LogicalBlockSize;
	      unsigned long 	PathTableSize;
	      unsigned long 	LocationLPathTable;
	      unsigned long 	LocationOptionLPathTable;
	      unsigned long 	LocationMPathTable;
	      unsigned long     LocationOptionMPathTable;
	      struct structDirRecord RootDir;
	      unsigned char	BootSystemIdentifier[32];
	      unsigned char	BootIdentifier[32];
	      unsigned char	SystemIdentifier[32];
	      unsigned char	VolumeIdentifier[32];
	      unsigned char     VolumeSetIdentifier[128];
	      unsigned char	PublisherIdentifier[128];
	      unsigned char	PreparerIdentifier[128];
	      unsigned char	ApplicationIdentifier[128];
	      unsigned char	CopyrightIdentifier[37];
	      unsigned char	AbstractIdentifier[37];
	      unsigned char	BibliographicIdentifier[37];
	      struct structHdrTime CreationDateTime;
	      struct structHdrTime ModificationDateTime;
	      struct structHdrTime ExpirationDateTime;
	      struct structHdrTime EffectiveDateTime;
	      unsigned char	DOSJolietRomeo;  /* 0x00=DOS
						    0x40=Joliet UCS-2 level 1
						    0x43=Joliet UCS-2 level 2
						    0x45=Joliet UCS-2 level 3
						*/
	     };

struct       structCache
	     {
	      unsigned char	DeviceNumber;
	      unsigned long	SectorNumber;
	      unsigned char     SectorCount;
	      unsigned char	*MemoryLocation;
	     };

struct	     structATAPIErrorText
	     {
	      unsigned char	ErrorNumber;
	      unsigned char	ErrorSubNumber;
	      unsigned char	SolutionNumber;
				/* 0=no solution presented
				   1=do not consider as error
				   2=continue
				   3=retry
				   4=reset & retry
				   5=fail & continu
				   6=user intervention & retry
				   7=fail, user intervention & continue
				   8=ask user
				   9=abort
				   ff=software failure
				*/
	      unsigned char	SolutionSubNumber;
				/* Solutionnumber.SolutionSubNumber
				   0.
				   1.
				   2.
				   3.
				   4.
				   5.0=fail & continu (on next LogicalBlock)
				   5.1=fail & continu (on next LogicalSector)
				   5.2=fail & continu (on next file)
				   6.
				   7.
				   8.
				   9.
				   ff.0=ATAPI device failure
				   ff.1=Host failure
				*/
	      unsigned char     Text[25];
	     };

struct structATAPIError
	     {
	      unsigned char              Flag;
		       /*   Flag   76543210
				   xxxxxxx0=no error
				   xxxxxxx1=error
				   xxxxxx0x=pointer valid
				   xxxxxx1x=pointer not valid
				   xxxxx0xx=sense key valid
				   xxxxx1xx=sense key not valid
				   xxxx0xxx=current error
				   xxxx1xxx=deferred error
			    Pointer to ErrorText
		       */
	      unsigned char               SenseKey;
	      unsigned char               AdditionalSenseKey;
	      unsigned char               AdditionalSenseKeyQualifier;
	      unsigned char		  SolutionNumber;
	      unsigned char		  SolutionSubNumber;
	      struct structATAPIErrorText *Text;
	     };

struct structCDPosition
	     {
	      unsigned long Absolute;
	      unsigned long Relative;
	      unsigned char Track;
	      unsigned char Index;
	     };

struct structCDNumber
	     {
	      int Flag;	/* 0:number=valid
			   1:number=not valid
			  -1:hardware error */
	      unsigned char Number[14];
	     };


/* declarations 							*/
const
unsigned int IDEport=0X170,	/* IDE port 0=0x1F0, 1=0x170     	*/
	     IDERegData=0,  	/* number of IDE registers		*/
	     IDERegError=1,
	     IDERegFeature=1,
	     IDERegSectCount=2,
	     IDERegSectNum=3,
	     IDERegCylLow=4,
	     IDERegCylHigh=5,
	     IDERegDevHead=6,
	     IDERegStatus=7,
	     IDERegCommand=7,
	     IDERegAltStatus=14,
	     IDERegAdres=15;

const
struct structATAPIErrorText ATAPIErrorText[]=
	     {
	      {0x00,0x00,0,0,"No additional info      "},
	      {0x00,0x11,1,0,"Audio play in progress  "},
	      {0x00,0x12,1,0,"Audio play paused       "},
	      {0x00,0x13,1,0,"Audio play completed    "},
	      {0x00,0x14,9,0,"Audio play error        "},
	      {0x00,0x15,1,0,"No audio play status    "},
	      {0x01,0x00,9,0,"Mechanical error        "},
	      {0x02,0x00,0,0,"No seek complete        "},
	      {0x04,0x00,8,0,"Not ready               "},
	      {0x04,0x01,1,0,"Not ready, in progress.."},
	      {0x04,0x02,4,0,"Not ready, reinitialize "},
	      {0x04,0x03,6,0,"Not ready, manual interv"},
	      {0x04,0x04,1,0,"Not ready, formatting   "},
	      {0x05,0x00,0,0,"No response to selection"},
	      {0x05,0x01,9,0,"Load/eject failure      "},
	      {0x06,0x00,9,0,"No reference position   "},
	      {0x08,0x00,9,0,"Communication failure   "},
	      {0x08,0x01,9,0,"Communication timed out "},
	      {0x08,0x02,9,0,"Communication bad parity"},
	      {0x09,0x00,3,0,"Tracking error          "},
	      {0x09,0x01,8,0,"Tracking servo failure  "},
	      {0x09,0x02,8,0,"Focus servo failure     "},
	      {0x09,0x03,8,0,"Spindle servo failure   "},
	      {0x11,0x00,3,0,"Unrecovered read error  "},
	      {0x11,0x06,3,0,"CIRC unrecovered error  "},
	      {0x15,0x00,3,0,"Random position error   "},
	      {0x15,0x01,8,0,"Mechanical error        "},
	      {0x15,0x02,3,0,"Random position error   "},
	      {0x17,0x00,1,0,"Recovered, no correction"},
	      {0x17,0x01,1,0,"Recovered, retries      "},
	      {0x17,0x02,1,0,"Recovered, + head offset"},
	      {0x17,0x03,1,0,"Recovered, - head offset"},
	      {0x17,0x04,1,0,"Recovered, retries/CIRC "},
	      {0x17,0x05,1,0,"Recovered, previous ID  "},
	      {0x18,0x00,1,0,"Recovered, correction   "},
	      {0x18,0x01,1,0,"Recovered, reties/correc"},
	      {0x18,0x02,1,0,"Recovered, auto realloc "},
	      {0x18,0x03,1,0,"Recovered, CIRC         "},
	      {0x18,0x04,1,0,"Recovered, L-EC         "},
	      {0x1A,0x00,0xFF,1,"Bad parameterlist length"},
	      {0x20,0x00,0xFF,1,"Invalid command         "},
	      {0x21,0x00,0xFF,1,"Bad logical block number"},
	      {0x24,0x00,0xFF,1,"Invalid field in packet "},
	      {0x25,0x00,0,0,"No logical unit support "},
	      {0x26,0x00,0xFF,1,"Invalid field in paramet"},
	      {0x26,0x01,0xFF,1,"Parameter not supported "},
	      {0x26,0x02,0xFF,1,"Bad parameter value     "},
	      {0x28,0x00,0,0,"Medium may have changed "},
	      {0x29,0x00,1,0,"Reset occured           "},
	      {0x2A,0x00,1,0,"Parameters changed      "},
	      {0x2A,0x01,1,0,"Mode parameters changed "},
	      {0x30,0x00,8,0,"Incompatible medium     "},
	      {0x30,0x01,8,0,"Unknown format medium   "},
	      {0x30,0x02,8,0,"Incompatible format     "},
	      {0x39,0x00,9,0,"No saving support       "},
	      {0x3A,0x00,1,0,"No medium               "},
	      {0x3A,0x01,1,0,"No medium, tray closed  "},
	      {0x3A,0x02,1,0,"No medium, tray opened  "},
	      {0x3E,0x00,1,0,"Not self-configured yet "},
	      {0x3F,0x00,1,0,"Operate condition change"},
	      {0x3F,0x01,1,0,"Microcode changed       "},
	      {0x3F,0x03,1,0,"Inquiry data changed    "},
	      {0x40,0xFF,0xFF,0,"Self test failed        "},
	      {0x44,0x00,0xFF,0,"Internal error          "},
	      {0x4C,0x00,0xFF,0,"Failed self-config      "},
	      {0x4E,0x00,0xFF,1,"Overlap command attempt "},
	      {0x53,0x00,9,0,"Load/eject failure      "},
	      {0x53,0x02,0,0,"Medium removal prevented"},
	      {0x57,0x00,8,0,"TOC load error          "},
	      {0x5A,0x00,0,0,"Operator request        "},
	      {0x5A,0x01,0,0,"Medium removal request  "},
	      {0x63,0x00,0xFF,1,"End of user area error  "},
	      {0x64,0x00,0xFF,1,"Illegal track mode      "},
	      {0xB9,0x00,0,0,"Audio play aborted      "},
	      {0xBF,0x00,3,0,"Loss of streaming       "},
	      {0xFF,0xFF,0,0,"                        "}
	     };
/*                            123456789012345678901234567890


/* global variables 							*/
unsigned int IDENop        [6]    ={0,0,0,0,0xA0,0X00},
	     IDEATAPIReset [6]    ={0,0,0,0,0XA0,0X08},
	     IDEDiagnostic [6]    ={0,0,0,0,0XA0,0X90},
	     IDEATAPIPacket[6]    ={0,0,0,0,0XA0,0XA0},
	     IDEATAPIIdent [6]    ={0,0,0,0,0XA0,0XA1},
	     IDEStandbyImm [6]    ={0,0,0,0,0XA0,0XE0},
	     IDEIdleImm	   [6]    ={0,0,0,0,0XA0,0XE1},
	     IDECheckpower [6]    ={0,0,0,0,0XA0,0XE5},
	     IDESleep      [6]    ={0,0,0,0,0XA0,0XE6},
	     IDESetFeatures[6]    ={0,0,0,0,0XA0,0XEF};
unsigned char
	     ATAPIRequestSense[12]={0X03,0,0,0,18,0,0,0,0,0,0,0},
	     ATAPIStartStopUnit[12]={0X1B,1,0,0,0,0,0,0,0,0,0,0},
	     ATAPIRead10      [12]={0X28,0,0,0,0,0,0,0,0,0,0,0},
	     ATAPIReadSubChan1[12]={0X42,0,0x40,1,0,0,0,0,16,0,0,0},
	     ATAPIReadSubChan2[12]={0x42,0,0x40,2,0,0,0,0,24,0,0,0},
	     ATAPIReadSubChan3[12]={0x42,0,0x40,3,0,0,0,0,24,0,0,0},
	     ATAPIReadTOC     [12]={0X43,0,0,0,0,0,0,0X03,0X24,0,0,0},
	     ATAPIPlayAudioMSF[12]={0X47,0,0,0,0,0,0,0,0,0,0,0},
	     ATAPIPauseAudio  [12]={0X4B,0,0,0,0,0,0,0,0,0,0,0},
	     ATAPIStopAudio   [12]={0X4E,0,0,0,0,0,0,0,0,0,0,0},
	     ATAPISetSpeed    [12]={0XBB,0,0,0,0,0,0,0,0,0,0,0};

struct structCache SectorCache;	/* SectorBuffer Cache			*/

unsigned int Device0Data[256],  /* Table for device data for dev0	*/
	     Device1Data[256];  /* Table for device data for dev1	*/
unsigned char
	     Device0TOC[804],   /* Table for device 0 TOC               */
	     Device1TOC[804],   /* Table for device 1 TOC		*/
	     SectorBuf[2048];	/* Temporary buffer			*/

struct structISOHdr Device0ISOHdr; /*Table for device 0 ISO header	*/
struct structISOHdr Device1ISOHdr; /*Table for device 1 ISO header	*/

unsigned long
	     Device0DirTable[36], /* Table with Sectornumbers of Dirs
				     WARNING: SECTOR numbers not Logical Block Numbers !!!
				     +32=current sectornumber current dir
				     +33=current length current dir
				     +34=current byte counter current dir
				     +35=DOSJolietRomeo
				     +36=Logical Block Size
									*/
	     Device1DirTable[36]; /* Table with Sectornumbers of Dirs   */

unsigned int NumDevice;


/************************************************************************/

void		Test		(unsigned char *ATAPICommand)
{
 unsigned int i;

 for (i=0;i<12;i++)
   {
    printf("%X-",*(ATAPICommand+i));
   }
}

void		PrintLong	(unsigned long var)
{
 printf("%X",var>>16);
 printf("%X",var&0xFFFF);
}



void            Wait            (unsigned int counter)
/* Wait
*/
{
 unsigned int i;
 while (counter>0)
   {counter--;
    i=0Xffff;
    while (i!=0)
      {i--;}
   }
}

unsigned char   WaitKey		()
/* Wait for a key press
   in:  nothing
   out: key
*/
{
 unsigned int i;

 printf("\nPress any key to continu...");
 while ((i=getch())==EOF)
  {}
 return(i);
}


unsigned int 	ReadIDEReg	(unsigned int regnum)
/* Read value of IDE register (LOW-LEVEL)
   in: number of register:  0=data register (16 bit)
			    1=error register
			    2=sector count register
			    3=sector number register
			    4=cylinder register (LSB)
			    5=cylinder register (MSB)
			    6=drive/head register
			    7=status register
			    8=Not used
			    9=not used
			   10=not used
			   11=not used
			   12=not used
			   13=not used
			   14=alternate status register
			   15=adres register
   out:value
*/
{
 unsigned int i,j;

 if (regnum>=8) {i=IDEport+regnum+0X1F8;}
		else {i=IDEport+regnum;}
 asm {
      MOV DX,(i)
      IN AX,DX
      MOV (j),AX
     }
 return(j);
}

void 		WriteIDEReg	(unsigned int regnum, unsigned int data)
/* Write value to IDE register (LOW-LEVEL)
   in: number of register:  0=data register (16 bit)
			    1=feature register
			    2=sector count register
			    3=sector number register
			    4=cylinder register (LSB)
			    5=cylinder register (MSB)
			    6=drive/head register
			    7=command register
			    8=Not used
			    9=not used
			   10=not used
			   11=not used
			   12=not used
			   13=not used
			   14=control register
			   15=not used
       data
*/
{
 unsigned int i,j;

 if (regnum>=8) {i=IDEport+regnum+0X1F8;}
		else {i=IDEport+regnum;}
 j=data;
 asm {
      MOV DX,(i)
      MOV AX,(j)
      OUT DX,AX
     }
}

int		WriteIDECommand (unsigned int *data,unsigned int devnum)
/* Write IDE Command
   in: 	data 	= pointer to 6 unsigned int with values for reg 2-reg7
	devnum  = device number 0/1
   out:	0	= OK
	-1	= error
*/

{
 unsigned int i,j;

 i=0;
 do
   {
    if (i==0XFFFF)
      {
       return(-1);
      }
    i++;
   }
 while ((ReadIDEReg(IDERegStatus)&0X80)!=0);
 WriteIDEReg(IDERegDevHead,(*(data+4)+(devnum<<4)));

 i=0;
 do
   {
    if (i==0XFFFF)
      {
       return(-1);
      }
    i++;
   }
 while ((ReadIDEReg(IDERegStatus)&0XC0)!=0X40);

 for (i=0;i<4;i++)
   {
    WriteIDEReg(i+2,*(data+i));
   }
 WriteIDEReg(IDERegCommand,*(data+5));
 return(0);
}

int        	ReadIDEData	(unsigned int *data,unsigned int len)
/* Read IDE (16 bit) data from data-register
   in:  *data 	= pointer where data is to be located
	len   	= maximum number of words
   out: -1    	= error
	 0    	= OK
*/
{
 unsigned int i,j;

 i=0;
 do
   {
    if (i==0XFFFF)
      {
       return(-1);
      }
    if ((ReadIDEReg(7)&0x01)!=0)
      {
       return(-1);};
      }
  while ((ReadIDEReg(7)&0x80)!=0);

  if ((ReadIDEReg(7)&0x08)!=0x08)
    {
     return(-1);
    }

  while (len!=0)
   {
    *data=ReadIDEReg(0);
    len--;
    data++;
   }
 return(0);
}

int		WriteATAPICommand(unsigned char *data,unsigned int devnum,unsigned int maxlen)
/* Write ATAPI Command
   in:	*data = pointer to unsigned char array [12] with command arguments
	MaxLen = maximum number of bytes to be transfered in 1 time (0xffff allowed)
	DriveNum = drive number 0/1
   out: -1    = error
	 0    = OK
*/
{
 unsigned int i;

 i=0;
 do
   {
    if (i==0XFFFF)
      {
       return(-1);
      }
    i++;
   }
 while ((ReadIDEReg(IDERegStatus)&0X80)!=0);
 WriteIDEReg(IDERegDevHead,(0XA0+(devnum<<4)));

 i=0;
 do
   {
    if (i==0XFFFF)
      {
       return(-1);
      }
    i++;
   }
 while ((ReadIDEReg(IDERegStatus)&0X80)!=0);

 WriteIDEReg(IDERegCylLow,maxlen&0XFF);
 WriteIDEReg(IDERegCylHigh,maxlen>>8);
 WriteIDEReg(IDERegCommand,0XA0);

 i=0;
 do
    {
     if (i==0XFFFF)
       {
	return(-1);
       }
     if ((ReadIDEReg(IDERegStatus)&0x01)!=0)
       {
	return(-1);
       }
    }
 while ((ReadIDEReg(IDERegStatus)&0x08)==0);

 for (i=1;i<=6;i++)
   {
    WriteIDEReg(IDERegData,*(data+0)+(*(data+1)<<8));
    data=data+2;
   }
 return(0);
}

int		ReadATAPIData	(unsigned char *data,unsigned int len)
/* Read ATAPI data from data-register to CHAR array
   in:	*data = pointer to unsigned char array where data is to be located
	len   = number of WORDS
   out: -1    = error
	 0    = OK
*/
{
 unsigned int i,j,k;

    i=0;
    do
      {
       if (i==0XFFFF)
	 {
	  return(len);
	 }
       if ((ReadIDEReg(IDERegStatus)&0x01)!=0)
	 {
	  return(-1);
	 }
       i++;
      }
    while ((ReadIDEReg(IDERegStatus)&0x08)==0);

    do
      {
       k=(ReadIDEReg(4)&0XFF)+((ReadIDEReg(5)&0XFF)<<8);
       do
	 {
	  if (len==0)
	    {
	     return(0);
	    }
	  i=ReadIDEReg(IDERegData);
	  *data=i&0xff;
	  data++;
	  *data=i>>8;
	  len--;
	  k--;
	  data++;
	 }
       while (k!=0);
      }
    while ((ReadIDEReg(IDERegStatus)&0X08)!=0);
  return(0);
}

int		WriteATAPIData	(unsigned char *data,unsigned int len)
/* Write ATAPI data to data-register to CHAR array
   in:	*data = pointer to unsigned char array with data
	len   = number of WORDS to write
   out:  -1   = error
	  0   = OK
*/
{
 unsigned int i,j,k;

    i=0;
    do
      {
       if (i==0)
	 {
	  return(len);
	 }
       if ((ReadIDEReg(IDERegStatus)&0x01)!=0)
	 {
	  return(-1);
	 }
       i++;
      }
    while ((ReadIDEReg(IDERegStatus)&0x08)==0);

    do
      {
       k=(ReadIDEReg(4)&0XFF)+((ReadIDEReg(5)&0XFF)<<8);
       do
	 {
	  if (len==0)
	    {
	     return(0);
	    }
	  WriteIDEReg(IDERegData,*data+(*(data+1)<<8));
	  len--;
	  k--;
	  data=data+2;
	 }
       while (k!=0);
      }
    while ((ReadIDEReg(IDERegStatus)&0X08)!=0);
    return(0);
}

struct structATAPIError	        ATAPIError	(unsigned char devnum)
/* Check if there is an ATAPI-error pending
   in:  devnum		 = device number 0/1
   out:	structATAPIError =  Flag   76543210
				   xxxxxxx0=no error
				   xxxxxxx1=error
				   xxxxxx0x=pointer valid
				   xxxxxx1x=pointer not valid
				   xxxxx0xx=sense key valid
				   xxxxx1xx=sense key not valid
				   xxxx0xxx=current error
				   xxxx1xxx=deferred error
			    SenseKey
			    AdditionalSenseKey
			    AdditionalSenseKeyQualifier
			    Pointer to ErrorText
*/
{
 unsigned int  i;
 unsigned char temp[256],*j;
 struct structATAPIError ReturnValue;

 ReturnValue.Flag=0x07;
 i=0;
 do
   {
    if (i==0XFFFF)
      {
       return(ReturnValue);
      }
    i++;
   }
 while ((ReadIDEReg(IDERegStatus)&0X80)!=0);
 WriteIDEReg(IDERegDevHead,(0XA0+(devnum<<4)));

 i=0;
 do
   {
    if (i==0XFFFF)
      {
       return(ReturnValue);
      }
    i++;
   }
 while ((ReadIDEReg(IDERegStatus)&0X80)!=0);

 ReturnValue.Flag=ReturnValue.Flag&(ReadIDEReg(IDERegStatus)&0x01);
 WriteATAPICommand(ATAPIRequestSense,devnum,128);
 if (ReadATAPIData(temp,128)==0)

   {
    ReturnValue.Flag=ReturnValue.Flag&0xfb;
    ReturnValue.Flag=ReturnValue.Flag|(*(temp+2)>>2);
    ReturnValue.SenseKey=*(temp+2)&0x0f;
    ReturnValue.AdditionalSenseKey=*(temp+12);
    ReturnValue.AdditionalSenseKeyQualifier=*(temp+13);

    for (j=ATAPIErrorText;((*j!=0xff) || (*(j+1)!=0xff));j=j+29)
      {
       if ((*j==ReturnValue.AdditionalSenseKey) && (*(j+1)==ReturnValue.AdditionalSenseKeyQualifier))
	 {
	  ReturnValue.Flag=ReturnValue.Flag&0xfd;
	  ReturnValue.SolutionNumber=*(j+2);
	  ReturnValue.SolutionSubNumber=*(j+3);
	  ReturnValue.Text=j+4;
	  return(ReturnValue);
	 }
      }
   }
 return(ReturnValue);
}

int 		PlayAudio	(unsigned long startsect,unsigned long endsect,unsigned int devnum)
/* Play Audio
   in: startsect = start sector (logical block)
       endsect   = end sector   (logical block)
       devnum    = device number 0/1
   out:        0 = OK
	      -1 = error
*/
{
 unsigned long i;

 i=LBA2MSF(startsect);
 ATAPIPlayAudioMSF[3] = (i&0x00ff0000)>>16;
 ATAPIPlayAudioMSF[4] = (i&0x0000ff00)>>8;
 ATAPIPlayAudioMSF[5] = (i&0x000000ff);
 i=LBA2MSF(endsect);
 ATAPIPlayAudioMSF[6] = (i&0x00ff0000)>>16;
 ATAPIPlayAudioMSF[7] = (i&0x0000ff00)>>8;
 ATAPIPlayAudioMSF[8] = (i&0x000000ff);

 return(WriteATAPICommand(ATAPIPlayAudioMSF,devnum,0XFFFF));
}

int		StopAudio	(unsigned int devnum)
/* Stop Audio
   in: devnum    = device number 0/1
   out:        0 = OK
	      -1 = error
*/
{
 return(WriteATAPICommand(ATAPIStopAudio,devnum,0XFFFF));
}

int		PauseAudio	(unsigned int OnOff,unsigned int devnum)
/* Pause Audio
   in: OnOff   0 = pause
	       1 = resume
       devnum    = device number 0/1
   out:        0 = OK
	      -1 = error
*/
{
 ATAPIPauseAudio[8]=OnOff&0x01;
 return(WriteATAPICommand(ATAPIPauseAudio,devnum,0XFFFF));
}

int		SetCDSpeed	(unsigned int speed,unsigned int devnum)
/* Set CD Speed
   in: speed     = speed in Kbyte/sec  0xFFFF = fastest
       devnum    = device number 0/1
   out:        0 = OK
	      -1 = error
*/
{
 Int2CharMSBLSB(speed,ATAPISetSpeed+2);
 return(WriteATAPICommand(ATAPISetSpeed,devnum,0XFFFF));
}

int		StartStopUnit	(unsigned int action,unsigned int devnum)
/* Start CD spindle servo, Stop CD spindle servo, Open tray, Close tray
   in: action  0 = Stop spindle servo
	       1 = Start spindle servo
	       2 = Open tray
	       3 = Close tray
       devnum    = device number 0/1
   out:        0 = OK
	      -1 = error
*/
{
 ATAPIStartStopUnit[4]=action&0x03;
 return(WriteATAPICommand(ATAPIStartStopUnit,devnum,0XFFFF));
}


struct structCDPosition ReadCDPosition  (unsigned int devnum)
/* Read from Sub-channel data current audio-play-position
   in:  devnum = device number 0/1
   out: structCDPos,
	if .Absolute=0xffffffff then error
*/
{
 unsigned char temp[16];
 struct structCDPosition CDPos;

 CDPos.Absolute=0xffffffff;

 if (WriteATAPICommand(ATAPIReadSubChan1,devnum,16)!=0)
   {
    return(CDPos);
   }
 if (ReadATAPIData(temp,8)!=0)
   {
    return(CDPos);
   }

 CDPos.Absolute   =Char2LongMSBLSB(temp+8);
 CDPos.Relative   =Char2LongMSBLSB(temp+12);
 CDPos.Track      =*(temp+6);
 CDPos.Index      =*(temp+7);
 return(CDPos);
}

struct structCDNumber ReadUPC  (unsigned int devnum)
/* Read from Sub-channel data current Media Catalog Number
   in:  devnum = device number 0/1
   out: structCDNumber,
	if .Flag=-1 then hardware error
*/
{
 unsigned int i;
 unsigned char temp[24];
 struct structCDNumber CDNum;

 CDNum.Flag=-1;

 if (WriteATAPICommand(ATAPIReadSubChan2,devnum,24)!=0)
   {
    return(CDNum);
   }
 if (ReadATAPIData(temp,12)!=0)
   {
    return(CDNum);
   }

 CDNum.Flag=(*(temp+8)>>7)^0x01;
 for (i=0;i<=13;i++)
   {
    CDNum.Number[i]=*(temp+i+9);
   }
 return(CDNum);
}

struct structCDNumber ReadISRC  (unsigned int track,unsigned int devnum)
/* Read from Sub-channel data track international standard recording code
   in:  track  = tracknumber
	devnum = device number 0/1
   out: structCDNumber,
	if .Flag=-1 then hardware error
*/
{
 unsigned int i;
 unsigned char temp[24];
 struct structCDNumber CDNum;

 CDNum.Flag=-1;

 ATAPIReadSubChan3[6]=track;
 if (WriteATAPICommand(ATAPIReadSubChan3,devnum,24)!=0)
   {
    return(CDNum);
   }
 if (ReadATAPIData(temp,12)!=0)
   {
    return(CDNum);
   }

 CDNum.Flag=(*(temp+8)>>7)^0x01;
 for (i=0;i<=13;i++)
   {
    CDNum.Number[i]=*(temp+i+9);
   }
 return(CDNum);
}


unsigned long	LBA2MSF		(unsigned long LBA)
/* convert LBA to MSF
   in:	LBA = unsigned long LBA number
   out: MSF = unsigned long, bit 0- 7:F
			     bit 8-15:S
			     bit16-23:M
*/
{
 unsigned long i,j;

 LBA=LBA+150;
 i=(LBA/4500);
 LBA=LBA-(i*4500);
 i=i*0x10000;
 j=(LBA/75);
 LBA=LBA-(j*75);
 i=i+(j*0x100)+LBA;
 return(i);
}

unsigned long	MSF2LBA		(unsigned long MSF)
/* convert MSF to LBA
   in:	MSF = unsigned long MSF, bit 0- 7:F
				 bit 8-15:S
				 bit16-23:M
   out: LBA
*/
{
 unsigned long i;

 i=((MSF&0xff0000)>>16)*4500+
   ((MSF&0x00ff00)>> 8)*75  +
    (MSF&0x0000ff);
 i=i-150;
 return(i);
}

void		PrintMSF	(unsigned long MSF,int flag)
/* print MSF
   in: MSF = unsigned long,  bit 0- 7:F
			     bit 8-15:S
			     bit16-23:M
       flag = 0:print F
	    !=0:do not print F
*/
{
 printf("%.2d", (MSF&0xff0000)>>16);
 printf(":%.2d",(MSF&0x00ff00)>>8);
 if (flag==0)
   {
    printf(":%.2d",(MSF&0x0000ff));
   }
}


int		ReadCDSector	(unsigned long sectnum,unsigned char *data,unsigned int sectcount,unsigned int devnum)
/* Read data-sectors from CD
    !!!! includes cacheing !!!!


   in:	sectnum = start sector number to be read
	data	= pointer to CHAR where data is to be written
	sectcount= number of sectors to be read
	devnum  = device number 0/1
   out: 0	= OK
	-1	= error
*/
{
 unsigned long i;

 if ( (SectorCache.DeviceNumber==devnum)  &&
      (SectorCache.SectorNumber==sectnum) &&
      (SectorCache.MemoryLocation==data)  &&
      (sectcount==1)                      &&
      (SectorCache.SectorCount==1)           )
   {
    return(0);
   }

 Long2CharMSBLSB(sectnum,ATAPIRead10+2);
 Int2CharMSBLSB(sectcount,ATAPIRead10+7);

 if (WriteATAPICommand(ATAPIRead10,devnum,0XFFFF)!=0)
   {
    return(-1);
   }
 i=0;
 do
   {
    if (i==0x0FFFFFF)
      {
       printf("Duurt te lang");
       return(-1);
      }
    i++;
   }
 while ((ReadIDEReg(IDERegStatus)&0X80)!=0);

 if (ReadATAPIData(data,sectcount<<10)!=0)
   {
    return(-1);
   }

 SectorCache.DeviceNumber=devnum;
 SectorCache.SectorNumber=sectnum;
 SectorCache.MemoryLocation=data;
 SectorCache.SectorCount=sectcount;
 return(0);
}

void 		PrintText	(unsigned int *data,unsigned int len)
/* Print ASCII-characters in words
   in:	*data = pointer to words with 2 ASCII characters in each
	len   = number of words (=Number of characters/2)
*/
{
 unsigned int i;

 for (i=0;i<len;i++)
  {printf("%c%c",(*(data+i))>>8,(*(data+i))&0xff);};
}

void		PrintFileName	(unsigned char *data,unsigned char DOSJolietRomeo)
/* Print a filename, DOS 8.3 (ISO9660 extended to 32 characters), Joliet, Romeo
   in:	*data = pointer to filename. First char gives length
	DOSJolietRomeo = DOSJolietRomeo flag
*/
{
 unsigned int i;

 for (i=1;i<=*(data);)
      {
       if (DOSJolietRomeo==0)
	 {
	  if (*(data+i)==0x3B)
	    {
	     return;
	    }
	  printf("%c",*(data+i));
	  i++;
	 }
       else if ( (DOSJolietRomeo==0x40) ||
		 (DOSJolietRomeo==0x43) ||
		 (DOSJolietRomeo==0x45)   )
	 {
	  if ( (*(data+i))==0x00 ||
	       (*(data+i+1))==0x3B  )
	    {
	     return;
	    }
	  printf("%c",*(data+i+1));
	  i++;
	  i++;
	 }
       /* else if hier moet nog Romeo-code staan $#@!$#! */
      }
}

int  		ReadTOC		(unsigned char *data,struct structISOHdr *ISOHdr,unsigned long *DirTable,unsigned int devnum)
/* Read TOC of a CD, and ISO9660 data
   in:	*data	= pointer to dataspace (max 804 bytes)
	*ISOdata= pointer to ISO-data
	devnum	= device number
   out: -1	= error
	0	= OK, no data tracks
	1	= OK, 1 track (data track)
	>1	= OK, datatracks, more than 1 track (mixed mode?)
*/
{
 unsigned int i,datatrack=0;
 unsigned long adres;
 unsigned char *j;

 if (WriteATAPICommand(ATAPIReadTOC,devnum,0XFFFF)!=0)
   {
    return(-1);
   }
 if (ReadATAPIData(data,804)!=0)
   {
    return(-1);
   }

 for (i=*(data+2);i<=(data+3);i++)
   {
    if ((*(data+(i-*(data+2))*8+5)&0X0D)==0X04)
      {
       if (datatrack==0)
	 {
	  j=data+(i-*(data+2))*8+8;
	  adres=(*(j+0)<<24) + (*(j+1)<<16) + (*(j+2)<<8) + (*(j+3));
	  ReadISOHdr(adres,ISOHdr,DirTable,devnum);
	 }
       datatrack=i;
      }
   }


 return(datatrack);
}


int		ReadISOHdr	(unsigned long sector,struct structISOHdr *ISOHdr,unsigned long *DirTable,unsigned int devnum)
/* Fill ISOHdr
   in:	sector 	= first sector of ISO9660 data-block
	data	= pointer to where ISOHdr is to be located
	devnum	= device number 0/1
   out:	0	= OK (ISO9660 disc)
	-1	= error (not ISO9660 disc)
*/

{
 unsigned long cursect;
 unsigned int i;

 cursect=sector+16;
 do
   {
    ReadCDSector(cursect,SectorBuf,1,devnum);
    if (*(SectorBuf+1)!='C' ||
	*(SectorBuf+2)!='D' ||
	*(SectorBuf+3)!='0' ||
	*(SectorBuf+4)!='0' ||
	*(SectorBuf+5)!='1'   ) {return(-1);}
    switch (*(SectorBuf))
      {
      case 0 :
	{
	 CopyBytes(SectorBuf+7,ISOHdr->BootSystemIdentifier,32);
	 CopyBytes(SectorBuf+39,ISOHdr->BootIdentifier,32);
	 break;
	}
      case 1 :
	{
	 CopyBytes(SectorBuf+8,&ISOHdr->SystemIdentifier,32);
	 CopyBytes(SectorBuf+40,&ISOHdr->VolumeIdentifier,32);
	 ISOHdr->VolumeSpaceSize	=Char2Long(SectorBuf+80);
	 ISOHdr->VolumeSetSize		=Char2Int(SectorBuf+120);
	 ISOHdr->VolumeSequenceNumber	=Char2Int(SectorBuf+124);
	 ISOHdr->LogicalBlockSize	=Char2Int(SectorBuf+128);
	 ISOHdr->PathTableSize		=Char2Long(SectorBuf+132);
	 ISOHdr->LocationLPathTable	=Char2Long(SectorBuf+140);
	 ISOHdr->LocationOptionLPathTable=Char2Long(SectorBuf+144);
	 ISOHdr->LocationMPathTable	=Char2Long(SectorBuf+148);
	 ISOHdr->LocationOptionMPathTable=Char2Long(SectorBuf+152);
	 ISOHdr->RootDir.RecordLen	=*(SectorBuf+156);
	 ISOHdr->RootDir.ExtAttributeLen=*(SectorBuf+157);
	 ISOHdr->RootDir.LocationExtent=Char2Long(SectorBuf+158);
	 ISOHdr->RootDir.DataLen	=Char2Long(SectorBuf+166);
	 CopyBytes(SectorBuf+174,&ISOHdr->RootDir.DateTime,7);
	 ISOHdr->RootDir.FileFlags	=*(SectorBuf+181);
	 ISOHdr->RootDir.FileUnitSize	=*(SectorBuf+182);
	 ISOHdr->RootDir.InterleaveGapSize=*(SectorBuf+183);
	 ISOHdr->RootDir.VolumeSequenceNumber=*(SectorBuf+184);
	 ISOHdr->RootDir.FileIdentifierLen=*(SectorBuf+185);
	 CopyBytes(SectorBuf+189,&ISOHdr->RootDir.FileIdentifier,1);
	 CopyBytes(SectorBuf+190,&ISOHdr->VolumeSetIdentifier,128);
	 CopyBytes(SectorBuf+318,&ISOHdr->PublisherIdentifier,128);
	 CopyBytes(SectorBuf+446,&ISOHdr->PreparerIdentifier,128);
	 CopyBytes(SectorBuf+574,&ISOHdr->ApplicationIdentifier,128);
	 CopyBytes(SectorBuf+702,&ISOHdr->CopyrightIdentifier,37);
	 CopyBytes(SectorBuf+739,&ISOHdr->AbstractIdentifier,37);
	 CopyBytes(SectorBuf+776,&ISOHdr->BibliographicIdentifier,37);
	 CopyBytes(SectorBuf+813,&ISOHdr->CreationDateTime,17);
	 CopyBytes(SectorBuf+830,&ISOHdr->ModificationDateTime,17);
	 CopyBytes(SectorBuf+847,&ISOHdr->ExpirationDateTime,17);
	 CopyBytes(SectorBuf+864,&ISOHdr->EffectiveDateTime,17);
	 ISOHdr->StructureVersion=*(SectorBuf+881);
	 ISOHdr->DOSJolietRomeo=0;
	 break;
	}
      case 2 :
	{
	 if ((*(SectorBuf+7)&0x01)==0)
	   {
	    if ( (*(SectorBuf+88)==0x25) &&
		 (*(SectorBuf+89)==0x2F)    )
	      {
	       if ( (*(SectorBuf+90)==0x40) ||
		    (*(SectorBuf+90)==0x43) ||
		    (*(SectorBuf+90)==0x45)   )
		 {
		  CopyBytes(SectorBuf+8,&ISOHdr->SystemIdentifier,32);
		  CopyBytes(SectorBuf+40,&ISOHdr->VolumeIdentifier,32);
		  ISOHdr->VolumeSpaceSize	=Char2Long(SectorBuf+80);
		  ISOHdr->VolumeSetSize		=Char2Int(SectorBuf+120);
		  ISOHdr->VolumeSequenceNumber	=Char2Int(SectorBuf+124);
		  ISOHdr->LogicalBlockSize	=Char2Int(SectorBuf+128);
		  ISOHdr->PathTableSize		=Char2Long(SectorBuf+132);
		  ISOHdr->LocationLPathTable	=Char2Long(SectorBuf+140);
		  ISOHdr->LocationOptionLPathTable=Char2Long(SectorBuf+144);
		  ISOHdr->LocationMPathTable	=Char2Long(SectorBuf+148);
		  ISOHdr->LocationOptionMPathTable=Char2Long(SectorBuf+152);
		  ISOHdr->RootDir.RecordLen	=*(SectorBuf+156);
		  ISOHdr->RootDir.ExtAttributeLen=*(SectorBuf+157);
		  ISOHdr->RootDir.LocationExtent=Char2Long(SectorBuf+158);
		  ISOHdr->RootDir.DataLen	=Char2Long(SectorBuf+166);
		  CopyBytes(SectorBuf+174,&ISOHdr->RootDir.DateTime,7);
		  ISOHdr->RootDir.FileFlags	=*(SectorBuf+181);
		  ISOHdr->RootDir.FileUnitSize	=*(SectorBuf+182);
		  ISOHdr->RootDir.InterleaveGapSize=*(SectorBuf+183);
		  ISOHdr->RootDir.VolumeSequenceNumber=*(SectorBuf+184);
		  ISOHdr->RootDir.FileIdentifierLen=*(SectorBuf+185);
		  CopyBytes(SectorBuf+189,&ISOHdr->RootDir.FileIdentifier,1);
		  CopyBytes(SectorBuf+190,&ISOHdr->VolumeSetIdentifier,128);
		  CopyBytes(SectorBuf+318,&ISOHdr->PublisherIdentifier,128);
		  CopyBytes(SectorBuf+446,&ISOHdr->PreparerIdentifier,128);
		  CopyBytes(SectorBuf+574,&ISOHdr->ApplicationIdentifier,128);
		  CopyBytes(SectorBuf+702,&ISOHdr->CopyrightIdentifier,37);
		  CopyBytes(SectorBuf+739,&ISOHdr->AbstractIdentifier,37);
		  CopyBytes(SectorBuf+776,&ISOHdr->BibliographicIdentifier,37);
		  CopyBytes(SectorBuf+813,&ISOHdr->CreationDateTime,17);
		  CopyBytes(SectorBuf+830,&ISOHdr->ModificationDateTime,17);
		  CopyBytes(SectorBuf+847,&ISOHdr->ExpirationDateTime,17);
		  CopyBytes(SectorBuf+864,&ISOHdr->EffectiveDateTime,17);
		  ISOHdr->StructureVersion=*(SectorBuf+881);
		  ISOHdr->DOSJolietRomeo=*(SectorBuf+90);
		 }
	      }
	   }
	 break;
	}
      case 3 :
	{
	 break;
	}
      case 255 :
	{
	 break;
	}
      default :
	{
	 return(-1);
	}
      }
     cursect++;
    }
    while (*(SectorBuf)!=255);

    for (i=0;i<34;i++)
      {
       *(DirTable+i)=0;
      }

    *(DirTable+36)=ISOHdr->LogicalBlockSize;
    *(DirTable)=(ISOHdr->RootDir.LocationExtent)/(2048/ *(DirTable+36));
    *(DirTable+1)=ISOHdr->RootDir.DataLen;
    *(DirTable+35)=ISOHdr->DOSJolietRomeo;
    return(0);
}

unsigned int	SearchDir	(unsigned long *DirTable)
/* Give depth of current directory in DirTable
   in:	DirTable= pointer to Directory Table
   out:		integer of directory depth
*/
{
 unsigned int i;

 i=15;
 while (*(DirTable+(i<<1))==0)
   {
    i--;
   }

 return(i);
}

void		ResetInquiry	(unsigned long *DirTable,unsigned int devnum)
/* Reset Inquiry. Give this command, before the FIRST "next inquiry item" command
   in:	DirTable= pointer to Directory Table
	devnum	= device number 0/1
*/
{
 unsigned int i;

 i=SearchDir(DirTable);
 *(DirTable+32)=*(DirTable+(i<<1));
 *(DirTable+33)=*(DirTable+(i<<1)+1)-68;
 *(DirTable+34)=68;
}

int		Inquiry		(unsigned long *DirTable,unsigned char *SourceName,unsigned char *data,unsigned int devnum)
/* Give next file in inquiry
   in:	DirTable= pointer to Directory Table
	SourceName=Name to look for. Char array terminated with \0
		   wildcards: 	? = any character
				* = any number of any characters upto "."
				\ = from here on don't care
	data	= pointer to data area where directory record is loaded
	devnum	= device number
   out:	0	= OK, found
	1	= error (not found)
	-1	= error (hardware)
*/
{
 unsigned long  cursect,
		curlen,
		curbyte;

 cursect=*(DirTable+32);
 curlen =*(DirTable+33);
 curbyte=*(DirTable+34);

 while (curlen!=0)
   {
    if (curbyte==512)
      {
       curbyte=0;
       cursect++;
      }
    if (ReadCDSector(cursect,SectorBuf,1,devnum)!=0)
      {
       return(-1);
      }
    if (*(SectorBuf+curbyte)==0)
      {
       if (curlen<=(2048-curbyte))
	 {
	  *(DirTable+33)=0;
	  return(1);
	 }
       curlen=curlen-(2048-curbyte);
       curbyte=0;
       cursect++;
       ReadCDSector(cursect,SectorBuf,1,devnum);
      }
    if (NameMatch(SectorBuf+curbyte+32,SourceName,*(DirTable+35))==0)
	 {
	  CopyBytes(SectorBuf+curbyte,data,*(SectorBuf+curbyte));
	  *(DirTable+32)=cursect;
	  *(DirTable+33)=curlen-*(SectorBuf+curbyte);
	  *(DirTable+34)=curbyte+*(SectorBuf+curbyte);
	  return(0);
	 }
    curlen=curlen-*(SectorBuf+curbyte);
    curbyte=curbyte+*(SectorBuf+curbyte);
   }

 *(DirTable+32)=cursect;
 *(DirTable+33)=curlen;
 *(DirTable+34)=curbyte;
 return(1);
}

int		NameMatch	(unsigned char *SourceName,unsigned char *CheckName,unsigned char DOSJolietRomeo)
/* Check if SourceName and CheckName are equal. CheckName is allowed to have wildcards
   in:	SourceName = char pointer to char array to be checked.
		     FIRST byte L in array is length of name (so length array is L+1)
	CheckName  = pointer to char ASCIIZ text
		   wildcards: 	? = any character
				* = any number of any characters upto "."
				\ = from here on don't care
	DOSJolietRomeo = 00 = DOS 8.3 filename in Sourcename
			 40 = Joliet filename in Sourcename, UCS-2 level 1
			 43 = Joliet filename in Sourcename, UCS-2 level 2
			 45 = Joliet filename in Sourcename, UCS-2 level 3
   out:	0 	= OK (equal)
	-1 	= error (not equal)
*/
{
 unsigned int SourceCounter=1,
	      CheckCounter =0;

 do
   {
    if (*(CheckName+CheckCounter)=='\\')
      {
       return(0);
      }
    if (    ((*SourceName - SourceCounter + 1 )==0) ||
	  ( (DOSJolietRomeo==0) && (*(SourceName + SourceCounter)==0x3B) ) ||
	  ( ( (DOSJolietRomeo==0x40) || (DOSJolietRomeo==0x43) || (DOSJolietRomeo==0x45) ) && ( (*(SourceName + SourceCounter)==0x00) && (*(SourceName + SourceCounter)==0x3B) ))  )
	 {
	  while (*(CheckName+CheckCounter)!=0)
	    {
	     if ((*(CheckName+CheckCounter)=='*') ||
		 (*(CheckName+CheckCounter)=='?') ||
		 (*(CheckName+CheckCounter)=='.') ||
		 (*(CheckName+CheckCounter)=='\\')   )
		  {
		   CheckCounter++;
		  }
	     else
		  {
		   return(-1);
		  }
	     }
	   return(0);
	  }
    if (*(CheckName+CheckCounter)==0)
      {
       return(-1);
      }
    if (*(CheckName+CheckCounter)=='?')
      {
       CheckCounter++;
       if (DOSJolietRomeo==0)
	 {
	  SourceCounter++;
	 }
       else if ( (DOSJolietRomeo==0x40) ||
		 (DOSJolietRomeo==0x43) ||
		 (DOSJolietRomeo==0x45)   )
	 {
	  SourceCounter++;
	  SourceCounter++;
	 }
       /* else if .... hier moet nog een check voor Romeo %$#@#$@!%$ */
      }
    else if (*(CheckName+CheckCounter)=='*')
	   {
	    if (DOSJolietRomeo==0)
	      {
	       while (*(SourceName+SourceCounter)!='.')
		 {
		  SourceCounter++;
		  if ((*SourceName - SourceCounter) == 0)
		    {
		     return(0);
		    }
		 }
	       CheckCounter++;
	      }
	    else if ( (DOSJolietRomeo==0x40) ||
		      (DOSJolietRomeo==0x43) ||
		      (DOSJolietRomeo==0x45)   )
	      {
	       while (*(SourceName+SourceCounter)!='.')
		 {
		  SourceCounter++;
		  SourceCounter++;
		  if ((*SourceName - SourceCounter) == 0)
		    {
		     return(0);
		    }
		 }
	       CheckCounter++;
	      }
	    /* else if ..... hier moet nog een check voor Romeo !$%#@!$#@ */
	   }
    else
      {
       if (DOSJolietRomeo==0)
	 {
	  if (*(SourceName+SourceCounter)!= *(CheckName+CheckCounter))
	    {
	     return (-1);
	    }
	  else
	    {
	     SourceCounter++;
	     CheckCounter++;
	    }
	 }
       else if ( (DOSJolietRomeo==0x40) ||
		 (DOSJolietRomeo==0x43) ||
		 (DOSJolietRomeo==0x45)   )
	 {
	  if (*(SourceName+SourceCounter+1)!= *(CheckName+CheckCounter))
	    {
	     return (-1);
	    }
	  else
	    {
	     SourceCounter++;
	     SourceCounter++;
	     CheckCounter++;
	    }
	 }
       /* else if hier moet nog een test voor Romeo  */
      }
   }
 while (1);
}

int		ChangeDirectory (unsigned long *DirTable,unsigned char *SourceName,unsigned int devnum)
/* Change active directory
   in:	DirTable= pointer to Directory Table
	SourceName=Name to look for. Char array terminated with \0
		   wildcards: 	? = any character
				* = any number of any characters upto "."
				\ = from here on don't care
	devnum	= device number
   out:	0	= OK, found
	1	= error (not found)
	2       = error (too deep (>16))
	-1	= error (hardware)
*/
{
 unsigned char temp[256];
 unsigned int i;

 ResetInquiry(DirTable,devnum);
 while (1)
   {
    i=Inquiry(DirTable,SourceName,temp,devnum);
    if (i!=0)
      {
       return(i);
      }
    if ((*(temp+25)&0x02)==0x02)
      {
       i=SearchDir(DirTable);
       if (i==15)
	 {
	  return(2);
	 }
       i++;
       *(DirTable+(i<<1))=(Char2Long(temp+2))/(2048/ *(DirTable+36));
       *(DirTable+(i<<1)+1)=Char2Long(temp+10);
       ResetInquiry(DirTable,devnum);
       return(0);
      }
   }
}

int		ChangeDirectoryUp(unsigned long *DirTable,unsigned int devnum)
/* Change active directory, one brach up.
   in:	DirTable= pointer to Directory Table
	devnum	= device number
   out:	0	= OK, found
	1	= error (allready in root)
*/
{
 unsigned int i;

 i=SearchDir(DirTable);
 if (i==0)
   {
    return(1);
   }
 *(DirTable+(i<<1))=0;
 *(DirTable+(i<<1)+1)=0;
 ResetInquiry(DirTable,devnum);
 return(0);
}

int		OpenFile	(unsigned long *DirTable,unsigned char *SourceName,unsigned char *FilePointer,unsigned int devnum)
/* Open File
   in:	DirTable= pointer to Directory Table
	SourceName=Name to look for. Char array terminated with \0
		   wildcards: 	? = any character
				* = any number of any characters upto "."
				\ = from here on don't care
	FilePointer=Char array (274 bytes)
			+0   = directory entry       (256)
			+256 = current Logical Block (4)
			+260 = current File length   (4)
			+264 = current byte counter  (4)
			+268 = devnum                (1)
			+269 = Logical Block Length  (4)
			+273 = current File Unit Size counter (1)
	devnum	= device number
   out:	0	= OK, found
	1	= error (not found)
	-1	= error (hardware)
*/
{
 unsigned int i;

 ResetInquiry(DirTable,devnum);
 while (1)
   {
    i=Inquiry(DirTable,SourceName,FilePointer,devnum);
    if (i!=0)
      {
       return(i);
      }
    if ((*(FilePointer+25)&0x02)!=0x02)
      {
       CopyBytes(FilePointer+2,FilePointer+256,4);
       CopyBytes(FilePointer+10,FilePointer+260,4);
       Long2Char(0,FilePointer+264);
       *(FilePointer+268)=devnum;
       Long2Char(*(DirTable+36),FilePointer+269);
       *(FilePointer+273)=1;
       return(0);
      }
   }
}

int		ReadFileBytes	(unsigned char *FilePointer,unsigned int length,unsigned char *data)
/* Read from File, in bytes
   in:	FilePointer= pointer to file info table
	length	= number of bytes to be read
	data	= pointer to where data is to be located
   out:	0	= OK
	<>0	= error (EOF) number is bytes read
	-1	= error (hardware)
*/
{
 unsigned long curLB,
	       curbyte,
	       curlen,
	       LBL;

 unsigned int  i=0,
	       j;

 unsigned char devnum;

 curLB=Char2Long(FilePointer+256);
 curlen=Char2Long(FilePointer+260);
 curbyte=Char2Long(FilePointer+264);
 devnum=*(FilePointer+268);
 LBL=Char2Long(FilePointer+269);


 while (length!=0)
   {
    if (curlen==0)
      {
       return(-1);
      }
    if (ReadCDSector(curLB/(2048/LBL),SectorBuf,1,devnum)!=0)
      {
       return(-1);
      }
    j=(curLB%(2048/LBL))<<9;
    if (curlen<(LBL-curbyte))
      {
       if (curlen<=length)
	 {
	  CopyBytes(SectorBuf+curbyte+j,data,curlen);
	  i=i+curlen;
	  return(i);
	 }
      }
    if (length<(LBL-curbyte))
      {
       CopyBytes(SectorBuf+curbyte+j,data,length);
       Long2Char(curLB,FilePointer+256);
       Long2Char(curlen-length,FilePointer+260);
       Long2Char(curbyte+length,FilePointer+264);
       return(0);
      }
    CopyBytes(SectorBuf+curbyte+j,data,(LBL-curbyte));
    if (*(FilePointer+26)==0)
      {
       curLB++;
      }
    else
      {
       if ( *(FilePointer+273) == *(FilePointer+26) )
	 {
	  *(FilePointer+273)=1;
	  curLB=curLB + *(FilePointer+27) + 1;
	 }
       else
	 {
	  *(FilePointer+273)=*(FilePointer+273)+1;
	  curLB++;
	 }
      }
    curlen=curlen-(LBL-curbyte);
    length=length-(LBL-curbyte);
    i=i+(LBL-curbyte);
    data=data+(LBL-curbyte);
    curbyte=0;
   }
 Long2Char(curLB,FilePointer+256);
 Long2Char(curlen,FilePointer+260);
 Long2Char(curbyte,FilePointer+264);
 return(0);
}

void		CopyBytes	(unsigned char *source,unsigned char *dest,unsigned int len)
/* copy bytes from source to destination
   in:	*source	pointer to source
	*dest	pointer to destination
	len	number of bytes
*/
{
 while (len!=0)
   {
    *dest=*source;
    len--;
    dest++;
    source++;
   }
}

unsigned long	Char2Long	(unsigned char *bytes)
/* convert 4 bytes to 1 long, (LSB----MSB)
   in:	*char	pointer to 4 bytes
   out:	value
*/
{
 unsigned long j;

 j =          *(bytes+3);
 j = (j<<8) + *(bytes+2);
 j = (j<<8) + *(bytes+1);
 j = (j<<8) + *(bytes+0);
 return(j);
}

unsigned long	Char2LongMSBLSB (unsigned char *bytes)
/* convert 4 bytes to 1 long, (MSB----LSB)
   in: *char	pointer to 4 bytes
   out: value
*/
{
 unsigned long j;

 j =          *(bytes+0);
 j = (j<<8) + *(bytes+1);
 j = (j<<8) + *(bytes+2);
 j = (j<<8) + *(bytes+3);
 return(j);
}

unsigned int	Char2Int	(unsigned char *bytes)
/* convert 2 bytes to 1 int, (LSB----MSB)
   in:	*char	pointer to 2 bytes
   out:	value
*/
{
 return(    *(bytes+0)      +
	   (*(bytes+1)<<8)
       );
}

unsigned int	Char2IntMSBLSB	(unsigned char *bytes)
/* convert 2 bytes to 1 int, (MSB----LSB)
   in:	*char	pointer to 2 bytes
   out:	value
*/
{
 return(    *(bytes+1)      +
	   (*(bytes+0)<<8)
       );
}


void		Int2Char	(unsigned int value,unsigned char *bytes)
{
 *(bytes  )=(value&0x00ff);
 *(bytes+1)=(value&0xff00)>>8;
}


void		Int2CharMSBLSB	(unsigned int value,unsigned char *bytes)
{
 *(bytes+1)=(value&0x00ff);
 *(bytes  )=(value&0xff00)>>8;
}

void		Long2Char	(unsigned long value,unsigned char *bytes)
{
 *(bytes  )=(value&0x000000ff);
 *(bytes+1)=(value&0x0000ff00)>>8;
 *(bytes+2)=(value&0x00ff0000)>>16;
 *(bytes+3)=(value&0xff000000)>>24;
}

void		Long2CharMSBLSB	(unsigned long value,unsigned char *bytes)
{
 *(bytes+3)=(value&0x000000ff);
 *(bytes+2)=(value&0x0000ff00)>>8;
 *(bytes+1)=(value&0x00ff0000)>>16;
 *(bytes  )=(value&0xff000000)>>24;
}

void main ()
{
 unsigned int i,j,k;

 unsigned char temp[512],
	       temp1[512],
	       *test;

 struct structCDPosition CDPos;
 struct structCDNumber   CDNum;
 struct structATAPIError error;

 SectorCache.DeviceNumber=0xff;
 printf("\nATA                       v0.10a");
 printf("\nATAPI-CDROM               v0.10a");
 printf("\nATAPI audio-extension     v0.00a");
 printf("\nISO 9660:1988, level 2    v0.00a");
 printf("\nISO 9660:Joliet-extension v0.00a");
 printf("\n\nProgrammed by V.M.G. van Acht");
 printf("\n(c) 1998 by VVA\n");

 if (WriteIDECommand(IDEATAPIIdent,0)==0)
   {
    if (ReadIDEData(Device0Data,256)==0)
      {
       printf("Device 0: ");
       PrintText(Device0Data+27,20);
       printf(" - ");
       PrintText(Device0Data+23,4);
       printf("\n");
       NumDevice=0;
      }
    else
      {
       NumDevice=0XFFFF;
      }
   }
  else
    {
     NumDevice=0XFFFF;
    }
  if (NumDevice==0XFFFF)
    {
     printf("ATAPI Device 0 error\n");
     return(-1);
    }
  if (WriteIDECommand(IDEATAPIIdent,1)==0)
   {
    if (ReadIDEData(Device1Data,256)==0)
      {
       printf("Device 1: ");
       PrintText(Device1Data+27,20);
       printf(" - ");
       PrintText(Device1Data+23,4);
       printf("\n");
       NumDevice=1;
      }
    }

 ReadTOC(Device0TOC,&Device0ISOHdr,Device0DirTable,0);

 PlayAudio(40000,100000,0);

 Wait(3000);

 printf("\n");

 for (i=0;i<0x1000;i++)
   {
    CDPos=ReadCDPosition(0);
    PrintMSF(LBA2MSF(CDPos.Relative),0);
    printf("\r");
   }

 PauseAudio(0,0);
 Wait(1000);
 PauseAudio(1,0);
 Wait(10000);

 StopAudio(0);

 StartStopUnit(2,0);
 Wait(3000);
 StartStopUnit(3,0);









 /* CDROM
 ResetInquiry(Device0DirTable,0);

 while (Inquiry(Device0DirTable,"\\",temp,0)==0)
   {
    PrintFileName(temp+32,Device0ISOHdr.DOSJolietRomeo);
    printf("\n");
   }

 printf("\n");

 if (ChangeDirectory(Device0DirTable,"BC5\\",0)!=0)
   {
    printf("\nChange Dir error");
   }

 ResetInquiry(Device0DirTable,0);

 j=0;
 while (j<7 && Inquiry(Device0DirTable,"\\",temp,0)==0)
   {
    PrintFileName(temp+32,Device0ISOHdr.DOSJolietRomeo);
    printf("\n");
    j++;
   }
 printf("\n");


/*
 if (ChangeDirectoryUp(Device0DirTable,0)!=0)
   {
    printf("\nChange Dir error");
   }


 ResetInquiry(Device0DirTable,0);
 j=0;
 while (j<15 && Inquiry(Device0DirTable,"\\",temp,0)==0)
   {
    for (i=33;i<(33+temp[32]);i++)
      {
       printf("%c",temp[i]);
      }
    printf("\n");
    j++;
   }
 */

/* CR-ROM

 if (OpenFile(Device0DirTable,"V*.TXT",temp,0)!=0)
   {
    printf("Open error");
   }
 else
   {
    while ((i=ReadFileBytes(temp,5,temp1))==0)
      {
       for (i=0;i<5;i++)
	{
	 printf("%c",temp1[i]);
	}
      }
    if (i!=-1)
      {
       for (j=0;i!=0;i--,j++)
	 {
	  printf("%c",temp1[j]);
	 }
      }
   }
 WaitKey();

 error=ATAPIError(0);
 printf("\nFlag:%X",error.Flag);
 printf("\nText:%s",error.Text);

*/

}




好久没碰Dos,手都生了,赶紧回来练练.嘿嘿
2008-2-6 21:24
查看资料  发送邮件  发短消息 网志  OICQ (181315400)  编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 2 楼』:  

这个是不是编译成可执行?


2008-2-7 01:29
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
070
高级用户

苏醒的沉睡者


积分 659
发帖 217
注册 2003-2-15
来自 福建
状态 离线
『第 3 楼』:  

看内联汇编的格式,应该可能需要vc




好久没碰Dos,手都生了,赶紧回来练练.嘿嘿
2008-2-7 15:20
查看资料  发送邮件  发短消息 网志  OICQ (181315400)  编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 4 楼』:  

用 BC3.1 编过了 可以的,可执行,运行后能识别光驱,可是,不能分配盘符,运行shsucdx.exe,没有驱动标识,不知道怎么使用


2008-2-7 17:56
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
070
高级用户

苏醒的沉睡者


积分 659
发帖 217
注册 2003-2-15
来自 福建
状态 离线
『第 5 楼』:  

能不能驻留内存阿,如果不行,恐怕就是一个只能识别cd的东西了




好久没碰Dos,手都生了,赶紧回来练练.嘿嘿
2008-2-7 18:07
查看资料  发送邮件  发短消息 网志  OICQ (181315400)  编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 6 楼』:  

Originally posted by 070 at 2008-2-7 06:07 PM: 能不能驻留内存阿,如果不行,恐怕就是一个只能识别cd的东西了
即使能驻留内存也没用啊, 现在没法使用


2008-2-7 18:57
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
070
高级用户

苏醒的沉睡者


积分 659
发帖 217
注册 2003-2-15
来自 福建
状态 离线
『第 7 楼』:  

如果不能驻留内存,那就肯定不能分配盘符 如果能驻留内存,说明应该是由bug




好久没碰Dos,手都生了,赶紧回来练练.嘿嘿
2008-2-7 19:33
查看资料  发送邮件  发短消息 网志  OICQ (181315400)  编辑帖子  回复  引用回复
kaixinmao
初级用户





积分 27
发帖 14
注册 2007-4-7
状态 离线
『第 8 楼』:  存下来看看,不看好这个东东

找找毛病再说


2008-3-17 23:36
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: