1
2 #include "appmake.h"
3
4 #include "ff.h" /* Obtains integer types */
5 #include "diskio.h" /* Declarations of disk functions */
6
7
8 static char *c_binary_name = NULL;
9 static char *c_crt_filename = NULL;
10 static char *c_disc_format = NULL;
11 static char *c_output_file = NULL;
12 static char *c_boot_filename = NULL;
13 static char *c_disc_container = "raw";
14 static char help = 0;
15
16
17
18 /* Options that are available for this module */
19 option_t fat_options[] = {
20 { 'h', "help", "Display this help", OPT_BOOL, &help},
21 { 'f', "format", "Disk format", OPT_STR, &c_disc_format},
22 { 'b', "binfile", "Linked binary file", OPT_STR|OPT_INPUT, &c_binary_name },
23 { 'c', "crt0file", "crt0 file used in linking", OPT_STR, &c_crt_filename },
24 { 'o', "output", "Name of output file", OPT_STR|OPT_OUTPUT, &c_output_file },
25 { 's', "bootfile", "Name of the boot file", OPT_STR, &c_boot_filename },
26 { 0, "container", "Type of container (raw,dsk)", OPT_STR, &c_disc_container },
27 { 0 , NULL, NULL, OPT_NONE, NULL }
28 };
29
30 static disc_spec msxdos_bluemsx_fat12 = {
31 .name = "MSXDOS-F12",
32 .sectors_per_track = 9,
33 .tracks = 80,
34 .sides = 2,
35 .sector_size = 512,
36 .gap3_length = 0x2a,
37 .filler_byte = 0xe5,
38 .boottracks = 0,
39 .directory_entries = 112,
40 .number_of_fats = 2,
41 .cluster_size = 1024,
42 .fat_format_flags = FM_FAT|FM_SFD,
43 .alternate_sides = 0,
44 .first_sector_offset = 1 // Required for .dsk
45 };
46
47 static disc_spec msxdos_takeda_fat12 = {
48 .name = "MSXDOS-F12",
49 .sectors_per_track = 9,
50 .tracks = 80,
51 .sides = 2,
52 .sector_size = 512,
53 .gap3_length = 0x2a,
54 .filler_byte = 0xe5,
55 .boottracks = 0,
56 .directory_entries = 112,
57 .number_of_fats = 2,
58 .cluster_size = 1024,
59 .fat_format_flags = FM_FAT|FM_SFD,
60 .alternate_sides = 1,
61 .first_sector_offset = 1 // Required for .dsk
62 };
63
64
65
66 static struct formats {
67 const char *name;
68 const char *description;
69 disc_spec *spec;
70 size_t bootlen;
71 void *bootsector;
72 char force_com_extension;
73 } formats[] = {
74 { "msxdos", "MSXDOS DSDD", &msxdos_bluemsx_fat12, 0, NULL, 1 },
75 { "msxdos-tak","MSXDOS DSDD (takeda)",&msxdos_takeda_fat12, 0, NULL, 1 },
76 { "msxbasic", "MSXDOS DSDD (BASIC)", &msxdos_bluemsx_fat12, 0, NULL, 0 },
77 { NULL, NULL }
78 };
79
dump_formats()80 static void dump_formats()
81 {
82 struct formats* f = &formats[0];
83
84 printf("Supported FAT formats:\n\n");
85
86 while (f->name) {
87 printf("%-20s%s\n", f->name, f->description);
88 printf("%d tracks, %d sectors/track, %d bytes/sector, %d entries, %d bytes/cluster\n\n", f->spec->tracks, f->spec->sectors_per_track, f->spec->sector_size, f->spec->directory_entries, f->spec->cluster_size);
89 f++;
90 }
91
92 printf("\nSupported containers:\n\n");
93 disc_print_writers(stdout);
94 exit(1);
95 }
96
97
fat_exec(char * target)98 int fat_exec(char *target)
99 {
100 if (help)
101 return -1;
102 if (c_binary_name == NULL) {
103 return -1;
104 }
105 if (c_disc_format == NULL || c_disc_container == NULL ) {
106 dump_formats();
107 return -1;
108 }
109 return fat_write_file_to_image(c_disc_format, c_disc_container, c_output_file, c_binary_name, c_crt_filename, c_boot_filename);
110 }
111
112
fat_write_file_to_image(const char * disc_format,const char * container,const char * output_file,const char * binary_name,const char * crt_filename,const char * boot_filename)113 int fat_write_file_to_image(const char *disc_format, const char *container, const char* output_file, const char* binary_name, const char* crt_filename, const char* boot_filename)
114 {
115 disc_handle *h;
116 char dos_filename[20];
117 struct formats *f = &formats[0];
118 disc_spec *spec = NULL;
119 char disc_name[FILENAME_MAX+1];
120 const char *extension;
121 disc_writer_func writer = disc_get_writer(container, &extension);
122 FILE *binary_fp;
123 size_t binlen;
124 void *filebuf;
125
126
127 while (f->name != NULL) {
128 if (strcasecmp(disc_format, f->name) == 0) {
129 spec = f->spec;
130 break;
131 }
132 f++;
133 }
134 if ( spec == NULL || writer == NULL ) {
135 return -1;
136 }
137
138 if (output_file == NULL) {
139 strcpy(disc_name, binary_name);
140 suffix_change(disc_name, extension);
141 } else {
142 strcpy(disc_name, output_file);
143 }
144
145 cpm_create_filename(binary_name, dos_filename, f->force_com_extension, 1);
146
147 // Open the binary file
148 if ((binary_fp = fopen_bin(binary_name, crt_filename)) == NULL) {
149 exit_log(1, "Can't open input file %s\n", binary_name);
150 }
151 if (fseek(binary_fp, 0, SEEK_END)) {
152 fclose(binary_fp);
153 exit_log(1, "Couldn't determine size of file\n");
154 }
155 binlen = ftell(binary_fp);
156 fseek(binary_fp, 0L, SEEK_SET);
157 filebuf = malloc(binlen);
158 if (1 != fread(filebuf, binlen, 1, binary_fp)) { fclose(binary_fp); exit_log(1, "Could not read required data from <%s>\n",binary_name); }
159 fclose(binary_fp);
160
161 h = fat_create(spec);
162 disc_write_file(h, dos_filename, filebuf, binlen);
163
164 if (writer(h, disc_name) < 0) {
165 exit_log(1, "Can't write disc image");
166 }
167 disc_free(h);
168 return 0;
169 }
170
171
172