*/
Written some cool source code? Upload it to Programmer's Heaven.
*/

View SOURCE\RIPCD.PAS

0cd CD-Rom Emulator v7.1 with Asm/Pascal sourcecode

Submitted By: WEBMASTER
Rating: (Not rated) (Rate It)


{$A+,B-,D+,E+,F+,G+,I+,L+,N+,O+,P+,Q+,R+,S+,T-,V+,X+,Y+}
{$M 16384,0,16384}
Program RipCD;

Uses
        Crt,Dos;

Const
        DriveNo : Word   = 4;

Var
        _AX, _Flags     : Word;

Const
        DriverOk                : Byte  = 255;
        CDOk                : Byte      = 255;
        CDDrives                : Byte  = 0;

Function cdExist : Boolean; Assembler;
Asm
        CMP          [CDOk],-1
        JE            @@DOCHECK
        MOV          AL,[CDOk]
        JMP          @@EXIT
@@DOCHECK:
        MOV          AX,$1500
        XOR          BX,BX
        XOR          CX,CX
        INT          $2F
        TEST    BX,BX
        JNZ          @@OK
        MOV          AL,FALSE
        JMP          @@EXIT
@@OK:
        MOV          AL,TRUE
        MOV          [CDDrives],BL
@@EXIT:
        MOV          [CDOk],AL
End;

Function cdDriveCount : Byte; Assembler;
Asm
        CALL    cdExist
        OR            AL,AL
        JZ            @@NO_CD
        MOV          AL,[CDDrives]
        JMP          @@EXIT
@@NO_CD:
        XOR          AX,AX
@@EXIT:
End;

Function driverExist : Boolean; Assembler;
Asm
        CMP          [DriverOk],-1
        JE            @@DOCHECK
        MOV          AL,[DriverOk]
        JMP          @@EXIT
@@DOCHECK:
        MOV          AX,$1100
        PUSH    $DADA
        INT          $2F
        POP          BX
        CMP          AL,$FF
        JE            @@OK
@@NOT_OK:
        MOV          AL,FALSE
        JMP          @@EXIT
@@OK:
        CMP          BX,$ADAD
        JNE          @@NOT_OK
        MOV          AL,TRUE
@@EXIT:
        MOV          [DriverOK],AL
End;

Procedure Request(Prompt: String; rCommand,rParam: Byte; rDataLength: Byte; Var rData);
Var
        DeviceRequest   : Record
                Len                    : Byte;
                UnitNo    : Byte;
                Command  : Byte;
                Status    : Word;
                Reserved        : Array[1..8] Of Byte;
                TheData  : Array[0..31] Of Byte;
        End;
        Data                    : Array[0..31] Of Byte;
        P                                                 : PChar;
        W                                                 : Word;

        Procedure SendRequest(Var R);
        Begin
                Asm
                        MOV          AX,$1510
                        MOV          CX,[DriveNo]
                        LES          BX,[DWORD PTR R]
                        INT          $2F
                End;
        End;

Begin
        If Prompt<>'' Then
                Write('Reading: ',Prompt);
        With DeviceRequest Do Begin
                Len:=13;
                UnitNo:=0;
                Command:=3;

                TheData[0]:=0;
                P:=@Data;
                Move(P,TheData[1],4);
                W:=rDataLength+1;
                Move(W,TheData[5],2);
                TheData[7]:=0;
                TheData[8]:=0;
                TheData[9]:=0;
                TheData[10]:=0;
                TheData[11]:=0;
                TheData[12]:=0;
        End;
        Data[0]:=rCommand;
        Data[1]:=rParam;
        SendRequest(DeviceRequest);
        Move(Data[1],rData,rDataLength);
        If Prompt<>'' Then
                WriteLn;
End;

Function ReadVTOC(Var VTOC; Index : Word) : Word; Assembler;
Asm
        MOV          AX,$1505
        LES          BX,[DWORD PTR VTOC]
        MOV          CX,[DriveNo]
        MOV          DX,[Index]
        INT          $2F
        PUSHF
        POP          [_Flags]
        MOV          [_AX],AX
        JC            @@ERR

        MOV          [DosError],0
        JMP          @@EXIT
@@ERR:
        MOV          [DosError],AX
        XOR          AX,AX
@@EXIT:
End;

Function cdDrive(Index : Byte) : Char; Assembler;
Var
        Letters : Array[1..26] Of Char;
Asm
        CMP          [Index],0
        JE            @@NO_DRIVE
        CALL    cdDriveCount
        CMP          AL,[Index]
        JB            @@NO_DRIVE
        MOV          AX,$150D
        MOV          BX,SS
        MOV          ES,BX
        LEA          BX,[Letters]
        INT          $2F
        MOV          BL,[Index]
        XOR          BH,BH
        MOV          SI,BX
        MOV          AL,[BYTE PTR Letters+SI-1]
        ADD          AL,'A'
        JMP          @@EXIT
