/[projet1]/public/pc/tools/osdk/main/tap2dsk/sources/tap2dsk.c
Defence Force logotype

Contents of /public/pc/tools/osdk/main/tap2dsk/sources/tap2dsk.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1320 - (show annotations)
Sat Oct 24 15:33:07 2015 UTC (3 years, 10 months ago) by dbug
File MIME type: text/plain
File size: 11752 byte(s)
Re-formated code to make it easier to follow the flow
1 /* tap2dsk : converts an Oric tape image to a sedoric/stratsed dsk image */
2 /* (c) F.Frances 2004 */
3
4 /* Limitations :
5 * - only 1 bitmap sector, thus limits the capacity to ~2048 sectors
6 * - only 1 side with 80 tracks max.
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #define NBTRACKS 21
13 #define NBSECT 17
14
15 typedef unsigned char byte;
16 typedef byte sector[256];
17
18 struct {
19 char signature[8];
20 int sides;
21 int tracks;
22 int sect;
23 char pad[256-20];
24 } imageheader = { "ORICDISK", 1, NBTRACKS, NBSECT };
25
26 sector disk[80][NBSECT];
27 sector directory,descriptor;
28 sector system_sect={ // some system parameters
29 0xD0,0xD0,0xD0,0xD0, // drive table
30 0, // keyboard type
31 100,0,10,0, // RENUM parameters
32 'T','A','P','2','D','S','K',' ','S','A','M','P','L','E',' ','D','I','S','C',' ',' ', // disk name
33 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
34 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
35 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' // inist
36 };
37 sector bitmap={
38 0xFF, // signature
39 0,
40 0,0, // number of free sectors
41 0,0, // number of files
42 NBTRACKS, // number of tracks/side
43 NBSECT, // number of sectors/track
44 1, // number of directory sectors
45 NBTRACKS, // number of tracks + 128 if double sided
46 0 // master/slave/gameinit indicator
47 };
48
49 byte sedoric[]=
50 {
51 #include "sedoric3.h"
52 };
53
54 int track,sect=1;
55 unsigned int dir_offset=0x10;
56 int used_sectors;
57
58
59
60 void allocate_sector(int track, int sect, byte *contents)
61 {
62 int linear_sector=track*NBSECT+sect-1;
63 bitmap[0x10+linear_sector/8] &= ~(1<<linear_sector%8);
64 memcpy(disk[track][sect-1],contents,sizeof(sector));
65 used_sectors++;
66 }
67
68 void find_free_sector(byte *contents)
69 {
70 int linear_sector=0;
71 while ((bitmap[0x10+linear_sector/8] & (1<<linear_sector%8)) == 0)
72 linear_sector++;
73
74 track=linear_sector/NBSECT;
75 sect=linear_sector%NBSECT+1;
76 if (track==80) {
77 fprintf(stderr,"Not enough space on sample disc");
78 exit(1);
79 }
80 allocate_sector(track,sect,contents);
81 }
82
83 void update_sector(int track, int sect, byte *contents)
84 {
85 memcpy(disk[track][sect-1],contents,sizeof(sector));
86 }
87
88 void convert_basename(char *dest, char *name)
89 {
90 static int filenumber=0;
91 int dest_offset=0, src_offset=0;
92 printf("Storing ");
93 while (dest_offset<9 && src_offset<17 && name[src_offset])
94 {
95 if (name[src_offset]>='a' && name[src_offset]<='z')
96 name[src_offset]-=0x20;
97
98 if ((name[src_offset]>='0' && name[src_offset]<='9')
99 || (name[src_offset]>='A' && name[src_offset]<='Z'))
100 {
101 putchar(name[src_offset]);
102 dest[dest_offset++]=name[src_offset];
103 }
104 src_offset++;
105 }
106 if (dest_offset)
107 {
108 while (dest_offset<9)
109 dest[dest_offset++]=' ';
110 }
111 else
112 {
113 printf("NONAME%03d",filenumber);
114 sprintf(dest,"NONAME%03d",filenumber++);
115 }
116 }
117
118 void store_file(byte *buf, char *name, byte *header)
119 {
120 int start=(header[6]<<8)+header[7];
121 int end=(header[4]<<8)+header[5];
122 int exec=header[3];
123 int block=header[2];
124 int sectors=(end-start)/sizeof(sector)+1;
125 int desc_sect,desc_track;
126 int desc_off=0x0C;
127
128 memset(descriptor,0,sizeof(sector));
129 find_free_sector(descriptor);
130 desc_track=track; desc_sect=sect;
131 descriptor[2]=0xFF;
132 descriptor[3]=(block?0x40:0x80)+(exec?1:0);
133 descriptor[4]=header[7];
134 descriptor[5]=header[6];
135 descriptor[6]=header[5];
136 descriptor[7]=header[4];
137 if (exec)
138 {
139 descriptor[8]=descriptor[4];
140 descriptor[9]=descriptor[5];
141 }
142 else
143 {
144 descriptor[8]=descriptor[9]=0;
145 }
146 descriptor[10]=sectors&0xFF;
147 descriptor[11]=sectors>>8;
148
149 convert_basename((char*)(directory+dir_offset),name);
150 if (exec)
151 {
152 sprintf((char*)(directory+dir_offset+9),"COM");
153 printf(".COM");
154 }
155 else
156 {
157 sprintf((char*)(directory+dir_offset+9),"%s",block?"BIN":"BAS");
158 printf(".%s",block?"BIN":"BAS");
159 }
160 printf("\n");
161 directory[dir_offset+12]=desc_track;
162 directory[dir_offset+13]=desc_sect;
163 directory[dir_offset+14]=sectors+1+(sectors>=(256-12)/2?1:0); // Sedoric bug work-around : allocate a second descriptor when exactly 122 sectors of data
164 directory[dir_offset+15]=0x40; // UNPROT
165
166 while (sectors--)
167 {
168 find_free_sector(buf);
169 buf+=sizeof(sector);
170 descriptor[desc_off++]=track;
171 descriptor[desc_off++]=sect;
172 if (desc_off==0x100)
173 { // Sedoric bug work-around : allocate a second descriptor when the first is full, even if not needed
174 find_free_sector(descriptor);
175 descriptor[0]=track;
176 descriptor[1]=sect;
177 update_sector(desc_track,desc_sect,descriptor);
178 memset(descriptor,0,sizeof(sector));
179 desc_track=track;
180 desc_sect=sect;
181 desc_off=2;
182 }
183 }
184 update_sector(desc_track,desc_sect,descriptor);
185 }
186
187 char generateEscapeCode(int color)
188 {
189 return (char) 64 + color;
190 }
191
192 int main(int argc, char *argv[])
193 {
194 byte header[9];
195 char name[17];
196 byte file_buffer[48*1024];
197 FILE *tape, *dsk;
198 int dir_track=20, dir_sect=4;
199 int tracks=21; // minimum track number
200 int total_sectors,free_sectors;
201 int tape_num,i;
202 int tape_name_index = -1;
203 int paper_color = -1;
204 int ink_color = -1;
205
206 printf("Tap2dsk V2.1\n");
207
208 if (argc<2)
209 {
210 fprintf(stderr,"Usage: tap2dsk [-c<paper_color>:<ink_color>] [-n<disk_label>] [-i<init_string>] <tape_image1> ...<tape_imageN> <old_disk_image>\n");
211 exit(1);
212 }
213
214 for (i=1; i<argc; i++)
215 {
216 if (argv[i][0]=='-')
217 {
218 switch (argv[i][1])
219 {
220 case 'c':
221 case 'C':
222 if (sscanf(argv[i], "-c%d:%d", &paper_color, &ink_color) != 2)
223 {
224 fprintf(stderr, "Malformed color option. It should be -c<paper_color>:<ink_color>\n");
225 exit(3);
226 }
227 if (paper_color <16 || paper_color >23 || ink_color < 0 || ink_color > 7)
228 {
229 fprintf(stderr, "Wrong colors. Paper color should be between 16 and 23 and ink color between 0 and 7\n");
230 exit(3);
231 }
232 // if the name was before
233 if (tape_name_index > 0)
234 {
235 memset(system_sect + 9, ' ', 21);
236 *(system_sect + 9) = (char)27;
237 *(system_sect + 10) = generateEscapeCode(paper_color);
238 *(system_sect + 11) = (char)27;
239 *(system_sect + 12) = generateEscapeCode(ink_color);
240 if (strlen(argv[tape_name_index]) - 2 > 17)
241 {
242 fprintf(stderr, "Disk label too long (if you use colors you loose four characters)\n");
243 exit(3);
244 }
245 memcpy(system_sect + 13, argv[tape_name_index] + 2, strlen(argv[tape_name_index]) - 2);
246 }
247 break;
248 case 'i':
249 case 'I':
250 if (strlen(argv[i]) - 2 > 60)
251 {
252 fprintf(stderr,"Init string too long\n");
253 exit(3);
254 }
255 memcpy(system_sect+0x1E,argv[i]+2,strlen(argv[i])-2);
256 // remember where it was
257 tape_name_index = i;
258 break;
259 case 'n':
260 case 'N':
261 memset(system_sect+9,' ',21);
262 // if the colors were before
263 if (paper_color > 0 && ink_color >= 0)
264 {
265 *(system_sect + 9) = (char)27;
266 *(system_sect + 10) = generateEscapeCode(paper_color);
267 *(system_sect + 11) = (char)27;
268 *(system_sect + 12) = generateEscapeCode(ink_color);
269 if (strlen(argv[i]) - 2 > 17)
270 {
271 fprintf(stderr, "Disk label too long (if you use colors you loose four characters)\n");
272 exit(3);
273 }
274 memcpy(system_sect + 13, argv[i] + 2, strlen(argv[i]) - 2);
275 }
276 else
277 {
278 // if there are no colors do like before
279 // if the colors are after we will overwrite the label
280 if (strlen(argv[i]) - 2 > 21)
281 {
282 fprintf(stderr, "Disk label too long\n");
283 exit(3);
284 }
285 memcpy(system_sect + 9, argv[i] + 2, strlen(argv[i]) - 2);
286 }
287 tape_name_index = i;
288 break;
289
290 default:
291 fprintf(stderr,"Bad option : %c\n",argv[i][1]);
292 exit(2);
293 }
294 }
295 }
296
297 dsk=fopen(argv[argc-1],"wb");
298 if (dsk==NULL)
299 {
300 fprintf(stderr,"Cannot open %s for writing\n",argv[2]);
301 exit(1);
302 }
303
304 memset(bitmap+0x10,0xFF,sizeof(sector)-0x10);
305 for (i=0; i<99; i++)
306 { // 99 secteurs pour sedoric
307 int track= i/NBSECT;
308 int sector = i%NBSECT + 1;
309 allocate_sector(track,sector,sedoric+i*256);
310 }
311 allocate_sector(20,1,system_sect);
312 allocate_sector(20,2,bitmap);
313 allocate_sector(20,4,directory);
314
315 for (tape_num=1; tape_num<argc-1; tape_num++)
316 {
317 if (argv[tape_num][0]=='-') continue;
318 tape=fopen(argv[tape_num],"rb");
319 if (tape==NULL)
320 {
321 fprintf(stderr,"Cannot read tape image %s\n",argv[tape_num]);
322 exit(1);
323 }
324 printf("Reading %s\n",argv[tape_num]);
325
326
327 while (fgetc(tape)!=EOF)
328 {
329 int start,end,i;
330 while (fgetc(tape)!=0x24)
331 ;
332 for (i=0;i<9;i++) header[i]=fgetc(tape);
333 for (i=0;i<17;i++) {
334 name[i]=fgetc(tape);
335 if (name[i]==0) break;
336 }
337
338 // if the name is null then copy the file name instead
339 if (name[0] == 0)
340 {
341 // only take the file name from the path
342 char *lastdot;
343 char *fileName = argv[tape_num];
344 // try to find '\\'
345 char *lastsep = strrchr(fileName, '\\');
346 if (lastsep != NULL)
347 {
348 // if there is something after the separator
349 if (lastsep+1 != 0)
350 fileName = lastsep + 1;
351 }
352 else
353 {
354 // try to find /
355 lastsep = strrchr(fileName, '/');
356 if (lastsep != NULL)
357 {
358 // if there is something after the separator
359 if (lastsep + 1 != 0)
360 fileName = lastsep + 1;
361 }
362 }
363
364 // remove the extension if there is one
365 lastdot = strrchr(fileName, '.');
366 if (lastdot != NULL)
367 *lastdot = 0;
368 for (i = 0; i<17; i++)
369 {
370 name[i] = fileName[i];
371 if (name[i] == 0) break;
372 }
373 }
374
375 start=(header[6]<<8)+header[7];
376 end =(header[4]<<8)+header[5];
377 for (i=0; i<end+1-start; i++)
378 file_buffer[i]=fgetc(tape);
379 printf("Found %s\n",name);
380 store_file(file_buffer,name,header);
381 bitmap[4]++; // number of files
382 dir_offset+=16;
383 if (dir_offset==0x100)
384 {
385 find_free_sector(directory);
386 directory[0]=track;
387 directory[1]=sect;
388 update_sector(dir_track,dir_sect,directory);
389 memset(directory,0,sizeof(sector));
390 dir_track=track;
391 dir_sect=sect;
392 dir_offset=0x10;
393 update_sector(dir_track,dir_sect,directory);
394 }
395 }
396 fclose(tape);
397 tape=NULL;
398 }
399 directory[2]=dir_offset;
400 update_sector(dir_track,dir_sect,directory);
401
402 if (track>=tracks) tracks=track+1;
403 total_sectors=tracks*NBSECT;
404 free_sectors=total_sectors-used_sectors;
405 bitmap[2]=free_sectors & 0xFF;
406 bitmap[3]=free_sectors >> 8;
407 bitmap[6]=tracks;
408 bitmap[9]=tracks;
409 update_sector(20,2,bitmap);
410
411 imageheader.tracks=tracks;
412 fwrite(&imageheader,sizeof(imageheader),1,dsk);
413 for (track=0;track<tracks;track++)
414 for (sect=1;sect<=NBSECT;sect++)
415 fwrite(disk[track][sect-1],sizeof(sector),1,dsk);
416
417 return 0;
418 }
419
420

  ViewVC Help
Powered by ViewVC 1.1.26