ďťż
Lemur zaprasza
{$X+,O+,F+} UNIT CDRom; INTERFACE {**********************************************} USES DOS; CONST CDRead = $4402; CDWrite = $4403; { Definicje niektórych kodów funkcji dla wej./wyj. IOCTL CD-ROM-u} EjectDisk = 0; LockUnlock = 1; ResetCD = 2; AudioCtrl = 3; WriteCtrlStr= 4; CloseTray = 5; TYPE CDPosType = RECORD CtlAdr : BYTE; { Bajt kontrolny } Track : BYTE; { Bieżąca ścieżka audio } Indx : BYTE; { Wskaźnik lub bajt indeksowy } Min : BYTE; { Minuty \ } Sec : BYTE; { Sekundy > Bieżący czas ścieżki } Frame : BYTE; { Ramki / } Zero : BYTE; { Zawsze powinno być } DMin : BYTE; { Minuty \ } DSec : BYTE; { Sekundy > Bieżący czas na dysku} DFrame : BYTE; { Ramki / } END; CDInfoRecord = RECORD Status : WORD; {Przechowuje status ostatniej operacji} NumCD : WORD; {Liczba dostępnych napędów CD-ROM} DrvChar: CHAR; {Litera pierwszego dostępnego CD-ROM-u} DrvNo : BYTE; {Wartość typy byte pierwszego napędu} DVParam: LONGINT; { Parametry napędu } VolInf : ARRAY[1..8] OF BYTE;{ Przechowuje informacjęf o kanałach audio } LoTrack: BYTE; { Numer pierwszej ścieżki audio } HiTrack: BYTE; { Numer ostatniej ścieżki audio } LdAdr : LONGINT; { Adres Lead_Track (ścieżki } { prowadzącej) w standardzie HSG } END; DriveList = RECORD UnitCode : BYTE; DOffset,DSegment : WORD; END; VAR CDDevice :TEXT; { Nazwa własna napędu CD-ROM } CDStatus :WORD; {Status ostatnio wykonanej operacji} CDControl:ARRAY[0..200] OF BYTE; {Rezerwacja pamięci} {na blok Device_Driver_Request } CDHandle :WORD; { Adres pamięci, gdzie } { znajduje się początek nagłówka drivera } CDInf :CDInfoRecord; PosInf :CDPosType; FUNCTION CDGetHandle : WORD; { Procedura, która umożliwia ustalenie nazwy} { napędu CD-ROM } PROCEDURE CDCloseHandle; { Procedura zamyka dostęp do danego napędu } { CD-ROM } FUNCTION CDIoctl(IntFunc, Len : WORD; VAR Device_Driver_Request ) : BOOLEAN; PROCEDURE DriverRequest(Drive : BYTE; VAR Device_Driver_Request ); FUNCTION CDEject : BOOLEAN; { Procedura otwiera kieszeń CD-ROM } FUNCTION CDCloseTray : BOOLEAN; { Procedura zamyka kieszeń CD-ROM } FUNCTION CDReset : BOOLEAN; { Procedura inicjalizująca driver CD-ROM } FUNCTION CDGetVol(VAR InfRec : CDInfoRecord) : BOOLEAN; { Procedura pobiera aktualny stan siły głosu } FUNCTION CDStop : BOOLEAN; { Procedura wstrzymuje odtwarzanie audio CD-ROM } PROCEDURE CDInitInfo; { Procedura inicjująca informacje o CD-ROM-ie } FUNCTION CDResumePlay : BOOLEAN; { Procedura wznawia odtwarzanie audio CD-ROM } FUNCTION CDGetPos(VAR PosInf : CDPosType ) : BOOLEAN; { Procedura zwraca auktualną pozycję ścieżki,} { która właśnie jest odtwarzana } FUNCTION Red2HSG(Inf : LONGINT ) : LONGINT; FUNCTION CDGetTrackStart(Track : BYTE ) : LONGINT; FUNCTION CDVolSize : LONGINT; { Procedura ustala rozmiar siły głosu w sektorach } FUNCTION CDSectSize : WORD; { Procedura ustalająca rozmiar sektora w bajtach } FUNCTION CDPlayAudio(Track : BYTE; Len : LONGINT ) : BOOLEAN; IMPLEMENTATION {*************************************************} VAR OldExit : POINTER; CDDL : DriveList; CDDriver : STRING[8]; { nazwa napędu CD-ROM } FUNCTION GetDriverName : String; VAR CDNTemp : Array[1..18] OF BYTE; Where : POINTER; Count : BYTE; CDSTemp : STRING[8]; BEGIN ASM MOV AX, 1501h { pobierz nazwę } MOV BX, OFFSET CDDL MOV DX, SEG CDDL MOV ES, DX INT $2F END; Where := Ptr(CDDL.DSegment,CDDL.DOffset); { oblicz, gdzie w pamięci } Move(Where^^,CDNTemp,18); Count := 1; REPEAT CDStemp[Count] := CHR(CDNTemp[10+Count]); {przelicz} {wartości cyfrowe na odpowiednie nazwy literowe napędu(ów)} INC(Count); UNTIL (Count > 8) OR (CDNTemp[10+Count]=32); CDSTemp[0] := CHR(Count-1); GetDriverName := CDSTemp; END; FUNCTION CDGetHandle : WORD; VAR Handle : WORD; BEGIN Assign(CDDevice,CDDriver); {$I-} Reset(CDDevice); { Otwiera dostęp do drivera CDROM-u} {$I+} IF (IOResult = 0) THEN Handle := TextRec(CDDevice).Handle { Zapamiętuje} {adres (typ predefiniowany w TP 7.0)} ELSE Handle := 0; CDGetHandle := Handle; END;{CDGetHandle} PROCEDURE CDCloseHandle; BEGIN {$I-} Close(CDDevice); {$I+} IF (IOResult = 0) THEN {Bez znaczenia } {Czyści rezultat operacji odczytu} BEGIN END; END;{CDCloseHandle} FUNCTION CDIoctl(IntFunc, Len : WORD;VAR Device_Driver_Request ) : BOOLEAN; ASSEMBLER; ASM PUSH DS MOV AX,IntFunc { 4402 = Odczyt, 4403 = Zapis } MOV BX,CDHandle { Ładuje nazwę drivera CD-ROM } MOV CX,Len LDS DX,Device_Driver_Request { Ładuje do DS:DX adres bloku danych} INT $21 MOV CDStatus,AX { Zapamiętuje status ct funkcji } JNC @NoError { Jeśli bez błędu, to skok do NoError} MOV AX,0 { Zwróć FALSE } @NoError: MOV AX,1 { Zwróć TRUE } @Exit: POP DS END;{CDIoctl} PROCEDURE DriverRequest(Drive : BYTE;VAR Device_Driver_Request ); ASSEMBLER; ASM PUSH ES { Zachowaj na stosie ES } MOV AX,$1510 XOR CH,CH MOV CL,Drive { Określenie napędu, którego } { będzie to dotyczyło } LES BX,Device_Driver_Request{ Ładuje do DS:DX adres bloku danych} INT $2F POP ES { Odtwórz ES } END;{DriverRequest} FUNCTION CDEject : BOOLEAN; BEGIN CDControl[0] := EjectDisk; CDEject := CDIoctl(CDWrite,1,CDControl); END;{CDEject} FUNCTION CDCloseTray : BOOLEAN; BEGIN CDControl[0] := CloseTray; CDCloseTray := CDIoctl(CDWrite,1,CDControl); END;{CDCloseTray} FUNCTION CDReset : BOOLEAN; BEGIN CDControl[0] := ResetCD; CDReset := CDIoctl(CDWrite,1,CDControl); END;{CDReset} FUNCTION CDGetVol(VAR InfRec : CDInfoRecord) : BOOLEAN; VAR Temp : BOOLEAN; { Zapamiętuje rezultat odczytu} BEGIN CDControl[0] := 4; Temp := CDIoctl(CDRead,8,CDControl); IF Temp THEN { Jeśli odczyt był w porządku, } Move(CDControl[1],InfRec.VolInf,8) {zapamiętaj} { ustawienia siły głosu} ELSE FillChar(InfRec.VolInf,8,#0); { w przeciwnym } { razie wyzeruj tablicę } CDGetVol := Temp; END;{CDGetVol} FUNCTION CDStop : BOOLEAN; BEGIN FillChar(CDControl,Sizeof(CDControl),#0); CDControl[0] := 5; {Oczekiwana długość bloku danuch} CDControl[1] := 0; {Zawsze zero } CDControl[2] := $85; { Stop audio CD-ROM } DriverRequest(CDInf.DrvNo,CDControl); CDStatus := CDControl[3] OR CDControl[4] SHL 8; CDStop := (CDStatus AND $8000) = 0; END;{CDStop} PROCEDURE CDInitInfo; BEGIN ASM MOV AX,$1500 MOV BX,0 INT $2F MOV CDInf.NumCD,BX { Zapamiętaj liczbę dostępnych CD-ROM-ów } MOV CDInf.DrvNo,CL { Zapamiętaj numer pierwszego} MOV CDInf.DrvChar,CL { Przekształć numer w literowe oznaczenie } ADD CDInf.DrvChar,'A' END; FillChar(CDControl,SizeOf(CDControl),#0); CDControl[0] := $0A; CDIoctl(CDRead,6,CDControl); Move(CDControl[1],CDInf.LoTrack,6); END;{CDInitInfo} FUNCTION CDResumePlay : BOOLEAN; BEGIN FillChar(CDControl,Sizeof(CDControl),#0); CDControl[0] := 5; { Oczekiwana długość bloku danych} CDControl[1] := 0; { Zawsze zero } CDControl[2] := $88; { Function to Resume play a CD } DriverRequest(CDInf.DrvNo,CDControl); CDStatus := CDControl[3] OR CDControl[4] SHL 8; CDResumePlay := (CDStatus AND $8000) = 0; END;{CDResumePlay} FUNCTION CDGetPos(VAR PosInf : CDPosType ) : BOOLEAN; BEGIN CDControl[0] := $0C; CDGetPos := CDIoctl(CDRead,10,CDControl); Move(CDControl[1],PosInf,10); END;{CDGetPos} FUNCTION Red2HSG(Inf : LONGINT ) : LONGINT; VAR Temp :LONGINT; BEGIN Temp := LONGINT(( Inf SHR 16 ) AND $FF ) * 4500; Temp := Temp + LONGINT(( Inf SHR 8 ) AND $FF ) * 75; Temp := Temp + LONGINT(( Inf ) AND $FF ) ; Red2HSG := Temp - 2; END;{Red2HSG} FUNCTION CDGetTrackStart(Track : BYTE ) : LONGINT; VAR TrackInf :ARRAY[0..6] OF BYTE; Start :LONGINT; BEGIN TrackInf[0] := $0B; TrackInf[1] := Track; { Którego tracku będzie} { dotyczyła informacja} CDIoctl(CDRead,6,TrackInf); Move(TrackInf[2],Start,4); CDGetTrackStart := Red2HSG(Start); END;{CDGetTrackStart} FUNCTION CDVolSize : LONGINT; VAR TempLong : LONGINT; BEGIN CDControl[0] := 8; CDIoctl(CDRead,4,CDControl); { Pobierz informację} Move(CDControl[1],TempLong,4); CDVolSize := TempLong; END;{CDVolSize} FUNCTION CDSectSize : WORD; VAR TempWord :WORD; BEGIN CDControl[0] := 7; CDIoctl(CDRead,4,CDControl); { Pobierz informację} Move(CDControl[2],TempWord,2); CDSectSize := TempWord; END;{CDSectSize} FUNCTION CDPlayAudio(Track : BYTE;Len : LONGINT ) : BOOLEAN; VAR TrackStart : LONGINT; BEGIN FillChar(CDControl,SizeOf(CDControl),#0); { Wyczyść blok danych} CDControl[0] := 22; { Długość bloku danych } CDControl[1] := 0; { Zawsze zero } CDControl[2] := $84; { Odtwarzaj audio } TrackStart := CDGetTrackStart(Track); Move(TrackStart,CDControl[14],4); Move(Len,CDControl[18],4); { Liczba sektorów do odegrania} DriverRequest(CDInf.DrvNo,CDControl); CDStatus := CDControl[3] OR CDControl[4] SHL 8; CDPlayAudio := (CDStatus AND $8000) = 0; END;{CDPlayAudio} {$F+} PROCEDURE CDExit; { Procedura do robienia porządków po nas} BEGIN ExitProc := OldExit; { Odtwórz oryginalną procedurę wyjścia} CDCloseHandle; { Zamknij dostęp do drivera CD-ROM-u} END; {$F-} BEGIN CDDriver := GetDriverName; CDHandle := CDGetHandle; IF (CDHandle 0) THEN BEGIN CDInitInfo; OldExit := ExitProc; ExitProc := @CDExit; END; END.{CDRom} {*************************************************************************} Stronę opracował |