@@NO_DRIVE:
        MOV          AL,0
@@EXIT:
End;

Function cdDriveExist(Drive : Char) : Boolean; Assembler;
Asm
        CALL    driverExist
        OR            AL,AL
        JZ            @@NO_DRIVER
        MOV          CL,[Drive]
        XOR          CH,CH
        AND          CL,$DF
        CMP          CL,'A'
        JB            @@NO_DRIVER
        CMP          CL,'Z'
        JA            @@NO_DRIVER
        SUB          CL,'A'
        MOV          AX,$150B
        XOR          BX,BX
        INT          $2F
        CMP          BX,$ADAD
        JNE          @@NO_DRIVER
        TEST    AX,AX
        JZ            @@NO_DRIVER
        MOV          AL,TRUE
        JMP          @@EXIT
@@NO_DRIVER:
        MOV          AL,FALSE
@@EXIT:
End;

Function GetFileName(Func: Byte; Var Name) : Boolean; Assembler;
Asm
        MOV          AH,$15
        MOV          AL,[Func]
        LES          BX,[DWORD PTR Name]
        MOV          CX,[DriveNo]
        INT          $2F
End;

Procedure ReadSector(Index : LongInt; Var Sector); Assembler;
Asm
        mov          ax,$1508
        les          bx,[dword ptr Sector]
        mov          cx,[DriveNo]
        mov          dx,$0001
        mov          di,[word ptr Index]
        mov          si,[word ptr Index+2]
        int          $2f
End;

Procedure GetDiskFree(Var _ax,_bx,_cx,_dx : Word); Assembler;
Asm
        mov          ah,$36
        mov   dx,[DriveNo]
        inc          dx
        int          $21
        les          di,[dword ptr _ax]
        mov          [es:di],ax
        les          di,[dword ptr _bx]
        mov          [es:di],bx
        les          di,[dword ptr _cx]
        mov          [es:di],cx
        les          di,[dword ptr _dx]
        mov          [es:di],dx
End;

Procedure GetVolumeLabel(Var VL);
Var
        SR      : SearchRec;
