[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]