Contributor: MENNO VICTOR VAN DER STAR
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 (2ドルF,Regs);
 If Regs.al255 then Fail; { MSCDEX Not installed, fail to construct }
 Regs.AX:=150ドルC; { Get MSCDEX version }
 Intr (2ドルF,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 (2ドルF,Regs); NumCDRoms:=Regs.BX; If NumCDRoms=0 then Fail; { No cdroms present, fail to construct } Regs.AX:=150ドルD; Regs.ES:=Seg (ValidCDRoms[1]); Regs.BX:=Ofs (ValidCDRoms[1]); Intr (2ドルF,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 (2ドルf,Regs); c2:='A'; For c:='A' to 'Z' Do Begin Regs.AX:=150ドルB; Regs.CX:=Ord (c)-65; Intr (2ドルF,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 (2ドルF,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:=0ドルB;
 Track1.TrackNr:=TrackNr;
 Error:=DeviceCommand (8,4402,ドルTrack1);
 Track1.HSGAddress:=RedBookToHSG (Track1.RedBookAdress.Minute,
 Track1.RedBookAdress.Second,
 Track1.RedBookAdress.Frame);
 If Track1.TrackControl And 163840 then Exit;
 Track2.Command:=0ドルB;
 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 (2ドルF,Regs);
End;
Procedure CDRom.PausePlay;
Var
 Data : Array [0..12] Of Byte;
Begin
 Data[0]:=0ドルD;
 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 (2ドルF,Regs);
End;
Procedure CDRom.ResumePlay;
Var
 Data : Array [0..12] Of Byte;
Begin
 Data[0]:=0ドルD;
 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 (2ドルF,Regs);
End;
Function CDRom.NumberOfAudioTracks : Byte;
Var
 Data : Record Command : Byte; FirstTrack, LastTrack : Byte; Dummy : LongInt; End;
Begin
 Data.Command:=0ドルA;
 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.

AltStyle によって変換されたページ (->オリジナル) /