Begin
        Write('Reading: Volume label');
        FillChar(VL,13,#0);
        FindFirst(Chr(65+DriveNo)+':\*.*',VolumeID,SR);
        While DosError=0 Do Begin
                If (SR.Attr And VolumeID)<>0 Then Begin
                        If Pos('.',SR.Name)>0 Then
                                Delete(SR.name,Pos('.',SR.Name),1);
                        Move(SR.Name[1],VL,Length(SR.Name));
                        Break;
                End;
                FindNext(SR);
        End;
        WriteLn;
End;

Var
        Data                        : Array[1..16] Of Byte;
        F,F2                        : File;
        I                                                        : Word;
        TrackLo     : Byte;
        TrackHi     : Byte;
        VTOC                        : Array[0..16383] Of Byte;
        Index                  : Word;

        Dir                                   : DirStr;
        Name                        : NameStr;
        Ext                                   : ExtStr;
        Size                        : Word;
        InBuffer                                : Word;
        S                                                        : String;
        C                                                        : Char;
        _bx,_cx,_dx               : Word;

Begin
        If Not driverExist Then Begin
                WriteLn('MSCDEX not loaded');
                Halt(1);
        End;
        If ParamStr(1)='/?' Then Begin
                WriteLn('Usage: RIPCD filename d:');
                Halt(1);
        End;
        If cdDriveCount=1 Then Begin
                If (ParamCount<1) Or (ParamCount>2) Then Begin
                        WriteLn('Invalid number of parameters; RIPCD /? for help');
                        Halt(1);
                End;
                DriveNo:=Ord(cdDrive(1))-Ord('A');
        End Else Begin
                If ParamCount<>2 Then Begin
                        WriteLn('Invalid number of parameters; RIPCD /? for help');
                        Halt(1);
                End;
                S:=ParamStr(2);
                If (Length(S)=2) And (S[2]=':') And (UpCase(S[1]) In ['A'..'Z']) Then Begin
                        C:=UpCase(S[1]);
                        If Not cdDriveExist(C) Then Begin
                                WriteLn('Drive ',C,': is not a cd-rom');
                                Halt(1);
                        End;
                        DriveNo:=Ord(C)-Ord('A');
                End Else Begin
                        WriteLn('Invalid parameters; RIPCD /? for help');
                        Halt(1);
                End;
        End;
        FSplit(ParamStr(0),Dir,Name,Ext);
        Assign(F,ParamStr(1));
        ReWrite(F,1);
        I:=0;
        BlockWrite(F,I,2);      { Offset of VTOC            }
        BlockWrite(F,I,2);      { Offset of Sectors   }
        Request('Sector size',7,0,3,Data);
        BlockWrite(F,Data,3);
        Request('Volume size',8,0,4,Data);
        BlockWrite(F,Data,4);
        Request('Audio disk info',10,0,6,Data);
        BlockWrite(F,Data,6);
        TrackLo:=Data[1];
        TrackHi:=Data[2];
        Request('UPC code',14,0,10,Data);
        BlockWrite(F,Data,10);

        Write('Reading: Filenames');
        GetFileName(2,VTOC);
        BlockWrite(F,VTOC,38);

        GetFileName(3,VTOC);
        BlockWrite(F,VTOC,38);

        GetFileName(4,VTOC);
        BlockWrite(F,VTOC,38);
        WriteLn;

        GetVolumeLabel(VTOC);
        BlockWrite(F,VTOC,12);

        Write('Reading: Disk free data');
        GetDiskFree(_ax,_bx,_cx,_dx);
        BlockWrite(F,_ax,2);
        BlockWrite(F,_bx,2);
        BlockWrite(F,_cx,2);
        BlockWrite(F,_dx,2);
        WriteLn;

        BlockWrite(F,TrackLo,1);
        BlockWrite(F,TrackHi,1);
        Write('Reading: Audio track info, tracks ',TrackLo,'-',TrackHi);
        For I:=TrackLo To TrackHi Do Begin
                WriteLn(I);
                Request('',11,I,6,Data);
                BlockWrite(F,Data[2],5);
        End;
        WriteLn;

        I:=FileSize(F);
        Seek(F,0);
        BlockWrite(F,I,2);
        Seek(F,I);

        ReadVTOC(VTOC,0);
        Index:=0;
        Repeat
                Write('Reading: Sector ',Index);
                Write(', reading');
                ReadVTOC(VTOC,Index);
                If DosError<>0 Then Begin
                        WriteLn(', end of table');
                        Break;
                End;
                Write(', compressing');
                Assign(F2,'VTOC.TMP');
                ReWrite(F2,1);
                BlockWrite(F2,VTOC,2048);
                Close(F2);
                SwapVectors;
                If GetEnv('COMSPEC')='' Then
                        Exec('C:\COMMAND.COM','/C '+Dir+'CRUNCH.COM VTOC.TMP VTOC_C.TMP >NUL')
                Else
                        Exec(GetEnv('COMSPEC'),'/C '+Dir+'CRUNCH.COM VTOC.TMP VTOC_C.TMP >NUL');
                SwapVectors;

                Assign(F2,'VTOC.TMP');
                Erase(F2);
                Assign(F2,'VTOC_C.TMP');
                ReSet(F2,1);
                BlockWrite(F,Index,2);
                Size:=FileSize(F2)+6;
                BlockWrite(F,Size,2);
                BlockWrite(F,_AX,2);
                BlockWrite(F,_Flags,2);
                BlockRead(F2,VTOC,16384,InBuffer);
                BlockWrite(F,VTOC,InBuffer);
                Close(F2);
                Erase(F2);
                WriteLn;

                Inc(Index);
        Until FALSE;
        ReadVTOC(VTOC,$FFFF);
        Index:=$FFFF;
        BlockWrite(F,Index,2);
        BlockWrite(F,Size,2);
        BlockWrite(F,_AX,2);
        _Flags:=_Flags Or 1;
        BlockWrite(F,_Flags,2);
        I:=FileSize(F);
        Seek(F,2);
        BlockWrite(F,I,2);
        Seek(F,I);
        Write('Reading: System sector 16');
        ReadSector(16,VTOC);
        Assign(F2,'VTOC.TMP');
        ReWrite(F2,1);
        BlockWrite(F2,VTOC,2048);
        Close(F2);

        SwapVectors;
        Exec(GetEnv('COMSPEC'),'/C '+Dir+'CRUNCH.COM VTOC.TMP VTOC_C.TMP >NUL');
        SwapVectors;

        Assign(F2,'VTOC.TMP');
        Erase(F2);
        Assign(F2,'VTOC_C.TMP');
        ReSet(F2,1);
        Size:=FileSize(F2)+6;
        BlockRead(F2,VTOC,16384,InBuffer);
        BlockWrite(F,VTOC,InBuffer);
        Close(F2);
        Erase(F2);

        WriteLn;
        Close(F);
End.
{ return 33032 for invalid tracks }

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.