Rev 922 | Details | Compare with Previous | Last modification | View Log
Rev | Author | Line No. | Line |
---|---|---|---|
8 | dimkam | 1 | #include <stdio.h> |
2 | #include <stdlib.h> |
||
930 | alone | 3 | //#include <mem.h> |
8 | dimkam | 4 | #include <string.h> |
5 | |||
6 | #define BYTE unsigned char |
||
7 | #define BOOL unsigned char |
||
8 | #define FALSE 0x00 |
||
9 | #define TRUE 0xff |
||
10 | #define TRDSIZE 655360 |
||
113 | alone | 11 | #define BLOCKSIZE 65280/*32768*/ |
8 | dimkam | 12 | #define DESCSIZE 16 |
13 | |||
457 | demige | 14 | BYTE trd[10000000]; |
8 | dimkam | 15 | BYTE filebuf[TRDSIZE]; |
16 | BYTE descbuf[DESCSIZE+1]; //for hobeta |
||
17 | |||
18 | const BYTE trdheader[0x20] = { |
||
19 | 0x00,0x00,0x01,0x16,0x00,0xf0,0x09,0x10, 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20, |
||
20 | 0x20,0x20,0x20,0x00,0x00,0x20,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00 |
||
21 | }; |
||
22 | |||
23 | BOOL verbose; |
||
24 | BOOL ishobeta; |
||
25 | |||
26 | int readtrd(char * trdname) |
||
27 | { |
||
28 | FILE* file; |
||
29 | int result; |
||
30 | file = fopen(trdname, "rb"); |
||
31 | if (file) { |
||
32 | if (verbose) {printf("opened trd: %s\n",trdname); }; |
||
33 | fread(trd, 1, TRDSIZE, file); |
||
34 | fclose(file); |
||
35 | result = 1; |
||
36 | }else { |
||
37 | printf("trd not found: %s\n",trdname); |
||
38 | result = 0; |
||
39 | }; |
||
40 | return result; |
||
41 | } |
||
42 | |||
43 | void writetrd(char * trdname) |
||
44 | { |
||
45 | FILE* file; |
||
46 | file = fopen(trdname, "wb"); |
||
47 | if (file) { |
||
48 | fwrite(trd, 1, TRDSIZE, file); |
||
49 | fclose(file); |
||
50 | }; |
||
51 | } |
||
52 | |||
53 | void genname(char * filename) |
||
54 | { |
||
55 | int i; |
||
56 | int j; |
||
57 | char c; |
||
58 | j = 0; |
||
59 | while (j<9) { |
||
60 | descbuf[j] = ' '; |
||
61 | j++; |
||
62 | }; |
||
63 | descbuf[9] = 0x00; |
||
64 | descbuf[10] = 0x00; |
||
65 | //find last backslash |
||
66 | i = 0; |
||
67 | j = 0; |
||
68 | while (filename[i] != '\0') { |
||
69 | if ((filename[i] == '\\') || (filename[i] == '/')) j = i + 1; //after backslash |
||
70 | i++; |
||
71 | }; |
||
72 | i = j; //after last backslash |
||
73 | //copy to descbuf: [i] => [j] |
||
74 | j = 0; |
||
75 | while (j<9) { |
||
76 | c = filename[i]; if (c=='\0') break; |
||
77 | i++; |
||
78 | if (c=='.') { |
||
79 | c = filename[i]; if (c=='\0') break; |
||
80 | if (ishobeta) if (c=='$') i++; |
||
81 | c = filename[i]; if (c=='\0') break; |
||
82 | i++; |
||
83 | descbuf[8] = c; |
||
84 | c = filename[i]; if (c=='\0') break; |
||
85 | i++; |
||
86 | descbuf[9] = c; |
||
87 | c = filename[i]; if (c=='\0') break; |
||
88 | i++; |
||
89 | descbuf[10] = c; |
||
90 | break; |
||
91 | }; |
||
92 | descbuf[j] = c; |
||
93 | j++; |
||
94 | }; |
||
95 | } |
||
96 | |||
97 | long finddesc(int namelen, int ignorereg) //return descriptor address or -1 if not found |
||
98 | { |
||
99 | long descaddr; |
||
100 | long result; |
||
101 | int i; |
||
102 | BYTE err; |
||
103 | result = -1; |
||
104 | descaddr = 0; |
||
105 | while (trd[descaddr] != 0) { |
||
106 | err = 0; |
||
107 | i = 0; |
||
108 | while (i < namelen) { //name, ext, block |
||
109 | if (ignorereg) { |
||
110 | err = err | ( ((BYTE)trd[descaddr+i]|(BYTE)0x20) ^ ((BYTE)descbuf[i]|(BYTE)0x20) ); |
||
111 | }else { |
||
112 | err = err | (trd[descaddr+i]^descbuf[i]); |
||
113 | }; |
||
114 | i++; |
||
115 | }; |
||
116 | if (err == 0) { |
||
117 | result = descaddr; |
||
118 | break; |
||
119 | }; |
||
120 | descaddr = descaddr + DESCSIZE; |
||
121 | }; |
||
122 | /** if (result == -1) printf("\"%c%c%c%c%c%c%c%c.%c\" not found\n", |
||
123 | descbuf[0], |
||
124 | descbuf[1], |
||
125 | descbuf[2], |
||
126 | descbuf[3], |
||
127 | descbuf[4], |
||
128 | descbuf[5], |
||
129 | descbuf[6], |
||
130 | descbuf[7], |
||
131 | descbuf[8] |
||
132 | );*/ |
||
133 | return result; |
||
134 | } |
||
135 | |||
136 | void extractfile(char * trdname, char * filename) |
||
137 | { |
||
138 | FILE* fout; |
||
139 | int descaddr; |
||
140 | int addr; //in sectors |
||
141 | BYTE block; |
||
142 | int wrsize; |
||
143 | if (readtrd(trdname)) { |
||
144 | fout = fopen(filename, "wb"); |
||
145 | if (fout) { |
||
146 | genname(filename); |
||
147 | |||
148 | block = 0; |
||
149 | do { |
||
150 | //descbuf[9] = block; |
||
151 | descaddr = finddesc(10, 0); //name, ext, block |
||
152 | wrsize = 0; |
||
153 | if (descaddr != -1) { |
||
154 | wrsize = trd[descaddr+11] + trd[descaddr+12]*256; |
||
155 | addr = trd[descaddr+14] + trd[descaddr+15]*16; |
||
156 | block++; |
||
157 | descbuf[9] = (BYTE)descbuf[9]+(BYTE)0x01; |
||
158 | }; |
||
159 | if (wrsize != 0) { |
||
160 | fwrite(trd+(addr<<8), 1, wrsize, fout); |
||
161 | }; |
||
162 | }while (wrsize != 0); |
||
163 | |||
164 | if (block == 0) { |
||
165 | printf("%s not found\n",filename); |
||
166 | }else { |
||
167 | printf("extracted %s\n",filename); |
||
168 | }; |
||
169 | |||
170 | fclose(fout); |
||
171 | }; |
||
172 | }; |
||
173 | } |
||
174 | |||
175 | void extractbinary(char * trdname, char * filename) |
||
176 | { |
||
177 | FILE* fout; |
||
178 | int descaddr; |
||
179 | int addr; //in sectors |
||
180 | int wrsize; |
||
181 | if (readtrd(trdname)) { |
||
182 | fout = fopen(filename, "wb"); |
||
183 | if (fout) { |
||
184 | genname(filename); |
||
185 | |||
186 | descaddr = finddesc(9, 0); //name, ext, block |
||
187 | wrsize = 0; |
||
188 | if (descaddr != -1) { |
||
189 | wrsize = trd[descaddr+11] + trd[descaddr+12]*256; |
||
190 | addr = trd[descaddr+14] + trd[descaddr+15]*16; |
||
191 | printf("extracted %s\n",filename); |
||
192 | }else { |
||
193 | printf("%s not found\n",filename); |
||
194 | }; |
||
195 | if (wrsize != 0) { |
||
196 | fwrite(trd+(addr<<8), 1, wrsize, fout); |
||
197 | }; |
||
198 | |||
199 | fclose(fout); |
||
200 | }; |
||
201 | }; |
||
202 | } |
||
203 | |||
204 | void extracthobeta(char * trdname, char * filename) |
||
205 | { |
||
206 | FILE* fout; |
||
207 | int descaddr; |
||
208 | int addr; //in sectors |
||
209 | int wrsize; |
||
210 | unsigned int checksum; |
||
211 | int i; |
||
212 | if (readtrd(trdname)) { |
||
213 | fout = fopen(filename, "wb"); |
||
214 | if (fout) { |
||
215 | genname(filename); |
||
216 | /** |
||
217 | p 13 - p . |
||
218 | p; .. p 256, p , p - |
||
219 | p. - p . |
||
220 | p - p p 15 , |
||
221 | 257 p ___0__14 .. 105. |
||
222 | pp Z80 Asm: |
||
223 | ; de = p |
||
224 | ld hl,0 |
||
225 | ld b,15 |
||
226 | m1: ld a,(de) |
||
227 | add a,l |
||
228 | ld l,a |
||
229 | jr nc,m2 |
||
230 | inc h |
||
231 | m2: inc de |
||
232 | djnz m1 |
||
233 | add a,h |
||
234 | ld h,a |
||
235 | ld c,105 |
||
236 | add hl,bc ; hl = Hobeta sum |
||
237 | */ |
||
238 | descaddr = finddesc(9, 1); //name, ext |
||
239 | if (descaddr != -1) { |
||
240 | memcpy(descbuf, trd+descaddr, DESCSIZE); //descriptor |
||
241 | wrsize = trd[descaddr+13]*256; |
||
242 | addr = trd[descaddr+14] + trd[descaddr+15]*16; |
||
243 | descbuf[14] = descbuf[13]; |
||
244 | descbuf[13] = 0; |
||
245 | for (i=0; i<=14; checksum = checksum + (descbuf[i] * 257) + i, i++); |
||
246 | descbuf[15] = (BYTE)checksum; |
||
247 | descbuf[16] = (BYTE)(checksum>>8); |
||
248 | fwrite(descbuf, 1, 17, fout); |
||
249 | fwrite(trd+(addr<<8), 1, wrsize, fout); |
||
250 | printf("extracted %s\n",filename); |
||
251 | }else { |
||
252 | printf("%s not found\n",filename); |
||
253 | }; |
||
254 | |||
255 | fclose(fout); |
||
256 | }; |
||
257 | }; |
||
258 | } |
||
259 | |||
260 | void addfile(char * trdname, char * filename, int iscode, int startaddr) |
||
261 | { |
||
262 | FILE* fin; |
||
263 | long descaddr; |
||
264 | long addr; //in sectors |
||
265 | long size; |
||
266 | long wrsize; |
||
267 | long secsize; |
||
268 | long index; |
||
269 | long free; |
||
270 | BYTE block; |
||
271 | long maxsize; |
||
272 | if (readtrd(trdname)) { |
||
273 | fin = fopen(filename, "rb"); |
||
274 | if (fin) { |
||
275 | size = fread(filebuf, 1, TRDSIZE, fin); |
||
276 | |||
277 | genname(filename); |
||
278 | if (iscode) { |
||
279 | descbuf[8] = 'C'; |
||
280 | maxsize = 65280; |
||
281 | }else { |
||
282 | maxsize = BLOCKSIZE; |
||
283 | }; |
||
284 | |||
285 | index = 0; |
||
286 | if (iscode) { |
||
287 | block = (BYTE)startaddr; |
||
288 | }else { |
||
289 | block = descbuf[9]; |
||
290 | }; |
||
291 | while (size > 0) { |
||
292 | |||
293 | if (size > maxsize) { |
||
294 | wrsize = maxsize; |
||
295 | }else { |
||
296 | wrsize = size; |
||
297 | }; |
||
298 | descbuf[9] = block; |
||
299 | if (iscode) { |
||
300 | descbuf[10] = (BYTE)(startaddr>>8); |
||
301 | }; |
||
302 | descbuf[11] = (BYTE)wrsize; |
||
303 | descbuf[12] = (BYTE)(wrsize>>8); |
||
304 | secsize = (wrsize+255)>>8; |
||
305 | descbuf[13] = (BYTE)secsize; |
||
306 | |||
307 | addr = trd[0x08e1] + (((long)trd[0x08e2])<<4); //first free sector, track |
||
308 | memcpy(trd+(addr<<8), filebuf+index, wrsize); //data |
||
309 | descbuf[14] = (BYTE)(addr&0x0f); //sector |
||
310 | descbuf[15] = (BYTE)(addr>>4); //track |
||
311 | addr = addr + secsize; |
||
312 | trd[0x08e1] = (BYTE)(addr&0x0f); //first free sector |
||
313 | trd[0x08e2] = (BYTE)(addr>>4); //first free track |
||
314 | |||
315 | descaddr = ((long)trd[0x08e4])<<4; //files |
||
316 | trd[0x08e4]++; //files |
||
317 | free = trd[0x08e5] + 256*trd[0x08e6]; //free |
||
318 | free = free - secsize; |
||
319 | trd[0x08e5] = (BYTE)free; |
||
320 | trd[0x08e6] = (BYTE)(free>>8); |
||
321 | |||
322 | memcpy(trd+descaddr, descbuf, DESCSIZE); //descriptor |
||
323 | |||
324 | size = size - maxsize; |
||
325 | index = index + maxsize; |
||
326 | block++; |
||
327 | }; |
||
328 | fclose(fin); |
||
329 | }; |
||
330 | writetrd(trdname); |
||
331 | }; |
||
332 | } |
||
333 | |||
334 | void addhobeta(char * trdname, char * filename) |
||
335 | { |
||
336 | FILE* fin; |
||
337 | long descaddr; |
||
338 | long addr; //in sectors |
||
339 | long size; |
||
340 | long wrsize; |
||
341 | long secsize; |
||
342 | long index; |
||
343 | long free; |
||
344 | int i; |
||
345 | if (readtrd(trdname)) { |
||
346 | fin = fopen(filename, "rb"); |
||
347 | if (fin) { |
||
348 | size = fread(filebuf, 1, TRDSIZE, fin); |
||
349 | if (size >= 17) { |
||
350 | wrsize = size - 17; |
||
351 | index = 17; |
||
352 | |||
353 | i = 0; |
||
354 | while (i<13) { |
||
355 | descbuf[i] = filebuf[i]; |
||
356 | i++; |
||
357 | }; |
||
358 | secsize = filebuf[14]; |
||
359 | descbuf[13] = (BYTE)secsize; |
||
360 | |||
361 | addr = trd[0x08e1] + (((long)trd[0x08e2])<<4); //first free sector, track |
||
362 | memcpy(trd+(addr<<8), filebuf+index, wrsize); //data |
||
363 | descbuf[14] = (BYTE)(addr&0x0f); //sector |
||
364 | descbuf[15] = (BYTE)(addr>>4); //track |
||
365 | addr = addr + secsize; |
||
366 | trd[0x08e1] = (BYTE)(addr&0x0f); //first free sector |
||
367 | trd[0x08e2] = (BYTE)(addr>>4); //first free track |
||
368 | |||
369 | descaddr = ((long)trd[0x08e4])<<4; //files |
||
370 | trd[0x08e4]++; //files |
||
371 | free = trd[0x08e5] + 256*trd[0x08e6]; //free |
||
372 | free = free - secsize; |
||
373 | trd[0x08e5] = (BYTE)free; |
||
374 | trd[0x08e6] = (BYTE)(free>>8); |
||
375 | |||
376 | memcpy(trd+descaddr, descbuf, DESCSIZE); //descriptor |
||
377 | }; |
||
378 | fclose(fin); |
||
379 | }; |
||
380 | writetrd(trdname); |
||
381 | }; |
||
382 | } |
||
383 | |||
384 | void newtrd(char * trdname) |
||
385 | { |
||
386 | memset(trd, 0x00, TRDSIZE); |
||
387 | memcpy(trd+0x08e0, trdheader, 0x0020); |
||
388 | writetrd(trdname); |
||
389 | } |
||
390 | |||
391 | int main(int argc,char* argv[]) |
||
392 | { |
||
393 | int i; |
||
394 | int startaddr; |
||
395 | char *trdname; |
||
396 | char *filename; |
||
397 | startaddr = 24576; |
||
398 | trdname = "test.trd"; |
||
399 | verbose = FALSE; |
||
400 | |||
401 | if (argc<2) { |
||
402 | printf( |
||
403 | "NedoTRD\n" |
||
404 | "add partitioned file:\n" |
||
405 | "\tnedotrd.exe trdname.trd -a file.f\n" |
||
406 | "add code file with default start address (24576):\n" |
||
407 | "\tnedotrd.exe trdname.trd -ac file.c\n" |
||
408 | "add code file with start address 32768:\n" |
||
409 | "\tnedotrd.exe trdname.trd -s 32768 -ac file.c\n" |
||
410 | "add hobeta file:\n" |
||
411 | "\tnedotrd.exe trdname.trd -ah file.$b\n" |
||
412 | "extract partitioned file:\n" |
||
413 | "\tnedotrd.exe trdname.trd -e file.f\n" |
||
414 | "extract binary file:\n" |
||
415 | "\tnedotrd.exe trdname.trd -eb file.c\n" |
||
416 | "extract hobeta file:\n" |
||
417 | "\tnedotrd.exe trdname.trd -eh file.$b\n" |
||
418 | "new trd file:\n" |
||
419 | "\tnedotrd.exe trdname.trd -n\n" |
||
420 | "verbose: -v\n" |
||
421 | ); |
||
422 | }; |
||
423 | |||
424 | for (i=1; i<argc; i++) { |
||
425 | ishobeta = FALSE; |
||
426 | if (!strcmp(argv[i],"-a")) { //add |
||
427 | i++; |
||
428 | filename = argv[i]; |
||
429 | addfile(trdname, filename, 0, startaddr); |
||
430 | }else if (!strcmp(argv[i],"-ac")) { //add code |
||
431 | i++; |
||
432 | filename = argv[i]; |
||
433 | addfile(trdname, filename, 1, startaddr); |
||
434 | }else if (!strcmp(argv[i],"-ah")) { //add hobeta |
||
435 | i++; |
||
436 | filename = argv[i]; |
||
437 | ishobeta = TRUE; |
||
438 | addhobeta(trdname, filename); |
||
439 | }else if (!strcmp(argv[i],"-e")) { //extract partitioned |
||
440 | i++; |
||
441 | filename = argv[i]; |
||
442 | extractfile(trdname, filename); |
||
443 | }else if (!strcmp(argv[i],"-eb")) { //extract binary |
||
444 | i++; |
||
445 | filename = argv[i]; |
||
446 | extractbinary(trdname, filename); |
||
447 | }else if (!strcmp(argv[i],"-eh")) { //extract hobeta |
||
448 | i++; |
||
449 | filename = argv[i]; |
||
450 | ishobeta = TRUE; |
||
451 | extracthobeta(trdname, filename); |
||
452 | }else if (!strcmp(argv[i],"-n")) { //new trd |
||
453 | newtrd(trdname); |
||
454 | }else if (!strcmp(argv[i],"-v")) { //verbose |
||
455 | verbose = TRUE; |
||
456 | }else if (!strcmp(argv[i],"-s")) { //use start address |
||
457 | i++; |
||
458 | filename = argv[i]; |
||
459 | startaddr = atoi(filename); |
||
460 | }else { |
||
461 | trdname = argv[i]; |
||
462 | }; |
||
463 | } |
||
464 | return 0; |
||
457 | demige | 465 | } |