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