Previous 15994 Revisions Next

r8799 Wednesday 18th August, 2010 at 17:20:46 UTC by Sandro Ronco
[IMGTOOL] Added module for Psion Datapack image
[src/mess/tools/imgtool]imgtool.mak modules.c
[src/mess/tools/imgtool/modules]psion.c*

src/mess/tools/imgtool/imgtool.mak
r8798r8799
8080   $(IMGTOOL_MODULES)/thomson.o         \
8181   $(IMGTOOL_MODULES)/macutil.o         \
8282   $(IMGTOOL_MODULES)/cybiko.o         \
83   $(IMGTOOL_MODULES)/cybikoxt.o
83   $(IMGTOOL_MODULES)/cybikoxt.o      \
84   $(IMGTOOL_MODULES)/psion.o      \
8485#   $(IMGTOOLOBJ)/tstsuite.o         \
8586#   $(MESS_FORMATS)/fmsx_cas.o         \
8687#   $(MESS_FORMATS)/svi_cas.o         \
src/mess/tools/imgtool/modules.c
r8798r8799
111111MODULE(thom_sap_basic)
112112MODULE(cybiko)
113113MODULE(cybikoxt)
114MODULE(psion)
114115
115116#endif /* MODULES_RECURSIVE */
src/mess/tools/imgtool/modules/psion.c
r0r8799
1/***************************************************************************
2 
3        Psion Organiser II Datapack
4 
5      08/18/2010 Sandro Ronco
6 
7        Known file types:
8         0x00         invalid record
9         0x01 - 0x7e  deleted record
10         0x7f         invalid deleted record
11         0x80         long record
12         0x81         file name
13         0x82         diary
14         0x83         OPL/OB3 procedure
15         0x84         RS232 setup
16         0x85 - 0x8f  reserved
17         0x90         MAIN Record
18         0x91 - 0xfe  data records from files
19         0xff         invalid record
20 
21****************************************************************************/
22 
23#include "imgtool.h"
24 
25#define MAXFILES 256
26 
27struct psion_file
28{
29   char filename[9];
30   UINT8 type;
31   UINT8 id;
32 
33   UINT16 name_rec;
34   UINT16 data_rec;
35};
36 
37struct psion_pack
38{
39   imgtool_stream *stream;
40 
41   UINT16 eop;
42   struct psion_file pack_index[MAXFILES];
43};
44 
45struct psion_iter
46{
47   UINT16 index;
48};
49 
50UINT16 head_checksum(UINT8* data)
51{
52   UINT16 checksum = 0;
53 
54   for (int i=0; i<6; i+=2)
55      checksum += (data[i]<<8 | data[i+1]);
56 
57   return checksum;
58}
59 
60UINT16 get_long_rec_size(imgtool_stream *stream)
61{
62   UINT8 size_h, size_l;
63 
64   stream_read(stream, &size_h, 1);
65   stream_read(stream, &size_l, 1);
66 
67   return (size_h<<8) | size_l;
68}
69 
70UINT32 update_pack_index(psion_pack *pack)
71{
72   UINT8 data, type;
73   UINT16 size;
74   UINT16 index = 0;
75 
76   memset(pack->pack_index, 0, sizeof(psion_file) * MAXFILES);
77 
78   // start at the first record
79   stream_seek(pack->stream, 0x10, SEEK_SET);
80 
81   do
82   {
83      stream_read(pack->stream, &data, 1);
84 
85      if(data == 0xff)
86      {
87         pack->eop = stream_tell(pack->stream) - 1;
88         return TRUE;
89      }
90      else if (data == 0x02)
91      {
92         // long record without name are ignored
93         stream_read(pack->stream, &data, 1);
94         size = get_long_rec_size(pack->stream);
95         stream_seek(pack->stream, size, SEEK_CUR);
96      }
97      else
98      {
99         stream_read(pack->stream, &type, 1);
100 
101         // deleted record are not listed
102         if (type < 0x90 && (type & 0x80))
103         {
104            pack->pack_index[index].type = type;
105            stream_read(pack->stream, &pack->pack_index[index].filename, 8);
106            stream_read(pack->stream, &pack->pack_index[index].id, 1);
107            pack->pack_index[index].name_rec = stream_tell(pack->stream) - 11;
108 
109            //check for data record
110            stream_read(pack->stream, &data, 1);
111            if (data == 0x02)
112               pack->pack_index[index].data_rec = stream_tell(pack->stream) - 1;
113 
114            stream_seek(pack->stream, -1, SEEK_CUR);
115 
116            index++;
117         }
118         else
119            stream_seek(pack->stream, data, SEEK_CUR);
120      }
121 
122   } while (stream_size(pack->stream) > stream_tell(pack->stream));
123 
124   // corrupted image
125   return FALSE;
126}
127 
128int seek_next_record(imgtool_stream *stream, UINT8 id)
129{
130   UINT8 data, rec_id;
131   UINT16 size;
132 
133   do
134   {
135      stream_read(stream, &data, 1);
136 
137      if(data == 0xff)
138         break;
139 
140      if (data == 2)
141      {
142         stream_read(stream, &rec_id, 1);
143         size = get_long_rec_size(stream);
144 
145      }
146      else
147      {
148         stream_read(stream, &rec_id, 1);
149         if (id == rec_id)
150         {
151            stream_seek(stream, -2, SEEK_CUR);
152            return TRUE;
153         }
154         size = data;
155      }
156 
157      // next record
158      stream_seek(stream, size, SEEK_CUR);
159 
160   } while (stream_size(stream) > stream_tell(stream));
161 
162   return FALSE;
163}
164 
165// if there are multiple files with the same name, only the first is found
166int seek_file_name(psion_pack *pack, const char *filename)
167{
168   UINT16 index = 0;
169 
170   while (pack->pack_index[index].name_rec)
171   {
172      if (!strncmp(filename, pack->pack_index[index].filename, strlen(filename)))
173         return index;
174      index++;
175   }
176 
177   // filename not found
178   return -1;
179}
180 
181UINT8 get_free_file_id(psion_pack *pack)
182{
183   for (UINT8 file_id=0x91; file_id<=0xff; file_id++)
184   {
185      int index = 0;
186 
187      while (pack->pack_index[index].id != file_id)
188         if (pack->pack_index[index++].name_rec == 0)
189            return file_id;
190   }
191 
192   return 0xff;
193}
194 
195void put_name_record(imgtool_stream *stream, const char* filename, UINT8 record_type, UINT8 record_id)
196{
197   char data[0x10];
198   int i = 0;
199 
200   data[i++] = 0x09;
201   data[i++] = record_type;
202 
203   // filename is 8 char long space filled
204   for (int j=0; j<8; j++)
205      if (j < strlen(filename))
206         data[i++] = filename[j];
207      else
208         data[i++] = 0x20;
209 
210   data[i++] = record_id;
211 
212   stream_write(stream, data, i);
213}
214 
215void update_opk_head(imgtool_stream *stream)
216{
217   UINT16 size = stream_size(stream) - 6;
218 
219   stream_seek(stream, 4, SEEK_SET);
220   stream_putc(stream, (size>>8) & 0xff);
221   stream_putc(stream, size & 0xff);
222}
223 
224char *stream_getline(imgtool_stream *source, UINT16 max_len)
225{
226   UINT16 pos = 0;
227   char data;
228   char *line = (char*)malloc(max_len);
229   memset(line, 0, max_len);
230 
231   while (pos < max_len && stream_size(source) > stream_tell(source))
232   {
233      stream_read(source, &data, 1);
234 
235      switch(data)
236      {
237         case '\r':
238            stream_read(source, &data, 1);
239            if (data != '\n')
240               stream_seek(source, -1, SEEK_CUR);
241         case '\n':
242            return line;
243            break;
244         default:
245            line[pos++] = data;
246            break;
247      }
248   }
249 
250   if (pos)
251      return line;
252 
253   free(line);
254   return NULL;
255}
256 
257UINT16 put_odb(imgtool_stream *instream, imgtool_stream *outstream, UINT8 file_id)
258{
259   char *line;
260   UINT16 out_size = 0;
261 
262   // reset stream
263   stream_seek(instream, 0, SEEK_SET);
264 
265   while ((line = stream_getline(instream, 256)))
266   {
267      UINT16 len = strlen(line);
268 
269      stream_putc(outstream, (UINT8)len);
270      stream_putc(outstream, file_id);
271      stream_write(outstream, line, len);
272 
273      out_size += (len + 1);
274 
275      free(line);
276   }
277 
278   // end of pack
279   stream_fill(outstream, 0xff, 2);
280 
281   return out_size + 4;
282}
283 
284UINT16 put_ob3(imgtool_stream *instream, imgtool_stream *outstream)
285{
286   UINT16 size = stream_size(instream) - 6;
287   UINT8 *buffer = (UINT8*)malloc(size);
288 
289   stream_seek(instream, 6, SEEK_SET);
290   stream_read(instream, buffer, size);
291 
292   stream_write(outstream, buffer, size);
293 
294   free(buffer);
295 
296   // end of pack
297   stream_fill(outstream, 0xff, 2);
298 
299   return size;
300}
301 
302UINT16 put_opl(imgtool_stream *instream, imgtool_stream *outstream)
303{
304   UINT16 out_size = 0;
305   UINT32 rec_start = stream_tell(outstream);
306   char *line;
307 
308   // reset stream
309   stream_seek(instream, 0, SEEK_SET);
310 
311   stream_fill(outstream, 0x00, 4);
312 
313   // replace all eol with 0x00
314   while ((line = stream_getline(instream, 256)))
315   {
316      // replace tab with space
317      for (int i=0; i<strlen(line); i++)
318         if (line[i] == '\t') line[i] = ' ';
319 
320      stream_write(outstream, line, strlen(line));
321      stream_putc(outstream, 0x00);
322      out_size += strlen(line) + 1;
323      free(line);
324   }
325 
326   // end of pack
327   stream_fill(outstream, 0xff, 2);
328 
329   // update the size in the head
330   stream_seek(outstream, rec_start + 2, SEEK_SET);
331   stream_putc(outstream, (out_size>>8) & 0xff);
332   stream_putc(outstream, out_size & 0xff);
333 
334   return out_size + 4;
335}
336 
337UINT16 get_odb(imgtool_stream *instream, imgtool_stream *outstream, UINT8 type, UINT8 file_id)
338{
339   UINT8 data, *buffer;
340   UINT16 out_size = 0;
341 
342   if (file_id >= 0x90)
343      while (seek_next_record(instream, file_id))
344      {
345         stream_read(instream, &data, 1);
346         stream_seek(instream, 1, SEEK_CUR);
347         buffer = (UINT8*)malloc(data);
348         stream_read(instream, buffer, data);
349         stream_write(outstream, buffer, data);
350         stream_putc(outstream, '\r');
351         stream_putc(outstream, '\n');
352         free (buffer);
353         out_size += data;
354      }
355 
356   return out_size;
357}
358 
359UINT16 get_ob3(imgtool_stream *instream, imgtool_stream *outstream, UINT8 type, UINT8 file_id)
360{
361   UINT8 data, *buffer = NULL;
362   UINT16 size = 0;
363   char ob3_magic[3] = {'O', 'R', 'G'};
364 
365   stream_read(instream, &data, 1);
366 
367   if (data == 0x02)
368   {
369      stream_seek(instream, 1, SEEK_CUR);
370      size = get_long_rec_size(instream);
371      buffer = (UINT8*)malloc(size);
372      stream_read(instream, buffer, size);
373   }
374 
375   stream_write(outstream, ob3_magic, 3);
376   stream_putc(outstream, (size>>8) & 0xff);
377   stream_putc(outstream, size & 0xff);
378   stream_putc(outstream, type | 0x80);
379 
380   if (buffer)
381   {
382      stream_write(outstream, buffer, size);
383      free (buffer);
384   }
385 
386   return size;
387}
388 
389static imgtoolerr_t datapack_open( imgtool_image *image, imgtool_stream *stream)
390{
391   psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image);
392   char opk_magic[4];
393 
394   stream_read(stream, opk_magic, 4);
395 
396   if(strcmp(opk_magic, "OPK\0"))
397      return IMGTOOLERR_UNEXPECTED;
398 
399   pack->stream = stream;
400 
401   if (update_pack_index(pack))
402      return IMGTOOLERR_SUCCESS;
403   else
404      return IMGTOOLERR_CORRUPTIMAGE;
405}
406 
407static imgtoolerr_t datapack_create( imgtool_image *image, imgtool_stream *stream, option_resolution *opts)
408{
409   psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image);
410   UINT8 opk_magic[4] = {'O', 'P', 'K', 0x00};
411   UINT8 pack_head[8] = {0x40, 0x00, 0x59, 0x01, 0x01, 0x01, 0x00, 0x00};
412   UINT16 checksum;
413 
414   pack_head[0] |= (option_resolution_lookup_int(opts, 'R')) ? 0x00 : 0x02;
415   pack_head[0] |= (option_resolution_lookup_int(opts, 'P')) ? 0x04 : 0x00;
416   pack_head[0] |= (option_resolution_lookup_int(opts, 'W')) ? 0x00 : 0x08;
417   pack_head[0] |= (option_resolution_lookup_int(opts, 'B')) ? 0x00 : 0x10;
418   pack_head[0] |= (option_resolution_lookup_int(opts, 'C')) ? 0x20 : 0x00;
419   pack_head[1] = option_resolution_lookup_int(opts, 'S');
420 
421   checksum = head_checksum(pack_head);
422 
423   stream_write(stream, opk_magic, 4);
424   stream_fill(stream, 0x00, 2);
425   stream_write(stream, pack_head, 8);
426 
427   stream_putc(stream, (checksum>>8) & 0xff);
428   stream_putc(stream, checksum & 0xff);
429 
430   put_name_record(stream, "MAIN", 0x81, 0x90);
431 
432   stream_fill(stream, 0xff, 2);
433 
434   update_opk_head(stream);
435 
436   pack->stream = stream;
437 
438   if (update_pack_index(pack))
439      return IMGTOOLERR_SUCCESS;
440   else
441      return IMGTOOLERR_CORRUPTIMAGE;
442}
443 
444static void datapack_close( imgtool_image *image)
445{
446   psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image);
447 
448   stream_close( pack->stream );
449}
450 
451static imgtoolerr_t datapack_begin_enum(imgtool_directory *enumeration, const char *path)
452{
453   psion_iter *iter = (psion_iter*)imgtool_directory_extrabytes(enumeration);
454   iter->index = 0;
455 
456   return IMGTOOLERR_SUCCESS;
457}
458 
459static imgtoolerr_t datapack_next_enum(imgtool_directory *enumeration, imgtool_dirent *ent)
460{
461   imgtool_image *image = imgtool_directory_image(enumeration);
462   psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image);
463   psion_iter *iter = (psion_iter*)imgtool_directory_extrabytes(enumeration);
464   UINT8 data = 0;
465 
466   if (!pack->pack_index[iter->index].name_rec)
467   {
468      ent->eof = 1;
469      return IMGTOOLERR_SUCCESS;
470   }
471   memcpy(ent->filename, pack->pack_index[iter->index].filename, 8);
472   sprintf(ent->attr, "Type: %02x ID: %02x", pack->pack_index[iter->index].type, pack->pack_index[iter->index].id);
473 
474   if (pack->pack_index[iter->index].data_rec)
475   {
476      stream_seek(pack->stream, pack->pack_index[iter->index].data_rec + 2, SEEK_SET);
477      ent->filesize = get_long_rec_size(pack->stream);
478   }
479 
480   // seek all file's records
481   if (pack->pack_index[iter->index].id >= 0x90)
482   {
483      stream_seek(pack->stream, 0x10, SEEK_SET);
484      while (seek_next_record(pack->stream, pack->pack_index[iter->index].id))
485      {
486         stream_read(pack->stream, &data, 1);
487         stream_seek(pack->stream, data + 1, SEEK_CUR);
488         ent->filesize +=data;
489      }
490   }
491 
492   iter->index++;
493   return IMGTOOLERR_SUCCESS;
494}
495 
496static void datapack_close_enum( imgtool_directory *enumeration)
497{
498}
499 
500static imgtoolerr_t datapack_free_space( imgtool_partition *partition, UINT64 *size)
501{
502   imgtool_image *image = imgtool_partition_image( partition);
503   psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image);
504   UINT32 pack_size = 0;
505 
506   stream_seek(pack->stream, 0x07, SEEK_SET);
507   stream_read(pack->stream, &pack_size, 1);
508 
509   if (size)
510      *size = (pack_size * 0x2000) - pack->eop;
511 
512   return IMGTOOLERR_SUCCESS;
513}
514 
515static imgtoolerr_t datapack_read_file(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf)
516{
517   imgtool_image *image = imgtool_partition_image(partition);
518   psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image);
519   int index = seek_file_name(pack, filename);
520 
521   if (index >= 0)
522   {
523      if ((pack->pack_index[index].type & 0x7f) == 0x01)
524      {
525         // ODB files
526         stream_seek(pack->stream, 0x10, SEEK_SET);
527         get_odb(pack->stream, destf, pack->pack_index[index].type, pack->pack_index[index].id);
528      }
529      else if ((pack->pack_index[index].type & 0x7f) == 0x03)
530      {
531         // OB3/OPL files
532         stream_seek(pack->stream, pack->pack_index[index].data_rec, SEEK_SET);
533         get_ob3(pack->stream, destf, pack->pack_index[index].type, pack->pack_index[index].id);
534      }
535      else
536      {
537         // Other files
538         return IMGTOOLERR_UNIMPLEMENTED;
539      }
540 
541      return IMGTOOLERR_SUCCESS;
542   }
543   else
544      return IMGTOOLERR_FILENOTFOUND;
545}
546 
547static imgtoolerr_t datapack_write_file( imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, option_resolution *opts)
548{
549   imgtool_image *image = imgtool_partition_image(partition);
550   psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image);
551   UINT8 data_head[4] = {0x02, 0x80, 0x00, 0x00};
552   UINT8 head[3];
553   UINT16 size = 0;
554   UINT8 type = option_resolution_lookup_int(opts, 'T');
555   UINT8 file_id = option_resolution_lookup_int(opts, 'I');
556 
557   if (!pack->eop)
558      return IMGTOOLERR_CORRUPTIMAGE;
559 
560   // if not file_id is specified get the first free (for ODB only)
561   if (file_id == 0 && type == 3)
562   {
563      file_id = get_free_file_id(pack);
564 
565      if (file_id == 0xff)
566         return IMGTOOLERR_NOSPACE;
567   }
568 
569   stream_read(sourcef, head, 3);
570   stream_seek(pack->stream, pack->eop, SEEK_SET);
571 
572   if (type == 0)
573      type = (!strncmp((char*)head, "ORG", 3)) ? 1 : 2;
574 
575   switch (type)
576   {
577      case 1:      //OB3 file
578         put_name_record(pack->stream, filename, 0x83, file_id);
579         stream_write(pack->stream, data_head, 4);
580         size = put_ob3(sourcef, pack->stream);
581         break;
582      case 2:      //OPL file
583         put_name_record(pack->stream, filename, 0x83, file_id);
584         stream_write(pack->stream, data_head, 4);
585         size = put_opl(sourcef, pack->stream);
586         break;
587      case 3:      //ODB file
588         put_name_record(pack->stream, filename, 0x81, file_id);
589         size = put_odb(sourcef, pack->stream, file_id);
590         break;
591   }
592 
593   if (type != 3)
594   {
595      // update the OB3/OPL long record size
596      stream_seek(pack->stream, pack->eop + 13, SEEK_SET);
597      stream_putc(pack->stream, (size>>8) & 0xff);
598      stream_putc(pack->stream, size & 0xff);
599   }
600 
601   update_opk_head(pack->stream);
602 
603   if (update_pack_index(pack))
604      return IMGTOOLERR_SUCCESS;
605   else
606      return IMGTOOLERR_CORRUPTIMAGE;
607}
608 
609static imgtoolerr_t datapack_delete_file( imgtool_partition *partition, const char *filename)
610{
611   imgtool_image *image = imgtool_partition_image(partition);
612   psion_pack *pack = (psion_pack*)imgtool_image_extra_bytes(image);
613   int index = seek_file_name(pack, filename);
614 
615   if (index >= 0)
616   {
617      // clear the bit 7 of the file type to mark the file as deleted
618      stream_seek(pack->stream, pack->pack_index[index].name_rec + 1, SEEK_SET);
619      stream_putc(pack->stream, pack->pack_index[index].type & 0x7f);
620 
621      if (update_pack_index(pack))
622         return IMGTOOLERR_SUCCESS;
623      else
624         return IMGTOOLERR_CORRUPTIMAGE;
625   }
626   else
627      return IMGTOOLERR_FILENOTFOUND;
628}
629 
630static OPTION_GUIDE_START( psion_create_optguide )
631   OPTION_ENUM_START( 'S', "size", "datapack size" )
632      OPTION_ENUM( 1, "8k", "8 kbyte" )
633      OPTION_ENUM( 2, "16k", "16 kbyts" )
634      OPTION_ENUM( 4, "32k", "32 kbyte" )
635      OPTION_ENUM( 8, "64k", "64 kbyte" )
636      OPTION_ENUM( 16, "128k", "128 kbyte" ) // only paged datapacks can have this size
637   OPTION_ENUM_END
638   OPTION_INT('R', "ram", "EPROM/RAM datapack" )
639   OPTION_INT('P', "paged", "linear/paged datapack" )
640   OPTION_INT('W', "protect", "write-protected datapack" )
641   OPTION_INT('B', "boot", "bootable datapack" )
642   OPTION_INT('C', "copy", "copyable datapack" )
643OPTION_GUIDE_END
644 
645static OPTION_GUIDE_START( psion_write_optguide )
646   OPTION_ENUM_START( 'T', "type", "file type" )
647      OPTION_ENUM( 1, "OB3", "OB3 files" )
648      OPTION_ENUM( 2, "OPL", "OPL files" )
649      OPTION_ENUM( 3, "ODB", "ODB or text files" )
650   OPTION_ENUM_END
651   OPTION_INT( 'I', "id", "File ID" )
652OPTION_GUIDE_END
653 
654void psion_get_info( const imgtool_class *imgclass, UINT32 state, union imgtoolinfo *info)
655{
656   switch (state)
657   {
658      // --- the following bits of info are returned as 64-bit signed integers ---
659      case IMGTOOLINFO_INT_IMAGE_EXTRA_BYTES          : info->i = sizeof(psion_pack); break;
660      case IMGTOOLINFO_INT_DIRECTORY_EXTRA_BYTES      : info->i = sizeof(psion_iter); break;
661 
662      // --- the following bits of info are returned as pointers to data or functions ---
663      case IMGTOOLINFO_PTR_OPEN        : info->open        = datapack_open; break;
664      case IMGTOOLINFO_PTR_CREATE      : info->create      = datapack_create; break;
665      case IMGTOOLINFO_PTR_CLOSE       : info->close       = datapack_close; break;
666      case IMGTOOLINFO_PTR_BEGIN_ENUM  : info->begin_enum  = datapack_begin_enum; break;
667      case IMGTOOLINFO_PTR_NEXT_ENUM   : info->next_enum   = datapack_next_enum; break;
668      case IMGTOOLINFO_PTR_CLOSE_ENUM  : info->close_enum  = datapack_close_enum; break;
669      case IMGTOOLINFO_PTR_FREE_SPACE  : info->free_space  = datapack_free_space; break;
670      case IMGTOOLINFO_PTR_READ_FILE   : info->read_file   = datapack_read_file; break;
671      case IMGTOOLINFO_PTR_WRITE_FILE  : info->write_file  = datapack_write_file; break;
672      case IMGTOOLINFO_PTR_DELETE_FILE : info->delete_file = datapack_delete_file; break;
673      case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE : info->createimage_optguide = psion_create_optguide; break;
674      case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE : info->createimage_optguide = psion_write_optguide; break;
675 
676      // --- the following bits of info are returned as NULL-terminated strings ---
677      case IMGTOOLINFO_STR_NAME            : strcpy( info->s = imgtool_temp_str(), "psionpack"); break;
678      case IMGTOOLINFO_STR_DESCRIPTION     : strcpy( info->s = imgtool_temp_str(), "Psion Organiser II Datapack"); break;
679      case IMGTOOLINFO_STR_FILE            : strcpy( info->s = imgtool_temp_str(), __FILE__); break;
680      case IMGTOOLINFO_STR_FILE_EXTENSIONS : strcpy( info->s = imgtool_temp_str(), "opk"); break;
681      case IMGTOOLINFO_STR_CREATEIMAGE_OPTSPEC : strcpy( info->s = imgtool_temp_str(), "S1/2/[4]/8/16;R[0]/1;P[0]/1;W0/[1];B[0]/1;C0/[1]"); break;
682      case IMGTOOLINFO_STR_WRITEFILE_OPTSPEC : strcpy( info->s = imgtool_temp_str(), "T[1]/2/3;I[0]/145-255"); break;
683   }
684}

Previous 15994 Revisions Next


© 1998-2018 The MESS Team