[Back to DRIVES SWAG index] [Back to Main SWAG index] [Original]

    Unit CD;

    {----------------------------------------------------------------------------}

    {  CD : An implementation of a CD-ROM driver.                                }

    {****************************************************************************}

    {  Author            : Menno Victor van der star                             }

    {  E-Mail            : s795238@dutiwy.twi.tudelft.nl                         }

    {  Developed on      : 08-06-'95                                             }

    {  Last update on    : 07-09-'95                                             }

    {  Status            : Finished                                              }

    {  Future extensions : None                                                  }

    {----------------------------------------------------------------------------}

    {$R-}

    Interface

    Uses Dos;

    Type

      CDRomParametersRecord = Record

                                Raw : Boolean;

                                SectorSize : Word;

                                NumberOfSectors : LongInt;

                              End;

      CDRomPositionInfo = Record

                            CntAdr : Byte;

                            CTrk   : Byte;

                            Cindx  : Byte;

                            CMin   : Byte;

                            CSek   : Byte;

                            CFrm   : Byte;

                            Czero  : Byte;

                            CAmin  : Byte;

                            CAsec  : Byte;

                            CAFrm  : Byte;

                          End;

      CDRom = Object

                ValidCDRoms : String;

                Error : Word;

                CDRomDevice : Text;

                Constructor Init;

                Destructor  Done; Virtual;

                Procedure   ChangeDrive (DriveLetter : Char);

                Procedure   OpenDoor;

                Procedure   CloseDoor;

                Procedure   LockDoor;

                Procedure   UnlockDoor;

                Procedure   Reset;

                Function    DriveStatus : Word;

                Procedure   GetDriveParameters (Var Parameters : CDRomParametersRecord);

                Procedure   GetPosition (Var Position : CDRomPositionInfo);

                Procedure   PlayAudio (MinuteStart, SecondStart, MinuteEnd, SecondEnd : Byte);

                Procedure   PlayTrack (TrackNr : Byte);

                Procedure   PausePlay;

                Procedure   ResumePlay;

                Function    NumberOfAudioTracks : Byte;

              Private

                Regs : Registers;

                MSCDEXVerMajor, MSCDEXVerMinor : Byte;

                NumCDRoms : Byte;

                DriverNames : Array ['A'..'Z'] Of Record

                                                    SubunitNr : Byte;

                                                    Name : String[8];

                                                  End;

                CurrentDrive : Char;

                Function    DeviceCommand (CommandNr, DosFunction : Word; Var Data) : Word;

                Function    RedBookToHSG (Minute, Second, Frame : Byte) : LongInt;

              End;

    Implementation

    Type

      PCharArray = ^CharArray;

      CharArray = Array [0..0] Of Char;

    Constructor CDRom.Init;

    Var

      n : Word;

      c, c2 : Char;

      DeviceInfo : Array ['A'..'Z'] Of Record

                                         SubunitNr : Byte;

                                         NamePtr : PCharArray;

                                       End;

    Begin

      Regs.ax:=$1100;             { MSCDEX Installed? }

      Intr ($2F,Regs);

      If Regs.al<>255 then Fail;  { MSCDEX Not installed, fail to construct }

      Regs.AX:=$150C;            { Get MSCDEX version }

      Intr ($2F,Regs);

      MSCDEXVerMajor:=Regs.BH;

      MSCDEXVerMinor:=Regs.BL;

      { Only work with versions 2.1 or higher }

      If (MSCDEXVerMajor<2) Or ((MSCDEXVerMajor=2) And (MSCDEXVerMinor < 10)) then Fail;

      Regs.AX:=$1500;             { get number of cdrom's }

      Regs.BX:=0;

      Intr ($2F,Regs);

      NumCDRoms:=Regs.BX;

      If NumCDRoms=0 then Fail;   { No cdroms present, fail to construct }

      Regs.AX:=$150D;

      Regs.ES:=Seg (ValidCDRoms[1]);

      Regs.BX:=Ofs (ValidCDRoms[1]);

      Intr ($2F,Regs);

      ValidCDRoms[0]:=Chr (NumCDRoms);

      For n:=1 to Length (ValidCDRoms) Do ValidCDRoms[n]:=Chr (Ord (ValidCDRoms[n])+65);

      For c:='A' to 'Z' Do Begin

        DriverNames[c].Name:='';

        DriverNames[c].SubunitNr:=0;

        DeviceInfo[c].SubunitNr:=0;

        DeviceInfo[c].NamePtr:=NIL;

      End;

      Regs.AX:=$1501;

      Regs.ES:=Seg (DeviceInfo);

      Regs.BX:=Ofs (DeviceInfo);

      Intr ($2f,Regs);

      c2:='A';

      For c:='A' to 'Z' Do Begin

        Regs.AX:=$150B;

        Regs.CX:=Ord (c)-65;

        Intr ($2F,Regs);

        If (Regs.AX>0) And Assigned (DeviceInfo[c2].NamePtr) then Begin

          n:=10;

          While (n<=17) And (DeviceInfo[c2].NamePtr^[n]<>' ') Do Begin

            DriverNames[c].Name:=DriverNames[c].Name+DeviceInfo[c2].NamePtr^[n];

            Inc (n);

          End;

          DriverNames[c].SubunitNr:=DeviceInfo[c2].SubunitNr;

          If c2='A' then ChangeDrive (c);

          Inc (c2);

        End

      End;

      Reset;

    End;

    Destructor CDRom.Done;

    Begin

      Close (CDRomDevice);

    End;

    Procedure CDRom.ChangeDrive (DriveLetter : Char);

    Begin

      If DriverNames[DriveLetter].Name='' then Exit;

      Assign (CDRomDevice,DriverNames[DriveLetter].Name);

      System.Reset (CDRomDevice);

      CurrentDrive:=DriveLetter;

    End;

    Procedure CDRom.OpenDoor;

    Var

      Data : Byte;

    Begin

      Data:=0;

      Error:=DeviceCommand (1,$4403,Data);

    End;

    Procedure CDRom.CloseDoor;

    Var

      Data : Byte;

    Begin

      Data:=5;

      Error:=DeviceCommand (1,$4403,Data);

      Reset;

    End;

    Procedure CDRom.LockDoor;

    Var

      Data : Word;

    Begin

      Data:=$0001;

      Error:=DeviceCommand (2,$4403,Data);

    End;

    Procedure CDRom.UnlockDoor;

    Var

      Data : Word;

    Begin

      Data:=$0101;

      Error:=DeviceCommand (2,$4403,Data);

      Reset;

    End;

    Procedure CDRom.Reset;

    Var

      Data : Byte;

    Begin

      Data:=2;

      Error:=DeviceCommand (1,$4403,Data);

    End;

    Function CDRom.DriveStatus : Word;

    Var

      Data : Record Command : Byte; Status : Word; Dummy2 : Word; End;

    Begin

      Data.Command:=6;

      Error:=DeviceCommand (5,$4402,Data);

      DriveStatus:=Data.Status And 2047;

    {  Reset; }

    End;

    Procedure CDRom.GetDriveParameters (Var Parameters : CDRomParametersRecord);

    Var

      Data1 : Record Command, Raw : Byte; SectorSize : Word; End;

      Data2 : Record Command : Byte; NumberOfSectors : LongInt; End;

    Begin

      Data1.Command:=7;

      Error:=DeviceCommand (4,$4402,Data1);

      Data2.Command:=8;

      Error:=DeviceCommand (5,$4402,Data2);

      Parameters.Raw:=Data1.Raw=1;

      Parameters.SectorSize:=Data1.SectorSize;

      Parameters.NumberOfSectors:=Data2.NumberOfSectors;

    End;

    Procedure CDRom.GetPosition (Var Position : CDRomPositionInfo);

    Var

      Data : Record

               Command : Byte;

               Info : CDRomPositionInfo;

             End;

    Begin

      Data.Command:=12;

      Error:=DeviceCommand (129,$4402,Data);

      Position:=Data.Info;

    End;

    Procedure CDRom.PlayAudio (MinuteStart, SecondStart, MinuteEnd, SecondEnd : Byte);

    Var

      HSGAddress1, HSGAddress2 : LongInt;

      Data : Record

               Bytes : Array [0..13] Of Byte;

               HSGAddress : LongInt;

               NumberOfFrames : LongInt;

             End;

    Begin

      HSGAddress1:=RedBookToHSG (MinuteStart, SecondStart, 0);

      HSGAddress2:=RedBookToHSG (MinuteEnd, SecondEnd, 0);

      Data.Bytes[0]:=$16;

      Data.Bytes[1]:=DriverNames[CurrentDrive].SubunitNr;

      Data.Bytes[2]:=$84;

      Data.Bytes[13]:=0;

      Data.HSGAddress:=HSGAddress1;

      Data.NumberOfFrames:=HSGAddress2-HSGAddress1;

      Regs.ES:=Seg (Data);

      Regs.BX:=Ofs (Data);

      Regs.CX:=Ord (CurrentDrive)-65;

      Regs.AX:=$1510;

      Intr ($2F,Regs);

    End;

    Procedure CDRom.PlayTrack (TrackNr : Byte);

    Var

      Track1 : Record

                Command, TrackNr : Byte;

                RedBookAdress : Record

                                  Frame,

                                  Second,

                                  Minute,

                                  Dummy : Byte;

                                End;

                TrackControl : Word;

                HSGAddress : LongInt;

              End;

      Track2 : Record

                Command, TrackNr : Byte;

                RedBookAdress : Record

                                  Frame,

                                  Second,

                                  Minute,

                                  Dummy : Byte;

                                End;

                TrackControl : Word;

                HSGAddress : LongInt;

              End;

      Data : Record

               Bytes : Array [0..13] Of Byte;

               HSGAddress : LongInt;

               NumberOfFrames : LongInt;

             End;

      NumberOfTracks : Byte;

    Begin

      NumberOfTracks:=NumberOfAudioTracks;

      Track1.Command:=$0B;

      Track1.TrackNr:=TrackNr;

      Error:=DeviceCommand (8,$4402,Track1);

      Track1.HSGAddress:=RedBookToHSG (Track1.RedBookAdress.Minute,

                                       Track1.RedBookAdress.Second,

                                       Track1.RedBookAdress.Frame);

      If Track1.TrackControl And 16384<>0 then Exit;

      Track2.Command:=$0B;

      Track2.TrackNr:=TrackNr+1;

      Error:=DeviceCommand (8,$4402,Track2);

      Track2.HSGAddress:=RedBookToHSG (Track2.RedBookAdress.Minute,

                                       Track2.RedBookAdress.Second,

                                       Track2.RedBookAdress.Frame);

      Data.Bytes[0]:=$16;

      Data.Bytes[1]:=DriverNames[CurrentDrive].SubunitNr;

      Data.Bytes[2]:=$84;

      Data.Bytes[13]:=0;

      Data.HSGAddress:=Track1.HSGAddress;

      Data.NumberOfFrames:=Track2.HSGAddress-Track1.HSGAddress;

      Regs.ES:=Seg (Data);

      Regs.BX:=Ofs (Data);

      Regs.CX:=Ord (CurrentDrive)-65;

      Regs.AX:=$1510;

      Intr ($2F,Regs);

    End;

    Procedure CDRom.PausePlay;

    Var

      Data : Array [0..12] Of Byte;

    Begin

      Data[0]:=$0D;

      Data[1]:=DriverNames[CurrentDrive].SubunitNr;

      Data[2]:=$85;

      Regs.ES:=Seg (Data);

      Regs.BX:=Ofs (Data);

      Regs.CX:=Ord (CurrentDrive)-65;

      Regs.AX:=$1510;

      Intr ($2F,Regs);

    End;

    Procedure CDRom.ResumePlay;

    Var

      Data : Array [0..12] Of Byte;

    Begin

      Data[0]:=$0D;

      Data[1]:=DriverNames[CurrentDrive].SubunitNr;

      Data[2]:=$88;

      Regs.ES:=Seg (Data);

      Regs.BX:=Ofs (Data);

      Regs.CX:=Ord (CurrentDrive)-65;

      Regs.AX:=$1510;

      Intr ($2F,Regs);

    End;

    Function CDRom.NumberOfAudioTracks : Byte;

    Var

      Data : Record Command : Byte; FirstTrack, LastTrack : Byte; Dummy : LongInt; End;

    Begin

      Data.Command:=$0A;

      Error:=DeviceCommand (7,$4402,Data);

      NumberOfAudioTracks:=Data.LastTrack-Data.FirstTrack+1;

    End;

    Function CDRom.DeviceCommand (CommandNr, DosFunction : Word; Var Data) : Word;

    Begin

      Regs.BX:=TextRec (CDRomDevice).Handle;

      Regs.DS:=Seg (Data);

      Regs.DX:=Ofs (Data);

      Regs.CX:=CommandNr;

      Regs.AX:=DosFunction;

      MsDos (Regs);

      If Regs.Flags And fCarry=0 then

        DeviceCommand:=0

      Else

        DeviceCommand:=Regs.AX;

    End;

    Function CDRom.RedBookToHSG (Minute, Second, Frame : Byte) : LongInt;

    Begin

      RedBookToHSG:=(LongInt (Minute)*4500)+(LongInt (Second)*75)+Frame-183;

    End;

    End.

[Back to DRIVES SWAG index] [Back to Main SWAG index] [Original]