1 /*
2 * CCE MMC-1000 BIN to CAS file converter and WAV generator
3 *
4 * $Id: mc.c $
5 */
6
7 #include "appmake.h"
8
9
10 static char *binname = NULL;
11 static char *crtfile = NULL;
12 static char *outfile = NULL;
13 static char *blockname = NULL;
14 static int origin = -1;
15 static char help = 0;
16 static char audio = 0;
17 static char fast = 0;
18 static char khz_22 = 0;
19
20
21 /* Options that are available for this module */
22 option_t mc_options[] = {
23 { 'h', "help", "Display this help", OPT_BOOL, &help},
24 { 'b', "binfile", "Linked binary file", OPT_STR, &binname },
25 { 'c', "crt0file", "crt0 file used in linking", OPT_STR, &crtfile },
26 { 'o', "output", "Name of output file", OPT_STR, &outfile },
27 { 0, "audio", "Create also a WAV file", OPT_BOOL, &audio },
28 { 0, "fast", "Fast loading WAV trick for MESS emulator", OPT_BOOL, &fast },
29 { 0, "22", "22050hz bitrate option", OPT_BOOL, &khz_22 },
30 // { 0, "dumb", "Just convert to WAV a tape file", OPT_BOOL, &dumb },
31 { 0 , "org", "Origin of the binary", OPT_INT, &origin },
32 { 0 , "blockname", "Name of the code block", OPT_STR, &blockname},
33 { 0 , NULL, NULL, OPT_NONE, NULL }
34 };
35
mc_bit(FILE * fpout,unsigned char bit)36 void mc_bit(FILE* fpout, unsigned char bit)
37 {
38 int period1, period0;
39
40 if (fast) {
41 // We're just guessing, no test on the real harware has been done
42 period0 = 27;
43 period1 = 14;
44 } else {
45 period0 = 31;
46 period1 = 16;
47 }
48
49 if (bit) {
50 /* '1' */
51 zx_rawbit(fpout, period1);
52 } else {
53 /* '0' */
54 zx_rawbit(fpout, period0);
55 }
56 }
57
mc_rawout(FILE * fpout,unsigned char b)58 void mc_rawout(FILE* fpout, unsigned char b)
59 {
60 static unsigned char c[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
61 int i, parity;
62
63 parity = 1;
64
65 /* start bit */
66 mc_bit(fpout, 1);
67
68 /* byte */
69 for (i = 0; i < 8; i++) {
70 mc_bit(fpout, b & c[i]);
71 if (b & c[i])
72 parity++;
73 }
74
75 /* parity bit */
76 mc_bit(fpout, parity & 1);
77 }
78
mc_exec(char * target)79 int mc_exec(char* target)
80 {
81 char filename[FILENAME_MAX + 1];
82 char wavfile[FILENAME_MAX + 1];
83 char name[18];
84 FILE *fpin, *fpout;
85 int c;
86 int i;
87 int len, hdlen;
88 unsigned short startaddr;
89 unsigned short endaddr;
90
91 if (help)
92 return -1;
93
94 if (binname == NULL) {
95 return -1;
96 }
97
98 if (origin == -1)
99 if ((origin = get_org_addr(crtfile)) == -1) {
100 exit_log(1,"Could not find parameter ZORG (not z88dk compiled?)\n");
101 }
102
103 if (outfile == NULL) {
104 strcpy(filename, binname);
105 suffix_change(filename, ".cas");
106 } else {
107 strcpy(filename, outfile);
108 }
109
110 if (blockname == NULL)
111 blockname = " \0";
112
113 if ((fpin = fopen_bin(binname, crtfile)) == NULL) {
114 exit_log(1, "Can't open input file %s\n", binname);
115 }
116
117 /*
118 * Now we try to determine the size of the file
119 * to be converted
120 */
121 if (fseek(fpin, 0, SEEK_END)) {
122 fclose(fpin);
123 exit_log(1, "Couldn't determine size of file\n");
124 }
125
126 len = ftell(fpin);
127 fseek(fpin, 0, SEEK_SET);
128
129 if ((fpout = fopen(filename, "wb")) == NULL) {
130 fclose(fpin);
131 exit_log(1,"Can't open output file\n");
132 }
133
134 if (origin != 0x200) {
135 /* Deal with the filename */
136 if (strlen(blockname) > 14) {
137 strncpy(name, blockname, 14);
138 } else {
139 strcpy(name, blockname);
140 }
141 for (i = 0; i < (strlen(name)); i++)
142 fputc(toupper(name[i]), fpout);
143 if (strlen(blockname) <= 14)
144 fputc(13, fpout);
145 } else {
146 /* TLOAD ignores the file name, so
147 * let's shorten it as much as possible */
148 fputc(13, fpout);
149 }
150
151 startaddr = origin;
152 endaddr = origin + len;
153
154 writeword(startaddr, fpout);
155 writeword(endaddr, fpout);
156
157 for (i = 0; i < len; i++) {
158 c = getc(fpin);
159 fputc(c, fpout);
160 }
161
162 /* end address */
163 fputc(255, fpout);
164
165 fclose(fpin);
166 fclose(fpout);
167
168 /* ***************************************** */
169 /* Now, if requested, create the audio file */
170 /* ***************************************** */
171 if ((audio) || (fast) || (khz_22)) {
172 if ((fpin = fopen(filename, "rb")) == NULL) {
173 exit_log(1, "Can't open file %s for wave conversion\n", filename);
174 }
175
176 if (fseek(fpin, 0, SEEK_END)) {
177 fclose(fpin);
178 exit_log(1,"Couldn't determine size of file\n");
179 }
180 len = ftell(fpin);
181 fseek(fpin, 0L, SEEK_SET);
182
183 strcpy(wavfile, filename);
184 suffix_change(wavfile, ".RAW");
185 if ((fpout = fopen(wavfile, "wb")) == NULL) {
186 exit_log(1, "Can't open output raw audio file %s\n", wavfile);
187 }
188
189 /* preamble + leadin + type + name + string termination */
190 //hdlen=128 + 5 + 1 + strlen(name) + 1;
191
192 /* leading silence */
193 for (i = 0; i < 0x5000; i++)
194 fputc(0x80, fpout);
195
196 /* headinf tones */
197 for (i = 0; i < 4096; i++)
198 mc_bit(fpout, 1);
199 for (i = 0; i < 256; i++)
200 mc_bit(fpout, 0);
201
202 hdlen = 0;
203
204 /* filename */
205 c = 0;
206 while ((c != 13) && (hdlen < 14)) {
207 c = getc(fpin);
208 mc_rawout(fpout, c);
209 hdlen++;
210 }
211
212 /* start+end locations */
213 for (i = 0; i < 4; i++) {
214 c = getc(fpin);
215 mc_rawout(fpout, c);
216 }
217 hdlen += 4;
218
219 /* start addr + end addr + program block */
220 for (i = 0; (i < (len - hdlen)); i++) {
221 c = getc(fpin);
222 mc_rawout(fpout, c);
223 }
224
225 /* trailing silence */
226 for (i = 0; i < 0x1500; i++)
227 fputc(0x80, fpout);
228
229 fclose(fpin);
230 fclose(fpout);
231
232 /* Now let's think at the WAV format */
233 if (khz_22)
234 raw2wav_22k(wavfile,2);
235 else
236 raw2wav(wavfile);
237 }
238
239 return 0;
240 }
241