1 uses Atapi,Transvar;
2
3 const IDEPORT_DATA=0;
4
5 procedure PrintWord(w:word);
6 begin
7 if Chr(w shr 8)<>#0 then
8 write(Chr(w shr 8));
9 if Chr(w and $FF)<>#0 then
10 write(Chr(w and $FF));
11 end;
12
13 var ATAPIDev:PATAPIDevice;
14 f:file;
15 Filename,nr:string;
16 TrackNr,NextTrack,u:byte;
17 err:integer;
18 BlockSize,a,b,TOCSize:word;
19 TOCP:PTOC;
20 TrackLBA,TrackLength:longint;
21 WavH:TWaveHeader;
22 Buffer:array[0..7] of array[0..MAX_CDDADATABLOCK] of byte;
23 TrackCache:word;
24 Drive:boolean;
25 idep:byte;
26 begin
27 if ParamCount<3 then
28 begin
29 writeln(#10+'CDDA2WAV -drive Wavfile TrackNr ...');
30
31
32 writeln(#10,' -drive : -m0 = MASTER IDE 0');
33 writeln(' -s0 = SLAVE IDE 0');
34 writeln(' -m1 = MASTER IDE 1');
35 writeln(' -s1 = SLAVE IDE 1',#10);
36
37 writeln(' Wavfile - specify w/o .WAV');
38 writeln(' TrackNr - die Tracknummern');
39 writeln(' z.B.: "1 4 5 ..."');
40 writeln(#10,'READ README.TXT FIRST !!!');
41 Halt;
42 end;
43
44 Filename:=Paramstr(1);
45 if (Filename[1]<>'-')or(not(Filename[2] in ['m','s']))or
46 (not(Filename[3] in ['0','1'])) then
47 begin
48 writeln('Wrong source drive.');
49 Halt;
50 end else
51 begin
52 if Filename[2]='m' then drive:=DRV_MASTER
53 else drive:=DRV_SLAVE;
54 if Filename[3]='0' then idep:=0
55 else idep:=1;
56 end;
57
58 ATAPIDev:=New(PATAPIDevice,Init(drive,idep,NORESET_DRIVE));
59 write('Identifying device ... ');
60 ATAPIDev^.AllocResponseBuffer(512);
61 if not ATAPIDev^.Identify then
62 begin
63 writeln(#13+#10+'This doesn''t seem to be an ATAPI-device.');
64 writeln('You''re not in Windows, are you ???');
65 ATAPIDev^.FreeResponseBuffer;
66 Dispose(ATAPIDev,Done);
67 Halt;
68 end;
69 write('OK'+#13+#10+'ATAPI device found: ');
70 for u:=0 to 19 do
71 PrintWord(ATAPIDev^.ResponseBuffer^[u+27]);
72 writeln;
73 write('Resetting drive ... ');
74 ATAPIDev^.SoftReset;
75 writeln('OK');
76 ATAPIDev^.FreeResponseBuffer;
77 Dispose(ATAPIDev,Done);
78
79 for u:=3 to ParamCount do
80 begin
81 Val(Paramstr(u),TrackNr,err);
82
83 if err<>0 then
84 begin
85 writeln('Invalid track number (',Paramstr(u),').');
86 Halt;
87 end else write('CD-Readout init ... ');
88 ATAPIDev:=New(PATAPIDevice,Init(drive,idep,NORESET_DRIVE));
89 ATAPIDev^.AllocResponseBuffer(MAX_CDDADATABLOCK*16);
90
91 { err:=3;
92 while (err>0)and(TOCSize=0) do
93 begin}
94 ATAPIDev^.ReadTOC(TOCP,TOCSize);
95 { writeln(ATAPIDev^.GetError);
96 dec(err);
97 end;}
98
99 if ((ATAPIDev^.GetStatus and AST_CHECK)=0)and(TOCSize>0) then
100 begin
101 a:=0;
102 while (TOCP^.Entry[a].TrackNr<>TrackNr)and(TrackNr<=TOCP^.LastTrack)
103 do Inc(a);
104 if TOCP^.Entry[a].TrackNr=TrackNr then
105 begin
106 TrackLBA:=BigEndianLongint(TOCP^.Entry[a].LBA);
107 if TrackNr=TOCP^.LastTrack then NextTrack:=$AA
108 else NextTrack:=TrackNr+1;
109
110 a:=0;
111 while (TOCP^.Entry[a].TrackNr<>NextTrack)
112 do Inc(a);
113 if TOCP^.Entry[a].TrackNr=NextTrack then
114 begin
115 TrackLength:=BigEndianLongint(TOCP^.Entry[a].LBA)-TrackLBA;
116
117 Filename:=UpStr(Paramstr(2));
118 Filename:=Filename+'.WAV';
119 Str(TrackNr,nr);while(Length(nr)<2)do nr:='0'+nr;
120 Insert(nr,Filename,Length(Filename)-3);
121
122
123 Assign(f,Filename);
124
125 Rewrite(f,1);
126
127 with WavH do
128 begin
129 Riff:='RIFF';
130 DataSize:=TrackLength*MAX_CDDADATABLOCK;
131 Length:=DataSize+SizeOf(TWaveHeader);
132 Wavefmt:='WAVEfmt ';
133 Dummy1:=16;
134 Dummy2:=1;
135 Channels:=2;
136 Freq:=44100;
137 SmpRes:=16;
138 BperSmp:=(Channels*SmpRes) div 8;
139 BperSec:=BperSmp*Freq;
140 Data:='data';
141 end;
142
143 BlockWrite(f,WavH,SizeOf(TWaveHeader));
144
145 write('reading out track ',TrackNr,' ... ');
146
147 { writeln('S: ',TrackLBA,'L: ',TrackLength);}
148 while (TrackLength>0) do
149 begin
150 if TrackLength>16 then TrackCache:=16 else TrackCache:=TrackLength;
151
152 { writeln('Pos: ',TrackLBA,' ');}
153
154 if not ATAPIDev^.ReadCDInit(SECTYPE_CDDA,TrackLBA,TrackCache,
155 RCDF_NOHDR+RCDF_USERDATA,RCDSC_NOSUBCHDATA,MAX_CDDADATABLOCK) then
156 begin
157 writeln('No CDDA-Data in track. ',TrackLength);
158 Close(f);Erase(f);Break;
159 { TrackCache:=0;
160 Dec(TrackLength);
161 continue;}
162 end;
163
164 if (ATAPIDev^.GetStatusEx and AST_CHECK)>0 then
165 begin
166 Close(f);
167 break;
168 end;
169
170 { if TrackCache>0 then}
171
172 for a:=0 to Pred(TrackCache) do
173 begin
174 while (ATAPIDev^.GetStatus and AST_BSY)>0 do;
175 while (ATAPIDev^.GetInterruptReason and AIR_IO)=0 do;
176
177 for b:=0 to Pred(MAX_CDDADATABLOCK) shr 1 do
178 ATAPIDev^.ResponseBuffer^[b+(MAX_CDDADATABLOCK shr 1)*a]:=
179 Portw[ATAPIDev^.ATAPIPort+IDEPORT_DATA];
180
181 Dec(TrackLength);
182 Inc(TrackLBA);
183 end;
184 { while (ATAPIDev^.GetStatus and AST_BSY)>0 do;}
185 BlockWrite(f,ATAPIDev^.ResponseBuffer^,TrackCache*MAX_CDDADATABLOCK);
186 end;
187 if TrackLength=0 then Close(f);
188 writeln('done.');
189 end else
190 writeln('track ',TrackNr,' not found.');
191
192 end else
193 writeln('Track not found (',TrackNr,').');
194
195
196 FreeMem(TOCP,TOCSize);
197 end else
198 writeln('failed.');
199
200 if TrackLength>0 then
201 begin
202 writeln('Readout failure.');
203 writeln('WAV-file truncated.');
204 end;
205
206
207 ATAPIDev^.FreeResponseBuffer;
208 Dispose(ATAPIDev,Done);
209 end;
210 end.
211