中国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 楼』:  



  Quote:
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
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

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


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



论坛跳转: