Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

t64.c

00001 /*
00002  *      This program is free software; you can redistribute it and/or
00003  *      modify it under the terms of the GNU General Public License
00004  *      as published by the Free Software Foundation; either version
00005  *      2 of the License, or (at your option) any later version.
00006  *
00007  *  Copyright 2001-2003 Michael Klein <michael(dot)klein(at)puffin(dot)lb(dot)shuttle(dot)de>
00008 */
00009 
00010 #ifdef SAVE_RCSID
00011 static char *rcsid =
00012     "@(#) $Id: t64.c,v 1.4 2006/02/24 12:01:01 trikalio Exp $";
00013 #endif
00014 
00015 #include <stdlib.h>
00016 #include <string.h>
00017 
00018 #include "opencbm.h"
00019 #include "inputfiles.h"
00020 
00021 static int probe(FILE *file, const char *fname, cbmcopy_message_cb msg_cb)
00022 {
00023     /* signature list stolen from cbmconvert */
00024     const char signatures[][32] =
00025     {
00026         "C64 tape image file\0\0\0\0\0\0\0\0\0\0\0\0\0",
00027         "C64S tape file\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
00028         "C64S tape image file\0\0\0\0\0\0\0\0\0\0\0\0"
00029     };
00030     struct
00031     {
00032         char sig[32];
00033         unsigned char major;
00034         unsigned char minor;
00035         unsigned char max_entries_l;
00036         unsigned char max_entries_h;
00037         unsigned char used_entries_l;
00038         unsigned char used_entries_h;
00039         char pad[2];
00040         char name[24];  /* careful: not '\0'-terminated! */
00041     } t64header;
00042 
00043     size_t i;
00044     int used_entries;
00045     
00046     msg_cb( sev_debug, "checking for t64" );
00047 
00048     if(fread( &t64header, sizeof(t64header), 1, file) == 1)
00049     {
00050         for(i = 0; i < sizeof(signatures) / 32; i++)
00051         {
00052             if(memcmp(signatures[i], t64header.sig, 32) == 0)
00053             {
00054                 used_entries =
00055                     t64header.used_entries_l +
00056                     t64header.used_entries_h * 256;
00057                 msg_cb( sev_debug, "found t64 signature `%sī", signatures[i] );
00058                 msg_cb( sev_debug, "tape version %u.%u",
00059                         t64header.major, t64header.minor );
00060                 msg_cb( sev_debug, "tape contains %d file%c",
00061                         used_entries, used_entries > 1 ? 's' : '\0' );
00062                 return used_entries;
00063             }
00064         }
00065     }
00066     rewind( file );
00067     return 0;
00068 }
00069 
00070 
00071 static int read(FILE *file, const char *fname, int entry,
00072                 char *cbmname, char *type,
00073                 unsigned char **data, size_t *size,
00074                 cbmcopy_message_cb msg_cb)
00075 {
00076     struct
00077     {
00078         unsigned char c64s_type;
00079         unsigned char c1541_type;
00080         unsigned char start_l;
00081         unsigned char start_h;
00082         unsigned char end_l;
00083         unsigned char end_h;
00084         unsigned char unused1[2];
00085         unsigned char offset[4];  /* l to h */
00086         unsigned char unused2[4];
00087         unsigned char name[16];
00088     } t64entry;
00089     long offset;
00090     int i;
00091     int start;
00092     int end;
00093 
00094     if(fseek( file, 0x40 + 32 * entry, SEEK_SET ) == 0 &&
00095        fread( &t64entry, sizeof(t64entry), 1, file ) == 1)
00096     {
00097         memcpy( cbmname, t64entry.name, 16 );
00098         for( i = 15; i >= 0 && cbmname[i] == 0x20; i-- )
00099         {
00100             cbmname[i] = (char) 0xa0;
00101         }
00102         switch(t64entry.c1541_type)
00103         {
00104             case 0x01:
00105             case 0x80:
00106             case 'D' :
00107                 *type = 'D';
00108                 break;
00109             case 0x81:
00110             case 'S' :
00111                 *type = 'S';
00112                 break;
00113             case 0x82:
00114             case 'P' :
00115                 *type = 'P';
00116                 break;
00117             case 0x83:
00118             case 'U' :
00119                 *type = 'U';
00120                 break;
00121             default:
00122                 msg_cb( sev_info, "unknown 1541 file type, using default" );
00123                 *type = 'P';
00124                 break;
00125         }
00126         for(offset = 0, i = 3; i >= 0; i--)
00127         {
00128             offset = offset * 0x100 + t64entry.offset[i];
00129         }
00130         msg_cb( sev_debug, "data offset = %08lx", offset );
00131         start = t64entry.start_l + 0x100 * t64entry.start_h;
00132         end = t64entry.end_l + 0x100 * t64entry.end_h;
00133 
00134         if(fseek(file, offset, SEEK_SET) == 0)
00135         {
00136             *size = 2 + (end - start);
00137             *data = malloc(*size);
00138             if(*data)
00139             {
00140                 (*data)[0] = t64entry.start_l;
00141                 (*data)[1] = t64entry.start_h;
00142                 if(fread(&(*data)[2], (*size)-2, 1, file) == 1)
00143                 {
00144                     return 0;
00145                 }
00146                 else
00147                 {
00148                     msg_cb( sev_warning, "could not read file data" );
00149                 }
00150                 free(*data);
00151             }
00152             else
00153             {
00154                 msg_cb( sev_warning, "no memory" );
00155             }
00156         }
00157         else
00158         {
00159             msg_cb( sev_warning, "could not seek to file data" );
00160         }
00161     }
00162     else
00163     {
00164         msg_cb( sev_warning, "could not seek to directory entry" );
00165     }
00166     return 1;
00167 }
00168 
00169 DECLARE_INPUT_READER(t64);

Generated on Sun Apr 30 18:45:59 2006 for opencbm by  doxygen 1.4.2