· 8 years ago · Jun 25, 2018, 01:14 AM
1/////////////////////////////////////////////////////
2//
3// EpsLin v1.31 Beta (c) Juha Forsten 18 Jun / 2002
4// -------------------------------------------------
5// * File utility for Ensoniq samplers (EPS/ASR)
6//
7//
8// ------------------------------------------------------------------------
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; either version 2 of the License, or
12// (at your option) any later version.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22//
23// -------------------------------------------------------------------------
24//
25// TO COMPILE:
26// ===========
27//
28// gcc -Wall EpsLin_v1.31.c -o epslin
29//
30//
31// NOTES!
32// ======
33//
34// * The official ASR-OS disk has "corrupted" OS-file. It has BAD
35// dir-entry, so get/put/erase operations would NOT work correctly..
36// This is not MY fault.. Really!
37//
38// TIP: You can get a GOOD OS-Disk using ASR's own "copy os" command.
39// Get OS efe from that disk and you have a valid OS in file..
40//
41//
42// * Some _commercial_ EPS/ASR tools corrupts the FAT.. You should avoid
43// those programs.. IF you have to use them, please at least check
44// the disks and image-files before use with EpsLin 'check' option (-C).
45// If you use those corrupted disk/images you may loose data!!
46//
47// TODO:
48// =====
49//
50//
51// !! Fix MKDIR Kludge in PutEFE...
52//
53// !! Using Floppy with ReadImage sometimes mess up the FD controller !?
54//
55// !! Working with SCSI (/dev/sd*) my not work properly !? (Termination !?)
56//
57// !! Add 'image copy' -feature (ie. make it possible to transfer
58// data in SCSI HD <-> ZIP, Zip requires '0x6d' at first byte in disk)
59//
60// ! WAV to EFE & EFE to WAV conversions.
61//
62// ! In EPS, the OS has to be in one contiguos part
63// * ASR don't mind...
64//
65// - Erase: Recurse Dirs !!
66//
67// - Format_n_Write -support (?!)
68//
69// - First block not used by EPS/ASR. Write some info to that block ie. use
70// it as a "comments & info" for that disk.. The first letter has to be
71// 'm' (='0x6d).. see above.
72//
73
74#include <ctype.h>
75#include <stdio.h>
76#include <errno.h>
77#include <stdlib.h>
78#include <string.h>
79#include <unistd.h>
80#include <fcntl.h>
81#include <sys/io.h>
82#include <sys/stat.h>
83#include <sys/ioctl.h>
84#include <linux/fd.h>
85#include <linux/fdreg.h>
86
87#define VERSION "v1.31B"
88#define BLOCK_SIZE 512
89#define DIR_BLOCKS 2
90#define DIR_START_BLOCK 3
91#define DIR_END_BLOCK 4
92#define MAX_DIR_DEPTH 10
93
94#define ID_BLOCK 1
95#define OS_BLOCK 2
96#define DISK_LABEL_SIZE 8
97
98#define MAX_NUM_OF_DIR_ENTRIES 39
99#define EFE_SIZE 26
100
101#define FAT_START_BLOCK 5
102#define FAT_ENTRIES 170
103
104#define MAX_DISK_SECT 20
105
106#define EPS_IMAGE_SIZE 819200
107#define ASR_IMAGE_SIZE 1638400
108
109#define DEFAULT_DISK_LABEL "DISK000 "
110
111#define EDE_LABEL "EPS-16 Disk"
112#define EDE_SKIP_START 0xA0
113#define EDE_SKIP_SIZE 200
114#define EDE_ID 0x03
115
116#define EDA_LABEL "ASR-10 Disk"
117#define EDA_SKIP_START 0x60
118#define EDA_SKIP_SIZE 400
119#define EDA_ID 0xCB
120
121// Imagefile types
122#define EPS_TYPE 'e'
123#define ASR_TYPE 'a'
124#define GKH_TYPE 'g'
125#define EDE_TYPE 'E'
126#define EDA_TYPE 'A'
127#define OTHER_TYPE 'o'
128
129// OS version info offsets (in EFE)
130#define EPS_OS_POS 0x3A8
131#define E16_OS_POS 0x390
132#define ASR_OS_POS 0x6F2
133
134// Modes
135#define NONE 0
136#define READ 1
137#define WRITE 2
138#define GET 3
139#define PUT 4
140#define ERASE 5
141#define MKDIR 6
142#define FORMAT 7
143#define TEST 99
144
145
146
147// Return values
148#define ERR -1
149#define OK 0
150
151// Error print-out & exit
152#ifdef DEBUG
153#define EEXIT(args) (fprintf(stderr,"(line: %d) ",__LINE__), fprintf args, exit(ERR))
154#else
155#define EEXIT(args) (fprintf args, exit(ERR))
156#endif
157
158// For 'getopt'
159extern char *optarg;
160extern int optind, opterr, optopt;
161
162// Temp-file name
163static char tmp_file[13] = "EpsLinXXXXXX";
164//static char tmp_file[64];
165
166// Temp-file cleanup -function (called by 'atexit')
167static void CleanTmpFile(void) {
168 unlink(tmp_file);
169}
170
171// EPS/ASR-file types
172static char *EpsTypes[40]={
173 // 0 1 2 3 4 5 6 7 8 9
174 "(empty)","EPS-OS ","DIR/ ","Instr ","EPS-Bnk","EPS-Seq","EPS-Sng","EPS-Sys",".. / ","EPS-Mac",
175
176 // 10 11 12 13 14 15 16 17 18 19
177 " "," "," "," "," "," "," "," "," "," ",
178
179 // 20 21 22 23 24 25 26 27 28 29
180 " "," "," ","E16-Bnk","E16-Eff","E16-Seq","E16-Sng","E16-OS ","ASR-Seq","ASR-Sng",
181
182 // 30 31 32 33 34 35 36 37 38 39
183 "ASR-Bnk","ASR-Trk","ASR-OS ","ASR-Eff"," "," "," "," "," "," ??? ",
184
185
186};
187
188
189//////////////
190// ShowUsage
191void ShowUsage()
192{
193 printf("EpsLin %s (c) J. Forsten (%s)\n", VERSION, __DATE__);
194 printf("==========================================\n");
195 printf("\nUsage: epslin [options] [image_file] [Efe #0] [Efe #1] ... [Efe #N]\n\n");
196 printf("Options:\n-------- \n\n");
197 printf(" -r READ image from disk. (Disk type (EPS/ASR) is autodetected!)\n");
198 printf(" File extension (img/ede/eda) selects the format.\n\n");
199
200 printf(" -w WRITE image to disk. (Disk type (EPS/ASR) is autodetected!)\n");
201 printf(" File extension (img/gkh/ede/eda) selects the format.\n\n");
202
203 printf(" -fe,-fa, -fi FORMAT disk/image/device (a=asr, e=eps, i=image/device)\n");
204 printf(" Use '-l' option to define disk label.\n");
205 printf(" If imagefile don't exists it is created. \n");
206 printf(" Image size is then needed an a last argument.\n");
207 printf(" Size is in bytes ('K' and 'M' can be used as a suffix)\n");
208
209 printf(" Examples: 'epslin -fa' : Format ASR-Disk\n");
210 printf(" 'epslin -fi MyImage.img' : Format MyImage.img\n");
211 printf(" file exists\n");
212 printf(" 'epslin -fi MyCDROM.img 650M' : Create and format\n");
213 printf(" file size 650MB\n");
214 printf(" 'epslin -l EpsHD -fi /dev/sda : Format SCSI disk\n\n");
215
216 printf(" -c CONVERT imagefile from one format to another.\n");
217 printf(" Supported conversions:\n");
218 printf(" .img -> ede (EPS)\n");
219 printf(" .img -> eda (ASR)\n");
220 printf(" .gkh -> img (EPS)\n");
221 printf(" .ede -> img (EPS)\n");
222 printf(" .eda -> img (ASR)\n");
223 printf(" Examples: 'epslin -c my_disk.img my_disk.ede'\n\n");
224
225 printf(" -g index_list \n");
226 printf(" GET Efe(s) from image/dev.\n");
227 printf(" Examples: -g1,2,4 : Efe's 1,2 and 4.\n");
228 printf(" -g10-20 : from 10 to 20.\n");
229 printf(" -g10- : from 10 to end.\n");
230 printf(" -g1,3-5,8 : 1,3 to 5 and 5.\n");
231 printf(" -ga : All from that dir.\n\n");
232
233 printf(" -p [start_index] \n");
234 printf(" PUT Efe(s) to image/dev. The efe is saved to the\n");
235 printf(" first empty index found. The search of empty index\n");
236 printf(" can be set to start at start_index (default=1).\n");
237 printf(" The Efe-files must be defined afer image-file.\n");
238 printf(" Examples: -p efe_files.efe : Put Efe in the first \n");
239 printf(" empty index.\n");
240 printf(" -p *.efe : Put all efes found in\n");
241 printf(" current dir.\n");
242 printf(" -p0 os_file.efe : Put Operating System\n");
243 printf(" to index 0.\n\n");
244
245 printf(" -e index_list \n");
246 printf(" ERASE Efe(s) from image/dev.\n\n");
247
248 printf(" -d path DIRECTORY definition for most operations. \n");
249 printf(" Use sub-directory _numbers_.\n");
250 printf(" Example: -d12/4/7\n\n");
251
252 printf(" -m dir_name MAKE directory.\n\n");
253
254 printf(" -C CHECK the disk/image. Gives detailed info\n");
255 printf(" about the structure of the disk/image.\n\n");
256
257 printf("Image_file = Ensoniq(EPS/ASR)-Disk imagefile\n\n");
258}
259
260///////////////
261// ParseRange
262void ParseRange(char *optarg, char process_efe[MAX_NUM_OF_DIR_ENTRIES])
263{
264 size_t ssize;
265 char tmp_str[80];
266 int from_efe,to_efe,i;
267
268 strcpy(tmp_str,optarg);
269
270 ssize = strspn(tmp_str,"0123456789");
271 tmp_str[ssize]='\0';
272 from_efe= atoi(tmp_str);
273
274 if(strlen(optarg)== ssize+1) {
275 to_efe=MAX_NUM_OF_DIR_ENTRIES-1;
276 } else {
277 to_efe= atoi(tmp_str+ssize+1);
278 }
279 // Mark the range of efes
280 for(i=from_efe;i<=to_efe;i++) process_efe[i]=1;
281
282}
283
284////////////////
285// ParseList
286void ParseList(char *optarg, char process_efe[MAX_NUM_OF_DIR_ENTRIES])
287{
288 size_t ssize;
289 char tmp_str[80];
290 int j;
291
292 strcpy(tmp_str,optarg);
293 j=0;
294 // Slice the argument using ',' as a separator.
295 while((ssize = strspn(tmp_str+j,"0123456789-")) != 0) {
296 tmp_str[ssize+j]='\0';
297 // List element is 'range'
298 if((index(tmp_str+j,'-')) != NULL) {
299 ParseRange(tmp_str+j,process_efe);
300 } else {
301 process_efe[atoi(tmp_str+j)] = 1;
302 }
303 j=j+(ssize+1);
304 }
305}
306
307/////////////////////////
308// ParseEntry
309void ParseEntry(char *optarg, char process_efe[MAX_NUM_OF_DIR_ENTRIES])
310{
311 char *idx_new;
312 int i;
313
314 // All?
315 if(strcmp(optarg,"a")==0) {
316 //Mark all
317 for(i=0;i < MAX_NUM_OF_DIR_ENTRIES; i++) process_efe[i]=1;
318 } else {
319 // List ?
320 if((idx_new=index(optarg,',')) == NULL) {
321 // Range ?
322 if(index(optarg,'-')) {
323 ParseRange(optarg,process_efe);
324 } else {
325 // One number - Mark it
326 process_efe[atoi(optarg)]=1;
327 }
328 } else {
329 ParseList(optarg,process_efe);
330 }
331 }
332
333}
334
335//////////////////////
336// ParseDir
337int ParseDir(char *dirpath_str, unsigned int DirPath[MAX_DIR_DEPTH], unsigned int *subdir_cnt)
338{
339
340 char *idx_new, *idx, dir_str[80];
341
342 // Make a copy of path string
343 strcpy(dir_str,dirpath_str);
344
345 // Check if path starts with '/'
346 if(*dir_str == '/') {
347 if(*(dir_str+1) == '\0') return(OK); else *dir_str=' ';
348 }
349
350 *subdir_cnt=0;
351
352 // Parse 'path'
353 if(dir_str[strlen(dir_str)-1] != '/') {
354 dir_str[strlen(dir_str)]='/';
355 dir_str[strlen(dir_str)+1]='\0';
356 }
357
358 idx= dir_str;
359 while((idx_new= (char *) index(idx,'/')) != NULL) {
360 *idx_new= '\0';
361 DirPath[*subdir_cnt]=atoi(idx);
362 idx= idx_new+1;
363 (*subdir_cnt)++;
364 }
365 return(OK);
366}
367
368
369////////////////////
370// Name to DosName
371void DosName(register char *dosname, char *name)
372{
373 register char *p;
374
375 strcpy(dosname,name);
376 while((p=(char *) strchr(dosname,'*'))!=NULL) {
377 *p='#';
378 }
379
380 // Uncomment if 'space' to '_' -conversion needed
381 /*
382 strcpy(dosname,name);
383 while((p=strchr(dosname,' '))!=NULL) {
384 *p='_';
385 }
386 */
387 strcat(dosname,".efe");
388
389}
390
391////////////////////////////////
392// Print the Dir-List (EFEs)
393void PrintDir(unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE], unsigned int mode,
394 char process_efe[MAX_NUM_OF_DIR_ENTRIES], char in_file[FILENAME_MAX],
395 char media_type, char *DiskLabel, unsigned int free_blks, unsigned int used_blks)
396{
397 unsigned int size, cont, start;
398 unsigned int type, real_type, j, k;
399 char name[13],dosname[17];
400 char media[FILENAME_MAX];
401
402
403 switch (media_type)
404 {
405 case 'f':
406 strcpy(media,"FILE: ");
407 strcat(media,in_file);
408 break;
409 case 'e':
410 strcpy(media,"EPS-DISK ");
411 //strcat(media,DiskLabel);
412 break;
413 case 'a':
414 strcpy(media,"ASR-DISK ");
415 //strcat(media,DiskLabel);
416 break;
417 }
418
419 // Print DirectoryList
420 // ===================
421
422 printf("\n-----------------------------------------+---------------------------------+\n");
423 printf(" Disk Label: %-27s |", DiskLabel);
424 printf(" %-31s |\n", media);
425 printf("------+---------+--------------+---------+------------------+--------------+\n");
426 printf(" Idx |Type | Name |Blocks | FileName | FileSize |\n");
427 printf("------+---------+--------------+---------+------------------+--------------+\n");
428
429
430 for(j=0;j<MAX_NUM_OF_DIR_ENTRIES;j++){
431
432 //Name
433 for(k=0;k<12;k++) {
434 name[k]=Efe[j][k+2];
435 }
436 name[12]=0;
437
438 DosName(dosname,name);
439
440 size =(unsigned int) ((Efe[j][14] << 8) + Efe[j][15]);
441 cont =(unsigned int) ((Efe[j][16] << 8) + Efe[j][17]);
442 start=(unsigned long) ((Efe[j][18] << 24)+ (Efe[j][19] << 16) +
443 (Efe[j][20] << 8 ) + Efe[j][21]);
444 type=Efe[j][1];
445 real_type=type;
446
447 // Check If type in unknown
448 if(type>39) {
449 type=39;
450 }
451
452 //if(1) {
453 if(type!=0) {
454
455 if(process_efe[j] == 1) {
456 switch(mode)
457 {
458 case GET:
459 printf("<-");
460 break;
461
462 case PUT:
463 case MKDIR:
464 printf("->");
465 break;
466
467 case ERASE:
468 printf("!!");
469 break;
470
471 default:
472 ;
473 }
474 } else {
475 printf(" ");
476 }
477
478 if((type==2) || (type==8)) {
479 printf(" %02d | %s | %-12s | | | |\n",j,EpsTypes[type],name);
480 } else {
481 if(type!=0)
482 printf(" %02d | %s | %-12s | %7d | %s | %12ld |\n",j,EpsTypes[type],name ,size,dosname, (unsigned long) (size+1)*512);
483 }
484
485
486 // This line is for debuggin. Uncomment it if needed
487 //printf(" %02d | %s(%d) | %-12s | %4d | start=%d(%x) , cont=%d(%x) |\n",j,EpsTypes[type],real_type,name ,size, start,start,cont,cont);
488
489 }
490 }
491
492 printf("------+---------+--------------+---------+---------------------------------+\n");
493 printf(" Used: %23d Blocks | Used: %16ld Bytes |\n", used_blks, (unsigned long) (used_blks)*512);
494 printf(" Free: %23d Blocks | Free: %16ld Bytes |\n", free_blks, (unsigned long) (free_blks)*512);
495 printf("---------------------------------------------------------------------------+\n\n");
496
497
498}
499
500/////////////////////////////////
501// Get FAT entry - use fat-table
502unsigned int GetFatEntry(char media_type, unsigned char *DiskFAT, FILE *file, unsigned int block)
503{
504 unsigned int fatsect, fatpos,tmp;
505 unsigned char FatEntry[3];
506
507 fatsect= (int) block / 170;
508 fatpos = block % 170;
509
510 if(media_type=='f') {
511 // FILE ACCESS
512 if(fseek(file,(FAT_START_BLOCK+fatsect)*BLOCK_SIZE+fatpos*3, SEEK_SET) == -1) {
513 printf("ERROR in seek\n");
514 }
515 if(fread(FatEntry,sizeof(unsigned char),3,file) == 0) {
516 printf("ERROR in read\n");
517 }
518 return((FatEntry[0] << 16) + (FatEntry[1] << 8) + FatEntry[2]);
519
520 } else {
521 // DISK ACCESS - uses FAT-table
522 tmp = (fatsect*BLOCK_SIZE) + fatpos*3;
523 return((DiskFAT[tmp] << 16) + (DiskFAT[tmp+1] << 8) + DiskFAT[tmp+2]);
524 }
525}
526
527/////////////////////
528// PutFatEntry
529int PutFatEntry(char media_type, unsigned char *DiskFAT, FILE *file,
530 unsigned int block, unsigned int fatval)
531{
532 unsigned int fatsect, fatpos,tmp;
533 unsigned char FatEntry[3];
534
535 fatsect= (int) block / 170;
536 fatpos = block % 170;
537
538 FatEntry[2] = fatval & 0x000000FF;
539 FatEntry[1] = (fatval >> 8) & 0x000000FF;
540 FatEntry[0] = (fatval >> 16) & 0x000000FF;
541
542 if(media_type=='f') {
543 // file access
544 fseek(file,(FAT_START_BLOCK+fatsect)*BLOCK_SIZE+fatpos*3, SEEK_SET);
545 fwrite(FatEntry,sizeof(unsigned char),3,file);
546 return(OK);
547
548 } else {
549 // disk access - uses FAT-table
550 tmp = (fatsect*BLOCK_SIZE) + fatpos*3;
551 memcpy(DiskFAT+tmp, FatEntry,3);
552 return(OK);
553 }
554}
555
556//////////////////////
557// Convert MacFormat
558// ===================
559// - Convert really _stupid_ 'Mac'-format (ie. every '0x0a' is replaced by '0x0d0a')..
560// Why this even exists !?!?
561
562int ConvertMacFormat(FILE **in, char *in_file)
563{
564 FILE *out;
565 //int c;
566 unsigned int Hdr,i,prev;
567 char temp_file[FILENAME_MAX];
568 unsigned char *mem_pointer;
569 struct stat stat_buf;
570
571 fseek(*in,(long) 0,SEEK_SET);
572 fread(&Hdr,sizeof(unsigned int),1,*in);
573 fseek(*in,(long) 0,SEEK_SET);
574
575 Hdr = Hdr & 0x00FFFFFF;
576 if(Hdr == 0x0a0d0d) {
577
578 mkstemp(temp_file);
579 if((out =fopen(temp_file, "w+b"))== NULL) {
580 EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",temp_file));
581 }
582 unlink(temp_file);
583
584 if(stat(in_file,&stat_buf) != 0) {
585 EEXIT((stderr,"ERROR: Can't get the filesize!!\n"));
586 }
587
588 mem_pointer=malloc(stat_buf.st_size);
589 if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
590
591 fread(mem_pointer, sizeof(unsigned char), stat_buf.st_size,*in);
592
593 // Find '0x0a' and copy fragments to file without proceeding '0x0d'
594
595 prev = 0;
596 for(i=0; i<stat_buf.st_size; i++) {
597 if(mem_pointer[i] == 0x0a) {
598 fwrite(mem_pointer+prev,sizeof(unsigned char),i - prev -1,out);
599 prev = i;
600 }
601 }
602
603 // if '0x0a' is last byte it has to write out separately..
604 // Otherwise write whats left...
605 if((i-1) != prev) {
606 fwrite(mem_pointer+prev,sizeof(unsigned char),i - prev,out);
607 } else {
608 fwrite(mem_pointer+prev,sizeof(unsigned char),1,out);
609 }
610
611 free(mem_pointer);
612
613 // Close orginal and give pointer to converted file
614 fclose(*in);
615 *in=out;
616
617 return(OK);
618
619 } else {
620 return(ERR);
621 }
622}
623
624//////////////////////
625// ConvertToImageFile
626int ConvertToImage(char in_file[FILENAME_MAX], char out_file[FILENAME_MAX])
627{
628 FILE *in, *out;
629 struct stat stat_buf;
630
631 unsigned int i, j, skip_start, skip_size, num_of_tags, num_of_blks, img_length, img_offset;
632 unsigned char buffer[BLOCK_SIZE], Data[BLOCK_SIZE], *mem_pointer, *SkipTable;
633 char bits, *p;
634
635 mem_pointer=NULL;
636
637 if((in=fopen(in_file, "rb"))== NULL) {
638 EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",in_file));
639 }
640 if((out=fopen(out_file, "wb"))== NULL) {
641 EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",out_file));
642 }
643
644 if((p= (char *) rindex(in_file,'.')) != NULL) {
645 p++;
646 //printf("Extension: %s\n",p);
647
648 if(strcasecmp(p,"gkh") == 0) {
649 //printf("GKH-file found\n");
650
651 //// GKH ////
652 if(stat(in_file,&stat_buf) != 0) {
653 EEXIT((stderr,"ERROR: Can't get the filesize!!\n"));
654 }
655
656 fseek(in,(long) 0, SEEK_SET);
657 fread(Data,sizeof(unsigned char),8,in);
658
659 if(Data[4] != 'I') {
660 EEXIT((stderr,"ERROR: GKH file in Motorola format is not supported!!\n"));
661 }
662
663 //num_of_tags = (Data[6] & 0x000000ff) + (Data[7] & 0x000000ff);
664 num_of_tags = (unsigned int) (*((unsigned int *) (Data+6)) & 0x0000ffff);
665
666 //printf("num_of_tags= %d\n",num_of_tags);
667
668 for(i=0; i<num_of_tags; i++) {
669 fread(Data,sizeof(unsigned char),10,in);
670
671 // DISKINFO-tag
672 if(*Data == 0x0a) {
673 num_of_blks = (unsigned int) ((*((unsigned int *) (Data+2)) & 0x0000ffff) *
674 (*((unsigned int *) (Data+4)) & 0x0000ffff) *
675 (*((unsigned int *) (Data+6)) & 0x0000ffff));
676 //printf("num_of_blks = %d\n", num_of_blks);
677 }
678
679 // DISKINFO-tag
680 if(*Data == 0x0b) {
681 img_length = (unsigned int) *((unsigned int *)(Data+2));
682 img_offset = (unsigned int) *((unsigned int *)(Data+6));
683 //printf("img_length = %d\n", img_length);
684 //printf("img_offset = %d\n", img_offset);
685 }
686
687 }
688
689 // Skip the 58-byte header
690 fseek(in,(long) img_offset, SEEK_SET);
691
692 // Do copy...
693 for(i=0; i<num_of_blks;i++) {
694 fread(Data,sizeof(unsigned char),BLOCK_SIZE,in);
695 fwrite(Data,sizeof(unsigned char),BLOCK_SIZE,out);
696 }
697
698 // Get INFO after image
699 // -- uncomment if INFO needed
700 /*
701 if(!feof(in)) {
702 printf("\nInfo included in GKH file: \n");
703 bits=fgetc(in);
704 while (feof(in) == 0) {
705 printf("%c",bits);
706 bits=fgetc(in);
707 }
708 printf("\n");
709 }
710 */
711
712 } else if ((strcasecmp(p,"ede") == 0) || (strcasecmp(p,"eda") == 0)) {
713
714 //// EDE / EDA /////
715
716 if (strcasecmp(p,"ede") == 0) {
717 skip_start= EDE_SKIP_START;
718 skip_size = EDE_SKIP_SIZE;
719 } else {
720 skip_start= EDA_SKIP_START;
721 skip_size = EDA_SKIP_SIZE;
722 }
723
724 // Write 'empty'-buffer
725 for(i=0; i<BLOCK_SIZE;i=i+2) {
726 buffer[i ]=0x6D;
727 buffer[i+1]=0xB6;
728 }
729
730 // Check and convert if 'Mac'-format :-P is found
731 if(ConvertMacFormat(&in, in_file) == OK) {
732 printf("Warning: Macintosh generated EDx file found!\n");
733 }
734
735 mem_pointer=malloc(BLOCK_SIZE);
736 if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
737 SkipTable = mem_pointer + skip_start;
738
739 // Read Ede/Eda skip Table
740 fseek(in, (long) 0, SEEK_SET);
741 fread(mem_pointer,sizeof(unsigned char),BLOCK_SIZE,in);
742
743 fseek(in, BLOCK_SIZE, SEEK_SET);
744
745 for(i=0; i<skip_size;i++) {
746 bits= SkipTable[i];
747
748 for(j=0;j<8;j++) {
749 if(bits < 0) {
750 fwrite(buffer,sizeof(unsigned char),BLOCK_SIZE,out);
751 } else {
752 fread(Data,sizeof(unsigned char),BLOCK_SIZE,in);
753 fwrite(Data,sizeof(unsigned char),BLOCK_SIZE,out);
754 }
755 bits=bits << 1;
756 } // for j
757
758 } // for i
759
760
761 } else {
762 // other extension - lets guess its raw-image
763 //printf("No conversion!\n");
764 free(mem_pointer);
765 fclose(in); fclose(out);
766 return(ERR);
767 }
768 } else {
769 // Can't get file type
770 //printf("No conversion!\n");
771 free(mem_pointer);
772 fclose(in); fclose(out);
773 return(ERR);
774 }
775
776 //printf("conversion done!\n");
777 free(mem_pointer);
778 fclose(in); fclose(out);
779 return(OK);
780}
781
782//////////////////////
783// ConvertFromImage
784int ConvertFromImage (char in_file[FILENAME_MAX], char out_file[FILENAME_MAX], char type)
785{
786 FILE *in,*out;
787 unsigned char bits, *SkipTable, *mem_pointer, edx_id;
788 char edx_label[12];
789 unsigned int skip_size, skip_start,block, i,j;
790 unsigned char Data[BLOCK_SIZE];
791
792 edx_id = 0; skip_start = 0; skip_size = 0;
793
794 switch (type)
795 {
796 case EDE_TYPE:
797 skip_start= EDE_SKIP_START;
798 skip_size = EDE_SKIP_SIZE;
799 edx_id = EDE_ID;
800 strcpy(edx_label, EDE_LABEL);
801 break;
802
803 case EDA_TYPE:
804
805 skip_start= EDA_SKIP_START;
806 skip_size = EDA_SKIP_SIZE;
807 edx_id = EDA_ID;
808 strcpy(edx_label, EDA_LABEL);
809 break;
810
811 case GKH_TYPE:
812 EEXIT((stderr,"ERROR: GKH-output not supported yet!\n"));
813
814 default:
815 EEXIT((stderr,"ERROR: Unsupported conversion!\n"));
816
817 }
818
819 //printf("RAW -> EDx conversion!!\n");
820
821 if((in=fopen(in_file, "rb"))== NULL) {
822 EEXIT((stderr,"ERROR: Couldn't open file '%s'.",in_file));
823
824 }
825 if((out=fopen(out_file, "wb"))== NULL) {
826 EEXIT((stderr,"ERROR: Couldn't open file '%s'.",out_file));
827
828 }
829
830 mem_pointer = malloc(BLOCK_SIZE);
831 if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
832
833 SkipTable=mem_pointer+skip_start;
834
835 // Construct EDx header
836
837 // CR & LF
838 mem_pointer[0]=0x0D;
839 mem_pointer[1]=0x0A;
840
841 // Spaces trough 0x02 - 0x4D
842 for(i=0x02; i<0x4E;i++) {
843 mem_pointer[i] = 0x20;
844 }
845
846 // Write EDE label
847 strncpy((char *) (mem_pointer+2), edx_label, 11);
848
849 // CR & LF
850 mem_pointer[0x4E]=0x0D;
851 mem_pointer[0x4F]=0x0A;
852
853 // Spaces trough 0x50 - skip_start
854 for(i=0x50; i<skip_start;i++) {
855 mem_pointer[i] = 0x20;
856 }
857
858 // CR & LF
859 mem_pointer[skip_start-3]=0x0D;
860 mem_pointer[skip_start-2]=0x0A;
861 mem_pointer[skip_start-1]=0x1A;
862
863 // Disktype ID
864 mem_pointer[BLOCK_SIZE-1] = edx_id;
865 // Write Header
866 fwrite(mem_pointer,sizeof(unsigned char),BLOCK_SIZE,out);
867
868 // Generate SkipTable
869 block=0;
870 for(i=0; i<skip_size ; i++) {
871 bits=0;
872 for(j=0; j<8 ; j++) {
873 bits=bits << 1;
874 if(GetFatEntry('f',NULL,in,block) == 0) {
875 bits=bits | 0x01;
876 } else {
877 fseek(in, block * BLOCK_SIZE, SEEK_SET);
878 fread(Data,sizeof(unsigned char), BLOCK_SIZE,in);
879 fwrite(Data,sizeof(unsigned char),BLOCK_SIZE,out);
880 }
881 block++;
882 }
883 SkipTable[i]=bits;
884 }
885 // Write last EOF-marker
886 fputc(0x1A,out);
887
888 fseek(out, skip_start, SEEK_SET);
889 fwrite(SkipTable,sizeof(unsigned char),skip_size,out);
890 return(OK);
891}
892
893
894///////////////
895// IsEFE
896int IsEFE(char in_file[FILENAME_MAX])
897{
898 char *p;
899
900 if((p=rindex(in_file,'.')) != NULL) {
901
902 // Extension found!
903 p++;
904 //printf("Extension: %s\n",p);
905
906 if((strcasecmp(p,"efe") == 0) || (strcasecmp(p,"efa") == 0) ) {
907 //printf("EFE-file found\n");
908 return(OK);
909 }
910 }
911 return(ERR);
912}
913
914
915///////////////////
916// GetImageType
917int GetImageType(char in_file[FILENAME_MAX], char *image_type)
918{
919 char *p;
920 struct stat stat_buf;
921
922 if((p=rindex(in_file,'.')) != NULL) {
923
924 // Extension found!
925 p++;
926 //printf("Extension: %s\n",p);
927
928 if(strcasecmp(p,"gkh") == 0) {
929 //printf("GKH-file found\n");
930 *image_type=GKH_TYPE;
931 return(OK);
932 } else if(strcasecmp(p,"ede") == 0) {
933 //printf("EDE-file found\n");
934 *image_type=EDE_TYPE;
935 return(OK);
936 } else if(strcasecmp(p,"eda") == 0) {
937 //printf("EDA-file found\n");
938 *image_type=EDA_TYPE;
939 return(OK);
940 }
941 }
942
943 // No or unknown extension - check if known raw-image
944
945
946 // Uncomment for header-check when raw-image expected
947 /*
948 if((in=fopen(in_file, "rb"))== NULL) {
949 EEXIT((stderr, "ERROR: Couldn't open file '%s'.", in_file));
950
951 }
952
953 fseek(in, 512,0);
954 fread(&Hdr,sizeof(unsigned long), 1,in);
955
956 printf("hdr: %lx \n", Hdr);
957 */
958
959 if(stat(in_file,&stat_buf) != 0) {
960 //fprintf(stderr,"\n(line: %d) ERROR: Can't get the filesize!!\n", __LINE__);
961 return(ERR);
962 }
963
964 //printf("filesize: %ld\n",stat_buf.st_size);
965
966 if(stat_buf.st_size == EPS_IMAGE_SIZE) {
967 //printf("EPS-file found\n");
968 *image_type = EPS_TYPE;
969 return(OK);
970 } else if(stat_buf.st_size == ASR_IMAGE_SIZE) {
971 //printf("ASR-file found\n");
972 *image_type = ASR_TYPE;
973 return(OK);
974 } else {
975 //fprintf(stderr,"\nWarning! Not a known file format. Might be an HD-image or SCSI-device! \n\n");
976 *image_type = OTHER_TYPE;
977 return(OK);
978 }
979
980}
981
982////////////////////
983// GetTHS
984void GetTHS(unsigned int block, unsigned int num_of_sect,
985 unsigned int *track, unsigned int *head, unsigned int *sector)
986{
987 *track = block / (2 * num_of_sect);
988 *head = (block - (*track * 2 * num_of_sect)) / num_of_sect;
989 *sector = block - (*track * 2 * num_of_sect) - (*head * num_of_sect);
990}
991
992
993//////////////////////////////////////
994// Set FD geometry. 'a'=ASR, 'e'=EPS
995void FD_SetGeometry(int fd, char disk_type)
996{
997 struct floppy_struct g;
998
999 if(disk_type == 'a') {
1000 // Geometry of ASR-Disk
1001 g.size = 3200;
1002 g.sect = 20;
1003
1004 } else {
1005 // Geometry of EPS-Disk
1006 g.size = 1600;
1007 g.sect = 10;
1008 }
1009
1010 // Common parameters
1011 g.head = 2;
1012 g.track = 80;
1013 g.stretch = 0;
1014
1015 // Set Disk geometry
1016 if(ioctl(fd, FDSETPRM , &g) < 0) {
1017 perror("geometry ioctl");
1018 exit(ERR);
1019 }
1020}
1021
1022// Calibrate FD
1023void FD_Calibrate(int fd)
1024{
1025 struct floppy_raw_cmd raw_cmd;
1026
1027 // Calibrate
1028 raw_cmd.flags = 8;
1029 raw_cmd.cmd_count = 2;
1030 raw_cmd.cmd[0] = 7;
1031 raw_cmd.cmd[1] = 0;
1032
1033 if (ioctl( fd, FDRAWCMD, & raw_cmd) < 0 ){
1034 perror("raw cmd");
1035 exit(ERR);
1036 }
1037}
1038
1039///////////////////////
1040// Seek the FD track
1041void FD_Seek(int fd, int track)
1042{
1043 struct floppy_raw_cmd raw_cmd;
1044
1045 // SEEK
1046 raw_cmd.flags = 8;
1047 raw_cmd.cmd_count = 3;
1048 raw_cmd.cmd[0] = 15;
1049 raw_cmd.cmd[1] = 0;
1050 raw_cmd.cmd[2] = track;
1051
1052 if (ioctl( fd, FDRAWCMD, & raw_cmd ) < 0 ){
1053 perror("raw cmd");
1054 exit(ERR);
1055 }
1056}
1057
1058////////////////////////////
1059// FD_Raw Read/Write Track
1060// (read: rw=1, write: rw=2)
1061int FD_RawRW_DiskTrack(int fd, char disk_type, int track, int head, char *buffer, int rw)
1062{
1063 struct floppy_raw_cmd raw_cmd;
1064
1065 // RAW-COMMADS
1066
1067 if(disk_type == 'a') {
1068 //ASR
1069 raw_cmd.length = 512*20;
1070 raw_cmd.rate = 0;
1071 raw_cmd.flags = 136+rw; // read=137, write=138
1072 raw_cmd.cmd[6] = 20; // Sectors (20)
1073 } else {
1074 //EPS
1075 raw_cmd.length = 512*10;
1076 raw_cmd.rate = 2;
1077 raw_cmd.flags = 136+rw; // read=137, write=138
1078 raw_cmd.cmd[6] = 10; // Sectors (10)
1079 }
1080
1081 // Common parameters
1082 raw_cmd.data = buffer;
1083 raw_cmd.track = track;
1084 raw_cmd.cmd_count = 9;
1085
1086 raw_cmd.cmd[0] = 230-33*(rw-1); // read=230, write=197
1087 raw_cmd.cmd[1] = head*4;
1088 raw_cmd.cmd[2] = track;
1089 raw_cmd.cmd[3] = head;
1090 raw_cmd.cmd[4] = 0;
1091 raw_cmd.cmd[5] = 2;
1092 raw_cmd.cmd[7] = 27;
1093 raw_cmd.cmd[8] = 255;
1094
1095 if (ioctl( fd, FDRAWCMD, & raw_cmd) < 0 ){
1096 //perror("Disk access");
1097 EEXIT((stderr,"\nPlease insert Ensoniq disk in disk drive or define an image file!\n\n"));
1098
1099 }
1100 if (raw_cmd.reply[0]>= 40) {
1101 return(ERR);
1102 }
1103 return(OK);
1104}
1105
1106////////////////////////////
1107// FD_Raw Read/Write Blocks
1108// (read: rw=0, write: rw=1)
1109int FD_RawRW_DiskSectors(int fd, char disk_type, int track, int head,
1110 int sector, int num_of_sectors, char *buffer, int rw)
1111{
1112 struct floppy_raw_cmd raw_cmd;
1113
1114 // RAW-COMMADS
1115
1116 if(disk_type == 'a') {
1117 //ASR
1118 raw_cmd.length = 512*num_of_sectors;
1119 raw_cmd.rate = 0;
1120 raw_cmd.flags = 136+rw;
1121 raw_cmd.cmd[6] = 20; // Sectors (20)
1122 } else {
1123 //EPS
1124 raw_cmd.length = 512*num_of_sectors;
1125 raw_cmd.rate = 2;
1126 raw_cmd.flags = 136+rw;
1127 raw_cmd.cmd[6] = 10; // Sectors (10)
1128 }
1129
1130 // Common parameters
1131 raw_cmd.data = buffer;
1132 raw_cmd.track = track;
1133 raw_cmd.cmd_count = 9;
1134
1135 raw_cmd.cmd[0] = 230-33*(rw-1); // read=230, write=197
1136 raw_cmd.cmd[1] = head*4;
1137 raw_cmd.cmd[2] = track;
1138 raw_cmd.cmd[3] = head;
1139 raw_cmd.cmd[4] = sector;
1140 raw_cmd.cmd[5] = 2;
1141 raw_cmd.cmd[7] = 27;
1142 raw_cmd.cmd[8] = 255;
1143
1144 if (ioctl( fd, FDRAWCMD, & raw_cmd) < 0 ){
1145 //perror("Disk access");
1146 EEXIT((stderr,"\nPlease insert Ensoniq disk in disk drive or define image file!\n\n"));
1147
1148 }
1149 if (raw_cmd.reply[0]>= 40) {
1150 return(ERR);
1151 }
1152 return(OK);
1153}
1154
1155////////////////////////
1156// Datatypes for Format
1157typedef struct {
1158 char track;
1159 char head;
1160 char sector;
1161 char szcode;
1162} FormatHeader;
1163
1164typedef FormatHeader FormatHeaders[MAX_DISK_SECT];
1165
1166////////////////////
1167// Format DiskTrack
1168int FD_Format_DiskTrack(int fd, int track, int head, int nsect, int rate, int skew)
1169{
1170
1171 FormatHeaders headers;
1172 struct floppy_raw_cmd raw_cmd;
1173 int i,tmp;
1174
1175 for (i=0; i<nsect; i++)
1176 {
1177
1178 headers[i].track = track; // track
1179 headers[i].head = head; // head
1180 headers[i].sector = (i+skew) % nsect; // sector (with skew ie. sector shift)
1181 headers[i].szcode = 2; // sizecode
1182 }
1183
1184 raw_cmd.track = track;
1185 raw_cmd.data = headers;
1186 raw_cmd.length = 4*nsect;
1187 raw_cmd.rate = rate;
1188 raw_cmd.flags = 138;
1189 raw_cmd.cmd_count = 6;
1190 raw_cmd.cmd[0] = 77;
1191 raw_cmd.cmd[1] = head*4;
1192 raw_cmd.cmd[2] = 2;
1193 raw_cmd.cmd[3] = nsect;
1194 raw_cmd.cmd[4] = 40;
1195 raw_cmd.cmd[5] = 0;
1196
1197 tmp = ioctl( fd, FDRAWCMD, & raw_cmd );
1198 if ( tmp < 0 ){
1199 perror("raw cmd");
1200 exit(ERR);
1201 }
1202 if (raw_cmd.reply[0]>= 40) {
1203 printf("\nERROR at: head=%d, track=%d !!\n\n",head,track);
1204 return(ERR);
1205 }
1206 return(OK);
1207}
1208
1209////////////////
1210// MakeID_Block
1211void MakeID_Block(unsigned char *buffer, char *label, unsigned int tracks,
1212 unsigned int nsect, unsigned int total_blks)
1213{
1214 int i;
1215
1216 for(i=0; i<BLOCK_SIZE;i++) {
1217 buffer[i]=0;
1218 }
1219
1220 // Device type
1221 //buffer[0] = 0x00;
1222
1223 // Rem. Media device Type
1224 buffer[1] = 0x80;
1225
1226 // Std. vers. #
1227 buffer[2] = 0x01;
1228
1229 // SCSI
1230 //buffer[3] = 0x00;
1231
1232 // Nsect
1233 buffer[4] = 0x00; buffer[5] = (unsigned char) nsect;
1234
1235 // Heads
1236 buffer[6] = 0x00; buffer[7] = 0x02;
1237
1238 // Tracks
1239 buffer[8] = 0x00; buffer[9] = (unsigned char) tracks;
1240
1241 // Bytes per Block - 512
1242 buffer[10] = 0x00; buffer[11] = 0x00; buffer[12] = 0x02; buffer[13] = 0x00;
1243
1244 // Total Blocks
1245
1246 buffer[14] = (total_blks >> 24) & 0x000000ff; // MSB
1247 buffer[15] = (total_blks >> 16) & 0x000000ff;
1248 buffer[16] = (total_blks >> 8) & 0x000000ff;
1249 buffer[17] = total_blks & 0x000000ff; // LSB
1250
1251 // SCSI Medium Type
1252 buffer[18] = 0x1e;
1253
1254 // SCSI Density Code
1255 buffer[19] = 0x02;
1256
1257 // reserved (20-29)
1258
1259 // Disk Label
1260 if(label != NULL) {
1261
1262 for(i=0;i<7;i++) {
1263 buffer[31+i] = label[i];
1264 }
1265 buffer[30] = 0xff;
1266 }
1267
1268 // ID
1269 buffer[38] = 'I'; buffer[39] = 'D';
1270
1271}
1272
1273/////////////////
1274// MakeOS_Block
1275void MakeOS_Block(unsigned char *buffer, unsigned int free_blks)
1276{
1277 int i;
1278
1279 for(i=0; i<BLOCK_SIZE;i++) {
1280 buffer[i]=0;
1281 }
1282
1283 // Free Blocks
1284 buffer[0] = (free_blks >> 24) & 0x000000ff; // MSB
1285 buffer[1] = (free_blks >> 16) & 0x000000ff;
1286 buffer[2] = (free_blks >> 8) & 0x000000ff;
1287 buffer[3] = free_blks & 0x000000ff; // LSB
1288
1289
1290 // ID
1291 buffer[28] = 'O';
1292 buffer[29] = 'S';
1293}
1294
1295/////////////////
1296// MakeDR_Block
1297void MakeDR_Block(unsigned char *buffer, int write_id)
1298{
1299 int i;
1300
1301 for(i=0; i<BLOCK_SIZE;i++) {
1302 buffer[i]=0;
1303 }
1304
1305 if(write_id == 1) {
1306 buffer[510]='D';
1307 buffer[511]='R';
1308 }
1309
1310}
1311
1312
1313//////////////////////
1314// Format Disk
1315void FD_Format_Disk(char disk_type, int nsect, int rate, char* disk_label)
1316{
1317 int fd,track,head,free_blks,fat_blks,i,j,skew,head_skew,track_skew;
1318 unsigned char buffer[BLOCK_SIZE*40];
1319 char str[81],tmp;
1320
1321 // Init the skew factory for the disk
1322 if(disk_type=='e') {
1323
1324 track_skew = nsect-2;
1325 head_skew = nsect-1;
1326 skew = -track_skew;
1327
1328 } else {
1329
1330 track_skew = nsect-3;
1331 head_skew = nsect-2;
1332 skew = -track_skew;
1333
1334 }
1335
1336 // Calc disk parameters
1337 fat_blks = nsect*2*80 / 170 +1;
1338 free_blks = nsect*2*80 - (5 + fat_blks);
1339
1340 //Open FD
1341 fd = open( "/dev/fd0", O_ACCMODE | O_NDELAY);
1342 //fd = open( "/dev/fd0", O_ACCMODE | O_SYNC);
1343 if ( fd < 0 ){
1344 perror("open floppy");
1345 exit(ERR);
1346 }
1347 FD_SetGeometry(fd,disk_type);
1348
1349 printf("1 10 20 30 40 50 60 70 80\n");
1350 sprintf(str,"|---+----|----+----|----+----|----+----|----+----|----+----|----+----|----+----|");
1351
1352 for(track=0; track<80; track++) {
1353
1354 //Shift sectors (track skew)
1355 skew=skew+track_skew;
1356
1357 for(head=0; head<2; head++) {
1358
1359 if(head==0) {
1360 tmp = str[track];
1361
1362 str[track]='\\';
1363
1364 } else {
1365 // Shift sectors (head skew)
1366 skew=skew+head_skew;
1367
1368 str[track]='/';
1369
1370 }
1371 printf("\r%s",str);
1372 fflush(stdout);
1373
1374 if((FD_Format_DiskTrack(fd,track,head,nsect,rate,skew)) == ERR) {
1375 exit(ERR);
1376 }
1377 } //for head
1378 if(tmp == '|') str[track]=tmp; else str[track]='#';
1379 }// for track
1380
1381 printf("\r%s",str);
1382 fflush(stdout);
1383 printf("\n\nWriting System Block..\n");
1384
1385 // TODO: Get the FD status so we don't have to wait
1386
1387 sleep(1);
1388
1389 // Write System-Blocks
1390
1391 for(i=0; i<BLOCK_SIZE*40;i++) {
1392 buffer[i]=0;
1393 }
1394
1395 // ID-Block
1396 MakeID_Block(buffer+BLOCK_SIZE,disk_label,80,nsect,2*80*nsect);
1397
1398 // OS-Block
1399 MakeOS_Block(buffer+BLOCK_SIZE*2, free_blks);
1400
1401 // Write Dir-ID (to second Dir-Block)
1402 buffer[BLOCK_SIZE*4 + 510] = 'D';
1403 buffer[BLOCK_SIZE*4 + 511] = 'R';
1404
1405 // FAT-Blocks
1406 for(i=0; i<fat_blks; i++) {
1407 if(i==0) {
1408 for(j=0; j<(fat_blks+5); j++) {
1409 buffer[BLOCK_SIZE * 5 + 3*j + 2] = 1;
1410 }
1411 }
1412 buffer[BLOCK_SIZE * (5+i) + 510] = 'F';
1413 buffer[BLOCK_SIZE * (5+i) + 511] = 'B';
1414 }
1415
1416 if(FD_RawRW_DiskTrack(fd,disk_type,0,0,buffer,WRITE) == ERR) {
1417 EEXIT((stderr,"ERROR: Couldn't write SystemData to disk!!\n\n"));
1418 }
1419
1420 if(FD_RawRW_DiskTrack(fd,disk_type,0,1,buffer+(nsect*BLOCK_SIZE),WRITE) == ERR) {
1421 EEXIT((stderr,"ERROR: Couldn't write SystemData to disk!!\n\n"));
1422 }
1423
1424 printf("Operation completed succesfully!\n\n");
1425 close(fd);
1426}
1427
1428///////////////////////////////////////////////////////////
1429// Check which type of disk is inserted (EPS=DD or ASR=HD)
1430int FD_GetDiskType(char *disk_type, int *nsect, int *trk_size)
1431{
1432
1433 int fd;
1434 char buffer[20*512];
1435
1436 *disk_type='n';
1437
1438 //Open FD
1439 fd = open( "/dev/fd0", O_ACCMODE | O_NDELAY);
1440 if ( fd < 0 ){
1441 perror("open floppy");
1442 exit(ERR);
1443 }
1444
1445 // EPS-Disk !? (DD)
1446
1447 FD_SetGeometry(fd,'e');
1448 if((FD_RawRW_DiskTrack(fd,'e',0,0,buffer,READ) )== ERR) {
1449
1450 //.. OR ASR-Disk !? (HD)
1451 FD_SetGeometry(fd,'a');
1452 if((FD_RawRW_DiskTrack(fd,'a',0,0,buffer,READ) )== ERR) {
1453
1454 // NEITHER :(
1455 return(ERR);
1456
1457 } else { // ASR
1458 //printf("\nASR-Disk detected..\n");
1459 *disk_type = 'a';
1460 *nsect=20;
1461 *trk_size = 20* 512;
1462 }
1463 } else { // EPS
1464 //printf("\nEPS-Disk detected..\n");
1465 *disk_type = 'e';
1466 *nsect=10;
1467 *trk_size = 10* 512;
1468 }
1469
1470 close(fd);
1471 return(OK);
1472}
1473
1474//////////////////////////
1475// Read/Write the Disk
1476void FD_RW_Disk(char in_file[FILENAME_MAX], int rw_disk)
1477{
1478 FILE *file;
1479
1480 int fd,track,head,nsect,trk_size,convert,idx, errors;
1481 char disk_type, image_type;
1482 char buffer[512 * 20],str[81],tmp, filename[FILENAME_MAX];
1483 char mark[5] = {'\\','/','#','E','E'};
1484 char errors_text[20000];
1485
1486 errors=0; idx=0; errors_text[0]='\0';
1487
1488 //Open FD
1489 fd = open( "/dev/fd0", O_ACCMODE | O_NDELAY);
1490 //fd = open( "/dev/fd0", O_ACCMODE | O_SYNC);
1491 if ( fd < 0 ){
1492 perror("open floppy");
1493 exit(ERR);
1494 }
1495
1496 // Check image file
1497 if((GetImageType(in_file, &image_type) == ERR) && (rw_disk == WRITE)) {
1498 EEXIT((stderr,"ERROR: NOT a valid image!!\n\n"));
1499 }
1500
1501 // Check disk
1502 if(FD_GetDiskType(&disk_type, &nsect, &trk_size) == ERR) {
1503 EEXIT((stderr,"ERROR: NOT an Ensoniq Disk.\n\n"));
1504 }
1505
1506 // Check if disk and file types match
1507 if(disk_type == EPS_TYPE) {
1508 strcpy(str,"EPS-DISK");
1509 if(image_type == EDA_TYPE) {
1510 EEXIT((stderr,"ERROR: Don't use EPS disks with EDA files! Replace extension 'eda' to 'ede'.\n"));
1511 }
1512
1513 } else {
1514 strcpy(str,"ASR-DISK");
1515
1516 if(image_type == EDE_TYPE) {
1517 EEXIT((stderr,"ERROR: Don't use ASR disks with EDE files! Replace extension 'ede' to 'eda'.\n"));
1518 }
1519 }
1520
1521 FD_SetGeometry(fd,disk_type);
1522
1523 // If file type is other than image, conversion is needed
1524
1525 if((image_type == GKH_TYPE) && (rw_disk == READ)) {
1526 EEXIT((stderr,"Sorry! Reading disk to GKH file is not yet supported!.\n"));
1527 }
1528
1529 if((image_type == EDE_TYPE) || (image_type == EDA_TYPE) || (image_type == GKH_TYPE)) {
1530 // Generate tmp-file and bind the clean-up for it
1531 //tmpnam(tmp_file);
1532 if(mkstemp(tmp_file) == -1) {
1533 perror("mkstemp");
1534 exit(ERR);
1535 }
1536
1537 atexit(CleanTmpFile);
1538 convert = 1;
1539 } else {
1540 convert = 0;
1541 strcpy(filename,in_file);
1542 }
1543
1544 // Open image-file
1545 if(rw_disk == READ) {
1546 if(convert) strcpy(filename,tmp_file);
1547 if((file = fopen(filename,"wb")) == NULL) {
1548 EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",filename));
1549 }
1550 printf("Reading %s to file '%s'..\n\n",str,in_file);
1551 } else {
1552
1553 // Check if conversion is needed
1554 if(convert) {
1555
1556 if(ConvertToImage(in_file,tmp_file) == OK) {
1557 //printf("CONVERSION DONE!!!\n");
1558 //repalace in_file to converted image
1559 strcpy(filename,tmp_file);
1560 } else {
1561 EEXIT((stderr,"ERROR: Something wrong with the image file!!\n"));
1562
1563 }
1564 }
1565
1566 file = fopen(filename,"rb");
1567 printf("Writing %s from file '%s'..\n\n",str,in_file);
1568 }
1569
1570 printf("1 10 20 30 40 50 60 70 80\n");
1571 sprintf(str,"|---+----|----+----|----+----|----+----|----+----|----+----|----+----|----+----|");
1572
1573 for(track=0; track<80; track++) {
1574 //FD_Seek(fd,track);
1575 for(head=0; head<2; head++) {
1576
1577 tmp = str[track];
1578 str[track]=mark[idx];
1579
1580 printf("\r%s",str);
1581 fflush(stdout);
1582
1583 if(rw_disk == WRITE) {
1584 fread(buffer,sizeof(unsigned char),trk_size,file);
1585 }
1586
1587 {
1588 int retry_cnt=0;
1589
1590 retry:
1591
1592 if(FD_RawRW_DiskTrack(fd,disk_type,track,head,buffer,rw_disk) == ERR) {
1593 // Error: 'E'
1594 idx=2;
1595 //Show retry count
1596 str[track]='0'+retry_cnt;
1597 printf("\r%s",str);
1598 fflush(stdout);
1599 retry_cnt++;
1600 if (retry_cnt <= 9 ) goto retry; // Yes, I know.. The Goto is a "bad programming"
1601
1602 //Error text & count
1603 sprintf(errors_text+strlen(errors_text)," ERROR: track=%d, head=%d\n",track,head);
1604 errors++;
1605 }
1606
1607 }
1608
1609 if(rw_disk == READ) {
1610 fwrite(buffer,sizeof(unsigned char),trk_size,file);
1611 }
1612 idx++;
1613 } //for head
1614
1615 if((mark[idx] != 'E') && ((((track+1) % 10) == 0) || (track == 0))) str[track]='|';
1616 else str[track]=mark[idx];
1617 idx=0;
1618 }// for track
1619
1620 printf("\r%s",str);
1621 fflush(stdout);
1622
1623 if(convert && rw_disk==READ) {
1624 ConvertFromImage(filename,in_file,image_type);
1625 }
1626
1627 if(errors > 0) {
1628 printf("\n\nWarning: %d error(s) found!\n",errors);
1629 printf("\n%s\n",errors_text);
1630 } else {
1631 printf("\n\nOperation completed succesfully!\n\n");
1632 }
1633 close(fd);
1634}
1635
1636/////////////////////////////////////////////////////////////////
1637// ReadBlocks
1638// ----------
1639// media_type : 'file'-access('f') or disk-access('e','a')
1640// fd : device (dev/fd0) file descriptor (depends on media_type if needed!)
1641// file : file descriptor (depends on media_type if needed!)
1642// start_block : First block to read
1643// length : How many blocks to read
1644// buffer : Where to put the data
1645
1646int ReadBlocks(char media_type, int fd, FILE *file, unsigned int start_block,
1647 unsigned int length, unsigned char *buffer)
1648{
1649 unsigned int sector,head,track;
1650 unsigned int end_sector, end_head, end_track;
1651 unsigned int end_block, cur_block,nsect = 0;
1652 unsigned char tmp_buffer[BLOCK_SIZE*20];
1653
1654 switch (media_type)
1655 {
1656 case 'f':
1657 if(fseek(file, start_block * BLOCK_SIZE, SEEK_SET) == -1) {
1658 printf("ERROR in seek\n");
1659 exit(ERR);
1660 }
1661 if(fread(buffer,sizeof(unsigned char), BLOCK_SIZE*length,file) == 0) {
1662 printf("ERROR in fread\n");
1663 exit(ERR);
1664 }
1665 return(OK);
1666
1667 case 'e':
1668
1669 nsect=10;
1670 break;
1671
1672 case 'a':
1673
1674 nsect=20;
1675 break;
1676 }
1677 GetTHS(start_block,nsect,&track,&head,§or);
1678
1679 end_block = start_block + length -1;
1680
1681 GetTHS(end_block,nsect,&end_track,&end_head,&end_sector);
1682
1683 FD_RawRW_DiskTrack(fd,media_type,track,head,tmp_buffer,READ);
1684
1685 cur_block = start_block;
1686
1687 while(cur_block <= end_block) {
1688 memcpy(buffer,tmp_buffer+(sector*BLOCK_SIZE), BLOCK_SIZE);
1689
1690 buffer=buffer+BLOCK_SIZE;
1691 cur_block++;
1692 sector++;
1693 //printf("\r Reading from disk: %-4d of %-4d (blocks) .. ", cur_block-start_block, end_block-start_block+1);
1694 //fflush(stdout);
1695 if(sector>(nsect-1) && cur_block <= end_block ) {
1696 //Load next track
1697 GetTHS(cur_block,nsect,&track,&head,§or);
1698 FD_RawRW_DiskTrack(fd,media_type,track,head,tmp_buffer,READ);
1699 sector=0;
1700 }
1701 }
1702 //printf("\r ");
1703 //fflush(stdout);
1704 return(OK);
1705
1706}
1707
1708/////////////////////////////////////////////////////////////////
1709// WriteBlocks
1710// ----------
1711// media_type : 'file'-access('f') or disk-access('e','a')
1712// fd : device (dev/fd0) file descriptor (depends on media_type if needed!)
1713// file : file descriptor (depends on media_type if needed!)
1714// start_block : First block to write
1715// length : How many blocks to write
1716// buffer : Where to get the data
1717
1718int WriteBlocks(char media_type, int fd, FILE *file, unsigned int start_block,
1719 unsigned int length, unsigned char *buffer)
1720{
1721 int sector,head,track;
1722 int end_sector, end_head, end_track;
1723 unsigned int end_block, cur_block,nsect = 0, num_of_sectors, start_sector, tmp;
1724 unsigned char tmp_buffer[BLOCK_SIZE*20];
1725
1726 switch (media_type)
1727 {
1728 case 'f':
1729 fseek(file, start_block * BLOCK_SIZE, SEEK_SET);
1730 fwrite(buffer,sizeof(unsigned char), BLOCK_SIZE*length,file);
1731 return(OK);
1732
1733 case 'e':
1734 nsect=10;
1735 break;
1736
1737 case 'a':
1738 nsect=20;
1739 break;
1740 }
1741
1742 GetTHS(start_block,nsect,&track,&head,§or);
1743 end_block = start_block + length -1;
1744 GetTHS(end_block,nsect,&end_track,&end_head,&end_sector);
1745
1746 cur_block = start_block;
1747 start_sector = sector;
1748
1749 do {
1750 memcpy(tmp_buffer+(sector*BLOCK_SIZE),buffer, BLOCK_SIZE);
1751 buffer=buffer+BLOCK_SIZE;
1752
1753 if(sector >= (nsect-1) || cur_block >= end_block ) {
1754 //Write blocks to disk
1755
1756 num_of_sectors = sector - start_sector+1;
1757 GetTHS(cur_block,nsect,&track,&head,&tmp);
1758
1759 FD_RawRW_DiskSectors(fd,media_type,track,head,start_sector, num_of_sectors, \
1760 tmp_buffer+(start_sector*BLOCK_SIZE),WRITE);
1761
1762 sector=0;
1763 start_sector=0;
1764
1765 } else {
1766 sector++;
1767 }
1768 cur_block++;
1769 printf("\r Writing to disk: %-4d of %-4d (blocks) .. ", cur_block-start_block, end_block-start_block+1);
1770 fflush(stdout);
1771 } while(cur_block <= end_block);
1772 printf("\r ");
1773 fflush(stdout);
1774 return(OK);
1775
1776}
1777
1778
1779//////////////////////////////////////////////
1780// Load Dir entry to Efe-array - use FAT-table
1781void LoadDirBlocks(char media_type, int fd, unsigned char *DiskFAT, FILE *file,
1782 unsigned long start_blk, int cont, unsigned char Efe[][EFE_SIZE])
1783{
1784
1785 unsigned char Dir[DIR_BLOCKS*BLOCK_SIZE];
1786 int i,j;
1787
1788 // Get DirBlocks
1789
1790 // First dir-block - Guess the block are contiguous, so read 2 blocks
1791 ReadBlocks(media_type,fd,file,start_blk,2,Dir);
1792
1793 //.. and second, if needed (ie. not contiguous..)
1794 if(cont != 2) {
1795 ReadBlocks(media_type,fd,file,GetFatEntry(media_type,DiskFAT,file,start_blk),1,Dir+BLOCK_SIZE);
1796 }
1797
1798 // Scan Directory
1799 for(i=0;i<MAX_NUM_OF_DIR_ENTRIES;i++) {
1800 for(j=0; j < EFE_SIZE ; j++) {
1801 Efe[i][j]=Dir[i * EFE_SIZE+j];
1802 }
1803 }
1804}
1805
1806////////////////////////////////////////////////////
1807// FormatMedia
1808// -----------
1809// -Format (and create if needed) imagefile/device
1810//
1811int FormatMedia(char **argv, int argc, int optind, char format_arg, char *disk_label)
1812{
1813 int fd;
1814
1815 long long i,j,k,image_size, total_blks, free_blks, fat_blks,fat_count;
1816 long long partial_blks, rest_blks;
1817 unsigned char buffer[BLOCK_SIZE];
1818
1819 image_size=0;
1820
1821 switch(format_arg)
1822 {
1823
1824 case 'a':
1825 // ASR Disk
1826 printf("\nFormatting ASR-DISK.. \n\n");
1827 FD_Format_Disk('a',20,0,disk_label);
1828 return(OK);
1829
1830 // ASR Disk
1831 case 'e':
1832 printf("\nFormatting EPS-DISK.. \n\n");
1833 FD_Format_Disk('e',10,2,disk_label);
1834 return(OK);
1835
1836
1837 case 'i':
1838
1839
1840 // IMAGEFILE/DEVICE
1841
1842 // check if file argument exists
1843 if(argv[optind] == NULL) {
1844 ShowUsage();
1845 exit(ERR);
1846 }
1847
1848 if((fd=open(argv[optind],O_RDWR)) != -1) {
1849
1850 //File exists.. get size
1851
1852 if((image_size=lseek(fd,0,SEEK_END)) == -1) {
1853 perror("lseek");
1854 exit(ERR);
1855 }
1856 if((image_size % BLOCK_SIZE) != 0) {
1857 printf("Image size have to be multiple of %d!\n",BLOCK_SIZE);
1858 exit(ERR);
1859 }
1860
1861 total_blks=image_size/BLOCK_SIZE;
1862
1863
1864 } else {
1865
1866 // File DON'T exists..
1867
1868 if(argv[optind+1] != NULL) {
1869 image_size=atol(argv[optind+1]);
1870
1871
1872 if(image_size == 0) {
1873 printf("No valid filesize!\n\n");
1874 exit(ERR);
1875 }
1876
1877 // Check if 'M' or 'K' suffix used
1878 switch(argv[optind+1][strlen(argv[optind+1])-1])
1879 {
1880 case 'm':
1881 case 'M':
1882 image_size=image_size*1024;
1883 case 'k':
1884 case 'K':
1885 image_size=image_size*1024;
1886 }
1887
1888 } else {
1889 printf("No filesize defined!\n\n");
1890 exit(ERR);
1891 }
1892
1893 // Check the validity of the given filesize
1894
1895 if((image_size % BLOCK_SIZE) != 0) {
1896 printf("Image size have to be multiple of %d!\n",BLOCK_SIZE);
1897 exit(ERR);
1898 }
1899
1900 total_blks=image_size/BLOCK_SIZE;
1901
1902 // create file
1903 fd = open( argv[optind], O_RDWR | O_CREAT, 0600);
1904 // Make empty file
1905
1906 // 1st clear the buffer
1907 for(k=0; k<BLOCK_SIZE;k++) {
1908 buffer[k]=0;
1909 }
1910
1911 //..create
1912
1913 partial_blks = total_blks/100;
1914 rest_blks = total_blks % 100;
1915
1916 for(j=0;j<100;j++) {
1917 printf("\rCreating image file... %d%% completed", (int) j);
1918 fflush(stdout);
1919 for(i=0; i< partial_blks;i++) {
1920 write(fd,buffer,BLOCK_SIZE);
1921 }
1922 }
1923 for(i=0;i<rest_blks;i++) {
1924 write(fd,buffer,BLOCK_SIZE);
1925 }
1926 printf("\rCreating image file... OK! \n");
1927 fflush(stdout);
1928 }
1929
1930
1931 // Calc num of needed FAT-Blocks
1932 printf("\rWriting filesystem....");
1933 fflush(stdout);
1934
1935 fat_blks=total_blks / 170;
1936
1937 if((total_blks % 170) != 0)
1938 fat_blks++;
1939
1940 free_blks=total_blks - (fat_blks+5);
1941
1942 //Write "not used" (first) block with added info
1943 lseek(fd,0,SEEK_SET);
1944 strcpy(buffer,"mCreated with EpsImageCreator.");
1945 write(fd,buffer,BLOCK_SIZE);
1946
1947 //Write ID-Block
1948 lseek(fd,BLOCK_SIZE*ID_BLOCK,SEEK_SET);
1949 MakeID_Block(buffer,disk_label,0,0,total_blks);
1950 write(fd,buffer,BLOCK_SIZE);
1951
1952 //Write OS-Block
1953 lseek(fd,BLOCK_SIZE*OS_BLOCK,SEEK_SET);
1954 MakeOS_Block(buffer,free_blks);
1955 write(fd,buffer,BLOCK_SIZE);
1956
1957 //Write Dir-Blocks
1958 lseek(fd,BLOCK_SIZE*DIR_START_BLOCK,SEEK_SET);
1959 MakeDR_Block(buffer,0);
1960 write(fd,buffer,BLOCK_SIZE);
1961
1962 lseek(fd,BLOCK_SIZE*DIR_END_BLOCK,SEEK_SET);
1963 MakeDR_Block(buffer,1);
1964 write(fd,buffer,BLOCK_SIZE);
1965
1966 //Write FAT-Blocks
1967 fat_count=fat_blks+5;
1968
1969 //for(i=0; i<BLOCK_SIZE;i++) {
1970 // buffer[i]=0;
1971 //}
1972 buffer[510] = 'F';
1973 buffer[511] = 'B';
1974
1975 for(i=0; i<fat_blks; i++) {
1976
1977 // Clear buffer needed: once at start and once after all "used block" marked
1978 if(fat_count >= 0) {
1979 for(k=0; k<BLOCK_SIZE-2;k++) {
1980 buffer[k]=0;
1981 }
1982 if(fat_count==0)
1983 fat_count--;
1984 }
1985
1986 if(fat_count > 0) {
1987 for(j=0; j<510; j=j+3) {
1988 buffer[j] = 0;
1989 buffer[j+1] = 0;
1990 buffer[j+2] = 1;
1991 fat_count--;
1992 if(fat_count == 0) {
1993 break;
1994 }
1995 }
1996 }
1997
1998 lseek(fd,BLOCK_SIZE*(i+5),SEEK_SET);
1999 if( write(fd,buffer,BLOCK_SIZE) <= 0)
2000 perror("write:");
2001 }
2002 printf("\rWriting filesystem.... OK!\n\n");
2003 fflush(stdout);
2004 close(fd);
2005 } // case
2006 return(OK);
2007}
2008
2009////////////////////////////////////////////////
2010// Save Dir entry from Efe-array - use FAT-table
2011void SaveDirBlocks(char media_type, int fd, unsigned char *DiskFAT, FILE *file,
2012 unsigned long start_blk, int cont, unsigned char Efe[][EFE_SIZE])
2013{
2014
2015 unsigned char Dir[DIR_BLOCKS*BLOCK_SIZE];
2016 int i,j;
2017
2018 // Put Directory
2019 for(i=0;i<MAX_NUM_OF_DIR_ENTRIES;i++) {
2020 for(j=0; j < EFE_SIZE ; j++) {
2021 Dir[i * EFE_SIZE+j]=Efe[i][j];
2022 }
2023 }
2024 // .. and tail (ie. '00000000' and 'DR')
2025
2026 for(i=10; i<2; i--) {
2027 Dir[DIR_BLOCKS*BLOCK_SIZE - i] = 0;
2028 }
2029 Dir[DIR_BLOCKS*BLOCK_SIZE - 2] = 'D';
2030 Dir[DIR_BLOCKS*BLOCK_SIZE - 1] = 'R';
2031
2032
2033 // Put DirBlocks
2034
2035 if(cont == 2) {
2036 // If contiguous, write all in one
2037 WriteBlocks(media_type,fd,file,start_blk,2,Dir);
2038 } else {
2039 // .. and if not, do it separately
2040 WriteBlocks(media_type,fd,file,start_blk,1,Dir);
2041 WriteBlocks(media_type,fd,file,GetFatEntry(media_type,DiskFAT,file,start_blk),1,Dir+BLOCK_SIZE);
2042 }
2043}
2044
2045
2046/////////////////////////////
2047// GetEFEs
2048int GetEFEs(char media_type, int fd, FILE *in, unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE],
2049 char *process_efe, unsigned char *DiskFAT)
2050{
2051 FILE *out;
2052 unsigned int i,j,k, size, cont, start, fatval, bp;
2053 unsigned char type, Header[BLOCK_SIZE], *mem_pointer;
2054 char name[13],dosname[17];
2055 unsigned char Data[BLOCK_SIZE];
2056
2057 // Process Efe's list
2058 for(j=0;j<MAX_NUM_OF_DIR_ENTRIES;j++) {
2059
2060 // Check if current efe has to be processed
2061 if(process_efe[j] == 0) continue;
2062
2063 // Get info
2064 if((type=Efe[j][1]) == 0) continue;
2065
2066 size =(unsigned int) ((Efe[j][14] << 8) + Efe[j][15]);
2067 cont =(unsigned int) ((Efe[j][16] << 8) + Efe[j][17]);
2068 start=(unsigned long) ((Efe[j][18] << 24) + (Efe[j][19] << 16)
2069 +(Efe[j][20] <<8 ) + Efe[j][21]);
2070
2071 //Name
2072 for(k=0;k<12;k++) {
2073 name[k]=Efe[j][k+2];
2074 }
2075 name[12]=0;
2076
2077 // Name to DosName
2078 DosName(dosname,name);
2079
2080 // Write EFE-Header
2081
2082 //Construct Header
2083 Header[0] =0x0D;
2084 Header[1] =0x0A;
2085 strcpy(&Header[2],"Eps File: ");
2086 strcpy(&Header[18],name);
2087 strcpy(&Header[30],EpsTypes[type]);
2088 strcpy(&Header[37]," ");
2089
2090 Header[50]=Efe[j][1]; // Instrument
2091 Header[51]=0;
2092 Header[52]=Efe[j][14];
2093 Header[53]=Efe[j][15];
2094 Header[54]=Efe[j][16];
2095 Header[55]=Efe[j][17];
2096 Header[56]=Efe[j][20];
2097 Header[57]=Efe[j][21];
2098 for(i=58;i<BLOCK_SIZE;i++) Header[i]=0;
2099
2100 if((out=fopen(dosname,"wb"))== NULL) {
2101 EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",dosname));
2102 }
2103
2104 fwrite(Header,sizeof(unsigned char),BLOCK_SIZE,out);
2105
2106 // Copy contiguous blocks
2107
2108 if(media_type=='f') {
2109 // FILE - ACCESS
2110 for(i=0;i<cont;i++) {
2111 ReadBlocks(media_type,fd,in,start+i,1,Data);
2112 fwrite(Data,sizeof(unsigned char),BLOCK_SIZE,out);
2113 }
2114
2115 } else {
2116 // DISK - ACCESS - Can be copied in one big chunck (disk size is limited!)
2117 mem_pointer=malloc(BLOCK_SIZE*cont);
2118 if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
2119 ReadBlocks(media_type,fd,in,start,cont,mem_pointer);
2120 fwrite(mem_pointer,sizeof(unsigned char),BLOCK_SIZE*cont,out);
2121 free(mem_pointer);
2122 }
2123
2124 //Get rest of the blocks
2125 bp=start+cont-1;
2126
2127 fatval=GetFatEntry(media_type,DiskFAT,in,bp);
2128
2129 if(fatval != 1) {
2130
2131
2132 if(media_type == 'f') {
2133 // FILE ACCESS
2134 while(fatval !=1) {
2135
2136 ReadBlocks(media_type,fd,in,fatval,1,Data);
2137 fwrite(Data,sizeof(unsigned char),BLOCK_SIZE,out);
2138
2139 bp=fatval;
2140 fatval = GetFatEntry(media_type,DiskFAT,in,bp);
2141 }
2142 } else {
2143 // DISK ACCESS
2144 while(fatval != 1) {
2145
2146 // Find contigous blocks from FAT-table
2147 cont=1;
2148 start=fatval;
2149 bp=fatval;
2150 fatval=GetFatEntry(media_type,DiskFAT,in,start);
2151
2152 while(fatval == bp+1) {
2153 bp=fatval;
2154 fatval = GetFatEntry(media_type,DiskFAT,in,bp);
2155 cont++;
2156 }
2157
2158 // Copy contigous blocks
2159 mem_pointer=malloc(BLOCK_SIZE*cont);
2160 if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
2161 ReadBlocks(media_type,fd,in,start,cont,mem_pointer);
2162 fwrite(mem_pointer,sizeof(unsigned char),BLOCK_SIZE*cont,out);
2163 free(mem_pointer);
2164 } // while
2165 } // else
2166 } // if
2167
2168 fclose(out);
2169 }
2170 return(OK);
2171}
2172
2173//////////////////////////////////////////////////////////////
2174// PutEFE
2175// ------
2176// - This function can be used for writing EFEs to disk/image
2177// from EFE-file or from memory. If memory is used, the
2178// pointer for efe header (MemDataHdr) and efe data (MemData)
2179// are needed!!
2180
2181void PutEFE(
2182 char *process_efe,
2183 unsigned char start_idx,
2184 unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE],
2185 char media_type,
2186 char image_type,
2187 char *image_file,
2188 char **efe_files,
2189 int optind,
2190 char *orig_image_name,
2191 unsigned int dir_start,
2192 unsigned int dir_cont,
2193 unsigned int total_blks,
2194 unsigned int *free_blks,
2195 unsigned int fat_blks,
2196 int fd,
2197 unsigned char *DiskFAT,
2198 unsigned char *DiskHdr,
2199 unsigned char *MemDataHdr,
2200 unsigned char *MemData
2201 )
2202{
2203
2204 FILE *in, *out;
2205 char in_file[FILENAME_MAX];
2206 unsigned int idx,i,j,blks,start;
2207 unsigned char efe_name[13], EfeData[EFE_SIZE], buffer[4], efe_type, Data[BLOCK_SIZE];
2208 unsigned char *mem_pointer;
2209 unsigned int efe_start_block, efe_blks, first_free_block, first_cont_blks, prev_block;
2210 unsigned int free_start, free_cnt, OS;
2211
2212
2213 //printf("__LINE__\n");
2214 //fflush(stdout);
2215
2216 if((media_type == 'f') && (MemData == NULL)) {
2217 // FILE ACCESS
2218
2219 if((out=fopen(image_file, "r+b"))== NULL) {
2220 EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",image_file));
2221 }
2222 // Skip image_file
2223 optind++;
2224 }
2225
2226 //printf("%d\n",__LINE__);
2227 //fflush(stdout);
2228
2229 // PROCESS ALL EFEs
2230
2231 //printf("%d\n",optind);
2232 //fflush(stdout);
2233
2234 // KLUDGE!!!
2235 while((MemData != NULL) || (efe_files[optind] != NULL)) {
2236
2237 //printf("%d\n",__LINE__);
2238 //fflush(stdout);
2239
2240 // Starting at pos 'start_idx' !!
2241 // (It's quite a unusual to put other that OS or SubDir to idx 0)
2242 for(idx= start_idx; idx<MAX_NUM_OF_DIR_ENTRIES; idx++) {
2243 if(Efe[idx][1] == 0) break;
2244 }
2245
2246 process_efe[idx] = 1;
2247
2248 if(idx==MAX_NUM_OF_DIR_ENTRIES) {
2249 EEXIT((stderr,"ERROR: Directory full!\n"));
2250 }
2251
2252 if(MemData == NULL) {
2253 //EFE from file
2254 //=============
2255
2256 // Efe-file
2257 if((in=fopen(efe_files[optind], "rb"))== NULL) {
2258 EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",efe_files[optind+1]));
2259 }
2260 strcpy(in_file,efe_files[optind]);
2261
2262 // Check and convert if 'Mac'-format :-P is found
2263 if(ConvertMacFormat(&in, in_file) == OK) {
2264 printf("Warning: Macintosh generated EFx file found!\n");
2265 }
2266
2267 fseek(in, (long) 0x32, SEEK_SET);
2268 fread(EfeData,sizeof(unsigned char), EFE_SIZE,in);
2269
2270 fseek(in, (long) 0x12, SEEK_SET);
2271 fread(efe_name,sizeof(unsigned char),12,in);
2272 efe_name[12]='\0';
2273
2274
2275 efe_blks = (EfeData[2] << 8) + EfeData[3];
2276 efe_type = EfeData[0];
2277
2278 // name
2279 strcpy(&Efe[idx][2],efe_name);
2280 // zero
2281 Efe[idx][0] = 0;
2282 // type
2283 Efe[idx][1] = efe_type;
2284 // size
2285 Efe[idx][14] = EfeData[2];
2286 Efe[idx][15] = EfeData[3];
2287 // empty
2288 Efe[idx][22] = 0; Efe[idx][23] = 0; Efe[idx][24] = 0; Efe[idx][25] = 0;
2289
2290 // If efe is OS, get OS version
2291 switch (efe_type)
2292 {
2293 case 1: // EPS OS
2294 fseek(in, EPS_OS_POS, SEEK_SET);
2295 fread(&OS,sizeof(unsigned int),1,in);
2296 break;
2297 case 27: // E16 OS
2298 fseek(in, E16_OS_POS, SEEK_SET);
2299 fread(&OS,sizeof(unsigned int),1,in);
2300 break;
2301 case 32: // ASR OS
2302 fseek(in, ASR_OS_POS, SEEK_SET);
2303 fread(&OS,sizeof(unsigned int),1,in);
2304 break;
2305 default:
2306 OS = 0;
2307 }
2308
2309 // Set reading point to start od data
2310 fseek(in,BLOCK_SIZE, SEEK_SET);
2311
2312 } else {
2313 //printf("%d\n",__LINE__);
2314 //fflush(stdout);
2315 // EFE from memory (ie. for ex. mkdir)
2316 //====================================
2317
2318 if(media_type == 'f') {
2319 // FILE ACCESS
2320 // Image-file
2321 if((out=fopen(image_file, "r+b"))== NULL) {
2322 EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",image_file));
2323 }
2324 }
2325
2326 // Copy header to Efe (ie. make dir entry)
2327 memcpy(Efe[idx], MemDataHdr, EFE_SIZE);
2328
2329 efe_type = MemDataHdr[1];
2330
2331 if(efe_type == 2) {
2332 // set dir size temporary to 2
2333 efe_blks = 2;
2334 // Root dir has info about parent's index in 'cont'
2335 MemData[16] = 0;
2336 MemData[17] = idx;
2337 } else {
2338 efe_blks = (MemDataHdr[14] << 8) + MemDataHdr[15];
2339 }
2340 //printf("%d\n",__LINE__);
2341 //fflush(stdout);
2342 }
2343
2344 if(efe_blks > *free_blks) {
2345 EEXIT((stderr,"Not enough free space! %d needed, %d available.\n", efe_blks, *free_blks));
2346 }
2347
2348 first_free_block = 0;
2349 free_start = 0;
2350 free_cnt=0;
2351
2352
2353 // First PASS - Check if enough contiguos blocks
2354 for(i=FAT_START_BLOCK+fat_blks; i<total_blks; i++) {
2355 if(GetFatEntry(media_type,DiskFAT,out,i) == 0) {
2356 //Free block found
2357 if(free_start == 0) {
2358 // Save the num. of the first free block found
2359 if(first_free_block == 0) {
2360 first_free_block = i;
2361 }
2362
2363 free_start = i;
2364 }
2365 free_cnt++;
2366
2367 if(free_cnt == efe_blks) {
2368 // Contiguos blocks found - write whole efe from start_block
2369
2370 if(media_type == 'f') {
2371 // FILE ACCESS
2372
2373 // Copy Blocks
2374 fseek(out, BLOCK_SIZE*free_start , SEEK_SET);
2375 for(j=0; j<efe_blks; j++) {
2376
2377 if(MemData == NULL) {
2378 fread(Data,sizeof(unsigned char),BLOCK_SIZE,in);
2379 } else {
2380 memcpy(Data, MemData, BLOCK_SIZE);
2381 MemData = MemData + BLOCK_SIZE;
2382 }
2383
2384 fwrite(Data,sizeof(unsigned char),BLOCK_SIZE,out);
2385 }
2386
2387 } else {
2388 // DISK ACCESS
2389 mem_pointer=malloc(BLOCK_SIZE*efe_blks);
2390 if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
2391
2392 if(MemData == NULL) {
2393 fread(mem_pointer, sizeof(unsigned char), BLOCK_SIZE*efe_blks, in);
2394 } else {
2395 memcpy(mem_pointer, MemData, BLOCK_SIZE*efe_blks);
2396 }
2397
2398 WriteBlocks(media_type,fd,NULL,free_start,efe_blks,mem_pointer);
2399 free(mem_pointer);
2400 }
2401
2402 // Write FAT
2403 for(j=free_start; j<free_start+efe_blks-1; j++) {
2404 PutFatEntry(media_type,DiskFAT,out, j,j+1);
2405 }
2406
2407 // Mark the end-of-efe
2408 PutFatEntry(media_type,DiskFAT,out, j,1);
2409
2410 efe_start_block = free_start;
2411 first_cont_blks = efe_blks;
2412 break;
2413 }
2414
2415 } else {
2416 free_start = 0;
2417 free_cnt = 0;
2418 }
2419 }
2420
2421 // Second PASS (if needed)
2422 // If there was no enough contiguos blocks, the efe must be
2423 // saved using the space fragments available.. :-(
2424
2425 if(i==total_blks) {
2426 efe_start_block = first_free_block;
2427 prev_block = 0;
2428 free_cnt = 0;
2429 first_cont_blks = 0;
2430 blks=0;
2431 start=0;
2432
2433 // Spilt n' write the efe
2434 for(i=first_free_block; (i<total_blks) || (free_cnt == efe_blks); i++) {
2435
2436 if(free_cnt == efe_blks) break;
2437
2438 // Try to find free space
2439 if(GetFatEntry(media_type,DiskFAT,out,i) == 0) {
2440
2441 if(start==0) start=i;
2442
2443 if(prev_block != 0) {
2444 PutFatEntry(media_type,DiskFAT,out, prev_block,i);
2445 }
2446 prev_block = i;
2447 free_cnt++;
2448 blks++;
2449 } else {
2450 // Calc cont blocks (first entry);
2451 if(first_cont_blks == 0) {
2452 first_cont_blks= i - first_free_block;
2453 }
2454
2455 // process data in chunks (after found free space)
2456 if(blks!= 0) {
2457
2458 // Allocate mem
2459 mem_pointer=malloc(BLOCK_SIZE*blks);
2460 if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
2461
2462 // Read data
2463 if(MemData == NULL) {
2464 fread(mem_pointer,sizeof(unsigned char),BLOCK_SIZE*blks,in);
2465 } else {
2466 memcpy(mem_pointer, MemData, BLOCK_SIZE*blks);
2467 MemData = MemData + BLOCK_SIZE*blks;
2468 }
2469
2470 // Write data
2471 WriteBlocks(media_type, fd, out, start, blks, mem_pointer);
2472
2473 free(mem_pointer);
2474 start=0;
2475 blks=0;
2476
2477 }
2478
2479 }
2480 }
2481
2482 // Allocate mem
2483 mem_pointer=malloc(BLOCK_SIZE*blks);
2484 if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
2485
2486 // Read data
2487 if(MemData == NULL) {
2488 fread(mem_pointer,sizeof(unsigned char),BLOCK_SIZE*blks,in);
2489 } else {
2490 memcpy(mem_pointer, MemData, BLOCK_SIZE*blks);
2491 MemData = MemData + BLOCK_SIZE*blks;
2492 }
2493
2494 // Write data
2495 WriteBlocks(media_type, fd, out, start, blks, mem_pointer);
2496
2497 free(mem_pointer);
2498
2499
2500 if(i==total_blks) {
2501 EEXIT((stderr,"ERROR: Image/Disk has a corrupted fat!!\n"));
2502 }
2503
2504 // Mark the end-of-efe
2505 PutFatEntry(media_type,DiskFAT,out, i-1,1);
2506 }
2507
2508 // Update disk-free field
2509 *free_blks = (*free_blks) - efe_blks;
2510 buffer[0] = ((*free_blks) >> 24) & 0x000000ff; // MSB
2511 buffer[1] = ((*free_blks) >> 16) & 0x000000ff;
2512 buffer[2] = ((*free_blks) >> 8) & 0x000000ff;
2513 buffer[3] = (*free_blks) & 0x000000ff; // LSB
2514
2515 if(media_type=='f') {
2516 // FILE ACCESS
2517 fseek(out, OS_BLOCK*BLOCK_SIZE, SEEK_SET);
2518 fwrite(buffer,sizeof(unsigned char),4,out);
2519
2520 // If OS, update OS-verion
2521 if(OS != 0) {
2522 fwrite(&OS,sizeof(unsigned int),1,out);
2523 }
2524
2525 } else {
2526 // DISK ACCESS
2527 memcpy(DiskHdr+OS_BLOCK*BLOCK_SIZE,buffer,4);
2528
2529 // If OS, update OS-version
2530 if(OS != 0) {
2531 memcpy(DiskHdr+OS_BLOCK*BLOCK_SIZE+4,&OS,4);
2532 }
2533 }
2534
2535 // Complete DirEntry
2536
2537 // size in blocks
2538 if(efe_type == 2) {
2539 // dir's size = num of files ( = 0 when created)
2540 Efe[idx][14] = 0;
2541 Efe[idx][15] = 0;
2542 } else {
2543 Efe[idx][14] = (unsigned char) (efe_blks >> 8) & 0xFF;
2544 Efe[idx][15] = (unsigned char) (efe_blks & 0xFF);
2545 }
2546
2547 // contiguos blocks
2548 Efe[idx][16] = (unsigned char) (first_cont_blks >> 8);
2549 Efe[idx][17] = (unsigned char) first_cont_blks & 0x00FF;
2550
2551 // start block
2552 Efe[idx][18] = efe_start_block >> 24;
2553 Efe[idx][19] = efe_start_block >> 16;
2554 Efe[idx][20] = efe_start_block >> 8;
2555 Efe[idx][21] = efe_start_block & 0x000000FF;
2556
2557 // Go to Dir entry
2558
2559 // Write System Blocks
2560 if(media_type=='f') {
2561 // FILE ACCESS
2562 fseek(out, dir_start*BLOCK_SIZE + EFE_SIZE*idx , SEEK_SET);
2563 fwrite(Efe[idx],sizeof(unsigned char),EFE_SIZE,out);
2564 } else {
2565 // DISK ACCESS
2566
2567 // !!!!!
2568 if(dir_start == DIR_START_BLOCK) {
2569 memcpy(DiskHdr+dir_start*BLOCK_SIZE + EFE_SIZE*idx,Efe[idx],EFE_SIZE);
2570 }
2571
2572 //WriteBlocks(media_type,fd,NULL,0,5+fat_blks,DiskHdr);
2573 }
2574
2575 // If Not in Main Dir, update Dir Entries & num. of files in dir
2576 if(dir_start != DIR_START_BLOCK) {
2577
2578 unsigned char ParentEfe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE];
2579 unsigned int parent_dir_idx, parent_dir_files;
2580
2581 // Save changes in curent dir
2582 SaveDirBlocks(media_type, fd, DiskFAT, out, dir_start, dir_cont,Efe);
2583
2584 // Get info about parent dir
2585 parent_dir_idx = (unsigned int) ((Efe[0][16] << 8) + Efe[0][17]);
2586 dir_start = (unsigned long) ((Efe[0][18] << 24) + (Efe[0][19] << 16)
2587 +(Efe[0][20] << 8 ) + Efe[0][21]);
2588
2589 // Don't know how many cont blocks so suppose worst case
2590 dir_cont = 1;
2591
2592 // Load parent dir
2593 LoadDirBlocks(media_type,fd,DiskFAT,out,dir_start,dir_cont,ParentEfe);
2594
2595 // Update parent dir 'num. of files'
2596 parent_dir_files =(unsigned int) ((ParentEfe[parent_dir_idx][14] << 8) +
2597 ParentEfe[parent_dir_idx][15]);
2598
2599 parent_dir_files++;
2600 ParentEfe[parent_dir_idx][14] = (unsigned char) (parent_dir_files >> 8) & 0xFF;
2601 ParentEfe[parent_dir_idx][15] = (unsigned char) (parent_dir_files & 0xFF);
2602
2603 // Save changes in parent dir
2604 SaveDirBlocks(media_type, fd, DiskFAT, out, dir_start, dir_cont,ParentEfe);
2605 }
2606
2607 optind++;
2608
2609 // KLUDGE!!!
2610 if(MemData != NULL) break;
2611
2612 } // while(efe_files...)
2613
2614
2615 // Free memory used for DiskFat etc. cache
2616 if(media_type != 'f') {
2617 // Write SystemBlocks to disk and free mem
2618 WriteBlocks(media_type,fd,NULL,0,5+fat_blks,DiskHdr);
2619 free(DiskHdr);
2620
2621 } else {
2622
2623 // Convert to back to orginal format if not raw-image
2624 if((image_type != EPS_TYPE) && (image_type != ASR_TYPE) && (image_type != OTHER_TYPE)) {
2625
2626 if(MemData != NULL) {
2627 fclose(in);
2628 }
2629
2630 fclose(out);
2631 ConvertFromImage (image_file, orig_image_name, image_type);
2632 }
2633 }
2634
2635}
2636
2637
2638/////////////////////////////
2639// EraseEFEs
2640int EraseEFEs(char media_type, char image_type, int fd,
2641 unsigned char *DiskFAT, unsigned char *DiskHdr,
2642 char *in_file, char *orig_image_name,
2643 unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE], char *process_efe,
2644 unsigned int fat_blks, unsigned int *free_blks,
2645 unsigned int dir_start, unsigned int dir_cont)
2646{
2647 FILE *out;
2648 unsigned int size,cont,start,type,i,j,counter;
2649 unsigned int OS = 1;
2650 unsigned char buffer[4];
2651
2652 counter = 0;
2653
2654 // FILE ACCESS
2655 if(media_type=='f') {
2656 // Image-file
2657 if((out=fopen(in_file, "r+b"))== NULL) {
2658 EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",in_file));
2659 }
2660 }
2661
2662 // Process Efe's list
2663 for(j=0;j<MAX_NUM_OF_DIR_ENTRIES;j++) {
2664 // Check if current efe has to be processed
2665 if(process_efe[j] == 0) continue;
2666
2667 // Get info
2668 type=Efe[j][1];
2669
2670 switch (type)
2671 {
2672 case 0: // Empty
2673 continue;
2674
2675 case 2: // Sub dir
2676 if(Efe[j][15] > 0) {
2677 fprintf(stderr, "\nIDX %-2d: Can't erase directory! Directory not empty.\n\n",j);
2678 continue;
2679 }
2680 size = 2;
2681 break;
2682
2683 case 8: // Pointer to 'root'
2684 fprintf(stderr, "\nIDX %-2d: Can't erase link to parent dir!\n\n",j);
2685 continue;
2686
2687 // If erasing os, clear version field
2688 case 1:
2689 case 27:
2690 case 32:
2691 OS = 0;
2692
2693 default:
2694 size =(unsigned int) ((Efe[j][14] << 8) + Efe[j][15]);
2695 }
2696
2697 cont =(unsigned int) ((Efe[j][16] << 8) + Efe[j][17]);
2698 start=(unsigned long) ((Efe[j][18] << 24) + (Efe[j][19] << 16)
2699 +(Efe[j][20] <<8 ) + Efe[j][21]);
2700
2701 // Calculate 'disk-free'
2702 *free_blks = (*free_blks) + size;
2703
2704 // Clear FAT entries
2705
2706 while((i=GetFatEntry(media_type,DiskFAT,out,start)) != 1) {
2707 PutFatEntry(media_type,DiskFAT,out,start,0);
2708 start=i;
2709 }
2710 // .. and last entry (ie. stopmark '1')
2711 PutFatEntry(media_type,DiskFAT,out,start,0);
2712
2713 // Clear Dir entry
2714 for(i=0;i<26;i++) {
2715 Efe[j][i] = 0;
2716 }
2717
2718 // Count erased files for 'num of files' in parent dir
2719 counter++;
2720
2721 } // For 'process_efes'
2722
2723 // Update disk-free field
2724 buffer[0] = ((*free_blks) >> 24) & 0x000000ff; // MSB
2725 buffer[1] = ((*free_blks) >> 16) & 0x000000ff;
2726 buffer[2] = ((*free_blks) >> 8) & 0x000000ff;
2727 buffer[3] = (*free_blks) & 0x000000ff; // LSB
2728
2729 if(media_type=='f') {
2730 // FILE ACCESS
2731 fseek(out, OS_BLOCK*BLOCK_SIZE, SEEK_SET);
2732 fwrite(buffer,sizeof(unsigned char),4,out);
2733 // If erasing OS, clear OS-field
2734 if(!OS) {
2735 fwrite(&OS,sizeof(unsigned int),1,out);
2736 }
2737
2738 } else {
2739 // DISK ACCESS
2740 memcpy(DiskHdr+OS_BLOCK*BLOCK_SIZE,buffer,4);
2741 // If erasing OS, clear OS-field
2742 if(!OS) {
2743 memcpy(DiskHdr+OS_BLOCK*BLOCK_SIZE+4,&OS,4);
2744 }
2745
2746 }
2747
2748 // Write System Blocks
2749 if(media_type != 'f') {
2750 // DISK ACCESS
2751 WriteBlocks(media_type,fd,NULL,0,5+fat_blks,DiskHdr);
2752 }
2753
2754
2755 // Update Dir Entries
2756 SaveDirBlocks(media_type, fd, DiskFAT, out, dir_start, dir_cont,Efe);
2757
2758 // If Not in Main Dir, update Dir Entries & num. of files in dir
2759 if(dir_start != DIR_START_BLOCK) {
2760
2761 unsigned char ParentEfe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE];
2762 unsigned int parent_dir_idx, parent_dir_files;
2763
2764 // Get info about parent dir
2765 parent_dir_idx = (unsigned int) ((Efe[0][16] << 8) + Efe[0][17]);
2766 dir_start = (unsigned long) ((Efe[0][18] << 24) + (Efe[0][19] << 16)
2767 +(Efe[0][20] << 8 ) + Efe[0][21]);
2768
2769 // Don't know how many cont blocks so suppose worst case
2770 dir_cont = 1;
2771
2772 // Load parent dir
2773 LoadDirBlocks(media_type,fd,DiskFAT,out,dir_start,dir_cont,ParentEfe);
2774
2775 // Update parent dir 'num of files'
2776 parent_dir_files =(unsigned int) ((ParentEfe[parent_dir_idx][14] << 8) +
2777 ParentEfe[parent_dir_idx][15]);
2778
2779 // Decrement 'num. of files' in parent dir
2780 parent_dir_files = parent_dir_files - counter;
2781
2782 // if everything is OK, this _should_ NOT happen...
2783 if(parent_dir_files < 0) parent_dir_files = 0;
2784
2785 ParentEfe[parent_dir_idx][14] = (unsigned char) (parent_dir_files >> 8) & 0xFF;
2786 ParentEfe[parent_dir_idx][15] = (unsigned char) (parent_dir_files & 0xFF);
2787
2788 // Save changes in parent dir
2789 SaveDirBlocks(media_type, fd, DiskFAT, out, dir_start, dir_cont,ParentEfe);
2790 }
2791
2792
2793 // Free memory used for DiskFat etc. cache
2794 if(media_type != 'f') {
2795 free(DiskHdr);
2796
2797 } else {
2798
2799 // Convert to back to orginal format if not raw-image
2800 if((image_type != EPS_TYPE) && (image_type != ASR_TYPE) && (image_type != OTHER_TYPE)) {
2801 fclose(out);
2802 ConvertFromImage (in_file, orig_image_name, image_type);
2803 }
2804 }
2805
2806 return(OK);
2807}
2808
2809//////////////////
2810// MkDir
2811int MkDir(
2812 char *process_efe,
2813 unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE],
2814 char media_type,
2815 char image_type,
2816 char *image_file,
2817 char *orig_image_name,
2818 unsigned int dir_start,
2819 unsigned int dir_cont,
2820 char *dir_name,
2821 unsigned int total_blks,
2822 unsigned int *free_blks,
2823 unsigned int fat_blks,
2824 int fd,
2825 unsigned char *DiskFAT,
2826 unsigned char *DiskHdr,
2827 char DirName[12]
2828 )
2829{
2830 unsigned char MemDataHdr[EFE_SIZE], *MemData;
2831 int i;
2832
2833 for(i=0; i < EFE_SIZE; i++) {
2834 MemDataHdr[i] = 0;
2835 }
2836
2837 // Convert name
2838 for(i=0; i < 12; i++) {
2839 DirName[i] = (unsigned char) toupper(DirName[i]);
2840 }
2841
2842 // Make header
2843
2844 // Type (2)
2845 MemDataHdr[1] = 2;
2846 // Name
2847 for(i=0; i<12; i++) {
2848 if(DirName[i] == 0) {
2849 MemDataHdr[2+i] = 0x20;
2850 } else {
2851 MemDataHdr[2+i] = DirName[i];
2852 }
2853 }
2854 // Size (2)
2855 MemDataHdr[15] = 2;
2856
2857
2858
2859 // Make data
2860
2861 // 2 x Blocks
2862 MemData=calloc(2*BLOCK_SIZE,sizeof(unsigned char));
2863 if(MemData == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
2864
2865 // First entry is root-dir
2866
2867 // Type (8)
2868 MemData[1] = 8;
2869 // Name of parent dir
2870 strncpy(MemData+2, dir_name, 12);
2871 // Cont ( < 255!!)
2872 MemData[17] = (unsigned char) dir_cont;
2873 // Root Dir start block
2874 MemData[18] = (dir_start >> 24) & 0x000000FF;
2875 MemData[19] = (dir_start >> 16) & 0x000000FF;
2876 MemData[20] = (dir_start >> 8) & 0x000000FF;
2877 MemData[21] = dir_start & 0x000000FF;
2878
2879 // 'DR'
2880 MemData[2*BLOCK_SIZE-2] = 0x44; MemData[2*BLOCK_SIZE-1] = 0x52;
2881
2882 // Write dir
2883
2884 PutEFE(process_efe, 1, Efe, media_type, image_type,
2885 image_file, NULL, 0, orig_image_name,
2886 dir_start, dir_cont, total_blks, free_blks, fat_blks,
2887 fd, DiskFAT, DiskHdr, MemDataHdr, MemData);
2888
2889 return(OK);
2890}
2891
2892/////////////////////////////
2893// DoConversion
2894void DoConversion(char in_file[FILENAME_MAX], char out_file[FILENAME_MAX], int argc)
2895{
2896 struct stat stat_buf;
2897 char image_type;
2898
2899 if(argc != 4) {
2900 fprintf(stderr,"ERROR: Wrong number of argumets\n");
2901 ShowUsage();
2902 exit(ERR);
2903 }
2904
2905 if(ConvertToImage(in_file,out_file) == OK) {
2906 //printf("CONVERSION DONE!!!\n");
2907 exit(OK);
2908 }
2909
2910 // No conversion - suppose img-file
2911 // Check if ASR or EPS image
2912
2913 if(stat(in_file,&stat_buf) != 0) {
2914 EEXIT((stderr,"ERROR: Can't get the filesize!!\n"));
2915 }
2916
2917 if(stat_buf.st_size == EPS_IMAGE_SIZE) {
2918 image_type = EDE_TYPE;
2919 } else if(stat_buf.st_size == ASR_IMAGE_SIZE) {
2920 image_type = EDA_TYPE;
2921 } else {
2922 EEXIT((stderr,"ERROR: Unsupported image type!\n\n"));
2923 }
2924
2925 ConvertFromImage (in_file,out_file, image_type);
2926
2927 //printf("Conversion succesfully!\n");
2928}
2929
2930/////////////////////////////////////////
2931// GetMedia
2932// ------------
2933// - Determines if disk or image is used,
2934// and does nessecery opening and conversions
2935
2936void GetMedia(char *arg, int argc, char *media_type, char *image_type,
2937 unsigned int *nsect, unsigned int *trk_size, int *fd,
2938 char *in_file, FILE **in)
2939{
2940 unsigned int tmp;
2941
2942 // Determines is DISK or FILE access
2943
2944 // TODO: THIS IS EXPERIMENTAL
2945 if((arg == NULL) || ((IsEFE(arg) == OK) && (argc >= 3))) {
2946 // DISK ACCESS
2947 if(FD_GetDiskType(media_type,nsect,trk_size) == ERR) {
2948 EEXIT((stderr,"ERROR: NOT an Ensoniq Disk.\n Please format the disk (-fe or -fa) and try again!!\n\n"));
2949 }
2950 //Open FD
2951 *fd = open( "/dev/fd0", O_ACCMODE | O_NDELAY);
2952 if ( fd < 0 ){
2953 perror("open floppy");
2954 exit(ERR);
2955 }
2956
2957 } else {
2958 // FILE ACCESS
2959 *media_type='f';
2960
2961 // Get the image filename
2962 strcpy(in_file,arg);
2963
2964 GetImageType(in_file, image_type);
2965
2966 // Check if conversion is needed!
2967 if((*image_type != EPS_TYPE) && (*image_type != ASR_TYPE) && (*image_type != OTHER_TYPE)) {
2968
2969 // Generate tmp-file and bind the clean-up for it
2970 //tmpnam(tmp_file);
2971 mkstemp(tmp_file);
2972 atexit(CleanTmpFile);
2973
2974 if(ConvertToImage(in_file,tmp_file) == OK) {
2975 //repalace in_file to converted image
2976 strcpy(in_file,tmp_file);
2977 }
2978 }
2979
2980 if((*in =fopen(in_file, "rb"))== NULL) {
2981 perror("open:");
2982 EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",in_file));
2983 }
2984
2985 if(IsEFE(in_file) != OK) {
2986 // Check that EPS/ASR image is valid! (ie. do the 'ID-check')
2987 fseek(*in, (long) 0x224, SEEK_SET);
2988 fread(&tmp,sizeof(unsigned int),1,*in);
2989
2990 if((tmp & 0xffff0000) != 0x44490000) {
2991 EEXIT((stderr,"ERROR: Not a valid image file!\n"));
2992 }
2993 }
2994
2995 }
2996
2997}
2998
2999
3000////////////////////////////////////////////////////
3001// GetInfo
3002// -------
3003// -Get info about used media and loads the selected
3004// directory structure.
3005//
3006
3007void GetInfo(char *media_type, int fd, unsigned char **DiskFAT, unsigned char **DiskHdr,
3008 FILE *in,
3009 unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE],
3010 unsigned int *fat_blks, unsigned int *free_blks, unsigned int *total_blks,
3011 unsigned int *dir_start, unsigned int *dir_cont,
3012 char *parent_dir_name, int subdir_cnt,
3013 unsigned int *DirPath, char *DiskLabel)
3014{
3015
3016 unsigned char *mem_pointer;
3017 unsigned int tmp,i,j;
3018
3019 if(*media_type=='f') {
3020 // FILE ACCESS
3021 mem_pointer=malloc(5*BLOCK_SIZE);
3022 if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
3023
3024 ReadBlocks(*media_type,fd,in,0,5,mem_pointer);
3025
3026 } else {
3027 // DISK ACCESS
3028 if(*media_type=='e') *fat_blks=10; else *fat_blks=19;
3029
3030 mem_pointer=malloc((5+(*fat_blks))*BLOCK_SIZE);
3031 if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
3032
3033 ReadBlocks(*media_type,fd,in,0,5+(*fat_blks),mem_pointer);
3034 *DiskHdr=mem_pointer;
3035 *DiskFAT=mem_pointer+FAT_START_BLOCK*BLOCK_SIZE;
3036 }
3037
3038 // Get 'TotalBlocks' and 'DiskLabel' from ID_BLOCK
3039
3040 tmp=ID_BLOCK*BLOCK_SIZE;
3041 *total_blks = (unsigned int) ((mem_pointer[tmp+14] << 24) +
3042 (mem_pointer[tmp+15] << 16) +
3043 (mem_pointer[tmp+16] << 8 ) +
3044 (mem_pointer[tmp+17] & 0x000000ff));
3045
3046 strncpy(DiskLabel, mem_pointer+tmp+31,7);
3047 DiskLabel[7]='\0';
3048
3049 if(strlen(DiskLabel) == 0) strcpy(DiskLabel,"<NONE>");
3050 *fat_blks = (*total_blks /170) + 1;
3051
3052 // Get 'FreeBlocks' from OS_BLOCK
3053
3054 tmp=OS_BLOCK*BLOCK_SIZE;
3055 *free_blks = (unsigned int) ((mem_pointer[tmp] << 24) +
3056 (mem_pointer[tmp+1] << 16) +
3057 (mem_pointer[tmp+2] << 8 ) +
3058 (mem_pointer[tmp+3] & 0x000000ff));
3059
3060 // Load main directory
3061 *dir_start=DIR_START_BLOCK;
3062 *dir_cont = 2;
3063
3064 // Scan Main Directory
3065 for(i=0;i<MAX_NUM_OF_DIR_ENTRIES;i++) {
3066 for(j=0; j < EFE_SIZE ; j++) {
3067 Efe[i][j]=mem_pointer[DIR_START_BLOCK*BLOCK_SIZE + i * EFE_SIZE + j];
3068 }
3069 }
3070
3071 //LoadDirBlocks(media_type,fd,DiskFAT,in,dir_start,dir_cont,Efe);
3072
3073 // SUB-DIRS - Use the 'path' to 'change dir'...
3074 if(subdir_cnt >0) {
3075 for(i=0; i < subdir_cnt; i++) {
3076 j=DirPath[i];
3077 if (Efe[j][1] != 2) {
3078 EEXIT((stderr,"ERROR: Index '%d' is not a directory!\n\n",j));
3079 }
3080
3081 strncpy(parent_dir_name, Efe[j]+2, 12);
3082 *dir_cont =(unsigned int) ((Efe[j][16] << 8) + Efe[j][17]);
3083 *dir_start =(unsigned long) ((Efe[j][18] << 24) + (Efe[j][19] << 16)
3084 +(Efe[j][20] << 8 ) + Efe[j][21]);
3085
3086 LoadDirBlocks(*media_type,fd,*DiskFAT,in,*dir_start,*dir_cont,Efe);
3087 }
3088
3089 } else {
3090 // if parent is root dir, set parent_name to 'ROOT'
3091 strncpy(parent_dir_name,"ROOT ", 12);
3092 }
3093
3094}
3095
3096////////////////////////////////////////////////////
3097// CheckMedia
3098// ----------
3099// -Get info about used media and check the filesystem
3100// structure
3101
3102void CheckMedia(char media_type, int fd, FILE *file, int check_level)
3103{
3104 long i,j,count,used_blks;
3105 unsigned char buffer[BLOCK_SIZE],*root_dir;
3106 long total_blks,free_blks;
3107 long file_size;
3108
3109
3110 //Get File/Device info
3111 if(media_type=='f') {
3112 // FILE ACCESS
3113 if(fseek(file,0,SEEK_END) == -1) {
3114 perror("lseek");
3115 exit(1);
3116 }
3117 file_size=ftell(file);
3118 } else {
3119 // DISK ACCESS
3120 if((file_size=lseek(fd,0,SEEK_END)) == -1) {
3121 perror("lseek");
3122 exit(1);
3123 }
3124
3125 }
3126
3127 printf("\nFile/Device size: %ld bytes (%ld blocks)\n\n",file_size,file_size/BLOCK_SIZE);
3128
3129 //ID-Block
3130
3131 ReadBlocks(media_type,fd,file,ID_BLOCK,1,buffer);
3132
3133 printf("\nID-BLOCK\n");
3134 printf("========\n\n");
3135
3136 printf("Device type : %d(%x)\n" ,buffer[0],buffer[0]);
3137 printf("Rem. Media Device type : %d(%x)\n" ,buffer[1],buffer[1]);
3138 printf("Std.Version# : %d(%x)\n" ,buffer[2],buffer[2]);
3139 printf("SCSI (?) : %d(%x)\n" ,buffer[3],buffer[3]);
3140 printf("Number of Sectors : %d(%x%x)\n",(buffer[4]*256+buffer[5]),buffer[4],buffer[5]);
3141 printf("Number of Heads : %d(%x%x)\n",(buffer[6]*256+buffer[7]),buffer[6],buffer[7]);
3142 printf("Number of Tracks : %d(%x%x)\n",(buffer[8]*256+buffer[9]),buffer[8],buffer[9]);
3143 printf("Bytes per Block (512) : %d(%x%x)\n",(buffer[12]*256+buffer[13]),buffer[12],buffer[13]);
3144
3145 total_blks = ((buffer[14] << 24) +
3146 (buffer[15] << 16) +
3147 (buffer[16] << 8 ) +
3148 (buffer[17] & 0x000000ff));
3149 printf("Total Blocks : %ld(%x%x%x%x) (%ld Bytes = %ld KBytes = %ld MBytes)\n",
3150 total_blks,
3151 buffer[14],buffer[15],buffer[16],buffer[17],
3152 total_blks*512,total_blks*512/1024,total_blks*512/1024/1024);
3153
3154 printf("SCSI Medium type : %d(%x)\n" ,buffer[18],buffer[18]);
3155 printf("SCSI Density Code : %d(%x)\n" ,buffer[19],buffer[19]);
3156
3157 printf("DISK LABEL : \"%c%c%c%c%c%c%c\" \n",buffer[31],buffer[32],buffer[33],
3158 buffer[34],buffer[35],buffer[36],buffer[37]);
3159
3160 printf("End of ID-Block(\"ID\") : \"%c%c\"\n",buffer[38],buffer[39]);
3161
3162
3163 //OS-Block
3164
3165 ReadBlocks(media_type,fd,file,OS_BLOCK,1,buffer);
3166
3167 printf("\nOS-BLOCK\n");
3168 printf("========\n\n");
3169
3170 free_blks = ((buffer[0] << 24) +
3171 (buffer[1] << 16) +
3172 (buffer[2] << 8 ) +
3173 (buffer[3] & 0x000000ff));
3174
3175 printf("Free Blocks : %ld(%x%x%x%x)\n",free_blks,
3176 buffer[0],buffer[1],buffer[2],buffer[3]);
3177
3178 printf("Disk OS Version : %d.%d(%x.%x)\n" ,buffer[4],buffer[5],buffer[4],buffer[5]);
3179 printf("ROM OS Version : %d.%d(%x.%x)\n" ,buffer[6],buffer[7],buffer[6],buffer[7]);
3180
3181 printf("End of OS-Block(\"OS\") : \"%c%c\"\n",buffer[28],buffer[29]);
3182
3183 printf("\nOther Blocks\n");
3184 printf("============\n\n");
3185
3186 count=0;
3187 used_blks=0;
3188
3189 ReadBlocks(media_type,fd,file,DIR_END_BLOCK,1,buffer);
3190
3191 printf("Root DirBlocks : ");
3192 if(buffer[510]=='D' && buffer[511]=='R')
3193 printf("OK\n");
3194 else
3195 printf("NOT OK - DISK/FILE is corrupted!\n");
3196
3197 for(i=FAT_START_BLOCK;;i++) {
3198
3199 ReadBlocks(media_type,fd,file,i,1,buffer);
3200
3201 //Check if valid FAT BLOCK
3202 if(buffer[510]!='F' || buffer[511]!='B')
3203 break;
3204
3205 //Count used blocks
3206 for(j=2;j<510;j=j+3) {
3207
3208 if( !((buffer[j] == 0) && (buffer[j-1] ==0) && (buffer[j-2]==0)))
3209 used_blks++;
3210
3211 }
3212 count++;
3213 }
3214
3215 printf("Num. of FatBlocks : %ld\n",count);
3216 printf("FAT entries : %ld => ",170*count);
3217 if((170*count) >= total_blks)
3218 printf("OK\n");
3219 else
3220 printf("FAT corrupted!! Not enough FAT tables!\n");
3221
3222 printf("Used Blocks in FAT: %ld => ",used_blks);
3223 if( (total_blks - (used_blks+free_blks)) == 0)
3224 printf("OK\n");
3225 else
3226 printf("FAT corrupted!! Used blocks should be %ld\n",total_blks - free_blks);
3227
3228 printf("\n");
3229
3230 // If higher check_level, display also root dir structure
3231 if(check_level > 0) {
3232 // Directory structure info
3233 printf("\nROOT DIR:\n");
3234 printf("=========\n");
3235
3236 root_dir=(unsigned char *) malloc(BLOCK_SIZE*2);
3237
3238 ReadBlocks(media_type,fd,file,DIR_START_BLOCK,2,root_dir);
3239
3240 // Scan Directory
3241 for(i=0;i<MAX_NUM_OF_DIR_ENTRIES;i++) {
3242 char name[13];
3243 printf("%3ld:",i);
3244 for(j=0; j < EFE_SIZE ; j++) {
3245 printf("%02x ",root_dir[i * EFE_SIZE+j]);
3246 }
3247 printf("\n");
3248 strncpy(name, &root_dir[i * EFE_SIZE+2],12);
3249 name[12]='\0';
3250
3251 printf(" Type:%2d, Name:%12s, Size:%ld, Cont:%ld, Start:%ld \n\n",
3252 root_dir[i * EFE_SIZE+1],
3253 name,
3254 (long) root_dir[i * EFE_SIZE+14]*256+root_dir[i * EFE_SIZE+15],
3255 (long) root_dir[i * EFE_SIZE+16]*256+root_dir[i * EFE_SIZE+17],
3256 (long) root_dir[i * EFE_SIZE+18]*256*256*256+root_dir[i * EFE_SIZE+19]*256*256 +
3257 root_dir[i * EFE_SIZE+20]*256+root_dir[i * EFE_SIZE+21]
3258 );
3259 }
3260 free(root_dir);
3261 }
3262
3263}
3264
3265////////////////////////////////////////////////////
3266// Confirm
3267// -------
3268// -Asks if user wants to proceed
3269
3270void Confirm()
3271{
3272 char answer;
3273
3274 printf("\nThis operation will DESTROY everything in the TARGET medium!\n\n");
3275 printf("Do You want to proceed (y/n) ? ");
3276 scanf("%c",&answer);
3277
3278 if((answer == 'y') || (answer == 'Y'))
3279 printf("\n");
3280 else {
3281 printf("Operation aborted!\n\n");
3282 exit(OK);
3283 }
3284}
3285
3286
3287
3288//################################################################
3289// MAIN PROGRAM ###############################################
3290//##############################################################
3291
3292int main(int argc, char **argv)
3293{
3294 FILE *in;
3295
3296 unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE];
3297 unsigned char *DiskFAT,*DiskHdr, *mem_pointer;
3298 char DiskLabel[DISK_LABEL_SIZE];
3299
3300 unsigned int DirPath[MAX_DIR_DEPTH], subdir_cnt;
3301 unsigned int total_blks, free_blks, fat_blks;
3302 unsigned int dir_start, dir_cont, start_idx;
3303
3304 unsigned long i,j;
3305
3306 char c, media_type, image_type, process_efe[MAX_NUM_OF_DIR_ENTRIES], in_file[FILENAME_MAX];
3307 char mkdir_name[12], parent_dir_name[12];
3308 char format_arg;
3309 int fd, mode, trk_size, nsect;
3310 int check_level, confirm_operation;
3311
3312 // Initialize variables
3313 mode = NONE; subdir_cnt = 0; j = 0; image_type= -1;
3314 trk_size = 0; media_type = 0; fat_blks = 0; in = NULL;
3315 fd = -1; DiskFAT = NULL; mem_pointer=NULL; start_idx = 1;
3316 confirm_operation = 0;
3317 strncpy(DiskLabel,DEFAULT_DISK_LABEL,DISK_LABEL_SIZE);
3318
3319 for(i=0;i < MAX_NUM_OF_DIR_ENTRIES; i++) process_efe[i]=0;
3320
3321 printf("\n");
3322
3323 // Get options and parameters
3324 while (1)
3325 {
3326
3327 c = getopt(argc, argv, "rwf:g:p::e:d:m:itc:C::l:q");
3328 if (c == -1)
3329 break;
3330
3331 switch (c)
3332 {
3333 case 't': // ** TEST **
3334 //EEXIT((stderr,"ERROR: No test-modes!\n"));
3335 mode = TEST;
3336 break;
3337
3338 case 'C': // ** CHECK MEDIA **
3339 GetMedia(argv[optind], argc, &media_type, &image_type, &nsect, &trk_size, &fd, in_file, &in);
3340 if(optarg==NULL) check_level=0; else check_level=*optarg-'0';
3341 CheckMedia(media_type, fd, in, check_level);
3342 exit(OK);
3343 break;
3344
3345 case 'c': // ** CONVERT **
3346 DoConversion(argv[2], argv[3], argc);
3347 exit(OK);
3348 break;
3349
3350 case 'i': // ** INFO **
3351 if(FD_GetDiskType(&media_type,&nsect,&trk_size) == ERR) {
3352 EEXIT((stderr,"ERROR: NOT an Ensoniq Disk.\n Please format the disk (-fe or -fa) and try again!!\n\n"));
3353 }
3354 exit(OK);
3355 break;
3356
3357 case 'r': // ** READ DISK to IMAGE **
3358 mode = READ;
3359 confirm_operation++;
3360 break;
3361
3362 case 'w': // ** WRITE DISK from IMAGE **
3363 mode = WRITE;
3364 confirm_operation++;
3365 break;
3366
3367 case 'f': // ** FORMAT DISK/IMAGE **
3368 mode=FORMAT;
3369 confirm_operation++;
3370 //printf("optarg=%s\n",optarg);
3371 format_arg=optarg[0];
3372 break;
3373
3374 case 'l':
3375 strncpy(DiskLabel,optarg,DISK_LABEL_SIZE);
3376 break;
3377
3378 case 'g': // ** Get EFEs **
3379 ParseEntry(optarg,process_efe);
3380 mode=GET;
3381 break;
3382
3383 case 'p': // ** Put EFEs **
3384 if(optarg != NULL) {
3385 start_idx = atoi(optarg);
3386 }
3387 mode=PUT;
3388 break;
3389
3390 case 'e': // ** Erase EFEs **
3391 ParseEntry(optarg,process_efe);
3392 mode=ERASE;
3393 break;
3394
3395 case 'd': // ** Directory **
3396 ParseDir(optarg, DirPath, &subdir_cnt);
3397 break;
3398
3399 case 'm': // ** Make directory **
3400 mode=MKDIR;
3401 strncpy(mkdir_name, optarg,12);
3402 break;
3403
3404 case 'q': // Quiet mode //
3405 confirm_operation--;
3406 break;
3407
3408 case '?':
3409 ShowUsage();
3410 return(ERR);
3411 break;
3412
3413 default:
3414 printf("DEFAULT\n");
3415 printf ("\n");
3416 }
3417 }
3418
3419
3420 if(mode == FORMAT) {
3421 if(confirm_operation) Confirm();
3422 FormatMedia(argv, argc, optind, format_arg, DiskLabel);
3423 }
3424
3425 // If other than disk read/write/format, get info etc..
3426
3427 //if((mode != WRITE) && (mode != READ) && (mode != FORMAT)) {
3428
3429 if((mode != WRITE) && (mode != READ)) {
3430
3431 // Check if DISK or FILE access and get media parameters
3432 GetMedia(argv[optind], argc, &media_type, &image_type,
3433 &nsect, &trk_size, &fd, in_file, &in);
3434
3435 // GET DIR & MISC INFO
3436 GetInfo(&media_type, fd, &DiskFAT, &DiskHdr, in, Efe,
3437 &fat_blks, &free_blks, &total_blks, &dir_start, &dir_cont,
3438 parent_dir_name, subdir_cnt, DirPath, DiskLabel);
3439
3440 }
3441
3442 // Select operation mode (if any)
3443 // ==============================
3444 switch (mode)
3445 {
3446 case READ: // Read/Wite DISK
3447 case WRITE:
3448 if(confirm_operation) Confirm();
3449
3450 FD_RW_Disk(argv[optind], mode);
3451 exit(OK);
3452
3453 case GET: // Get EFEs
3454 GetEFEs(media_type, fd, in, Efe, process_efe, DiskFAT);
3455 break;
3456
3457 case PUT: // Put EFEs
3458 PutEFE(process_efe, start_idx, Efe, media_type, image_type,
3459 in_file, argv, optind, argv[optind],
3460 dir_start, dir_cont, total_blks, &free_blks, fat_blks,
3461 fd, DiskFAT, DiskHdr, NULL, NULL);
3462 break;
3463
3464 case ERASE: // Erase EFEs
3465 EraseEFEs(media_type, image_type, fd, DiskFAT, DiskHdr, in_file, argv[optind],
3466 Efe, process_efe,
3467 fat_blks, &free_blks, dir_start, dir_cont);
3468 break;
3469
3470 case MKDIR: // Make Dir
3471 MkDir(process_efe, Efe, media_type, image_type,
3472 in_file, argv[optind],
3473 dir_start, dir_cont, parent_dir_name, total_blks,
3474 &free_blks, fat_blks,
3475 fd, DiskFAT, DiskHdr, mkdir_name);
3476 break;
3477
3478 case TEST:
3479 printf("\nFAT:\n");
3480 for(i=0 ; i<total_blks; i++) {
3481 switch(GetFatEntry(media_type,DiskFAT,in,i)) {
3482 case 0:
3483 printf(".");
3484 break;
3485 case 1:
3486 printf("E");
3487 break;
3488 default:
3489 printf("#");
3490 }
3491
3492 }
3493 printf("\n");
3494 exit(0);
3495
3496 }
3497
3498 // Close file-pointers if needed
3499 if(in != NULL) fclose(in);
3500 if(fd != -1) close(fd);
3501
3502 // Print the DirectoryList - Uses 'original' filename (not tmp :-)
3503 PrintDir(Efe, mode, process_efe, argv[optind], media_type, DiskLabel,
3504 free_blks, (total_blks - free_blks - fat_blks - 5));
3505
3506 exit(OK);
3507}