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