1 /*
2 * BIN to NEWBRAIN .BAS file
3 *
4 * Stefano Bodrato 4/2007
5 *
6 * $Id: newbrain.c,v 1.8 2016-06-26 00:46:55 aralbrec Exp $
7 */
8
9 #include "appmake.h"
10
11 static char *binname = NULL;
12 static char *crtfile = NULL;
13 static char *outfile = NULL;
14 static char *blockname = NULL;
15 static int origin = -1;
16 static char ascii = 0;
17 static char help = 0;
18
19 /* Options that are available for this module */
20 option_t newbrain_options[] = {
21 { 'h', "help", "Display this help", OPT_BOOL, &help},
22 { 'b', "binfile", "Linked binary file", OPT_STR, &binname },
23 { 'c', "crt0file", "crt0 file used in linking", OPT_STR, &crtfile },
24 { 'o', "output", "Name of output file", OPT_STR, &outfile },
25 { 'a', "ascii", "Generate a BASIC loader in plain text", OPT_BOOL, &outfile },
26 { 0 , "blockname", "Name of the binary block in tape", OPT_STR, &blockname},
27 { 0 , "org", "Origin of the binary", OPT_INT, &origin },
28 { 0, NULL, NULL, OPT_NONE, NULL }
29 };
30
31
32 int newbrain_exec()
33 {
34 char filename[FILENAME_MAX+1];
35 FILE *fpin, *fpout, *fpout2;
36 int pos;
37
38 int c;
39 int i,p,l,b;
40 int len;
41 int lnum;
42
43 unsigned long checksum;
44
45
46 if ( help || binname == NULL || ( crtfile == NULL && origin == -1 ) ) {
mtx_bit(FILE * fpout,unsigned char bit)47 return -1;
48 }
49
50 if ( blockname == NULL ) blockname = zbasename(binname);
51
52 if ( outfile == NULL ) {
53 strcpy(filename,binname);
54 suffix_change(filename,".txt");
55 } else {
56 strcpy(filename,outfile);
57 }
58
59
60 if ( origin != -1 ) {
61 pos = origin;
62 } else {
63 if ( (pos = get_org_addr(crtfile)) == -1 ) {
64 exit_log(1,"Could not find parameter ZORG (not z88dk compiled?)\n");
65 }
66 }
67
68
69 if ( (fpin=fopen_bin(binname, crtfile) ) == NULL ) {
70 exit_log(1,"Can't open input file %s\n",binname);
71 }
72
73
mtx_rawout(FILE * fpout,unsigned char b)74 /*
75 * Now we try to determine the size of the file
76 * to be converted
77 */
78 if (fseek(fpin,0,SEEK_END)) {
79 fclose(fpin);
80 exit_log(1,"Couldn't determine size of file\n");
81 }
82
83 len=ftell(fpin);
84
mtx_leader(FILE * fpout)85
86 fseek(fpin,0L,SEEK_SET);
87
88
89 if ( ascii ) {
90
91 /* All in a BASIC program */
92
93 if ( (fpout=fopen(filename,"w") ) == NULL ) {
94 exit_log(1,"Can't open output text format file %s\n",filename);
95 }
96
97 fprintf(fpout,"10 IF TOP>%i THEN RESERVE TOP-%i\n",pos-1,pos-1);
98 fprintf(fpout,"20 FOR i=0TO%i:READa:POKE%i+i,a:NEXT i\n",len-1,pos);
99 fprintf(fpout,"30 CALL%i\n",pos);
100 fprintf(fpout,"40 END\n");
101 lnum=100;
102 /* ... M/C ...*/
103 for (i=0; i<len;i++) {
mtx_exec(char * target)104 if ((i % 60) == 0) {
105 fprintf(fpout,"\n");
106 fprintf(fpout,"%i DATA ",lnum);
107 lnum=lnum+2;
108 }
109 else
110 fputc(',',fpout);
111 c=getc(fpin);
112 fprintf(fpout,"%i",c);
113 }
114 fprintf(fpout,"\n");
115
116 fclose(fpin);
117 fclose(fpout);
118
119 }
120 else /* Much more efficient LOADER */
121 {
122
123 /* binary block */
124
125 suffix_change(filename,".dat");
126
127 if ( (fpout2=fopen(filename,"wb") ) == NULL ) {
128 exit_log(1,"Can't open output dat Binary file %s\n",filename);
129 }
130
131 checksum=0x3b; /* Init checksum */
132 fputc (0,fpout2);
133 writeword_cksum(strlen(blockname), fpout2, &checksum);
134 for (i=0; i<strlen(blockname); i++) {
135 fputc (blockname[i],fpout2);
136 checksum += blockname[i];
137 }
138 writebyte_cksum(0x81, fpout2, &checksum);
139 writeword((checksum%65536),fpout2); /* name checksum */
140
141 /* Block */
142 for (b=0; b<=(len/1024); b++) {
143
144 for (i=0; i<10;i++) /* block leading zeroes */
145 fputc (0,fpout2);
146
147 checksum=0x3b; /* Init checksum */
148
149 p = (b * 1024) + 1024 -1; /* set the pointer at the end of the block */
150 l = 1024;
151
152 if ( p > (len - 1) ) { /* is last block smaller ? */
153 p = len - 1;
154 l = len - (b * 1024);
155 }
156
157 /* Block length*/
158 writeword_cksum(l, fpout2, &checksum);
159
160 for (i=p; i>(p-l); i--) {
161 fseek(fpin, i, SEEK_SET);
162 c = getc(fpin);
163 writebyte_cksum(c, fpout2, &checksum);
164 }
165
166 writebyte_cksum(b+1, fpout2, &checksum);
167 writeword((checksum%65536), fpout2);
168 }
169
170 for (i=0; i<9;i++) /* tail */
171 fputc (0,fpout2);
172
173 fclose(fpin);
174 fclose(fpout2);
175
176
177
178 /* TEMP BASIC loader */
179
180 suffix_change(filename,".tmp");
181
182 if ( (fpout=fopen(filename,"wb") ) == NULL ) {
183 exit_log(1,"Can't open temp output file %s\n",filename);
184 }
185
186 fputc(0x0d,fpout);
187
188 fprintf(fpout,"10 ");
189 fputc(0xAC,fpout); /* RESERVE */
190 fputc(0xA8,fpout); /* TOP */
191 fputc(0x82,fpout); /* - */
192 fprintf(fpout,"%i",pos); /* memory location */
193 fputc(0x0d,fpout);
194
195 fprintf(fpout,"20 ");
196 fputc('b',fpout);
197 fputc(0x8c,fpout); /* = */
198 fprintf(fpout,"121:"); /* 121 */
199 fputc(0x89,fpout); /* IF */
200 fputc(0xa4,fpout); /* PEEK */
201 fprintf(fpout,"(51)");
202 fputc(0x8d,fpout); /* > */
203 fprintf(fpout,"127");
204 fputc(0xb4,fpout); /* THEN */
205 fprintf(fpout,"b");
206 fputc(0x8c,fpout); /* = */
207 fputc(0xa4,fpout); /* PEEK */
208 fprintf(fpout,"(168)");
209 fputc(0x81,fpout); /* + */
210 fprintf(fpout,"256");
211 fputc(0x83,fpout); /* * */
212 fputc(0xa4,fpout); /* PEEK */
213 fprintf(fpout,"(169):");
214 fputc(0x9e,fpout); /* POKE */
215 fprintf(fpout,"169,");
216 fputc(0x96,fpout); /* INT */
217 fprintf(fpout,"((b");
218 fputc(0x81,fpout); /* + */
219 fprintf(fpout,"23)");
220 fputc(0x84,fpout); /* / */
221 fprintf(fpout,"256):");
222 fputc(0x9e,fpout); /* POKE */
223 fprintf(fpout,"168,b");
224 fputc(0x81,fpout); /* + */
225 fprintf(fpout,"23");
226 fputc(0x82,fpout); /* - */
227 fprintf(fpout,"256");
228 fputc(0x83,fpout); /* * */
229 fputc(0xa4,fpout); /* PEEK */
230 fprintf(fpout,"(169)");
231 fputc(0x0d,fpout);
232
233 fprintf(fpout,"30 ");
234 fputc(0x8b,fpout); /* FOR */
235 fprintf(fpout," i ");
236 fputc(0x8c,fpout); /* = */
237 fprintf(fpout," 0 ");
238 fputc(0xb6,fpout); /* TO */
239 fprintf(fpout," 22:");
240 fputc(0x9c,fpout); /* READ */
241 fprintf(fpout," c:");
242 fputc(0x9e,fpout); /* POKE */
243 fprintf(fpout," b");
244 fputc(0x81,fpout); /* + */
245 fprintf(fpout,"i,c:");
246 fputc(0x8c,fpout); /* NEXT */
247 fprintf(fpout," i:");
248 fputc(0x9d,fpout); /* DATA */
249 fprintf(fpout," 253,110,32,253,102,33,22,0,30,1,1,");
250 fprintf(fpout,"%i",len%256); /* LSB for Length */
251 fputc(',',fpout);
252 fprintf(fpout,"%i",len/256); /* MSB for Length */
253 fprintf(fpout,",231,49,119,35,11,120,177,200,24,246");
254 fputc(0x0d,fpout);
255
256 fprintf(fpout,"40 ");
257 fputc(0x97,fpout); /* OPEN */
258 /* fputc(' ',fpout); */
259 fputc(0xb3,fpout); /* # */
260 fprintf(fpout,"1,");
261 fputc('"',fpout);
262 fprintf(fpout,"%s",blockname);
263 fputc('"',fpout);
264 fputc(0x0d,fpout);
265
266 fprintf(fpout,"50 ");
267 fputc(0x9f,fpout); /* CALL */
268 fprintf(fpout," b : ");
269 fputc(0x9f,fpout); /* CALL */
270 fprintf(fpout," %i",pos);
271 fputc(0x0d,fpout);
272
273 fputc(0x04,fpout);
274 fputc(0x0d,fpout);
275 fclose(fpout);
276
277
278
279 /* Now convert in tape format */
280
281 if ( (fpin=fopen(filename,"rb") ) == NULL ) {
282 exit_log(1,"Can't read temp file%s\n",binname);
283 }
284
285 if (fseek(fpin,0,SEEK_END)) {
286 fclose(fpin);
287 exit_log(1,"Couldn't determine size of temp file\n");
288 }
289
290 len=ftell(fpin);
291
292 suffix_change(filename,".bas");
293
294 if ( (fpout2=fopen(filename,"wb") ) == NULL ) {
295 exit_log(1,"Can't open output BASIC Binary file %s\n",filename);
296 }
297
298 /* header for binary block */
299
300 checksum=0x3b; /* Init checksum */
301
302 fputc (0,fpout2);
303 writeword_cksum(strlen(filename), fpout2, &checksum);
304 for (i=0; i<strlen(filename); i++) {
305 fputc (filename[i],fpout2); /* +1 ?? */
306 checksum += filename[i];
307 }
308 writebyte_cksum(0x81, fpout2, &checksum);
309 writeword((checksum%65536),fpout2); /* name checksum */
310
311 for (i=0; i<10;i++) /* zero filling the next part */
312 fputc (0,fpout2);
313
314 checksum=0x3b; /* Init checksum */
315
316 /* Block length*/
317 writeword_cksum(len, fpout2, &checksum);
318
319 /* Block */
320 for (i=len-1; i>=0; i--) {
321 fseek(fpin, i, SEEK_SET);
322 c=getc(fpin);
323 writebyte_cksum(c, fpout2, &checksum);
324 }
325
326 writebyte_cksum(0x41, fpout2, &checksum);
327
328 writeword((checksum%65536),fpout2); /* block checksum */
329 for (i=0; i<9;i++) /* tail */
330 fputc (0,fpout2);
331
332 fclose(fpin);
333 fclose(fpout2);
334
335
336 /* TAPE directory */
337
338 if ( (fpout=fopen("_dir.txt","w") ) == NULL ) {
339 exit_log(1,"Can't open output text format file %s\n",filename);
340 }
341 fprintf(fpout,"%s\n",filename);
342 suffix_change(filename,".dat");
343 fprintf(fpout,"%s\n",filename);
344 fclose(fpout);
345
346 suffix_change(filename,".tmp");
347 remove(filename);
348
349 }
350 return 0;
351 }
352