3 /* Added by SDLEMU (http://sdlemu.ngemu.com) */
\r
4 /* Added for GCC UNIX compatibility */
\r
7 #include <sys/types.h>
\r
10 #define O_BINARY (0)
\r
13 #define CDI_V2 0x80000004
\r
14 #define CDI_V3 0x80000005
\r
15 #define CDI_V35 0x80000006
\r
17 static uint8 cdi_track_start_mark[10] = { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
\r
22 uint32 cdi_load_address;
\r
23 uint32 cdi_code_length;
\r
24 s_cdi_descriptor *cdi_descriptor;
\r
25 s_cdi_track **cdi_tracks;
\r
26 uint32 cdi_tracks_count;
\r
29 //////////////////////////////////////////////////////////////////////////////
\r
31 //////////////////////////////////////////////////////////////////////////////
\r
38 //////////////////////////////////////////////////////////////////////////////
\r
39 int cdi_open(char *path)
\r
41 fprintf(log_get(),"cdi: opening %s\n",path);
\r
42 return(open(path,O_BINARY|O_RDONLY));
\r
44 //////////////////////////////////////////////////////////////////////////////
\r
46 //////////////////////////////////////////////////////////////////////////////
\r
53 //////////////////////////////////////////////////////////////////////////////
\r
54 void cdi_close(int fp)
\r
56 fprintf(log_get(),"cdi: closing\n");
\r
59 //////////////////////////////////////////////////////////////////////////////
\r
61 //////////////////////////////////////////////////////////////////////////////
\r
68 //////////////////////////////////////////////////////////////////////////////
\r
72 return lseek(fd, 0LL, SEEK_CUR);
\r
75 s_cdi_descriptor *cdi_get_descriptor(int fp, FILE *stdfp)
\r
77 s_cdi_descriptor *descriptor;
\r
79 uint32 previous_position=0;
\r
84 descriptor=(s_cdi_descriptor *)malloc(sizeof(s_cdi_descriptor));
\r
88 lseek(fp,0,SEEK_END);
\r
89 descriptor->length=tell(fp);
\r
90 if (descriptor->length<8)
\r
92 if (stdfp) fprintf(stdfp,"cdi: image is too short (%i bytes)\n",descriptor->length);
\r
96 lseek(fp,descriptor->length-8,SEEK_SET);
\r
97 read(fp,&descriptor->version,4);
\r
98 read(fp,&descriptor->header_offset,4);
\r
99 lseek(fp,descriptor->header_offset,SEEK_SET);
\r
100 read(fp,&descriptor->nb_of_sessions,2);
\r
102 descriptor->sessions=(s_cdi_session *)malloc(descriptor->nb_of_sessions*sizeof(s_cdi_session));
\r
103 if (descriptor->sessions==0)
\r
108 if (stdfp) fprintf(stdfp,"cdi: %i sessions\n",descriptor->nb_of_sessions);
\r
109 uint32 track_position=0;
\r
110 for (uint16 session=0;session<descriptor->nb_of_sessions;session++)
\r
112 read(fp,&descriptor->sessions[session].nb_of_tracks,2);
\r
113 descriptor->sessions[session].tracks=(s_cdi_track*)malloc(descriptor->sessions[session].nb_of_tracks*sizeof(s_cdi_track));
\r
115 if (stdfp) fprintf(stdfp,"cdi:\ncdi: reading session %i (%i tracks)\n",session,descriptor->sessions[session].nb_of_tracks);
\r
117 for (uint16 track=0;track<descriptor->sessions[session].nb_of_tracks;track++)
\r
119 static char current_start_mark[10];
\r
120 s_cdi_track *current_track=&descriptor->sessions[session].tracks[track];
\r
121 if (stdfp) fprintf(stdfp,"cdi:\ncdi: \t\treading track %i\n",track);
\r
125 read(fp,&temp_value, 4);
\r
126 if (temp_value != 0)
\r
127 lseek(fp, 8, SEEK_CUR); // extra data (DJ 3.00.780 and up)
\r
129 read(fp,current_start_mark, 10);
\r
130 if (memcmp(cdi_track_start_mark, current_start_mark, 10))
\r
132 if (stdfp) fprintf(stdfp,"cdi: could not find the track start mark");
\r
135 read(fp,current_start_mark, 10);
\r
136 if (memcmp(cdi_track_start_mark, current_start_mark, 10))
\r
138 if (stdfp) fprintf(stdfp,"cdi: could not find the track start mark");
\r
142 lseek(fp, 4, SEEK_CUR);
\r
143 read(fp,¤t_track->filename_length, 1);
\r
144 lseek(fp, current_track->filename_length, SEEK_CUR);
\r
146 lseek(fp, 11, SEEK_CUR);
\r
147 lseek(fp, 4, SEEK_CUR);
\r
148 lseek(fp, 4, SEEK_CUR);
\r
149 read(fp,&temp_value, 4);
\r
150 if (temp_value == 0x80000000)
\r
151 lseek(fp, 8, SEEK_CUR); // DJ4
\r
152 lseek(fp, 2, SEEK_CUR);
\r
154 read(fp, ¤t_track->pregap_length, 4);
\r
155 if (current_track->pregap_length!=150)
\r
157 fprintf(log_get(),"cdi: warning: pregap different than 150\n");
\r
159 read(fp, ¤t_track->length, 4);
\r
160 if (stdfp) fprintf(stdfp,"cdi: \t\t\tpregap length : %i\n", current_track->pregap_length);
\r
161 if (stdfp) fprintf(stdfp,"cdi: \t\t\tlength : %i\n", current_track->length);
\r
163 lseek(fp, 6, SEEK_CUR);
\r
165 read(fp, ¤t_track->mode, 4);
\r
166 if (stdfp) fprintf(stdfp,"cdi: \t\t\tmode : %i\n", current_track->mode);
\r
168 lseek(fp, 12, SEEK_CUR);
\r
169 read(fp, ¤t_track->start_lba, 4);
\r
170 if (stdfp) fprintf(stdfp,"cdi: \t\t\tstart lba : %i\n", current_track->start_lba);
\r
171 read(fp, ¤t_track->total_length, 4);
\r
172 if (stdfp) fprintf(stdfp,"cdi: \t\t\ttotal length : %i\n", current_track->total_length);
\r
173 lseek(fp, 16, SEEK_CUR);
\r
174 read(fp, ¤t_track->sector_size_value, 4);
\r
175 if (stdfp) fprintf(stdfp,"cdi: \t\t\tsector size : %i\n", current_track->sector_size_value);
\r
177 switch(current_track->sector_size_value)
\r
179 case 0 : current_track->sector_size = 2048; break;
\r
180 case 1 : current_track->sector_size = 2336; break;
\r
181 case 2 : current_track->sector_size = 2352; break;
\r
183 if (stdfp) fprintf(stdfp,"cdi: \t\t\tunsupported %i bytes sector",current_track->sector_size_value);
\r
188 if (current_track->mode > 2)
\r
189 if (stdfp) fprintf(stdfp,"cdi: \t\t\ttrack mode %i not supported",current_track->mode);
\r
191 lseek(fp, 29, SEEK_CUR);
\r
192 if (descriptor->version != CDI_V2)
\r
194 lseek(fp, 5, SEEK_CUR);
\r
195 read(fp,&temp_value, 4);
\r
196 if (temp_value == 0xffffffff)
\r
197 lseek(fp, 78, SEEK_CUR); // extra data (DJ 3.00.780 and up)
\r
199 current_track->position=track_position;
\r
200 track_position+=(current_track->pregap_length+current_track->length)*current_track->sector_size;
\r
201 previous_position=track_position;
\r
203 lseek(fp, 4, SEEK_CUR);
\r
204 lseek(fp, 8, SEEK_CUR);
\r
205 if (descriptor->version != CDI_V2)
\r
206 lseek(fp, 1, SEEK_CUR);
\r
209 if (descriptor->header_offset == 0)
\r
212 return(descriptor);
\r
214 //////////////////////////////////////////////////////////////////////////////
\r
216 //////////////////////////////////////////////////////////////////////////////
\r
223 //////////////////////////////////////////////////////////////////////////////
\r
224 void cdi_dump_descriptor(FILE *fp,s_cdi_descriptor *cdi_descriptor)
\r
226 fprintf(fp,"cdi: %i Mb\n",cdi_descriptor->length>>20);
\r
227 fprintf(fp,"cdi: format version ");
\r
228 switch(cdi_descriptor->version)
\r
230 case CDI_V2: fprintf(fp,"2\n"); break;
\r
231 case CDI_V3: fprintf(fp,"3\n"); break;
\r
232 case CDI_V35: fprintf(fp,"3.5\n"); break;
\r
233 default: fprintf(fp,"unknown\n"); break;
\r
235 fprintf(fp,"cdi: %i sessions\n",cdi_descriptor->nb_of_sessions);
\r
237 //////////////////////////////////////////////////////////////////////////////
\r
239 //////////////////////////////////////////////////////////////////////////////
\r
246 //////////////////////////////////////////////////////////////////////////////
\r
247 uint8 *cdi_extract_boot_code(int fp, s_cdi_descriptor *cdi_descriptor)
\r
249 s_cdi_track *boot_track=&cdi_descriptor->sessions[1].tracks[0];
\r
250 uint32 boot_track_size=boot_track->length*boot_track->sector_size;
\r
252 uint8 *boot_track_data=(uint8*)malloc(boot_track_size);
\r
253 lseek(fp,2+(boot_track->position), SEEK_SET);
\r
254 read(fp,boot_track_data,boot_track_size);
\r
256 uint32 *boot_track_data_32=(uint32*)boot_track_data;
\r
258 while (offset<(boot_track_size>>2))
\r
260 if (boot_track_data_32[offset]==0x49205452)
\r
264 if (offset==(boot_track_size>>2))
\r
266 fprintf(log_get(),"cdi: cannot find the boot code\n");
\r
269 offset=(offset<<2)+4;
\r
270 uint16 *data16=(uint16*)&boot_track_data[offset];
\r
271 cdi_load_address=*data16++; cdi_load_address<<=16; cdi_load_address|=*data16++;
\r
272 cdi_code_length=*data16++; cdi_code_length<<=16; cdi_code_length|=*data16++;
\r
273 fprintf(log_get(),"cdi: load address: 0x%.8x\n",cdi_load_address);
\r
274 fprintf(log_get(),"cdi: length: 0x%.8x\n",cdi_code_length);
\r
275 fprintf(log_get(),"cdi: byte swapping boot code\n");
\r
277 for (uint32 i=0;i<(cdi_code_length>>1);i++)
\r
279 uint16 sdata=data16[i];
\r
280 sdata=(sdata>>8)|(sdata<<8);
\r
283 return((uint8*)data16);
\r
285 //////////////////////////////////////////////////////////////////////////////
\r
287 //////////////////////////////////////////////////////////////////////////////
\r
294 //////////////////////////////////////////////////////////////////////////////
\r
295 void cdi_load_sector(uint32 sector, uint8 *buffer)
\r
297 if (sector==0xffffffff)
\r
299 memset(buffer,0x00,2352);
\r
305 lseek(cdi_fp,2+sector,SEEK_SET);
\r
306 read(cdi_fp,buffer,2352);
\r
309 for (uint32 i=0;i<2352;i+=2)
\r
311 uint8 sdata=buffer[i+0];
\r
312 buffer[i+0]=buffer[i+1];
\r